diff options
| -rw-r--r-- | drivers/base/class.c | 32 | ||||
| -rw-r--r-- | include/linux/device.h | 2 |
2 files changed, 34 insertions, 0 deletions
diff --git a/drivers/base/class.c b/drivers/base/class.c index 0e71dff327cd..b1ea4df85c7d 100644 --- a/drivers/base/class.c +++ b/drivers/base/class.c | |||
| @@ -456,6 +456,35 @@ static void class_device_remove_attrs(struct class_device * cd) | |||
| 456 | } | 456 | } |
| 457 | } | 457 | } |
| 458 | 458 | ||
| 459 | static int class_device_add_groups(struct class_device * cd) | ||
| 460 | { | ||
| 461 | int i; | ||
| 462 | int error = 0; | ||
| 463 | |||
| 464 | if (cd->groups) { | ||
| 465 | for (i = 0; cd->groups[i]; i++) { | ||
| 466 | error = sysfs_create_group(&cd->kobj, cd->groups[i]); | ||
| 467 | if (error) { | ||
| 468 | while (--i >= 0) | ||
| 469 | sysfs_remove_group(&cd->kobj, cd->groups[i]); | ||
| 470 | goto out; | ||
| 471 | } | ||
| 472 | } | ||
| 473 | } | ||
| 474 | out: | ||
| 475 | return error; | ||
| 476 | } | ||
| 477 | |||
| 478 | static void class_device_remove_groups(struct class_device * cd) | ||
| 479 | { | ||
| 480 | int i; | ||
| 481 | if (cd->groups) { | ||
| 482 | for (i = 0; cd->groups[i]; i++) { | ||
| 483 | sysfs_remove_group(&cd->kobj, cd->groups[i]); | ||
| 484 | } | ||
| 485 | } | ||
| 486 | } | ||
| 487 | |||
| 459 | static ssize_t show_dev(struct class_device *class_dev, char *buf) | 488 | static ssize_t show_dev(struct class_device *class_dev, char *buf) |
| 460 | { | 489 | { |
| 461 | return print_dev_t(buf, class_dev->devt); | 490 | return print_dev_t(buf, class_dev->devt); |
| @@ -559,6 +588,8 @@ int class_device_add(struct class_device *class_dev) | |||
| 559 | class_name); | 588 | class_name); |
| 560 | } | 589 | } |
| 561 | 590 | ||
| 591 | class_device_add_groups(class_dev); | ||
| 592 | |||
| 562 | kobject_uevent(&class_dev->kobj, KOBJ_ADD); | 593 | kobject_uevent(&class_dev->kobj, KOBJ_ADD); |
| 563 | 594 | ||
| 564 | /* notify any interfaces this device is now here */ | 595 | /* notify any interfaces this device is now here */ |
| @@ -672,6 +703,7 @@ void class_device_del(struct class_device *class_dev) | |||
| 672 | if (class_dev->devt_attr) | 703 | if (class_dev->devt_attr) |
| 673 | class_device_remove_file(class_dev, class_dev->devt_attr); | 704 | class_device_remove_file(class_dev, class_dev->devt_attr); |
| 674 | class_device_remove_attrs(class_dev); | 705 | class_device_remove_attrs(class_dev); |
| 706 | class_device_remove_groups(class_dev); | ||
| 675 | 707 | ||
| 676 | kobject_uevent(&class_dev->kobj, KOBJ_REMOVE); | 708 | kobject_uevent(&class_dev->kobj, KOBJ_REMOVE); |
| 677 | kobject_del(&class_dev->kobj); | 709 | kobject_del(&class_dev->kobj); |
diff --git a/include/linux/device.h b/include/linux/device.h index f6e72a65a3f2..e8e53b9accc6 100644 --- a/include/linux/device.h +++ b/include/linux/device.h | |||
| @@ -200,6 +200,7 @@ extern int class_device_create_file(struct class_device *, | |||
| 200 | * @node: for internal use by the driver core only. | 200 | * @node: for internal use by the driver core only. |
| 201 | * @kobj: for internal use by the driver core only. | 201 | * @kobj: for internal use by the driver core only. |
| 202 | * @devt_attr: for internal use by the driver core only. | 202 | * @devt_attr: for internal use by the driver core only. |
| 203 | * @groups: optional additional groups to be created | ||
| 203 | * @dev: if set, a symlink to the struct device is created in the sysfs | 204 | * @dev: if set, a symlink to the struct device is created in the sysfs |
| 204 | * directory for this struct class device. | 205 | * directory for this struct class device. |
| 205 | * @class_data: pointer to whatever you want to store here for this struct | 206 | * @class_data: pointer to whatever you want to store here for this struct |
| @@ -228,6 +229,7 @@ struct class_device { | |||
| 228 | struct device * dev; /* not necessary, but nice to have */ | 229 | struct device * dev; /* not necessary, but nice to have */ |
| 229 | void * class_data; /* class-specific data */ | 230 | void * class_data; /* class-specific data */ |
| 230 | struct class_device *parent; /* parent of this child device, if there is one */ | 231 | struct class_device *parent; /* parent of this child device, if there is one */ |
| 232 | struct attribute_group ** groups; /* optional groups */ | ||
| 231 | 233 | ||
| 232 | void (*release)(struct class_device *dev); | 234 | void (*release)(struct class_device *dev); |
| 233 | int (*uevent)(struct class_device *dev, char **envp, | 235 | int (*uevent)(struct class_device *dev, char **envp, |
