aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStephen Hemminger <shemminger@osdl.org>2006-05-06 20:55:11 -0400
committerDavid S. Miller <davem@davemloft.net>2006-05-06 20:55:11 -0400
commit1498221d51a43d5fa1a580618591497d90f957d9 (patch)
tree20554a3fa474c9d09f649958b85b90a3de718477
parent5528e568a760442e0ec8fd2dea1f0791875a066b (diff)
[CLASS DEVICE]: add attribute_group creation
Extend the support of attribute groups in class_device's to allow groups to be created as part of the registration process. This allows network device's to avoid race between registration and creating groups. Note that unlike attributes that are a property of the class object, the groups are a property of the class_device object. This is done because there are different types of network devices (wireless for example). Signed-off-by: Stephen Hemminger <shemminger@osdl.org> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--drivers/base/class.c32
-rw-r--r--include/linux/device.h2
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
459static 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 }
474out:
475 return error;
476}
477
478static 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
459static ssize_t show_dev(struct class_device *class_dev, char *buf) 488static 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,