diff options
author | Guenter Roeck <linux@roeck-us.net> | 2013-07-14 19:05:57 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2013-07-16 13:57:37 -0400 |
commit | 39ef311204941ddd01ea2950d6220c8ccc710d15 (patch) | |
tree | ff043a79a7864d0e50367bcbca80f6562a282ae5 /drivers/base/core.c | |
parent | 388a8c353d671d4ea2f638be84cfcbb912afdcf2 (diff) |
driver core: Introduce device_create_groups
device_create_groups lets callers create devices as well as associated
sysfs attributes with a single call. This avoids race conditions seen
if sysfs attributes on new devices are created later.
[fixed up comment block placement and add checks for printk buffer
formats - gregkh]
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
Cc: Jean Delvare <khali@linux-fr.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/base/core.c')
-rw-r--r-- | drivers/base/core.c | 111 |
1 files changed, 83 insertions, 28 deletions
diff --git a/drivers/base/core.c b/drivers/base/core.c index dc3ea237f086..a8aae1823f73 100644 --- a/drivers/base/core.c +++ b/drivers/base/core.c | |||
@@ -1667,34 +1667,11 @@ static void device_create_release(struct device *dev) | |||
1667 | kfree(dev); | 1667 | kfree(dev); |
1668 | } | 1668 | } |
1669 | 1669 | ||
1670 | /** | 1670 | static struct device * |
1671 | * device_create_vargs - creates a device and registers it with sysfs | 1671 | device_create_groups_vargs(struct class *class, struct device *parent, |
1672 | * @class: pointer to the struct class that this device should be registered to | 1672 | dev_t devt, void *drvdata, |
1673 | * @parent: pointer to the parent struct device of this new device, if any | 1673 | const struct attribute_group **groups, |
1674 | * @devt: the dev_t for the char device to be added | 1674 | 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 | { | 1675 | { |
1699 | struct device *dev = NULL; | 1676 | struct device *dev = NULL; |
1700 | int retval = -ENODEV; | 1677 | int retval = -ENODEV; |
@@ -1711,6 +1688,7 @@ struct device *device_create_vargs(struct class *class, struct device *parent, | |||
1711 | dev->devt = devt; | 1688 | dev->devt = devt; |
1712 | dev->class = class; | 1689 | dev->class = class; |
1713 | dev->parent = parent; | 1690 | dev->parent = parent; |
1691 | dev->groups = groups; | ||
1714 | dev->release = device_create_release; | 1692 | dev->release = device_create_release; |
1715 | dev_set_drvdata(dev, drvdata); | 1693 | dev_set_drvdata(dev, drvdata); |
1716 | 1694 | ||
@@ -1728,6 +1706,39 @@ error: | |||
1728 | put_device(dev); | 1706 | put_device(dev); |
1729 | return ERR_PTR(retval); | 1707 | return ERR_PTR(retval); |
1730 | } | 1708 | } |
1709 | |||
1710 | /** | ||
1711 | * device_create_vargs - creates a device and registers it with sysfs | ||
1712 | * @class: pointer to the struct class that this device should be registered to | ||
1713 | * @parent: pointer to the parent struct device of this new device, if any | ||
1714 | * @devt: the dev_t for the char device to be added | ||
1715 | * @drvdata: the data to be added to the device for callbacks | ||
1716 | * @fmt: string for the device's name | ||
1717 | * @args: va_list for the device's name | ||
1718 | * | ||
1719 | * This function can be used by char device classes. A struct device | ||
1720 | * will be created in sysfs, registered to the specified class. | ||
1721 | * | ||
1722 | * A "dev" file will be created, showing the dev_t for the device, if | ||
1723 | * the dev_t is not 0,0. | ||
1724 | * If a pointer to a parent struct device is passed in, the newly created | ||
1725 | * struct device will be a child of that device in sysfs. | ||
1726 | * The pointer to the struct device will be returned from the call. | ||
1727 | * Any further sysfs files that might be required can be created using this | ||
1728 | * pointer. | ||
1729 | * | ||
1730 | * Returns &struct device pointer on success, or ERR_PTR() on error. | ||
1731 | * | ||
1732 | * Note: the struct class passed to this function must have previously | ||
1733 | * been created with a call to class_create(). | ||
1734 | */ | ||
1735 | struct device *device_create_vargs(struct class *class, struct device *parent, | ||
1736 | dev_t devt, void *drvdata, const char *fmt, | ||
1737 | va_list args) | ||
1738 | { | ||
1739 | return device_create_groups_vargs(class, parent, devt, drvdata, NULL, | ||
1740 | fmt, args); | ||
1741 | } | ||
1731 | EXPORT_SYMBOL_GPL(device_create_vargs); | 1742 | EXPORT_SYMBOL_GPL(device_create_vargs); |
1732 | 1743 | ||
1733 | /** | 1744 | /** |
@@ -1767,6 +1778,50 @@ struct device *device_create(struct class *class, struct device *parent, | |||
1767 | } | 1778 | } |
1768 | EXPORT_SYMBOL_GPL(device_create); | 1779 | EXPORT_SYMBOL_GPL(device_create); |
1769 | 1780 | ||
1781 | /** | ||
1782 | * device_create_with_groups - creates a device and registers it with sysfs | ||
1783 | * @class: pointer to the struct class that this device should be registered to | ||
1784 | * @parent: pointer to the parent struct device of this new device, if any | ||
1785 | * @devt: the dev_t for the char device to be added | ||
1786 | * @drvdata: the data to be added to the device for callbacks | ||
1787 | * @groups: NULL-terminated list of attribute groups to be created | ||
1788 | * @fmt: string for the device's name | ||
1789 | * | ||
1790 | * This function can be used by char device classes. A struct device | ||
1791 | * will be created in sysfs, registered to the specified class. | ||
1792 | * Additional attributes specified in the groups parameter will also | ||
1793 | * be created automatically. | ||
1794 | * | ||
1795 | * A "dev" file will be created, showing the dev_t for the device, if | ||
1796 | * the dev_t is not 0,0. | ||
1797 | * If a pointer to a parent struct device is passed in, the newly created | ||
1798 | * struct device will be a child of that device in sysfs. | ||
1799 | * The pointer to the struct device will be returned from the call. | ||
1800 | * Any further sysfs files that might be required can be created using this | ||
1801 | * pointer. | ||
1802 | * | ||
1803 | * Returns &struct device pointer on success, or ERR_PTR() on error. | ||
1804 | * | ||
1805 | * Note: the struct class passed to this function must have previously | ||
1806 | * been created with a call to class_create(). | ||
1807 | */ | ||
1808 | struct device *device_create_with_groups(struct class *class, | ||
1809 | struct device *parent, dev_t devt, | ||
1810 | void *drvdata, | ||
1811 | const struct attribute_group **groups, | ||
1812 | const char *fmt, ...) | ||
1813 | { | ||
1814 | va_list vargs; | ||
1815 | struct device *dev; | ||
1816 | |||
1817 | va_start(vargs, fmt); | ||
1818 | dev = device_create_groups_vargs(class, parent, devt, drvdata, groups, | ||
1819 | fmt, vargs); | ||
1820 | va_end(vargs); | ||
1821 | return dev; | ||
1822 | } | ||
1823 | EXPORT_SYMBOL_GPL(device_create_with_groups); | ||
1824 | |||
1770 | static int __match_devt(struct device *dev, const void *data) | 1825 | static int __match_devt(struct device *dev, const void *data) |
1771 | { | 1826 | { |
1772 | const dev_t *devt = data; | 1827 | const dev_t *devt = data; |