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]
Unified · Split
| @@ -1667,34 +1667,11 @@ static void device_create_release(struct device *dev) · 1666 unmodified lines | ||
| 1667 | 1667 | kfree(dev); |
| 1668 | 1668 | } |
| 1669 | 1669 | |
| 1670 | −/** | |
| 1671 | − * device_create_vargs - creates a device and registers it with sysfs | |
| 1672 | − * @class: pointer to the struct class that this device should be registered to | |
| 1673 | − * @parent: pointer to the parent struct device of this new device, if any | |
| 1674 | − * @devt: the dev_t for the char device to be added | |
| 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) | |
| 1670 | +static struct device * | |
| 1671 | +device_create_groups_vargs(struct class *class, struct device *parent, | |
| 1672 | + dev_t devt, void *drvdata, | |
| 1673 | + const struct attribute_group **groups, | |
| 1674 | + const char *fmt, va_list args) | |
| 1698 | 1675 | { |
| 1699 | 1676 | struct device *dev = NULL; |
| 1700 | 1677 | int retval = -ENODEV; |
| @@ -1711,6 +1688,7 @@ struct device *device_create_vargs(struct class *class, struct device *parent, · 10 unmodified lines | ||
| 1711 | 1688 | dev->devt = devt; |
| 1712 | 1689 | dev->class = class; |
| 1713 | 1690 | dev->parent = parent; |
| 1691 | + dev->groups = groups; | |
| 1714 | 1692 | dev->release = device_create_release; |
| 1715 | 1693 | dev_set_drvdata(dev, drvdata); |
| 1716 | 1694 | |
| @@ -1728,6 +1706,39 @@ error: · 11 unmodified lines | ||
| 1728 | 1706 | put_device(dev); |
| 1729 | 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 | 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, · 33 unmodified lines | ||
| 1767 | 1778 | } |
| 1768 | 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 | 1825 | static int __match_devt(struct device *dev, const void *data) |
| 1771 | 1826 | { |
| 1772 | 1827 | const dev_t *devt = data; |
| @@ -938,6 +938,11 @@ extern __printf(5, 6) · 937 unmodified lines | ||
| 938 | 938 | struct device *device_create(struct class *cls, struct device *parent, |
| 939 | 939 | dev_t devt, void *drvdata, |
| 940 | 940 | const char *fmt, ...); |
| 941 | +extern __printf(6, 7) | |
| 942 | +struct device *device_create_with_groups(struct class *cls, | |
| 943 | + struct device *parent, dev_t devt, void *drvdata, | |
| 944 | + const struct attribute_group **groups, | |
| 945 | + const char *fmt, ...); | |
| 941 | 946 | extern void device_destroy(struct class *cls, dev_t devt); |
| 942 | 947 | |
| 943 | 948 | /* |