rtc: switch to using is_visible() to control sysfs attributes
Instead of creating wakealarm attribute manually, after the device has been registered, let's rely on facilities provided by the attribute groups to control which attributes are visible and which are not. This allows to create all needed attributes at once, at the same time that we register RTC class device. Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com> Reviewed-by: Krzysztof Kozlowski <k.kozlowski@samsung.com> Signed-off-by: Alexandre Belloni <alexandre.belloni@free-electrons.com>
This commit is contained in:
parent
a17ccd1c6a
commit
3ee2c40b7a
|
@ -202,6 +202,7 @@ struct rtc_device *rtc_device_register(const char *name, struct device *dev,
|
|||
rtc->max_user_freq = 64;
|
||||
rtc->dev.parent = dev;
|
||||
rtc->dev.class = rtc_class;
|
||||
rtc->dev.groups = rtc_get_dev_attribute_groups();
|
||||
rtc->dev.release = rtc_device_release;
|
||||
|
||||
mutex_init(&rtc->ops_lock);
|
||||
|
@ -240,7 +241,6 @@ struct rtc_device *rtc_device_register(const char *name, struct device *dev,
|
|||
}
|
||||
|
||||
rtc_dev_add_device(rtc);
|
||||
rtc_sysfs_add_device(rtc);
|
||||
rtc_proc_add_device(rtc);
|
||||
|
||||
dev_info(dev, "rtc core: registered %s as %s\n",
|
||||
|
@ -271,7 +271,6 @@ void rtc_device_unregister(struct rtc_device *rtc)
|
|||
* Remove innards of this RTC, then disable it, before
|
||||
* letting any rtc_class_open() users access it again
|
||||
*/
|
||||
rtc_sysfs_del_device(rtc);
|
||||
rtc_dev_del_device(rtc);
|
||||
rtc_proc_del_device(rtc);
|
||||
device_del(&rtc->dev);
|
||||
|
@ -360,7 +359,6 @@ static int __init rtc_init(void)
|
|||
}
|
||||
rtc_class->pm = RTC_CLASS_DEV_PM_OPS;
|
||||
rtc_dev_init();
|
||||
rtc_sysfs_init(rtc_class);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -48,23 +48,10 @@ static inline void rtc_proc_del_device(struct rtc_device *rtc)
|
|||
#endif
|
||||
|
||||
#ifdef CONFIG_RTC_INTF_SYSFS
|
||||
|
||||
extern void __init rtc_sysfs_init(struct class *);
|
||||
extern void rtc_sysfs_add_device(struct rtc_device *rtc);
|
||||
extern void rtc_sysfs_del_device(struct rtc_device *rtc);
|
||||
|
||||
const struct attribute_group **rtc_get_dev_attribute_groups(void);
|
||||
#else
|
||||
|
||||
static inline void rtc_sysfs_init(struct class *rtc)
|
||||
static inline const struct attribute_group **rtc_get_dev_attribute_groups(void)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static inline void rtc_sysfs_add_device(struct rtc_device *rtc)
|
||||
{
|
||||
}
|
||||
|
||||
static inline void rtc_sysfs_del_device(struct rtc_device *rtc)
|
||||
{
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -122,17 +122,6 @@ hctosys_show(struct device *dev, struct device_attribute *attr, char *buf)
|
|||
}
|
||||
static DEVICE_ATTR_RO(hctosys);
|
||||
|
||||
static struct attribute *rtc_attrs[] = {
|
||||
&dev_attr_name.attr,
|
||||
&dev_attr_date.attr,
|
||||
&dev_attr_time.attr,
|
||||
&dev_attr_since_epoch.attr,
|
||||
&dev_attr_max_user_freq.attr,
|
||||
&dev_attr_hctosys.attr,
|
||||
NULL,
|
||||
};
|
||||
ATTRIBUTE_GROUPS(rtc);
|
||||
|
||||
static ssize_t
|
||||
wakealarm_show(struct device *dev, struct device_attribute *attr, char *buf)
|
||||
{
|
||||
|
@ -222,6 +211,16 @@ wakealarm_store(struct device *dev, struct device_attribute *attr,
|
|||
}
|
||||
static DEVICE_ATTR_RW(wakealarm);
|
||||
|
||||
static struct attribute *rtc_attrs[] = {
|
||||
&dev_attr_name.attr,
|
||||
&dev_attr_date.attr,
|
||||
&dev_attr_time.attr,
|
||||
&dev_attr_since_epoch.attr,
|
||||
&dev_attr_max_user_freq.attr,
|
||||
&dev_attr_hctosys.attr,
|
||||
&dev_attr_wakealarm.attr,
|
||||
NULL,
|
||||
};
|
||||
|
||||
/* The reason to trigger an alarm with no process watching it (via sysfs)
|
||||
* is its side effect: waking from a system state like suspend-to-RAM or
|
||||
|
@ -236,29 +235,31 @@ static bool rtc_does_wakealarm(struct rtc_device *rtc)
|
|||
return rtc->ops->set_alarm != NULL;
|
||||
}
|
||||
|
||||
|
||||
void rtc_sysfs_add_device(struct rtc_device *rtc)
|
||||
static umode_t rtc_attr_is_visible(struct kobject *kobj,
|
||||
struct attribute *attr, int n)
|
||||
{
|
||||
int err;
|
||||
struct device *dev = container_of(kobj, struct device, kobj);
|
||||
struct rtc_device *rtc = to_rtc_device(dev);
|
||||
umode_t mode = attr->mode;
|
||||
|
||||
/* not all RTCs support both alarms and wakeup */
|
||||
if (attr == &dev_attr_wakealarm.attr)
|
||||
if (!rtc_does_wakealarm(rtc))
|
||||
return;
|
||||
mode = 0;
|
||||
|
||||
err = device_create_file(&rtc->dev, &dev_attr_wakealarm);
|
||||
if (err)
|
||||
dev_err(rtc->dev.parent,
|
||||
"failed to create alarm attribute, %d\n", err);
|
||||
return mode;
|
||||
}
|
||||
|
||||
void rtc_sysfs_del_device(struct rtc_device *rtc)
|
||||
static struct attribute_group rtc_attr_group = {
|
||||
.is_visible = rtc_attr_is_visible,
|
||||
.attrs = rtc_attrs,
|
||||
};
|
||||
|
||||
static const struct attribute_group *rtc_attr_groups[] = {
|
||||
&rtc_attr_group,
|
||||
NULL
|
||||
};
|
||||
|
||||
const struct attribute_group **rtc_get_dev_attribute_groups(void)
|
||||
{
|
||||
/* REVISIT did we add it successfully? */
|
||||
if (rtc_does_wakealarm(rtc))
|
||||
device_remove_file(&rtc->dev, &dev_attr_wakealarm);
|
||||
}
|
||||
|
||||
void __init rtc_sysfs_init(struct class *rtc_class)
|
||||
{
|
||||
rtc_class->dev_groups = rtc_groups;
|
||||
return rtc_attr_groups;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue