Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

Dmitry Torokhov and committed by
Alexandre Belloni
3ee2c40b a17ccd1c

+34 -48
+1 -3
drivers/rtc/class.c
··· 202 202 rtc->max_user_freq = 64; 203 203 rtc->dev.parent = dev; 204 204 rtc->dev.class = rtc_class; 205 + rtc->dev.groups = rtc_get_dev_attribute_groups(); 205 206 rtc->dev.release = rtc_device_release; 206 207 207 208 mutex_init(&rtc->ops_lock); ··· 241 240 } 242 241 243 242 rtc_dev_add_device(rtc); 244 - rtc_sysfs_add_device(rtc); 245 243 rtc_proc_add_device(rtc); 246 244 247 245 dev_info(dev, "rtc core: registered %s as %s\n", ··· 271 271 * Remove innards of this RTC, then disable it, before 272 272 * letting any rtc_class_open() users access it again 273 273 */ 274 - rtc_sysfs_del_device(rtc); 275 274 rtc_dev_del_device(rtc); 276 275 rtc_proc_del_device(rtc); 277 276 device_del(&rtc->dev); ··· 359 360 } 360 361 rtc_class->pm = RTC_CLASS_DEV_PM_OPS; 361 362 rtc_dev_init(); 362 - rtc_sysfs_init(rtc_class); 363 363 return 0; 364 364 } 365 365
+3 -16
drivers/rtc/rtc-core.h
··· 48 48 #endif 49 49 50 50 #ifdef CONFIG_RTC_INTF_SYSFS 51 - 52 - extern void __init rtc_sysfs_init(struct class *); 53 - extern void rtc_sysfs_add_device(struct rtc_device *rtc); 54 - extern void rtc_sysfs_del_device(struct rtc_device *rtc); 55 - 51 + const struct attribute_group **rtc_get_dev_attribute_groups(void); 56 52 #else 57 - 58 - static inline void rtc_sysfs_init(struct class *rtc) 53 + static inline const struct attribute_group **rtc_get_dev_attribute_groups(void) 59 54 { 55 + return NULL; 60 56 } 61 - 62 - static inline void rtc_sysfs_add_device(struct rtc_device *rtc) 63 - { 64 - } 65 - 66 - static inline void rtc_sysfs_del_device(struct rtc_device *rtc) 67 - { 68 - } 69 - 70 57 #endif
+30 -29
drivers/rtc/rtc-sysfs.c
··· 122 122 } 123 123 static DEVICE_ATTR_RO(hctosys); 124 124 125 - static 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 - }; 134 - ATTRIBUTE_GROUPS(rtc); 135 - 136 125 static ssize_t 137 126 wakealarm_show(struct device *dev, struct device_attribute *attr, char *buf) 138 127 { ··· 211 222 } 212 223 static DEVICE_ATTR_RW(wakealarm); 213 224 225 + static struct attribute *rtc_attrs[] = { 226 + &dev_attr_name.attr, 227 + &dev_attr_date.attr, 228 + &dev_attr_time.attr, 229 + &dev_attr_since_epoch.attr, 230 + &dev_attr_max_user_freq.attr, 231 + &dev_attr_hctosys.attr, 232 + &dev_attr_wakealarm.attr, 233 + NULL, 234 + }; 214 235 215 236 /* The reason to trigger an alarm with no process watching it (via sysfs) 216 237 * is its side effect: waking from a system state like suspend-to-RAM or ··· 235 236 return rtc->ops->set_alarm != NULL; 236 237 } 237 238 238 - 239 - void rtc_sysfs_add_device(struct rtc_device *rtc) 239 + static umode_t rtc_attr_is_visible(struct kobject *kobj, 240 + struct attribute *attr, int n) 240 241 { 241 - int err; 242 + struct device *dev = container_of(kobj, struct device, kobj); 243 + struct rtc_device *rtc = to_rtc_device(dev); 244 + umode_t mode = attr->mode; 242 245 243 - /* not all RTCs support both alarms and wakeup */ 244 - if (!rtc_does_wakealarm(rtc)) 245 - return; 246 + if (attr == &dev_attr_wakealarm.attr) 247 + if (!rtc_does_wakealarm(rtc)) 248 + mode = 0; 246 249 247 - err = device_create_file(&rtc->dev, &dev_attr_wakealarm); 248 - if (err) 249 - dev_err(rtc->dev.parent, 250 - "failed to create alarm attribute, %d\n", err); 250 + return mode; 251 251 } 252 252 253 - void rtc_sysfs_del_device(struct rtc_device *rtc) 254 - { 255 - /* REVISIT did we add it successfully? */ 256 - if (rtc_does_wakealarm(rtc)) 257 - device_remove_file(&rtc->dev, &dev_attr_wakealarm); 258 - } 253 + static struct attribute_group rtc_attr_group = { 254 + .is_visible = rtc_attr_is_visible, 255 + .attrs = rtc_attrs, 256 + }; 259 257 260 - void __init rtc_sysfs_init(struct class *rtc_class) 258 + static const struct attribute_group *rtc_attr_groups[] = { 259 + &rtc_attr_group, 260 + NULL 261 + }; 262 + 263 + const struct attribute_group **rtc_get_dev_attribute_groups(void) 261 264 { 262 - rtc_class->dev_groups = rtc_groups; 265 + return rtc_attr_groups; 263 266 }