aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGreg Kroah-Hartman <gregkh@suse.de>2006-06-28 19:19:58 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2006-09-26 00:08:38 -0400
commit2620efef7029bb040430f50f0fc148f2d5e002ad (patch)
tree433b19e18c40f6972ac0c936b844c997644dc176
parent64bb5d2c116478dba7501d2acf078ed74ba30c1f (diff)
Driver core: add ability for classes to handle devices properly
This adds two new callbacks to the class structure: int (*dev_uevent)(struct device *dev, char **envp, int num_envp, char *buffer, int buffer_size); void (*dev_release)(struct device *dev); And one pointer: struct device_attribute * dev_attrs; which all corrispond with the same thing as the "normal" class devices do, yet this is for when a struct device is bound to a class. Someday soon, struct class_device will go away, and then the other fields in this structure can be removed too. But this is necessary in order to get the transition to work properly. Tested out on a network core patch that converted it to use struct device instead of struct class_device. Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
-rw-r--r--drivers/base/core.c53
-rw-r--r--include/linux/device.h4
2 files changed, 57 insertions, 0 deletions
diff --git a/drivers/base/core.c b/drivers/base/core.c
index 5c91d0d81e78..f1228f25efe0 100644
--- a/drivers/base/core.c
+++ b/drivers/base/core.c
@@ -94,6 +94,8 @@ static void device_release(struct kobject * kobj)
94 94
95 if (dev->release) 95 if (dev->release)
96 dev->release(dev); 96 dev->release(dev);
97 else if (dev->class && dev->class->dev_release)
98 dev->class->dev_release(dev);
97 else { 99 else {
98 printk(KERN_ERR "Device '%s' does not have a release() function, " 100 printk(KERN_ERR "Device '%s' does not have a release() function, "
99 "it is broken and must be fixed.\n", 101 "it is broken and must be fixed.\n",
@@ -183,6 +185,15 @@ static int dev_uevent(struct kset *kset, struct kobject *kobj, char **envp,
183 } 185 }
184 } 186 }
185 187
188 if (dev->class && dev->class->dev_uevent) {
189 /* have the class specific function add its stuff */
190 retval = dev->class->dev_uevent(dev, envp, num_envp, buffer, buffer_size);
191 if (retval) {
192 pr_debug("%s - dev_uevent() returned %d\n",
193 __FUNCTION__, retval);
194 }
195 }
196
186 return retval; 197 return retval;
187} 198}
188 199
@@ -228,6 +239,43 @@ static void device_remove_groups(struct device *dev)
228 } 239 }
229} 240}
230 241
242static int device_add_attrs(struct device *dev)
243{
244 struct class *class = dev->class;
245 int error = 0;
246 int i;
247
248 if (!class)
249 return 0;
250
251 if (class->dev_attrs) {
252 for (i = 0; attr_name(class->dev_attrs[i]); i++) {
253 error = device_create_file(dev, &class->dev_attrs[i]);
254 if (error)
255 break;
256 }
257 }
258 if (error)
259 while (--i >= 0)
260 device_remove_file(dev, &class->dev_attrs[i]);
261 return error;
262}
263
264static void device_remove_attrs(struct device *dev)
265{
266 struct class *class = dev->class;
267 int i;
268
269 if (!class)
270 return;
271
272 if (class->dev_attrs) {
273 for (i = 0; attr_name(class->dev_attrs[i]); i++)
274 device_remove_file(dev, &class->dev_attrs[i]);
275 }
276}
277
278
231static ssize_t show_dev(struct device *dev, struct device_attribute *attr, 279static ssize_t show_dev(struct device *dev, struct device_attribute *attr,
232 char *buf) 280 char *buf)
233{ 281{
@@ -382,6 +430,8 @@ int device_add(struct device *dev)
382 } 430 }
383 } 431 }
384 432
433 if ((error = device_add_attrs(dev)))
434 goto AttrsError;
385 if ((error = device_add_groups(dev))) 435 if ((error = device_add_groups(dev)))
386 goto GroupError; 436 goto GroupError;
387 if ((error = device_pm_add(dev))) 437 if ((error = device_pm_add(dev)))
@@ -412,6 +462,8 @@ int device_add(struct device *dev)
412 PMError: 462 PMError:
413 device_remove_groups(dev); 463 device_remove_groups(dev);
414 GroupError: 464 GroupError:
465 device_remove_attrs(dev);
466 AttrsError:
415 if (dev->devt_attr) { 467 if (dev->devt_attr) {
416 device_remove_file(dev, dev->devt_attr); 468 device_remove_file(dev, dev->devt_attr);
417 kfree(dev->devt_attr); 469 kfree(dev->devt_attr);
@@ -509,6 +561,7 @@ void device_del(struct device * dev)
509 } 561 }
510 device_remove_file(dev, &dev->uevent_attr); 562 device_remove_file(dev, &dev->uevent_attr);
511 device_remove_groups(dev); 563 device_remove_groups(dev);
564 device_remove_attrs(dev);
512 565
513 /* Notify the platform of the removal, in case they 566 /* Notify the platform of the removal, in case they
514 * need to do anything... 567 * need to do anything...
diff --git a/include/linux/device.h b/include/linux/device.h
index 994d3ebd53f4..3122bd25ce42 100644
--- a/include/linux/device.h
+++ b/include/linux/device.h
@@ -151,12 +151,16 @@ struct class {
151 151
152 struct class_attribute * class_attrs; 152 struct class_attribute * class_attrs;
153 struct class_device_attribute * class_dev_attrs; 153 struct class_device_attribute * class_dev_attrs;
154 struct device_attribute * dev_attrs;
154 155
155 int (*uevent)(struct class_device *dev, char **envp, 156 int (*uevent)(struct class_device *dev, char **envp,
156 int num_envp, char *buffer, int buffer_size); 157 int num_envp, char *buffer, int buffer_size);
158 int (*dev_uevent)(struct device *dev, char **envp, int num_envp,
159 char *buffer, int buffer_size);
157 160
158 void (*release)(struct class_device *dev); 161 void (*release)(struct class_device *dev);
159 void (*class_release)(struct class *class); 162 void (*class_release)(struct class *class);
163 void (*dev_release)(struct device *dev);
160 164
161 int (*suspend)(struct device *, pm_message_t state); 165 int (*suspend)(struct device *, pm_message_t state);
162 int (*resume)(struct device *); 166 int (*resume)(struct device *);