aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/rtc
diff options
context:
space:
mode:
authorDmitry Torokhov <dmitry.torokhov@gmail.com>2015-07-23 19:01:08 -0400
committerAlexandre Belloni <alexandre.belloni@free-electrons.com>2015-09-05 07:19:07 -0400
commit3ee2c40b7ac2bf121aaa1176d8ac25b6a26e3a94 (patch)
treeefe5e8ee4667aa49c34f1ef2653067206297f2da /drivers/rtc
parenta17ccd1c6a327e5b468358e8352a6af004261473 (diff)
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>
Diffstat (limited to 'drivers/rtc')
-rw-r--r--drivers/rtc/class.c4
-rw-r--r--drivers/rtc/rtc-core.h19
-rw-r--r--drivers/rtc/rtc-sysfs.c59
3 files changed, 34 insertions, 48 deletions
diff --git a/drivers/rtc/class.c b/drivers/rtc/class.c
index de7707f7e766..de86578bcd6d 100644
--- a/drivers/rtc/class.c
+++ b/drivers/rtc/class.c
@@ -202,6 +202,7 @@ struct rtc_device *rtc_device_register(const char *name, struct device *dev,
202 rtc->max_user_freq = 64; 202 rtc->max_user_freq = 64;
203 rtc->dev.parent = dev; 203 rtc->dev.parent = dev;
204 rtc->dev.class = rtc_class; 204 rtc->dev.class = rtc_class;
205 rtc->dev.groups = rtc_get_dev_attribute_groups();
205 rtc->dev.release = rtc_device_release; 206 rtc->dev.release = rtc_device_release;
206 207
207 mutex_init(&rtc->ops_lock); 208 mutex_init(&rtc->ops_lock);
@@ -240,7 +241,6 @@ struct rtc_device *rtc_device_register(const char *name, struct device *dev,
240 } 241 }
241 242
242 rtc_dev_add_device(rtc); 243 rtc_dev_add_device(rtc);
243 rtc_sysfs_add_device(rtc);
244 rtc_proc_add_device(rtc); 244 rtc_proc_add_device(rtc);
245 245
246 dev_info(dev, "rtc core: registered %s as %s\n", 246 dev_info(dev, "rtc core: registered %s as %s\n",
@@ -271,7 +271,6 @@ void rtc_device_unregister(struct rtc_device *rtc)
271 * Remove innards of this RTC, then disable it, before 271 * Remove innards of this RTC, then disable it, before
272 * letting any rtc_class_open() users access it again 272 * letting any rtc_class_open() users access it again
273 */ 273 */
274 rtc_sysfs_del_device(rtc);
275 rtc_dev_del_device(rtc); 274 rtc_dev_del_device(rtc);
276 rtc_proc_del_device(rtc); 275 rtc_proc_del_device(rtc);
277 device_del(&rtc->dev); 276 device_del(&rtc->dev);
@@ -360,7 +359,6 @@ static int __init rtc_init(void)
360 } 359 }
361 rtc_class->pm = RTC_CLASS_DEV_PM_OPS; 360 rtc_class->pm = RTC_CLASS_DEV_PM_OPS;
362 rtc_dev_init(); 361 rtc_dev_init();
363 rtc_sysfs_init(rtc_class);
364 return 0; 362 return 0;
365} 363}
366 364
diff --git a/drivers/rtc/rtc-core.h b/drivers/rtc/rtc-core.h
index 5f9df7430a22..a098aea197fc 100644
--- a/drivers/rtc/rtc-core.h
+++ b/drivers/rtc/rtc-core.h
@@ -48,23 +48,10 @@ static inline void rtc_proc_del_device(struct rtc_device *rtc)
48#endif 48#endif
49 49
50#ifdef CONFIG_RTC_INTF_SYSFS 50#ifdef CONFIG_RTC_INTF_SYSFS
51 51const struct attribute_group **rtc_get_dev_attribute_groups(void);
52extern void __init rtc_sysfs_init(struct class *);
53extern void rtc_sysfs_add_device(struct rtc_device *rtc);
54extern void rtc_sysfs_del_device(struct rtc_device *rtc);
55
56#else 52#else
57 53static inline const struct attribute_group **rtc_get_dev_attribute_groups(void)
58static inline void rtc_sysfs_init(struct class *rtc)
59{
60}
61
62static inline void rtc_sysfs_add_device(struct rtc_device *rtc)
63{ 54{
55 return NULL;
64} 56}
65
66static inline void rtc_sysfs_del_device(struct rtc_device *rtc)
67{
68}
69
70#endif 57#endif
diff --git a/drivers/rtc/rtc-sysfs.c b/drivers/rtc/rtc-sysfs.c
index e3ce1dc92b65..7273855ed02e 100644
--- a/drivers/rtc/rtc-sysfs.c
+++ b/drivers/rtc/rtc-sysfs.c
@@ -122,17 +122,6 @@ hctosys_show(struct device *dev, struct device_attribute *attr, char *buf)
122} 122}
123static DEVICE_ATTR_RO(hctosys); 123static DEVICE_ATTR_RO(hctosys);
124 124
125static struct attribute *rtc_attrs[] = {
126 &dev_attr_name.attr,
127 &dev_attr_date.attr,
128 &dev_attr_time.attr,
129 &dev_attr_since_epoch.attr,
130 &dev_attr_max_user_freq.attr,
131 &dev_attr_hctosys.attr,
132 NULL,
133};
134ATTRIBUTE_GROUPS(rtc);
135
136static ssize_t 125static ssize_t
137wakealarm_show(struct device *dev, struct device_attribute *attr, char *buf) 126wakealarm_show(struct device *dev, struct device_attribute *attr, char *buf)
138{ 127{
@@ -222,6 +211,16 @@ wakealarm_store(struct device *dev, struct device_attribute *attr,
222} 211}
223static DEVICE_ATTR_RW(wakealarm); 212static DEVICE_ATTR_RW(wakealarm);
224 213
214static struct attribute *rtc_attrs[] = {
215 &dev_attr_name.attr,
216 &dev_attr_date.attr,
217 &dev_attr_time.attr,
218 &dev_attr_since_epoch.attr,
219 &dev_attr_max_user_freq.attr,
220 &dev_attr_hctosys.attr,
221 &dev_attr_wakealarm.attr,
222 NULL,
223};
225 224
226/* The reason to trigger an alarm with no process watching it (via sysfs) 225/* The reason to trigger an alarm with no process watching it (via sysfs)
227 * is its side effect: waking from a system state like suspend-to-RAM or 226 * 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)
236 return rtc->ops->set_alarm != NULL; 235 return rtc->ops->set_alarm != NULL;
237} 236}
238 237
239 238static umode_t rtc_attr_is_visible(struct kobject *kobj,
240void rtc_sysfs_add_device(struct rtc_device *rtc) 239 struct attribute *attr, int n)
241{ 240{
242 int err; 241 struct device *dev = container_of(kobj, struct device, kobj);
242 struct rtc_device *rtc = to_rtc_device(dev);
243 umode_t mode = attr->mode;
243 244
244 /* not all RTCs support both alarms and wakeup */ 245 if (attr == &dev_attr_wakealarm.attr)
245 if (!rtc_does_wakealarm(rtc)) 246 if (!rtc_does_wakealarm(rtc))
246 return; 247 mode = 0;
247 248
248 err = device_create_file(&rtc->dev, &dev_attr_wakealarm); 249 return mode;
249 if (err)
250 dev_err(rtc->dev.parent,
251 "failed to create alarm attribute, %d\n", err);
252} 250}
253 251
254void rtc_sysfs_del_device(struct rtc_device *rtc) 252static struct attribute_group rtc_attr_group = {
255{ 253 .is_visible = rtc_attr_is_visible,
256 /* REVISIT did we add it successfully? */ 254 .attrs = rtc_attrs,
257 if (rtc_does_wakealarm(rtc)) 255};
258 device_remove_file(&rtc->dev, &dev_attr_wakealarm); 256
259} 257static const struct attribute_group *rtc_attr_groups[] = {
258 &rtc_attr_group,
259 NULL
260};
260 261
261void __init rtc_sysfs_init(struct class *rtc_class) 262const struct attribute_group **rtc_get_dev_attribute_groups(void)
262{ 263{
263 rtc_class->dev_groups = rtc_groups; 264 return rtc_attr_groups;
264} 265}