diff options
| author | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2013-07-08 17:53:25 -0700 |
|---|---|---|
| committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2013-07-08 17:53:25 -0700 |
| commit | 587ab858102ac95c961d6118a62078dc25b1ee3a (patch) | |
| tree | 3b8296f5e8ead69bf0b75c9eb09671c14e8be2e6 | |
| parent | e3f8ceca3b824d9e3299fb1565acd74d56b5adf3 (diff) | |
| download | patches-587ab858102ac95c961d6118a62078dc25b1ee3a.tar.gz | |
dev_group reworks
| -rw-r--r-- | d1.patch | 1458 | ||||
| -rw-r--r-- | misc-c2port-use-dev_bin_attrs-instead-of-hand-coding-it.patch | 93 | ||||
| -rw-r--r-- | series | 4 | ||||
| -rw-r--r-- | sysfs.h-add-__attr_rw-macro.patch | 49 | ||||
| -rw-r--r-- | sysfs.h-add-attribute_groups-macro.patch | 33 |
5 files changed, 1637 insertions, 0 deletions
diff --git a/d1.patch b/d1.patch new file mode 100644 index 00000000000000..9073f2105da82a --- /dev/null +++ b/d1.patch @@ -0,0 +1,1458 @@ +Subject: meta-patch of all of the dev_attr conversions + + + +--- + drivers/base/core.c | 19 ++++--- + drivers/dma/dmaengine.c | 16 +++-- + drivers/leds/led-class.c | 34 ++++++++++-- + drivers/misc/c2port/core.c | 41 +++++++++------ + drivers/pci/pci-sysfs.c | 26 +++++++-- + drivers/pci/pci.h | 2 + drivers/pci/probe.c | 2 + drivers/pps/pps.c | 2 + drivers/pps/sysfs.c | 31 ++++++++--- + drivers/ptp/ptp_clock.c | 2 + drivers/ptp/ptp_private.h | 2 + drivers/ptp/ptp_sysfs.c | 51 ++++++++++-------- + drivers/rtc/rtc-sysfs.c | 27 ++++++---- + drivers/scsi/sd.c | 94 +++++++++++++++++++---------------- + drivers/staging/comedi/comedi_fops.c | 27 +++++----- + drivers/uio/uio.c | 16 +++-- + drivers/video/backlight/backlight.c | 26 +++++---- + drivers/video/output.c | 12 ++-- + include/linux/device.h | 3 - + include/linux/pps_kernel.h | 2 + mm/backing-dev.c | 22 +++++--- + net/core/net-sysfs.c | 94 ++++++++++++++++++++--------------- + net/rfkill/core.c | 38 +++++++------- + 23 files changed, 362 insertions(+), 227 deletions(-) + +--- a/drivers/base/core.c ++++ b/drivers/base/core.c +@@ -528,12 +528,15 @@ static int device_add_attrs(struct devic + int error; + + if (class) { +- error = device_add_attributes(dev, class->dev_attrs); ++// error = device_add_attributes(dev, class->dev_attrs); ++// if (error) ++// return error; ++ error = device_add_groups(dev, class->dev_groups); + if (error) +- return error; ++ goto err_remove_class_attrs; + error = device_add_bin_attributes(dev, class->dev_bin_attrs); + if (error) +- goto err_remove_class_attrs; ++ goto err_remove_class_groups; + } + + if (type) { +@@ -560,9 +563,12 @@ static int device_add_attrs(struct devic + err_remove_class_bin_attrs: + if (class) + device_remove_bin_attributes(dev, class->dev_bin_attrs); ++ err_remove_class_groups: ++ if (class) ++ device_remove_groups(dev, class->dev_groups); + err_remove_class_attrs: +- if (class) +- device_remove_attributes(dev, class->dev_attrs); ++// if (class) ++// device_remove_attributes(dev, class->dev_attrs); + + return error; + } +@@ -579,7 +585,8 @@ static void device_remove_attrs(struct d + device_remove_groups(dev, type->groups); + + if (class) { +- device_remove_attributes(dev, class->dev_attrs); ++ device_remove_groups(dev, class->dev_groups); ++// device_remove_attributes(dev, class->dev_attrs); + device_remove_bin_attributes(dev, class->dev_bin_attrs); + } + } +--- a/drivers/dma/dmaengine.c ++++ b/drivers/dma/dmaengine.c +@@ -106,6 +106,7 @@ static ssize_t show_memcpy_count(struct + + return err; + } ++static DEVICE_ATTR(memcpy_count, S_IRUGO, show_memcpy_count, NULL); + + static ssize_t show_bytes_transferred(struct device *dev, struct device_attribute *attr, + char *buf) +@@ -127,6 +128,7 @@ static ssize_t show_bytes_transferred(st + + return err; + } ++static DEVICE_ATTR(bytes_transferred, S_IRUGO, show_bytes_transferred, NULL); + + static ssize_t show_in_use(struct device *dev, struct device_attribute *attr, char *buf) + { +@@ -143,13 +145,15 @@ static ssize_t show_in_use(struct device + + return err; + } ++static DEVICE_ATTR(in_use, S_IRUGO, show_in_use, NULL); + +-static struct device_attribute dma_attrs[] = { +- __ATTR(memcpy_count, S_IRUGO, show_memcpy_count, NULL), +- __ATTR(bytes_transferred, S_IRUGO, show_bytes_transferred, NULL), +- __ATTR(in_use, S_IRUGO, show_in_use, NULL), +- __ATTR_NULL ++static struct attribute *dma_dev_attrs[] = { ++ &dev_attr_memcpy_count.attr, ++ &dev_attr_bytes_transferred.attr, ++ &dev_attr_in_use.attr, ++ NULL, + }; ++ATTRIBUTE_GROUPS(dma_dev); + + static void chan_dev_release(struct device *dev) + { +@@ -167,7 +171,7 @@ static void chan_dev_release(struct devi + + static struct class dma_devclass = { + .name = "dma", +- .dev_attrs = dma_attrs, ++ .dev_groups = dma_dev_groups, + .dev_release = chan_dev_release, + }; + +--- a/drivers/leds/led-class.c ++++ b/drivers/leds/led-class.c +@@ -57,6 +57,7 @@ static ssize_t led_brightness_store(stru + + return size; + } ++static DEVICE_ATTR(brightness, 0644, led_brightness_show, led_brightness_store); + + static ssize_t led_max_brightness_show(struct device *dev, + struct device_attribute *attr, char *buf) +@@ -65,14 +66,35 @@ static ssize_t led_max_brightness_show(s + + return sprintf(buf, "%u\n", led_cdev->max_brightness); + } ++static DEVICE_ATTR(max_brightness, 0444, led_max_brightness_show, NULL); + +-static struct device_attribute led_class_attrs[] = { +- __ATTR(brightness, 0644, led_brightness_show, led_brightness_store), +- __ATTR(max_brightness, 0444, led_max_brightness_show, NULL), + #ifdef CONFIG_LEDS_TRIGGERS +- __ATTR(trigger, 0644, led_trigger_show, led_trigger_store), ++static DEVICE_ATTR(trigger, 0644, led_trigger_show, led_trigger_store); ++static struct attribute *led_trigger_attrs[] = { ++ &dev_attr_trigger.attr, ++ NULL, ++}; ++static const struct attribute_group led_trigger_group = { ++ .attrs = led_trigger_attrs, ++}; ++#endif ++ ++static struct attribute *led_class_attrs[] = { ++ &dev_attr_brightness.attr, ++ &dev_attr_max_brightness.attr, ++ NULL, ++}; ++ ++static const struct attribute_group led_group = { ++ .attrs = led_class_attrs, ++}; ++ ++static const struct attribute_group *led_groups[] = { ++ &led_group, ++#ifdef CONFIG_LEDS_TRIGGERS ++ &led_trigger_group, + #endif +- __ATTR_NULL, ++ NULL, + }; + + static void led_timer_function(unsigned long data) +@@ -258,7 +280,7 @@ static int __init leds_init(void) + if (IS_ERR(leds_class)) + return PTR_ERR(leds_class); + leds_class->pm = &leds_class_dev_pm_ops; +- leds_class->dev_attrs = led_class_attrs; ++ leds_class->dev_groups = led_groups; + return 0; + } + +--- a/drivers/misc/c2port/core.c ++++ b/drivers/misc/c2port/core.c +@@ -311,6 +311,7 @@ static ssize_t c2port_show_name(struct d + + return sprintf(buf, "%s\n", c2dev->name); + } ++static DEVICE_ATTR(name, 0444, c2port_show_name, NULL); + + static ssize_t c2port_show_flash_blocks_num(struct device *dev, + struct device_attribute *attr, char *buf) +@@ -320,6 +321,7 @@ static ssize_t c2port_show_flash_blocks_ + + return sprintf(buf, "%d\n", ops->blocks_num); + } ++static DEVICE_ATTR(flash_blocks_num, 0444, c2port_show_flash_blocks_num, NULL); + + static ssize_t c2port_show_flash_block_size(struct device *dev, + struct device_attribute *attr, char *buf) +@@ -329,6 +331,7 @@ static ssize_t c2port_show_flash_block_s + + return sprintf(buf, "%d\n", ops->block_size); + } ++static DEVICE_ATTR(flash_block_size, 0444, c2port_show_flash_block_size, NULL); + + static ssize_t c2port_show_flash_size(struct device *dev, + struct device_attribute *attr, char *buf) +@@ -338,6 +341,7 @@ static ssize_t c2port_show_flash_size(st + + return sprintf(buf, "%d\n", ops->blocks_num * ops->block_size); + } ++static DEVICE_ATTR(flash_size, 0444, c2port_show_flash_size, NULL); + + static ssize_t c2port_show_access(struct device *dev, + struct device_attribute *attr, char *buf) +@@ -375,6 +379,7 @@ static ssize_t c2port_store_access(struc + + return count; + } ++static DEVICE_ATTR(access, 0644, c2port_show_access, c2port_store_access); + + static ssize_t c2port_store_reset(struct device *dev, + struct device_attribute *attr, +@@ -395,6 +400,7 @@ static ssize_t c2port_store_reset(struct + + return count; + } ++static DEVICE_ATTR(reset, 0200, NULL, c2port_store_reset); + + static ssize_t __c2port_show_dev_id(struct c2port_device *dev, char *buf) + { +@@ -431,6 +437,7 @@ static ssize_t c2port_show_dev_id(struct + + return ret; + } ++static DEVICE_ATTR(dev_id, 0444, c2port_show_dev_id, NULL); + + static ssize_t __c2port_show_rev_id(struct c2port_device *dev, char *buf) + { +@@ -467,6 +474,7 @@ static ssize_t c2port_show_rev_id(struct + + return ret; + } ++static DEVICE_ATTR(rev_id, 0444, c2port_show_rev_id, NULL); + + static ssize_t c2port_show_flash_access(struct device *dev, + struct device_attribute *attr, char *buf) +@@ -536,6 +544,8 @@ static ssize_t c2port_store_flash_access + + return count; + } ++static DEVICE_ATTR(flash_access, 0644, c2port_show_flash_access, ++ c2port_store_flash_access); + + static ssize_t __c2port_write_flash_erase(struct c2port_device *dev) + { +@@ -616,6 +626,7 @@ static ssize_t c2port_store_flash_erase( + + return count; + } ++static DEVICE_ATTR(flash_erase, 0200, NULL, c2port_store_flash_erase); + + static ssize_t __c2port_read_flash_data(struct c2port_device *dev, + char *buffer, loff_t offset, size_t count) +@@ -850,22 +861,20 @@ static ssize_t c2port_write_flash_data(s + /* + * Class attributes + */ +- +-static struct device_attribute c2port_attrs[] = { +- __ATTR(name, 0444, c2port_show_name, NULL), +- __ATTR(flash_blocks_num, 0444, c2port_show_flash_blocks_num, NULL), +- __ATTR(flash_block_size, 0444, c2port_show_flash_block_size, NULL), +- __ATTR(flash_size, 0444, c2port_show_flash_size, NULL), +- __ATTR(access, 0644, c2port_show_access, c2port_store_access), +- __ATTR(reset, 0200, NULL, c2port_store_reset), +- __ATTR(dev_id, 0444, c2port_show_dev_id, NULL), +- __ATTR(rev_id, 0444, c2port_show_rev_id, NULL), +- +- __ATTR(flash_access, 0644, c2port_show_flash_access, +- c2port_store_flash_access), +- __ATTR(flash_erase, 0200, NULL, c2port_store_flash_erase), +- __ATTR_NULL, ++static struct attribute *c2port_attrs[] = { ++ &dev_attr_name.attr, ++ &dev_attr_flash_blocks_num.attr, ++ &dev_attr_flash_block_size.attr, ++ &dev_attr_flash_size.attr, ++ &dev_attr_access.attr, ++ &dev_attr_reset.attr, ++ &dev_attr_dev_id.attr, ++ &dev_attr_rev_id.attr, ++ &dev_attr_flash_access.attr, ++ &dev_attr_flash_erase.attr, ++ NULL, + }; ++ATTRIBUTE_GROUPS(c2port); + + static struct bin_attribute c2port_bin_attrs[] = { + { +@@ -979,7 +988,7 @@ static int __init c2port_init(void) + printk(KERN_ERR "c2port: failed to allocate class\n"); + return PTR_ERR(c2port_class); + } +- c2port_class->dev_attrs = c2port_attrs; ++ c2port_class->dev_groups = c2port_groups; + c2port_class->dev_bin_attrs = c2port_bin_attrs; + + return 0; +--- a/drivers/pci/pci-sysfs.c ++++ b/drivers/pci/pci-sysfs.c +@@ -131,19 +131,21 @@ static ssize_t pci_bus_show_cpuaffinity( + return ret; + } + +-static inline ssize_t pci_bus_show_cpumaskaffinity(struct device *dev, ++static ssize_t pci_bus_show_cpumaskaffinity(struct device *dev, + struct device_attribute *attr, + char *buf) + { + return pci_bus_show_cpuaffinity(dev, 0, attr, buf); + } ++static DEVICE_ATTR(cpuaffinity, S_IRUGO, pci_bus_show_cpumaskaffinity, NULL); + +-static inline ssize_t pci_bus_show_cpulistaffinity(struct device *dev, ++static ssize_t pci_bus_show_cpulistaffinity(struct device *dev, + struct device_attribute *attr, + char *buf) + { + return pci_bus_show_cpuaffinity(dev, 1, attr, buf); + } ++static DEVICE_ATTR(cpulistaffinity, S_IRUGO, pci_bus_show_cpulistaffinity, NULL); + + /* show resources */ + static ssize_t +@@ -379,6 +381,7 @@ dev_bus_rescan_store(struct device *dev, + } + return count; + } ++static DEVICE_ATTR(rescan, (S_IWUSR|S_IWGRP), NULL, dev_bus_rescan_store); + + #if defined(CONFIG_PM_RUNTIME) && defined(CONFIG_ACPI) + static ssize_t d3cold_allowed_store(struct device *dev, +@@ -514,11 +517,20 @@ struct device_attribute pci_dev_attrs[] + __ATTR_NULL, + }; + +-struct device_attribute pcibus_dev_attrs[] = { +- __ATTR(rescan, (S_IWUSR|S_IWGRP), NULL, dev_bus_rescan_store), +- __ATTR(cpuaffinity, S_IRUGO, pci_bus_show_cpumaskaffinity, NULL), +- __ATTR(cpulistaffinity, S_IRUGO, pci_bus_show_cpulistaffinity, NULL), +- __ATTR_NULL, ++static struct attribute *pcibus_attrs[] = { ++ &dev_attr_rescan.attr, ++ &dev_attr_cpuaffinity.attr, ++ &dev_attr_cpulistaffinity.attr, ++ NULL, ++}; ++ ++static const struct attribute_group pcibus_group = { ++ .attrs = pcibus_attrs, ++}; ++ ++const struct attribute_group *pcibus_groups[] = { ++ &pcibus_group, ++ NULL, + }; + + static ssize_t +--- a/drivers/pci/pci.h ++++ b/drivers/pci/pci.h +@@ -151,7 +151,7 @@ static inline int pci_no_d1d2(struct pci + + } + extern struct device_attribute pci_dev_attrs[]; +-extern struct device_attribute pcibus_dev_attrs[]; ++extern const struct attribute_group *pcibus_groups[]; + extern struct device_type pci_dev_type; + extern struct bus_attribute pci_bus_attrs[]; + +--- a/drivers/pci/probe.c ++++ b/drivers/pci/probe.c +@@ -96,7 +96,7 @@ static void release_pcibus_dev(struct de + static struct class pcibus_class = { + .name = "pci_bus", + .dev_release = &release_pcibus_dev, +- .dev_attrs = pcibus_dev_attrs, ++ .dev_groups = pcibus_groups, + }; + + static int __init pcibus_class_init(void) +--- a/drivers/pps/pps.c ++++ b/drivers/pps/pps.c +@@ -406,7 +406,7 @@ static int __init pps_init(void) + pr_err("failed to allocate class\n"); + return PTR_ERR(pps_class); + } +- pps_class->dev_attrs = pps_attrs; ++ pps_class->dev_groups = pps_groups; + + err = alloc_chrdev_region(&pps_devt, 0, PPS_MAX_SOURCES, "pps"); + if (err < 0) { +--- a/drivers/pps/sysfs.c ++++ b/drivers/pps/sysfs.c +@@ -41,6 +41,7 @@ static ssize_t pps_show_assert(struct de + (long long) pps->assert_tu.sec, pps->assert_tu.nsec, + pps->assert_sequence); + } ++static DEVICE_ATTR(assert, S_IRUGO, pps_show_assert, NULL); + + static ssize_t pps_show_clear(struct device *dev, + struct device_attribute *attr, char *buf) +@@ -54,6 +55,7 @@ static ssize_t pps_show_clear(struct dev + (long long) pps->clear_tu.sec, pps->clear_tu.nsec, + pps->clear_sequence); + } ++static DEVICE_ATTR(clear, S_IRUGO, pps_show_clear, NULL); + + static ssize_t pps_show_mode(struct device *dev, + struct device_attribute *attr, char *buf) +@@ -62,6 +64,7 @@ static ssize_t pps_show_mode(struct devi + + return sprintf(buf, "%4x\n", pps->info.mode); + } ++static DEVICE_ATTR(mode, S_IRUGO, pps_show_mode, NULL); + + static ssize_t pps_show_echo(struct device *dev, + struct device_attribute *attr, char *buf) +@@ -70,6 +73,7 @@ static ssize_t pps_show_echo(struct devi + + return sprintf(buf, "%d\n", !!pps->info.echo); + } ++static DEVICE_ATTR(echo, S_IRUGO, pps_show_echo, NULL); + + static ssize_t pps_show_name(struct device *dev, + struct device_attribute *attr, char *buf) +@@ -78,6 +82,7 @@ static ssize_t pps_show_name(struct devi + + return sprintf(buf, "%s\n", pps->info.name); + } ++static DEVICE_ATTR(name, S_IRUGO, pps_show_name, NULL); + + static ssize_t pps_show_path(struct device *dev, + struct device_attribute *attr, char *buf) +@@ -86,13 +91,23 @@ static ssize_t pps_show_path(struct devi + + return sprintf(buf, "%s\n", pps->info.path); + } ++static DEVICE_ATTR(path, S_IRUGO, pps_show_path, NULL); + +-struct device_attribute pps_attrs[] = { +- __ATTR(assert, S_IRUGO, pps_show_assert, NULL), +- __ATTR(clear, S_IRUGO, pps_show_clear, NULL), +- __ATTR(mode, S_IRUGO, pps_show_mode, NULL), +- __ATTR(echo, S_IRUGO, pps_show_echo, NULL), +- __ATTR(name, S_IRUGO, pps_show_name, NULL), +- __ATTR(path, S_IRUGO, pps_show_path, NULL), +- __ATTR_NULL, ++static struct attribute *pps_attrs[] = { ++ &dev_attr_assert.attr, ++ &dev_attr_clear.attr, ++ &dev_attr_mode.attr, ++ &dev_attr_echo.attr, ++ &dev_attr_name.attr, ++ &dev_attr_path.attr, ++ NULL, ++}; ++ ++static const struct attribute_group pps_group = { ++ .attrs = pps_attrs, ++}; ++ ++const struct attribute_group *pps_groups[] = { ++ &pps_group, ++ NULL, + }; +--- a/drivers/ptp/ptp_clock.c ++++ b/drivers/ptp/ptp_clock.c +@@ -330,7 +330,7 @@ static int __init ptp_init(void) + goto no_region; + } + +- ptp_class->dev_attrs = ptp_dev_attrs; ++ ptp_class->dev_groups = ptp_groups; + pr_info("PTP clock support registered\n"); + return 0; + +--- a/drivers/ptp/ptp_private.h ++++ b/drivers/ptp/ptp_private.h +@@ -84,7 +84,7 @@ uint ptp_poll(struct posix_clock *pc, + * see ptp_sysfs.c + */ + +-extern struct device_attribute ptp_dev_attrs[]; ++extern const struct attribute_group *ptp_groups[]; + + int ptp_cleanup_sysfs(struct ptp_clock *ptp); + +--- a/drivers/ptp/ptp_sysfs.c ++++ b/drivers/ptp/ptp_sysfs.c +@@ -27,36 +27,43 @@ static ssize_t clock_name_show(struct de + struct ptp_clock *ptp = dev_get_drvdata(dev); + return snprintf(page, PAGE_SIZE-1, "%s\n", ptp->info->name); + } ++static DEVICE_ATTR(clock_name, 0444, clock_name_show, NULL); + +-#define PTP_SHOW_INT(name) \ +-static ssize_t name##_show(struct device *dev, \ ++#define PTP_SHOW_INT(name, var) \ ++static ssize_t var##_show(struct device *dev, \ + struct device_attribute *attr, char *page) \ + { \ + struct ptp_clock *ptp = dev_get_drvdata(dev); \ +- return snprintf(page, PAGE_SIZE-1, "%d\n", ptp->info->name); \ +-} ++ return snprintf(page, PAGE_SIZE-1, "%d\n", ptp->info->var); \ ++} \ ++static DEVICE_ATTR(name, 0444, var##_show, NULL); + +-PTP_SHOW_INT(max_adj); +-PTP_SHOW_INT(n_alarm); +-PTP_SHOW_INT(n_ext_ts); +-PTP_SHOW_INT(n_per_out); +-PTP_SHOW_INT(pps); +- +-#define PTP_RO_ATTR(_var, _name) { \ +- .attr = { .name = __stringify(_name), .mode = 0444 }, \ +- .show = _var##_show, \ +-} ++PTP_SHOW_INT(max_adjustment, max_adj); ++PTP_SHOW_INT(n_alarms, n_alarm); ++PTP_SHOW_INT(n_external_timestamps, n_ext_ts); ++PTP_SHOW_INT(n_periodic_outputs, n_per_out); ++PTP_SHOW_INT(pps_available, pps); ++ ++static struct attribute *ptp_attrs[] = { ++ &dev_attr_clock_name.attr, ++ &dev_attr_max_adjustment.attr, ++ &dev_attr_n_alarms.attr, ++ &dev_attr_n_external_timestamps.attr, ++ &dev_attr_n_periodic_outputs.attr, ++ &dev_attr_pps_available.attr, ++ NULL, ++}; + +-struct device_attribute ptp_dev_attrs[] = { +- PTP_RO_ATTR(clock_name, clock_name), +- PTP_RO_ATTR(max_adj, max_adjustment), +- PTP_RO_ATTR(n_alarm, n_alarms), +- PTP_RO_ATTR(n_ext_ts, n_external_timestamps), +- PTP_RO_ATTR(n_per_out, n_periodic_outputs), +- PTP_RO_ATTR(pps, pps_available), +- __ATTR_NULL, ++static const struct attribute_group ptp_group = { ++ .attrs = ptp_attrs, + }; + ++const struct attribute_group *ptp_groups[] = { ++ &ptp_group, ++ NULL, ++}; ++ ++ + static ssize_t extts_enable_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +--- a/drivers/rtc/rtc-sysfs.c ++++ b/drivers/rtc/rtc-sysfs.c +@@ -30,6 +30,7 @@ rtc_sysfs_show_name(struct device *dev, + { + return sprintf(buf, "%s\n", to_rtc_device(dev)->name); + } ++static DEVICE_ATTR(name, S_IRUGO, rtc_sysfs_show_name, NULL); + + static ssize_t + rtc_sysfs_show_date(struct device *dev, struct device_attribute *attr, +@@ -46,6 +47,7 @@ rtc_sysfs_show_date(struct device *dev, + + return retval; + } ++static DEVICE_ATTR(date, S_IRUGO, rtc_sysfs_show_date, NULL); + + static ssize_t + rtc_sysfs_show_time(struct device *dev, struct device_attribute *attr, +@@ -62,6 +64,7 @@ rtc_sysfs_show_time(struct device *dev, + + return retval; + } ++static DEVICE_ATTR(time, S_IRUGO, rtc_sysfs_show_time, NULL); + + static ssize_t + rtc_sysfs_show_since_epoch(struct device *dev, struct device_attribute *attr, +@@ -79,6 +82,7 @@ rtc_sysfs_show_since_epoch(struct device + + return retval; + } ++static DEVICE_ATTR(since_epoch, S_IRUGO, rtc_sysfs_show_since_epoch, NULL); + + static ssize_t + rtc_sysfs_show_max_user_freq(struct device *dev, struct device_attribute *attr, +@@ -101,6 +105,8 @@ rtc_sysfs_set_max_user_freq(struct devic + + return n; + } ++static DEVICE_ATTR(max_user_freq, S_IRUGO | S_IWUSR, ++ rtc_sysfs_show_max_user_freq, rtc_sysfs_set_max_user_freq); + + /** + * rtc_sysfs_show_hctosys - indicate if the given RTC set the system time +@@ -121,17 +127,18 @@ rtc_sysfs_show_hctosys(struct device *de + #endif + return sprintf(buf, "0\n"); + } ++static DEVICE_ATTR(hctosys, S_IRUGO, rtc_sysfs_show_hctosys, NULL); + +-static struct device_attribute rtc_attrs[] = { +- __ATTR(name, S_IRUGO, rtc_sysfs_show_name, NULL), +- __ATTR(date, S_IRUGO, rtc_sysfs_show_date, NULL), +- __ATTR(time, S_IRUGO, rtc_sysfs_show_time, NULL), +- __ATTR(since_epoch, S_IRUGO, rtc_sysfs_show_since_epoch, NULL), +- __ATTR(max_user_freq, S_IRUGO | S_IWUSR, rtc_sysfs_show_max_user_freq, +- rtc_sysfs_set_max_user_freq), +- __ATTR(hctosys, S_IRUGO, rtc_sysfs_show_hctosys, NULL), +- { }, ++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 + rtc_sysfs_show_wakealarm(struct device *dev, struct device_attribute *attr, +@@ -261,5 +268,5 @@ void rtc_sysfs_del_device(struct rtc_dev + + void __init rtc_sysfs_init(struct class *rtc_class) + { +- rtc_class->dev_attrs = rtc_attrs; ++ rtc_class->dev_groups = rtc_groups; + } +--- a/drivers/scsi/sd.c ++++ b/drivers/scsi/sd.c +@@ -199,6 +199,16 @@ sd_store_cache_type(struct device *dev, + } + + static ssize_t ++sd_show_manage_start_stop(struct device *dev, struct device_attribute *attr, ++ char *buf) ++{ ++ struct scsi_disk *sdkp = to_scsi_disk(dev); ++ struct scsi_device *sdp = sdkp->device; ++ ++ return snprintf(buf, 20, "%u\n", sdp->manage_start_stop); ++} ++ ++static ssize_t + sd_store_manage_start_stop(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count) + { +@@ -212,6 +222,17 @@ sd_store_manage_start_stop(struct device + + return count; + } ++static DEVICE_ATTR(manage_start_stop, S_IRUGO|S_IWUSR, ++ sd_show_manage_start_stop, sd_store_manage_start_stop); ++ ++static ssize_t ++sd_show_allow_restart(struct device *dev, struct device_attribute *attr, ++ char *buf) ++{ ++ struct scsi_disk *sdkp = to_scsi_disk(dev); ++ ++ return snprintf(buf, 40, "%d\n", sdkp->device->allow_restart); ++} + + static ssize_t + sd_store_allow_restart(struct device *dev, struct device_attribute *attr, +@@ -230,6 +251,8 @@ sd_store_allow_restart(struct device *de + + return count; + } ++static DEVICE_ATTR(allow_restart, S_IRUGO|S_IWUSR, sd_show_allow_restart, ++ sd_store_allow_restart); + + static ssize_t + sd_show_cache_type(struct device *dev, struct device_attribute *attr, +@@ -240,6 +263,8 @@ sd_show_cache_type(struct device *dev, s + + return snprintf(buf, 40, "%s\n", sd_cache_types[ct]); + } ++static DEVICE_ATTR(cache_type, S_IRUGO|S_IWUSR, sd_show_cache_type, ++ sd_store_cache_type); + + static ssize_t + sd_show_fua(struct device *dev, struct device_attribute *attr, char *buf) +@@ -248,25 +273,7 @@ sd_show_fua(struct device *dev, struct d + + return snprintf(buf, 20, "%u\n", sdkp->DPOFUA); + } +- +-static ssize_t +-sd_show_manage_start_stop(struct device *dev, struct device_attribute *attr, +- char *buf) +-{ +- struct scsi_disk *sdkp = to_scsi_disk(dev); +- struct scsi_device *sdp = sdkp->device; +- +- return snprintf(buf, 20, "%u\n", sdp->manage_start_stop); +-} +- +-static ssize_t +-sd_show_allow_restart(struct device *dev, struct device_attribute *attr, +- char *buf) +-{ +- struct scsi_disk *sdkp = to_scsi_disk(dev); +- +- return snprintf(buf, 40, "%d\n", sdkp->device->allow_restart); +-} ++static DEVICE_ATTR(FUA, S_IRUGO, sd_show_fua, NULL); + + static ssize_t + sd_show_protection_type(struct device *dev, struct device_attribute *attr, +@@ -298,6 +305,8 @@ sd_store_protection_type(struct device * + + return count; + } ++static DEVICE_ATTR(protection_type, S_IRUGO|S_IWUSR, sd_show_protection_type, ++ sd_store_protection_type); + + static ssize_t + sd_show_protection_mode(struct device *dev, struct device_attribute *attr, +@@ -320,6 +329,7 @@ sd_show_protection_mode(struct device *d + + return snprintf(buf, 20, "%s%u\n", dix ? "dix" : "dif", dif); + } ++static DEVICE_ATTR(protection_mode, S_IRUGO, sd_show_protection_mode, NULL); + + static ssize_t + sd_show_app_tag_own(struct device *dev, struct device_attribute *attr, +@@ -329,6 +339,7 @@ sd_show_app_tag_own(struct device *dev, + + return snprintf(buf, 20, "%u\n", sdkp->ATO); + } ++static DEVICE_ATTR(app_tag_own, S_IRUGO, sd_show_app_tag_own, NULL); + + static ssize_t + sd_show_thin_provisioning(struct device *dev, struct device_attribute *attr, +@@ -338,6 +349,7 @@ sd_show_thin_provisioning(struct device + + return snprintf(buf, 20, "%u\n", sdkp->lbpme); + } ++static DEVICE_ATTR(thin_provisioning, S_IRUGO, sd_show_thin_provisioning, NULL); + + static const char *lbp_mode[] = { + [SD_LBP_FULL] = "full", +@@ -385,6 +397,8 @@ sd_store_provisioning_mode(struct device + + return count; + } ++static DEVICE_ATTR(provisioning_mode, S_IRUGO|S_IWUSR, ++ sd_show_provisioning_mode, sd_store_provisioning_mode); + + static ssize_t + sd_show_max_medium_access_timeouts(struct device *dev, +@@ -410,6 +424,9 @@ sd_store_max_medium_access_timeouts(stru + + return err ? err : count; + } ++static DEVICE_ATTR(max_medium_access_timeouts, S_IRUGO|S_IWUSR, ++ sd_show_max_medium_access_timeouts, ++ sd_store_max_medium_access_timeouts); + + static ssize_t + sd_show_write_same_blocks(struct device *dev, struct device_attribute *attr, +@@ -451,35 +468,30 @@ sd_store_write_same_blocks(struct device + + return count; + } ++static DEVICE_ATTR(max_write_same_blocks, S_IRUGO|S_IWUSR, ++ sd_show_write_same_blocks, sd_store_write_same_blocks); + +-static struct device_attribute sd_disk_attrs[] = { +- __ATTR(cache_type, S_IRUGO|S_IWUSR, sd_show_cache_type, +- sd_store_cache_type), +- __ATTR(FUA, S_IRUGO, sd_show_fua, NULL), +- __ATTR(allow_restart, S_IRUGO|S_IWUSR, sd_show_allow_restart, +- sd_store_allow_restart), +- __ATTR(manage_start_stop, S_IRUGO|S_IWUSR, sd_show_manage_start_stop, +- sd_store_manage_start_stop), +- __ATTR(protection_type, S_IRUGO|S_IWUSR, sd_show_protection_type, +- sd_store_protection_type), +- __ATTR(protection_mode, S_IRUGO, sd_show_protection_mode, NULL), +- __ATTR(app_tag_own, S_IRUGO, sd_show_app_tag_own, NULL), +- __ATTR(thin_provisioning, S_IRUGO, sd_show_thin_provisioning, NULL), +- __ATTR(provisioning_mode, S_IRUGO|S_IWUSR, sd_show_provisioning_mode, +- sd_store_provisioning_mode), +- __ATTR(max_write_same_blocks, S_IRUGO|S_IWUSR, +- sd_show_write_same_blocks, sd_store_write_same_blocks), +- __ATTR(max_medium_access_timeouts, S_IRUGO|S_IWUSR, +- sd_show_max_medium_access_timeouts, +- sd_store_max_medium_access_timeouts), +- __ATTR_NULL, ++static struct attribute *sd_disk_attrs[] = { ++ &dev_attr_cache_type.attr, ++ &dev_attr_FUA.attr, ++ &dev_attr_allow_restart.attr, ++ &dev_attr_manage_start_stop.attr, ++ &dev_attr_protection_type.attr, ++ &dev_attr_protection_mode.attr, ++ &dev_attr_app_tag_own.attr, ++ &dev_attr_thin_provisioning.attr, ++ &dev_attr_provisioning_mode.attr, ++ &dev_attr_max_write_same_blocks.attr, ++ &dev_attr_max_medium_access_timeouts.attr, ++ NULL, + }; ++ATTRIBUTE_GROUPS(sd_disk); + + static struct class sd_disk_class = { + .name = "scsi_disk", + .owner = THIS_MODULE, + .dev_release = scsi_disk_release, +- .dev_attrs = sd_disk_attrs, ++ .dev_groups = sd_disk_groups, + }; + + static const struct dev_pm_ops sd_pm_ops = { +--- a/drivers/staging/comedi/comedi_fops.c ++++ b/drivers/staging/comedi/comedi_fops.c +@@ -314,6 +314,8 @@ static ssize_t store_max_read_buffer_kb( + + return err ? err : count; + } ++static DEVICE_ATTR(max_read_buffer_kb, S_IRUGO | S_IWUSR, ++ show_max_read_buffer_kb, store_max_read_buffer_kb); + + static ssize_t show_read_buffer_kb(struct device *csdev, + struct device_attribute *attr, char *buf) +@@ -367,6 +369,8 @@ static ssize_t store_read_buffer_kb(stru + + return err ? err : count; + } ++static DEVICE_ATTR(read_buffer_kb, S_IRUGO | S_IWUSR | S_IWGRP, ++ show_read_buffer_kb, store_read_buffer_kb); + + static ssize_t show_max_write_buffer_kb(struct device *csdev, + struct device_attribute *attr, +@@ -421,6 +425,8 @@ static ssize_t store_max_write_buffer_kb + + return err ? err : count; + } ++static DEVICE_ATTR(max_write_buffer_kb, S_IRUGO | S_IWUSR, ++ show_max_write_buffer_kb, store_max_write_buffer_kb); + + static ssize_t show_write_buffer_kb(struct device *csdev, + struct device_attribute *attr, char *buf) +@@ -474,18 +480,17 @@ static ssize_t store_write_buffer_kb(str + + return err ? err : count; + } ++static DEVICE_ATTR(write_buffer_kb, S_IRUGO | S_IWUSR | S_IWGRP, ++ show_write_buffer_kb, store_write_buffer_kb); + +-static struct device_attribute comedi_dev_attrs[] = { +- __ATTR(max_read_buffer_kb, S_IRUGO | S_IWUSR, +- show_max_read_buffer_kb, store_max_read_buffer_kb), +- __ATTR(read_buffer_kb, S_IRUGO | S_IWUSR | S_IWGRP, +- show_read_buffer_kb, store_read_buffer_kb), +- __ATTR(max_write_buffer_kb, S_IRUGO | S_IWUSR, +- show_max_write_buffer_kb, store_max_write_buffer_kb), +- __ATTR(write_buffer_kb, S_IRUGO | S_IWUSR | S_IWGRP, +- show_write_buffer_kb, store_write_buffer_kb), +- __ATTR_NULL ++static struct attribute *comedi_dev_attrs[] = { ++ &dev_attr_max_read_buffer_kb.attr, ++ &dev_attr_read_buffer_kb.attr, ++ &dev_attr_max_write_buffer_kb.attr, ++ &dev_attr_write_buffer_kb.attr, ++ NULL, + }; ++ATTRIBUTE_GROUPS(comedi_dev); + + static void comedi_set_subdevice_runflags(struct comedi_subdevice *s, + unsigned mask, unsigned bits) +@@ -2554,7 +2559,7 @@ static int __init comedi_init(void) + return PTR_ERR(comedi_class); + } + +- comedi_class->dev_attrs = comedi_dev_attrs; ++ comedi_class->dev_groups = comedi_dev_groups; + + /* XXX requires /proc interface */ + comedi_proc_init(); +--- a/drivers/uio/uio.c ++++ b/drivers/uio/uio.c +@@ -230,6 +230,7 @@ static ssize_t show_name(struct device * + struct uio_device *idev = dev_get_drvdata(dev); + return sprintf(buf, "%s\n", idev->info->name); + } ++static DEVICE_ATTR(name, S_IRUGO, show_name, NULL); + + static ssize_t show_version(struct device *dev, + struct device_attribute *attr, char *buf) +@@ -237,6 +238,7 @@ static ssize_t show_version(struct devic + struct uio_device *idev = dev_get_drvdata(dev); + return sprintf(buf, "%s\n", idev->info->version); + } ++static DEVICE_ATTR(version, S_IRUGO, show_version, NULL); + + static ssize_t show_event(struct device *dev, + struct device_attribute *attr, char *buf) +@@ -244,18 +246,20 @@ static ssize_t show_event(struct device + struct uio_device *idev = dev_get_drvdata(dev); + return sprintf(buf, "%u\n", (unsigned int)atomic_read(&idev->event)); + } ++static DEVICE_ATTR(event, S_IRUGO, show_event, NULL); + +-static struct device_attribute uio_class_attributes[] = { +- __ATTR(name, S_IRUGO, show_name, NULL), +- __ATTR(version, S_IRUGO, show_version, NULL), +- __ATTR(event, S_IRUGO, show_event, NULL), +- {} ++static struct attribute *uio_attrs[] = { ++ &dev_attr_name.attr, ++ &dev_attr_version.attr, ++ &dev_attr_event.attr, ++ NULL, + }; ++ATTRIBUTE_GROUPS(uio); + + /* UIO class infrastructure */ + static struct class uio_class = { + .name = "uio", +- .dev_attrs = uio_class_attributes, ++ .dev_groups = uio_groups, + }; + + /* +--- a/drivers/video/backlight/backlight.c ++++ b/drivers/video/backlight/backlight.c +@@ -136,6 +136,7 @@ static ssize_t backlight_store_power(str + + return rc; + } ++static DEVICE_ATTR(bl_power, 0644, backlight_show_power, backlight_store_power); + + static ssize_t backlight_show_brightness(struct device *dev, + struct device_attribute *attr, char *buf) +@@ -175,6 +176,8 @@ static ssize_t backlight_store_brightnes + + return rc; + } ++static DEVICE_ATTR(brightness, 0644, backlight_show_brightness, ++ backlight_store_brightness); + + static ssize_t backlight_show_type(struct device *dev, + struct device_attribute *attr, char *buf) +@@ -183,6 +186,7 @@ static ssize_t backlight_show_type(struc + + return sprintf(buf, "%s\n", backlight_types[bd->props.type]); + } ++static DEVICE_ATTR(type, 0444, backlight_show_type, NULL); + + static ssize_t backlight_show_max_brightness(struct device *dev, + struct device_attribute *attr, char *buf) +@@ -191,6 +195,7 @@ static ssize_t backlight_show_max_bright + + return sprintf(buf, "%d\n", bd->props.max_brightness); + } ++static DEVICE_ATTR(max_brightness, 0444, backlight_show_max_brightness, NULL); + + static ssize_t backlight_show_actual_brightness(struct device *dev, + struct device_attribute *attr, char *buf) +@@ -205,6 +210,8 @@ static ssize_t backlight_show_actual_bri + + return rc; + } ++static DEVICE_ATTR(actual_brightness, 0444, backlight_show_actual_brightness, ++ NULL); + + static struct class *backlight_class; + +@@ -247,16 +254,15 @@ static void bl_device_release(struct dev + kfree(bd); + } + +-static struct device_attribute bl_device_attributes[] = { +- __ATTR(bl_power, 0644, backlight_show_power, backlight_store_power), +- __ATTR(brightness, 0644, backlight_show_brightness, +- backlight_store_brightness), +- __ATTR(actual_brightness, 0444, backlight_show_actual_brightness, +- NULL), +- __ATTR(max_brightness, 0444, backlight_show_max_brightness, NULL), +- __ATTR(type, 0444, backlight_show_type, NULL), +- __ATTR_NULL, ++static struct attribute *bl_device_attrs[] = { ++ &dev_attr_bl_power.attr, ++ &dev_attr_brightness.attr, ++ &dev_attr_actual_brightness.attr, ++ &dev_attr_max_brightness.attr, ++ &dev_attr_type.attr, ++ NULL, + }; ++ATTRIBUTE_GROUPS(bl_device); + + /** + * backlight_force_update - tell the backlight subsystem that hardware state +@@ -493,7 +499,7 @@ static int __init backlight_class_init(v + return PTR_ERR(backlight_class); + } + +- backlight_class->dev_attrs = bl_device_attributes; ++ backlight_class->dev_groups = bl_device_groups; + backlight_class->pm = &backlight_class_dev_pm_ops; + return 0; + } +--- a/drivers/video/output.c ++++ b/drivers/video/output.c +@@ -62,6 +62,8 @@ static ssize_t video_output_store_state( + } + return count; + } ++static DEVICE_ATTR(state, 0644, video_output_show_state, ++ video_output_store_state); + + static void video_output_release(struct device *dev) + { +@@ -69,16 +71,16 @@ static void video_output_release(struct + kfree(od); + } + +-static struct device_attribute video_output_attributes[] = { +- __ATTR(state, 0644, video_output_show_state, video_output_store_state), +- __ATTR_NULL, ++static struct attribute *video_output_attrs[] = { ++ &dev_attr_state.attr, ++ NULL, + }; +- ++ATTRIBUTE_GROUPS(video_output); + + static struct class video_output_class = { + .name = "video_output", + .dev_release = video_output_release, +- .dev_attrs = video_output_attributes, ++ .dev_groups = video_output_groups, + }; + + struct output_device *video_output_register(const char *name, +--- a/include/linux/device.h ++++ b/include/linux/device.h +@@ -342,7 +342,8 @@ struct class { + struct module *owner; + + struct class_attribute *class_attrs; +- struct device_attribute *dev_attrs; ++ const struct attribute_group **dev_groups; ++// struct device_attribute *dev_attrs; + struct bin_attribute *dev_bin_attrs; + struct kobject *dev_kobj; + +--- a/include/linux/pps_kernel.h ++++ b/include/linux/pps_kernel.h +@@ -80,7 +80,7 @@ struct pps_device { + * Global variables + */ + +-extern struct device_attribute pps_attrs[]; ++extern const struct attribute_group *pps_groups[]; + + /* + * Internal functions. +--- a/mm/backing-dev.c ++++ b/mm/backing-dev.c +@@ -183,6 +183,7 @@ static ssize_t name##_show(struct device + } + + BDI_SHOW(read_ahead_kb, K(bdi->ra_pages)) ++static DEVICE_ATTR(read_ahead_kb, 0644, read_ahead_kb_show, read_ahead_kb_store); + + static ssize_t min_ratio_store(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count) +@@ -201,7 +202,8 @@ static ssize_t min_ratio_store(struct de + + return ret; + } +-BDI_SHOW(min_ratio, bdi->min_ratio) ++BDI_SHOW(min_ratio, bdi->min_ratio); ++static DEVICE_ATTR(min_ratio, 0644, min_ratio_show, min_ratio_store); + + static ssize_t max_ratio_store(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count) +@@ -221,6 +223,7 @@ static ssize_t max_ratio_store(struct de + return ret; + } + BDI_SHOW(max_ratio, bdi->max_ratio) ++static DEVICE_ATTR(max_ratio, 0644, max_ratio_show, max_ratio_store); + + static ssize_t stable_pages_required_show(struct device *dev, + struct device_attribute *attr, +@@ -231,14 +234,17 @@ static ssize_t stable_pages_required_sho + return snprintf(page, PAGE_SIZE-1, "%d\n", + bdi_cap_stable_pages_required(bdi) ? 1 : 0); + } ++static DEVICE_ATTR(stable_pages_required, 0444, stable_pages_required_show, NULL); + +-static struct device_attribute bdi_dev_attrs[] = { +- __ATTR_RW(read_ahead_kb), +- __ATTR_RW(min_ratio), +- __ATTR_RW(max_ratio), +- __ATTR_RO(stable_pages_required), +- __ATTR_NULL, ++ ++static struct attribute *bdi_dev_attrs[] = { ++ &dev_attr_read_ahead_kb.attr, ++ &dev_attr_min_ratio.attr, ++ &dev_attr_max_ratio.attr, ++ &dev_attr_stable_pages_required.attr, ++ NULL, + }; ++ATTRIBUTE_GROUPS(bdi_dev); + + static __init int bdi_class_init(void) + { +@@ -246,7 +252,7 @@ static __init int bdi_class_init(void) + if (IS_ERR(bdi_class)) + return PTR_ERR(bdi_class); + +- bdi_class->dev_attrs = bdi_dev_attrs; ++ bdi_class->dev_groups = bdi_dev_groups; + bdi_debug_init(); + return 0; + } +--- a/net/core/net-sysfs.c ++++ b/net/core/net-sysfs.c +@@ -64,8 +64,15 @@ static ssize_t show_##field(struct devic + struct device_attribute *attr, char *buf) \ + { \ + return netdev_show(dev, attr, buf, format_##field); \ +-} ++} \ + ++#define NETDEVICE_SHOW_RO(field, format_string) \ ++NETDEVICE_SHOW(field, format_string); \ ++static DEVICE_ATTR(field, S_IRUGO, show_##field, NULL) ++ ++#define NETDEVICE_SHOW_RW(field, format_string) \ ++NETDEVICE_SHOW(field, format_string); \ ++static DEVICE_ATTR(field, S_IRUGO | S_IWUSR, show_##field, store_##field) + + /* use same locking and permission rules as SIF* ioctl's */ + static ssize_t netdev_store(struct device *dev, struct device_attribute *attr, +@@ -96,13 +103,13 @@ static ssize_t netdev_store(struct devic + return ret; + } + +-NETDEVICE_SHOW(dev_id, fmt_hex); +-NETDEVICE_SHOW(addr_assign_type, fmt_dec); +-NETDEVICE_SHOW(addr_len, fmt_dec); +-NETDEVICE_SHOW(iflink, fmt_dec); +-NETDEVICE_SHOW(ifindex, fmt_dec); +-NETDEVICE_SHOW(type, fmt_dec); +-NETDEVICE_SHOW(link_mode, fmt_dec); ++NETDEVICE_SHOW_RO(dev_id, fmt_hex); ++NETDEVICE_SHOW_RO(addr_assign_type, fmt_dec); ++NETDEVICE_SHOW_RO(addr_len, fmt_dec); ++NETDEVICE_SHOW_RO(iflink, fmt_dec); ++NETDEVICE_SHOW_RO(ifindex, fmt_dec); ++NETDEVICE_SHOW_RO(type, fmt_dec); ++NETDEVICE_SHOW_RO(link_mode, fmt_dec); + + /* use same locking rules as GIFHWADDR ioctl's */ + static ssize_t show_address(struct device *dev, struct device_attribute *attr, +@@ -117,6 +124,7 @@ static ssize_t show_address(struct devic + read_unlock(&dev_base_lock); + return ret; + } ++static DEVICE_ATTR(address, S_IRUGO, show_address, NULL); + + static ssize_t show_broadcast(struct device *dev, + struct device_attribute *attr, char *buf) +@@ -126,6 +134,7 @@ static ssize_t show_broadcast(struct dev + return sysfs_format_mac(buf, net->broadcast, net->addr_len); + return -EINVAL; + } ++static DEVICE_ATTR(broadcast, S_IRUGO, show_broadcast, NULL); + + static int change_carrier(struct net_device *net, unsigned long new_carrier) + { +@@ -149,6 +158,7 @@ static ssize_t show_carrier(struct devic + } + return -EINVAL; + } ++static DEVICE_ATTR(carrier, S_IRUGO | S_IWUSR, show_carrier, store_carrier); + + static ssize_t show_speed(struct device *dev, + struct device_attribute *attr, char *buf) +@@ -167,6 +177,7 @@ static ssize_t show_speed(struct device + rtnl_unlock(); + return ret; + } ++static DEVICE_ATTR(speed, S_IRUGO, show_speed, NULL); + + static ssize_t show_duplex(struct device *dev, + struct device_attribute *attr, char *buf) +@@ -198,6 +209,7 @@ static ssize_t show_duplex(struct device + rtnl_unlock(); + return ret; + } ++static DEVICE_ATTR(duplex, S_IRUGO, show_duplex, NULL); + + static ssize_t show_dormant(struct device *dev, + struct device_attribute *attr, char *buf) +@@ -209,6 +221,7 @@ static ssize_t show_dormant(struct devic + + return -EINVAL; + } ++static DEVICE_ATTR(dormant, S_IRUGO, show_dormant, NULL); + + static const char *const operstates[] = { + "unknown", +@@ -237,9 +250,9 @@ static ssize_t show_operstate(struct dev + + return sprintf(buf, "%s\n", operstates[operstate]); + } ++static DEVICE_ATTR(operstate, S_IRUGO, show_operstate, NULL); + + /* read-write attributes */ +-NETDEVICE_SHOW(mtu, fmt_dec); + + static int change_mtu(struct net_device *net, unsigned long new_mtu) + { +@@ -251,8 +264,7 @@ static ssize_t store_mtu(struct device * + { + return netdev_store(dev, attr, buf, len, change_mtu); + } +- +-NETDEVICE_SHOW(flags, fmt_hex); ++NETDEVICE_SHOW_RW(mtu, fmt_dec); + + static int change_flags(struct net_device *net, unsigned long new_flags) + { +@@ -264,8 +276,7 @@ static ssize_t store_flags(struct device + { + return netdev_store(dev, attr, buf, len, change_flags); + } +- +-NETDEVICE_SHOW(tx_queue_len, fmt_ulong); ++NETDEVICE_SHOW_RW(flags, fmt_hex); + + static int change_tx_queue_len(struct net_device *net, unsigned long new_len) + { +@@ -282,6 +293,7 @@ static ssize_t store_tx_queue_len(struct + + return netdev_store(dev, attr, buf, len, change_tx_queue_len); + } ++NETDEVICE_SHOW_RW(tx_queue_len, fmt_ulong); + + static ssize_t store_ifalias(struct device *dev, struct device_attribute *attr, + const char *buf, size_t len) +@@ -319,8 +331,7 @@ static ssize_t show_ifalias(struct devic + rtnl_unlock(); + return ret; + } +- +-NETDEVICE_SHOW(group, fmt_dec); ++static DEVICE_ATTR(ifalias, S_IRUGO | S_IWUSR, show_ifalias, store_ifalias); + + static int change_group(struct net_device *net, unsigned long new_group) + { +@@ -333,30 +344,32 @@ static ssize_t store_group(struct device + { + return netdev_store(dev, attr, buf, len, change_group); + } ++NETDEVICE_SHOW(group, fmt_dec); ++static DEVICE_ATTR(netdev_group, S_IRUGO | S_IWUSR, show_group, store_group); + +-static struct device_attribute net_class_attributes[] = { +- __ATTR(addr_assign_type, S_IRUGO, show_addr_assign_type, NULL), +- __ATTR(addr_len, S_IRUGO, show_addr_len, NULL), +- __ATTR(dev_id, S_IRUGO, show_dev_id, NULL), +- __ATTR(ifalias, S_IRUGO | S_IWUSR, show_ifalias, store_ifalias), +- __ATTR(iflink, S_IRUGO, show_iflink, NULL), +- __ATTR(ifindex, S_IRUGO, show_ifindex, NULL), +- __ATTR(type, S_IRUGO, show_type, NULL), +- __ATTR(link_mode, S_IRUGO, show_link_mode, NULL), +- __ATTR(address, S_IRUGO, show_address, NULL), +- __ATTR(broadcast, S_IRUGO, show_broadcast, NULL), +- __ATTR(carrier, S_IRUGO | S_IWUSR, show_carrier, store_carrier), +- __ATTR(speed, S_IRUGO, show_speed, NULL), +- __ATTR(duplex, S_IRUGO, show_duplex, NULL), +- __ATTR(dormant, S_IRUGO, show_dormant, NULL), +- __ATTR(operstate, S_IRUGO, show_operstate, NULL), +- __ATTR(mtu, S_IRUGO | S_IWUSR, show_mtu, store_mtu), +- __ATTR(flags, S_IRUGO | S_IWUSR, show_flags, store_flags), +- __ATTR(tx_queue_len, S_IRUGO | S_IWUSR, show_tx_queue_len, +- store_tx_queue_len), +- __ATTR(netdev_group, S_IRUGO | S_IWUSR, show_group, store_group), +- {} ++static struct attribute *net_class_attrs[] = { ++ &dev_attr_netdev_group.attr, ++ &dev_attr_type.attr, ++ &dev_attr_dev_id.attr, ++ &dev_attr_iflink.attr, ++ &dev_attr_ifindex.attr, ++ &dev_attr_addr_assign_type.attr, ++ &dev_attr_addr_len.attr, ++ &dev_attr_link_mode.attr, ++ &dev_attr_address.attr, ++ &dev_attr_broadcast.attr, ++ &dev_attr_speed.attr, ++ &dev_attr_duplex.attr, ++ &dev_attr_dormant.attr, ++ &dev_attr_operstate.attr, ++ &dev_attr_ifalias.attr, ++ &dev_attr_carrier.attr, ++ &dev_attr_mtu.attr, ++ &dev_attr_flags.attr, ++ &dev_attr_tx_queue_len.attr, ++ NULL, + }; ++ATTRIBUTE_GROUPS(net_class); + + /* Show a given an attribute in the statistics group */ + static ssize_t netstat_show(const struct device *d, +@@ -457,6 +470,9 @@ static struct attribute_group wireless_g + .attrs = wireless_attrs, + }; + #endif ++ ++#else /* CONFIG_SYSFS */ ++#define net_class_groups NULL + #endif /* CONFIG_SYSFS */ + + #ifdef CONFIG_RPS +@@ -1229,9 +1245,7 @@ static const void *net_namespace(struct + static struct class net_class = { + .name = "net", + .dev_release = netdev_release, +-#ifdef CONFIG_SYSFS +- .dev_attrs = net_class_attributes, +-#endif /* CONFIG_SYSFS */ ++ .dev_groups = net_class_groups, + .dev_uevent = netdev_uevent, + .ns_type = &net_ns_type_operations, + .namespace = net_namespace, +--- a/net/rfkill/core.c ++++ b/net/rfkill/core.c +@@ -584,6 +584,7 @@ static ssize_t rfkill_name_show(struct d + + return sprintf(buf, "%s\n", rfkill->name); + } ++static DEVICE_ATTR(name, S_IRUGO, rfkill_name_show, NULL); + + static const char *rfkill_get_type_str(enum rfkill_type type) + { +@@ -619,6 +620,7 @@ static ssize_t rfkill_type_show(struct d + + return sprintf(buf, "%s\n", rfkill_get_type_str(rfkill->type)); + } ++static DEVICE_ATTR(type, S_IRUGO, rfkill_type_show, NULL); + + static ssize_t rfkill_idx_show(struct device *dev, + struct device_attribute *attr, +@@ -628,6 +630,7 @@ static ssize_t rfkill_idx_show(struct de + + return sprintf(buf, "%d\n", rfkill->idx); + } ++static DEVICE_ATTR(index, S_IRUGO, rfkill_idx_show, NULL); + + static ssize_t rfkill_persistent_show(struct device *dev, + struct device_attribute *attr, +@@ -637,6 +640,7 @@ static ssize_t rfkill_persistent_show(st + + return sprintf(buf, "%d\n", rfkill->persistent); + } ++static DEVICE_ATTR(persistent, S_IRUGO, rfkill_persistent_show, NULL); + + static ssize_t rfkill_hard_show(struct device *dev, + struct device_attribute *attr, +@@ -646,6 +650,7 @@ static ssize_t rfkill_hard_show(struct d + + return sprintf(buf, "%d\n", (rfkill->state & RFKILL_BLOCK_HW) ? 1 : 0 ); + } ++static DEVICE_ATTR(hard, S_IRUGO, rfkill_hard_show, NULL); + + static ssize_t rfkill_soft_show(struct device *dev, + struct device_attribute *attr, +@@ -680,6 +685,7 @@ static ssize_t rfkill_soft_store(struct + + return count; + } ++static DEVICE_ATTR(soft, S_IRUGO|S_IWUSR, rfkill_soft_show, rfkill_soft_store); + + static u8 user_state_from_blocked(unsigned long state) + { +@@ -725,6 +731,7 @@ static ssize_t rfkill_state_store(struct + + return count; + } ++static DEVICE_ATTR(state, S_IRUGO|S_IWUSR, rfkill_state_show, rfkill_state_store); + + static ssize_t rfkill_claim_show(struct device *dev, + struct device_attribute *attr, +@@ -732,25 +739,20 @@ static ssize_t rfkill_claim_show(struct + { + return sprintf(buf, "%d\n", 0); + } ++static DEVICE_ATTR(claim, S_IRUGO, rfkill_claim_show, NULL); + +-static ssize_t rfkill_claim_store(struct device *dev, +- struct device_attribute *attr, +- const char *buf, size_t count) +-{ +- return -EOPNOTSUPP; +-} +- +-static struct device_attribute rfkill_dev_attrs[] = { +- __ATTR(name, S_IRUGO, rfkill_name_show, NULL), +- __ATTR(type, S_IRUGO, rfkill_type_show, NULL), +- __ATTR(index, S_IRUGO, rfkill_idx_show, NULL), +- __ATTR(persistent, S_IRUGO, rfkill_persistent_show, NULL), +- __ATTR(state, S_IRUGO|S_IWUSR, rfkill_state_show, rfkill_state_store), +- __ATTR(claim, S_IRUGO|S_IWUSR, rfkill_claim_show, rfkill_claim_store), +- __ATTR(soft, S_IRUGO|S_IWUSR, rfkill_soft_show, rfkill_soft_store), +- __ATTR(hard, S_IRUGO, rfkill_hard_show, NULL), +- __ATTR_NULL ++static struct attribute *rfkill_dev_attrs[] = { ++ &dev_attr_name.attr, ++ &dev_attr_type.attr, ++ &dev_attr_index.attr, ++ &dev_attr_persistent.attr, ++ &dev_attr_state.attr, ++ &dev_attr_claim.attr, ++ &dev_attr_soft.attr, ++ &dev_attr_hard.attr, ++ NULL, + }; ++ATTRIBUTE_GROUPS(rfkill_dev); + + static void rfkill_release(struct device *dev) + { +@@ -830,7 +832,7 @@ static int rfkill_resume(struct device * + static struct class rfkill_class = { + .name = "rfkill", + .dev_release = rfkill_release, +- .dev_attrs = rfkill_dev_attrs, ++ .dev_groups = rfkill_dev_groups, + .dev_uevent = rfkill_dev_uevent, + .suspend = rfkill_suspend, + .resume = rfkill_resume, diff --git a/misc-c2port-use-dev_bin_attrs-instead-of-hand-coding-it.patch b/misc-c2port-use-dev_bin_attrs-instead-of-hand-coding-it.patch new file mode 100644 index 00000000000000..79a279f1d14c21 --- /dev/null +++ b/misc-c2port-use-dev_bin_attrs-instead-of-hand-coding-it.patch @@ -0,0 +1,93 @@ +From foo@baz Mon Jul 8 11:31:26 PDT 2013 +Date: Mon, 08 Jul 2013 11:31:26 -0700 +To: Greg KH <gregkh@linuxfoundation.org> +From: Greg Kroah-Hartman <gregkh@linuxfoundation.org> +Subject: [PATCH] misc: c2port: use dev_bin_attrs instead of hand-coding it + +From: Greg Kroah-Hartman <gregkh@linuxfoundation.org> + +Classes support a list of default binary attributes, so use that in the +c2port driver, instead of hand creating and destroying the file, which +is racing with userspace. Bonus is this removes lines of code. + +Cc: Rodolfo Giometti <giometti@linux.it> +Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> +-- + drivers/misc/c2port/core.c | 30 +++++++++++++----------------- + 1 file changed, 13 insertions(+), 17 deletions(-) + +--- a/drivers/misc/c2port/core.c ++++ b/drivers/misc/c2port/core.c +@@ -867,14 +867,17 @@ static struct device_attribute c2port_at + __ATTR_NULL, + }; + +-static struct bin_attribute c2port_bin_attrs = { +- .attr = { +- .name = "flash_data", +- .mode = 0644 ++static struct bin_attribute c2port_bin_attrs[] = { ++ { ++ .attr = { ++ .name = "flash_data", ++ .mode = 0644 ++ }, ++ .read = c2port_read_flash_data, ++ .write = c2port_write_flash_data, ++ /* .size is computed at run-time */ + }, +- .read = c2port_read_flash_data, +- .write = c2port_write_flash_data, +- /* .size is computed at run-time */ ++ __ATTR_NULL + }; + + /* +@@ -907,6 +910,8 @@ struct c2port_device *c2port_device_regi + goto error_idr_alloc; + c2dev->id = ret; + ++ c2port_bin_attrs[0].size = ops->blocks_num * ops->block_size; ++ + c2dev->dev = device_create(c2port_class, NULL, 0, c2dev, + "c2port%d", c2dev->id); + if (unlikely(IS_ERR(c2dev->dev))) { +@@ -919,12 +924,6 @@ struct c2port_device *c2port_device_regi + c2dev->ops = ops; + mutex_init(&c2dev->mutex); + +- /* Create binary file */ +- c2port_bin_attrs.size = ops->blocks_num * ops->block_size; +- ret = device_create_bin_file(c2dev->dev, &c2port_bin_attrs); +- if (unlikely(ret)) +- goto error_device_create_bin_file; +- + /* By default C2 port access is off */ + c2dev->access = c2dev->flash_access = 0; + ops->access(c2dev, 0); +@@ -937,9 +936,6 @@ struct c2port_device *c2port_device_regi + + return c2dev; + +-error_device_create_bin_file: +- device_destroy(c2port_class, 0); +- + error_device_create: + spin_lock_irq(&c2port_idr_lock); + idr_remove(&c2port_idr, c2dev->id); +@@ -959,7 +955,6 @@ void c2port_device_unregister(struct c2p + + dev_info(c2dev->dev, "C2 port %s removed\n", c2dev->name); + +- device_remove_bin_file(c2dev->dev, &c2port_bin_attrs); + spin_lock_irq(&c2port_idr_lock); + idr_remove(&c2port_idr, c2dev->id); + spin_unlock_irq(&c2port_idr_lock); +@@ -985,6 +980,7 @@ static int __init c2port_init(void) + return PTR_ERR(c2port_class); + } + c2port_class->dev_attrs = c2port_attrs; ++ c2port_class->dev_bin_attrs = c2port_bin_attrs; + + return 0; + } @@ -1,4 +1,8 @@ # My specific stuff, at the top to make it easier to work stuff below. +sysfs.h-add-__attr_rw-macro.patch +sysfs.h-add-attribute_groups-macro.patch +misc-c2port-use-dev_bin_attrs-instead-of-hand-coding-it.patch +d1.patch usb-ldusb-remove-custom-dbg_info-macro.patch usb-legotower-remove-unneeded-tracing-macros.patch usb-legousbtower-remove-custom-debug-macro.patch diff --git a/sysfs.h-add-__attr_rw-macro.patch b/sysfs.h-add-__attr_rw-macro.patch new file mode 100644 index 00000000000000..3666fb44937113 --- /dev/null +++ b/sysfs.h-add-__attr_rw-macro.patch @@ -0,0 +1,49 @@ +From foo@baz Mon Jul 8 12:30:29 PDT 2013 +Date: Mon, 08 Jul 2013 12:30:29 -0700 +To: Greg KH <gregkh@linuxfoundation.org> +From: Greg Kroah-Hartman <gregkh@linuxfoundation.org> +Subject: sysfs.h: add __ATTR_RW() macro + +A number of parts of the kernel created their own version of this, might +as well have the sysfs core provide it instead. + +Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> +--- + include/linux/sysfs.h | 2 ++ + kernel/events/core.c | 2 -- + mm/backing-dev.c | 2 -- + 3 files changed, 2 insertions(+), 4 deletions(-) + +--- a/include/linux/sysfs.h ++++ b/include/linux/sysfs.h +@@ -79,6 +79,8 @@ struct attribute_group { + .show = _name##_show, \ + } + ++#define __ATTR_RW(_name) __ATTR(_name, 0644, _name##_show, _name##_store) ++ + #define __ATTR_NULL { .attr = { .name = NULL } } + + #ifdef CONFIG_DEBUG_LOCK_ALLOC +--- a/kernel/events/core.c ++++ b/kernel/events/core.c +@@ -6212,8 +6212,6 @@ perf_event_mux_interval_ms_store(struct + return count; + } + +-#define __ATTR_RW(attr) __ATTR(attr, 0644, attr##_show, attr##_store) +- + static struct device_attribute pmu_dev_attrs[] = { + __ATTR_RO(type), + __ATTR_RW(perf_event_mux_interval_ms), +--- a/mm/backing-dev.c ++++ b/mm/backing-dev.c +@@ -232,8 +232,6 @@ static ssize_t stable_pages_required_sho + bdi_cap_stable_pages_required(bdi) ? 1 : 0); + } + +-#define __ATTR_RW(attr) __ATTR(attr, 0644, attr##_show, attr##_store) +- + static struct device_attribute bdi_dev_attrs[] = { + __ATTR_RW(read_ahead_kb), + __ATTR_RW(min_ratio), diff --git a/sysfs.h-add-attribute_groups-macro.patch b/sysfs.h-add-attribute_groups-macro.patch new file mode 100644 index 00000000000000..31816858e04505 --- /dev/null +++ b/sysfs.h-add-attribute_groups-macro.patch @@ -0,0 +1,33 @@ +From foo@baz Mon Jul 8 16:40:50 PDT 2013 +Date: Mon, 08 Jul 2013 16:40:50 -0700 +To: Greg KH <gregkh@linuxfoundation.org> +From: Greg Kroah-Hartman <gregkh@linuxfoundation.org> +Subject: sysfs.h: add ATTRIBUTE_GROUPS() macro + +To make it easier for driver subsystems to work with attribute groups, +create the ATTRIBUTE_GROUPS macro to remove some of the repetitive +typing for the most common use for attribute groups. + +Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> +--- + include/linux/sysfs.h | 9 +++++++++ + 1 file changed, 9 insertions(+) + +--- a/include/linux/sysfs.h ++++ b/include/linux/sysfs.h +@@ -94,6 +94,15 @@ struct attribute_group { + #define __ATTR_IGNORE_LOCKDEP __ATTR + #endif + ++#define ATTRIBUTE_GROUPS(name) \ ++static const struct attribute_group name##_group = { \ ++ .attrs = name##_attrs, \ ++}; \ ++static const struct attribute_group *name##_groups[] = { \ ++ &name##_group, \ ++ NULL, \ ++} ++ + #define attr_name(_attr) (_attr).attr.name + + struct file; |
