diff --git a/drivers/base/core.c b/drivers/base/core.c
index 7a5336f7df897605f576f6bcd28f1e0f153fff7b..34ac18778d8a30173a2eecef077cd04c819527c3 100644
--- a/drivers/base/core.c
+++ b/drivers/base/core.c
@@ -95,6 +95,8 @@ static void device_release(struct kobject * kobj)
 
 	if (dev->release)
 		dev->release(dev);
+	else if (dev->type && dev->type->release)
+		dev->type->release(dev);
 	else if (dev->class && dev->class->dev_release)
 		dev->class->dev_release(dev);
 	else {
@@ -206,19 +208,25 @@ static int dev_uevent(struct kset *kset, struct kobject *kobj, char **envp,
 	if (dev->bus && dev->bus->uevent) {
 		/* have the bus specific function add its stuff */
 		retval = dev->bus->uevent(dev, envp, num_envp, buffer, buffer_size);
-			if (retval) {
-			pr_debug ("%s - uevent() returned %d\n",
+		if (retval)
+			pr_debug ("%s: bus uevent() returned %d\n",
 				  __FUNCTION__, retval);
-		}
 	}
 
 	if (dev->class && dev->class->dev_uevent) {
 		/* have the class specific function add its stuff */
 		retval = dev->class->dev_uevent(dev, envp, num_envp, buffer, buffer_size);
-			if (retval) {
-				pr_debug("%s - dev_uevent() returned %d\n",
-					 __FUNCTION__, retval);
-		}
+		if (retval)
+			pr_debug("%s: class uevent() returned %d\n",
+				 __FUNCTION__, retval);
+	}
+
+	if (dev->type && dev->type->uevent) {
+		/* have the device type specific fuction add its stuff */
+		retval = dev->type->uevent(dev, envp, num_envp, buffer, buffer_size);
+		if (retval)
+			pr_debug("%s: dev_type uevent() returned %d\n",
+				 __FUNCTION__, retval);
 	}
 
 	return retval;
@@ -269,37 +277,50 @@ static void device_remove_groups(struct device *dev)
 static int device_add_attrs(struct device *dev)
 {
 	struct class *class = dev->class;
+	struct device_type *type = dev->type;
 	int error = 0;
 	int i;
 
-	if (!class)
-		return 0;
-
-	if (class->dev_attrs) {
+	if (class && class->dev_attrs) {
 		for (i = 0; attr_name(class->dev_attrs[i]); i++) {
 			error = device_create_file(dev, &class->dev_attrs[i]);
 			if (error)
 				break;
 		}
+		if (error)
+			while (--i >= 0)
+				device_remove_file(dev, &class->dev_attrs[i]);
 	}
-	if (error)
-		while (--i >= 0)
-			device_remove_file(dev, &class->dev_attrs[i]);
+
+	if (type && type->attrs) {
+		for (i = 0; attr_name(type->attrs[i]); i++) {
+			error = device_create_file(dev, &type->attrs[i]);
+			if (error)
+				break;
+		}
+		if (error)
+			while (--i >= 0)
+				device_remove_file(dev, &type->attrs[i]);
+	}
+
 	return error;
 }
 
 static void device_remove_attrs(struct device *dev)
 {
 	struct class *class = dev->class;
+	struct device_type *type = dev->type;
 	int i;
 
-	if (!class)
-		return;
-
-	if (class->dev_attrs) {
+	if (class && class->dev_attrs) {
 		for (i = 0; attr_name(class->dev_attrs[i]); i++)
 			device_remove_file(dev, &class->dev_attrs[i]);
 	}
+
+	if (type && type->attrs) {
+		for (i = 0; attr_name(type->attrs[i]); i++)
+			device_remove_file(dev, &type->attrs[i]);
+	}
 }
 
 
diff --git a/drivers/usb/input/hid-lgff.c b/drivers/usb/input/hid-lgff.c
index e47466268565668d10285c3948f5acbc3b49a3ba..4f4fc3be192e9116f40128b03b12384dbd06e124 100644
--- a/drivers/usb/input/hid-lgff.c
+++ b/drivers/usb/input/hid-lgff.c
@@ -32,7 +32,7 @@
 #include <linux/hid.h>
 #include "usbhid.h"
 
-struct device_type {
+struct dev_type {
 	u16 idVendor;
 	u16 idProduct;
 	const signed short *ff;
@@ -48,7 +48,7 @@ static const signed short ff_joystick[] = {
 	-1
 };
 
-static const struct device_type devices[] = {
+static const struct dev_type devices[] = {
 	{ 0x046d, 0xc211, ff_rumble },
 	{ 0x046d, 0xc219, ff_rumble },
 	{ 0x046d, 0xc283, ff_joystick },
diff --git a/include/linux/device.h b/include/linux/device.h
index da7221913114ce31488fdeae8b7e81cba10f4299..e1e164f81eea3b5168d2310cb66deafb20fc9d08 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,
 					__attribute__((format(printf,5,6)));
 extern void class_device_destroy(struct class *cls, dev_t devt);
 
+struct device_type {
+	struct device_attribute *attrs;
+	int (*uevent)(struct device *dev, char **envp, int num_envp,
+		      char *buffer, int buffer_size);
+	void (*release)(struct device *dev);
+};
+
 /* interface for exporting device attributes */
 struct device_attribute {
 	struct attribute	attr;
@@ -356,6 +363,7 @@ struct device {
 
 	struct kobject kobj;
 	char	bus_id[BUS_ID_SIZE];	/* position on parent bus */
+	struct device_type	*type;
 	unsigned		is_registered:1;
 	struct device_attribute uevent_attr;
 	struct device_attribute *devt_attr;