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; |
