aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKay Sievers <kay.sievers@novell.com>2006-10-07 15:54:55 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2007-02-07 13:37:14 -0500
commitf9f852df2faf76a2667949ddb4947d4b8f99f02f (patch)
tree3dfdbae06ef17c83266cc18ed77fcd1c51328c15
parent239378f16aa1ab5c502e42a06359d2de4f88ebb4 (diff)
Driver core: add device_type to struct device
This allows us to add type specific attributes, uevent vars and release funtions. A subsystem can carry different types of devices like the "block" subsys has disks and partitions. Both types create a different set of attributes, but belong to the same subsystem. This corresponds to the low level objects: kobject -> device (object/device data) kobj_type -> device_type (type of object/device we are embedded in) kset -> class/bus (list of objects/devices of a subsystem) Signed-off-by: Kay Sievers <kay.sievers@novell.com> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
-rw-r--r--drivers/base/core.c57
-rw-r--r--drivers/usb/input/hid-lgff.c4
-rw-r--r--include/linux/device.h8
3 files changed, 49 insertions, 20 deletions
diff --git a/drivers/base/core.c b/drivers/base/core.c
index 7a5336f7df89..34ac18778d8a 100644
--- a/drivers/base/core.c
+++ b/drivers/base/core.c
@@ -95,6 +95,8 @@ static void device_release(struct kobject * kobj)
95 95
96 if (dev->release) 96 if (dev->release)
97 dev->release(dev); 97 dev->release(dev);
98 else if (dev->type && dev->type->release)
99 dev->type->release(dev);
98 else if (dev->class && dev->class->dev_release) 100 else if (dev->class && dev->class->dev_release)
99 dev->class->dev_release(dev); 101 dev->class->dev_release(dev);
100 else { 102 else {
@@ -206,19 +208,25 @@ static int dev_uevent(struct kset *kset, struct kobject *kobj, char **envp,
206 if (dev->bus && dev->bus->uevent) { 208 if (dev->bus && dev->bus->uevent) {
207 /* have the bus specific function add its stuff */ 209 /* have the bus specific function add its stuff */
208 retval = dev->bus->uevent(dev, envp, num_envp, buffer, buffer_size); 210 retval = dev->bus->uevent(dev, envp, num_envp, buffer, buffer_size);
209 if (retval) { 211 if (retval)
210 pr_debug ("%s - uevent() returned %d\n", 212 pr_debug ("%s: bus uevent() returned %d\n",
211 __FUNCTION__, retval); 213 __FUNCTION__, retval);
212 }
213 } 214 }
214 215
215 if (dev->class && dev->class->dev_uevent) { 216 if (dev->class && dev->class->dev_uevent) {
216 /* have the class specific function add its stuff */ 217 /* have the class specific function add its stuff */
217 retval = dev->class->dev_uevent(dev, envp, num_envp, buffer, buffer_size); 218 retval = dev->class->dev_uevent(dev, envp, num_envp, buffer, buffer_size);
218 if (retval) { 219 if (retval)
219 pr_debug("%s - dev_uevent() returned %d\n", 220 pr_debug("%s: class uevent() returned %d\n",
220 __FUNCTION__, retval); 221 __FUNCTION__, retval);
221 } 222 }
223
224 if (dev->type && dev->type->uevent) {
225 /* have the device type specific fuction add its stuff */
226 retval = dev->type->uevent(dev, envp, num_envp, buffer, buffer_size);
227 if (retval)
228 pr_debug("%s: dev_type uevent() returned %d\n",
229 __FUNCTION__, retval);
222 } 230 }
223 231
224 return retval; 232 return retval;
@@ -269,37 +277,50 @@ static void device_remove_groups(struct device *dev)
269static int device_add_attrs(struct device *dev) 277static int device_add_attrs(struct device *dev)
270{ 278{
271 struct class *class = dev->class; 279 struct class *class = dev->class;
280 struct device_type *type = dev->type;
272 int error = 0; 281 int error = 0;
273 int i; 282 int i;
274 283
275 if (!class) 284 if (class && class->dev_attrs) {
276 return 0;
277
278 if (class->dev_attrs) {
279 for (i = 0; attr_name(class->dev_attrs[i]); i++) { 285 for (i = 0; attr_name(class->dev_attrs[i]); i++) {
280 error = device_create_file(dev, &class->dev_attrs[i]); 286 error = device_create_file(dev, &class->dev_attrs[i]);
281 if (error) 287 if (error)
282 break; 288 break;
283 } 289 }
290 if (error)
291 while (--i >= 0)
292 device_remove_file(dev, &class->dev_attrs[i]);
284 } 293 }
285 if (error) 294
286 while (--i >= 0) 295 if (type && type->attrs) {
287 device_remove_file(dev, &class->dev_attrs[i]); 296 for (i = 0; attr_name(type->attrs[i]); i++) {
297 error = device_create_file(dev, &type->attrs[i]);
298 if (error)
299 break;
300 }
301 if (error)
302 while (--i >= 0)
303 device_remove_file(dev, &type->attrs[i]);
304 }
305
288 return error; 306 return error;
289} 307}
290 308
291static void device_remove_attrs(struct device *dev) 309static void device_remove_attrs(struct device *dev)
292{ 310{
293 struct class *class = dev->class; 311 struct class *class = dev->class;
312 struct device_type *type = dev->type;
294 int i; 313 int i;
295 314
296 if (!class) 315 if (class && class->dev_attrs) {
297 return;
298
299 if (class->dev_attrs) {
300 for (i = 0; attr_name(class->dev_attrs[i]); i++) 316 for (i = 0; attr_name(class->dev_attrs[i]); i++)
301 device_remove_file(dev, &class->dev_attrs[i]); 317 device_remove_file(dev, &class->dev_attrs[i]);
302 } 318 }
319
320 if (type && type->attrs) {
321 for (i = 0; attr_name(type->attrs[i]); i++)
322 device_remove_file(dev, &type->attrs[i]);
323 }
303} 324}
304 325
305 326
diff --git a/drivers/usb/input/hid-lgff.c b/drivers/usb/input/hid-lgff.c
index e47466268565..4f4fc3be192e 100644
--- a/drivers/usb/input/hid-lgff.c
+++ b/drivers/usb/input/hid-lgff.c
@@ -32,7 +32,7 @@
32#include <linux/hid.h> 32#include <linux/hid.h>
33#include "usbhid.h" 33#include "usbhid.h"
34 34
35struct device_type { 35struct dev_type {
36 u16 idVendor; 36 u16 idVendor;
37 u16 idProduct; 37 u16 idProduct;
38 const signed short *ff; 38 const signed short *ff;
@@ -48,7 +48,7 @@ static const signed short ff_joystick[] = {
48 -1 48 -1
49}; 49};
50 50
51static const struct device_type devices[] = { 51static const struct dev_type devices[] = {
52 { 0x046d, 0xc211, ff_rumble }, 52 { 0x046d, 0xc211, ff_rumble },
53 { 0x046d, 0xc219, ff_rumble }, 53 { 0x046d, 0xc219, ff_rumble },
54 { 0x046d, 0xc283, ff_joystick }, 54 { 0x046d, 0xc283, ff_joystick },
diff --git a/include/linux/device.h b/include/linux/device.h
index da7221913114..e1e164f81eea 100644
--- a/include/linux/device.h
+++ b/include/linux/device.h
@@ -328,6 +328,13 @@ extern struct class_device *class_device_create(struct class *cls,
328 __attribute__((format(printf,5,6))); 328 __attribute__((format(printf,5,6)));
329extern void class_device_destroy(struct class *cls, dev_t devt); 329extern void class_device_destroy(struct class *cls, dev_t devt);
330 330
331struct device_type {
332 struct device_attribute *attrs;
333 int (*uevent)(struct device *dev, char **envp, int num_envp,
334 char *buffer, int buffer_size);
335 void (*release)(struct device *dev);
336};
337
331/* interface for exporting device attributes */ 338/* interface for exporting device attributes */
332struct device_attribute { 339struct device_attribute {
333 struct attribute attr; 340 struct attribute attr;
@@ -356,6 +363,7 @@ struct device {
356 363
357 struct kobject kobj; 364 struct kobject kobj;
358 char bus_id[BUS_ID_SIZE]; /* position on parent bus */ 365 char bus_id[BUS_ID_SIZE]; /* position on parent bus */
366 struct device_type *type;
359 unsigned is_registered:1; 367 unsigned is_registered:1;
360 struct device_attribute uevent_attr; 368 struct device_attribute uevent_attr;
361 struct device_attribute *devt_attr; 369 struct device_attribute *devt_attr;