diff options
-rw-r--r-- | drivers/base/core.c | 120 | ||||
-rw-r--r-- | drivers/base/platform.c | 1 | ||||
-rw-r--r-- | fs/sysfs/group.c | 70 | ||||
-rw-r--r-- | include/linux/device.h | 37 | ||||
-rw-r--r-- | include/linux/sysfs.h | 64 | ||||
-rw-r--r-- | kernel/events/core.c | 2 | ||||
-rw-r--r-- | mm/backing-dev.c | 2 |
7 files changed, 224 insertions, 72 deletions
diff --git a/drivers/base/core.c b/drivers/base/core.c index dc3ea237f086..8856d74545d9 100644 --- a/drivers/base/core.c +++ b/drivers/base/core.c | |||
@@ -528,9 +528,12 @@ static int device_add_attrs(struct device *dev) | |||
528 | int error; | 528 | int error; |
529 | 529 | ||
530 | if (class) { | 530 | if (class) { |
531 | error = device_add_attributes(dev, class->dev_attrs); | 531 | error = device_add_groups(dev, class->dev_groups); |
532 | if (error) | 532 | if (error) |
533 | return error; | 533 | return error; |
534 | error = device_add_attributes(dev, class->dev_attrs); | ||
535 | if (error) | ||
536 | goto err_remove_class_groups; | ||
534 | error = device_add_bin_attributes(dev, class->dev_bin_attrs); | 537 | error = device_add_bin_attributes(dev, class->dev_bin_attrs); |
535 | if (error) | 538 | if (error) |
536 | goto err_remove_class_attrs; | 539 | goto err_remove_class_attrs; |
@@ -563,6 +566,9 @@ static int device_add_attrs(struct device *dev) | |||
563 | err_remove_class_attrs: | 566 | err_remove_class_attrs: |
564 | if (class) | 567 | if (class) |
565 | device_remove_attributes(dev, class->dev_attrs); | 568 | device_remove_attributes(dev, class->dev_attrs); |
569 | err_remove_class_groups: | ||
570 | if (class) | ||
571 | device_remove_groups(dev, class->dev_groups); | ||
566 | 572 | ||
567 | return error; | 573 | return error; |
568 | } | 574 | } |
@@ -581,6 +587,7 @@ static void device_remove_attrs(struct device *dev) | |||
581 | if (class) { | 587 | if (class) { |
582 | device_remove_attributes(dev, class->dev_attrs); | 588 | device_remove_attributes(dev, class->dev_attrs); |
583 | device_remove_bin_attributes(dev, class->dev_bin_attrs); | 589 | device_remove_bin_attributes(dev, class->dev_bin_attrs); |
590 | device_remove_groups(dev, class->dev_groups); | ||
584 | } | 591 | } |
585 | } | 592 | } |
586 | 593 | ||
@@ -1667,34 +1674,11 @@ static void device_create_release(struct device *dev) | |||
1667 | kfree(dev); | 1674 | kfree(dev); |
1668 | } | 1675 | } |
1669 | 1676 | ||
1670 | /** | 1677 | static struct device * |
1671 | * device_create_vargs - creates a device and registers it with sysfs | 1678 | device_create_groups_vargs(struct class *class, struct device *parent, |
1672 | * @class: pointer to the struct class that this device should be registered to | 1679 | dev_t devt, void *drvdata, |
1673 | * @parent: pointer to the parent struct device of this new device, if any | 1680 | const struct attribute_group **groups, |
1674 | * @devt: the dev_t for the char device to be added | 1681 | const char *fmt, va_list args) |
1675 | * @drvdata: the data to be added to the device for callbacks | ||
1676 | * @fmt: string for the device's name | ||
1677 | * @args: va_list for the device's name | ||
1678 | * | ||
1679 | * This function can be used by char device classes. A struct device | ||
1680 | * will be created in sysfs, registered to the specified class. | ||
1681 | * | ||
1682 | * A "dev" file will be created, showing the dev_t for the device, if | ||
1683 | * the dev_t is not 0,0. | ||
1684 | * If a pointer to a parent struct device is passed in, the newly created | ||
1685 | * struct device will be a child of that device in sysfs. | ||
1686 | * The pointer to the struct device will be returned from the call. | ||
1687 | * Any further sysfs files that might be required can be created using this | ||
1688 | * pointer. | ||
1689 | * | ||
1690 | * Returns &struct device pointer on success, or ERR_PTR() on error. | ||
1691 | * | ||
1692 | * Note: the struct class passed to this function must have previously | ||
1693 | * been created with a call to class_create(). | ||
1694 | */ | ||
1695 | struct device *device_create_vargs(struct class *class, struct device *parent, | ||
1696 | dev_t devt, void *drvdata, const char *fmt, | ||
1697 | va_list args) | ||
1698 | { | 1682 | { |
1699 | struct device *dev = NULL; | 1683 | struct device *dev = NULL; |
1700 | int retval = -ENODEV; | 1684 | int retval = -ENODEV; |
@@ -1711,6 +1695,7 @@ struct device *device_create_vargs(struct class *class, struct device *parent, | |||
1711 | dev->devt = devt; | 1695 | dev->devt = devt; |
1712 | dev->class = class; | 1696 | dev->class = class; |
1713 | dev->parent = parent; | 1697 | dev->parent = parent; |
1698 | dev->groups = groups; | ||
1714 | dev->release = device_create_release; | 1699 | dev->release = device_create_release; |
1715 | dev_set_drvdata(dev, drvdata); | 1700 | dev_set_drvdata(dev, drvdata); |
1716 | 1701 | ||
@@ -1728,6 +1713,39 @@ error: | |||
1728 | put_device(dev); | 1713 | put_device(dev); |
1729 | return ERR_PTR(retval); | 1714 | return ERR_PTR(retval); |
1730 | } | 1715 | } |
1716 | |||
1717 | /** | ||
1718 | * device_create_vargs - creates a device and registers it with sysfs | ||
1719 | * @class: pointer to the struct class that this device should be registered to | ||
1720 | * @parent: pointer to the parent struct device of this new device, if any | ||
1721 | * @devt: the dev_t for the char device to be added | ||
1722 | * @drvdata: the data to be added to the device for callbacks | ||
1723 | * @fmt: string for the device's name | ||
1724 | * @args: va_list for the device's name | ||
1725 | * | ||
1726 | * This function can be used by char device classes. A struct device | ||
1727 | * will be created in sysfs, registered to the specified class. | ||
1728 | * | ||
1729 | * A "dev" file will be created, showing the dev_t for the device, if | ||
1730 | * the dev_t is not 0,0. | ||
1731 | * If a pointer to a parent struct device is passed in, the newly created | ||
1732 | * struct device will be a child of that device in sysfs. | ||
1733 | * The pointer to the struct device will be returned from the call. | ||
1734 | * Any further sysfs files that might be required can be created using this | ||
1735 | * pointer. | ||
1736 | * | ||
1737 | * Returns &struct device pointer on success, or ERR_PTR() on error. | ||
1738 | * | ||
1739 | * Note: the struct class passed to this function must have previously | ||
1740 | * been created with a call to class_create(). | ||
1741 | */ | ||
1742 | struct device *device_create_vargs(struct class *class, struct device *parent, | ||
1743 | dev_t devt, void *drvdata, const char *fmt, | ||
1744 | va_list args) | ||
1745 | { | ||
1746 | return device_create_groups_vargs(class, parent, devt, drvdata, NULL, | ||
1747 | fmt, args); | ||
1748 | } | ||
1731 | EXPORT_SYMBOL_GPL(device_create_vargs); | 1749 | EXPORT_SYMBOL_GPL(device_create_vargs); |
1732 | 1750 | ||
1733 | /** | 1751 | /** |
@@ -1767,6 +1785,50 @@ struct device *device_create(struct class *class, struct device *parent, | |||
1767 | } | 1785 | } |
1768 | EXPORT_SYMBOL_GPL(device_create); | 1786 | EXPORT_SYMBOL_GPL(device_create); |
1769 | 1787 | ||
1788 | /** | ||
1789 | * device_create_with_groups - creates a device and registers it with sysfs | ||
1790 | * @class: pointer to the struct class that this device should be registered to | ||
1791 | * @parent: pointer to the parent struct device of this new device, if any | ||
1792 | * @devt: the dev_t for the char device to be added | ||
1793 | * @drvdata: the data to be added to the device for callbacks | ||
1794 | * @groups: NULL-terminated list of attribute groups to be created | ||
1795 | * @fmt: string for the device's name | ||
1796 | * | ||
1797 | * This function can be used by char device classes. A struct device | ||
1798 | * will be created in sysfs, registered to the specified class. | ||
1799 | * Additional attributes specified in the groups parameter will also | ||
1800 | * be created automatically. | ||
1801 | * | ||
1802 | * A "dev" file will be created, showing the dev_t for the device, if | ||
1803 | * the dev_t is not 0,0. | ||
1804 | * If a pointer to a parent struct device is passed in, the newly created | ||
1805 | * struct device will be a child of that device in sysfs. | ||
1806 | * The pointer to the struct device will be returned from the call. | ||
1807 | * Any further sysfs files that might be required can be created using this | ||
1808 | * pointer. | ||
1809 | * | ||
1810 | * Returns &struct device pointer on success, or ERR_PTR() on error. | ||
1811 | * | ||
1812 | * Note: the struct class passed to this function must have previously | ||
1813 | * been created with a call to class_create(). | ||
1814 | */ | ||
1815 | struct device *device_create_with_groups(struct class *class, | ||
1816 | struct device *parent, dev_t devt, | ||
1817 | void *drvdata, | ||
1818 | const struct attribute_group **groups, | ||
1819 | const char *fmt, ...) | ||
1820 | { | ||
1821 | va_list vargs; | ||
1822 | struct device *dev; | ||
1823 | |||
1824 | va_start(vargs, fmt); | ||
1825 | dev = device_create_groups_vargs(class, parent, devt, drvdata, groups, | ||
1826 | fmt, vargs); | ||
1827 | va_end(vargs); | ||
1828 | return dev; | ||
1829 | } | ||
1830 | EXPORT_SYMBOL_GPL(device_create_with_groups); | ||
1831 | |||
1770 | static int __match_devt(struct device *dev, const void *data) | 1832 | static int __match_devt(struct device *dev, const void *data) |
1771 | { | 1833 | { |
1772 | const dev_t *devt = data; | 1834 | const dev_t *devt = data; |
diff --git a/drivers/base/platform.c b/drivers/base/platform.c index 15789875128e..3c3197a8de41 100644 --- a/drivers/base/platform.c +++ b/drivers/base/platform.c | |||
@@ -522,6 +522,7 @@ static void platform_drv_shutdown(struct device *_dev) | |||
522 | /** | 522 | /** |
523 | * __platform_driver_register - register a driver for platform-level devices | 523 | * __platform_driver_register - register a driver for platform-level devices |
524 | * @drv: platform driver structure | 524 | * @drv: platform driver structure |
525 | * @owner: owning module/driver | ||
525 | */ | 526 | */ |
526 | int __platform_driver_register(struct platform_driver *drv, | 527 | int __platform_driver_register(struct platform_driver *drv, |
527 | struct module *owner) | 528 | struct module *owner) |
diff --git a/fs/sysfs/group.c b/fs/sysfs/group.c index aec3d5c98c94..09a1a25cd145 100644 --- a/fs/sysfs/group.c +++ b/fs/sysfs/group.c | |||
@@ -20,38 +20,64 @@ static void remove_files(struct sysfs_dirent *dir_sd, struct kobject *kobj, | |||
20 | const struct attribute_group *grp) | 20 | const struct attribute_group *grp) |
21 | { | 21 | { |
22 | struct attribute *const* attr; | 22 | struct attribute *const* attr; |
23 | int i; | 23 | struct bin_attribute *const* bin_attr; |
24 | 24 | ||
25 | for (i = 0, attr = grp->attrs; *attr; i++, attr++) | 25 | if (grp->attrs) |
26 | sysfs_hash_and_remove(dir_sd, NULL, (*attr)->name); | 26 | for (attr = grp->attrs; *attr; attr++) |
27 | sysfs_hash_and_remove(dir_sd, NULL, (*attr)->name); | ||
28 | if (grp->bin_attrs) | ||
29 | for (bin_attr = grp->bin_attrs; *bin_attr; bin_attr++) | ||
30 | sysfs_remove_bin_file(kobj, *bin_attr); | ||
27 | } | 31 | } |
28 | 32 | ||
29 | static int create_files(struct sysfs_dirent *dir_sd, struct kobject *kobj, | 33 | static int create_files(struct sysfs_dirent *dir_sd, struct kobject *kobj, |
30 | const struct attribute_group *grp, int update) | 34 | const struct attribute_group *grp, int update) |
31 | { | 35 | { |
32 | struct attribute *const* attr; | 36 | struct attribute *const* attr; |
37 | struct bin_attribute *const* bin_attr; | ||
33 | int error = 0, i; | 38 | int error = 0, i; |
34 | 39 | ||
35 | for (i = 0, attr = grp->attrs; *attr && !error; i++, attr++) { | 40 | if (grp->attrs) { |
36 | umode_t mode = 0; | 41 | for (i = 0, attr = grp->attrs; *attr && !error; i++, attr++) { |
42 | umode_t mode = 0; | ||
43 | |||
44 | /* | ||
45 | * In update mode, we're changing the permissions or | ||
46 | * visibility. Do this by first removing then | ||
47 | * re-adding (if required) the file. | ||
48 | */ | ||
49 | if (update) | ||
50 | sysfs_hash_and_remove(dir_sd, NULL, | ||
51 | (*attr)->name); | ||
52 | if (grp->is_visible) { | ||
53 | mode = grp->is_visible(kobj, *attr, i); | ||
54 | if (!mode) | ||
55 | continue; | ||
56 | } | ||
57 | error = sysfs_add_file_mode(dir_sd, *attr, | ||
58 | SYSFS_KOBJ_ATTR, | ||
59 | (*attr)->mode | mode); | ||
60 | if (unlikely(error)) | ||
61 | break; | ||
62 | } | ||
63 | if (error) { | ||
64 | remove_files(dir_sd, kobj, grp); | ||
65 | goto exit; | ||
66 | } | ||
67 | } | ||
37 | 68 | ||
38 | /* in update mode, we're changing the permissions or | 69 | if (grp->bin_attrs) { |
39 | * visibility. Do this by first removing then | 70 | for (bin_attr = grp->bin_attrs; *bin_attr; bin_attr++) { |
40 | * re-adding (if required) the file */ | 71 | if (update) |
41 | if (update) | 72 | sysfs_remove_bin_file(kobj, *bin_attr); |
42 | sysfs_hash_and_remove(dir_sd, NULL, (*attr)->name); | 73 | error = sysfs_create_bin_file(kobj, *bin_attr); |
43 | if (grp->is_visible) { | 74 | if (error) |
44 | mode = grp->is_visible(kobj, *attr, i); | 75 | break; |
45 | if (!mode) | ||
46 | continue; | ||
47 | } | 76 | } |
48 | error = sysfs_add_file_mode(dir_sd, *attr, SYSFS_KOBJ_ATTR, | 77 | if (error) |
49 | (*attr)->mode | mode); | 78 | remove_files(dir_sd, kobj, grp); |
50 | if (unlikely(error)) | ||
51 | break; | ||
52 | } | 79 | } |
53 | if (error) | 80 | exit: |
54 | remove_files(dir_sd, kobj, grp); | ||
55 | return error; | 81 | return error; |
56 | } | 82 | } |
57 | 83 | ||
@@ -67,8 +93,8 @@ static int internal_create_group(struct kobject *kobj, int update, | |||
67 | /* Updates may happen before the object has been instantiated */ | 93 | /* Updates may happen before the object has been instantiated */ |
68 | if (unlikely(update && !kobj->sd)) | 94 | if (unlikely(update && !kobj->sd)) |
69 | return -EINVAL; | 95 | return -EINVAL; |
70 | if (!grp->attrs) { | 96 | if (!grp->attrs && !grp->bin_attrs) { |
71 | WARN(1, "sysfs: attrs not set by subsystem for group: %s/%s\n", | 97 | WARN(1, "sysfs: (bin_)attrs not set by subsystem for group: %s/%s\n", |
72 | kobj->name, grp->name ? "" : grp->name); | 98 | kobj->name, grp->name ? "" : grp->name); |
73 | return -EINVAL; | 99 | return -EINVAL; |
74 | } | 100 | } |
diff --git a/include/linux/device.h b/include/linux/device.h index bcf8c0d4cd98..22b546a58591 100644 --- a/include/linux/device.h +++ b/include/linux/device.h | |||
@@ -47,7 +47,11 @@ struct bus_attribute { | |||
47 | }; | 47 | }; |
48 | 48 | ||
49 | #define BUS_ATTR(_name, _mode, _show, _store) \ | 49 | #define BUS_ATTR(_name, _mode, _show, _store) \ |
50 | struct bus_attribute bus_attr_##_name = __ATTR(_name, _mode, _show, _store) | 50 | struct bus_attribute bus_attr_##_name = __ATTR(_name, _mode, _show, _store) |
51 | #define BUS_ATTR_RW(_name) \ | ||
52 | struct bus_attribute bus_attr_##_name = __ATTR_RW(_name) | ||
53 | #define BUS_ATTR_RO(_name) \ | ||
54 | struct bus_attribute bus_attr_##_name = __ATTR_RO(_name) | ||
51 | 55 | ||
52 | extern int __must_check bus_create_file(struct bus_type *, | 56 | extern int __must_check bus_create_file(struct bus_type *, |
53 | struct bus_attribute *); | 57 | struct bus_attribute *); |
@@ -261,9 +265,12 @@ struct driver_attribute { | |||
261 | size_t count); | 265 | size_t count); |
262 | }; | 266 | }; |
263 | 267 | ||
264 | #define DRIVER_ATTR(_name, _mode, _show, _store) \ | 268 | #define DRIVER_ATTR(_name, _mode, _show, _store) \ |
265 | struct driver_attribute driver_attr_##_name = \ | 269 | struct driver_attribute driver_attr_##_name = __ATTR(_name, _mode, _show, _store) |
266 | __ATTR(_name, _mode, _show, _store) | 270 | #define DRIVER_ATTR_RW(_name) \ |
271 | struct driver_attribute driver_attr_##_name = __ATTR_RW(_name) | ||
272 | #define DRIVER_ATTR_RO(_name) \ | ||
273 | struct driver_attribute driver_attr_##_name = __ATTR_RO(_name) | ||
267 | 274 | ||
268 | extern int __must_check driver_create_file(struct device_driver *driver, | 275 | extern int __must_check driver_create_file(struct device_driver *driver, |
269 | const struct driver_attribute *attr); | 276 | const struct driver_attribute *attr); |
@@ -313,6 +320,7 @@ int subsys_virtual_register(struct bus_type *subsys, | |||
313 | * @name: Name of the class. | 320 | * @name: Name of the class. |
314 | * @owner: The module owner. | 321 | * @owner: The module owner. |
315 | * @class_attrs: Default attributes of this class. | 322 | * @class_attrs: Default attributes of this class. |
323 | * @dev_groups: Default attributes of the devices that belong to the class. | ||
316 | * @dev_attrs: Default attributes of the devices belong to the class. | 324 | * @dev_attrs: Default attributes of the devices belong to the class. |
317 | * @dev_bin_attrs: Default binary attributes of the devices belong to the class. | 325 | * @dev_bin_attrs: Default binary attributes of the devices belong to the class. |
318 | * @dev_kobj: The kobject that represents this class and links it into the hierarchy. | 326 | * @dev_kobj: The kobject that represents this class and links it into the hierarchy. |
@@ -342,7 +350,8 @@ struct class { | |||
342 | struct module *owner; | 350 | struct module *owner; |
343 | 351 | ||
344 | struct class_attribute *class_attrs; | 352 | struct class_attribute *class_attrs; |
345 | struct device_attribute *dev_attrs; | 353 | struct device_attribute *dev_attrs; /* use dev_groups instead */ |
354 | const struct attribute_group **dev_groups; | ||
346 | struct bin_attribute *dev_bin_attrs; | 355 | struct bin_attribute *dev_bin_attrs; |
347 | struct kobject *dev_kobj; | 356 | struct kobject *dev_kobj; |
348 | 357 | ||
@@ -414,8 +423,12 @@ struct class_attribute { | |||
414 | const struct class_attribute *attr); | 423 | const struct class_attribute *attr); |
415 | }; | 424 | }; |
416 | 425 | ||
417 | #define CLASS_ATTR(_name, _mode, _show, _store) \ | 426 | #define CLASS_ATTR(_name, _mode, _show, _store) \ |
418 | struct class_attribute class_attr_##_name = __ATTR(_name, _mode, _show, _store) | 427 | struct class_attribute class_attr_##_name = __ATTR(_name, _mode, _show, _store) |
428 | #define CLASS_ATTR_RW(_name) \ | ||
429 | struct class_attribute class_attr_##_name = __ATTR_RW(_name) | ||
430 | #define CLASS_ATTR_RO(_name) \ | ||
431 | struct class_attribute class_attr_##_name = __ATTR_RO(_name) | ||
419 | 432 | ||
420 | extern int __must_check class_create_file(struct class *class, | 433 | extern int __must_check class_create_file(struct class *class, |
421 | const struct class_attribute *attr); | 434 | const struct class_attribute *attr); |
@@ -423,7 +436,6 @@ extern void class_remove_file(struct class *class, | |||
423 | const struct class_attribute *attr); | 436 | const struct class_attribute *attr); |
424 | 437 | ||
425 | /* Simple class attribute that is just a static string */ | 438 | /* Simple class attribute that is just a static string */ |
426 | |||
427 | struct class_attribute_string { | 439 | struct class_attribute_string { |
428 | struct class_attribute attr; | 440 | struct class_attribute attr; |
429 | char *str; | 441 | char *str; |
@@ -512,6 +524,10 @@ ssize_t device_store_bool(struct device *dev, struct device_attribute *attr, | |||
512 | 524 | ||
513 | #define DEVICE_ATTR(_name, _mode, _show, _store) \ | 525 | #define DEVICE_ATTR(_name, _mode, _show, _store) \ |
514 | struct device_attribute dev_attr_##_name = __ATTR(_name, _mode, _show, _store) | 526 | struct device_attribute dev_attr_##_name = __ATTR(_name, _mode, _show, _store) |
527 | #define DEVICE_ATTR_RW(_name) \ | ||
528 | struct device_attribute dev_attr_##_name = __ATTR_RW(_name) | ||
529 | #define DEVICE_ATTR_RO(_name) \ | ||
530 | struct device_attribute dev_attr_##_name = __ATTR_RO(_name) | ||
515 | #define DEVICE_ULONG_ATTR(_name, _mode, _var) \ | 531 | #define DEVICE_ULONG_ATTR(_name, _mode, _var) \ |
516 | struct dev_ext_attribute dev_attr_##_name = \ | 532 | struct dev_ext_attribute dev_attr_##_name = \ |
517 | { __ATTR(_name, _mode, device_show_ulong, device_store_ulong), &(_var) } | 533 | { __ATTR(_name, _mode, device_show_ulong, device_store_ulong), &(_var) } |
@@ -924,6 +940,11 @@ extern __printf(5, 6) | |||
924 | struct device *device_create(struct class *cls, struct device *parent, | 940 | struct device *device_create(struct class *cls, struct device *parent, |
925 | dev_t devt, void *drvdata, | 941 | dev_t devt, void *drvdata, |
926 | const char *fmt, ...); | 942 | const char *fmt, ...); |
943 | extern __printf(6, 7) | ||
944 | struct device *device_create_with_groups(struct class *cls, | ||
945 | struct device *parent, dev_t devt, void *drvdata, | ||
946 | const struct attribute_group **groups, | ||
947 | const char *fmt, ...); | ||
927 | extern void device_destroy(struct class *cls, dev_t devt); | 948 | extern void device_destroy(struct class *cls, dev_t devt); |
928 | 949 | ||
929 | /* | 950 | /* |
diff --git a/include/linux/sysfs.h b/include/linux/sysfs.h index e2cee22f578a..9e8a9b555ad6 100644 --- a/include/linux/sysfs.h +++ b/include/linux/sysfs.h | |||
@@ -17,10 +17,12 @@ | |||
17 | #include <linux/list.h> | 17 | #include <linux/list.h> |
18 | #include <linux/lockdep.h> | 18 | #include <linux/lockdep.h> |
19 | #include <linux/kobject_ns.h> | 19 | #include <linux/kobject_ns.h> |
20 | #include <linux/stat.h> | ||
20 | #include <linux/atomic.h> | 21 | #include <linux/atomic.h> |
21 | 22 | ||
22 | struct kobject; | 23 | struct kobject; |
23 | struct module; | 24 | struct module; |
25 | struct bin_attribute; | ||
24 | enum kobj_ns_type; | 26 | enum kobj_ns_type; |
25 | 27 | ||
26 | struct attribute { | 28 | struct attribute { |
@@ -59,26 +61,28 @@ struct attribute_group { | |||
59 | umode_t (*is_visible)(struct kobject *, | 61 | umode_t (*is_visible)(struct kobject *, |
60 | struct attribute *, int); | 62 | struct attribute *, int); |
61 | struct attribute **attrs; | 63 | struct attribute **attrs; |
64 | struct bin_attribute **bin_attrs; | ||
62 | }; | 65 | }; |
63 | 66 | ||
64 | |||
65 | |||
66 | /** | 67 | /** |
67 | * Use these macros to make defining attributes easier. See include/linux/device.h | 68 | * Use these macros to make defining attributes easier. See include/linux/device.h |
68 | * for examples.. | 69 | * for examples.. |
69 | */ | 70 | */ |
70 | 71 | ||
71 | #define __ATTR(_name,_mode,_show,_store) { \ | 72 | #define __ATTR(_name,_mode,_show,_store) { \ |
72 | .attr = {.name = __stringify(_name), .mode = _mode }, \ | 73 | .attr = {.name = __stringify(_name), .mode = _mode }, \ |
73 | .show = _show, \ | 74 | .show = _show, \ |
74 | .store = _store, \ | 75 | .store = _store, \ |
75 | } | 76 | } |
76 | 77 | ||
77 | #define __ATTR_RO(_name) { \ | 78 | #define __ATTR_RO(_name) { \ |
78 | .attr = { .name = __stringify(_name), .mode = 0444 }, \ | 79 | .attr = { .name = __stringify(_name), .mode = S_IRUGO }, \ |
79 | .show = _name##_show, \ | 80 | .show = _name##_show, \ |
80 | } | 81 | } |
81 | 82 | ||
83 | #define __ATTR_RW(_name) __ATTR(_name, (S_IWUSR | S_IRUGO), \ | ||
84 | _name##_show, _name##_store) | ||
85 | |||
82 | #define __ATTR_NULL { .attr = { .name = NULL } } | 86 | #define __ATTR_NULL { .attr = { .name = NULL } } |
83 | 87 | ||
84 | #ifdef CONFIG_DEBUG_LOCK_ALLOC | 88 | #ifdef CONFIG_DEBUG_LOCK_ALLOC |
@@ -92,6 +96,18 @@ struct attribute_group { | |||
92 | #define __ATTR_IGNORE_LOCKDEP __ATTR | 96 | #define __ATTR_IGNORE_LOCKDEP __ATTR |
93 | #endif | 97 | #endif |
94 | 98 | ||
99 | #define __ATTRIBUTE_GROUPS(_name) \ | ||
100 | static const struct attribute_group *_name##_groups[] = { \ | ||
101 | &_name##_group, \ | ||
102 | NULL, \ | ||
103 | } | ||
104 | |||
105 | #define ATTRIBUTE_GROUPS(_name) \ | ||
106 | static const struct attribute_group _name##_group = { \ | ||
107 | .attrs = _name##_attrs, \ | ||
108 | }; \ | ||
109 | __ATTRIBUTE_GROUPS(_name) | ||
110 | |||
95 | #define attr_name(_attr) (_attr).attr.name | 111 | #define attr_name(_attr) (_attr).attr.name |
96 | 112 | ||
97 | struct file; | 113 | struct file; |
@@ -121,6 +137,36 @@ struct bin_attribute { | |||
121 | */ | 137 | */ |
122 | #define sysfs_bin_attr_init(bin_attr) sysfs_attr_init(&(bin_attr)->attr) | 138 | #define sysfs_bin_attr_init(bin_attr) sysfs_attr_init(&(bin_attr)->attr) |
123 | 139 | ||
140 | /* macros to create static binary attributes easier */ | ||
141 | #define __BIN_ATTR(_name, _mode, _read, _write, _size) { \ | ||
142 | .attr = { .name = __stringify(_name), .mode = _mode }, \ | ||
143 | .read = _read, \ | ||
144 | .write = _write, \ | ||
145 | .size = _size, \ | ||
146 | } | ||
147 | |||
148 | #define __BIN_ATTR_RO(_name, _size) { \ | ||
149 | .attr = { .name = __stringify(_name), .mode = S_IRUGO }, \ | ||
150 | .read = _name##_read, \ | ||
151 | .size = _size, \ | ||
152 | } | ||
153 | |||
154 | #define __BIN_ATTR_RW(_name, _size) __BIN_ATTR(_name, \ | ||
155 | (S_IWUSR | S_IRUGO), _name##_read, \ | ||
156 | _name##_write) | ||
157 | |||
158 | #define __BIN_ATTR_NULL __ATTR_NULL | ||
159 | |||
160 | #define BIN_ATTR(_name, _mode, _read, _write, _size) \ | ||
161 | struct bin_attribute bin_attr_##_name = __BIN_ATTR(_name, _mode, _read, \ | ||
162 | _write, _size) | ||
163 | |||
164 | #define BIN_ATTR_RO(_name, _size) \ | ||
165 | struct bin_attribute bin_attr_##_name = __BIN_ATTR_RO(_name, _size) | ||
166 | |||
167 | #define BIN_ATTR_RW(_name, _size) \ | ||
168 | struct bin_attribute bin_attr_##_name = __BIN_ATTR_RW(_name, _size) | ||
169 | |||
124 | struct sysfs_ops { | 170 | struct sysfs_ops { |
125 | ssize_t (*show)(struct kobject *, struct attribute *,char *); | 171 | ssize_t (*show)(struct kobject *, struct attribute *,char *); |
126 | ssize_t (*store)(struct kobject *,struct attribute *,const char *, size_t); | 172 | ssize_t (*store)(struct kobject *,struct attribute *,const char *, size_t); |
diff --git a/kernel/events/core.c b/kernel/events/core.c index f3e9dce39bc9..f86599e8c123 100644 --- a/kernel/events/core.c +++ b/kernel/events/core.c | |||
@@ -6234,8 +6234,6 @@ perf_event_mux_interval_ms_store(struct device *dev, | |||
6234 | return count; | 6234 | return count; |
6235 | } | 6235 | } |
6236 | 6236 | ||
6237 | #define __ATTR_RW(attr) __ATTR(attr, 0644, attr##_show, attr##_store) | ||
6238 | |||
6239 | static struct device_attribute pmu_dev_attrs[] = { | 6237 | static struct device_attribute pmu_dev_attrs[] = { |
6240 | __ATTR_RO(type), | 6238 | __ATTR_RO(type), |
6241 | __ATTR_RW(perf_event_mux_interval_ms), | 6239 | __ATTR_RW(perf_event_mux_interval_ms), |
diff --git a/mm/backing-dev.c b/mm/backing-dev.c index d014ee5fcbbd..e04454cdb33f 100644 --- a/mm/backing-dev.c +++ b/mm/backing-dev.c | |||
@@ -232,8 +232,6 @@ static ssize_t stable_pages_required_show(struct device *dev, | |||
232 | bdi_cap_stable_pages_required(bdi) ? 1 : 0); | 232 | bdi_cap_stable_pages_required(bdi) ? 1 : 0); |
233 | } | 233 | } |
234 | 234 | ||
235 | #define __ATTR_RW(attr) __ATTR(attr, 0644, attr##_show, attr##_store) | ||
236 | |||
237 | static struct device_attribute bdi_dev_attrs[] = { | 235 | static struct device_attribute bdi_dev_attrs[] = { |
238 | __ATTR_RW(read_ahead_kb), | 236 | __ATTR_RW(read_ahead_kb), |
239 | __ATTR_RW(min_ratio), | 237 | __ATTR_RW(min_ratio), |