diff options
Diffstat (limited to 'drivers/base/core.c')
-rw-r--r-- | drivers/base/core.c | 120 |
1 files changed, 91 insertions, 29 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; |