Merge master.kernel.org:/pub/scm/linux/kernel/git/gregkh/driver-2.6
diff --git a/Documentation/Changes b/Documentation/Changes
index 27232be..783ddc3 100644
--- a/Documentation/Changes
+++ b/Documentation/Changes
@@ -65,7 +65,7 @@
 o  nfs-utils              1.0.5                   # showmount --version
 o  procps                 3.2.0                   # ps --version
 o  oprofile               0.9                     # oprofiled --version
-o  udev                   058                     # udevinfo -V
+o  udev                   071                     # udevinfo -V
 
 Kernel compilation
 ==================
diff --git a/Documentation/DocBook/writing_usb_driver.tmpl b/Documentation/DocBook/writing_usb_driver.tmpl
index 51f3bfb..008a341 100644
--- a/Documentation/DocBook/writing_usb_driver.tmpl
+++ b/Documentation/DocBook/writing_usb_driver.tmpl
@@ -345,8 +345,7 @@
   <programlisting>
 static inline void skel_delete (struct usb_skel *dev)
 {
-    if (dev->bulk_in_buffer != NULL)
-        kfree (dev->bulk_in_buffer);
+    kfree (dev->bulk_in_buffer);
     if (dev->bulk_out_buffer != NULL)
         usb_buffer_free (dev->udev, dev->bulk_out_size,
             dev->bulk_out_buffer,
diff --git a/Documentation/driver-model/driver.txt b/Documentation/driver-model/driver.txt
index fabaca1..59806c9 100644
--- a/Documentation/driver-model/driver.txt
+++ b/Documentation/driver-model/driver.txt
@@ -14,8 +14,8 @@
         int     (*probe)        (struct device * dev);
         int     (*remove)       (struct device * dev);
 
-        int     (*suspend)      (struct device * dev, pm_message_t state, u32 level);
-        int     (*resume)       (struct device * dev, u32 level);
+        int     (*suspend)      (struct device * dev, pm_message_t state);
+        int     (*resume)       (struct device * dev);
 };
 
 
@@ -194,69 +194,13 @@
 If the device is still present, it should quiesce the device and place
 it into a supported low-power state.
 
-	int	(*suspend)	(struct device * dev, pm_message_t state, u32 level);
+	int	(*suspend)	(struct device * dev, pm_message_t state);
 
-suspend is called to put the device in a low power state. There are
-several stages to successfully suspending a device, which is denoted in
-the @level parameter. Breaking the suspend transition into several
-stages affords the platform flexibility in performing device power
-management based on the requirements of the system and the
-user-defined policy.
+suspend is called to put the device in a low power state.
 
-SUSPEND_NOTIFY notifies the device that a suspend transition is about
-to happen. This happens on system power state transitions to verify
-that all devices can successfully suspend.
+	int	(*resume)	(struct device * dev);
 
-A driver may choose to fail on this call, which should cause the
-entire suspend transition to fail. A driver should fail only if it
-knows that the device will not be able to be resumed properly when the
-system wakes up again. It could also fail if it somehow determines it
-is in the middle of an operation too important to stop.
-
-SUSPEND_DISABLE tells the device to stop I/O transactions. When it
-stops transactions, or what it should do with unfinished transactions
-is a policy of the driver. After this call, the driver should not
-accept any other I/O requests.
-
-SUSPEND_SAVE_STATE tells the device to save the context of the
-hardware. This includes any bus-specific hardware state and
-device-specific hardware state. A pointer to this saved state can be
-stored in the device's saved_state field.
-
-SUSPEND_POWER_DOWN tells the driver to place the device in the low
-power state requested. 
-
-Whether suspend is called with a given level is a policy of the
-platform. Some levels may be omitted; drivers must not assume the
-reception of any level. However, all levels must be called in the
-order above; i.e. notification will always come before disabling;
-disabling the device will come before suspending the device.
-
-All calls are made with interrupts enabled, except for the
-SUSPEND_POWER_DOWN level.
-
-	int	(*resume)	(struct device * dev, u32 level);
-
-Resume is used to bring a device back from a low power state. Like the
-suspend transition, it happens in several stages. 
-
-RESUME_POWER_ON tells the driver to set the power state to the state
-before the suspend call (The device could have already been in a low
-power state before the suspend call to put in a lower power state). 
-
-RESUME_RESTORE_STATE tells the driver to restore the state saved by
-the SUSPEND_SAVE_STATE suspend call. 
-
-RESUME_ENABLE tells the driver to start accepting I/O transactions
-again. Depending on driver policy, the device may already have pending
-I/O requests. 
-
-RESUME_POWER_ON is called with interrupts disabled. The other resume
-levels are called with interrupts enabled. 
-
-As with the various suspend stages, the driver must not assume that
-any other resume calls have been or will be made. Each call should be
-self-contained and not dependent on any external state.
+Resume is used to bring a device back from a low power state.
 
 
 Attributes
diff --git a/Documentation/driver-model/porting.txt b/Documentation/driver-model/porting.txt
index ff2fef2..98b233c 100644
--- a/Documentation/driver-model/porting.txt
+++ b/Documentation/driver-model/porting.txt
@@ -350,7 +350,7 @@
 over. bus->match() is called for each device that is not already
 claimed by a driver. 
 
-When a device is successfully bound to a device, device->driver is
+When a device is successfully bound to a driver, device->driver is
 set, the device is added to a per-driver list of devices, and a
 symlink is created in the driver's sysfs directory that points to the
 device's physical directory:
diff --git a/arch/arm/common/locomo.c b/arch/arm/common/locomo.c
index e8053d1..5cdb412 100644
--- a/arch/arm/common/locomo.c
+++ b/arch/arm/common/locomo.c
@@ -550,15 +550,12 @@
 	u16	LCM_SPIMD;
 };
 
-static int locomo_suspend(struct device *dev, pm_message_t state, u32 level)
+static int locomo_suspend(struct device *dev, pm_message_t state)
 {
 	struct locomo *lchip = dev_get_drvdata(dev);
 	struct locomo_save_data *save;
 	unsigned long flags;
 
-	if (level != SUSPEND_DISABLE)
-		return 0;
-
 	save = kmalloc(sizeof(struct locomo_save_data), GFP_KERNEL);
 	if (!save)
 		return -ENOMEM;
@@ -597,16 +594,13 @@
 	return 0;
 }
 
-static int locomo_resume(struct device *dev, u32 level)
+static int locomo_resume(struct device *dev)
 {
 	struct locomo *lchip = dev_get_drvdata(dev);
 	struct locomo_save_data *save;
 	unsigned long r;
 	unsigned long flags;
 	
-	if (level != RESUME_ENABLE)
-		return 0;
-
 	save = (struct locomo_save_data *) dev->power.saved_state;
 	if (!save)
 		return 0;
diff --git a/arch/arm/common/sa1111.c b/arch/arm/common/sa1111.c
index 1a47fbf9c..21e2a51 100644
--- a/arch/arm/common/sa1111.c
+++ b/arch/arm/common/sa1111.c
@@ -801,7 +801,7 @@
 
 #ifdef CONFIG_PM
 
-static int sa1111_suspend(struct device *dev, pm_message_t state, u32 level)
+static int sa1111_suspend(struct device *dev, pm_message_t state)
 {
 	struct sa1111 *sachip = dev_get_drvdata(dev);
 	struct sa1111_save_data *save;
@@ -809,9 +809,6 @@
 	unsigned int val;
 	void __iomem *base;
 
-	if (level != SUSPEND_DISABLE)
-		return 0;
-
 	save = kmalloc(sizeof(struct sa1111_save_data), GFP_KERNEL);
 	if (!save)
 		return -ENOMEM;
@@ -856,23 +853,19 @@
 /*
  *	sa1111_resume - Restore the SA1111 device state.
  *	@dev: device to restore
- *	@level: resume level
  *
  *	Restore the general state of the SA1111; clock control and
  *	interrupt controller.  Other parts of the SA1111 must be
  *	restored by their respective drivers, and must be called
  *	via LDM after this function.
  */
-static int sa1111_resume(struct device *dev, u32 level)
+static int sa1111_resume(struct device *dev)
 {
 	struct sa1111 *sachip = dev_get_drvdata(dev);
 	struct sa1111_save_data *save;
 	unsigned long flags, id;
 	void __iomem *base;
 
-	if (level != RESUME_ENABLE)
-		return 0;
-
 	save = (struct sa1111_save_data *)dev->power.saved_state;
 	if (!save)
 		return 0;
diff --git a/arch/arm/common/scoop.c b/arch/arm/common/scoop.c
index 9e5245c..e8356b7 100644
--- a/arch/arm/common/scoop.c
+++ b/arch/arm/common/scoop.c
@@ -102,26 +102,24 @@
 }
 
 #ifdef CONFIG_PM
-static int scoop_suspend(struct device *dev, pm_message_t state, uint32_t level)
+static int scoop_suspend(struct device *dev, pm_message_t state)
 {
-	if (level == SUSPEND_POWER_DOWN) {
-		struct scoop_dev *sdev = dev_get_drvdata(dev);
+	struct scoop_dev *sdev = dev_get_drvdata(dev);
 
-		check_scoop_reg(sdev);
-  		sdev->scoop_gpwr = SCOOP_REG(sdev->base, SCOOP_GPWR);
-		SCOOP_REG(sdev->base, SCOOP_GPWR) = (sdev->scoop_gpwr & ~sdev->suspend_clr) | sdev->suspend_set;
-	}
+	check_scoop_reg(sdev);
+	sdev->scoop_gpwr = SCOOP_REG(sdev->base, SCOOP_GPWR);
+	SCOOP_REG(sdev->base, SCOOP_GPWR) = (sdev->scoop_gpwr & ~sdev->suspend_clr) | sdev->suspend_set;
+
 	return 0;
 }
 
-static int scoop_resume(struct device *dev, uint32_t level)
+static int scoop_resume(struct device *dev)
 {
-	if (level == RESUME_POWER_ON) {
-		struct scoop_dev *sdev = dev_get_drvdata(dev);
+	struct scoop_dev *sdev = dev_get_drvdata(dev);
 
-		check_scoop_reg(sdev);
-		SCOOP_REG(sdev->base,SCOOP_GPWR) = sdev->scoop_gpwr;
-	}
+	check_scoop_reg(sdev);
+	SCOOP_REG(sdev->base,SCOOP_GPWR) = sdev->scoop_gpwr;
+
 	return 0;
 }
 #else
diff --git a/arch/arm/mach-pxa/corgi_ssp.c b/arch/arm/mach-pxa/corgi_ssp.c
index 0ef4282..136c269 100644
--- a/arch/arm/mach-pxa/corgi_ssp.c
+++ b/arch/arm/mach-pxa/corgi_ssp.c
@@ -222,24 +222,22 @@
 	return 0;
 }
 
-static int corgi_ssp_suspend(struct device *dev, pm_message_t state, u32 level)
+static int corgi_ssp_suspend(struct device *dev, pm_message_t state)
 {
-	if (level == SUSPEND_POWER_DOWN) {
-		ssp_flush(&corgi_ssp_dev);
-		ssp_save_state(&corgi_ssp_dev,&corgi_ssp_state);
-	}
+	ssp_flush(&corgi_ssp_dev);
+	ssp_save_state(&corgi_ssp_dev,&corgi_ssp_state);
+
 	return 0;
 }
 
-static int corgi_ssp_resume(struct device *dev, u32 level)
+static int corgi_ssp_resume(struct device *dev)
 {
-	if (level == RESUME_POWER_ON) {
-		GPSR(ssp_machinfo->cs_lcdcon) = GPIO_bit(ssp_machinfo->cs_lcdcon);  /* High - Disable LCD Control/Timing Gen */
-		GPSR(ssp_machinfo->cs_max1111) = GPIO_bit(ssp_machinfo->cs_max1111); /* High - Disable MAX1111*/
-		GPSR(ssp_machinfo->cs_ads7846) = GPIO_bit(ssp_machinfo->cs_ads7846); /* High - Disable ADS7846*/
-		ssp_restore_state(&corgi_ssp_dev,&corgi_ssp_state);
-		ssp_enable(&corgi_ssp_dev);
-	}
+	GPSR(ssp_machinfo->cs_lcdcon) = GPIO_bit(ssp_machinfo->cs_lcdcon);  /* High - Disable LCD Control/Timing Gen */
+	GPSR(ssp_machinfo->cs_max1111) = GPIO_bit(ssp_machinfo->cs_max1111); /* High - Disable MAX1111*/
+	GPSR(ssp_machinfo->cs_ads7846) = GPIO_bit(ssp_machinfo->cs_ads7846); /* High - Disable ADS7846*/
+	ssp_restore_state(&corgi_ssp_dev,&corgi_ssp_state);
+	ssp_enable(&corgi_ssp_dev);
+
 	return 0;
 }
 
diff --git a/arch/arm/mach-sa1100/neponset.c b/arch/arm/mach-sa1100/neponset.c
index 0c5eff3..052e4ca 100644
--- a/arch/arm/mach-sa1100/neponset.c
+++ b/arch/arm/mach-sa1100/neponset.c
@@ -178,33 +178,27 @@
 /*
  * LDM power management.
  */
-static int neponset_suspend(struct device *dev, pm_message_t state, u32 level)
+static int neponset_suspend(struct device *dev, pm_message_t state)
 {
 	/*
 	 * Save state.
 	 */
-	if (level == SUSPEND_SAVE_STATE ||
-	    level == SUSPEND_DISABLE ||
-	    level == SUSPEND_POWER_DOWN) {
-		if (!dev->power.saved_state)
-			dev->power.saved_state = kmalloc(sizeof(unsigned int), GFP_KERNEL);
-		if (!dev->power.saved_state)
-			return -ENOMEM;
+	if (!dev->power.saved_state)
+		dev->power.saved_state = kmalloc(sizeof(unsigned int), GFP_KERNEL);
+	if (!dev->power.saved_state)
+		return -ENOMEM;
 
-		*(unsigned int *)dev->power.saved_state = NCR_0;
-	}
+	*(unsigned int *)dev->power.saved_state = NCR_0;
 
 	return 0;
 }
 
-static int neponset_resume(struct device *dev, u32 level)
+static int neponset_resume(struct device *dev)
 {
-	if (level == RESUME_RESTORE_STATE || level == RESUME_ENABLE) {
-		if (dev->power.saved_state) {
-			NCR_0 = *(unsigned int *)dev->power.saved_state;
-			kfree(dev->power.saved_state);
-			dev->power.saved_state = NULL;
-		}
+	if (dev->power.saved_state) {
+		NCR_0 = *(unsigned int *)dev->power.saved_state;
+		kfree(dev->power.saved_state);
+		dev->power.saved_state = NULL;
 	}
 
 	return 0;
diff --git a/arch/i386/kernel/cpuid.c b/arch/i386/kernel/cpuid.c
index 4647db4..13bae79 100644
--- a/arch/i386/kernel/cpuid.c
+++ b/arch/i386/kernel/cpuid.c
@@ -163,7 +163,7 @@
 	int err = 0;
 	struct class_device *class_err;
 
-	class_err = class_device_create(cpuid_class, MKDEV(CPUID_MAJOR, i), NULL, "cpu%d",i);
+	class_err = class_device_create(cpuid_class, NULL, MKDEV(CPUID_MAJOR, i), NULL, "cpu%d",i);
 	if (IS_ERR(class_err))
 		err = PTR_ERR(class_err);
 	return err;
diff --git a/arch/i386/kernel/msr.c b/arch/i386/kernel/msr.c
index 03100d6..44470fe 100644
--- a/arch/i386/kernel/msr.c
+++ b/arch/i386/kernel/msr.c
@@ -246,7 +246,7 @@
 	int err = 0;
 	struct class_device *class_err;
 
-	class_err = class_device_create(msr_class, MKDEV(MSR_MAJOR, i), NULL, "msr%d",i);
+	class_err = class_device_create(msr_class, NULL, MKDEV(MSR_MAJOR, i), NULL, "msr%d",i);
 	if (IS_ERR(class_err)) 
 		err = PTR_ERR(class_err);
 	return err;
diff --git a/drivers/base/attribute_container.c b/drivers/base/attribute_container.c
index 6b2eb6f..2a7d7ae 100644
--- a/drivers/base/attribute_container.c
+++ b/drivers/base/attribute_container.c
@@ -19,6 +19,8 @@
 #include <linux/list.h>
 #include <linux/module.h>
 
+#include "base.h"
+
 /* This is a private structure used to tie the classdev and the
  * container .. it should never be visible outside this file */
 struct internal_container {
diff --git a/drivers/base/base.h b/drivers/base/base.h
index 783752b..e3b548d 100644
--- a/drivers/base/base.h
+++ b/drivers/base/base.h
@@ -1,3 +1,15 @@
+
+/* initialisation functions */
+
+extern int devices_init(void);
+extern int buses_init(void);
+extern int classes_init(void);
+extern int firmware_init(void);
+extern int platform_bus_init(void);
+extern int system_bus_init(void);
+extern int cpu_dev_init(void);
+extern int attribute_container_init(void);
+
 extern int bus_add_device(struct device * dev);
 extern void bus_remove_device(struct device * dev);
 
diff --git a/drivers/base/class.c b/drivers/base/class.c
index ce23dc8..c3e5697 100644
--- a/drivers/base/class.c
+++ b/drivers/base/class.c
@@ -99,7 +99,8 @@
 
 void class_put(struct class * cls)
 {
-	subsys_put(&cls->subsys);
+	if (cls)
+		subsys_put(&cls->subsys);
 }
 
 
@@ -165,14 +166,25 @@
 
 static void class_create_release(struct class *cls)
 {
+	pr_debug("%s called for %s\n", __FUNCTION__, cls->name);
 	kfree(cls);
 }
 
 static void class_device_create_release(struct class_device *class_dev)
 {
+	pr_debug("%s called for %s\n", __FUNCTION__, class_dev->class_id);
 	kfree(class_dev);
 }
 
+/* needed to allow these devices to have parent class devices */
+static int class_device_create_hotplug(struct class_device *class_dev,
+				       char **envp, int num_envp,
+				       char *buffer, int buffer_size)
+{
+	pr_debug("%s called for %s\n", __FUNCTION__, class_dev->class_id);
+	return 0;
+}
+
 /**
  * class_create - create a struct class structure
  * @owner: pointer to the module that is to "own" this struct class
@@ -301,10 +313,12 @@
 	kfree(cd->devt_attr);
 	cd->devt_attr = NULL;
 
-	if (cls->release)
+	if (cd->release)
+		cd->release(cd);
+	else if (cls->release)
 		cls->release(cd);
 	else {
-		printk(KERN_ERR "Device class '%s' does not have a release() function, "
+		printk(KERN_ERR "Class Device '%s' does not have a release() function, "
 			"it is broken and must be fixed.\n",
 			cd->class_id);
 		WARN_ON(1);
@@ -382,14 +396,18 @@
 	buffer = &buffer[length];
 	buffer_size -= length;
 
-	if (class_dev->class->hotplug) {
-		/* have the bus specific function add its stuff */
-		retval = class_dev->class->hotplug (class_dev, envp, num_envp,
-						    buffer, buffer_size);
-			if (retval) {
-			pr_debug ("%s - hotplug() returned %d\n",
-				  __FUNCTION__, retval);
-		}
+	if (class_dev->hotplug) {
+		/* have the class device specific function add its stuff */
+		retval = class_dev->hotplug(class_dev, envp, num_envp,
+					    buffer, buffer_size);
+		if (retval)
+			pr_debug("class_dev->hotplug() returned %d\n", retval);
+	} else if (class_dev->class->hotplug) {
+		/* have the class specific function add its stuff */
+		retval = class_dev->class->hotplug(class_dev, envp, num_envp,
+						   buffer, buffer_size);
+		if (retval)
+			pr_debug("class->hotplug() returned %d\n", retval);
 	}
 
 	return retval;
@@ -442,6 +460,13 @@
 	return print_dev_t(buf, class_dev->devt);
 }
 
+static ssize_t store_uevent(struct class_device *class_dev,
+			    const char *buf, size_t count)
+{
+	kobject_hotplug(&class_dev->kobj, KOBJ_ADD);
+	return count;
+}
+
 void class_device_initialize(struct class_device *class_dev)
 {
 	kobj_set_kset_s(class_dev, class_obj_subsys);
@@ -469,34 +494,45 @@
 
 int class_device_add(struct class_device *class_dev)
 {
-	struct class * parent = NULL;
-	struct class_interface * class_intf;
+	struct class *parent_class = NULL;
+	struct class_device *parent_class_dev = NULL;
+	struct class_interface *class_intf;
 	char *class_name = NULL;
-	int error;
+	int error = -EINVAL;
 
 	class_dev = class_device_get(class_dev);
 	if (!class_dev)
 		return -EINVAL;
 
-	if (!strlen(class_dev->class_id)) {
-		error = -EINVAL;
+	if (!strlen(class_dev->class_id))
 		goto register_done;
-	}
 
-	parent = class_get(class_dev->class);
+	parent_class = class_get(class_dev->class);
+	if (!parent_class)
+		goto register_done;
+	parent_class_dev = class_device_get(class_dev->parent);
 
 	pr_debug("CLASS: registering class device: ID = '%s'\n",
 		 class_dev->class_id);
 
 	/* first, register with generic layer. */
 	kobject_set_name(&class_dev->kobj, "%s", class_dev->class_id);
-	if (parent)
-		class_dev->kobj.parent = &parent->subsys.kset.kobj;
+	if (parent_class_dev)
+		class_dev->kobj.parent = &parent_class_dev->kobj;
+	else
+		class_dev->kobj.parent = &parent_class->subsys.kset.kobj;
 
-	if ((error = kobject_add(&class_dev->kobj)))
+	error = kobject_add(&class_dev->kobj);
+	if (error)
 		goto register_done;
 
 	/* add the needed attributes to this device */
+	class_dev->uevent_attr.attr.name = "uevent";
+	class_dev->uevent_attr.attr.mode = S_IWUSR;
+	class_dev->uevent_attr.attr.owner = parent_class->owner;
+	class_dev->uevent_attr.store = store_uevent;
+	class_device_create_file(class_dev, &class_dev->uevent_attr);
+
 	if (MAJOR(class_dev->devt)) {
 		struct class_device_attribute *attr;
 		attr = kzalloc(sizeof(*attr), GFP_KERNEL);
@@ -505,12 +541,10 @@
 			kobject_del(&class_dev->kobj);
 			goto register_done;
 		}
-
 		attr->attr.name = "dev";
 		attr->attr.mode = S_IRUGO;
-		attr->attr.owner = parent->owner;
+		attr->attr.owner = parent_class->owner;
 		attr->show = show_dev;
-		attr->store = NULL;
 		class_device_create_file(class_dev, attr);
 		class_dev->devt_attr = attr;
 	}
@@ -524,20 +558,23 @@
 				  class_name);
 	}
 
-	/* notify any interfaces this device is now here */
-	if (parent) {
-		down(&parent->sem);
-		list_add_tail(&class_dev->node, &parent->children);
-		list_for_each_entry(class_intf, &parent->interfaces, node)
-			if (class_intf->add)
-				class_intf->add(class_dev);
-		up(&parent->sem);
-	}
 	kobject_hotplug(&class_dev->kobj, KOBJ_ADD);
 
+	/* notify any interfaces this device is now here */
+	if (parent_class) {
+		down(&parent_class->sem);
+		list_add_tail(&class_dev->node, &parent_class->children);
+		list_for_each_entry(class_intf, &parent_class->interfaces, node)
+			if (class_intf->add)
+				class_intf->add(class_dev, class_intf);
+		up(&parent_class->sem);
+	}
+
  register_done:
-	if (error && parent)
-		class_put(parent);
+	if (error) {
+		class_put(parent_class);
+		class_device_put(parent_class_dev);
+	}
 	class_device_put(class_dev);
 	kfree(class_name);
 	return error;
@@ -552,21 +589,28 @@
 /**
  * class_device_create - creates a class device and registers it with sysfs
  * @cs: pointer to the struct class that this device should be registered to.
+ * @parent: pointer to the parent struct class_device of this new device, if any.
  * @dev: the dev_t for the char device to be added.
  * @device: a pointer to a struct device that is assiociated with this class device.
  * @fmt: string for the class device's name
  *
  * This function can be used by char device classes.  A struct
  * class_device will be created in sysfs, registered to the specified
- * class.  A "dev" file will be created, showing the dev_t for the
- * device.  The pointer to the struct class_device will be returned from
- * the call.  Any further sysfs files that might be required can be
- * created using this pointer.
+ * class.
+ * A "dev" file will be created, showing the dev_t for the device, if
+ * the dev_t is not 0,0.
+ * If a pointer to a parent struct class_device is passed in, the newly
+ * created struct class_device will be a child of that device in sysfs.
+ * The pointer to the struct class_device will be returned from the
+ * call.  Any further sysfs files that might be required can be created
+ * using this pointer.
  *
  * Note: the struct class passed to this function must have previously
  * been created with a call to class_create().
  */
-struct class_device *class_device_create(struct class *cls, dev_t devt,
+struct class_device *class_device_create(struct class *cls,
+					 struct class_device *parent,
+					 dev_t devt,
 					 struct device *device, char *fmt, ...)
 {
 	va_list args;
@@ -585,6 +629,9 @@
 	class_dev->devt = devt;
 	class_dev->dev = device;
 	class_dev->class = cls;
+	class_dev->parent = parent;
+	class_dev->release = class_device_create_release;
+	class_dev->hotplug = class_device_create_hotplug;
 
 	va_start(args, fmt);
 	vsnprintf(class_dev->class_id, BUS_ID_SIZE, fmt, args);
@@ -602,17 +649,18 @@
 
 void class_device_del(struct class_device *class_dev)
 {
-	struct class * parent = class_dev->class;
-	struct class_interface * class_intf;
+	struct class *parent_class = class_dev->class;
+	struct class_device *parent_device = class_dev->parent;
+	struct class_interface *class_intf;
 	char *class_name = NULL;
 
-	if (parent) {
-		down(&parent->sem);
+	if (parent_class) {
+		down(&parent_class->sem);
 		list_del_init(&class_dev->node);
-		list_for_each_entry(class_intf, &parent->interfaces, node)
+		list_for_each_entry(class_intf, &parent_class->interfaces, node)
 			if (class_intf->remove)
-				class_intf->remove(class_dev);
-		up(&parent->sem);
+				class_intf->remove(class_dev, class_intf);
+		up(&parent_class->sem);
 	}
 
 	if (class_dev->dev) {
@@ -620,6 +668,7 @@
 		sysfs_remove_link(&class_dev->kobj, "device");
 		sysfs_remove_link(&class_dev->dev->kobj, class_name);
 	}
+	class_device_remove_file(class_dev, &class_dev->uevent_attr);
 	if (class_dev->devt_attr)
 		class_device_remove_file(class_dev, class_dev->devt_attr);
 	class_device_remove_attrs(class_dev);
@@ -627,8 +676,8 @@
 	kobject_hotplug(&class_dev->kobj, KOBJ_REMOVE);
 	kobject_del(&class_dev->kobj);
 
-	if (parent)
-		class_put(parent);
+	class_device_put(parent_device);
+	class_put(parent_class);
 	kfree(class_name);
 }
 
@@ -708,7 +757,8 @@
 
 void class_device_put(struct class_device *class_dev)
 {
-	kobject_put(&class_dev->kobj);
+	if (class_dev)
+		kobject_put(&class_dev->kobj);
 }
 
 
@@ -728,7 +778,7 @@
 	list_add_tail(&class_intf->node, &parent->interfaces);
 	if (class_intf->add) {
 		list_for_each_entry(class_dev, &parent->children, node)
-			class_intf->add(class_dev);
+			class_intf->add(class_dev, class_intf);
 	}
 	up(&parent->sem);
 
@@ -747,7 +797,7 @@
 	list_del_init(&class_intf->node);
 	if (class_intf->remove) {
 		list_for_each_entry(class_dev, &parent->children, node)
-			class_intf->remove(class_dev);
+			class_intf->remove(class_dev, class_intf);
 	}
 	up(&parent->sem);
 
diff --git a/drivers/base/core.c b/drivers/base/core.c
index 6ab73f5..8615b42 100644
--- a/drivers/base/core.c
+++ b/drivers/base/core.c
@@ -154,6 +154,13 @@
 	.hotplug =	dev_hotplug,
 };
 
+static ssize_t store_uevent(struct device *dev, struct device_attribute *attr,
+			    const char *buf, size_t count)
+{
+	kobject_hotplug(&dev->kobj, KOBJ_ADD);
+	return count;
+}
+
 /**
  *	device_subsys - structure to be registered with kobject core.
  */
@@ -225,6 +232,7 @@
 		   klist_children_put);
 	INIT_LIST_HEAD(&dev->dma_pools);
 	init_MUTEX(&dev->sem);
+	device_init_wakeup(dev, 0);
 }
 
 /**
@@ -258,6 +266,14 @@
 
 	if ((error = kobject_add(&dev->kobj)))
 		goto Error;
+
+	dev->uevent_attr.attr.name = "uevent";
+	dev->uevent_attr.attr.mode = S_IWUSR;
+	if (dev->driver)
+		dev->uevent_attr.attr.owner = dev->driver->owner;
+	dev->uevent_attr.store = store_uevent;
+	device_create_file(dev, &dev->uevent_attr);
+
 	kobject_hotplug(&dev->kobj, KOBJ_ADD);
 	if ((error = device_pm_add(dev)))
 		goto PMError;
@@ -349,6 +365,7 @@
 
 	if (parent)
 		klist_del(&dev->knode_parent);
+	device_remove_file(dev, &dev->uevent_attr);
 
 	/* Notify the platform of the removal, in case they
 	 * need to do anything...
@@ -390,11 +407,11 @@
 
 /**
  *	device_for_each_child - device child iterator.
- *	@dev:	parent struct device.
+ *	@parent: parent struct device.
  *	@data:	data for the callback.
  *	@fn:	function to be called for each device.
  *
- *	Iterate over @dev's child devices, and call @fn for each,
+ *	Iterate over @parent's child devices, and call @fn for each,
  *	passing it @data.
  *
  *	We check the return of @fn each time. If it returns anything
diff --git a/drivers/base/cpu.c b/drivers/base/cpu.c
index b79badd..081c927 100644
--- a/drivers/base/cpu.c
+++ b/drivers/base/cpu.c
@@ -9,6 +9,7 @@
 #include <linux/topology.h>
 #include <linux/device.h>
 
+#include "base.h"
 
 struct sysdev_class cpu_sysdev_class = {
 	set_kset_name("cpu"),
diff --git a/drivers/base/driver.c b/drivers/base/driver.c
index ef3fe51..161f3a3 100644
--- a/drivers/base/driver.c
+++ b/drivers/base/driver.c
@@ -28,6 +28,7 @@
 /**
  *	driver_for_each_device - Iterator for devices bound to a driver.
  *	@drv:	Driver we're iterating.
+ *	@start: Device to begin with
  *	@data:	Data to pass to the callback.
  *	@fn:	Function to call for each device.
  *
@@ -57,7 +58,7 @@
 
 /**
  * driver_find_device - device iterator for locating a particular device.
- * @driver: The device's driver
+ * @drv: The device's driver
  * @start: Device to begin with
  * @data: Data to pass to match function
  * @match: Callback function to check device
diff --git a/drivers/base/firmware.c b/drivers/base/firmware.c
index 88ab044..cb1b98a 100644
--- a/drivers/base/firmware.c
+++ b/drivers/base/firmware.c
@@ -11,6 +11,9 @@
 #include <linux/kobject.h>
 #include <linux/module.h>
 #include <linux/init.h>
+#include <linux/device.h>
+
+#include "base.h"
 
 static decl_subsys(firmware, NULL, NULL);
 
diff --git a/drivers/base/init.c b/drivers/base/init.c
index a76ae5a..84e604e 100644
--- a/drivers/base/init.c
+++ b/drivers/base/init.c
@@ -10,14 +10,8 @@
 #include <linux/device.h>
 #include <linux/init.h>
 
-extern int devices_init(void);
-extern int buses_init(void);
-extern int classes_init(void);
-extern int firmware_init(void);
-extern int platform_bus_init(void);
-extern int system_bus_init(void);
-extern int cpu_dev_init(void);
-extern int attribute_container_init(void);
+#include "base.h"
+
 /**
  *	driver_init - initialize driver model.
  *
diff --git a/drivers/base/platform.c b/drivers/base/platform.c
index 361e204..75ce871 100644
--- a/drivers/base/platform.c
+++ b/drivers/base/platform.c
@@ -17,6 +17,8 @@
 #include <linux/bootmem.h>
 #include <linux/err.h>
 
+#include "base.h"
+
 struct device platform_bus = {
 	.bus_id		= "platform",
 };
@@ -279,13 +281,9 @@
 {
 	int ret = 0;
 
-	if (dev->driver && dev->driver->suspend) {
-		ret = dev->driver->suspend(dev, state, SUSPEND_DISABLE);
-		if (ret == 0)
-			ret = dev->driver->suspend(dev, state, SUSPEND_SAVE_STATE);
-		if (ret == 0)
-			ret = dev->driver->suspend(dev, state, SUSPEND_POWER_DOWN);
-	}
+	if (dev->driver && dev->driver->suspend)
+		ret = dev->driver->suspend(dev, state);
+
 	return ret;
 }
 
@@ -293,13 +291,9 @@
 {
 	int ret = 0;
 
-	if (dev->driver && dev->driver->resume) {
-		ret = dev->driver->resume(dev, RESUME_POWER_ON);
-		if (ret == 0)
-			ret = dev->driver->resume(dev, RESUME_RESTORE_STATE);
-		if (ret == 0)
-			ret = dev->driver->resume(dev, RESUME_ENABLE);
-	}
+	if (dev->driver && dev->driver->resume)
+		ret = dev->driver->resume(dev);
+
 	return ret;
 }
 
diff --git a/drivers/base/power/sysfs.c b/drivers/base/power/sysfs.c
index 8d04fb4..89c5787 100644
--- a/drivers/base/power/sysfs.c
+++ b/drivers/base/power/sysfs.c
@@ -48,8 +48,81 @@
 static DEVICE_ATTR(state, 0644, state_show, state_store);
 
 
+/*
+ *	wakeup - Report/change current wakeup option for device
+ *
+ *	Some devices support "wakeup" events, which are hardware signals
+ *	used to activate devices from suspended or low power states.  Such
+ *	devices have one of three values for the sysfs power/wakeup file:
+ *
+ *	 + "enabled\n" to issue the events;
+ *	 + "disabled\n" not to do so; or
+ *	 + "\n" for temporary or permanent inability to issue wakeup.
+ *
+ *	(For example, unconfigured USB devices can't issue wakeups.)
+ *
+ *	Familiar examples of devices that can issue wakeup events include
+ *	keyboards and mice (both PS2 and USB styles), power buttons, modems,
+ *	"Wake-On-LAN" Ethernet links, GPIO lines, and more.  Some events
+ *	will wake the entire system from a suspend state; others may just
+ *	wake up the device (if the system as a whole is already active).
+ *	Some wakeup events use normal IRQ lines; other use special out
+ *	of band signaling.
+ *
+ *	It is the responsibility of device drivers to enable (or disable)
+ *	wakeup signaling as part of changing device power states, respecting
+ *	the policy choices provided through the driver model.
+ *
+ *	Devices may not be able to generate wakeup events from all power
+ *	states.  Also, the events may be ignored in some configurations;
+ *	for example, they might need help from other devices that aren't
+ *	active, or which may have wakeup disabled.  Some drivers rely on
+ *	wakeup events internally (unless they are disabled), keeping
+ *	their hardware in low power modes whenever they're unused.  This
+ *	saves runtime power, without requiring system-wide sleep states.
+ */
+
+static const char enabled[] = "enabled";
+static const char disabled[] = "disabled";
+
+static ssize_t
+wake_show(struct device * dev, struct device_attribute *attr, char * buf)
+{
+	return sprintf(buf, "%s\n", device_can_wakeup(dev)
+		? (device_may_wakeup(dev) ? enabled : disabled)
+		: "");
+}
+
+static ssize_t
+wake_store(struct device * dev, struct device_attribute *attr,
+	const char * buf, size_t n)
+{
+	char *cp;
+	int len = n;
+
+	if (!device_can_wakeup(dev))
+		return -EINVAL;
+
+	cp = memchr(buf, '\n', n);
+	if (cp)
+		len = cp - buf;
+	if (len == sizeof enabled - 1
+			&& strncmp(buf, enabled, sizeof enabled - 1) == 0)
+		device_set_wakeup_enable(dev, 1);
+	else if (len == sizeof disabled - 1
+			&& strncmp(buf, disabled, sizeof disabled - 1) == 0)
+		device_set_wakeup_enable(dev, 0);
+	else
+		return -EINVAL;
+	return n;
+}
+
+static DEVICE_ATTR(wakeup, 0644, wake_show, wake_store);
+
+
 static struct attribute * power_attrs[] = {
 	&dev_attr_state.attr,
+	&dev_attr_wakeup.attr,
 	NULL,
 };
 static struct attribute_group pm_attr_group = {
diff --git a/drivers/block/aoe/aoe.h b/drivers/block/aoe/aoe.h
index 0e9e586..881c48d 100644
--- a/drivers/block/aoe/aoe.h
+++ b/drivers/block/aoe/aoe.h
@@ -1,5 +1,5 @@
 /* Copyright (c) 2004 Coraid, Inc.  See COPYING for GPL terms. */
-#define VERSION "12"
+#define VERSION "14"
 #define AOE_MAJOR 152
 #define DEVICE_NAME "aoe"
 
diff --git a/drivers/block/aoe/aoechr.c b/drivers/block/aoe/aoechr.c
index 45a2430..41ae0ed 100644
--- a/drivers/block/aoe/aoechr.c
+++ b/drivers/block/aoe/aoechr.c
@@ -224,7 +224,7 @@
 		return PTR_ERR(aoe_class);
 	}
 	for (i = 0; i < ARRAY_SIZE(chardevs); ++i)
-		class_device_create(aoe_class,
+		class_device_create(aoe_class, NULL,
 					MKDEV(AOE_MAJOR, chardevs[i].minor),
 					NULL, chardevs[i].name);
 
diff --git a/drivers/block/aoe/aoecmd.c b/drivers/block/aoe/aoecmd.c
index b5be4b7..5c9c7c1 100644
--- a/drivers/block/aoe/aoecmd.c
+++ b/drivers/block/aoe/aoecmd.c
@@ -8,6 +8,7 @@
 #include <linux/blkdev.h>
 #include <linux/skbuff.h>
 #include <linux/netdevice.h>
+#include <asm/unaligned.h>
 #include "aoe.h"
 
 #define TIMERTICK (HZ / 10)
@@ -311,16 +312,16 @@
 	u16 n;
 
 	/* word 83: command set supported */
-	n = le16_to_cpup((__le16 *) &id[83<<1]);
+	n = le16_to_cpu(get_unaligned((__le16 *) &id[83<<1]));
 
 	/* word 86: command set/feature enabled */
-	n |= le16_to_cpup((__le16 *) &id[86<<1]);
+	n |= le16_to_cpu(get_unaligned((__le16 *) &id[86<<1]));
 
 	if (n & (1<<10)) {	/* bit 10: LBA 48 */
 		d->flags |= DEVFL_EXT;
 
 		/* word 100: number lba48 sectors */
-		ssize = le64_to_cpup((__le64 *) &id[100<<1]);
+		ssize = le64_to_cpu(get_unaligned((__le64 *) &id[100<<1]));
 
 		/* set as in ide-disk.c:init_idedisk_capacity */
 		d->geo.cylinders = ssize;
@@ -331,12 +332,12 @@
 		d->flags &= ~DEVFL_EXT;
 
 		/* number lba28 sectors */
-		ssize = le32_to_cpup((__le32 *) &id[60<<1]);
+		ssize = le32_to_cpu(get_unaligned((__le32 *) &id[60<<1]));
 
 		/* NOTE: obsolete in ATA 6 */
-		d->geo.cylinders = le16_to_cpup((__le16 *) &id[54<<1]);
-		d->geo.heads = le16_to_cpup((__le16 *) &id[55<<1]);
-		d->geo.sectors = le16_to_cpup((__le16 *) &id[56<<1]);
+		d->geo.cylinders = le16_to_cpu(get_unaligned((__le16 *) &id[54<<1]));
+		d->geo.heads = le16_to_cpu(get_unaligned((__le16 *) &id[55<<1]));
+		d->geo.sectors = le16_to_cpu(get_unaligned((__le16 *) &id[56<<1]));
 	}
 	d->ssize = ssize;
 	d->geo.start = 0;
diff --git a/drivers/block/genhd.c b/drivers/block/genhd.c
index d42840c..486ce1f 100644
--- a/drivers/block/genhd.c
+++ b/drivers/block/genhd.c
@@ -337,10 +337,30 @@
 	return ret;
 }
 
+static ssize_t disk_attr_store(struct kobject * kobj, struct attribute * attr,
+			       const char *page, size_t count)
+{
+	struct gendisk *disk = to_disk(kobj);
+	struct disk_attribute *disk_attr =
+		container_of(attr,struct disk_attribute,attr);
+	ssize_t ret = 0;
+
+	if (disk_attr->store)
+		ret = disk_attr->store(disk, page, count);
+	return ret;
+}
+
 static struct sysfs_ops disk_sysfs_ops = {
 	.show	= &disk_attr_show,
+	.store	= &disk_attr_store,
 };
 
+static ssize_t disk_uevent_store(struct gendisk * disk,
+				 const char *buf, size_t count)
+{
+	kobject_hotplug(&disk->kobj, KOBJ_ADD);
+	return count;
+}
 static ssize_t disk_dev_read(struct gendisk * disk, char *page)
 {
 	dev_t base = MKDEV(disk->major, disk->first_minor); 
@@ -382,6 +402,10 @@
 		jiffies_to_msecs(disk_stat_read(disk, io_ticks)),
 		jiffies_to_msecs(disk_stat_read(disk, time_in_queue)));
 }
+static struct disk_attribute disk_attr_uevent = {
+	.attr = {.name = "uevent", .mode = S_IWUSR },
+	.store	= disk_uevent_store
+};
 static struct disk_attribute disk_attr_dev = {
 	.attr = {.name = "dev", .mode = S_IRUGO },
 	.show	= disk_dev_read
@@ -404,6 +428,7 @@
 };
 
 static struct attribute * default_attrs[] = {
+	&disk_attr_uevent.attr,
 	&disk_attr_dev.attr,
 	&disk_attr_range.attr,
 	&disk_attr_removable.attr,
diff --git a/drivers/block/paride/pg.c b/drivers/block/paride/pg.c
index b398239..82f2d6d 100644
--- a/drivers/block/paride/pg.c
+++ b/drivers/block/paride/pg.c
@@ -674,7 +674,7 @@
 	for (unit = 0; unit < PG_UNITS; unit++) {
 		struct pg *dev = &devices[unit];
 		if (dev->present) {
-			class_device_create(pg_class, MKDEV(major, unit),
+			class_device_create(pg_class, NULL, MKDEV(major, unit),
 					NULL, "pg%u", unit);
 			err = devfs_mk_cdev(MKDEV(major, unit),
 				      S_IFCHR | S_IRUSR | S_IWUSR, "pg/%u",
diff --git a/drivers/block/paride/pt.c b/drivers/block/paride/pt.c
index d8d3523..686c955 100644
--- a/drivers/block/paride/pt.c
+++ b/drivers/block/paride/pt.c
@@ -971,7 +971,7 @@
 	devfs_mk_dir("pt");
 	for (unit = 0; unit < PT_UNITS; unit++)
 		if (pt[unit].present) {
-			class_device_create(pt_class, MKDEV(major, unit),
+			class_device_create(pt_class, NULL, MKDEV(major, unit),
 					NULL, "pt%d", unit);
 			err = devfs_mk_cdev(MKDEV(major, unit),
 				      S_IFCHR | S_IRUSR | S_IWUSR,
@@ -980,7 +980,7 @@
 				class_device_destroy(pt_class, MKDEV(major, unit));
 				goto out_class;
 			}
-			class_device_create(pt_class, MKDEV(major, unit + 128),
+			class_device_create(pt_class, NULL, MKDEV(major, unit + 128),
 					NULL, "pt%dn", unit);
 			err = devfs_mk_cdev(MKDEV(major, unit + 128),
 				      S_IFCHR | S_IRUSR | S_IWUSR,
diff --git a/drivers/char/dsp56k.c b/drivers/char/dsp56k.c
index 26271e3..8693835 100644
--- a/drivers/char/dsp56k.c
+++ b/drivers/char/dsp56k.c
@@ -515,7 +515,7 @@
 		err = PTR_ERR(dsp56k_class);
 		goto out_chrdev;
 	}
-	class_device_create(dsp56k_class, MKDEV(DSP56K_MAJOR, 0), NULL, "dsp56k");
+	class_device_create(dsp56k_class, NULL, MKDEV(DSP56K_MAJOR, 0), NULL, "dsp56k");
 
 	err = devfs_mk_cdev(MKDEV(DSP56K_MAJOR, 0),
 		      S_IFCHR | S_IRUSR | S_IWUSR, "dsp56k");
diff --git a/drivers/char/ftape/zftape/zftape-init.c b/drivers/char/ftape/zftape/zftape-init.c
index 5745b74..821357c 100644
--- a/drivers/char/ftape/zftape/zftape-init.c
+++ b/drivers/char/ftape/zftape/zftape-init.c
@@ -331,27 +331,27 @@
 
 	zft_class = class_create(THIS_MODULE, "zft");
 	for (i = 0; i < 4; i++) {
-		class_device_create(zft_class, MKDEV(QIC117_TAPE_MAJOR, i), NULL, "qft%i", i);
+		class_device_create(zft_class, NULL, MKDEV(QIC117_TAPE_MAJOR, i), NULL, "qft%i", i);
 		devfs_mk_cdev(MKDEV(QIC117_TAPE_MAJOR, i),
 				S_IFCHR | S_IRUSR | S_IWUSR,
 				"qft%i", i);
-		class_device_create(zft_class, MKDEV(QIC117_TAPE_MAJOR, i + 4), NULL, "nqft%i", i);
+		class_device_create(zft_class, NULL, MKDEV(QIC117_TAPE_MAJOR, i + 4), NULL, "nqft%i", i);
 		devfs_mk_cdev(MKDEV(QIC117_TAPE_MAJOR, i + 4),
 				S_IFCHR | S_IRUSR | S_IWUSR,
 				"nqft%i", i);
-		class_device_create(zft_class, MKDEV(QIC117_TAPE_MAJOR, i + 16), NULL, "zqft%i", i);
+		class_device_create(zft_class, NULL, MKDEV(QIC117_TAPE_MAJOR, i + 16), NULL, "zqft%i", i);
 		devfs_mk_cdev(MKDEV(QIC117_TAPE_MAJOR, i + 16),
 				S_IFCHR | S_IRUSR | S_IWUSR,
 				"zqft%i", i);
-		class_device_create(zft_class, MKDEV(QIC117_TAPE_MAJOR, i + 20), NULL, "nzqft%i", i);
+		class_device_create(zft_class, NULL, MKDEV(QIC117_TAPE_MAJOR, i + 20), NULL, "nzqft%i", i);
 		devfs_mk_cdev(MKDEV(QIC117_TAPE_MAJOR, i + 20),
 				S_IFCHR | S_IRUSR | S_IWUSR,
 				"nzqft%i", i);
-		class_device_create(zft_class, MKDEV(QIC117_TAPE_MAJOR, i + 32), NULL, "rawqft%i", i);
+		class_device_create(zft_class, NULL, MKDEV(QIC117_TAPE_MAJOR, i + 32), NULL, "rawqft%i", i);
 		devfs_mk_cdev(MKDEV(QIC117_TAPE_MAJOR, i + 32),
 				S_IFCHR | S_IRUSR | S_IWUSR,
 				"rawqft%i", i);
-		class_device_create(zft_class, MKDEV(QIC117_TAPE_MAJOR, i + 36), NULL, "nrawrawqft%i", i);
+		class_device_create(zft_class, NULL, MKDEV(QIC117_TAPE_MAJOR, i + 36), NULL, "nrawrawqft%i", i);
 		devfs_mk_cdev(MKDEV(QIC117_TAPE_MAJOR, i + 36),
 				S_IFCHR | S_IRUSR | S_IWUSR,
 				"nrawqft%i", i);
diff --git a/drivers/char/ip2main.c b/drivers/char/ip2main.c
index 9e4e26a..d815d19 100644
--- a/drivers/char/ip2main.c
+++ b/drivers/char/ip2main.c
@@ -721,8 +721,9 @@
 			}
 
 			if ( NULL != ( pB = i2BoardPtrTable[i] ) ) {
-				class_device_create(ip2_class, MKDEV(IP2_IPL_MAJOR,
-						4 * i), NULL, "ipl%d", i);
+				class_device_create(ip2_class, NULL,
+						MKDEV(IP2_IPL_MAJOR, 4 * i),
+						NULL, "ipl%d", i);
 				err = devfs_mk_cdev(MKDEV(IP2_IPL_MAJOR, 4 * i),
 						S_IRUSR | S_IWUSR | S_IRGRP | S_IFCHR,
 						"ip2/ipl%d", i);
@@ -732,8 +733,9 @@
 					goto out_class;
 				}
 
-				class_device_create(ip2_class, MKDEV(IP2_IPL_MAJOR,
-						4 * i + 1), NULL, "stat%d", i);
+				class_device_create(ip2_class, NULL,
+						MKDEV(IP2_IPL_MAJOR, 4 * i + 1),
+						NULL, "stat%d", i);
 				err = devfs_mk_cdev(MKDEV(IP2_IPL_MAJOR, 4 * i + 1),
 						S_IRUSR | S_IWUSR | S_IRGRP | S_IFCHR,
 						"ip2/stat%d", i);
diff --git a/drivers/char/ipmi/ipmi_devintf.c b/drivers/char/ipmi/ipmi_devintf.c
index a09ff10..7c0684d 100644
--- a/drivers/char/ipmi/ipmi_devintf.c
+++ b/drivers/char/ipmi/ipmi_devintf.c
@@ -798,7 +798,7 @@
 	devfs_mk_cdev(dev, S_IFCHR | S_IRUSR | S_IWUSR,
 		      "ipmidev/%d", if_num);
 
-	class_device_create(ipmi_class, dev, NULL, "ipmi%d", if_num);
+	class_device_create(ipmi_class, NULL, dev, NULL, "ipmi%d", if_num);
 }
 
 static void ipmi_smi_gone(int if_num)
diff --git a/drivers/char/istallion.c b/drivers/char/istallion.c
index 9c19e54..e3ddbdb 100644
--- a/drivers/char/istallion.c
+++ b/drivers/char/istallion.c
@@ -5246,7 +5246,8 @@
 		devfs_mk_cdev(MKDEV(STL_SIOMEMMAJOR, i),
 			       S_IFCHR | S_IRUSR | S_IWUSR,
 			       "staliomem/%d", i);
-		class_device_create(istallion_class, MKDEV(STL_SIOMEMMAJOR, i),
+		class_device_create(istallion_class, NULL,
+				MKDEV(STL_SIOMEMMAJOR, i),
 				NULL, "staliomem%d", i);
 	}
 
diff --git a/drivers/char/lp.c b/drivers/char/lp.c
index 2afb903..e572605 100644
--- a/drivers/char/lp.c
+++ b/drivers/char/lp.c
@@ -805,7 +805,7 @@
 	if (reset)
 		lp_reset(nr);
 
-	class_device_create(lp_class, MKDEV(LP_MAJOR, nr), NULL,
+	class_device_create(lp_class, NULL, MKDEV(LP_MAJOR, nr), NULL,
 				"lp%d", nr);
 	devfs_mk_cdev(MKDEV(LP_MAJOR, nr), S_IFCHR | S_IRUGO | S_IWUGO,
 			"printers/%d", nr);
diff --git a/drivers/char/mem.c b/drivers/char/mem.c
index f182752..38be4b0 100644
--- a/drivers/char/mem.c
+++ b/drivers/char/mem.c
@@ -920,7 +920,8 @@
 
 	mem_class = class_create(THIS_MODULE, "mem");
 	for (i = 0; i < ARRAY_SIZE(devlist); i++) {
-		class_device_create(mem_class, MKDEV(MEM_MAJOR, devlist[i].minor),
+		class_device_create(mem_class, NULL,
+					MKDEV(MEM_MAJOR, devlist[i].minor),
 					NULL, devlist[i].name);
 		devfs_mk_cdev(MKDEV(MEM_MAJOR, devlist[i].minor),
 				S_IFCHR | devlist[i].mode, devlist[i].name);
diff --git a/drivers/char/misc.c b/drivers/char/misc.c
index 0c83751..3e4c041 100644
--- a/drivers/char/misc.c
+++ b/drivers/char/misc.c
@@ -234,7 +234,7 @@
 	}
 	dev = MKDEV(MISC_MAJOR, misc->minor);
 
-	misc->class = class_device_create(misc_class, dev, misc->dev,
+	misc->class = class_device_create(misc_class, NULL, dev, misc->dev,
 					  "%s", misc->name);
 	if (IS_ERR(misc->class)) {
 		err = PTR_ERR(misc->class);
diff --git a/drivers/char/ppdev.c b/drivers/char/ppdev.c
index 0e22880..306ee0f 100644
--- a/drivers/char/ppdev.c
+++ b/drivers/char/ppdev.c
@@ -752,7 +752,7 @@
 
 static void pp_attach(struct parport *port)
 {
-	class_device_create(ppdev_class, MKDEV(PP_MAJOR, port->number),
+	class_device_create(ppdev_class, NULL, MKDEV(PP_MAJOR, port->number),
 			NULL, "parport%d", port->number);
 }
 
diff --git a/drivers/char/raw.c b/drivers/char/raw.c
index f13e5de..30e4cbe 100644
--- a/drivers/char/raw.c
+++ b/drivers/char/raw.c
@@ -128,7 +128,7 @@
 static void bind_device(struct raw_config_request *rq)
 {
 	class_device_destroy(raw_class, MKDEV(RAW_MAJOR, rq->raw_minor));
-	class_device_create(raw_class, MKDEV(RAW_MAJOR, rq->raw_minor),
+	class_device_create(raw_class, NULL, MKDEV(RAW_MAJOR, rq->raw_minor),
 				      NULL, "raw%d", rq->raw_minor);
 }
 
@@ -307,7 +307,7 @@
 		unregister_chrdev_region(dev, MAX_RAW_MINORS);
 		goto error;
 	}
-	class_device_create(raw_class, MKDEV(RAW_MAJOR, 0), NULL, "rawctl");
+	class_device_create(raw_class, NULL, MKDEV(RAW_MAJOR, 0), NULL, "rawctl");
 
 	devfs_mk_cdev(MKDEV(RAW_MAJOR, 0),
 		      S_IFCHR | S_IRUGO | S_IWUGO,
diff --git a/drivers/char/s3c2410-rtc.c b/drivers/char/s3c2410-rtc.c
index e1a90d9..887b8b2 100644
--- a/drivers/char/s3c2410-rtc.c
+++ b/drivers/char/s3c2410-rtc.c
@@ -519,30 +519,28 @@
 
 static int ticnt_save;
 
-static int s3c2410_rtc_suspend(struct device *dev, pm_message_t state, u32 level)
+static int s3c2410_rtc_suspend(struct device *dev, pm_message_t state)
 {
 	struct rtc_time tm;
 	struct timespec time;
 
 	time.tv_nsec = 0;
 
-	if (level == SUSPEND_POWER_DOWN) {
-		/* save TICNT for anyone using periodic interrupts */
+	/* save TICNT for anyone using periodic interrupts */
 
-		ticnt_save = readb(S3C2410_TICNT);
+	ticnt_save = readb(S3C2410_TICNT);
 
-		/* calculate time delta for suspend */
+	/* calculate time delta for suspend */
 
-		s3c2410_rtc_gettime(&tm);
-		rtc_tm_to_time(&tm, &time.tv_sec);
-		save_time_delta(&s3c2410_rtc_delta, &time);
-		s3c2410_rtc_enable(dev, 0);
-	}
+	s3c2410_rtc_gettime(&tm);
+	rtc_tm_to_time(&tm, &time.tv_sec);
+	save_time_delta(&s3c2410_rtc_delta, &time);
+	s3c2410_rtc_enable(dev, 0);
 
 	return 0;
 }
 
-static int s3c2410_rtc_resume(struct device *dev, u32 level)
+static int s3c2410_rtc_resume(struct device *dev)
 {
 	struct rtc_time tm;
 	struct timespec time;
diff --git a/drivers/char/snsc.c b/drivers/char/snsc.c
index 261a41b..1758a83 100644
--- a/drivers/char/snsc.c
+++ b/drivers/char/snsc.c
@@ -437,7 +437,7 @@
 				continue;
 			}
 
-			class_device_create(snsc_class, dev, NULL,
+			class_device_create(snsc_class, NULL, dev, NULL,
 						"%s", devname);
 
 			ia64_sn_irtr_intr_enable(scd->scd_nasid,
diff --git a/drivers/char/sonypi.c b/drivers/char/sonypi.c
index 36ae9ad..f86c155 100644
--- a/drivers/char/sonypi.c
+++ b/drivers/char/sonypi.c
@@ -424,10 +424,6 @@
 
 #define SONYPI_BUF_SIZE	128
 
-/* The name of the devices for the input device drivers */
-#define SONYPI_JOG_INPUTNAME	"Sony Vaio Jogdial"
-#define SONYPI_KEY_INPUTNAME	"Sony Vaio Keys"
-
 /* Correspondance table between sonypi events and input layer events */
 static struct {
 	int sonypiev;
@@ -490,8 +486,8 @@
 	struct fasync_struct *fifo_async;
 	int open_count;
 	int model;
-	struct input_dev input_jog_dev;
-	struct input_dev input_key_dev;
+	struct input_dev *input_jog_dev;
+	struct input_dev *input_key_dev;
 	struct work_struct input_work;
 	struct kfifo *input_fifo;
 	spinlock_t input_fifo_lock;
@@ -779,8 +775,8 @@
 
 static void sonypi_report_input_event(u8 event)
 {
-	struct input_dev *jog_dev = &sonypi_device.input_jog_dev;
-	struct input_dev *key_dev = &sonypi_device.input_key_dev;
+	struct input_dev *jog_dev = sonypi_device.input_jog_dev;
+	struct input_dev *key_dev = sonypi_device.input_key_dev;
 	struct sonypi_keypress kp = { NULL };
 	int i;
 
@@ -1171,19 +1167,17 @@
 #ifdef CONFIG_PM
 static int old_camera_power;
 
-static int sonypi_suspend(struct device *dev, pm_message_t state, u32 level)
+static int sonypi_suspend(struct device *dev, pm_message_t state)
 {
-	if (level == SUSPEND_DISABLE) {
-		old_camera_power = sonypi_device.camera_power;
-		sonypi_disable();
-	}
+	old_camera_power = sonypi_device.camera_power;
+	sonypi_disable();
+
 	return 0;
 }
 
-static int sonypi_resume(struct device *dev, u32 level)
+static int sonypi_resume(struct device *dev)
 {
-	if (level == RESUME_ENABLE)
-		sonypi_enable(old_camera_power);
+	sonypi_enable(old_camera_power);
 	return 0;
 }
 #endif
@@ -1203,6 +1197,47 @@
 	.shutdown	= sonypi_shutdown,
 };
 
+static int __devinit sonypi_create_input_devices(void)
+{
+	struct input_dev *jog_dev;
+	struct input_dev *key_dev;
+	int i;
+
+	sonypi_device.input_jog_dev = jog_dev = input_allocate_device();
+	if (!jog_dev)
+		return -ENOMEM;
+
+	jog_dev->name = "Sony Vaio Jogdial";
+	jog_dev->id.bustype = BUS_ISA;
+	jog_dev->id.vendor = PCI_VENDOR_ID_SONY;
+
+	jog_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REL);
+	jog_dev->keybit[LONG(BTN_MOUSE)] = BIT(BTN_MIDDLE);
+	jog_dev->relbit[0] = BIT(REL_WHEEL);
+
+	sonypi_device.input_key_dev = key_dev = input_allocate_device();
+	if (!key_dev) {
+		input_free_device(jog_dev);
+		sonypi_device.input_jog_dev = NULL;
+		return -ENOMEM;
+	}
+
+	key_dev->name = "Sony Vaio Keys";
+	key_dev->id.bustype = BUS_ISA;
+	key_dev->id.vendor = PCI_VENDOR_ID_SONY;
+
+	/* Initialize the Input Drivers: special keys */
+	key_dev->evbit[0] = BIT(EV_KEY);
+	for (i = 0; sonypi_inputkeys[i].sonypiev; i++)
+		if (sonypi_inputkeys[i].inputev)
+			set_bit(sonypi_inputkeys[i].inputev, key_dev->keybit);
+
+	input_register_device(jog_dev);
+	input_register_device(key_dev);
+
+	return 0;
+}
+
 static int __devinit sonypi_probe(void)
 {
 	int i, ret;
@@ -1298,34 +1333,10 @@
 	}
 
 	if (useinput) {
-		/* Initialize the Input Drivers: jogdial */
-		int i;
-		sonypi_device.input_jog_dev.evbit[0] =
-			BIT(EV_KEY) | BIT(EV_REL);
-		sonypi_device.input_jog_dev.keybit[LONG(BTN_MOUSE)] =
-			BIT(BTN_MIDDLE);
-		sonypi_device.input_jog_dev.relbit[0] = BIT(REL_WHEEL);
-		sonypi_device.input_jog_dev.name = SONYPI_JOG_INPUTNAME;
-		sonypi_device.input_jog_dev.id.bustype = BUS_ISA;
-		sonypi_device.input_jog_dev.id.vendor = PCI_VENDOR_ID_SONY;
 
-		input_register_device(&sonypi_device.input_jog_dev);
-		printk(KERN_INFO "%s input method installed.\n",
-		       sonypi_device.input_jog_dev.name);
-
-		/* Initialize the Input Drivers: special keys */
-		sonypi_device.input_key_dev.evbit[0] = BIT(EV_KEY);
-		for (i = 0; sonypi_inputkeys[i].sonypiev; i++)
-			if (sonypi_inputkeys[i].inputev)
-				set_bit(sonypi_inputkeys[i].inputev,
-					sonypi_device.input_key_dev.keybit);
-		sonypi_device.input_key_dev.name = SONYPI_KEY_INPUTNAME;
-		sonypi_device.input_key_dev.id.bustype = BUS_ISA;
-		sonypi_device.input_key_dev.id.vendor = PCI_VENDOR_ID_SONY;
-
-		input_register_device(&sonypi_device.input_key_dev);
-		printk(KERN_INFO "%s input method installed.\n",
-		       sonypi_device.input_key_dev.name);
+		ret = sonypi_create_input_devices();
+		if (ret)
+			goto out_inputdevices;
 
 		spin_lock_init(&sonypi_device.input_fifo_lock);
 		sonypi_device.input_fifo =
@@ -1375,8 +1386,9 @@
 out_platformdev:
 	kfifo_free(sonypi_device.input_fifo);
 out_infifo:
-	input_unregister_device(&sonypi_device.input_key_dev);
-	input_unregister_device(&sonypi_device.input_jog_dev);
+	input_unregister_device(sonypi_device.input_key_dev);
+	input_unregister_device(sonypi_device.input_jog_dev);
+out_inputdevices:
 	free_irq(sonypi_device.irq, sonypi_irq);
 out_reqirq:
 	release_region(sonypi_device.ioport1, sonypi_device.region_size);
@@ -1402,8 +1414,8 @@
 	platform_device_unregister(sonypi_device.pdev);
 
 	if (useinput) {
-		input_unregister_device(&sonypi_device.input_key_dev);
-		input_unregister_device(&sonypi_device.input_jog_dev);
+		input_unregister_device(sonypi_device.input_key_dev);
+		input_unregister_device(sonypi_device.input_jog_dev);
 		kfifo_free(sonypi_device.input_fifo);
 	}
 
diff --git a/drivers/char/stallion.c b/drivers/char/stallion.c
index 951545a..1c68641 100644
--- a/drivers/char/stallion.c
+++ b/drivers/char/stallion.c
@@ -3095,7 +3095,9 @@
 		devfs_mk_cdev(MKDEV(STL_SIOMEMMAJOR, i),
 				S_IFCHR|S_IRUSR|S_IWUSR,
 				"staliomem/%d", i);
-		class_device_create(stallion_class, MKDEV(STL_SIOMEMMAJOR, i), NULL, "staliomem%d", i);
+		class_device_create(stallion_class, NULL,
+				    MKDEV(STL_SIOMEMMAJOR, i), NULL,
+				    "staliomem%d", i);
 	}
 
 	stl_serial->owner = THIS_MODULE;
diff --git a/drivers/char/tipar.c b/drivers/char/tipar.c
index ec78d2f..41a94bc 100644
--- a/drivers/char/tipar.c
+++ b/drivers/char/tipar.c
@@ -436,7 +436,7 @@
 		goto out;
 	}
 
-	class_device_create(tipar_class, MKDEV(TIPAR_MAJOR,
+	class_device_create(tipar_class, NULL, MKDEV(TIPAR_MAJOR,
 			TIPAR_MINOR + nr), NULL, "par%d", nr);
 	/* Use devfs, tree: /dev/ticables/par/[0..2] */
 	err = devfs_mk_cdev(MKDEV(TIPAR_MAJOR, TIPAR_MINOR + nr),
diff --git a/drivers/char/tty_io.c b/drivers/char/tty_io.c
index e5953f3..f5649a3 100644
--- a/drivers/char/tty_io.c
+++ b/drivers/char/tty_io.c
@@ -2728,7 +2728,7 @@
 		pty_line_name(driver, index, name);
 	else
 		tty_line_name(driver, index, name);
-	class_device_create(tty_class, dev, device, name);
+	class_device_create(tty_class, NULL, dev, device, "%s", name);
 }
 
 /**
@@ -2983,14 +2983,14 @@
 	    register_chrdev_region(MKDEV(TTYAUX_MAJOR, 0), 1, "/dev/tty") < 0)
 		panic("Couldn't register /dev/tty driver\n");
 	devfs_mk_cdev(MKDEV(TTYAUX_MAJOR, 0), S_IFCHR|S_IRUGO|S_IWUGO, "tty");
-	class_device_create(tty_class, MKDEV(TTYAUX_MAJOR, 0), NULL, "tty");
+	class_device_create(tty_class, NULL, MKDEV(TTYAUX_MAJOR, 0), NULL, "tty");
 
 	cdev_init(&console_cdev, &console_fops);
 	if (cdev_add(&console_cdev, MKDEV(TTYAUX_MAJOR, 1), 1) ||
 	    register_chrdev_region(MKDEV(TTYAUX_MAJOR, 1), 1, "/dev/console") < 0)
 		panic("Couldn't register /dev/console driver\n");
 	devfs_mk_cdev(MKDEV(TTYAUX_MAJOR, 1), S_IFCHR|S_IRUSR|S_IWUSR, "console");
-	class_device_create(tty_class, MKDEV(TTYAUX_MAJOR, 1), NULL, "console");
+	class_device_create(tty_class, NULL, MKDEV(TTYAUX_MAJOR, 1), NULL, "console");
 
 #ifdef CONFIG_UNIX98_PTYS
 	cdev_init(&ptmx_cdev, &ptmx_fops);
@@ -2998,7 +2998,7 @@
 	    register_chrdev_region(MKDEV(TTYAUX_MAJOR, 2), 1, "/dev/ptmx") < 0)
 		panic("Couldn't register /dev/ptmx driver\n");
 	devfs_mk_cdev(MKDEV(TTYAUX_MAJOR, 2), S_IFCHR|S_IRUGO|S_IWUGO, "ptmx");
-	class_device_create(tty_class, MKDEV(TTYAUX_MAJOR, 2), NULL, "ptmx");
+	class_device_create(tty_class, NULL, MKDEV(TTYAUX_MAJOR, 2), NULL, "ptmx");
 #endif
 
 #ifdef CONFIG_VT
@@ -3007,7 +3007,7 @@
 	    register_chrdev_region(MKDEV(TTY_MAJOR, 0), 1, "/dev/vc/0") < 0)
 		panic("Couldn't register /dev/tty0 driver\n");
 	devfs_mk_cdev(MKDEV(TTY_MAJOR, 0), S_IFCHR|S_IRUSR|S_IWUSR, "vc/0");
-	class_device_create(tty_class, MKDEV(TTY_MAJOR, 0), NULL, "tty0");
+	class_device_create(tty_class, NULL, MKDEV(TTY_MAJOR, 0), NULL, "tty0");
 
 	vty_init();
 #endif
diff --git a/drivers/char/vc_screen.c b/drivers/char/vc_screen.c
index 79c2928..f66c7ad 100644
--- a/drivers/char/vc_screen.c
+++ b/drivers/char/vc_screen.c
@@ -484,8 +484,10 @@
 	devfs_mk_cdev(MKDEV(VCS_MAJOR, tty->index + 129),
 			S_IFCHR|S_IRUSR|S_IWUSR,
 			"vcc/a%u", tty->index + 1);
-	class_device_create(vc_class, MKDEV(VCS_MAJOR, tty->index + 1), NULL, "vcs%u", tty->index + 1);
-	class_device_create(vc_class, MKDEV(VCS_MAJOR, tty->index + 129), NULL, "vcsa%u", tty->index + 1);
+	class_device_create(vc_class, NULL, MKDEV(VCS_MAJOR, tty->index + 1),
+			NULL, "vcs%u", tty->index + 1);
+	class_device_create(vc_class, NULL, MKDEV(VCS_MAJOR, tty->index + 129),
+			NULL, "vcsa%u", tty->index + 1);
 }
 void vcs_remove_devfs(struct tty_struct *tty)
 {
@@ -503,7 +505,7 @@
 
 	devfs_mk_cdev(MKDEV(VCS_MAJOR, 0), S_IFCHR|S_IRUSR|S_IWUSR, "vcc/0");
 	devfs_mk_cdev(MKDEV(VCS_MAJOR, 128), S_IFCHR|S_IRUSR|S_IWUSR, "vcc/a0");
-	class_device_create(vc_class, MKDEV(VCS_MAJOR, 0), NULL, "vcs");
-	class_device_create(vc_class, MKDEV(VCS_MAJOR, 128), NULL, "vcsa");
+	class_device_create(vc_class, NULL, MKDEV(VCS_MAJOR, 0), NULL, "vcs");
+	class_device_create(vc_class, NULL, MKDEV(VCS_MAJOR, 128), NULL, "vcsa");
 	return 0;
 }
diff --git a/drivers/char/viotape.c b/drivers/char/viotape.c
index 0aff45f..a5e104f 100644
--- a/drivers/char/viotape.c
+++ b/drivers/char/viotape.c
@@ -956,9 +956,9 @@
 	state[i].cur_part = 0;
 	for (j = 0; j < MAX_PARTITIONS; ++j)
 		state[i].part_stat_rwi[j] = VIOT_IDLE;
-	class_device_create(tape_class, MKDEV(VIOTAPE_MAJOR, i), NULL,
+	class_device_create(tape_class, NULL, MKDEV(VIOTAPE_MAJOR, i), NULL,
 			"iseries!vt%d", i);
-	class_device_create(tape_class, MKDEV(VIOTAPE_MAJOR, i | 0x80),
+	class_device_create(tape_class, NULL, MKDEV(VIOTAPE_MAJOR, i | 0x80),
 			NULL, "iseries!nvt%d", i);
 	devfs_mk_cdev(MKDEV(VIOTAPE_MAJOR, i), S_IFCHR | S_IRUSR | S_IWUSR,
 			"iseries/vt%d", i);
diff --git a/drivers/char/watchdog/s3c2410_wdt.c b/drivers/char/watchdog/s3c2410_wdt.c
index 3625b26..b732020 100644
--- a/drivers/char/watchdog/s3c2410_wdt.c
+++ b/drivers/char/watchdog/s3c2410_wdt.c
@@ -464,32 +464,28 @@
 static unsigned long wtcon_save;
 static unsigned long wtdat_save;
 
-static int s3c2410wdt_suspend(struct device *dev, pm_message_t state, u32 level)
+static int s3c2410wdt_suspend(struct device *dev, pm_message_t state)
 {
-	if (level == SUSPEND_POWER_DOWN) {
-		/* Save watchdog state, and turn it off. */
-		wtcon_save = readl(wdt_base + S3C2410_WTCON);
-		wtdat_save = readl(wdt_base + S3C2410_WTDAT);
+	/* Save watchdog state, and turn it off. */
+	wtcon_save = readl(wdt_base + S3C2410_WTCON);
+	wtdat_save = readl(wdt_base + S3C2410_WTDAT);
 
-		/* Note that WTCNT doesn't need to be saved. */
-		s3c2410wdt_stop();
-	}
+	/* Note that WTCNT doesn't need to be saved. */
+	s3c2410wdt_stop();
 
 	return 0;
 }
 
-static int s3c2410wdt_resume(struct device *dev, u32 level)
+static int s3c2410wdt_resume(struct device *dev)
 {
-	if (level == RESUME_POWER_ON) {
-		/* Restore watchdog state. */
+	/* Restore watchdog state. */
 
-		writel(wtdat_save, wdt_base + S3C2410_WTDAT);
-		writel(wtdat_save, wdt_base + S3C2410_WTCNT); /* Reset count */
-		writel(wtcon_save, wdt_base + S3C2410_WTCON);
+	writel(wtdat_save, wdt_base + S3C2410_WTDAT);
+	writel(wtdat_save, wdt_base + S3C2410_WTCNT); /* Reset count */
+	writel(wtcon_save, wdt_base + S3C2410_WTCON);
 
-		printk(KERN_INFO PFX "watchdog %sabled\n",
-		       (wtcon_save & S3C2410_WTCON_ENABLE) ? "en" : "dis");
-	}
+	printk(KERN_INFO PFX "watchdog %sabled\n",
+	       (wtcon_save & S3C2410_WTCON_ENABLE) ? "en" : "dis");
 
 	return 0;
 }
diff --git a/drivers/hwmon/hdaps.c b/drivers/hwmon/hdaps.c
index 7f01076..0015da5 100644
--- a/drivers/hwmon/hdaps.c
+++ b/drivers/hwmon/hdaps.c
@@ -296,11 +296,9 @@
 	return 0;
 }
 
-static int hdaps_resume(struct device *dev, u32 level)
+static int hdaps_resume(struct device *dev)
 {
-	if (level == RESUME_ENABLE)
-		return hdaps_device_init();
-	return 0;
+	return hdaps_device_init();
 }
 
 static struct device_driver hdaps_driver = {
diff --git a/drivers/hwmon/hwmon.c b/drivers/hwmon/hwmon.c
index 9b41c9b..6f48579 100644
--- a/drivers/hwmon/hwmon.c
+++ b/drivers/hwmon/hwmon.c
@@ -45,7 +45,7 @@
 		return ERR_PTR(-ENOMEM);
 
 	id = id & MAX_ID_MASK;
-	cdev = class_device_create(hwmon_class, MKDEV(0,0), dev,
+	cdev = class_device_create(hwmon_class, NULL, MKDEV(0,0), dev,
 					HWMON_ID_FORMAT, id);
 
 	if (IS_ERR(cdev))
diff --git a/drivers/i2c/busses/i2c-s3c2410.c b/drivers/i2c/busses/i2c-s3c2410.c
index 73a092f..69fa282 100644
--- a/drivers/i2c/busses/i2c-s3c2410.c
+++ b/drivers/i2c/busses/i2c-s3c2410.c
@@ -879,14 +879,12 @@
 }
 
 #ifdef CONFIG_PM
-static int s3c24xx_i2c_resume(struct device *dev, u32 level)
+static int s3c24xx_i2c_resume(struct device *dev)
 {
 	struct s3c24xx_i2c *i2c = dev_get_drvdata(dev);
-	
-	if (i2c != NULL && level == RESUME_ENABLE) {
-		dev_dbg(dev, "resume: level %d\n", level);
+
+	if (i2c != NULL)
 		s3c24xx_i2c_init(i2c);
-	}
 
 	return 0;
 }
diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c
index dda472e..45aa0e5 100644
--- a/drivers/i2c/i2c-core.c
+++ b/drivers/i2c/i2c-core.c
@@ -48,7 +48,7 @@
 	int rc = 0;
 
 	if (dev->driver && dev->driver->suspend)
-		rc = dev->driver->suspend(dev,state,0);
+		rc = dev->driver->suspend(dev, state);
 	return rc;
 }
 
@@ -57,7 +57,7 @@
 	int rc = 0;
 	
 	if (dev->driver && dev->driver->resume)
-		rc = dev->driver->resume(dev,0);
+		rc = dev->driver->resume(dev);
 	return rc;
 }
 
diff --git a/drivers/ide/ide-tape.c b/drivers/ide/ide-tape.c
index ee38e6b..47f2b83 100644
--- a/drivers/ide/ide-tape.c
+++ b/drivers/ide/ide-tape.c
@@ -1013,6 +1013,8 @@
 
 static DECLARE_MUTEX(idetape_ref_sem);
 
+static struct class *idetape_sysfs_class;
+
 #define to_ide_tape(obj) container_of(obj, struct ide_tape_obj, kref)
 
 #define ide_tape_g(disk) \
@@ -4704,6 +4706,10 @@
 
 	drive->dsc_overlap = 0;
 	drive->driver_data = NULL;
+	class_device_destroy(idetape_sysfs_class,
+			MKDEV(IDETAPE_MAJOR, tape->minor));
+	class_device_destroy(idetape_sysfs_class,
+			MKDEV(IDETAPE_MAJOR, tape->minor + 128));
 	devfs_remove("%s/mt", drive->devfs_name);
 	devfs_remove("%s/mtn", drive->devfs_name);
 	devfs_unregister_tape(g->number);
@@ -4878,6 +4884,11 @@
 
 	idetape_setup(drive, tape, minor);
 
+	class_device_create(idetape_sysfs_class, NULL,
+			MKDEV(IDETAPE_MAJOR, minor), dev, "%s", tape->name);
+	class_device_create(idetape_sysfs_class, NULL,
+			MKDEV(IDETAPE_MAJOR, minor + 128), dev, "n%s", tape->name);
+
 	devfs_mk_cdev(MKDEV(HWIF(drive)->major, minor),
 			S_IFCHR | S_IRUGO | S_IWUGO,
 			"%s/mt", drive->devfs_name);
@@ -4903,6 +4914,7 @@
 static void __exit idetape_exit (void)
 {
 	driver_unregister(&idetape_driver.gen_driver);
+	class_destroy(idetape_sysfs_class);
 	unregister_chrdev(IDETAPE_MAJOR, "ht");
 }
 
@@ -4911,11 +4923,33 @@
  */
 static int idetape_init (void)
 {
+	int error = 1;
+	idetape_sysfs_class = class_create(THIS_MODULE, "ide_tape");
+	if (IS_ERR(idetape_sysfs_class)) {
+		idetape_sysfs_class = NULL;
+		printk(KERN_ERR "Unable to create sysfs class for ide tapes\n");
+		error = -EBUSY;
+		goto out;
+	}
+
 	if (register_chrdev(IDETAPE_MAJOR, "ht", &idetape_fops)) {
 		printk(KERN_ERR "ide-tape: Failed to register character device interface\n");
-		return -EBUSY;
+		error = -EBUSY;
+		goto out_free_class;
 	}
-	return driver_register(&idetape_driver.gen_driver);
+
+	error = driver_register(&idetape_driver.gen_driver);
+	if (error)
+		goto out_free_driver;
+
+	return 0;
+
+out_free_driver:
+	driver_unregister(&idetape_driver.gen_driver);
+out_free_class:
+	class_destroy(idetape_sysfs_class);
+out:
+	return error;
 }
 
 module_init(idetape_init);
diff --git a/drivers/ieee1394/dv1394.c b/drivers/ieee1394/dv1394.c
index e34730c..cbbbe14 100644
--- a/drivers/ieee1394/dv1394.c
+++ b/drivers/ieee1394/dv1394.c
@@ -2361,7 +2361,7 @@
 
 	ohci = (struct ti_ohci *)host->hostdata;
 
-	class_device_create(hpsb_protocol_class, MKDEV(
+	class_device_create(hpsb_protocol_class, NULL, MKDEV(
 		IEEE1394_MAJOR,	IEEE1394_MINOR_BLOCK_DV1394 * 16 + (id<<2)), 
 		NULL, "dv1394-%d", id);
 	devfs_mk_dir("ieee1394/dv/host%d", id);
diff --git a/drivers/ieee1394/nodemgr.c b/drivers/ieee1394/nodemgr.c
index 347ece6..7fff5a1 100644
--- a/drivers/ieee1394/nodemgr.c
+++ b/drivers/ieee1394/nodemgr.c
@@ -1292,7 +1292,7 @@
 
 		if (ud->device.driver &&
 		    (!ud->device.driver->suspend ||
-		      ud->device.driver->suspend(&ud->device, PMSG_SUSPEND, 0)))
+		      ud->device.driver->suspend(&ud->device, PMSG_SUSPEND)))
 			device_release_driver(&ud->device);
 	}
 	up_write(&ne->device.bus->subsys.rwsem);
@@ -1315,7 +1315,7 @@
 			continue;
 
 		if (ud->device.driver && ud->device.driver->resume)
-			ud->device.driver->resume(&ud->device, 0);
+			ud->device.driver->resume(&ud->device);
 	}
 	up_read(&ne->device.bus->subsys.rwsem);
 
diff --git a/drivers/ieee1394/raw1394.c b/drivers/ieee1394/raw1394.c
index 0470f77..24411e6 100644
--- a/drivers/ieee1394/raw1394.c
+++ b/drivers/ieee1394/raw1394.c
@@ -2912,7 +2912,7 @@
 
 	hpsb_register_highlevel(&raw1394_highlevel);
 
-	if (IS_ERR(class_device_create(hpsb_protocol_class, MKDEV(
+	if (IS_ERR(class_device_create(hpsb_protocol_class, NULL, MKDEV(
 		IEEE1394_MAJOR,	IEEE1394_MINOR_BLOCK_RAW1394 * 16), 
 		NULL, RAW1394_DEVICE_NAME))) {
 		ret = -EFAULT;
diff --git a/drivers/ieee1394/video1394.c b/drivers/ieee1394/video1394.c
index 11be9c9..23911da 100644
--- a/drivers/ieee1394/video1394.c
+++ b/drivers/ieee1394/video1394.c
@@ -1370,7 +1370,7 @@
 	hpsb_set_hostinfo_key(&video1394_highlevel, host, ohci->host->id);
 
 	minor = IEEE1394_MINOR_BLOCK_VIDEO1394 * 16 + ohci->host->id;
-	class_device_create(hpsb_protocol_class, MKDEV(
+	class_device_create(hpsb_protocol_class, NULL, MKDEV(
 		IEEE1394_MAJOR,	minor), 
 		NULL, "%s-%d", VIDEO1394_DRIVER_NAME, ohci->host->id);
 	devfs_mk_cdev(MKDEV(IEEE1394_MAJOR, minor),
diff --git a/drivers/infiniband/core/ucm.c b/drivers/infiniband/core/ucm.c
index d0f0b0a..021b8f1 100644
--- a/drivers/infiniband/core/ucm.c
+++ b/drivers/infiniband/core/ucm.c
@@ -1300,7 +1300,7 @@
 		goto err_class;
 	}
 
-	class_device_create(ib_ucm_class, IB_UCM_DEV, NULL, "ucm");
+	class_device_create(ib_ucm_class, NULL, IB_UCM_DEV, NULL, "ucm");
 
 	idr_init(&ctx_id_table);
 	init_MUTEX(&ctx_id_mutex);
diff --git a/drivers/input/evdev.c b/drivers/input/evdev.c
index 3738d17..a4696cd 100644
--- a/drivers/input/evdev.c
+++ b/drivers/input/evdev.c
@@ -20,7 +20,6 @@
 #include <linux/major.h>
 #include <linux/smp_lock.h>
 #include <linux/device.h>
-#include <linux/devfs_fs_kernel.h>
 #include <linux/compat.h>
 
 struct evdev {
@@ -662,6 +661,7 @@
 static struct input_handle *evdev_connect(struct input_handler *handler, struct input_dev *dev, struct input_device_id *id)
 {
 	struct evdev *evdev;
+	struct class_device *cdev;
 	int minor;
 
 	for (minor = 0; minor < EVDEV_MINORS && evdev_table[minor]; minor++);
@@ -687,11 +687,13 @@
 
 	evdev_table[minor] = evdev;
 
-	devfs_mk_cdev(MKDEV(INPUT_MAJOR, EVDEV_MINOR_BASE + minor),
-			S_IFCHR|S_IRUGO|S_IWUSR, "input/event%d", minor);
-	class_device_create(input_class,
+	cdev = class_device_create(&input_class, &dev->cdev,
 			MKDEV(INPUT_MAJOR, EVDEV_MINOR_BASE + minor),
-			dev->dev, "event%d", minor);
+			dev->cdev.dev, evdev->name);
+
+	/* temporary symlink to keep userspace happy */
+	sysfs_create_link(&input_class.subsys.kset.kobj, &cdev->kobj,
+			  evdev->name);
 
 	return &evdev->handle;
 }
@@ -701,9 +703,9 @@
 	struct evdev *evdev = handle->private;
 	struct evdev_list *list;
 
-	class_device_destroy(input_class,
+	sysfs_remove_link(&input_class.subsys.kset.kobj, evdev->name);
+	class_device_destroy(&input_class,
 			MKDEV(INPUT_MAJOR, EVDEV_MINOR_BASE + evdev->minor));
-	devfs_remove("input/event%d", evdev->minor);
 	evdev->exist = 0;
 
 	if (evdev->open) {
diff --git a/drivers/input/input.c b/drivers/input/input.c
index 14ae558..3b1685f 100644
--- a/drivers/input/input.c
+++ b/drivers/input/input.c
@@ -22,12 +22,12 @@
 #include <linux/interrupt.h>
 #include <linux/poll.h>
 #include <linux/device.h>
-#include <linux/devfs_fs_kernel.h>
 
 MODULE_AUTHOR("Vojtech Pavlik <vojtech@suse.cz>");
 MODULE_DESCRIPTION("Input core");
 MODULE_LICENSE("GPL");
 
+EXPORT_SYMBOL(input_allocate_device);
 EXPORT_SYMBOL(input_register_device);
 EXPORT_SYMBOL(input_unregister_device);
 EXPORT_SYMBOL(input_register_handler);
@@ -39,7 +39,7 @@
 EXPORT_SYMBOL(input_accept_process);
 EXPORT_SYMBOL(input_flush_device);
 EXPORT_SYMBOL(input_event);
-EXPORT_SYMBOL(input_class);
+EXPORT_SYMBOL_GPL(input_class);
 
 #define INPUT_DEVICES	256
 
@@ -316,124 +316,21 @@
 	return NULL;
 }
 
-
-/*
- * Input hotplugging interface - loading event handlers based on
- * device bitfields.
- */
-
-#ifdef CONFIG_HOTPLUG
-
-/*
- * Input hotplugging invokes what /proc/sys/kernel/hotplug says
- * (normally /sbin/hotplug) when input devices get added or removed.
- *
- * This invokes a user mode policy agent, typically helping to load driver
- * or other modules, configure the device, and more.  Drivers can provide
- * a MODULE_DEVICE_TABLE to help with module loading subtasks.
- *
- */
-
-#define SPRINTF_BIT_A(bit, name, max) \
-	do { \
-		envp[i++] = scratch; \
-		scratch += sprintf(scratch, name); \
-		for (j = NBITS(max) - 1; j >= 0; j--) \
-			if (dev->bit[j]) break; \
-		for (; j >= 0; j--) \
-			scratch += sprintf(scratch, "%lx ", dev->bit[j]); \
-		scratch++; \
-	} while (0)
-
-#define SPRINTF_BIT_A2(bit, name, max, ev) \
-	do { \
-		if (test_bit(ev, dev->evbit)) \
-			SPRINTF_BIT_A(bit, name, max); \
-	} while (0)
-
-static void input_call_hotplug(char *verb, struct input_dev *dev)
+static int input_print_bitmap(char *buf, int buf_size, unsigned long *bitmap, int max)
 {
-	char *argv[3], **envp, *buf, *scratch;
-	int i = 0, j, value;
+	int i;
+	int len = 0;
 
-	if (!hotplug_path[0]) {
-		printk(KERN_ERR "input.c: calling hotplug without a hotplug agent defined\n");
-		return;
-	}
-	if (in_interrupt()) {
-		printk(KERN_ERR "input.c: calling hotplug from interrupt\n");
-		return;
-	}
-	if (!current->fs->root) {
-		printk(KERN_WARNING "input.c: calling hotplug without valid filesystem\n");
-		return;
-	}
-	if (!(envp = (char **) kmalloc(20 * sizeof(char *), GFP_KERNEL))) {
-		printk(KERN_ERR "input.c: not enough memory allocating hotplug environment\n");
-		return;
-	}
-	if (!(buf = kmalloc(1024, GFP_KERNEL))) {
-		kfree (envp);
-		printk(KERN_ERR "input.c: not enough memory allocating hotplug environment\n");
-		return;
-	}
+	for (i = NBITS(max) - 1; i > 0; i--)
+		if (bitmap[i])
+			break;
 
-	argv[0] = hotplug_path;
-	argv[1] = "input";
-	argv[2] = NULL;
-
-	envp[i++] = "HOME=/";
-	envp[i++] = "PATH=/sbin:/bin:/usr/sbin:/usr/bin";
-
-	scratch = buf;
-
-	envp[i++] = scratch;
-	scratch += sprintf(scratch, "ACTION=%s", verb) + 1;
-
-	envp[i++] = scratch;
-	scratch += sprintf(scratch, "PRODUCT=%x/%x/%x/%x",
-		dev->id.bustype, dev->id.vendor, dev->id.product, dev->id.version) + 1;
-
-	if (dev->name) {
-		envp[i++] = scratch;
-		scratch += sprintf(scratch, "NAME=%s", dev->name) + 1;
-	}
-
-	if (dev->phys) {
-		envp[i++] = scratch;
-		scratch += sprintf(scratch, "PHYS=%s", dev->phys) + 1;
-	}
-
-	SPRINTF_BIT_A(evbit, "EV=", EV_MAX);
-	SPRINTF_BIT_A2(keybit, "KEY=", KEY_MAX, EV_KEY);
-	SPRINTF_BIT_A2(relbit, "REL=", REL_MAX, EV_REL);
-	SPRINTF_BIT_A2(absbit, "ABS=", ABS_MAX, EV_ABS);
-	SPRINTF_BIT_A2(mscbit, "MSC=", MSC_MAX, EV_MSC);
-	SPRINTF_BIT_A2(ledbit, "LED=", LED_MAX, EV_LED);
-	SPRINTF_BIT_A2(sndbit, "SND=", SND_MAX, EV_SND);
-	SPRINTF_BIT_A2(ffbit,  "FF=",  FF_MAX, EV_FF);
-	SPRINTF_BIT_A2(swbit,  "SW=",  SW_MAX, EV_SW);
-
-	envp[i++] = NULL;
-
-#ifdef INPUT_DEBUG
-	printk(KERN_DEBUG "input.c: calling %s %s [%s %s %s %s %s]\n",
-		argv[0], argv[1], envp[0], envp[1], envp[2], envp[3], envp[4]);
-#endif
-
-	value = call_usermodehelper(argv [0], argv, envp, 0);
-
-	kfree(buf);
-	kfree(envp);
-
-#ifdef INPUT_DEBUG
-	if (value != 0)
-		printk(KERN_DEBUG "input.c: hotplug returned %d\n", value);
-#endif
+	for (; i >= 0; i--)
+		len += snprintf(buf + len, max(buf_size - len, 0),
+				"%lx%s", bitmap[i], i > 0 ? " " : "");
+	return len;
 }
 
-#endif
-
 #ifdef CONFIG_PROC_FS
 
 static struct proc_dir_entry *proc_bus_input_dir;
@@ -455,37 +352,39 @@
 	return 0;
 }
 
-#define SPRINTF_BIT_B(bit, name, max) \
-	do { \
-		len += sprintf(buf + len, "B: %s", name); \
-		for (i = NBITS(max) - 1; i >= 0; i--) \
-			if (dev->bit[i]) break; \
-		for (; i >= 0; i--) \
-			len += sprintf(buf + len, "%lx ", dev->bit[i]); \
-		len += sprintf(buf + len, "\n"); \
+#define SPRINTF_BIT(ev, bm)						\
+	do {								\
+		len += sprintf(buf + len, "B: %s=", #ev);		\
+		len += input_print_bitmap(buf + len, INT_MAX,		\
+					dev->bm##bit, ev##_MAX);	\
+		len += sprintf(buf + len, "\n");			\
 	} while (0)
 
-#define SPRINTF_BIT_B2(bit, name, max, ev) \
-	do { \
-		if (test_bit(ev, dev->evbit)) \
-			SPRINTF_BIT_B(bit, name, max); \
+#define TEST_AND_SPRINTF_BIT(ev, bm)					\
+	do {								\
+		if (test_bit(EV_##ev, dev->evbit))			\
+			SPRINTF_BIT(ev, bm);				\
 	} while (0)
 
 static int input_devices_read(char *buf, char **start, off_t pos, int count, int *eof, void *data)
 {
 	struct input_dev *dev;
 	struct input_handle *handle;
+	const char *path;
 
 	off_t at = 0;
-	int i, len, cnt = 0;
+	int len, cnt = 0;
 
 	list_for_each_entry(dev, &input_dev_list, node) {
 
+		path = dev->dynalloc ? kobject_get_path(&dev->cdev.kobj, GFP_KERNEL) : NULL;
+
 		len = sprintf(buf, "I: Bus=%04x Vendor=%04x Product=%04x Version=%04x\n",
 			dev->id.bustype, dev->id.vendor, dev->id.product, dev->id.version);
 
 		len += sprintf(buf + len, "N: Name=\"%s\"\n", dev->name ? dev->name : "");
 		len += sprintf(buf + len, "P: Phys=%s\n", dev->phys ? dev->phys : "");
+		len += sprintf(buf + len, "S: Sysfs=%s\n", path ? path : "");
 		len += sprintf(buf + len, "H: Handlers=");
 
 		list_for_each_entry(handle, &dev->h_list, d_node)
@@ -493,15 +392,15 @@
 
 		len += sprintf(buf + len, "\n");
 
-		SPRINTF_BIT_B(evbit, "EV=", EV_MAX);
-		SPRINTF_BIT_B2(keybit, "KEY=", KEY_MAX, EV_KEY);
-		SPRINTF_BIT_B2(relbit, "REL=", REL_MAX, EV_REL);
-		SPRINTF_BIT_B2(absbit, "ABS=", ABS_MAX, EV_ABS);
-		SPRINTF_BIT_B2(mscbit, "MSC=", MSC_MAX, EV_MSC);
-		SPRINTF_BIT_B2(ledbit, "LED=", LED_MAX, EV_LED);
-		SPRINTF_BIT_B2(sndbit, "SND=", SND_MAX, EV_SND);
-		SPRINTF_BIT_B2(ffbit,  "FF=",  FF_MAX, EV_FF);
-		SPRINTF_BIT_B2(swbit,  "SW=",  SW_MAX, EV_SW);
+		SPRINTF_BIT(EV, ev);
+		TEST_AND_SPRINTF_BIT(KEY, key);
+		TEST_AND_SPRINTF_BIT(REL, rel);
+		TEST_AND_SPRINTF_BIT(ABS, abs);
+		TEST_AND_SPRINTF_BIT(MSC, msc);
+		TEST_AND_SPRINTF_BIT(LED, led);
+		TEST_AND_SPRINTF_BIT(SND, snd);
+		TEST_AND_SPRINTF_BIT(FF, ff);
+		TEST_AND_SPRINTF_BIT(SW, sw);
 
 		len += sprintf(buf + len, "\n");
 
@@ -516,6 +415,8 @@
 			if (cnt >= count)
 				break;
 		}
+
+		kfree(path);
 	}
 
 	if (&dev->node == &input_dev_list)
@@ -606,6 +507,240 @@
 static inline void input_proc_exit(void) { }
 #endif
 
+#define INPUT_DEV_STRING_ATTR_SHOW(name)					\
+static ssize_t input_dev_show_##name(struct class_device *dev, char *buf)	\
+{										\
+	struct input_dev *input_dev = to_input_dev(dev);			\
+	int retval;								\
+										\
+	retval = down_interruptible(&input_dev->sem);				\
+	if (retval)								\
+		return retval;							\
+										\
+	retval = sprintf(buf, "%s\n", input_dev->name ? input_dev->name : "");	\
+										\
+	up(&input_dev->sem);							\
+										\
+	return retval;								\
+}										\
+static CLASS_DEVICE_ATTR(name, S_IRUGO, input_dev_show_##name, NULL);
+
+INPUT_DEV_STRING_ATTR_SHOW(name);
+INPUT_DEV_STRING_ATTR_SHOW(phys);
+INPUT_DEV_STRING_ATTR_SHOW(uniq);
+
+static struct attribute *input_dev_attrs[] = {
+	&class_device_attr_name.attr,
+	&class_device_attr_phys.attr,
+	&class_device_attr_uniq.attr,
+	NULL
+};
+
+static struct attribute_group input_dev_group = {
+	.attrs	= input_dev_attrs,
+};
+
+#define INPUT_DEV_ID_ATTR(name)							\
+static ssize_t input_dev_show_id_##name(struct class_device *dev, char *buf)	\
+{										\
+	struct input_dev *input_dev = to_input_dev(dev);			\
+	return sprintf(buf, "%04x\n", input_dev->id.name);			\
+}										\
+static CLASS_DEVICE_ATTR(name, S_IRUGO, input_dev_show_id_##name, NULL);
+
+INPUT_DEV_ID_ATTR(bustype);
+INPUT_DEV_ID_ATTR(vendor);
+INPUT_DEV_ID_ATTR(product);
+INPUT_DEV_ID_ATTR(version);
+
+static struct attribute *input_dev_id_attrs[] = {
+	&class_device_attr_bustype.attr,
+	&class_device_attr_vendor.attr,
+	&class_device_attr_product.attr,
+	&class_device_attr_version.attr,
+	NULL
+};
+
+static struct attribute_group input_dev_id_attr_group = {
+	.name	= "id",
+	.attrs	= input_dev_id_attrs,
+};
+
+#define INPUT_DEV_CAP_ATTR(ev, bm)						\
+static ssize_t input_dev_show_cap_##bm(struct class_device *dev, char *buf)	\
+{										\
+	struct input_dev *input_dev = to_input_dev(dev);			\
+	return input_print_bitmap(buf, PAGE_SIZE, input_dev->bm##bit, ev##_MAX);\
+}										\
+static CLASS_DEVICE_ATTR(bm, S_IRUGO, input_dev_show_cap_##bm, NULL);
+
+INPUT_DEV_CAP_ATTR(EV, ev);
+INPUT_DEV_CAP_ATTR(KEY, key);
+INPUT_DEV_CAP_ATTR(REL, rel);
+INPUT_DEV_CAP_ATTR(ABS, abs);
+INPUT_DEV_CAP_ATTR(MSC, msc);
+INPUT_DEV_CAP_ATTR(LED, led);
+INPUT_DEV_CAP_ATTR(SND, snd);
+INPUT_DEV_CAP_ATTR(FF, ff);
+INPUT_DEV_CAP_ATTR(SW, sw);
+
+static struct attribute *input_dev_caps_attrs[] = {
+	&class_device_attr_ev.attr,
+	&class_device_attr_key.attr,
+	&class_device_attr_rel.attr,
+	&class_device_attr_abs.attr,
+	&class_device_attr_msc.attr,
+	&class_device_attr_led.attr,
+	&class_device_attr_snd.attr,
+	&class_device_attr_ff.attr,
+	&class_device_attr_sw.attr,
+	NULL
+};
+
+static struct attribute_group input_dev_caps_attr_group = {
+	.name	= "capabilities",
+	.attrs	= input_dev_caps_attrs,
+};
+
+static void input_dev_release(struct class_device *class_dev)
+{
+	struct input_dev *dev = to_input_dev(class_dev);
+
+	kfree(dev);
+	module_put(THIS_MODULE);
+}
+
+/*
+ * Input hotplugging interface - loading event handlers based on
+ * device bitfields.
+ */
+static int input_add_hotplug_bm_var(char **envp, int num_envp, int *cur_index,
+				    char *buffer, int buffer_size, int *cur_len,
+				    const char *name, unsigned long *bitmap, int max)
+{
+	if (*cur_index >= num_envp - 1)
+		return -ENOMEM;
+
+	envp[*cur_index] = buffer + *cur_len;
+
+	*cur_len += snprintf(buffer + *cur_len, max(buffer_size - *cur_len, 0), name);
+	if (*cur_len > buffer_size)
+		return -ENOMEM;
+
+	*cur_len += input_print_bitmap(buffer + *cur_len,
+					max(buffer_size - *cur_len, 0),
+					bitmap, max) + 1;
+	if (*cur_len > buffer_size)
+		return -ENOMEM;
+
+	(*cur_index)++;
+	return 0;
+}
+
+#define INPUT_ADD_HOTPLUG_VAR(fmt, val...)				\
+	do {								\
+		int err = add_hotplug_env_var(envp, num_envp, &i,	\
+					buffer, buffer_size, &len,	\
+					fmt, val);			\
+		if (err)						\
+			return err;					\
+	} while (0)
+
+#define INPUT_ADD_HOTPLUG_BM_VAR(name, bm, max)				\
+	do {								\
+		int err = input_add_hotplug_bm_var(envp, num_envp, &i,	\
+					buffer, buffer_size, &len,	\
+					name, bm, max);			\
+		if (err)						\
+			return err;					\
+	} while (0)
+
+static int input_dev_hotplug(struct class_device *cdev, char **envp,
+			     int num_envp, char *buffer, int buffer_size)
+{
+	struct input_dev *dev = to_input_dev(cdev);
+	int i = 0;
+	int len = 0;
+
+	INPUT_ADD_HOTPLUG_VAR("PRODUCT=%x/%x/%x/%x",
+				dev->id.bustype, dev->id.vendor,
+				dev->id.product, dev->id.version);
+	if (dev->name)
+		INPUT_ADD_HOTPLUG_VAR("NAME=\"%s\"", dev->name);
+	if (dev->phys)
+		INPUT_ADD_HOTPLUG_VAR("PHYS=\"%s\"", dev->phys);
+	if (dev->phys)
+		INPUT_ADD_HOTPLUG_VAR("UNIQ=\"%s\"", dev->uniq);
+
+	INPUT_ADD_HOTPLUG_BM_VAR("EV=", dev->evbit, EV_MAX);
+	if (test_bit(EV_KEY, dev->evbit))
+		INPUT_ADD_HOTPLUG_BM_VAR("KEY=", dev->keybit, KEY_MAX);
+	if (test_bit(EV_REL, dev->evbit))
+		INPUT_ADD_HOTPLUG_BM_VAR("REL=", dev->relbit, REL_MAX);
+	if (test_bit(EV_ABS, dev->evbit))
+		INPUT_ADD_HOTPLUG_BM_VAR("ABS=", dev->absbit, ABS_MAX);
+	if (test_bit(EV_MSC, dev->evbit))
+		INPUT_ADD_HOTPLUG_BM_VAR("MSC=", dev->mscbit, MSC_MAX);
+	if (test_bit(EV_LED, dev->evbit))
+		INPUT_ADD_HOTPLUG_BM_VAR("LED=", dev->ledbit, LED_MAX);
+	if (test_bit(EV_SND, dev->evbit))
+		INPUT_ADD_HOTPLUG_BM_VAR("SND=", dev->sndbit, SND_MAX);
+	if (test_bit(EV_FF, dev->evbit))
+		INPUT_ADD_HOTPLUG_BM_VAR("FF=", dev->ffbit, FF_MAX);
+	if (test_bit(EV_SW, dev->evbit))
+		INPUT_ADD_HOTPLUG_BM_VAR("SW=", dev->swbit, SW_MAX);
+
+	envp[i] = NULL;
+
+	return 0;
+}
+
+struct class input_class = {
+	.name			= "input",
+	.release		= input_dev_release,
+	.hotplug		= input_dev_hotplug,
+};
+
+struct input_dev *input_allocate_device(void)
+{
+	struct input_dev *dev;
+
+	dev = kzalloc(sizeof(struct input_dev), GFP_KERNEL);
+	if (dev) {
+		dev->dynalloc = 1;
+		dev->cdev.class = &input_class;
+		class_device_initialize(&dev->cdev);
+		INIT_LIST_HEAD(&dev->h_list);
+		INIT_LIST_HEAD(&dev->node);
+	}
+
+	return dev;
+}
+
+static void input_register_classdevice(struct input_dev *dev)
+{
+	static atomic_t input_no = ATOMIC_INIT(0);
+	const char *path;
+
+	__module_get(THIS_MODULE);
+
+	dev->dev = dev->cdev.dev;
+
+	snprintf(dev->cdev.class_id, sizeof(dev->cdev.class_id),
+		 "input%ld", (unsigned long) atomic_inc_return(&input_no) - 1);
+
+	path = kobject_get_path(&dev->cdev.class->subsys.kset.kobj, GFP_KERNEL);
+	printk(KERN_INFO "input: %s/%s as %s\n",
+		dev->name ? dev->name : "Unspecified device",
+		path ? path : "", dev->cdev.class_id);
+	kfree(path);
+
+	class_device_add(&dev->cdev);
+	sysfs_create_group(&dev->cdev.kobj, &input_dev_group);
+	sysfs_create_group(&dev->cdev.kobj, &input_dev_id_attr_group);
+	sysfs_create_group(&dev->cdev.kobj, &input_dev_caps_attr_group);
+}
+
 void input_register_device(struct input_dev *dev)
 {
 	struct input_handle *handle;
@@ -632,15 +767,15 @@
 	INIT_LIST_HEAD(&dev->h_list);
 	list_add_tail(&dev->node, &input_dev_list);
 
+	if (dev->dynalloc)
+		input_register_classdevice(dev);
+
 	list_for_each_entry(handler, &input_handler_list, node)
 		if (!handler->blacklist || !input_match_device(handler->blacklist, dev))
 			if ((id = input_match_device(handler->id_table, dev)))
 				if ((handle = handler->connect(handler, dev, id)))
 					input_link_handle(handle);
 
-#ifdef CONFIG_HOTPLUG
-	input_call_hotplug("add", dev);
-#endif
 
 	input_wakeup_procfs_readers();
 }
@@ -660,12 +795,14 @@
 		handle->handler->disconnect(handle);
 	}
 
-#ifdef CONFIG_HOTPLUG
-	input_call_hotplug("remove", dev);
-#endif
-
 	list_del_init(&dev->node);
 
+	if (dev->dynalloc) {
+		sysfs_remove_group(&dev->cdev.kobj, &input_dev_caps_attr_group);
+		sysfs_remove_group(&dev->cdev.kobj, &input_dev_id_attr_group);
+		class_device_unregister(&dev->cdev);
+	}
+
 	input_wakeup_procfs_readers();
 }
 
@@ -748,16 +885,14 @@
 	.open = input_open_file,
 };
 
-struct class *input_class;
-
 static int __init input_init(void)
 {
 	int err;
 
-	input_class = class_create(THIS_MODULE, "input");
-	if (IS_ERR(input_class)) {
-		printk(KERN_ERR "input: unable to register input class\n");
-		return PTR_ERR(input_class);
+	err = class_register(&input_class);
+	if (err) {
+		printk(KERN_ERR "input: unable to register input_dev class\n");
+		return err;
 	}
 
 	err = input_proc_init();
@@ -770,24 +905,18 @@
 		goto fail2;
 	}
 
-	err = devfs_mk_dir("input");
-	if (err)
-		goto fail3;
-
 	return 0;
 
- fail3:	unregister_chrdev(INPUT_MAJOR, "input");
  fail2:	input_proc_exit();
- fail1:	class_destroy(input_class);
+ fail1:	class_unregister(&input_class);
 	return err;
 }
 
 static void __exit input_exit(void)
 {
 	input_proc_exit();
-	devfs_remove("input");
 	unregister_chrdev(INPUT_MAJOR, "input");
-	class_destroy(input_class);
+	class_unregister(&input_class);
 }
 
 subsys_initcall(input_init);
diff --git a/drivers/input/joydev.c b/drivers/input/joydev.c
index e0938d1..20e2972 100644
--- a/drivers/input/joydev.c
+++ b/drivers/input/joydev.c
@@ -26,7 +26,6 @@
 #include <linux/init.h>
 #include <linux/smp_lock.h>
 #include <linux/device.h>
-#include <linux/devfs_fs_kernel.h>
 
 MODULE_AUTHOR("Vojtech Pavlik <vojtech@ucw.cz>");
 MODULE_DESCRIPTION("Joystick device interfaces");
@@ -449,6 +448,7 @@
 static struct input_handle *joydev_connect(struct input_handler *handler, struct input_dev *dev, struct input_device_id *id)
 {
 	struct joydev *joydev;
+	struct class_device *cdev;
 	int i, j, t, minor;
 
 	for (minor = 0; minor < JOYDEV_MINORS && joydev_table[minor]; minor++);
@@ -514,11 +514,13 @@
 
 	joydev_table[minor] = joydev;
 
-	devfs_mk_cdev(MKDEV(INPUT_MAJOR, JOYDEV_MINOR_BASE + minor),
-			S_IFCHR|S_IRUGO|S_IWUSR, "input/js%d", minor);
-	class_device_create(input_class,
+	cdev = class_device_create(&input_class, &dev->cdev,
 			MKDEV(INPUT_MAJOR, JOYDEV_MINOR_BASE + minor),
-			dev->dev, "js%d", minor);
+			dev->cdev.dev, joydev->name);
+
+	/* temporary symlink to keep userspace happy */
+	sysfs_create_link(&input_class.subsys.kset.kobj, &cdev->kobj,
+			  joydev->name);
 
 	return &joydev->handle;
 }
@@ -528,8 +530,8 @@
 	struct joydev *joydev = handle->private;
 	struct joydev_list *list;
 
-	class_device_destroy(input_class, MKDEV(INPUT_MAJOR, JOYDEV_MINOR_BASE + joydev->minor));
-	devfs_remove("input/js%d", joydev->minor);
+	sysfs_remove_link(&input_class.subsys.kset.kobj, joydev->name);
+	class_device_destroy(&input_class, MKDEV(INPUT_MAJOR, JOYDEV_MINOR_BASE + joydev->minor));
 	joydev->exist = 0;
 
 	if (joydev->open) {
diff --git a/drivers/input/joystick/adi.c b/drivers/input/joystick/adi.c
index cf35ae6..9d95459 100644
--- a/drivers/input/joystick/adi.c
+++ b/drivers/input/joystick/adi.c
@@ -54,7 +54,7 @@
 #define ADI_MIN_LENGTH		8
 #define ADI_MIN_LEN_LENGTH	10
 #define ADI_MIN_ID_LENGTH	66
-#define ADI_MAX_NAME_LENGTH	48
+#define ADI_MAX_NAME_LENGTH	64
 #define ADI_MAX_CNAME_LENGTH	16
 #define ADI_MAX_PHYS_LENGTH	64
 
@@ -106,7 +106,7 @@
  */
 
 struct adi {
-	struct input_dev dev;
+	struct input_dev *dev;
 	int length;
 	int ret;
 	int idx;
@@ -215,7 +215,7 @@
 
 static int adi_decode(struct adi *adi)
 {
-	struct input_dev *dev = &adi->dev;
+	struct input_dev *dev = adi->dev;
 	char *abs = adi->abs;
 	short *key = adi->key;
 	int i, t;
@@ -318,7 +318,8 @@
 
 	for (i = 0; seq[i]; i++) {
 		gameport_trigger(gameport);
-		if (seq[i] > 0) msleep(seq[i]);
+		if (seq[i] > 0)
+			msleep(seq[i]);
 		if (seq[i] < 0) {
 			mdelay(-seq[i]);
 			udelay(-seq[i]*14);	/* It looks like mdelay() is off by approx 1.4% */
@@ -397,42 +398,46 @@
 	}
 }
 
-static void adi_init_input(struct adi *adi, struct adi_port *port, int half)
+static int adi_init_input(struct adi *adi, struct adi_port *port, int half)
 {
-	int i, t;
+	struct input_dev *input_dev;
 	char buf[ADI_MAX_NAME_LENGTH];
+	int i, t;
 
-	if (!adi->length) return;
-
-	init_input_dev(&adi->dev);
+	adi->dev = input_dev = input_allocate_device();
+	if (!input_dev)
+		return -ENOMEM;
 
 	t = adi->id < ADI_ID_MAX ? adi->id : ADI_ID_MAX;
 
 	snprintf(buf, ADI_MAX_PHYS_LENGTH, adi_names[t], adi->id);
-	snprintf(adi->name, ADI_MAX_NAME_LENGTH, "Logitech %s", buf);
+	snprintf(adi->name, ADI_MAX_NAME_LENGTH, "Logitech %s [%s]", buf, adi->cname);
 	snprintf(adi->phys, ADI_MAX_PHYS_LENGTH, "%s/input%d", port->gameport->phys, half);
 
 	adi->abs = adi_abs[t];
 	adi->key = adi_key[t];
 
-	adi->dev.open = adi_open;
-	adi->dev.close = adi_close;
+	input_dev->name = adi->name;
+	input_dev->phys = adi->phys;
+	input_dev->id.bustype = BUS_GAMEPORT;
+	input_dev->id.vendor = GAMEPORT_ID_VENDOR_LOGITECH;
+	input_dev->id.product = adi->id;
+	input_dev->id.version = 0x0100;
+	input_dev->cdev.dev = &port->gameport->dev;
+	input_dev->private = port;
 
-	adi->dev.name = adi->name;
-	adi->dev.phys = adi->phys;
-	adi->dev.id.bustype = BUS_GAMEPORT;
-	adi->dev.id.vendor = GAMEPORT_ID_VENDOR_LOGITECH;
-	adi->dev.id.product = adi->id;
-	adi->dev.id.version = 0x0100;
+	input_dev->open = adi_open;
+	input_dev->close = adi_close;
 
-	adi->dev.private = port;
-	adi->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
+	input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
 
 	for (i = 0; i < adi->axes10 + adi->axes8 + (adi->hats + (adi->pad != -1)) * 2; i++)
-		set_bit(adi->abs[i], adi->dev.absbit);
+		set_bit(adi->abs[i], input_dev->absbit);
 
 	for (i = 0; i < adi->buttons; i++)
-		set_bit(adi->key[i], adi->dev.keybit);
+		set_bit(adi->key[i], input_dev->keybit);
+
+	return 0;
 }
 
 static void adi_init_center(struct adi *adi)
@@ -445,17 +450,17 @@
 	for (i = 0; i < adi->axes10 + adi->axes8 + (adi->hats + (adi->pad != -1)) * 2; i++) {
 
 		t = adi->abs[i];
-		x = adi->dev.abs[t];
+		x = adi->dev->abs[t];
 
 		if (t == ABS_THROTTLE || t == ABS_RUDDER || adi->id == ADI_ID_WGPE)
 			x = i < adi->axes10 ? 512 : 128;
 
 		if (i < adi->axes10)
-			input_set_abs_params(&adi->dev, t, 64, x * 2 - 64, 2, 16);
+			input_set_abs_params(adi->dev, t, 64, x * 2 - 64, 2, 16);
 		else if (i < adi->axes10 + adi->axes8)
-			input_set_abs_params(&adi->dev, t, 48, x * 2 - 48, 1, 16);
+			input_set_abs_params(adi->dev, t, 48, x * 2 - 48, 1, 16);
 		else
-			input_set_abs_params(&adi->dev, t, -1, 1, 0, 0);
+			input_set_abs_params(adi->dev, t, -1, 1, 0, 0);
 	}
 }
 
@@ -469,7 +474,8 @@
 	int i;
 	int err;
 
-	if (!(port = kzalloc(sizeof(struct adi_port), GFP_KERNEL)))
+	port = kzalloc(sizeof(struct adi_port), GFP_KERNEL);
+	if (!port)
 		return -ENOMEM;
 
 	port->gameport = gameport;
@@ -477,10 +483,8 @@
 	gameport_set_drvdata(gameport, port);
 
 	err = gameport_open(gameport, drv, GAMEPORT_MODE_RAW);
-	if (err) {
-		kfree(port);
-		return err;
-	}
+	if (err)
+		goto fail1;
 
 	adi_init_digital(gameport);
 	adi_read_packet(port);
@@ -490,13 +494,18 @@
 
 	for (i = 0; i < 2; i++) {
 		adi_id_decode(port->adi + i, port);
-		adi_init_input(port->adi + i, port, i);
+
+		if (!port->adi[i].length)
+			continue;
+
+		err = adi_init_input(port->adi + i, port, i);
+		if (err)
+			goto fail2;
 	}
 
 	if (!port->adi[0].length && !port->adi[1].length) {
-		gameport_close(gameport);
-		kfree(port);
-		return -ENODEV;
+		err = -ENODEV;
+		goto fail2;
 	}
 
 	gameport_set_poll_handler(gameport, adi_poll);
@@ -511,12 +520,18 @@
 	for (i = 0; i < 2; i++)
 		if (port->adi[i].length > 0) {
 			adi_init_center(port->adi + i);
-			input_register_device(&port->adi[i].dev);
-			printk(KERN_INFO "input: %s [%s] on %s\n",
-				port->adi[i].name, port->adi[i].cname, gameport->phys);
+			input_register_device(port->adi[i].dev);
 		}
 
 	return 0;
+
+ fail2:	for (i = 0; i < 2; i++)
+		if (port->adi[i].dev)
+			input_free_device(port->adi[i].dev);
+	gameport_close(gameport);
+ fail1:	gameport_set_drvdata(gameport, NULL);
+	kfree(port);
+	return err;
 }
 
 static void adi_disconnect(struct gameport *gameport)
@@ -526,7 +541,7 @@
 
 	for (i = 0; i < 2; i++)
 		if (port->adi[i].length > 0)
-			input_unregister_device(&port->adi[i].dev);
+			input_unregister_device(port->adi[i].dev);
 	gameport_close(gameport);
 	gameport_set_drvdata(gameport, NULL);
 	kfree(port);
diff --git a/drivers/input/joystick/amijoy.c b/drivers/input/joystick/amijoy.c
index e996183..8558a99 100644
--- a/drivers/input/joystick/amijoy.c
+++ b/drivers/input/joystick/amijoy.c
@@ -53,11 +53,9 @@
 
 static int amijoy_used;
 static DECLARE_MUTEX(amijoy_sem);
-static struct input_dev amijoy_dev[2];
+static struct input_dev *amijoy_dev[2];
 static char *amijoy_phys[2] = { "amijoy/input0", "amijoy/input1" };
 
-static char *amijoy_name = "Amiga joystick";
-
 static irqreturn_t amijoy_interrupt(int irq, void *dummy, struct pt_regs *fp)
 {
 	int i, data = 0, button = 0;
@@ -70,15 +68,15 @@
 				case 1: data = ~custom.joy1dat; button = (~ciaa.pra >> 7) & 1; break;
 			}
 
-			input_regs(amijoy_dev + i, fp);
+			input_regs(amijoy_dev[i], fp);
 
-			input_report_key(amijoy_dev + i, BTN_TRIGGER, button);
+			input_report_key(amijoy_dev[i], BTN_TRIGGER, button);
 
-			input_report_abs(amijoy_dev + i, ABS_X, ((data >> 1) & 1) - ((data >> 9) & 1));
+			input_report_abs(amijoy_dev[i], ABS_X, ((data >> 1) & 1) - ((data >> 9) & 1));
 			data = ~(data ^ (data << 1));
-			input_report_abs(amijoy_dev + i, ABS_Y, ((data >> 1) & 1) - ((data >> 9) & 1));
+			input_report_abs(amijoy_dev[i], ABS_Y, ((data >> 1) & 1) - ((data >> 9) & 1));
 
-			input_sync(amijoy_dev + i);
+			input_sync(amijoy_dev[i]);
 		}
 	return IRQ_HANDLED;
 }
@@ -114,39 +112,52 @@
 static int __init amijoy_init(void)
 {
 	int i, j;
+	int err;
 
-	for (i = 0; i < 2; i++)
-		if (amijoy[i]) {
-			if (!request_mem_region(CUSTOM_PHYSADDR+10+i*2, 2,
-						"amijoy [Denise]")) {
-				if (i == 1 && amijoy[0]) {
-					input_unregister_device(amijoy_dev);
-					release_mem_region(CUSTOM_PHYSADDR+10, 2);
-				}
-				return -EBUSY;
-			}
+	for (i = 0; i < 2; i++) {
+		if (!amijoy[i])
+			continue;
 
-			amijoy_dev[i].open = amijoy_open;
-			amijoy_dev[i].close = amijoy_close;
-			amijoy_dev[i].evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
-			amijoy_dev[i].absbit[0] = BIT(ABS_X) | BIT(ABS_Y);
-			amijoy_dev[i].keybit[LONG(BTN_LEFT)] = BIT(BTN_LEFT) | BIT(BTN_MIDDLE) | BIT(BTN_RIGHT);
-			for (j = 0; j < 2; j++) {
-				amijoy_dev[i].absmin[ABS_X + j] = -1;
-				amijoy_dev[i].absmax[ABS_X + j] = 1;
-			}
-
-			amijoy_dev[i].name = amijoy_name;
-			amijoy_dev[i].phys = amijoy_phys[i];
-			amijoy_dev[i].id.bustype = BUS_AMIGA;
-			amijoy_dev[i].id.vendor = 0x0001;
-			amijoy_dev[i].id.product = 0x0003;
-			amijoy_dev[i].id.version = 0x0100;
-
-			input_register_device(amijoy_dev + i);
-			printk(KERN_INFO "input: %s at joy%ddat\n", amijoy_name, i);
+		amijoy_dev[i] = input_allocate_device();
+		if (!amijoy_dev[i]) {
+			err = -ENOMEM;
+			goto fail;
 		}
+
+		if (!request_mem_region(CUSTOM_PHYSADDR + 10 + i * 2, 2, "amijoy [Denise]")) {
+			input_free_device(amijoy_dev[i]);
+			err = -EBUSY;
+			goto fail;
+		}
+
+		amijoy_dev[i]->name = "Amiga joystick";
+		amijoy_dev[i]->phys = amijoy_phys[i];
+		amijoy_dev[i]->id.bustype = BUS_AMIGA;
+		amijoy_dev[i]->id.vendor = 0x0001;
+		amijoy_dev[i]->id.product = 0x0003;
+		amijoy_dev[i]->id.version = 0x0100;
+
+		amijoy_dev[i]->open = amijoy_open;
+		amijoy_dev[i]->close = amijoy_close;
+
+		amijoy_dev[i]->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
+		amijoy_dev[i]->absbit[0] = BIT(ABS_X) | BIT(ABS_Y);
+		amijoy_dev[i]->keybit[LONG(BTN_LEFT)] = BIT(BTN_LEFT) | BIT(BTN_MIDDLE) | BIT(BTN_RIGHT);
+		for (j = 0; j < 2; j++) {
+			amijoy_dev[i]->absmin[ABS_X + j] = -1;
+			amijoy_dev[i]->absmax[ABS_X + j] = 1;
+		}
+
+		input_register_device(amijoy_dev[i]);
+	}
 	return 0;
+
+ fail:	while (--i >= 0)
+		if (amijoy[i]) {
+			input_unregister_device(amijoy_dev[i]);
+			release_mem_region(CUSTOM_PHYSADDR + 10 + i * 2, 2);
+		}
+	return err;
 }
 
 static void __exit amijoy_exit(void)
@@ -155,8 +166,8 @@
 
 	for (i = 0; i < 2; i++)
 		if (amijoy[i]) {
-			input_unregister_device(amijoy_dev + i);
-			release_mem_region(CUSTOM_PHYSADDR+10+i*2, 2);
+			input_unregister_device(amijoy_dev[i]);
+			release_mem_region(CUSTOM_PHYSADDR + 10 + i * 2, 2);
 		}
 }
 
diff --git a/drivers/input/joystick/analog.c b/drivers/input/joystick/analog.c
index 64b1313..c75ac6e 100644
--- a/drivers/input/joystick/analog.c
+++ b/drivers/input/joystick/analog.c
@@ -111,7 +111,7 @@
 static unsigned char analog_chf[] = { 0xf, 0x0, 0x1, 0x9, 0x2, 0x4, 0xc, 0x8, 0x3, 0x5, 0xb, 0x7, 0xd, 0xe, 0xa, 0x6 };
 
 struct analog {
-	struct input_dev dev;
+	struct input_dev *dev;
 	int mask;
 	short *buttons;
 	char name[ANALOG_MAX_NAME_LENGTH];
@@ -182,7 +182,7 @@
 
 static void analog_decode(struct analog *analog, int *axes, int *initial, int buttons)
 {
-	struct input_dev *dev = &analog->dev;
+	struct input_dev *dev = analog->dev;
 	int i, j;
 
 	if (analog->mask & ANALOG_HAT_FCS)
@@ -428,27 +428,30 @@
  * analog_init_device()
  */
 
-static void analog_init_device(struct analog_port *port, struct analog *analog, int index)
+static int analog_init_device(struct analog_port *port, struct analog *analog, int index)
 {
+	struct input_dev *input_dev;
 	int i, j, t, v, w, x, y, z;
 
 	analog_name(analog);
 	sprintf(analog->phys, "%s/input%d", port->gameport->phys, index);
 	analog->buttons = (analog->mask & ANALOG_GAMEPAD) ? analog_pad_btn : analog_joy_btn;
 
-	init_input_dev(&analog->dev);
+	analog->dev = input_dev = input_allocate_device();
+	if (!input_dev)
+		return -ENOMEM;
 
-	analog->dev.name = analog->name;
-	analog->dev.phys = analog->phys;
-	analog->dev.id.bustype = BUS_GAMEPORT;
-	analog->dev.id.vendor = GAMEPORT_ID_VENDOR_ANALOG;
-	analog->dev.id.product = analog->mask >> 4;
-	analog->dev.id.version = 0x0100;
+	input_dev->name = analog->name;
+	input_dev->phys = analog->phys;
+	input_dev->id.bustype = BUS_GAMEPORT;
+	input_dev->id.vendor = GAMEPORT_ID_VENDOR_ANALOG;
+	input_dev->id.product = analog->mask >> 4;
+	input_dev->id.version = 0x0100;
 
-	analog->dev.open = analog_open;
-	analog->dev.close = analog_close;
-	analog->dev.private = port;
-	analog->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
+	input_dev->open = analog_open;
+	input_dev->close = analog_close;
+	input_dev->private = port;
+	input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
 
 	for (i = j = 0; i < 4; i++)
 		if (analog->mask & (1 << i)) {
@@ -461,8 +464,6 @@
 			v = (x >> 3);
 			w = (x >> 3);
 
-			set_bit(t, analog->dev.absbit);
-
 			if ((i == 2 || i == 3) && (j == 2 || j == 3) && (z > (y >> 3)))
 				x = y;
 
@@ -472,11 +473,7 @@
 				w = (x >> 4);
 			}
 
-			analog->dev.absmax[t] = (x << 1) - v;
-			analog->dev.absmin[t] = v;
-			analog->dev.absfuzz[t] = port->fuzz;
-			analog->dev.absflat[t] = w;
-
+			input_set_abs_params(input_dev, t, v, (x << 1) - v, port->fuzz, w);
 			j++;
 		}
 
@@ -484,41 +481,30 @@
 		if (analog->mask & analog_exts[i])
 			for (x = 0; x < 2; x++) {
 				t = analog_hats[j++];
-				set_bit(t, analog->dev.absbit);
-				analog->dev.absmax[t] = 1;
-				analog->dev.absmin[t] = -1;
+				input_set_abs_params(input_dev, t, -1, 1, 0, 0);
 			}
 
 	for (i = j = 0; i < 4; i++)
 		if (analog->mask & (0x10 << i))
-			set_bit(analog->buttons[j++], analog->dev.keybit);
+			set_bit(analog->buttons[j++], input_dev->keybit);
 
 	if (analog->mask & ANALOG_BTNS_CHF)
 		for (i = 0; i < 2; i++)
-			set_bit(analog->buttons[j++], analog->dev.keybit);
+			set_bit(analog->buttons[j++], input_dev->keybit);
 
 	if (analog->mask & ANALOG_HBTN_CHF)
 		for (i = 0; i < 4; i++)
-			set_bit(analog->buttons[j++], analog->dev.keybit);
+			set_bit(analog->buttons[j++], input_dev->keybit);
 
 	for (i = 0; i < 4; i++)
 		if (analog->mask & (ANALOG_BTN_TL << i))
-			set_bit(analog_pads[i], analog->dev.keybit);
+			set_bit(analog_pads[i], input_dev->keybit);
 
 	analog_decode(analog, port->axes, port->initial, port->buttons);
 
-	input_register_device(&analog->dev);
+	input_register_device(analog->dev);
 
-	printk(KERN_INFO "input: %s at %s", analog->name, port->gameport->phys);
-
-	if (port->cooked)
-		printk(" [ADC port]\n");
-	else
-		printk(" [%s timer, %d %sHz clock, %d ns res]\n", TIME_NAME,
-		port->speed > 10000 ? (port->speed + 800) / 1000 : port->speed,
-		port->speed > 10000 ? "M" : "k",
-		port->speed > 10000 ? (port->loop * 1000) / (port->speed / 1000)
-				    : (port->loop * 1000000) / port->speed);
+	return 0;
 }
 
 /*
@@ -659,37 +645,41 @@
 		return - ENOMEM;
 
 	err = analog_init_port(gameport, drv, port);
-	if (err) {
-		kfree(port);
-		return err;
-	}
+	if (err)
+		goto fail1;
 
 	err = analog_init_masks(port);
-	if (err) {
-		gameport_close(gameport);
-		gameport_set_drvdata(gameport, NULL);
-		kfree(port);
-		return err;
-	}
+	if (err)
+		goto fail2;
 
 	gameport_set_poll_handler(gameport, analog_poll);
 	gameport_set_poll_interval(gameport, 10);
 
 	for (i = 0; i < 2; i++)
-		if (port->analog[i].mask)
-			analog_init_device(port, port->analog + i, i);
+		if (port->analog[i].mask) {
+			err = analog_init_device(port, port->analog + i, i);
+			if (err)
+				goto fail3;
+		}
 
 	return 0;
+
+ fail3: while (--i >= 0)
+		input_unregister_device(port->analog[i].dev);
+ fail2:	gameport_close(gameport);
+ fail1:	gameport_set_drvdata(gameport, NULL);
+	kfree(port);
+	return err;
 }
 
 static void analog_disconnect(struct gameport *gameport)
 {
-	int i;
 	struct analog_port *port = gameport_get_drvdata(gameport);
+	int i;
 
 	for (i = 0; i < 2; i++)
 		if (port->analog[i].mask)
-			input_unregister_device(&port->analog[i].dev);
+			input_unregister_device(port->analog[i].dev);
 	gameport_close(gameport);
 	gameport_set_drvdata(gameport, NULL);
 	printk(KERN_INFO "analog.c: %d out of %d reads (%d%%) on %s failed\n",
diff --git a/drivers/input/joystick/cobra.c b/drivers/input/joystick/cobra.c
index 0b2e9fa..9a3dfc7 100644
--- a/drivers/input/joystick/cobra.c
+++ b/drivers/input/joystick/cobra.c
@@ -44,13 +44,11 @@
 #define COBRA_MAX_STROBE	45	/* 45 us max wait for first strobe */
 #define COBRA_LENGTH		36
 
-static char* cobra_name = "Creative Labs Blaster GamePad Cobra";
-
 static int cobra_btn[] = { BTN_START, BTN_SELECT, BTN_TL, BTN_TR, BTN_X, BTN_Y, BTN_Z, BTN_A, BTN_B, BTN_C, BTN_TL2, BTN_TR2, 0 };
 
 struct cobra {
 	struct gameport *gameport;
-	struct input_dev dev[2];
+	struct input_dev *dev[2];
 	int reads;
 	int bads;
 	unsigned char exists;
@@ -128,7 +126,7 @@
 	for (i = 0; i < 2; i++)
 		if (cobra->exists & r & (1 << i)) {
 
-			dev = cobra->dev + i;
+			dev = cobra->dev[i];
 
 			input_report_abs(dev, ABS_X, ((data[i] >> 4) & 1) - ((data[i] >> 3) & 1));
 			input_report_abs(dev, ABS_Y, ((data[i] >> 2) & 1) - ((data[i] >> 1) & 1));
@@ -159,11 +157,13 @@
 static int cobra_connect(struct gameport *gameport, struct gameport_driver *drv)
 {
 	struct cobra *cobra;
+	struct input_dev *input_dev;
 	unsigned int data[2];
 	int i, j;
 	int err;
 
-	if (!(cobra = kzalloc(sizeof(struct cobra), GFP_KERNEL)))
+	cobra = kzalloc(sizeof(struct cobra), GFP_KERNEL);
+	if (!cobra)
 		return -ENOMEM;
 
 	cobra->gameport = gameport;
@@ -191,38 +191,46 @@
 	gameport_set_poll_handler(gameport, cobra_poll);
 	gameport_set_poll_interval(gameport, 20);
 
-	for (i = 0; i < 2; i++)
-		if ((cobra->exists >> i) & 1) {
+	for (i = 0; i < 2; i++) {
+		if (~(cobra->exists >> i) & 1)
+			continue;
 
-			sprintf(cobra->phys[i], "%s/input%d", gameport->phys, i);
-
-			cobra->dev[i].private = cobra;
-			cobra->dev[i].open = cobra_open;
-			cobra->dev[i].close = cobra_close;
-
-			cobra->dev[i].name = cobra_name;
-			cobra->dev[i].phys = cobra->phys[i];
-			cobra->dev[i].id.bustype = BUS_GAMEPORT;
-			cobra->dev[i].id.vendor = GAMEPORT_ID_VENDOR_CREATIVE;
-			cobra->dev[i].id.product = 0x0008;
-			cobra->dev[i].id.version = 0x0100;
-
-			cobra->dev[i].evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
-
-			input_set_abs_params(&cobra->dev[i], ABS_X, -1, 1, 0, 0);
-			input_set_abs_params(&cobra->dev[i], ABS_Y, -1, 1, 0, 0);
-
-			for (j = 0; cobra_btn[j]; j++)
-				set_bit(cobra_btn[j], cobra->dev[i].keybit);
-
-			input_register_device(&cobra->dev[i]);
-			printk(KERN_INFO "input: %s on %s\n", cobra_name, gameport->phys);
+		cobra->dev[i] = input_dev = input_allocate_device();
+		if (!input_dev) {
+			err = -ENOMEM;
+			goto fail3;
 		}
 
+		sprintf(cobra->phys[i], "%s/input%d", gameport->phys, i);
+
+		input_dev->name = "Creative Labs Blaster GamePad Cobra";
+		input_dev->phys = cobra->phys[i];
+		input_dev->id.bustype = BUS_GAMEPORT;
+		input_dev->id.vendor = GAMEPORT_ID_VENDOR_CREATIVE;
+		input_dev->id.product = 0x0008;
+		input_dev->id.version = 0x0100;
+		input_dev->cdev.dev = &gameport->dev;
+		input_dev->private = cobra;
+
+		input_dev->open = cobra_open;
+		input_dev->close = cobra_close;
+
+		input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
+		input_set_abs_params(input_dev, ABS_X, -1, 1, 0, 0);
+		input_set_abs_params(input_dev, ABS_Y, -1, 1, 0, 0);
+		for (j = 0; cobra_btn[j]; j++)
+			set_bit(cobra_btn[j], input_dev->keybit);
+
+		input_register_device(cobra->dev[i]);
+	}
+
 	return 0;
 
-fail2:	gameport_close(gameport);
-fail1:	gameport_set_drvdata(gameport, NULL);
+ fail3:	for (i = 0; i < 2; i++)
+		if (cobra->dev[i])
+			input_unregister_device(cobra->dev[i]);
+ fail2:	gameport_close(gameport);
+ fail1:	gameport_set_drvdata(gameport, NULL);
 	kfree(cobra);
 	return err;
 }
@@ -234,7 +242,7 @@
 
 	for (i = 0; i < 2; i++)
 		if ((cobra->exists >> i) & 1)
-			input_unregister_device(cobra->dev + i);
+			input_unregister_device(cobra->dev[i]);
 	gameport_close(gameport);
 	gameport_set_drvdata(gameport, NULL);
 	kfree(cobra);
diff --git a/drivers/input/joystick/db9.c b/drivers/input/joystick/db9.c
index 2a3e4bb2..499344c 100644
--- a/drivers/input/joystick/db9.c
+++ b/drivers/input/joystick/db9.c
@@ -43,25 +43,28 @@
 MODULE_DESCRIPTION("Atari, Amstrad, Commodore, Amiga, Sega, etc. joystick driver");
 MODULE_LICENSE("GPL");
 
-static int db9[] __initdata = { -1, 0 };
-static int db9_nargs __initdata = 0;
-module_param_array_named(dev, db9, int, &db9_nargs, 0);
+struct db9_config {
+	int args[2];
+	int nargs;
+};
+
+#define DB9_MAX_PORTS		3
+static struct db9_config db9[DB9_MAX_PORTS] __initdata;
+
+module_param_array_named(dev, db9[0].args, int, &db9[0].nargs, 0);
 MODULE_PARM_DESC(dev, "Describes first attached device (<parport#>,<type>)");
-
-static int db9_2[] __initdata = { -1, 0 };
-static int db9_nargs_2 __initdata = 0;
-module_param_array_named(dev2, db9_2, int, &db9_nargs_2, 0);
+module_param_array_named(dev2, db9[1].args, int, &db9[0].nargs, 0);
 MODULE_PARM_DESC(dev2, "Describes second attached device (<parport#>,<type>)");
-
-static int db9_3[] __initdata = { -1, 0 };
-static int db9_nargs_3 __initdata = 0;
-module_param_array_named(dev3, db9_3, int, &db9_nargs_3, 0);
+module_param_array_named(dev3, db9[2].args, int, &db9[2].nargs, 0);
 MODULE_PARM_DESC(dev3, "Describes third attached device (<parport#>,<type>)");
 
 __obsolete_setup("db9=");
 __obsolete_setup("db9_2=");
 __obsolete_setup("db9_3=");
 
+#define DB9_ARG_PARPORT		0
+#define DB9_ARG_MODE		1
+
 #define DB9_MULTI_STICK		0x01
 #define DB9_MULTI2_STICK	0x02
 #define DB9_GENESIS_PAD		0x03
@@ -87,40 +90,53 @@
 #define DB9_NORMAL		0x0a
 #define DB9_NOSELECT		0x08
 
-#define DB9_MAX_DEVICES		2
-
 #define DB9_GENESIS6_DELAY	14
 #define DB9_REFRESH_TIME	HZ/100
 
+#define DB9_MAX_DEVICES		2
+
+struct db9_mode_data {
+	const char *name;
+	const short *buttons;
+	int n_buttons;
+	int n_pads;
+	int n_axis;
+	int bidirectional;
+	int reverse;
+};
+
 struct db9 {
-	struct input_dev dev[DB9_MAX_DEVICES];
+	struct input_dev *dev[DB9_MAX_DEVICES];
 	struct timer_list timer;
 	struct pardevice *pd;
 	int mode;
 	int used;
 	struct semaphore sem;
-	char phys[2][32];
+	char phys[DB9_MAX_DEVICES][32];
 };
 
 static struct db9 *db9_base[3];
 
-static short db9_multi_btn[] = { BTN_TRIGGER, BTN_THUMB };
-static short db9_genesis_btn[] = { BTN_START, BTN_A, BTN_B, BTN_C, BTN_X, BTN_Y, BTN_Z, BTN_MODE };
-static short db9_cd32_btn[] = { BTN_A, BTN_B, BTN_C, BTN_X, BTN_Y, BTN_Z, BTN_TL, BTN_TR, BTN_START };
-
-static char db9_buttons[DB9_MAX_PAD] = { 0, 1, 2, 4, 0, 6, 8, 9, 1, 1, 7, 9, 9 };
-static short *db9_btn[DB9_MAX_PAD] = { NULL, db9_multi_btn, db9_multi_btn, db9_genesis_btn, NULL, db9_genesis_btn,
-					db9_genesis_btn, db9_cd32_btn, db9_multi_btn, db9_multi_btn, db9_cd32_btn,
-					db9_cd32_btn, db9_cd32_btn };
-static char *db9_name[DB9_MAX_PAD] = { NULL, "Multisystem joystick", "Multisystem joystick (2 fire)", "Genesis pad",
-				      NULL, "Genesis 5 pad", "Genesis 6 pad", "Saturn pad", "Multisystem (0.8.0.2) joystick",
-				     "Multisystem (0.8.0.2-dual) joystick", "Amiga CD-32 pad", "Saturn dpp", "Saturn dpp dual" };
-
-static const int db9_max_pads[DB9_MAX_PAD] = { 0, 1, 1, 1, 0, 1, 1, 6, 1, 2, 1, 6, 12 };
-static const int db9_num_axis[DB9_MAX_PAD] = { 0, 2, 2, 2, 0, 2, 2, 7, 2, 2, 2 ,7, 7 };
+static const short db9_multi_btn[] = { BTN_TRIGGER, BTN_THUMB };
+static const short db9_genesis_btn[] = { BTN_START, BTN_A, BTN_B, BTN_C, BTN_X, BTN_Y, BTN_Z, BTN_MODE };
+static const short db9_cd32_btn[] = { BTN_A, BTN_B, BTN_C, BTN_X, BTN_Y, BTN_Z, BTN_TL, BTN_TR, BTN_START };
 static const short db9_abs[] = { ABS_X, ABS_Y, ABS_RX, ABS_RY, ABS_RZ, ABS_Z, ABS_HAT0X, ABS_HAT0Y, ABS_HAT1X, ABS_HAT1Y };
-static const int db9_bidirectional[DB9_MAX_PAD] = { 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 0, 0 };
-static const int db9_reverse[DB9_MAX_PAD] = { 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 0 };
+
+static const struct db9_mode_data db9_modes[] = {
+	{ NULL,					 NULL,		  0,  0,  0,  0,  0 },
+	{ "Multisystem joystick",		 db9_multi_btn,	  1,  1,  2,  1,  1 },
+	{ "Multisystem joystick (2 fire)",	 db9_multi_btn,	  2,  1,  2,  1,  1 },
+	{ "Genesis pad",			 db9_genesis_btn, 4,  1,  2,  1,  1 },
+	{ NULL,					 NULL,		  0,  0,  0,  0,  0 },
+	{ "Genesis 5 pad",			 db9_genesis_btn, 6,  1,  2,  1,  1 },
+	{ "Genesis 6 pad",			 db9_genesis_btn, 8,  1,  2,  1,  1 },
+	{ "Saturn pad",				 db9_cd32_btn,	  9,  6,  7,  0,  1 },
+	{ "Multisystem (0.8.0.2) joystick",	 db9_multi_btn,	  1,  1,  2,  1,  1 },
+	{ "Multisystem (0.8.0.2-dual) joystick", db9_multi_btn,	  1,  2,  2,  1,  1 },
+	{ "Amiga CD-32 pad",			 db9_cd32_btn,	  7,  1,  2,  1,  1 },
+	{ "Saturn dpp",				 db9_cd32_btn,	  9,  6,  7,  0,  0 },
+	{ "Saturn dpp dual",			 db9_cd32_btn,	  9,  12, 7,  0,  0 },
+};
 
 /*
  * Saturn controllers
@@ -342,7 +358,7 @@
 	default:
 		return -1;
 	}
-	max_pads = min(db9_max_pads[mode], DB9_MAX_DEVICES);
+	max_pads = min(db9_modes[mode].n_pads, DB9_MAX_DEVICES);
 	for (tmp = 0, i = 0; i < n; i++) {
 		id = db9_saturn_read_packet(port, data, type + i, 1);
 		tmp = db9_saturn_report(id, data, dev, tmp, max_pads);
@@ -354,17 +370,18 @@
 {
 	struct db9 *db9 = (void *) private;
 	struct parport *port = db9->pd->port;
-	struct input_dev *dev = db9->dev;
+	struct input_dev *dev = db9->dev[0];
+	struct input_dev *dev2 = db9->dev[1];
 	int data, i;
 
-	switch(db9->mode) {
+	switch (db9->mode) {
 		case DB9_MULTI_0802_2:
 
 			data = parport_read_data(port) >> 3;
 
-			input_report_abs(dev + 1, ABS_X, (data & DB9_RIGHT ? 0 : 1) - (data & DB9_LEFT ? 0 : 1));
-			input_report_abs(dev + 1, ABS_Y, (data & DB9_DOWN  ? 0 : 1) - (data & DB9_UP   ? 0 : 1));
-			input_report_key(dev + 1, BTN_TRIGGER, ~data & DB9_FIRE1);
+			input_report_abs(dev2, ABS_X, (data & DB9_RIGHT ? 0 : 1) - (data & DB9_LEFT ? 0 : 1));
+			input_report_abs(dev2, ABS_Y, (data & DB9_DOWN  ? 0 : 1) - (data & DB9_UP   ? 0 : 1));
+			input_report_key(dev2, BTN_TRIGGER, ~data & DB9_FIRE1);
 
 		case DB9_MULTI_0802:
 
@@ -405,7 +422,7 @@
 			input_report_key(dev, BTN_C, ~data & DB9_FIRE2);
 
 			parport_write_control(port, DB9_NORMAL);
-			data=parport_read_data(port);
+			data = parport_read_data(port);
 
 			input_report_key(dev, BTN_A,     ~data & DB9_FIRE1);
 			input_report_key(dev, BTN_START, ~data & DB9_FIRE2);
@@ -414,7 +431,7 @@
 		case DB9_GENESIS5_PAD:
 
 			parport_write_control(port, DB9_NOSELECT);
-			data=parport_read_data(port);
+			data = parport_read_data(port);
 
 			input_report_abs(dev, ABS_X, (data & DB9_RIGHT ? 0 : 1) - (data & DB9_LEFT ? 0 : 1));
 			input_report_abs(dev, ABS_Y, (data & DB9_DOWN  ? 0 : 1) - (data & DB9_UP   ? 0 : 1));
@@ -422,7 +439,7 @@
 			input_report_key(dev, BTN_C, ~data & DB9_FIRE2);
 
 			parport_write_control(port, DB9_NORMAL);
-			data=parport_read_data(port);
+			data = parport_read_data(port);
 
 			input_report_key(dev, BTN_A,     ~data & DB9_FIRE1);
 			input_report_key(dev, BTN_X,     ~data & DB9_FIRE2);
@@ -434,7 +451,7 @@
 
 			parport_write_control(port, DB9_NOSELECT); /* 1 */
 			udelay(DB9_GENESIS6_DELAY);
-			data=parport_read_data(port);
+			data = parport_read_data(port);
 
 			input_report_abs(dev, ABS_X, (data & DB9_RIGHT ? 0 : 1) - (data & DB9_LEFT ? 0 : 1));
 			input_report_abs(dev, ABS_Y, (data & DB9_DOWN  ? 0 : 1) - (data & DB9_UP   ? 0 : 1));
@@ -443,7 +460,7 @@
 
 			parport_write_control(port, DB9_NORMAL);
 			udelay(DB9_GENESIS6_DELAY);
-			data=parport_read_data(port);
+			data = parport_read_data(port);
 
 			input_report_key(dev, BTN_A, ~data & DB9_FIRE1);
 			input_report_key(dev, BTN_START, ~data & DB9_FIRE2);
@@ -477,7 +494,7 @@
 
 		case DB9_CD32_PAD:
 
-			data=parport_read_data(port);
+			data = parport_read_data(port);
 
 			input_report_abs(dev, ABS_X, (data & DB9_RIGHT ? 0 : 1) - (data & DB9_LEFT ? 0 : 1));
 			input_report_abs(dev, ABS_Y, (data & DB9_DOWN  ? 0 : 1) - (data & DB9_UP   ? 0 : 1));
@@ -489,7 +506,7 @@
 				parport_write_control(port, 0x02);
 				parport_write_control(port, 0x0a);
 				input_report_key(dev, db9_cd32_btn[i], ~data & DB9_FIRE2);
-				}
+			}
 
 			parport_write_control(port, 0x00);
 			break;
@@ -513,7 +530,7 @@
 	if (!db9->used++) {
 		parport_claim(db9->pd);
 		parport_write_data(port, 0xff);
-		if (db9_reverse[db9->mode]) {
+		if (db9_modes[db9->mode].reverse) {
 			parport_data_reverse(port);
 			parport_write_control(port, DB9_NORMAL);
 		}
@@ -539,117 +556,160 @@
 	up(&db9->sem);
 }
 
-static struct db9 __init *db9_probe(int *config, int nargs)
+static struct db9 __init *db9_probe(int parport, int mode)
 {
 	struct db9 *db9;
+	const struct db9_mode_data *db9_mode;
 	struct parport *pp;
+	struct pardevice *pd;
+	struct input_dev *input_dev;
 	int i, j;
+	int err;
 
-	if (config[0] < 0)
-		return NULL;
-
-	if (nargs < 2) {
-		printk(KERN_ERR "db9.c: Device type must be specified.\n");
-		return NULL;
+	if (mode < 1 || mode >= DB9_MAX_PAD || !db9_modes[mode].n_buttons) {
+		printk(KERN_ERR "db9.c: Bad device type %d\n", mode);
+		err = -EINVAL;
+		goto err_out;
 	}
 
-	if (config[1] < 1 || config[1] >= DB9_MAX_PAD || !db9_buttons[config[1]]) {
-		printk(KERN_ERR "db9.c: bad config\n");
-		return NULL;
-	}
+	db9_mode = &db9_modes[mode];
 
-	pp = parport_find_number(config[0]);
+	pp = parport_find_number(parport);
 	if (!pp) {
 		printk(KERN_ERR "db9.c: no such parport\n");
-		return NULL;
+		err = -ENODEV;
+		goto err_out;
 	}
 
-	if (db9_bidirectional[config[1]]) {
-		if (!(pp->modes & PARPORT_MODE_TRISTATE)) {
-			printk(KERN_ERR "db9.c: specified parport is not bidirectional\n");
-			parport_put_port(pp);
-			return NULL;
-		}
+	if (db9_mode[mode].bidirectional && !(pp->modes & PARPORT_MODE_TRISTATE)) {
+		printk(KERN_ERR "db9.c: specified parport is not bidirectional\n");
+		err = -EINVAL;
+		goto err_put_pp;
 	}
 
-	if (!(db9 = kzalloc(sizeof(struct db9), GFP_KERNEL))) {
-		parport_put_port(pp);
-		return NULL;
+	pd = parport_register_device(pp, "db9", NULL, NULL, NULL, PARPORT_DEV_EXCL, NULL);
+	if (!pd) {
+		printk(KERN_ERR "db9.c: parport busy already - lp.o loaded?\n");
+		err = -EBUSY;
+		goto err_put_pp;
+	}
+
+	db9 = kzalloc(sizeof(struct db9), GFP_KERNEL);
+	if (!db9) {
+		printk(KERN_ERR "db9.c: Not enough memory\n");
+		err = -ENOMEM;
+		goto err_unreg_pardev;
 	}
 
 	init_MUTEX(&db9->sem);
-	db9->mode = config[1];
+	db9->pd = pd;
+	db9->mode = mode;
 	init_timer(&db9->timer);
 	db9->timer.data = (long) db9;
 	db9->timer.function = db9_timer;
 
-	db9->pd = parport_register_device(pp, "db9", NULL, NULL, NULL, PARPORT_DEV_EXCL, NULL);
-	parport_put_port(pp);
+	for (i = 0; i < (min(db9_mode->n_pads, DB9_MAX_DEVICES)); i++) {
 
-	if (!db9->pd) {
-		printk(KERN_ERR "db9.c: parport busy already - lp.o loaded?\n");
-		kfree(db9);
-		return NULL;
-	}
-
-	for (i = 0; i < (min(db9_max_pads[db9->mode], DB9_MAX_DEVICES)); i++) {
+		db9->dev[i] = input_dev = input_allocate_device();
+		if (!input_dev) {
+			printk(KERN_ERR "db9.c: Not enough memory for input device\n");
+			err = -ENOMEM;
+			goto err_free_devs;
+		}
 
 		sprintf(db9->phys[i], "%s/input%d", db9->pd->port->name, i);
 
-		db9->dev[i].private = db9;
-		db9->dev[i].open = db9_open;
-		db9->dev[i].close = db9_close;
+		input_dev->name = db9_mode->name;
+		input_dev->phys = db9->phys[i];
+		input_dev->id.bustype = BUS_PARPORT;
+		input_dev->id.vendor = 0x0002;
+		input_dev->id.product = mode;
+		input_dev->id.version = 0x0100;
+		input_dev->private = db9;
 
-		db9->dev[i].name = db9_name[db9->mode];
-		db9->dev[i].phys = db9->phys[i];
-		db9->dev[i].id.bustype = BUS_PARPORT;
-		db9->dev[i].id.vendor = 0x0002;
-		db9->dev[i].id.product = config[1];
-		db9->dev[i].id.version = 0x0100;
+		input_dev->open = db9_open;
+		input_dev->close = db9_close;
 
-		db9->dev[i].evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
-		for (j = 0; j < db9_buttons[db9->mode]; j++)
-			set_bit(db9_btn[db9->mode][j], db9->dev[i].keybit);
-		for (j = 0; j < db9_num_axis[db9->mode]; j++) {
-			set_bit(db9_abs[j], db9->dev[i].absbit);
-			if (j < 2) {
-				db9->dev[i].absmin[db9_abs[j]] = -1;
-				db9->dev[i].absmax[db9_abs[j]] = 1;
-			} else {
-				db9->dev[i].absmin[db9_abs[j]] = 1;
-				db9->dev[i].absmax[db9_abs[j]] = 255;
-				db9->dev[i].absflat[db9_abs[j]] = 0;
-			}
+		input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
+		for (j = 0; j < db9_mode->n_buttons; j++)
+			set_bit(db9_mode->buttons[j], input_dev->keybit);
+		for (j = 0; j < db9_mode->n_axis; j++) {
+			if (j < 2)
+				input_set_abs_params(input_dev, db9_abs[j], -1, 1, 0, 0);
+			else
+				input_set_abs_params(input_dev, db9_abs[j], 1, 255, 0, 0);
 		}
-		input_register_device(db9->dev + i);
-		printk(KERN_INFO "input: %s on %s\n", db9->dev[i].name, db9->pd->port->name);
+
+		input_register_device(input_dev);
 	}
 
+	parport_put_port(pp);
 	return db9;
+
+ err_free_devs:
+	while (--i >= 0)
+		input_unregister_device(db9->dev[i]);
+	kfree(db9);
+ err_unreg_pardev:
+	parport_unregister_device(pd);
+ err_put_pp:
+	parport_put_port(pp);
+ err_out:
+	return ERR_PTR(err);
+}
+
+static void __exit db9_remove(struct db9 *db9)
+{
+	int i;
+
+	for (i = 0; i < min(db9_modes[db9->mode].n_pads, DB9_MAX_DEVICES); i++)
+		input_unregister_device(db9->dev[i]);
+	parport_unregister_device(db9->pd);
+	kfree(db9);
 }
 
 static int __init db9_init(void)
 {
-	db9_base[0] = db9_probe(db9, db9_nargs);
-	db9_base[1] = db9_probe(db9_2, db9_nargs_2);
-	db9_base[2] = db9_probe(db9_3, db9_nargs_3);
+	int i;
+	int have_dev = 0;
+	int err = 0;
 
-	if (db9_base[0] || db9_base[1] || db9_base[2])
-		return 0;
+	for (i = 0; i < DB9_MAX_PORTS; i++) {
+		if (db9[i].nargs == 0 || db9[i].args[DB9_ARG_PARPORT] < 0)
+			continue;
 
-	return -ENODEV;
+		if (db9[i].nargs < 2) {
+			printk(KERN_ERR "db9.c: Device type must be specified.\n");
+			err = -EINVAL;
+			break;
+		}
+
+		db9_base[i] = db9_probe(db9[i].args[DB9_ARG_PARPORT],
+					db9[i].args[DB9_ARG_MODE]);
+		if (IS_ERR(db9_base[i])) {
+			err = PTR_ERR(db9_base[i]);
+			break;
+		}
+
+		have_dev = 1;
+	}
+
+	if (err) {
+		while (--i >= 0)
+			db9_remove(db9_base[i]);
+		return err;
+	}
+
+	return have_dev ? 0 : -ENODEV;
 }
 
 static void __exit db9_exit(void)
 {
-	int i, j;
+	int i;
 
-	for (i = 0; i < 3; i++)
-		if (db9_base[i]) {
-			for (j = 0; j < min(db9_max_pads[db9_base[i]->mode], DB9_MAX_DEVICES); j++)
-				input_unregister_device(db9_base[i]->dev + j);
-		parport_unregister_device(db9_base[i]->pd);
-	}
+	for (i = 0; i < DB9_MAX_PORTS; i++)
+		if (db9_base[i])
+			db9_remove(db9_base[i]);
 }
 
 module_init(db9_init);
diff --git a/drivers/input/joystick/gamecon.c b/drivers/input/joystick/gamecon.c
index 5427bf9..7df2d82 100644
--- a/drivers/input/joystick/gamecon.c
+++ b/drivers/input/joystick/gamecon.c
@@ -41,20 +41,22 @@
 MODULE_DESCRIPTION("NES, SNES, N64, MultiSystem, PSX gamepad driver");
 MODULE_LICENSE("GPL");
 
-static int gc[] __initdata = { -1, 0, 0, 0, 0, 0 };
-static int gc_nargs __initdata = 0;
-module_param_array_named(map, gc, int, &gc_nargs, 0);
-MODULE_PARM_DESC(map, "Describers first set of devices (<parport#>,<pad1>,<pad2>,..<pad5>)");
+#define GC_MAX_PORTS		3
+#define GC_MAX_DEVICES		5
 
-static int gc_2[] __initdata = { -1, 0, 0, 0, 0, 0 };
-static int gc_nargs_2 __initdata = 0;
-module_param_array_named(map2, gc_2, int, &gc_nargs_2, 0);
-MODULE_PARM_DESC(map2, "Describers second set of devices");
+struct gc_config {
+	int args[GC_MAX_DEVICES + 1];
+	int nargs;
+};
 
-static int gc_3[] __initdata = { -1, 0, 0, 0, 0, 0 };
-static int gc_nargs_3 __initdata = 0;
-module_param_array_named(map3, gc_3, int, &gc_nargs_3, 0);
-MODULE_PARM_DESC(map3, "Describers third set of devices");
+static struct gc_config gc[GC_MAX_PORTS] __initdata;
+
+module_param_array_named(map, gc[0].args, int, &gc[0].nargs, 0);
+MODULE_PARM_DESC(map, "Describes first set of devices (<parport#>,<pad1>,<pad2>,..<pad5>)");
+module_param_array_named(map2, gc[1].args, int, &gc[1].nargs, 0);
+MODULE_PARM_DESC(map2, "Describes second set of devices");
+module_param_array_named(map3, gc[2].args, int, &gc[2].nargs, 0);
+MODULE_PARM_DESC(map3, "Describes third set of devices");
 
 __obsolete_setup("gc=");
 __obsolete_setup("gc_2=");
@@ -77,12 +79,12 @@
 
 struct gc {
 	struct pardevice *pd;
-	struct input_dev dev[5];
+	struct input_dev *dev[GC_MAX_DEVICES];
 	struct timer_list timer;
 	unsigned char pads[GC_MAX + 1];
 	int used;
 	struct semaphore sem;
-	char phys[5][32];
+	char phys[GC_MAX_DEVICES][32];
 };
 
 static struct gc *gc_base[3];
@@ -330,7 +332,6 @@
 static void gc_timer(unsigned long private)
 {
 	struct gc *gc = (void *) private;
-	struct input_dev *dev = gc->dev;
 	unsigned char data[GC_MAX_LENGTH];
 	unsigned char data_psx[5][GC_PSX_BYTES];
 	int i, j, s;
@@ -357,16 +358,16 @@
 					if (data[31 - j] & s) axes[1] |= 1 << j;
 				}
 
-				input_report_abs(dev + i, ABS_X,  axes[0]);
-				input_report_abs(dev + i, ABS_Y, -axes[1]);
+				input_report_abs(gc->dev[i], ABS_X,  axes[0]);
+				input_report_abs(gc->dev[i], ABS_Y, -axes[1]);
 
-				input_report_abs(dev + i, ABS_HAT0X, !(s & data[6]) - !(s & data[7]));
-				input_report_abs(dev + i, ABS_HAT0Y, !(s & data[4]) - !(s & data[5]));
+				input_report_abs(gc->dev[i], ABS_HAT0X, !(s & data[6]) - !(s & data[7]));
+				input_report_abs(gc->dev[i], ABS_HAT0Y, !(s & data[4]) - !(s & data[5]));
 
 				for (j = 0; j < 10; j++)
-					input_report_key(dev + i, gc_n64_btn[j], s & data[gc_n64_bytes[j]]);
+					input_report_key(gc->dev[i], gc_n64_btn[j], s & data[gc_n64_bytes[j]]);
 
-				input_sync(dev + i);
+				input_sync(gc->dev[i]);
 			}
 		}
 	}
@@ -384,19 +385,19 @@
 			s = gc_status_bit[i];
 
 			if (s & (gc->pads[GC_NES] | gc->pads[GC_SNES])) {
-				input_report_abs(dev + i, ABS_X, !(s & data[6]) - !(s & data[7]));
-				input_report_abs(dev + i, ABS_Y, !(s & data[4]) - !(s & data[5]));
+				input_report_abs(gc->dev[i], ABS_X, !(s & data[6]) - !(s & data[7]));
+				input_report_abs(gc->dev[i], ABS_Y, !(s & data[4]) - !(s & data[5]));
 			}
 
 			if (s & gc->pads[GC_NES])
 				for (j = 0; j < 4; j++)
-					input_report_key(dev + i, gc_snes_btn[j], s & data[gc_nes_bytes[j]]);
+					input_report_key(gc->dev[i], gc_snes_btn[j], s & data[gc_nes_bytes[j]]);
 
 			if (s & gc->pads[GC_SNES])
 				for (j = 0; j < 8; j++)
-					input_report_key(dev + i, gc_snes_btn[j], s & data[gc_snes_bytes[j]]);
+					input_report_key(gc->dev[i], gc_snes_btn[j], s & data[gc_snes_bytes[j]]);
 
-			input_sync(dev + i);
+			input_sync(gc->dev[i]);
 		}
 	}
 
@@ -413,15 +414,15 @@
 			s = gc_status_bit[i];
 
 			if (s & (gc->pads[GC_MULTI] | gc->pads[GC_MULTI2])) {
-				input_report_abs(dev + i, ABS_X,  !(s & data[2]) - !(s & data[3]));
-				input_report_abs(dev + i, ABS_Y,  !(s & data[0]) - !(s & data[1]));
-				input_report_key(dev + i, BTN_TRIGGER, s & data[4]);
+				input_report_abs(gc->dev[i], ABS_X,  !(s & data[2]) - !(s & data[3]));
+				input_report_abs(gc->dev[i], ABS_Y,  !(s & data[0]) - !(s & data[1]));
+				input_report_key(gc->dev[i], BTN_TRIGGER, s & data[4]);
 			}
 
 			if (s & gc->pads[GC_MULTI2])
-				input_report_key(dev + i, BTN_THUMB, s & data[5]);
+				input_report_key(gc->dev[i], BTN_THUMB, s & data[5]);
 
-			input_sync(dev + i);
+			input_sync(gc->dev[i]);
 		}
 	}
 
@@ -438,44 +439,44 @@
 
 				case GC_PSX_RUMBLE:
 
-					input_report_key(dev + i, BTN_THUMBL, ~data_psx[i][0] & 0x04);
-					input_report_key(dev + i, BTN_THUMBR, ~data_psx[i][0] & 0x02);
+					input_report_key(gc->dev[i], BTN_THUMBL, ~data_psx[i][0] & 0x04);
+					input_report_key(gc->dev[i], BTN_THUMBR, ~data_psx[i][0] & 0x02);
 
 				case GC_PSX_NEGCON:
 				case GC_PSX_ANALOG:
 
-					if(gc->pads[GC_DDR] & gc_status_bit[i]) {
+					if (gc->pads[GC_DDR] & gc_status_bit[i]) {
 						for(j = 0; j < 4; j++)
-							input_report_key(dev + i, gc_psx_ddr_btn[j], ~data_psx[i][0] & (0x10 << j));
+							input_report_key(gc->dev[i], gc_psx_ddr_btn[j], ~data_psx[i][0] & (0x10 << j));
 					} else {
 						for (j = 0; j < 4; j++)
-							input_report_abs(dev + i, gc_psx_abs[j+2], data_psx[i][j + 2]);
+							input_report_abs(gc->dev[i], gc_psx_abs[j+2], data_psx[i][j + 2]);
 
-						input_report_abs(dev + i, ABS_X, 128 + !(data_psx[i][0] & 0x20) * 127 - !(data_psx[i][0] & 0x80) * 128);
-						input_report_abs(dev + i, ABS_Y, 128 + !(data_psx[i][0] & 0x40) * 127 - !(data_psx[i][0] & 0x10) * 128);
+						input_report_abs(gc->dev[i], ABS_X, 128 + !(data_psx[i][0] & 0x20) * 127 - !(data_psx[i][0] & 0x80) * 128);
+						input_report_abs(gc->dev[i], ABS_Y, 128 + !(data_psx[i][0] & 0x40) * 127 - !(data_psx[i][0] & 0x10) * 128);
 					}
 
 					for (j = 0; j < 8; j++)
-						input_report_key(dev + i, gc_psx_btn[j], ~data_psx[i][1] & (1 << j));
+						input_report_key(gc->dev[i], gc_psx_btn[j], ~data_psx[i][1] & (1 << j));
 
-					input_report_key(dev + i, BTN_START,  ~data_psx[i][0] & 0x08);
-					input_report_key(dev + i, BTN_SELECT, ~data_psx[i][0] & 0x01);
+					input_report_key(gc->dev[i], BTN_START,  ~data_psx[i][0] & 0x08);
+					input_report_key(gc->dev[i], BTN_SELECT, ~data_psx[i][0] & 0x01);
 
-					input_sync(dev + i);
+					input_sync(gc->dev[i]);
 
 					break;
 
 				case GC_PSX_NORMAL:
-					if(gc->pads[GC_DDR] & gc_status_bit[i]) {
+					if (gc->pads[GC_DDR] & gc_status_bit[i]) {
 						for(j = 0; j < 4; j++)
-							input_report_key(dev + i, gc_psx_ddr_btn[j], ~data_psx[i][0] & (0x10 << j));
+							input_report_key(gc->dev[i], gc_psx_ddr_btn[j], ~data_psx[i][0] & (0x10 << j));
 					} else {
-						input_report_abs(dev + i, ABS_X, 128 + !(data_psx[i][0] & 0x20) * 127 - !(data_psx[i][0] & 0x80) * 128);
-						input_report_abs(dev + i, ABS_Y, 128 + !(data_psx[i][0] & 0x40) * 127 - !(data_psx[i][0] & 0x10) * 128);
+						input_report_abs(gc->dev[i], ABS_X, 128 + !(data_psx[i][0] & 0x20) * 127 - !(data_psx[i][0] & 0x80) * 128);
+						input_report_abs(gc->dev[i], ABS_Y, 128 + !(data_psx[i][0] & 0x40) * 127 - !(data_psx[i][0] & 0x10) * 128);
 
 						/* for some reason if the extra axes are left unset they drift */
 						/* for (j = 0; j < 4; j++)
-							input_report_abs(dev + i, gc_psx_abs[j+2], 128);
+							input_report_abs(gc->dev[i], gc_psx_abs[j+2], 128);
 						 * This needs to be debugged properly,
 						 * maybe fuzz processing needs to be done in input_sync()
 						 *				 --vojtech
@@ -483,12 +484,12 @@
 					}
 
 					for (j = 0; j < 8; j++)
-						input_report_key(dev + i, gc_psx_btn[j], ~data_psx[i][1] & (1 << j));
+						input_report_key(gc->dev[i], gc_psx_btn[j], ~data_psx[i][1] & (1 << j));
 
-					input_report_key(dev + i, BTN_START,  ~data_psx[i][0] & 0x08);
-					input_report_key(dev + i, BTN_SELECT, ~data_psx[i][0] & 0x01);
+					input_report_key(gc->dev[i], BTN_START,  ~data_psx[i][0] & 0x08);
+					input_report_key(gc->dev[i], BTN_SELECT, ~data_psx[i][0] & 0x01);
 
-					input_sync(dev + i);
+					input_sync(gc->dev[i]);
 
 					break;
 
@@ -533,177 +534,212 @@
 	up(&gc->sem);
 }
 
-static struct gc __init *gc_probe(int *config, int nargs)
+static int __init gc_setup_pad(struct gc *gc, int idx, int pad_type)
+{
+	struct input_dev *input_dev;
+	int i;
+
+	if (!pad_type)
+		return 0;
+
+	if (pad_type < 1 || pad_type > GC_MAX) {
+		printk(KERN_WARNING "gamecon.c: Pad type %d unknown\n", pad_type);
+		return -EINVAL;
+	}
+
+	gc->dev[idx] = input_dev = input_allocate_device();
+	if (!input_dev) {
+		printk(KERN_ERR "gamecon.c: Not enough memory for input device\n");
+		return -ENOMEM;
+	}
+
+	input_dev->name = gc_names[pad_type];
+	input_dev->phys = gc->phys[idx];
+	input_dev->id.bustype = BUS_PARPORT;
+	input_dev->id.vendor = 0x0001;
+	input_dev->id.product = pad_type;
+	input_dev->id.version = 0x0100;
+	input_dev->private = gc;
+
+	input_dev->open = gc_open;
+	input_dev->close = gc_close;
+
+	input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
+
+	for (i = 0; i < 2; i++)
+		input_set_abs_params(input_dev, ABS_X + i, -1, 1, 0, 0);
+
+	gc->pads[0] |= gc_status_bit[idx];
+	gc->pads[pad_type] |= gc_status_bit[idx];
+
+	switch (pad_type) {
+
+		case GC_N64:
+			for (i = 0; i < 10; i++)
+				set_bit(gc_n64_btn[i], input_dev->keybit);
+
+			for (i = 0; i < 2; i++) {
+				input_set_abs_params(input_dev, ABS_X + i, -127, 126, 0, 2);
+				input_set_abs_params(input_dev, ABS_HAT0X + i, -1, 1, 0, 0);
+			}
+
+			break;
+
+		case GC_SNES:
+			for (i = 4; i < 8; i++)
+				set_bit(gc_snes_btn[i], input_dev->keybit);
+		case GC_NES:
+			for (i = 0; i < 4; i++)
+				set_bit(gc_snes_btn[i], input_dev->keybit);
+			break;
+
+		case GC_MULTI2:
+			set_bit(BTN_THUMB, input_dev->keybit);
+		case GC_MULTI:
+			set_bit(BTN_TRIGGER, input_dev->keybit);
+			break;
+
+		case GC_PSX:
+			for (i = 0; i < 6; i++)
+				input_set_abs_params(input_dev, gc_psx_abs[i], 4, 252, 0, 2);
+			for (i = 0; i < 12; i++)
+				set_bit(gc_psx_btn[i], input_dev->keybit);
+
+			break;
+
+		case GC_DDR:
+			for (i = 0; i < 4; i++)
+				set_bit(gc_psx_ddr_btn[i], input_dev->keybit);
+			for (i = 0; i < 12; i++)
+				set_bit(gc_psx_btn[i], input_dev->keybit);
+
+			break;
+	}
+
+	return 0;
+}
+
+static struct gc __init *gc_probe(int parport, int *pads, int n_pads)
 {
 	struct gc *gc;
 	struct parport *pp;
-	int i, j;
+	struct pardevice *pd;
+	int i;
+	int err;
 
-	if (config[0] < 0)
-		return NULL;
-
-	if (nargs < 2) {
-		printk(KERN_ERR "gamecon.c: at least one device must be specified\n");
-		return NULL;
-	}
-
-	pp = parport_find_number(config[0]);
-
+	pp = parport_find_number(parport);
 	if (!pp) {
 		printk(KERN_ERR "gamecon.c: no such parport\n");
-		return NULL;
+		err = -EINVAL;
+		goto err_out;
 	}
 
-	if (!(gc = kzalloc(sizeof(struct gc), GFP_KERNEL))) {
-		parport_put_port(pp);
-		return NULL;
+	pd = parport_register_device(pp, "gamecon", NULL, NULL, NULL, PARPORT_DEV_EXCL, NULL);
+	if (!pd) {
+		printk(KERN_ERR "gamecon.c: parport busy already - lp.o loaded?\n");
+		err = -EBUSY;
+		goto err_put_pp;
+	}
+
+	gc = kzalloc(sizeof(struct gc), GFP_KERNEL);
+	if (!gc) {
+		printk(KERN_ERR "gamecon.c: Not enough memory\n");
+		err = -ENOMEM;
+		goto err_unreg_pardev;
 	}
 
 	init_MUTEX(&gc->sem);
-
-	gc->pd = parport_register_device(pp, "gamecon", NULL, NULL, NULL, PARPORT_DEV_EXCL, NULL);
-
-	parport_put_port(pp);
-
-	if (!gc->pd) {
-		printk(KERN_ERR "gamecon.c: parport busy already - lp.o loaded?\n");
-		kfree(gc);
-		return NULL;
-	}
-
-	parport_claim(gc->pd);
-
+	gc->pd = pd;
 	init_timer(&gc->timer);
 	gc->timer.data = (long) gc;
 	gc->timer.function = gc_timer;
 
-	for (i = 0; i < nargs - 1; i++) {
-
-		if (!config[i + 1])
+	for (i = 0; i < n_pads; i++) {
+		if (!pads[i])
 			continue;
 
-		if (config[i + 1] < 1 || config[i + 1] > GC_MAX) {
-			printk(KERN_WARNING "gamecon.c: Pad type %d unknown\n", config[i + 1]);
-			continue;
-		}
-
-                gc->dev[i].private = gc;
-                gc->dev[i].open = gc_open;
-                gc->dev[i].close = gc_close;
-
-                gc->dev[i].evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
-
-		for (j = 0; j < 2; j++) {
-			set_bit(ABS_X + j, gc->dev[i].absbit);
-			gc->dev[i].absmin[ABS_X + j] = -1;
-			gc->dev[i].absmax[ABS_X + j] =  1;
-		}
-
-		gc->pads[0] |= gc_status_bit[i];
-		gc->pads[config[i + 1]] |= gc_status_bit[i];
-
-		switch(config[i + 1]) {
-
-			case GC_N64:
-				for (j = 0; j < 10; j++)
-					set_bit(gc_n64_btn[j], gc->dev[i].keybit);
-
-				for (j = 0; j < 2; j++) {
-					set_bit(ABS_X + j, gc->dev[i].absbit);
-					gc->dev[i].absmin[ABS_X + j] = -127;
-					gc->dev[i].absmax[ABS_X + j] =  126;
-					gc->dev[i].absflat[ABS_X + j] = 2;
-					set_bit(ABS_HAT0X + j, gc->dev[i].absbit);
-					gc->dev[i].absmin[ABS_HAT0X + j] = -1;
-					gc->dev[i].absmax[ABS_HAT0X + j] =  1;
-				}
-
-				break;
-
-			case GC_SNES:
-				for (j = 4; j < 8; j++)
-					set_bit(gc_snes_btn[j], gc->dev[i].keybit);
-			case GC_NES:
-				for (j = 0; j < 4; j++)
-					set_bit(gc_snes_btn[j], gc->dev[i].keybit);
-				break;
-
-			case GC_MULTI2:
-				set_bit(BTN_THUMB, gc->dev[i].keybit);
-			case GC_MULTI:
-				set_bit(BTN_TRIGGER, gc->dev[i].keybit);
-				break;
-
-			case GC_PSX:
-			case GC_DDR:
-				if(config[i + 1] == GC_DDR) {
-					for (j = 0; j < 4; j++)
-						set_bit(gc_psx_ddr_btn[j], gc->dev[i].keybit);
-				} else {
-					for (j = 0; j < 6; j++) {
-						set_bit(gc_psx_abs[j], gc->dev[i].absbit);
-						gc->dev[i].absmin[gc_psx_abs[j]] = 4;
-						gc->dev[i].absmax[gc_psx_abs[j]] = 252;
-						gc->dev[i].absflat[gc_psx_abs[j]] = 2;
-					}
-				}
-
-				for (j = 0; j < 12; j++)
-					set_bit(gc_psx_btn[j], gc->dev[i].keybit);
-
-				break;
-		}
-
 		sprintf(gc->phys[i], "%s/input%d", gc->pd->port->name, i);
+		err = gc_setup_pad(gc, i, pads[i]);
+		if (err)
+			goto err_free_devs;
 
-                gc->dev[i].name = gc_names[config[i + 1]];
-		gc->dev[i].phys = gc->phys[i];
-                gc->dev[i].id.bustype = BUS_PARPORT;
-                gc->dev[i].id.vendor = 0x0001;
-                gc->dev[i].id.product = config[i + 1];
-                gc->dev[i].id.version = 0x0100;
+		input_register_device(gc->dev[i]);
 	}
 
-	parport_release(gc->pd);
-
 	if (!gc->pads[0]) {
-		parport_unregister_device(gc->pd);
-		kfree(gc);
-		return NULL;
+		printk(KERN_ERR "gamecon.c: No valid devices specified\n");
+		err = -EINVAL;
+		goto err_free_gc;
 	}
 
-	for (i = 0; i < 5; i++)
-		if (gc->pads[0] & gc_status_bit[i]) {
-			input_register_device(gc->dev + i);
-			printk(KERN_INFO "input: %s on %s\n", gc->dev[i].name, gc->pd->port->name);
-		}
-
+	parport_put_port(pp);
 	return gc;
+
+ err_free_devs:
+	while (--i >= 0)
+		input_unregister_device(gc->dev[i]);
+ err_free_gc:
+	kfree(gc);
+ err_unreg_pardev:
+	parport_unregister_device(pd);
+ err_put_pp:
+	parport_put_port(pp);
+ err_out:
+	return ERR_PTR(err);
+}
+
+static void __exit gc_remove(struct gc *gc)
+{
+	int i;
+
+	for (i = 0; i < GC_MAX_DEVICES; i++)
+		if (gc->dev[i])
+			input_unregister_device(gc->dev[i]);
+	parport_unregister_device(gc->pd);
+	kfree(gc);
 }
 
 static int __init gc_init(void)
 {
-	gc_base[0] = gc_probe(gc, gc_nargs);
-	gc_base[1] = gc_probe(gc_2, gc_nargs_2);
-	gc_base[2] = gc_probe(gc_3, gc_nargs_3);
+	int i;
+	int have_dev = 0;
+	int err = 0;
 
-	if (gc_base[0] || gc_base[1] || gc_base[2])
-		return 0;
+	for (i = 0; i < GC_MAX_PORTS; i++) {
+		if (gc[i].nargs == 0 || gc[i].args[0] < 0)
+			continue;
 
-	return -ENODEV;
+		if (gc[i].nargs < 2) {
+			printk(KERN_ERR "gamecon.c: at least one device must be specified\n");
+			err = -EINVAL;
+			break;
+		}
+
+		gc_base[i] = gc_probe(gc[i].args[0], gc[i].args + 1, gc[i].nargs - 1);
+		if (IS_ERR(gc_base[i])) {
+			err = PTR_ERR(gc_base[i]);
+			break;
+		}
+
+		have_dev = 1;
+	}
+
+	if (err) {
+		while (--i >= 0)
+			gc_remove(gc_base[i]);
+		return err;
+	}
+
+	return have_dev ? 0 : -ENODEV;
 }
 
 static void __exit gc_exit(void)
 {
-	int i, j;
+	int i;
 
-	for (i = 0; i < 3; i++)
-		if (gc_base[i]) {
-			for (j = 0; j < 5; j++)
-				if (gc_base[i]->pads[0] & gc_status_bit[j])
-					input_unregister_device(gc_base[i]->dev + j);
-			parport_unregister_device(gc_base[i]->pd);
-		}
+	for (i = 0; i < GC_MAX_PORTS; i++)
+		if (gc_base[i])
+			gc_remove(gc_base[i]);
 }
 
 module_init(gc_init);
diff --git a/drivers/input/joystick/gf2k.c b/drivers/input/joystick/gf2k.c
index 8e4f92b..e151f8c 100644
--- a/drivers/input/joystick/gf2k.c
+++ b/drivers/input/joystick/gf2k.c
@@ -81,7 +81,7 @@
 
 struct gf2k {
 	struct gameport *gameport;
-	struct input_dev dev;
+	struct input_dev *dev;
 	int reads;
 	int bads;
 	unsigned char id;
@@ -175,7 +175,7 @@
 
 static void gf2k_read(struct gf2k *gf2k, unsigned char *data)
 {
-	struct input_dev *dev = &gf2k->dev;
+	struct input_dev *dev = gf2k->dev;
 	int i, t;
 
 	for (i = 0; i < 4 && i < gf2k_axes[gf2k->id]; i++)
@@ -239,13 +239,19 @@
 static int gf2k_connect(struct gameport *gameport, struct gameport_driver *drv)
 {
 	struct gf2k *gf2k;
+	struct input_dev *input_dev;
 	unsigned char data[GF2K_LENGTH];
 	int i, err;
 
-	if (!(gf2k = kzalloc(sizeof(struct gf2k), GFP_KERNEL)))
-		return -ENOMEM;
+	gf2k = kzalloc(sizeof(struct gf2k), GFP_KERNEL);
+	input_dev = input_allocate_device();
+	if (!gf2k || !input_dev) {
+		err = -ENOMEM;
+		goto fail1;
+	}
 
 	gf2k->gameport = gameport;
+	gf2k->dev = input_dev;
 
 	gameport_set_drvdata(gameport, gf2k);
 
@@ -295,53 +301,52 @@
 
 	gf2k->length = gf2k_lens[gf2k->id];
 
-	init_input_dev(&gf2k->dev);
+	input_dev->name = gf2k_names[gf2k->id];
+	input_dev->phys = gf2k->phys;
+	input_dev->id.bustype = BUS_GAMEPORT;
+	input_dev->id.vendor = GAMEPORT_ID_VENDOR_GENIUS;
+	input_dev->id.product = gf2k->id;
+	input_dev->id.version = 0x0100;
+	input_dev->cdev.dev = &gameport->dev;
+	input_dev->private = gf2k;
 
-	gf2k->dev.private = gf2k;
-	gf2k->dev.open = gf2k_open;
-	gf2k->dev.close = gf2k_close;
-	gf2k->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
-
-	gf2k->dev.name = gf2k_names[gf2k->id];
-	gf2k->dev.phys = gf2k->phys;
-	gf2k->dev.id.bustype = BUS_GAMEPORT;
-	gf2k->dev.id.vendor = GAMEPORT_ID_VENDOR_GENIUS;
-	gf2k->dev.id.product = gf2k->id;
-	gf2k->dev.id.version = 0x0100;
+	input_dev->open = gf2k_open;
+	input_dev->close = gf2k_close;
+	input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
 
 	for (i = 0; i < gf2k_axes[gf2k->id]; i++)
-		set_bit(gf2k_abs[i], gf2k->dev.absbit);
+		set_bit(gf2k_abs[i], input_dev->absbit);
 
 	for (i = 0; i < gf2k_hats[gf2k->id]; i++) {
-		set_bit(ABS_HAT0X + i, gf2k->dev.absbit);
-		gf2k->dev.absmin[ABS_HAT0X + i] = -1;
-		gf2k->dev.absmax[ABS_HAT0X + i] = 1;
+		set_bit(ABS_HAT0X + i, input_dev->absbit);
+		input_dev->absmin[ABS_HAT0X + i] = -1;
+		input_dev->absmax[ABS_HAT0X + i] = 1;
 	}
 
 	for (i = 0; i < gf2k_joys[gf2k->id]; i++)
-		set_bit(gf2k_btn_joy[i], gf2k->dev.keybit);
+		set_bit(gf2k_btn_joy[i], input_dev->keybit);
 
 	for (i = 0; i < gf2k_pads[gf2k->id]; i++)
-		set_bit(gf2k_btn_pad[i], gf2k->dev.keybit);
+		set_bit(gf2k_btn_pad[i], input_dev->keybit);
 
 	gf2k_read_packet(gameport, gf2k->length, data);
 	gf2k_read(gf2k, data);
 
 	for (i = 0; i < gf2k_axes[gf2k->id]; i++) {
-		gf2k->dev.absmax[gf2k_abs[i]] = (i < 2) ? gf2k->dev.abs[gf2k_abs[i]] * 2 - 32 :
-			  gf2k->dev.abs[gf2k_abs[0]] + gf2k->dev.abs[gf2k_abs[1]] - 32;
-		gf2k->dev.absmin[gf2k_abs[i]] = 32;
-		gf2k->dev.absfuzz[gf2k_abs[i]] = 8;
-		gf2k->dev.absflat[gf2k_abs[i]] = (i < 2) ? 24 : 0;
+		input_dev->absmax[gf2k_abs[i]] = (i < 2) ? input_dev->abs[gf2k_abs[i]] * 2 - 32 :
+			  input_dev->abs[gf2k_abs[0]] + input_dev->abs[gf2k_abs[1]] - 32;
+		input_dev->absmin[gf2k_abs[i]] = 32;
+		input_dev->absfuzz[gf2k_abs[i]] = 8;
+		input_dev->absflat[gf2k_abs[i]] = (i < 2) ? 24 : 0;
 	}
 
-	input_register_device(&gf2k->dev);
-	printk(KERN_INFO "input: %s on %s\n", gf2k_names[gf2k->id], gameport->phys);
+	input_register_device(gf2k->dev);
 
 	return 0;
 
-fail2:	gameport_close(gameport);
-fail1:	gameport_set_drvdata(gameport, NULL);
+ fail2:	gameport_close(gameport);
+ fail1:	gameport_set_drvdata(gameport, NULL);
+	input_free_device(input_dev);
 	kfree(gf2k);
 	return err;
 }
@@ -350,7 +355,7 @@
 {
 	struct gf2k *gf2k = gameport_get_drvdata(gameport);
 
-	input_unregister_device(&gf2k->dev);
+	input_unregister_device(gf2k->dev);
 	gameport_close(gameport);
 	gameport_set_drvdata(gameport, NULL);
 	kfree(gf2k);
diff --git a/drivers/input/joystick/grip.c b/drivers/input/joystick/grip.c
index 9d3f910..e206bb5 100644
--- a/drivers/input/joystick/grip.c
+++ b/drivers/input/joystick/grip.c
@@ -55,7 +55,7 @@
 
 struct grip {
 	struct gameport *gameport;
-	struct input_dev dev[2];
+	struct input_dev *dev[2];
 	unsigned char mode[2];
 	int reads;
 	int bads;
@@ -190,7 +190,7 @@
 
 	for (i = 0; i < 2; i++) {
 
-		dev = grip->dev + i;
+		dev = grip->dev[i];
 		grip->reads++;
 
 		switch (grip->mode[i]) {
@@ -297,6 +297,7 @@
 static int grip_connect(struct gameport *gameport, struct gameport_driver *drv)
 {
 	struct grip *grip;
+	struct input_dev *input_dev;
 	unsigned int data[GRIP_LENGTH_XT];
 	int i, j, t;
 	int err;
@@ -339,48 +340,56 @@
 	gameport_set_poll_handler(gameport, grip_poll);
 	gameport_set_poll_interval(gameport, 20);
 
-	for (i = 0; i < 2; i++)
-		if (grip->mode[i]) {
+	for (i = 0; i < 2; i++) {
+		if (!grip->mode[i])
+			continue;
 
-			sprintf(grip->phys[i], "%s/input%d", gameport->phys, i);
-
-			grip->dev[i].private = grip;
-
-			grip->dev[i].open = grip_open;
-			grip->dev[i].close = grip_close;
-
-			grip->dev[i].name = grip_name[grip->mode[i]];
-			grip->dev[i].phys = grip->phys[i];
-			grip->dev[i].id.bustype = BUS_GAMEPORT;
-			grip->dev[i].id.vendor = GAMEPORT_ID_VENDOR_GRAVIS;
-			grip->dev[i].id.product = grip->mode[i];
-			grip->dev[i].id.version = 0x0100;
-
-			grip->dev[i].evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
-
-			for (j = 0; (t = grip_abs[grip->mode[i]][j]) >= 0; j++) {
-
-				if (j < grip_cen[grip->mode[i]])
-					input_set_abs_params(&grip->dev[i], t, 14, 52, 1, 2);
-				else if (j < grip_anx[grip->mode[i]])
-					input_set_abs_params(&grip->dev[i], t, 3, 57, 1, 0);
-				else
-					input_set_abs_params(&grip->dev[i], t, -1, 1, 0, 0);
-			}
-
-			for (j = 0; (t = grip_btn[grip->mode[i]][j]) >= 0; j++)
-				if (t > 0)
-					set_bit(t, grip->dev[i].keybit);
-
-			printk(KERN_INFO "input: %s on %s\n",
-				grip_name[grip->mode[i]], gameport->phys);
-			input_register_device(grip->dev + i);
+		grip->dev[i] = input_dev = input_allocate_device();
+		if (!input_dev) {
+			err = -ENOMEM;
+			goto fail3;
 		}
 
+		sprintf(grip->phys[i], "%s/input%d", gameport->phys, i);
+
+		input_dev->name = grip_name[grip->mode[i]];
+		input_dev->phys = grip->phys[i];
+		input_dev->id.bustype = BUS_GAMEPORT;
+		input_dev->id.vendor = GAMEPORT_ID_VENDOR_GRAVIS;
+		input_dev->id.product = grip->mode[i];
+		input_dev->id.version = 0x0100;
+		input_dev->cdev.dev = &gameport->dev;
+		input_dev->private = grip;
+
+		input_dev->open = grip_open;
+		input_dev->close = grip_close;
+
+		input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
+
+		for (j = 0; (t = grip_abs[grip->mode[i]][j]) >= 0; j++) {
+
+			if (j < grip_cen[grip->mode[i]])
+				input_set_abs_params(input_dev, t, 14, 52, 1, 2);
+			else if (j < grip_anx[grip->mode[i]])
+				input_set_abs_params(input_dev, t, 3, 57, 1, 0);
+			else
+				input_set_abs_params(input_dev, t, -1, 1, 0, 0);
+		}
+
+		for (j = 0; (t = grip_btn[grip->mode[i]][j]) >= 0; j++)
+			if (t > 0)
+				set_bit(t, input_dev->keybit);
+
+		input_register_device(grip->dev[i]);
+	}
+
 	return 0;
 
-fail2:	gameport_close(gameport);
-fail1:	gameport_set_drvdata(gameport, NULL);
+ fail3: for (i = 0; i < 2; i++)
+		if (grip->dev[i])
+			input_unregister_device(grip->dev[i]);
+ fail2:	gameport_close(gameport);
+ fail1:	gameport_set_drvdata(gameport, NULL);
 	kfree(grip);
 	return err;
 }
@@ -391,8 +400,8 @@
 	int i;
 
 	for (i = 0; i < 2; i++)
-		if (grip->mode[i])
-			input_unregister_device(grip->dev + i);
+		if (grip->dev[i])
+			input_unregister_device(grip->dev[i]);
 	gameport_close(gameport);
 	gameport_set_drvdata(gameport, NULL);
 	kfree(grip);
diff --git a/drivers/input/joystick/grip_mp.c b/drivers/input/joystick/grip_mp.c
index da17eee..a0ba93c 100644
--- a/drivers/input/joystick/grip_mp.c
+++ b/drivers/input/joystick/grip_mp.c
@@ -32,23 +32,37 @@
 #define dbg(format, arg...) do {} while (0)
 #endif
 
+#define GRIP_MAX_PORTS	4
 /*
  * Grip multiport state
  */
 
+struct grip_port {
+	struct input_dev *dev;
+	int mode;
+	int registered;
+
+	/* individual gamepad states */
+	int buttons;
+	int xaxes;
+	int yaxes;
+	int dirty;     /* has the state been updated? */
+};
+
 struct grip_mp {
 	struct gameport *gameport;
-	struct input_dev dev[4];
-	int mode[4];
-	int registered[4];
+	struct grip_port *port[GRIP_MAX_PORTS];
+//	struct input_dev *dev[4];
+//	int mode[4];
+//	int registered[4];
 	int reads;
 	int bads;
 
 	/* individual gamepad states */
-	int buttons[4];
-	int xaxes[4];
-	int yaxes[4];
-	int dirty[4];     /* has the state been updated? */
+//	int buttons[4];
+//	int xaxes[4];
+//	int yaxes[4];
+//	int dirty[4];     /* has the state been updated? */
 };
 
 /*
@@ -85,16 +99,16 @@
 #define GRIP_MODE_GP		2
 #define GRIP_MODE_C64		3
 
-static int grip_btn_gp[]  = { BTN_TR, BTN_TL, BTN_A, BTN_B, BTN_C, BTN_X, BTN_Y, BTN_Z, -1 };
-static int grip_btn_c64[] = { BTN_JOYSTICK, -1 };
+static const int grip_btn_gp[]  = { BTN_TR, BTN_TL, BTN_A, BTN_B, BTN_C, BTN_X, BTN_Y, BTN_Z, -1 };
+static const int grip_btn_c64[] = { BTN_JOYSTICK, -1 };
 
-static int grip_abs_gp[]  = { ABS_X, ABS_Y, -1 };
-static int grip_abs_c64[] = { ABS_X, ABS_Y, -1 };
+static const int grip_abs_gp[]  = { ABS_X, ABS_Y, -1 };
+static const int grip_abs_c64[] = { ABS_X, ABS_Y, -1 };
 
-static int *grip_abs[] = { NULL, NULL, grip_abs_gp, grip_abs_c64 };
-static int *grip_btn[] = { NULL, NULL, grip_btn_gp, grip_btn_c64 };
+static const int *grip_abs[] = { NULL, NULL, grip_abs_gp, grip_abs_c64 };
+static const int *grip_btn[] = { NULL, NULL, grip_btn_gp, grip_btn_c64 };
 
-static char *grip_name[] = { NULL, NULL, "Gravis Grip Pad", "Commodore 64 Joystick" };
+static const char *grip_name[] = { NULL, NULL, "Gravis Grip Pad", "Commodore 64 Joystick" };
 
 static const int init_seq[] = {
 	1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1,
@@ -104,9 +118,9 @@
 
 /* Maps multiport directional values to X,Y axis values (each axis encoded in 3 bits) */
 
-static int axis_map[] = { 5, 9, 1, 5, 6, 10, 2, 6, 4, 8, 0, 4, 5, 9, 1, 5 };
+static const int axis_map[] = { 5, 9, 1, 5, 6, 10, 2, 6, 4, 8, 0, 4, 5, 9, 1, 5 };
 
-static void register_slot(int i, struct grip_mp *grip);
+static int register_slot(int i, struct grip_mp *grip);
 
 /*
  * Returns whether an odd or even number of bits are on in pkt.
@@ -353,9 +367,10 @@
 
 static int get_and_decode_packet(struct grip_mp *grip, int flags)
 {
+	struct grip_port *port;
 	u32 packet;
 	int joytype = 0;
-	int slot = 0;
+	int slot;
 
 	/* Get a packet and check for validity */
 
@@ -377,6 +392,8 @@
 	if ((slot < 0) || (slot > 3))
 		return flags;
 
+	port = grip->port[slot];
+
 	/*
 	 * Handle "reset" packets, which occur at startup, and when gamepads
 	 * are removed or plugged in.  May contain configuration of a new gamepad.
@@ -385,14 +402,14 @@
 	joytype = (packet >> 16) & 0x1f;
 	if (!joytype) {
 
-		if (grip->registered[slot]) {
+		if (port->registered) {
 			printk(KERN_INFO "grip_mp: removing %s, slot %d\n",
-			       grip_name[grip->mode[slot]], slot);
-			input_unregister_device(grip->dev + slot);
-			grip->registered[slot] = 0;
+			       grip_name[port->mode], slot);
+			input_unregister_device(port->dev);
+			port->registered = 0;
 		}
 		dbg("Reset: grip multiport slot %d\n", slot);
-		grip->mode[slot] = GRIP_MODE_RESET;
+		port->mode = GRIP_MODE_RESET;
 		flags |= IO_SLOT_CHANGE;
 		return flags;
 	}
@@ -402,17 +419,17 @@
 	if (joytype == 0x1f) {
 
 		int dir = (packet >> 8) & 0xf;          /* eight way directional value */
-		grip->buttons[slot] = (~packet) & 0xff;
-		grip->yaxes[slot] = ((axis_map[dir] >> 2) & 3) - 1;
-		grip->xaxes[slot] = (axis_map[dir] & 3) - 1;
-		grip->dirty[slot] = 1;
+		port->buttons = (~packet) & 0xff;
+		port->yaxes = ((axis_map[dir] >> 2) & 3) - 1;
+		port->xaxes = (axis_map[dir] & 3) - 1;
+		port->dirty = 1;
 
-		if (grip->mode[slot] == GRIP_MODE_RESET)
+		if (port->mode == GRIP_MODE_RESET)
 			flags |= IO_SLOT_CHANGE;
 
-		grip->mode[slot] = GRIP_MODE_GP;
+		port->mode = GRIP_MODE_GP;
 
-		if (!grip->registered[slot]) {
+		if (!port->registered) {
 			dbg("New Grip pad in multiport slot %d.\n", slot);
 			register_slot(slot, grip);
 		}
@@ -445,9 +462,9 @@
 		return 0;
 
 	for (slot = 0; slot < 4; slot++) {
-		if (grip->mode[slot] == GRIP_MODE_RESET)
+		if (grip->port[slot]->mode == GRIP_MODE_RESET)
 			invalid = 1;
-		if (grip->mode[slot] != GRIP_MODE_NONE)
+		if (grip->port[slot]->mode != GRIP_MODE_NONE)
 			active = 1;
 	}
 
@@ -484,7 +501,7 @@
 
 	/* Get packets, store multiport state, and check state's validity */
 	for (tries = 0; tries < 4096; tries++) {
-		if ( slots_valid(grip) ) {
+		if (slots_valid(grip)) {
 			initialized = 1;
 			break;
 		}
@@ -499,24 +516,24 @@
 
 static void report_slot(struct grip_mp *grip, int slot)
 {
-	struct input_dev *dev = &(grip->dev[slot]);
-	int i, buttons = grip->buttons[slot];
+	struct grip_port *port = grip->port[slot];
+	int i;
 
 	/* Store button states with linux input driver */
 
 	for (i = 0; i < 8; i++)
-		input_report_key(dev, grip_btn_gp[i], (buttons >> i) & 1);
+		input_report_key(port->dev, grip_btn_gp[i], (port->buttons >> i) & 1);
 
 	/* Store axis states with linux driver */
 
-	input_report_abs(dev, ABS_X, grip->xaxes[slot]);
-	input_report_abs(dev, ABS_Y, grip->yaxes[slot]);
+	input_report_abs(port->dev, ABS_X, port->xaxes);
+	input_report_abs(port->dev, ABS_Y, port->yaxes);
 
 	/* Tell the receiver of the events to process them */
 
-	input_sync(dev);
+	input_sync(port->dev);
 
-	grip->dirty[slot] = 0;
+	port->dirty = 0;
 }
 
 /*
@@ -540,7 +557,7 @@
 	}
 
 	for (i = 0; i < 4; i++)
-		if (grip->dirty[i])
+		if (grip->port[i]->dirty)
 			report_slot(grip, i);
 }
 
@@ -571,35 +588,43 @@
  * Tell the linux input layer about a newly plugged-in gamepad.
  */
 
-static void register_slot(int slot, struct grip_mp *grip)
+static int register_slot(int slot, struct grip_mp *grip)
 {
+	struct grip_port *port = grip->port[slot];
+	struct input_dev *input_dev;
 	int j, t;
 
-	grip->dev[slot].private = grip;
-	grip->dev[slot].open = grip_open;
-	grip->dev[slot].close = grip_close;
-	grip->dev[slot].name = grip_name[grip->mode[slot]];
-	grip->dev[slot].id.bustype = BUS_GAMEPORT;
-	grip->dev[slot].id.vendor = GAMEPORT_ID_VENDOR_GRAVIS;
-	grip->dev[slot].id.product = 0x0100 + grip->mode[slot];
-	grip->dev[slot].id.version = 0x0100;
-	grip->dev[slot].evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
+	port->dev = input_dev = input_allocate_device();
+	if (!input_dev)
+		return -ENOMEM;
 
-	for (j = 0; (t = grip_abs[grip->mode[slot]][j]) >= 0; j++)
-		input_set_abs_params(&grip->dev[slot], t, -1, 1, 0, 0);
+	input_dev->name = grip_name[port->mode];
+	input_dev->id.bustype = BUS_GAMEPORT;
+	input_dev->id.vendor = GAMEPORT_ID_VENDOR_GRAVIS;
+	input_dev->id.product = 0x0100 + port->mode;
+	input_dev->id.version = 0x0100;
+	input_dev->cdev.dev = &grip->gameport->dev;
+	input_dev->private = grip;
 
-	for (j = 0; (t = grip_btn[grip->mode[slot]][j]) >= 0; j++)
+	input_dev->open = grip_open;
+	input_dev->close = grip_close;
+
+	input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
+
+	for (j = 0; (t = grip_abs[port->mode][j]) >= 0; j++)
+		input_set_abs_params(input_dev, t, -1, 1, 0, 0);
+
+	for (j = 0; (t = grip_btn[port->mode][j]) >= 0; j++)
 		if (t > 0)
-			set_bit(t, grip->dev[slot].keybit);
+			set_bit(t, input_dev->keybit);
 
-	input_register_device(grip->dev + slot);
-	grip->registered[slot] = 1;
+	input_register_device(port->dev);
+	port->registered = 1;
 
-	if (grip->dirty[slot])	            /* report initial state, if any */
+	if (port->dirty)	            /* report initial state, if any */
 		report_slot(grip, slot);
 
-	printk(KERN_INFO "grip_mp: added %s, slot %d\n",
-	       grip_name[grip->mode[slot]], slot);
+	return 0;
 }
 
 static int grip_connect(struct gameport *gameport, struct gameport_driver *drv)
@@ -626,7 +651,7 @@
 		goto fail2;
 	}
 
-	if (!grip->mode[0] && !grip->mode[1] && !grip->mode[2] && !grip->mode[3]) {
+	if (!grip->port[0]->mode && !grip->port[1]->mode && !grip->port[2]->mode && !grip->port[3]->mode) {
 		/* nothing plugged in */
 		err = -ENODEV;
 		goto fail2;
@@ -646,8 +671,8 @@
 	int i;
 
 	for (i = 0; i < 4; i++)
-		if (grip->registered[i])
-			input_unregister_device(grip->dev + i);
+		if (grip->port[i]->registered)
+			input_unregister_device(grip->port[i]->dev);
 	gameport_close(gameport);
 	gameport_set_drvdata(gameport, NULL);
 	kfree(grip);
diff --git a/drivers/input/joystick/guillemot.c b/drivers/input/joystick/guillemot.c
index 6a70ec4..c528473 100644
--- a/drivers/input/joystick/guillemot.c
+++ b/drivers/input/joystick/guillemot.c
@@ -67,7 +67,7 @@
 
 struct guillemot {
 	struct gameport *gameport;
-	struct input_dev dev;
+	struct input_dev *dev;
 	int bads;
 	int reads;
 	struct guillemot_type *type;
@@ -123,7 +123,7 @@
 static void guillemot_poll(struct gameport *gameport)
 {
 	struct guillemot *guillemot = gameport_get_drvdata(gameport);
-	struct input_dev *dev = &guillemot->dev;
+	struct input_dev *dev = guillemot->dev;
 	u8 data[GUILLEMOT_MAX_LENGTH];
 	int i;
 
@@ -179,14 +179,20 @@
 static int guillemot_connect(struct gameport *gameport, struct gameport_driver *drv)
 {
 	struct guillemot *guillemot;
+	struct input_dev *input_dev;
 	u8 data[GUILLEMOT_MAX_LENGTH];
 	int i, t;
 	int err;
 
-	if (!(guillemot = kzalloc(sizeof(struct guillemot), GFP_KERNEL)))
-		return -ENOMEM;
+	guillemot = kzalloc(sizeof(struct guillemot), GFP_KERNEL);
+	input_dev = input_allocate_device();
+	if (!guillemot || !input_dev) {
+		err = -ENOMEM;
+		goto fail1;
+	}
 
 	guillemot->gameport = gameport;
+	guillemot->dev = input_dev;
 
 	gameport_set_drvdata(gameport, guillemot);
 
@@ -216,41 +222,40 @@
 	gameport_set_poll_interval(gameport, 20);
 
 	sprintf(guillemot->phys, "%s/input0", gameport->phys);
-
 	guillemot->type = guillemot_type + i;
 
-	guillemot->dev.private = guillemot;
-	guillemot->dev.open = guillemot_open;
-	guillemot->dev.close = guillemot_close;
+	input_dev->name = guillemot_type[i].name;
+	input_dev->phys = guillemot->phys;
+	input_dev->id.bustype = BUS_GAMEPORT;
+	input_dev->id.vendor = GAMEPORT_ID_VENDOR_GUILLEMOT;
+	input_dev->id.product = guillemot_type[i].id;
+	input_dev->id.version = (int)data[14] << 8 | data[15];
+	input_dev->cdev.dev = &gameport->dev;
+	input_dev->private = guillemot;
 
-	guillemot->dev.name = guillemot_type[i].name;
-	guillemot->dev.phys = guillemot->phys;
-	guillemot->dev.id.bustype = BUS_GAMEPORT;
-	guillemot->dev.id.vendor = GAMEPORT_ID_VENDOR_GUILLEMOT;
-	guillemot->dev.id.product = guillemot_type[i].id;
-	guillemot->dev.id.version = (int)data[14] << 8 | data[15];
+	input_dev->open = guillemot_open;
+	input_dev->close = guillemot_close;
 
-	guillemot->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
+	input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
 
 	for (i = 0; (t = guillemot->type->abs[i]) >= 0; i++)
-		input_set_abs_params(&guillemot->dev, t, 0, 255, 0, 0);
+		input_set_abs_params(input_dev, t, 0, 255, 0, 0);
 
 	if (guillemot->type->hat) {
-		input_set_abs_params(&guillemot->dev, ABS_HAT0X, -1, 1, 0, 0);
-		input_set_abs_params(&guillemot->dev, ABS_HAT0Y, -1, 1, 0, 0);
+		input_set_abs_params(input_dev, ABS_HAT0X, -1, 1, 0, 0);
+		input_set_abs_params(input_dev, ABS_HAT0Y, -1, 1, 0, 0);
 	}
 
 	for (i = 0; (t = guillemot->type->btn[i]) >= 0; i++)
-		set_bit(t, guillemot->dev.keybit);
+		set_bit(t, input_dev->keybit);
 
-	input_register_device(&guillemot->dev);
-	printk(KERN_INFO "input: %s ver %d.%02d on %s\n",
-		guillemot->type->name, data[14], data[15], gameport->phys);
+	input_register_device(guillemot->dev);
 
 	return 0;
 
 fail2:	gameport_close(gameport);
 fail1:  gameport_set_drvdata(gameport, NULL);
+	input_free_device(input_dev);
 	kfree(guillemot);
 	return err;
 }
@@ -260,7 +265,7 @@
 	struct guillemot *guillemot = gameport_get_drvdata(gameport);
 
 	printk(KERN_INFO "guillemot.c: Failed %d reads out of %d on %s\n", guillemot->reads, guillemot->bads, guillemot->phys);
-	input_unregister_device(&guillemot->dev);
+	input_unregister_device(guillemot->dev);
 	gameport_close(gameport);
 	kfree(guillemot);
 }
diff --git a/drivers/input/joystick/iforce/iforce-main.c b/drivers/input/joystick/iforce/iforce-main.c
index e31b7b9..64b9c31 100644
--- a/drivers/input/joystick/iforce/iforce-main.c
+++ b/drivers/input/joystick/iforce/iforce-main.c
@@ -144,7 +144,7 @@
 	int is_update;
 
 /* Check this effect type is supported by this device */
-	if (!test_bit(effect->type, iforce->dev.ffbit))
+	if (!test_bit(effect->type, iforce->dev->ffbit))
 		return -EINVAL;
 
 /*
@@ -152,30 +152,31 @@
  */
 	if (effect->id == -1) {
 
-		for (id=0; id < FF_EFFECTS_MAX; ++id)
-			if (!test_and_set_bit(FF_CORE_IS_USED, iforce->core_effects[id].flags)) break;
+		for (id = 0; id < FF_EFFECTS_MAX; ++id)
+			if (!test_and_set_bit(FF_CORE_IS_USED, iforce->core_effects[id].flags))
+				break;
 
-		if ( id == FF_EFFECTS_MAX || id >= iforce->dev.ff_effects_max)
+		if (id == FF_EFFECTS_MAX || id >= iforce->dev->ff_effects_max)
 			return -ENOMEM;
 
 		effect->id = id;
 		iforce->core_effects[id].owner = current->pid;
-		iforce->core_effects[id].flags[0] = (1<<FF_CORE_IS_USED);	/* Only IS_USED bit must be set */
+		iforce->core_effects[id].flags[0] = (1 << FF_CORE_IS_USED);	/* Only IS_USED bit must be set */
 
 		is_update = FALSE;
 	}
 	else {
 		/* We want to update an effect */
-		if (!CHECK_OWNERSHIP(effect->id, iforce)) return -EACCES;
+		if (!CHECK_OWNERSHIP(effect->id, iforce))
+			return -EACCES;
 
 		/* Parameter type cannot be updated */
 		if (effect->type != iforce->core_effects[effect->id].effect.type)
 			return -EINVAL;
 
 		/* Check the effect is not already being updated */
-		if (test_bit(FF_CORE_UPDATE, iforce->core_effects[effect->id].flags)) {
+		if (test_bit(FF_CORE_UPDATE, iforce->core_effects[effect->id].flags))
 			return -EAGAIN;
-		}
 
 		is_update = TRUE;
 	}
@@ -339,15 +340,19 @@
 
 int iforce_init_device(struct iforce *iforce)
 {
+	struct input_dev *input_dev;
 	unsigned char c[] = "CEOV";
 	int i;
 
+	input_dev = input_allocate_device();
+	if (input_dev)
+		return -ENOMEM;
+
 	init_waitqueue_head(&iforce->wait);
 	spin_lock_init(&iforce->xmit_lock);
 	init_MUTEX(&iforce->mem_mutex);
 	iforce->xmit.buf = iforce->xmit_data;
-
-	iforce->dev.ff_effects_max = 10;
+	iforce->dev = input_dev;
 
 /*
  * Input device fields.
@@ -356,26 +361,27 @@
 	switch (iforce->bus) {
 #ifdef CONFIG_JOYSTICK_IFORCE_USB
 	case IFORCE_USB:
-		iforce->dev.id.bustype = BUS_USB;
-		iforce->dev.dev = &iforce->usbdev->dev;
+		input_dev->id.bustype = BUS_USB;
+		input_dev->cdev.dev = &iforce->usbdev->dev;
 		break;
 #endif
 #ifdef CONFIG_JOYSTICK_IFORCE_232
 	case IFORCE_232:
-		iforce->dev.id.bustype = BUS_RS232;
-		iforce->dev.dev = &iforce->serio->dev;
+		input_dev->id.bustype = BUS_RS232;
+		input_dev->cdev.dev = &iforce->serio->dev;
 		break;
 #endif
 	}
 
-	iforce->dev.private = iforce;
-	iforce->dev.name = "Unknown I-Force device";
-	iforce->dev.open = iforce_open;
-	iforce->dev.close = iforce_release;
-	iforce->dev.flush = iforce_flush;
-	iforce->dev.event = iforce_input_event;
-	iforce->dev.upload_effect = iforce_upload_effect;
-	iforce->dev.erase_effect = iforce_erase_effect;
+	input_dev->private = iforce;
+	input_dev->name = "Unknown I-Force device";
+	input_dev->open = iforce_open;
+	input_dev->close = iforce_release;
+	input_dev->flush = iforce_flush;
+	input_dev->event = iforce_input_event;
+	input_dev->upload_effect = iforce_upload_effect;
+	input_dev->erase_effect = iforce_erase_effect;
+	input_dev->ff_effects_max = 10;
 
 /*
  * On-device memory allocation.
@@ -399,7 +405,8 @@
 
 	if (i == 20) { /* 5 seconds */
 		printk(KERN_ERR "iforce-main.c: Timeout waiting for response from device.\n");
-		return -1;
+		input_free_device(input_dev);
+		return -ENODEV;
 	}
 
 /*
@@ -407,12 +414,12 @@
  */
 
 	if (!iforce_get_id_packet(iforce, "M"))
-		iforce->dev.id.vendor = (iforce->edata[2] << 8) | iforce->edata[1];
+		input_dev->id.vendor = (iforce->edata[2] << 8) | iforce->edata[1];
 	else
 		printk(KERN_WARNING "iforce-main.c: Device does not respond to id packet M\n");
 
 	if (!iforce_get_id_packet(iforce, "P"))
-		iforce->dev.id.product = (iforce->edata[2] << 8) | iforce->edata[1];
+		input_dev->id.product = (iforce->edata[2] << 8) | iforce->edata[1];
 	else
 		printk(KERN_WARNING "iforce-main.c: Device does not respond to id packet P\n");
 
@@ -422,15 +429,15 @@
 		printk(KERN_WARNING "iforce-main.c: Device does not respond to id packet B\n");
 
 	if (!iforce_get_id_packet(iforce, "N"))
-		iforce->dev.ff_effects_max = iforce->edata[1];
+		iforce->dev->ff_effects_max = iforce->edata[1];
 	else
 		printk(KERN_WARNING "iforce-main.c: Device does not respond to id packet N\n");
 
 	/* Check if the device can store more effects than the driver can really handle */
-	if (iforce->dev.ff_effects_max > FF_EFFECTS_MAX) {
+	if (iforce->dev->ff_effects_max > FF_EFFECTS_MAX) {
 		printk(KERN_WARNING "input??: Device can handle %d effects, but N_EFFECTS_MAX is set to %d in iforce.h\n",
-			iforce->dev.ff_effects_max, FF_EFFECTS_MAX);
-		iforce->dev.ff_effects_max = FF_EFFECTS_MAX;
+			iforce->dev->ff_effects_max, FF_EFFECTS_MAX);
+		iforce->dev->ff_effects_max = FF_EFFECTS_MAX;
 	}
 
 /*
@@ -453,29 +460,28 @@
  */
 
 	for (i = 0; iforce_device[i].idvendor; i++)
-		if (iforce_device[i].idvendor == iforce->dev.id.vendor &&
-		    iforce_device[i].idproduct == iforce->dev.id.product)
+		if (iforce_device[i].idvendor == input_dev->id.vendor &&
+		    iforce_device[i].idproduct == input_dev->id.product)
 			break;
 
 	iforce->type = iforce_device + i;
-	iforce->dev.name = iforce->type->name;
+	input_dev->name = iforce->type->name;
 
 /*
  * Set input device bitfields and ranges.
  */
 
-	iforce->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_ABS) | BIT(EV_FF) | BIT(EV_FF_STATUS);
+	input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS) | BIT(EV_FF) | BIT(EV_FF_STATUS);
 
 	for (i = 0; iforce->type->btn[i] >= 0; i++) {
 		signed short t = iforce->type->btn[i];
-		set_bit(t, iforce->dev.keybit);
+		set_bit(t, input_dev->keybit);
 	}
-	set_bit(BTN_DEAD, iforce->dev.keybit);
+	set_bit(BTN_DEAD, input_dev->keybit);
 
 	for (i = 0; iforce->type->abs[i] >= 0; i++) {
 
 		signed short t = iforce->type->abs[i];
-		set_bit(t, iforce->dev.absbit);
 
 		switch (t) {
 
@@ -483,52 +489,42 @@
 			case ABS_Y:
 			case ABS_WHEEL:
 
-				iforce->dev.absmax[t] =  1920;
-				iforce->dev.absmin[t] = -1920;
-				iforce->dev.absflat[t] = 128;
-				iforce->dev.absfuzz[t] = 16;
-
-				set_bit(t, iforce->dev.ffbit);
+				input_set_abs_params(input_dev, t, -1920, 1920, 16, 128);
+				set_bit(t, input_dev->ffbit);
 				break;
 
 			case ABS_THROTTLE:
 			case ABS_GAS:
 			case ABS_BRAKE:
 
-				iforce->dev.absmax[t] = 255;
-				iforce->dev.absmin[t] = 0;
+				input_set_abs_params(input_dev, t, 0, 255, 0, 0);
 				break;
 
 			case ABS_RUDDER:
 
-				iforce->dev.absmax[t] = 127;
-				iforce->dev.absmin[t] = -128;
+				input_set_abs_params(input_dev, t, -128, 127, 0, 0);
 				break;
 
 			case ABS_HAT0X:
 			case ABS_HAT0Y:
 		        case ABS_HAT1X:
 		        case ABS_HAT1Y:
-				iforce->dev.absmax[t] =  1;
-				iforce->dev.absmin[t] = -1;
+
+				input_set_abs_params(input_dev, t, -1, 1, 0, 0);
 				break;
 		}
 	}
 
 	for (i = 0; iforce->type->ff[i] >= 0; i++)
-		set_bit(iforce->type->ff[i], iforce->dev.ffbit);
+		set_bit(iforce->type->ff[i], input_dev->ffbit);
 
 /*
  * Register input device.
  */
 
-	input_register_device(&iforce->dev);
+	input_register_device(iforce->dev);
 
-	printk(KERN_DEBUG "iforce->dev.open = %p\n", iforce->dev.open);
-
-	printk(KERN_INFO "input: %s [%d effects, %ld bytes memory]\n",
-		iforce->dev.name, iforce->dev.ff_effects_max,
-		iforce->device_memory.end);
+	printk(KERN_DEBUG "iforce->dev->open = %p\n", iforce->dev->open);
 
 	return 0;
 }
diff --git a/drivers/input/joystick/iforce/iforce-packets.c b/drivers/input/joystick/iforce/iforce-packets.c
index e5a31e5..4a26292 100644
--- a/drivers/input/joystick/iforce/iforce-packets.c
+++ b/drivers/input/joystick/iforce/iforce-packets.c
@@ -139,7 +139,8 @@
 static int mark_core_as_ready(struct iforce *iforce, unsigned short addr)
 {
 	int i;
-	for (i=0; i<iforce->dev.ff_effects_max; ++i) {
+
+	for (i = 0; i < iforce->dev->ff_effects_max; ++i) {
 		if (test_bit(FF_CORE_IS_USED, iforce->core_effects[i].flags) &&
 		    (iforce->core_effects[i].mod1_chunk.start == addr ||
 		     iforce->core_effects[i].mod2_chunk.start == addr)) {
@@ -153,7 +154,7 @@
 
 void iforce_process_packet(struct iforce *iforce, u16 cmd, unsigned char *data, struct pt_regs *regs)
 {
-	struct input_dev *dev = &iforce->dev;
+	struct input_dev *dev = iforce->dev;
 	int i;
 	static int being_used = 0;
 
diff --git a/drivers/input/joystick/iforce/iforce-serio.c b/drivers/input/joystick/iforce/iforce-serio.c
index 11f5190..64a78c5 100644
--- a/drivers/input/joystick/iforce/iforce-serio.c
+++ b/drivers/input/joystick/iforce/iforce-serio.c
@@ -131,11 +131,10 @@
 	struct iforce *iforce;
 	int err;
 
-	if (!(iforce = kmalloc(sizeof(struct iforce), GFP_KERNEL)))
+	iforce = kzalloc(sizeof(struct iforce), GFP_KERNEL);
+	if (!iforce)
 		return -ENOMEM;
 
-	memset(iforce, 0, sizeof(struct iforce));
-
 	iforce->bus = IFORCE_232;
 	iforce->serio = serio;
 
@@ -148,7 +147,8 @@
 		return err;
 	}
 
-	if (iforce_init_device(iforce)) {
+	err = iforce_init_device(iforce);
+	if (err) {
 		serio_close(serio);
 		serio_set_drvdata(serio, NULL);
 		kfree(iforce);
@@ -162,7 +162,7 @@
 {
 	struct iforce *iforce = serio_get_drvdata(serio);
 
-	input_unregister_device(&iforce->dev);
+	input_unregister_device(iforce->dev);
 	serio_close(serio);
 	serio_set_drvdata(serio, NULL);
 	kfree(iforce);
diff --git a/drivers/input/joystick/iforce/iforce-usb.c b/drivers/input/joystick/iforce/iforce-usb.c
index 58600f9..64b4a30 100644
--- a/drivers/input/joystick/iforce/iforce-usb.c
+++ b/drivers/input/joystick/iforce/iforce-usb.c
@@ -135,28 +135,24 @@
 	struct usb_host_interface *interface;
 	struct usb_endpoint_descriptor *epirq, *epout;
 	struct iforce *iforce;
+	int err = -ENOMEM;
 
 	interface = intf->cur_altsetting;
 
 	epirq = &interface->endpoint[0].desc;
 	epout = &interface->endpoint[1].desc;
 
-	if (!(iforce = kmalloc(sizeof(struct iforce) + 32, GFP_KERNEL)))
+	if (!(iforce = kzalloc(sizeof(struct iforce) + 32, GFP_KERNEL)))
 		goto fail;
 
-	memset(iforce, 0, sizeof(struct iforce));
-
-	if (!(iforce->irq = usb_alloc_urb(0, GFP_KERNEL))) {
+	if (!(iforce->irq = usb_alloc_urb(0, GFP_KERNEL)))
 		goto fail;
-	}
 
-	if (!(iforce->out = usb_alloc_urb(0, GFP_KERNEL))) {
+	if (!(iforce->out = usb_alloc_urb(0, GFP_KERNEL)))
 		goto fail;
-	}
 
-	if (!(iforce->ctrl = usb_alloc_urb(0, GFP_KERNEL))) {
+	if (!(iforce->ctrl = usb_alloc_urb(0, GFP_KERNEL)))
 		goto fail;
-	}
 
 	iforce->bus = IFORCE_USB;
 	iforce->usbdev = dev;
@@ -174,7 +170,9 @@
 	usb_fill_control_urb(iforce->ctrl, dev, usb_rcvctrlpipe(dev, 0),
 			(void*) &iforce->cr, iforce->edata, 16, iforce_usb_ctrl, iforce);
 
-	if (iforce_init_device(iforce)) goto fail;
+	err = iforce_init_device(iforce);
+	if (err)
+		goto fail;
 
 	usb_set_intfdata(intf, iforce);
 	return 0;
@@ -187,7 +185,7 @@
 		kfree(iforce);
 	}
 
-	return -ENODEV;
+	return err;
 }
 
 /* Called by iforce_delete() */
@@ -211,7 +209,7 @@
 	usb_set_intfdata(intf, NULL);
 	if (iforce) {
 		iforce->usbdev = NULL;
-		input_unregister_device(&iforce->dev);
+		input_unregister_device(iforce->dev);
 
 		if (!open) {
 			iforce_delete_device(iforce);
diff --git a/drivers/input/joystick/iforce/iforce.h b/drivers/input/joystick/iforce/iforce.h
index bce247b..146f406 100644
--- a/drivers/input/joystick/iforce/iforce.h
+++ b/drivers/input/joystick/iforce/iforce.h
@@ -117,7 +117,7 @@
 };
 
 struct iforce {
-	struct input_dev dev;		/* Input device interface */
+	struct input_dev *dev;		/* Input device interface */
 	struct iforce_device *type;
 	int bus;
 
diff --git a/drivers/input/joystick/interact.c b/drivers/input/joystick/interact.c
index d7b3472..8511ee7 100644
--- a/drivers/input/joystick/interact.c
+++ b/drivers/input/joystick/interact.c
@@ -54,7 +54,7 @@
 
 struct interact {
 	struct gameport *gameport;
-	struct input_dev dev;
+	struct input_dev *dev;
 	int bads;
 	int reads;
 	unsigned char type;
@@ -130,7 +130,7 @@
 static void interact_poll(struct gameport *gameport)
 {
 	struct interact *interact = gameport_get_drvdata(gameport);
-	struct input_dev *dev = &interact->dev;
+	struct input_dev *dev = interact->dev;
 	u32 data[3];
 	int i;
 
@@ -208,14 +208,20 @@
 static int interact_connect(struct gameport *gameport, struct gameport_driver *drv)
 {
 	struct interact *interact;
+	struct input_dev *input_dev;
 	__u32 data[3];
 	int i, t;
 	int err;
 
-	if (!(interact = kzalloc(sizeof(struct interact), GFP_KERNEL)))
-		return -ENOMEM;
+	interact = kzalloc(sizeof(struct interact), GFP_KERNEL);
+	input_dev = input_allocate_device();
+	if (!interact || !input_dev) {
+		err = -ENOMEM;
+		goto fail1;
+	}
 
 	interact->gameport = gameport;
+	interact->dev = input_dev;
 
 	gameport_set_drvdata(gameport, interact);
 
@@ -249,41 +255,40 @@
 	interact->type = i;
 	interact->length = interact_type[i].length;
 
-	interact->dev.private = interact;
-	interact->dev.open = interact_open;
-	interact->dev.close = interact_close;
+	input_dev->name = interact_type[i].name;
+	input_dev->phys = interact->phys;
+	input_dev->id.bustype = BUS_GAMEPORT;
+	input_dev->id.vendor = GAMEPORT_ID_VENDOR_INTERACT;
+	input_dev->id.product = interact_type[i].id;
+	input_dev->id.version = 0x0100;
+	input_dev->private = interact;
 
-	interact->dev.name = interact_type[i].name;
-	interact->dev.phys = interact->phys;
-	interact->dev.id.bustype = BUS_GAMEPORT;
-	interact->dev.id.vendor = GAMEPORT_ID_VENDOR_INTERACT;
-	interact->dev.id.product = interact_type[i].id;
-	interact->dev.id.version = 0x0100;
+	input_dev->open = interact_open;
+	input_dev->close = interact_close;
 
-	interact->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
+	input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
 
 	for (i = 0; (t = interact_type[interact->type].abs[i]) >= 0; i++) {
-		set_bit(t, interact->dev.absbit);
+		set_bit(t, input_dev->absbit);
 		if (i < interact_type[interact->type].b8) {
-			interact->dev.absmin[t] = 0;
-			interact->dev.absmax[t] = 255;
+			input_dev->absmin[t] = 0;
+			input_dev->absmax[t] = 255;
 		} else {
-			interact->dev.absmin[t] = -1;
-			interact->dev.absmax[t] = 1;
+			input_dev->absmin[t] = -1;
+			input_dev->absmax[t] = 1;
 		}
 	}
 
 	for (i = 0; (t = interact_type[interact->type].btn[i]) >= 0; i++)
-		set_bit(t, interact->dev.keybit);
+		set_bit(t, input_dev->keybit);
 
-	input_register_device(&interact->dev);
-	printk(KERN_INFO "input: %s on %s\n",
-		interact_type[interact->type].name, gameport->phys);
+	input_register_device(interact->dev);
 
 	return 0;
 
 fail2:	gameport_close(gameport);
 fail1:  gameport_set_drvdata(gameport, NULL);
+	input_free_device(input_dev);
 	kfree(interact);
 	return err;
 }
@@ -292,7 +297,7 @@
 {
 	struct interact *interact = gameport_get_drvdata(gameport);
 
-	input_unregister_device(&interact->dev);
+	input_unregister_device(interact->dev);
 	gameport_close(gameport);
 	gameport_set_drvdata(gameport, NULL);
 	kfree(interact);
diff --git a/drivers/input/joystick/magellan.c b/drivers/input/joystick/magellan.c
index 1ba5036..ca3cc23 100644
--- a/drivers/input/joystick/magellan.c
+++ b/drivers/input/joystick/magellan.c
@@ -49,14 +49,13 @@
 
 static int magellan_buttons[] = { BTN_0, BTN_1, BTN_2, BTN_3, BTN_4, BTN_5, BTN_6, BTN_7, BTN_8 };
 static int magellan_axes[] = { ABS_X, ABS_Y, ABS_Z, ABS_RX, ABS_RY, ABS_RZ };
-static char *magellan_name = "LogiCad3D Magellan / SpaceMouse";
 
 /*
  * Per-Magellan data.
  */
 
 struct magellan {
-	struct input_dev dev;
+	struct input_dev *dev;
 	int idx;
 	unsigned char data[MAGELLAN_MAX_LENGTH];
 	char phys[32];
@@ -85,7 +84,7 @@
 
 static void magellan_process_packet(struct magellan* magellan, struct pt_regs *regs)
 {
-	struct input_dev *dev = &magellan->dev;
+	struct input_dev *dev = magellan->dev;
 	unsigned char *data = magellan->data;
 	int i, t;
 
@@ -138,9 +137,9 @@
 {
 	struct magellan* magellan = serio_get_drvdata(serio);
 
-	input_unregister_device(&magellan->dev);
 	serio_close(serio);
 	serio_set_drvdata(serio, NULL);
+	input_unregister_device(magellan->dev);
 	kfree(magellan);
 }
 
@@ -153,52 +152,48 @@
 static int magellan_connect(struct serio *serio, struct serio_driver *drv)
 {
 	struct magellan *magellan;
-	int i, t;
-	int err;
+	struct input_dev *input_dev;
+	int err = -ENOMEM;
+	int i;
 
-	if (!(magellan = kmalloc(sizeof(struct magellan), GFP_KERNEL)))
-		return -ENOMEM;
+	magellan = kzalloc(sizeof(struct magellan), GFP_KERNEL);
+	input_dev = input_allocate_device();
+	if (!magellan || !input_dev)
+		goto fail;
 
-	memset(magellan, 0, sizeof(struct magellan));
-
-	magellan->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
-
-	for (i = 0; i < 9; i++)
-		set_bit(magellan_buttons[i], magellan->dev.keybit);
-
-	for (i = 0; i < 6; i++) {
-		t = magellan_axes[i];
-		set_bit(t, magellan->dev.absbit);
-		magellan->dev.absmin[t] = -360;
-		magellan->dev.absmax[t] =  360;
-	}
-
+	magellan->dev = input_dev;
 	sprintf(magellan->phys, "%s/input0", serio->phys);
 
-	init_input_dev(&magellan->dev);
-	magellan->dev.private = magellan;
-	magellan->dev.name = magellan_name;
-	magellan->dev.phys = magellan->phys;
-	magellan->dev.id.bustype = BUS_RS232;
-	magellan->dev.id.vendor = SERIO_MAGELLAN;
-	magellan->dev.id.product = 0x0001;
-	magellan->dev.id.version = 0x0100;
-	magellan->dev.dev = &serio->dev;
+	input_dev->name = "LogiCad3D Magellan / SpaceMouse";
+	input_dev->phys = magellan->phys;
+	input_dev->id.bustype = BUS_RS232;
+	input_dev->id.vendor = SERIO_MAGELLAN;
+	input_dev->id.product = 0x0001;
+	input_dev->id.version = 0x0100;
+	input_dev->cdev.dev = &serio->dev;
+	input_dev->private = magellan;
+
+	input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
+
+	for (i = 0; i < 9; i++)
+		set_bit(magellan_buttons[i], input_dev->keybit);
+
+	for (i = 0; i < 6; i++)
+		input_set_abs_params(input_dev, magellan_axes[i], -360, 360, 0, 0);
 
 	serio_set_drvdata(serio, magellan);
 
 	err = serio_open(serio, drv);
-	if (err) {
-		serio_set_drvdata(serio, NULL);
-		kfree(magellan);
-		return err;
-	}
+	if (err)
+		goto fail;
 
-	input_register_device(&magellan->dev);
-
-	printk(KERN_INFO "input: %s on %s\n", magellan_name, serio->phys);
-
+	input_register_device(magellan->dev);
 	return 0;
+
+ fail:	serio_set_drvdata(serio, NULL);
+	input_free_device(input_dev);
+	kfree(magellan);
+	return err;
 }
 
 /*
diff --git a/drivers/input/joystick/sidewinder.c b/drivers/input/joystick/sidewinder.c
index 9e03537..eaaad45 100644
--- a/drivers/input/joystick/sidewinder.c
+++ b/drivers/input/joystick/sidewinder.c
@@ -113,7 +113,7 @@
 
 struct sw {
 	struct gameport *gameport;
-	struct input_dev dev[4];
+	struct input_dev *dev[4];
 	char name[64];
 	char phys[4][32];
 	int length;
@@ -301,7 +301,7 @@
 static int sw_parse(unsigned char *buf, struct sw *sw)
 {
 	int hat, i, j;
-	struct input_dev *dev = sw->dev;
+	struct input_dev *dev;
 
 	switch (sw->type) {
 
@@ -310,6 +310,8 @@
 			if (sw_check(GB(0,64)) || (hat = (GB(6,1) << 3) | GB(60,3)) > 8)
 				return -1;
 
+			dev = sw->dev[0];
+
 			input_report_abs(dev, ABS_X,        (GB( 3,3) << 7) | GB(16,7));
 			input_report_abs(dev, ABS_Y,        (GB( 0,3) << 7) | GB(24,7));
 			input_report_abs(dev, ABS_RZ,       (GB(35,2) << 7) | GB(40,7));
@@ -335,13 +337,13 @@
 				if (sw_parity(GB(i*15,15)))
 					return -1;
 
-				input_report_abs(dev + i, ABS_X, GB(i*15+3,1) - GB(i*15+2,1));
-				input_report_abs(dev + i, ABS_Y, GB(i*15+0,1) - GB(i*15+1,1));
+				input_report_abs(sw->dev[i], ABS_X, GB(i*15+3,1) - GB(i*15+2,1));
+				input_report_abs(sw->dev[i], ABS_Y, GB(i*15+0,1) - GB(i*15+1,1));
 
 				for (j = 0; j < 10; j++)
-					input_report_key(dev + i, sw_btn[SW_ID_GP][j], !GB(i*15+j+4,1));
+					input_report_key(sw->dev[i], sw_btn[SW_ID_GP][j], !GB(i*15+j+4,1));
 
-				input_sync(dev + i);
+				input_sync(sw->dev[i]);
 			}
 
 			return 0;
@@ -352,6 +354,7 @@
 			if (!sw_parity(GB(0,48)) || (hat = GB(42,4)) > 8)
 				return -1;
 
+			dev = sw->dev[0];
 			input_report_abs(dev, ABS_X,        GB( 9,10));
 			input_report_abs(dev, ABS_Y,        GB(19,10));
 			input_report_abs(dev, ABS_RZ,       GB(36, 6));
@@ -372,6 +375,7 @@
 			if (!sw_parity(GB(0,43)) || (hat = GB(28,4)) > 8)
 				return -1;
 
+			dev = sw->dev[0];
 			input_report_abs(dev, ABS_X,        GB( 0,10));
 			input_report_abs(dev, ABS_Y,        GB(16,10));
 			input_report_abs(dev, ABS_THROTTLE, GB(32, 6));
@@ -396,6 +400,7 @@
 			if (!sw_parity(GB(0,33)))
 				return -1;
 
+			dev = sw->dev[0];
 			input_report_abs(dev, ABS_RX,       GB( 0,10));
 			input_report_abs(dev, ABS_RUDDER,   GB(10, 6));
 			input_report_abs(dev, ABS_THROTTLE, GB(16, 6));
@@ -581,6 +586,7 @@
 static int sw_connect(struct gameport *gameport, struct gameport_driver *drv)
 {
 	struct sw *sw;
+	struct input_dev *input_dev;
 	int i, j, k, l;
 	int err;
 	unsigned char *buf = NULL;	/* [SW_LENGTH] */
@@ -729,42 +735,50 @@
 		sprintf(sw->name, "Microsoft SideWinder %s", sw_name[sw->type]);
 		sprintf(sw->phys[i], "%s/input%d", gameport->phys, i);
 
-		sw->dev[i].private = sw;
+		input_dev = input_allocate_device();
+		if (!input_dev) {
+			err = -ENOMEM;
+			goto fail3;
+		}
 
-		sw->dev[i].open = sw_open;
-		sw->dev[i].close = sw_close;
+		input_dev->name = sw->name;
+		input_dev->phys = sw->phys[i];
+		input_dev->id.bustype = BUS_GAMEPORT;
+		input_dev->id.vendor = GAMEPORT_ID_VENDOR_MICROSOFT;
+		input_dev->id.product = sw->type;
+		input_dev->id.version = 0x0100;
+		input_dev->cdev.dev = &gameport->dev;
+		input_dev->private = sw;
 
-		sw->dev[i].name = sw->name;
-		sw->dev[i].phys = sw->phys[i];
-		sw->dev[i].id.bustype = BUS_GAMEPORT;
-		sw->dev[i].id.vendor = GAMEPORT_ID_VENDOR_MICROSOFT;
-		sw->dev[i].id.product = sw->type;
-		sw->dev[i].id.version = 0x0100;
+		input_dev->open = sw_open;
+		input_dev->close = sw_close;
 
-		sw->dev[i].evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
+		input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
 
 		for (j = 0; (bits = sw_bit[sw->type][j]); j++) {
 			code = sw_abs[sw->type][j];
-			set_bit(code, sw->dev[i].absbit);
-			sw->dev[i].absmax[code] = (1 << bits) - 1;
-			sw->dev[i].absmin[code] = (bits == 1) ? -1 : 0;
-			sw->dev[i].absfuzz[code] = ((bits >> 1) >= 2) ? (1 << ((bits >> 1) - 2)) : 0;
+			set_bit(code, input_dev->absbit);
+			input_dev->absmax[code] = (1 << bits) - 1;
+			input_dev->absmin[code] = (bits == 1) ? -1 : 0;
+			input_dev->absfuzz[code] = ((bits >> 1) >= 2) ? (1 << ((bits >> 1) - 2)) : 0;
 			if (code != ABS_THROTTLE)
-				sw->dev[i].absflat[code] = (bits >= 5) ? (1 << (bits - 5)) : 0;
+				input_dev->absflat[code] = (bits >= 5) ? (1 << (bits - 5)) : 0;
 		}
 
 		for (j = 0; (code = sw_btn[sw->type][j]); j++)
-			set_bit(code, sw->dev[i].keybit);
+			set_bit(code, input_dev->keybit);
 
-		input_register_device(sw->dev + i);
-		printk(KERN_INFO "input: %s%s on %s [%d-bit id %d data %d]\n",
-			sw->name, comment, gameport->phys, m, l, k);
+		dbg("%s%s [%d-bit id %d data %d]\n", sw->name, comment, m, l, k);
+
+		input_register_device(sw->dev[i]);
 	}
 
 	return 0;
 
-fail2:	gameport_close(gameport);
-fail1:	gameport_set_drvdata(gameport, NULL);
+ fail3: while (--i >= 0)
+		input_unregister_device(sw->dev[i]);
+ fail2:	gameport_close(gameport);
+ fail1:	gameport_set_drvdata(gameport, NULL);
 	kfree(sw);
 	kfree(buf);
 	kfree(idbuf);
@@ -777,7 +791,7 @@
 	int i;
 
 	for (i = 0; i < sw->number; i++)
-		input_unregister_device(sw->dev + i);
+		input_unregister_device(sw->dev[i]);
 	gameport_close(gameport);
 	gameport_set_drvdata(gameport, NULL);
 	kfree(sw);
diff --git a/drivers/input/joystick/spaceball.c b/drivers/input/joystick/spaceball.c
index a436f22..d6f8db8 100644
--- a/drivers/input/joystick/spaceball.c
+++ b/drivers/input/joystick/spaceball.c
@@ -70,8 +70,7 @@
  */
 
 struct spaceball {
-	struct input_dev dev;
-	struct serio *serio;
+	struct input_dev *dev;
 	int idx;
 	int escape;
 	unsigned char data[SPACEBALL_MAX_LENGTH];
@@ -85,7 +84,7 @@
 
 static void spaceball_process_packet(struct spaceball* spaceball, struct pt_regs *regs)
 {
-	struct input_dev *dev = &spaceball->dev;
+	struct input_dev *dev = spaceball->dev;
 	unsigned char *data = spaceball->data;
 	int i;
 
@@ -193,9 +192,9 @@
 {
 	struct spaceball* spaceball = serio_get_drvdata(serio);
 
-	input_unregister_device(&spaceball->dev);
 	serio_close(serio);
 	serio_set_drvdata(serio, NULL);
+	input_unregister_device(spaceball->dev);
 	kfree(spaceball);
 }
 
@@ -208,69 +207,62 @@
 static int spaceball_connect(struct serio *serio, struct serio_driver *drv)
 {
 	struct spaceball *spaceball;
-	int i, t, id;
-	int err;
+	struct input_dev *input_dev;
+	int err = -ENOMEM;
+	int i, id;
 
 	if ((id = serio->id.id) > SPACEBALL_MAX_ID)
 		return -ENODEV;
 
-	if (!(spaceball = kmalloc(sizeof(struct spaceball), GFP_KERNEL)))
-		return - ENOMEM;
+	spaceball = kmalloc(sizeof(struct spaceball), GFP_KERNEL);
+	input_dev = input_allocate_device();
+	if (!spaceball || !input_dev)
+		goto fail;
 
-	memset(spaceball, 0, sizeof(struct spaceball));
+	spaceball->dev = input_dev;
+	sprintf(spaceball->phys, "%s/input0", serio->phys);
 
-	spaceball->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
+	input_dev->name = spaceball_names[id];
+	input_dev->phys = spaceball->phys;
+	input_dev->id.bustype = BUS_RS232;
+	input_dev->id.vendor = SERIO_SPACEBALL;
+	input_dev->id.product = id;
+	input_dev->id.version = 0x0100;
+	input_dev->cdev.dev = &serio->dev;
+	input_dev->private = spaceball;
+
+	input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
 
 	switch (id) {
 		case SPACEBALL_4000FLX:
 		case SPACEBALL_4000FLX_L:
-			spaceball->dev.keybit[LONG(BTN_0)] |= BIT(BTN_9);
-			spaceball->dev.keybit[LONG(BTN_A)] |= BIT(BTN_A) | BIT(BTN_B) | BIT(BTN_C) | BIT(BTN_MODE);
+			input_dev->keybit[LONG(BTN_0)] |= BIT(BTN_9);
+			input_dev->keybit[LONG(BTN_A)] |= BIT(BTN_A) | BIT(BTN_B) | BIT(BTN_C) | BIT(BTN_MODE);
 		default:
-			spaceball->dev.keybit[LONG(BTN_0)] |= BIT(BTN_2) | BIT(BTN_3) | BIT(BTN_4)
+			input_dev->keybit[LONG(BTN_0)] |= BIT(BTN_2) | BIT(BTN_3) | BIT(BTN_4)
 				| BIT(BTN_5) | BIT(BTN_6) | BIT(BTN_7) | BIT(BTN_8);
 		case SPACEBALL_3003C:
-			spaceball->dev.keybit[LONG(BTN_0)] |= BIT(BTN_1) | BIT(BTN_8);
+			input_dev->keybit[LONG(BTN_0)] |= BIT(BTN_1) | BIT(BTN_8);
 	}
 
-	for (i = 0; i < 6; i++) {
-		t = spaceball_axes[i];
-		set_bit(t, spaceball->dev.absbit);
-		spaceball->dev.absmin[t] = i < 3 ? -8000 : -1600;
-		spaceball->dev.absmax[t] = i < 3 ?  8000 :  1600;
-		spaceball->dev.absflat[t] = i < 3 ? 40 : 8;
-		spaceball->dev.absfuzz[t] = i < 3 ? 8 : 2;
+	for (i = 0; i < 3; i++) {
+		input_set_abs_params(input_dev, ABS_X + i, -8000, 8000, 8, 40);
+		input_set_abs_params(input_dev, ABS_RX + i, -1600, 1600, 2, 8);
 	}
 
-	spaceball->serio = serio;
-	spaceball->dev.private = spaceball;
-
-	sprintf(spaceball->phys, "%s/input0", serio->phys);
-
-	init_input_dev(&spaceball->dev);
-	spaceball->dev.name = spaceball_names[id];
-	spaceball->dev.phys = spaceball->phys;
-	spaceball->dev.id.bustype = BUS_RS232;
-	spaceball->dev.id.vendor = SERIO_SPACEBALL;
-	spaceball->dev.id.product = id;
-	spaceball->dev.id.version = 0x0100;
-	spaceball->dev.dev = &serio->dev;
-
 	serio_set_drvdata(serio, spaceball);
 
 	err = serio_open(serio, drv);
-	if (err) {
-		serio_set_drvdata(serio, NULL);
-		kfree(spaceball);
-		return err;
-	}
+	if (err)
+		goto fail;
 
-	input_register_device(&spaceball->dev);
-
-	printk(KERN_INFO "input: %s on serio%s\n",
-		spaceball_names[id], serio->phys);
-
+	input_register_device(spaceball->dev);
 	return 0;
+
+ fail:	serio_set_drvdata(serio, NULL);
+	input_free_device(input_dev);
+	kfree(spaceball);
+	return err;
 }
 
 /*
diff --git a/drivers/input/joystick/spaceorb.c b/drivers/input/joystick/spaceorb.c
index 01fd2e4..7c123a0 100644
--- a/drivers/input/joystick/spaceorb.c
+++ b/drivers/input/joystick/spaceorb.c
@@ -52,15 +52,13 @@
 
 static int spaceorb_buttons[] = { BTN_TL, BTN_TR, BTN_Y, BTN_X, BTN_B, BTN_A };
 static int spaceorb_axes[] = { ABS_X, ABS_Y, ABS_Z, ABS_RX, ABS_RY, ABS_RZ };
-static char *spaceorb_name = "SpaceTec SpaceOrb 360 / Avenger";
 
 /*
  * Per-Orb data.
  */
 
 struct spaceorb {
-	struct input_dev dev;
-	struct serio *serio;
+	struct input_dev *dev;
 	int idx;
 	unsigned char data[SPACEORB_MAX_LENGTH];
 	char phys[32];
@@ -78,7 +76,7 @@
 
 static void spaceorb_process_packet(struct spaceorb *spaceorb, struct pt_regs *regs)
 {
-	struct input_dev *dev = &spaceorb->dev;
+	struct input_dev *dev = spaceorb->dev;
 	unsigned char *data = spaceorb->data;
 	unsigned char c = 0;
 	int axes[6];
@@ -95,8 +93,8 @@
 		case 'R':				/* Reset packet */
 			spaceorb->data[spaceorb->idx - 1] = 0;
 			for (i = 1; i < spaceorb->idx && spaceorb->data[i] == ' '; i++);
-			printk(KERN_INFO "input: %s [%s] on %s\n",
-				 spaceorb_name, spaceorb->data + i, spaceorb->serio->phys);
+			printk(KERN_INFO "input: %s [%s] is %s\n",
+				 dev->name, spaceorb->data + i, spaceorb->phys);
 			break;
 
 		case 'D':				/* Ball + button data */
@@ -123,7 +121,7 @@
 
 		case 'E':				/* Error packet */
 			if (spaceorb->idx != 4) return;
-			printk(KERN_ERR "joy-spaceorb: Device error. [ ");
+			printk(KERN_ERR "spaceorb: Device error. [ ");
 			for (i = 0; i < 7; i++) if (data[1] & (1 << i)) printk("%s ", spaceorb_errors[i]);
 			printk("]\n");
 			break;
@@ -154,9 +152,9 @@
 {
 	struct spaceorb* spaceorb = serio_get_drvdata(serio);
 
-	input_unregister_device(&spaceorb->dev);
 	serio_close(serio);
 	serio_set_drvdata(serio, NULL);
+	input_unregister_device(spaceorb->dev);
 	kfree(spaceorb);
 }
 
@@ -169,52 +167,48 @@
 static int spaceorb_connect(struct serio *serio, struct serio_driver *drv)
 {
 	struct spaceorb *spaceorb;
-	int i, t;
-	int err;
+	struct input_dev *input_dev;
+	int err = -ENOMEM;
+	int i;
 
-	if (!(spaceorb = kmalloc(sizeof(struct spaceorb), GFP_KERNEL)))
-		return -ENOMEM;
+	spaceorb = kzalloc(sizeof(struct spaceorb), GFP_KERNEL);
+	input_dev = input_allocate_device();
+	if (!spaceorb || !input_dev)
+		goto fail;
 
-	memset(spaceorb, 0, sizeof(struct spaceorb));
-
-	spaceorb->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
-
-	for (i = 0; i < 6; i++)
-		set_bit(spaceorb_buttons[i], spaceorb->dev.keybit);
-
-	for (i = 0; i < 6; i++) {
-		t = spaceorb_axes[i];
-		set_bit(t, spaceorb->dev.absbit);
-		spaceorb->dev.absmin[t] = -508;
-		spaceorb->dev.absmax[t] =  508;
-	}
-
-	spaceorb->serio = serio;
-	spaceorb->dev.private = spaceorb;
-
+	spaceorb->dev = input_dev;
 	sprintf(spaceorb->phys, "%s/input0", serio->phys);
 
-	init_input_dev(&spaceorb->dev);
-	spaceorb->dev.name = spaceorb_name;
-	spaceorb->dev.phys = spaceorb->phys;
-	spaceorb->dev.id.bustype = BUS_RS232;
-	spaceorb->dev.id.vendor = SERIO_SPACEORB;
-	spaceorb->dev.id.product = 0x0001;
-	spaceorb->dev.id.version = 0x0100;
-	spaceorb->dev.dev = &serio->dev;
+	input_dev->name = "SpaceTec SpaceOrb 360 / Avenger";
+	input_dev->phys = spaceorb->phys;
+	input_dev->id.bustype = BUS_RS232;
+	input_dev->id.vendor = SERIO_SPACEORB;
+	input_dev->id.product = 0x0001;
+	input_dev->id.version = 0x0100;
+	input_dev->cdev.dev = &serio->dev;
+	input_dev->private = spaceorb;
+
+	input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
+
+	for (i = 0; i < 6; i++)
+		set_bit(spaceorb_buttons[i], input_dev->keybit);
+
+	for (i = 0; i < 6; i++)
+		input_set_abs_params(input_dev, spaceorb_axes[i], -508, 508, 0, 0);
 
 	serio_set_drvdata(serio, spaceorb);
 
 	err = serio_open(serio, drv);
-	if (err) {
-		serio_set_drvdata(serio, NULL);
-		kfree(spaceorb);
-		return err;
-	}
+	if (err)
+		goto fail;
 
-	input_register_device(&spaceorb->dev);
-
+	input_register_device(spaceorb->dev);
 	return 0;
+
+ fail:	serio_set_drvdata(serio, NULL);
+	input_free_device(input_dev);
+	kfree(spaceorb);
+	return err;
 }
 
 /*
diff --git a/drivers/input/joystick/stinger.c b/drivers/input/joystick/stinger.c
index 6f6e675..0a9ed1d 100644
--- a/drivers/input/joystick/stinger.c
+++ b/drivers/input/joystick/stinger.c
@@ -48,14 +48,12 @@
 
 #define STINGER_MAX_LENGTH 8
 
-static char *stinger_name = "Gravis Stinger";
-
 /*
  * Per-Stinger data.
  */
 
 struct stinger {
-	struct input_dev dev;
+	struct input_dev *dev;
 	int idx;
 	unsigned char data[STINGER_MAX_LENGTH];
 	char phys[32];
@@ -68,7 +66,7 @@
 
 static void stinger_process_packet(struct stinger *stinger, struct pt_regs *regs)
 {
-	struct input_dev *dev = &stinger->dev;
+	struct input_dev *dev = stinger->dev;
 	unsigned char *data = stinger->data;
 
 	if (!stinger->idx) return;
@@ -126,9 +124,9 @@
 {
 	struct stinger *stinger = serio_get_drvdata(serio);
 
-	input_unregister_device(&stinger->dev);
 	serio_close(serio);
 	serio_set_drvdata(serio, NULL);
+	input_unregister_device(stinger->dev);
 	kfree(stinger);
 }
 
@@ -141,53 +139,46 @@
 static int stinger_connect(struct serio *serio, struct serio_driver *drv)
 {
 	struct stinger *stinger;
-	int i;
-	int err;
+	struct input_dev *input_dev;
+	int err = -ENOMEM;
 
-	if (!(stinger = kmalloc(sizeof(struct stinger), GFP_KERNEL)))
-		return -ENOMEM;
+	stinger = kmalloc(sizeof(struct stinger), GFP_KERNEL);
+	input_dev = input_allocate_device();
+	if (!stinger || !input_dev)
+		goto fail;
 
-	memset(stinger, 0, sizeof(struct stinger));
-
-	stinger->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
-	stinger->dev.keybit[LONG(BTN_A)] = BIT(BTN_A) | BIT(BTN_B) | BIT(BTN_C) | BIT(BTN_X) | \
-					   BIT(BTN_Y) | BIT(BTN_Z) | BIT(BTN_TL) | BIT(BTN_TR) | \
-					   BIT(BTN_START) | BIT(BTN_SELECT);
-	stinger->dev.absbit[0] = BIT(ABS_X) | BIT(ABS_Y);
-
+	stinger->dev = input_dev;
 	sprintf(stinger->phys, "%s/serio0", serio->phys);
 
-	init_input_dev(&stinger->dev);
-	stinger->dev.name = stinger_name;
-	stinger->dev.phys = stinger->phys;
-	stinger->dev.id.bustype = BUS_RS232;
-	stinger->dev.id.vendor = SERIO_STINGER;
-	stinger->dev.id.product = 0x0001;
-	stinger->dev.id.version = 0x0100;
-	stinger->dev.dev = &serio->dev;
+	input_dev->name = "Gravis Stinger";
+	input_dev->phys = stinger->phys;
+	input_dev->id.bustype = BUS_RS232;
+	input_dev->id.vendor = SERIO_STINGER;
+	input_dev->id.product = 0x0001;
+	input_dev->id.version = 0x0100;
+	input_dev->cdev.dev = &serio->dev;
+	input_dev->private = stinger;
 
-	for (i = 0; i < 2; i++) {
-		stinger->dev.absmax[ABS_X+i] =  64;
-		stinger->dev.absmin[ABS_X+i] = -64;
-		stinger->dev.absflat[ABS_X+i] = 4;
-	}
-
-	stinger->dev.private = stinger;
+	input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
+	input_dev->keybit[LONG(BTN_A)] = BIT(BTN_A) | BIT(BTN_B) | BIT(BTN_C) | BIT(BTN_X) |
+					 BIT(BTN_Y) | BIT(BTN_Z) | BIT(BTN_TL) | BIT(BTN_TR) |
+					 BIT(BTN_START) | BIT(BTN_SELECT);
+	input_set_abs_params(input_dev, ABS_X, -64, 64, 0, 4);
+	input_set_abs_params(input_dev, ABS_Y, -64, 64, 0, 4);
 
 	serio_set_drvdata(serio, stinger);
 
 	err = serio_open(serio, drv);
-	if (err) {
-		serio_set_drvdata(serio, NULL);
-		kfree(stinger);
-		return err;
-	}
+	if (err)
+		goto fail;
 
-	input_register_device(&stinger->dev);
-
-	printk(KERN_INFO "input: %s on %s\n",  stinger_name, serio->phys);
-
+	input_register_device(stinger->dev);
 	return 0;
+
+ fail:	serio_set_drvdata(serio, NULL);
+	input_free_device(input_dev);
+	kfree(stinger);
+	return err;
 }
 
 /*
diff --git a/drivers/input/joystick/tmdc.c b/drivers/input/joystick/tmdc.c
index 7431efc..3a7d1bb 100644
--- a/drivers/input/joystick/tmdc.c
+++ b/drivers/input/joystick/tmdc.c
@@ -63,37 +63,70 @@
 #define TMDC_ABS_HAT		4
 #define TMDC_BTN		16
 
-static unsigned char tmdc_byte_a[16] = { 0, 1, 3, 4, 6, 7 };
-static unsigned char tmdc_byte_d[16] = { 2, 5, 8, 9 };
+static const unsigned char tmdc_byte_a[16] = { 0, 1, 3, 4, 6, 7 };
+static const unsigned char tmdc_byte_d[16] = { 2, 5, 8, 9 };
 
-static signed char tmdc_abs[TMDC_ABS] =
+static const signed char tmdc_abs[TMDC_ABS] =
 	{ ABS_X, ABS_Y, ABS_RUDDER, ABS_THROTTLE, ABS_RX, ABS_RY, ABS_RZ };
-static signed char tmdc_abs_hat[TMDC_ABS_HAT] =
+static const signed char tmdc_abs_hat[TMDC_ABS_HAT] =
 	{ ABS_HAT0X, ABS_HAT0Y, ABS_HAT1X, ABS_HAT1Y };
-static signed char tmdc_abs_at[TMDC_ABS] =
+static const signed char tmdc_abs_at[TMDC_ABS] =
 	{ ABS_X, ABS_Y, ABS_RUDDER, -1, ABS_THROTTLE };
-static signed char tmdc_abs_fm[TMDC_ABS] =
+static const signed char tmdc_abs_fm[TMDC_ABS] =
 	{ ABS_RX, ABS_RY, ABS_X, ABS_Y };
 
-static short tmdc_btn_pad[TMDC_BTN] =
+static const short tmdc_btn_pad[TMDC_BTN] =
 	{ BTN_A, BTN_B, BTN_C, BTN_X, BTN_Y, BTN_Z, BTN_START, BTN_SELECT, BTN_TL, BTN_TR };
-static short tmdc_btn_joy[TMDC_BTN] =
+static const short tmdc_btn_joy[TMDC_BTN] =
 	{ BTN_TRIGGER, BTN_THUMB, BTN_TOP, BTN_TOP2, BTN_BASE, BTN_BASE2, BTN_THUMB2, BTN_PINKIE,
 	  BTN_BASE3, BTN_BASE4, BTN_A, BTN_B, BTN_C, BTN_X, BTN_Y, BTN_Z };
-static short tmdc_btn_fm[TMDC_BTN] =
+static const short tmdc_btn_fm[TMDC_BTN] =
         { BTN_TRIGGER, BTN_C, BTN_B, BTN_A, BTN_THUMB, BTN_X, BTN_Y, BTN_Z, BTN_TOP, BTN_TOP2 };
-static short tmdc_btn_at[TMDC_BTN] =
+static const short tmdc_btn_at[TMDC_BTN] =
         { BTN_TRIGGER, BTN_THUMB2, BTN_PINKIE, BTN_THUMB, BTN_BASE6, BTN_BASE5, BTN_BASE4,
           BTN_BASE3, BTN_BASE2, BTN_BASE };
 
-static struct {
+static const struct {
         int x;
         int y;
 } tmdc_hat_to_axis[] = {{ 0, 0}, { 1, 0}, { 0,-1}, {-1, 0}, { 0, 1}};
 
+static const struct tmdc_model {
+	unsigned char id;
+	const char *name;
+	char abs;
+	char hats;
+	char btnc[4];
+	char btno[4];
+	const signed char *axes;
+	const short *buttons;
+} tmdc_models[] = {
+	{   1, "ThrustMaster Millenium 3D Inceptor",	  6, 2, { 4, 2 }, { 4, 6 }, tmdc_abs, tmdc_btn_joy },
+	{   3, "ThrustMaster Rage 3D Gamepad",		  2, 0, { 8, 2 }, { 0, 0 }, tmdc_abs, tmdc_btn_pad },
+	{   4, "ThrustMaster Attack Throttle",		  5, 2, { 4, 6 }, { 4, 2 }, tmdc_abs_at, tmdc_btn_at },
+	{   8, "ThrustMaster FragMaster",		  4, 0, { 8, 2 }, { 0, 0 }, tmdc_abs_fm, tmdc_btn_fm },
+	{ 163, "Thrustmaster Fusion GamePad",		  2, 0, { 8, 2 }, { 0, 0 }, tmdc_abs, tmdc_btn_pad },
+	{   0, "Unknown %d-axis, %d-button TM device %d", 0, 0, { 0, 0 }, { 0, 0 }, tmdc_abs, tmdc_btn_joy }
+};
+
+
+struct tmdc_port {
+	struct input_dev *dev;
+	char name[64];
+	char phys[32];
+	int mode;
+	const signed char *abs;
+	const short *btn;
+	unsigned char absc;
+	unsigned char btnc[4];
+	unsigned char btno[4];
+};
+
 struct tmdc {
 	struct gameport *gameport;
-	struct input_dev dev[2];
+	struct tmdc_port *port[2];
+#if 0
+	struct input_dev *dev[2];
 	char name[2][64];
 	char phys[2][32];
 	int mode[2];
@@ -102,6 +135,7 @@
 	unsigned char absc[2];
 	unsigned char btnc[2][4];
 	unsigned char btno[2][4];
+#endif
 	int reads;
 	int bads;
 	unsigned char exists;
@@ -156,6 +190,50 @@
 	return (i[0] == TMDC_MAX_LENGTH) | ((i[1] == TMDC_MAX_LENGTH) << 1);
 }
 
+static int tmdc_parse_packet(struct tmdc_port *port, unsigned char *data)
+{
+	int i, k, l;
+
+	if (data[TMDC_BYTE_ID] != port->mode)
+		return -1;
+
+	for (i = 0; i < port->absc; i++) {
+		if (port->abs[i] < 0)
+			return 0;
+
+		input_report_abs(port->dev, port->abs[i], data[tmdc_byte_a[i]]);
+	}
+
+	switch (port->mode) {
+
+		case TMDC_MODE_M3DI:
+
+			i = tmdc_byte_d[0];
+			input_report_abs(port->dev, ABS_HAT0X, ((data[i] >> 3) & 1) - ((data[i] >> 1) & 1));
+			input_report_abs(port->dev, ABS_HAT0Y, ((data[i] >> 2) & 1) - ( data[i]       & 1));
+			break;
+
+		case TMDC_MODE_AT:
+
+			i = tmdc_byte_a[3];
+			input_report_abs(port->dev, ABS_HAT0X, tmdc_hat_to_axis[(data[i] - 141) / 25].x);
+			input_report_abs(port->dev, ABS_HAT0Y, tmdc_hat_to_axis[(data[i] - 141) / 25].y);
+			break;
+
+	}
+
+	for (k = l = 0; k < 4; k++) {
+		for (i = 0; i < port->btnc[k]; i++)
+			input_report_key(port->dev, port->btn[i + l],
+				((data[tmdc_byte_d[k]] >> (i + port->btno[k])) & 1));
+		l += port->btnc[k];
+	}
+
+	input_sync(port->dev);
+
+	return 0;
+}
+
 /*
  * tmdc_poll() reads and analyzes ThrustMaster joystick data.
  */
@@ -164,57 +242,21 @@
 {
 	unsigned char data[2][TMDC_MAX_LENGTH];
 	struct tmdc *tmdc = gameport_get_drvdata(gameport);
-	struct input_dev *dev;
 	unsigned char r, bad = 0;
-	int i, j, k, l;
+	int i;
 
 	tmdc->reads++;
 
 	if ((r = tmdc_read_packet(tmdc->gameport, data)) != tmdc->exists)
 		bad = 1;
-	else
+	else {
+		for (i = 0; i < 2; i++) {
+			if (r & (1 << i) & tmdc->exists) {
 
-	for (j = 0; j < 2; j++)
-		if (r & (1 << j) & tmdc->exists) {
-
-			if (data[j][TMDC_BYTE_ID] != tmdc->mode[j]) {
-				bad = 1;
-				continue;
+				if (tmdc_parse_packet(tmdc->port[i], data[i]))
+					bad = 1;
 			}
-
-			dev = tmdc->dev + j;
-
-			for (i = 0; i < tmdc->absc[j]; i++) {
-				if (tmdc->abs[j][i] < 0) continue;
-				input_report_abs(dev, tmdc->abs[j][i], data[j][tmdc_byte_a[i]]);
-			}
-
-			switch (tmdc->mode[j]) {
-
-				case TMDC_MODE_M3DI:
-
-					i = tmdc_byte_d[0];
-					input_report_abs(dev, ABS_HAT0X, ((data[j][i] >> 3) & 1) - ((data[j][i] >> 1) & 1));
-					input_report_abs(dev, ABS_HAT0Y, ((data[j][i] >> 2) & 1) - ( data[j][i]       & 1));
-					break;
-
-				case TMDC_MODE_AT:
-
-					i = tmdc_byte_a[3];
-					input_report_abs(dev, ABS_HAT0X, tmdc_hat_to_axis[(data[j][i] - 141) / 25].x);
-					input_report_abs(dev, ABS_HAT0Y, tmdc_hat_to_axis[(data[j][i] - 141) / 25].y);
-					break;
-
-			}
-
-			for (k = l = 0; k < 4; k++) {
-				for (i = 0; i < tmdc->btnc[j][k]; i++)
-					input_report_key(dev, tmdc->btn[j][i + l],
-						((data[j][tmdc_byte_d[k]] >> (i + tmdc->btno[j][k])) & 1));
-				l += tmdc->btnc[j][k];
-			}
-
-			input_sync(dev);
+		}
 	}
 
 	tmdc->bads += bad;
@@ -235,31 +277,89 @@
 	gameport_stop_polling(tmdc->gameport);
 }
 
+static int tmdc_setup_port(struct tmdc *tmdc, int idx, unsigned char *data)
+{
+	const struct tmdc_model *model;
+	struct tmdc_port *port;
+	struct input_dev *input_dev;
+	int i, j, b = 0;
+
+	tmdc->port[idx] = port = kzalloc(sizeof (struct tmdc_port), GFP_KERNEL);
+	input_dev = input_allocate_device();
+	if (!port || !input_dev) {
+		kfree(port);
+		input_free_device(input_dev);
+		return -ENOMEM;
+	}
+
+	port->mode = data[TMDC_BYTE_ID];
+
+	for (model = tmdc_models; model->id && model->id != port->mode; model++)
+		/* empty */;
+
+	port->abs = model->axes;
+	port->btn = model->buttons;
+
+	if (!model->id) {
+		port->absc = data[TMDC_BYTE_DEF] >> 4;
+		for (i = 0; i < 4; i++)
+			port->btnc[i] = i < (data[TMDC_BYTE_DEF] & 0xf) ? 8 : 0;
+	} else {
+		port->absc = model->abs;
+		for (i = 0; i < 4; i++)
+			port->btnc[i] = model->btnc[i];
+	}
+
+	for (i = 0; i < 4; i++)
+		port->btno[i] = model->btno[i];
+
+	snprintf(port->name, sizeof(port->name), model->name,
+		 port->absc, (data[TMDC_BYTE_DEF] & 0xf) << 3, port->mode);
+	snprintf(port->phys, sizeof(port->phys), "%s/input%d", tmdc->gameport->phys, i);
+
+	port->dev = input_dev;
+
+	input_dev->name = port->name;
+	input_dev->phys = port->phys;
+	input_dev->id.bustype = BUS_GAMEPORT;
+	input_dev->id.vendor = GAMEPORT_ID_VENDOR_THRUSTMASTER;
+	input_dev->id.product = model->id;
+	input_dev->id.version = 0x0100;
+	input_dev->cdev.dev = &tmdc->gameport->dev;
+	input_dev->private = tmdc;
+
+	input_dev->open = tmdc_open;
+	input_dev->close = tmdc_close;
+
+	input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
+
+	for (i = 0; i < port->absc && i < TMDC_ABS; i++)
+		if (port->abs[i] >= 0)
+			input_set_abs_params(input_dev, port->abs[i], 8, 248, 2, 4);
+
+	for (i = 0; i < model->hats && i < TMDC_ABS_HAT; i++)
+		input_set_abs_params(input_dev, tmdc_abs_hat[i], -1, 1, 0, 0);
+
+	for (i = 0; i < 4; i++) {
+		for (j = 0; j < port->btnc[i] && j < TMDC_BTN; j++)
+			set_bit(port->btn[j + b], input_dev->keybit);
+		b += port->btnc[i];
+	}
+
+	input_register_device(port->dev);
+
+	return 0;
+}
+
 /*
  * tmdc_probe() probes for ThrustMaster type joysticks.
  */
 
 static int tmdc_connect(struct gameport *gameport, struct gameport_driver *drv)
 {
-	static struct models {
-		unsigned char id;
-		char *name;
-		char abs;
-		char hats;
-		char btnc[4];
-		char btno[4];
-		signed char *axes;
-		short *buttons;
-	} models[] = {	{   1, "ThrustMaster Millenium 3D Inceptor",	  6, 2, { 4, 2 }, { 4, 6 }, tmdc_abs, tmdc_btn_joy },
-			{   3, "ThrustMaster Rage 3D Gamepad",		  2, 0, { 8, 2 }, { 0, 0 }, tmdc_abs, tmdc_btn_pad },
-			{   4, "ThrustMaster Attack Throttle",		  5, 2, { 4, 6 }, { 4, 2 }, tmdc_abs_at, tmdc_btn_at },
-			{   8, "ThrustMaster FragMaster",		  4, 0, { 8, 2 }, { 0, 0 }, tmdc_abs_fm, tmdc_btn_fm },
-			{ 163, "Thrustmaster Fusion GamePad",		  2, 0, { 8, 2 }, { 0, 0 }, tmdc_abs, tmdc_btn_pad },
-			{   0, "Unknown %d-axis, %d-button TM device %d", 0, 0, { 0, 0 }, { 0, 0 }, tmdc_abs, tmdc_btn_joy }};
-
 	unsigned char data[2][TMDC_MAX_LENGTH];
 	struct tmdc *tmdc;
-	int i, j, k, l, m;
+	int i;
 	int err;
 
 	if (!(tmdc = kzalloc(sizeof(struct tmdc), GFP_KERNEL)))
@@ -281,68 +381,25 @@
 	gameport_set_poll_handler(gameport, tmdc_poll);
 	gameport_set_poll_interval(gameport, 20);
 
-	for (j = 0; j < 2; j++)
-		if (tmdc->exists & (1 << j)) {
+	for (i = 0; i < 2; i++) {
+		if (tmdc->exists & (1 << i)) {
 
-			tmdc->mode[j] = data[j][TMDC_BYTE_ID];
-
-			for (m = 0; models[m].id && models[m].id != tmdc->mode[j]; m++);
-
-			tmdc->abs[j] = models[m].axes;
-			tmdc->btn[j] = models[m].buttons;
-
-			if (!models[m].id) {
-				models[m].abs = data[j][TMDC_BYTE_DEF] >> 4;
-				for (k = 0; k < 4; k++)
-					models[m].btnc[k] = k < (data[j][TMDC_BYTE_DEF] & 0xf) ? 8 : 0;
-			}
-
-			tmdc->absc[j] = models[m].abs;
-			for (k = 0; k < 4; k++) {
-				tmdc->btnc[j][k] = models[m].btnc[k];
-				tmdc->btno[j][k] = models[m].btno[k];
-			}
-
-			sprintf(tmdc->name[j], models[m].name, models[m].abs,
-				(data[j][TMDC_BYTE_DEF] & 0xf) << 3, tmdc->mode[j]);
-
-			sprintf(tmdc->phys[j], "%s/input%d", gameport->phys, j);
-
-			tmdc->dev[j].private = tmdc;
-			tmdc->dev[j].open = tmdc_open;
-			tmdc->dev[j].close = tmdc_close;
-
-			tmdc->dev[j].name = tmdc->name[j];
-			tmdc->dev[j].phys = tmdc->phys[j];
-			tmdc->dev[j].id.bustype = BUS_GAMEPORT;
-			tmdc->dev[j].id.vendor = GAMEPORT_ID_VENDOR_THRUSTMASTER;
-			tmdc->dev[j].id.product = models[m].id;
-			tmdc->dev[j].id.version = 0x0100;
-
-			tmdc->dev[j].evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
-
-			for (i = 0; i < models[m].abs && i < TMDC_ABS; i++)
-				if (tmdc->abs[j][i] >= 0)
-					input_set_abs_params(&tmdc->dev[j], tmdc->abs[j][i], 8, 248, 2, 4);
-
-			for (i = 0; i < models[m].hats && i < TMDC_ABS_HAT; i++)
-				input_set_abs_params(&tmdc->dev[j], tmdc_abs_hat[i], -1, 1, 0, 0);
-
-
-			for (k = l = 0; k < 4; k++) {
-				for (i = 0; i < models[m].btnc[k] && i < TMDC_BTN; i++)
-					set_bit(tmdc->btn[j][i + l], tmdc->dev[j].keybit);
-				l += models[m].btnc[k];
-			}
-
-			input_register_device(tmdc->dev + j);
-			printk(KERN_INFO "input: %s on %s\n", tmdc->name[j], gameport->phys);
+			err = tmdc_setup_port(tmdc, i, data[i]);
+			if (err)
+				goto fail3;
 		}
+	}
 
 	return 0;
 
-fail2:	gameport_close(gameport);
-fail1:	gameport_set_drvdata(gameport, NULL);
+ fail3: while (--i >= 0) {
+		if (tmdc->port[i]) {
+			input_unregister_device(tmdc->port[i]->dev);
+			kfree(tmdc->port[i]);
+		}
+	}
+ fail2:	gameport_close(gameport);
+ fail1:	gameport_set_drvdata(gameport, NULL);
 	kfree(tmdc);
 	return err;
 }
@@ -352,9 +409,12 @@
 	struct tmdc *tmdc = gameport_get_drvdata(gameport);
 	int i;
 
-	for (i = 0; i < 2; i++)
-		if (tmdc->exists & (1 << i))
-			input_unregister_device(tmdc->dev + i);
+	for (i = 0; i < 2; i++) {
+		if (tmdc->port[i]) {
+			input_unregister_device(tmdc->port[i]->dev);
+			kfree(tmdc->port[i]);
+		}
+	}
 	gameport_close(gameport);
 	gameport_set_drvdata(gameport, NULL);
 	kfree(tmdc);
diff --git a/drivers/input/joystick/turbografx.c b/drivers/input/joystick/turbografx.c
index 0c5b9c8..7e97649 100644
--- a/drivers/input/joystick/turbografx.c
+++ b/drivers/input/joystick/turbografx.c
@@ -42,19 +42,21 @@
 MODULE_DESCRIPTION("TurboGraFX parallel port interface driver");
 MODULE_LICENSE("GPL");
 
-static int tgfx[] __initdata = { -1, 0, 0, 0, 0, 0, 0, 0 };
-static int tgfx_nargs __initdata = 0;
-module_param_array_named(map, tgfx, int, &tgfx_nargs, 0);
+#define TGFX_MAX_PORTS		3
+#define TGFX_MAX_DEVICES	7
+
+struct tgfx_config {
+	int args[TGFX_MAX_DEVICES + 1];
+	int nargs;
+};
+
+static struct tgfx_config tgfx[TGFX_MAX_PORTS] __initdata;
+
+module_param_array_named(map, tgfx[0].args, int, &tgfx[0].nargs, 0);
 MODULE_PARM_DESC(map, "Describes first set of devices (<parport#>,<js1>,<js2>,..<js7>");
-
-static int tgfx_2[] __initdata = { -1, 0, 0, 0, 0, 0, 0, 0 };
-static int tgfx_nargs_2 __initdata = 0;
-module_param_array_named(map2, tgfx_2, int, &tgfx_nargs_2, 0);
+module_param_array_named(map2, tgfx[1].args, int, &tgfx[1].nargs, 0);
 MODULE_PARM_DESC(map2, "Describes second set of devices");
-
-static int tgfx_3[] __initdata = { -1, 0, 0, 0, 0, 0, 0, 0 };
-static int tgfx_nargs_3 __initdata = 0;
-module_param_array_named(map3, tgfx_3, int, &tgfx_nargs_3, 0);
+module_param_array_named(map3, tgfx[2].args, int, &tgfx[2].nargs, 0);
 MODULE_PARM_DESC(map3, "Describes third set of devices");
 
 __obsolete_setup("tgfx=");
@@ -75,17 +77,17 @@
 #define TGFX_TOP2		0x08
 
 static int tgfx_buttons[] = { BTN_TRIGGER, BTN_THUMB, BTN_THUMB2, BTN_TOP, BTN_TOP2 };
-static char *tgfx_name = "TurboGraFX Multisystem joystick";
 
 static struct tgfx {
 	struct pardevice *pd;
 	struct timer_list timer;
-	struct input_dev dev[7];
-	char phys[7][32];
+	struct input_dev *dev[TGFX_MAX_DEVICES];
+	char name[TGFX_MAX_DEVICES][64];
+	char phys[TGFX_MAX_DEVICES][32];
 	int sticks;
 	int used;
 	struct semaphore sem;
-} *tgfx_base[3];
+} *tgfx_base[TGFX_MAX_PORTS];
 
 /*
  * tgfx_timer() reads and analyzes TurboGraFX joystick data.
@@ -100,7 +102,7 @@
 	for (i = 0; i < 7; i++)
 		if (tgfx->sticks & (1 << i)) {
 
-			dev = tgfx->dev + i;
+			dev = tgfx->dev[i];
 
 			parport_write_data(tgfx->pd->port, ~(1 << i));
 			data1 = parport_read_status(tgfx->pd->port) ^ 0x7f;
@@ -153,118 +155,165 @@
 	up(&tgfx->sem);
 }
 
+
+
 /*
  * tgfx_probe() probes for tg gamepads.
  */
 
-static struct tgfx __init *tgfx_probe(int *config, int nargs)
+static struct tgfx __init *tgfx_probe(int parport, int *n_buttons, int n_devs)
 {
 	struct tgfx *tgfx;
+	struct input_dev *input_dev;
 	struct parport *pp;
+	struct pardevice *pd;
 	int i, j;
+	int err;
 
-	if (config[0] < 0)
-		return NULL;
-
-	if (nargs < 2) {
-		printk(KERN_ERR "turbografx.c: at least one joystick must be specified\n");
-		return NULL;
-	}
-
-	pp = parport_find_number(config[0]);
-
+	pp = parport_find_number(parport);
 	if (!pp) {
 		printk(KERN_ERR "turbografx.c: no such parport\n");
-		return NULL;
+		err = -EINVAL;
+		goto err_out;
 	}
 
-	if (!(tgfx = kzalloc(sizeof(struct tgfx), GFP_KERNEL))) {
-		parport_put_port(pp);
-		return NULL;
+	pd = parport_register_device(pp, "turbografx", NULL, NULL, NULL, PARPORT_DEV_EXCL, NULL);
+	if (!pd) {
+		printk(KERN_ERR "turbografx.c: parport busy already - lp.o loaded?\n");
+		err = -EBUSY;
+		goto err_put_pp;
+	}
+
+	tgfx = kzalloc(sizeof(struct tgfx), GFP_KERNEL);
+	if (!tgfx) {
+		printk(KERN_ERR "turbografx.c: Not enough memory\n");
+		err = -ENOMEM;
+		goto err_unreg_pardev;
 	}
 
 	init_MUTEX(&tgfx->sem);
-
-	tgfx->pd = parport_register_device(pp, "turbografx", NULL, NULL, NULL, PARPORT_DEV_EXCL, NULL);
-
-	parport_put_port(pp);
-
-	if (!tgfx->pd) {
-		printk(KERN_ERR "turbografx.c: parport busy already - lp.o loaded?\n");
-		kfree(tgfx);
-		return NULL;
-	}
-
+	tgfx->pd = pd;
 	init_timer(&tgfx->timer);
 	tgfx->timer.data = (long) tgfx;
 	tgfx->timer.function = tgfx_timer;
 
-	tgfx->sticks = 0;
+	for (i = 0; i < n_devs; i++) {
+		if (n_buttons[i] < 1)
+			continue;
 
-	for (i = 0; i < nargs - 1; i++)
-		if (config[i+1] > 0 && config[i+1] < 6) {
-
-			tgfx->sticks |= (1 << i);
-
-			tgfx->dev[i].private = tgfx;
-			tgfx->dev[i].open = tgfx_open;
-			tgfx->dev[i].close = tgfx_close;
-
-			sprintf(tgfx->phys[i], "%s/input0", tgfx->pd->port->name);
-
-			tgfx->dev[i].name = tgfx_name;
-			tgfx->dev[i].phys = tgfx->phys[i];
-			tgfx->dev[i].id.bustype = BUS_PARPORT;
-			tgfx->dev[i].id.vendor = 0x0003;
-			tgfx->dev[i].id.product = config[i+1];
-			tgfx->dev[i].id.version = 0x0100;
-
-			tgfx->dev[i].evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
-			tgfx->dev[i].absbit[0] = BIT(ABS_X) | BIT(ABS_Y);
-
-			for (j = 0; j < config[i+1]; j++)
-				set_bit(tgfx_buttons[j], tgfx->dev[i].keybit);
-
-			tgfx->dev[i].absmin[ABS_X] = -1; tgfx->dev[i].absmax[ABS_X] = 1;
-			tgfx->dev[i].absmin[ABS_Y] = -1; tgfx->dev[i].absmax[ABS_Y] = 1;
-
-			input_register_device(tgfx->dev + i);
-			printk(KERN_INFO "input: %d-button Multisystem joystick on %s\n",
-				config[i+1], tgfx->pd->port->name);
+		if (n_buttons[i] > 6) {
+			printk(KERN_ERR "turbografx.c: Invalid number of buttons %d\n", n_buttons[i]);
+			err = -EINVAL;
+			goto err_free_devs;
 		}
 
+		tgfx->dev[i] = input_dev = input_allocate_device();
+		if (!input_dev) {
+			printk(KERN_ERR "turbografx.c: Not enough memory for input device\n");
+			err = -ENOMEM;
+			goto err_free_devs;
+		}
+
+		tgfx->sticks |= (1 << i);
+		snprintf(tgfx->name[i], sizeof(tgfx->name[i]),
+			 "TurboGraFX %d-button Multisystem joystick", n_buttons[i]);
+		snprintf(tgfx->phys[i], sizeof(tgfx->phys[i]),
+			 "%s/input%d", tgfx->pd->port->name, i);
+
+		input_dev->name = tgfx->name[i];
+		input_dev->phys = tgfx->phys[i];
+		input_dev->id.bustype = BUS_PARPORT;
+		input_dev->id.vendor = 0x0003;
+		input_dev->id.product = n_buttons[i];
+		input_dev->id.version = 0x0100;
+
+		input_dev->private = tgfx;
+		input_dev->open = tgfx_open;
+		input_dev->close = tgfx_close;
+
+		input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
+		input_set_abs_params(input_dev, ABS_X, -1, 1, 0, 0);
+		input_set_abs_params(input_dev, ABS_Y, -1, 1, 0, 0);
+
+		for (j = 0; j < n_buttons[i]; j++)
+			set_bit(tgfx_buttons[j], input_dev->keybit);
+
+		input_register_device(tgfx->dev[i]);
+	}
+
         if (!tgfx->sticks) {
-		parport_unregister_device(tgfx->pd);
-		kfree(tgfx);
-		return NULL;
+		printk(KERN_ERR "turbografx.c: No valid devices specified\n");
+		err = -EINVAL;
+		goto err_free_tgfx;
         }
 
 	return tgfx;
+
+ err_free_devs:
+	while (--i >= 0)
+		input_unregister_device(tgfx->dev[i]);
+ err_free_tgfx:
+	kfree(tgfx);
+ err_unreg_pardev:
+	parport_unregister_device(pd);
+ err_put_pp:
+	parport_put_port(pp);
+ err_out:
+	return ERR_PTR(err);
+}
+
+static void __exit tgfx_remove(struct tgfx *tgfx)
+{
+	int i;
+
+	for (i = 0; i < TGFX_MAX_DEVICES; i++)
+		if (tgfx->dev[i])
+			input_unregister_device(tgfx->dev[i]);
+	parport_unregister_device(tgfx->pd);
+	kfree(tgfx);
 }
 
 static int __init tgfx_init(void)
 {
-	tgfx_base[0] = tgfx_probe(tgfx, tgfx_nargs);
-	tgfx_base[1] = tgfx_probe(tgfx_2, tgfx_nargs_2);
-	tgfx_base[2] = tgfx_probe(tgfx_3, tgfx_nargs_3);
+	int i;
+	int have_dev = 0;
+	int err = 0;
 
-	if (tgfx_base[0] || tgfx_base[1] || tgfx_base[2])
-		return 0;
+	for (i = 0; i < TGFX_MAX_PORTS; i++) {
+		if (tgfx[i].nargs == 0 || tgfx[i].args[0] < 0)
+			continue;
 
-	return -ENODEV;
+		if (tgfx[i].nargs < 2) {
+			printk(KERN_ERR "turbografx.c: at least one joystick must be specified\n");
+			err = -EINVAL;
+			break;
+		}
+
+		tgfx_base[i] = tgfx_probe(tgfx[i].args[0], tgfx[i].args + 1, tgfx[i].nargs - 1);
+		if (IS_ERR(tgfx_base[i])) {
+			err = PTR_ERR(tgfx_base[i]);
+			break;
+		}
+
+		have_dev = 1;
+	}
+
+	if (err) {
+		while (--i >= 0)
+			tgfx_remove(tgfx_base[i]);
+		return err;
+	}
+
+	return have_dev ? 0 : -ENODEV;
 }
 
 static void __exit tgfx_exit(void)
 {
-	int i, j;
+	int i;
 
-	for (i = 0; i < 3; i++)
-		if (tgfx_base[i]) {
-			for (j = 0; j < 7; j++)
-				if (tgfx_base[i]->sticks & (1 << j))
-					input_unregister_device(tgfx_base[i]->dev + j);
-		parport_unregister_device(tgfx_base[i]->pd);
-	}
+	for (i = 0; i < TGFX_MAX_PORTS; i++)
+		if (tgfx_base[i])
+			tgfx_remove(tgfx_base[i]);
 }
 
 module_init(tgfx_init);
diff --git a/drivers/input/joystick/twidjoy.c b/drivers/input/joystick/twidjoy.c
index 0379bc1..cd3a1e7 100644
--- a/drivers/input/joystick/twidjoy.c
+++ b/drivers/input/joystick/twidjoy.c
@@ -69,8 +69,6 @@
 
 #define TWIDJOY_MAX_LENGTH 5
 
-static char *twidjoy_name = "Handykey Twiddler";
-
 static struct twidjoy_button_spec {
 	int bitshift;
 	int bitmask;
@@ -95,7 +93,7 @@
  */
 
 struct twidjoy {
-	struct input_dev dev;
+	struct input_dev *dev;
 	int idx;
 	unsigned char data[TWIDJOY_MAX_LENGTH];
 	char phys[32];
@@ -108,37 +106,33 @@
 
 static void twidjoy_process_packet(struct twidjoy *twidjoy, struct pt_regs *regs)
 {
-	if (twidjoy->idx == TWIDJOY_MAX_LENGTH) {
-		struct input_dev *dev = &twidjoy->dev;
-		unsigned char *data = twidjoy->data;
-		struct twidjoy_button_spec *bp;
-		int button_bits, abs_x, abs_y;
+	struct input_dev *dev = twidjoy->dev;
+	unsigned char *data = twidjoy->data;
+	struct twidjoy_button_spec *bp;
+	int button_bits, abs_x, abs_y;
 
-		button_bits = ((data[1] & 0x7f) << 7) | (data[0] & 0x7f);
+	button_bits = ((data[1] & 0x7f) << 7) | (data[0] & 0x7f);
 
-		input_regs(dev, regs);
+	input_regs(dev, regs);
 
-		for (bp = twidjoy_buttons; bp->bitmask; bp++) {
-			int value = (button_bits & (bp->bitmask << bp->bitshift)) >> bp->bitshift;
-			int i;
+	for (bp = twidjoy_buttons; bp->bitmask; bp++) {
+		int value = (button_bits & (bp->bitmask << bp->bitshift)) >> bp->bitshift;
+		int i;
 
-			for (i = 0; i < bp->bitmask; i++)
-				input_report_key(dev, bp->buttons[i], i+1 == value);
-		}
-
-		abs_x = ((data[4] & 0x07) << 5) | ((data[3] & 0x7C) >> 2);
-		if (data[4] & 0x08) abs_x -= 256;
-
-		abs_y = ((data[3] & 0x01) << 7) | ((data[2] & 0x7F) >> 0);
-		if (data[3] & 0x02) abs_y -= 256;
-
-		input_report_abs(dev, ABS_X, -abs_x);
-		input_report_abs(dev, ABS_Y, +abs_y);
-
-		input_sync(dev);
+		for (i = 0; i < bp->bitmask; i++)
+			input_report_key(dev, bp->buttons[i], i+1 == value);
 	}
 
-	return;
+	abs_x = ((data[4] & 0x07) << 5) | ((data[3] & 0x7C) >> 2);
+	if (data[4] & 0x08) abs_x -= 256;
+
+	abs_y = ((data[3] & 0x01) << 7) | ((data[2] & 0x7F) >> 0);
+	if (data[3] & 0x02) abs_y -= 256;
+
+	input_report_abs(dev, ABS_X, -abs_x);
+	input_report_abs(dev, ABS_Y, +abs_y);
+
+	input_sync(dev);
 }
 
 /*
@@ -179,9 +173,9 @@
 {
 	struct twidjoy *twidjoy = serio_get_drvdata(serio);
 
-	input_unregister_device(&twidjoy->dev);
 	serio_close(serio);
 	serio_set_drvdata(serio, NULL);
+	input_unregister_device(twidjoy->dev);
 	kfree(twidjoy);
 }
 
@@ -195,59 +189,49 @@
 {
 	struct twidjoy_button_spec *bp;
 	struct twidjoy *twidjoy;
+	struct input_dev *input_dev;
+	int err = -ENOMEM;
 	int i;
-	int err;
 
-	if (!(twidjoy = kmalloc(sizeof(struct twidjoy), GFP_KERNEL)))
-		return -ENOMEM;
+	twidjoy = kzalloc(sizeof(struct twidjoy), GFP_KERNEL);
+	input_dev = input_allocate_device();
+	if (!twidjoy || !input_dev)
+		goto fail;
 
-	memset(twidjoy, 0, sizeof(struct twidjoy));
-
+	twidjoy->dev = input_dev;
 	sprintf(twidjoy->phys, "%s/input0", serio->phys);
 
-	init_input_dev(&twidjoy->dev);
-	twidjoy->dev.name = twidjoy_name;
-	twidjoy->dev.phys = twidjoy->phys;
-	twidjoy->dev.id.bustype = BUS_RS232;
-	twidjoy->dev.id.vendor = SERIO_TWIDJOY;
-	twidjoy->dev.id.product = 0x0001;
-	twidjoy->dev.id.version = 0x0100;
-	twidjoy->dev.dev = &serio->dev;
+	input_dev->name = "Handykey Twiddler";
+	input_dev->phys = twidjoy->phys;
+	input_dev->id.bustype = BUS_RS232;
+	input_dev->id.vendor = SERIO_TWIDJOY;
+	input_dev->id.product = 0x0001;
+	input_dev->id.version = 0x0100;
+	input_dev->cdev.dev = &serio->dev;
+	input_dev->private = twidjoy;
 
-	twidjoy->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
+	input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
+	input_dev->absbit[0] = BIT(ABS_X) | BIT(ABS_Y);
+	input_set_abs_params(input_dev, ABS_X, -50, 50, 4, 4);
+	input_set_abs_params(input_dev, ABS_Y, -50, 50, 4, 4);
 
-	for (bp = twidjoy_buttons; bp->bitmask; bp++) {
+	for (bp = twidjoy_buttons; bp->bitmask; bp++)
 		for (i = 0; i < bp->bitmask; i++)
-			set_bit(bp->buttons[i], twidjoy->dev.keybit);
-	}
-
-	twidjoy->dev.absbit[0] = BIT(ABS_X) | BIT(ABS_Y);
-
-	for (i = 0; i < 2; i++) {
-		twidjoy->dev.absmax[ABS_X+i] =  50;
-		twidjoy->dev.absmin[ABS_X+i] = -50;
-
-		/* TODO: arndt 20010708: Are these values appropriate? */
-		twidjoy->dev.absfuzz[ABS_X+i] = 4;
-		twidjoy->dev.absflat[ABS_X+i] = 4;
-	}
-
-	twidjoy->dev.private = twidjoy;
+			set_bit(bp->buttons[i], input_dev->keybit);
 
 	serio_set_drvdata(serio, twidjoy);
 
 	err = serio_open(serio, drv);
-	if (err) {
-		serio_set_drvdata(serio, NULL);
-		kfree(twidjoy);
-		return err;
-	}
+	if (err)
+		goto fail;
 
-	input_register_device(&twidjoy->dev);
-
-	printk(KERN_INFO "input: %s on %s\n", twidjoy_name, serio->phys);
-
+	input_register_device(twidjoy->dev);
 	return 0;
+
+ fail:	serio_set_drvdata(serio, NULL);
+	input_free_device(input_dev);
+	kfree(twidjoy);
+	return err;
 }
 
 /*
diff --git a/drivers/input/joystick/warrior.c b/drivers/input/joystick/warrior.c
index 6976a21..99a642d 100644
--- a/drivers/input/joystick/warrior.c
+++ b/drivers/input/joystick/warrior.c
@@ -47,14 +47,13 @@
 
 #define WARRIOR_MAX_LENGTH	16
 static char warrior_lengths[] = { 0, 4, 12, 3, 4, 4, 0, 0 };
-static char *warrior_name = "Logitech WingMan Warrior";
 
 /*
  * Per-Warrior data.
  */
 
 struct warrior {
-	struct input_dev dev;
+	struct input_dev *dev;
 	int idx, len;
 	unsigned char data[WARRIOR_MAX_LENGTH];
 	char phys[32];
@@ -67,7 +66,7 @@
 
 static void warrior_process_packet(struct warrior *warrior, struct pt_regs *regs)
 {
-	struct input_dev *dev = &warrior->dev;
+	struct input_dev *dev = warrior->dev;
 	unsigned char *data = warrior->data;
 
 	if (!warrior->idx) return;
@@ -131,9 +130,9 @@
 {
 	struct warrior *warrior = serio_get_drvdata(serio);
 
-	input_unregister_device(&warrior->dev);
 	serio_close(serio);
 	serio_set_drvdata(serio, NULL);
+	input_unregister_device(warrior->dev);
 	kfree(warrior);
 }
 
@@ -146,60 +145,48 @@
 static int warrior_connect(struct serio *serio, struct serio_driver *drv)
 {
 	struct warrior *warrior;
-	int i;
-	int err;
+	struct input_dev *input_dev;
+	int err = -ENOMEM;
 
-	if (!(warrior = kmalloc(sizeof(struct warrior), GFP_KERNEL)))
-		return -ENOMEM;
+	warrior = kzalloc(sizeof(struct warrior), GFP_KERNEL);
+	input_dev = input_allocate_device();
+	if (!warrior || !input_dev)
+		goto fail;
 
-	memset(warrior, 0, sizeof(struct warrior));
-
-	warrior->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_REL) | BIT(EV_ABS);
-	warrior->dev.keybit[LONG(BTN_TRIGGER)] = BIT(BTN_TRIGGER) | BIT(BTN_THUMB) | BIT(BTN_TOP) | BIT(BTN_TOP2);
-	warrior->dev.relbit[0] = BIT(REL_DIAL);
-	warrior->dev.absbit[0] = BIT(ABS_X) | BIT(ABS_Y) | BIT(ABS_THROTTLE) | BIT(ABS_HAT0X) | BIT(ABS_HAT0Y);
-
+	warrior->dev = input_dev;
 	sprintf(warrior->phys, "%s/input0", serio->phys);
 
-	init_input_dev(&warrior->dev);
-	warrior->dev.name = warrior_name;
-	warrior->dev.phys = warrior->phys;
-	warrior->dev.id.bustype = BUS_RS232;
-	warrior->dev.id.vendor = SERIO_WARRIOR;
-	warrior->dev.id.product = 0x0001;
-	warrior->dev.id.version = 0x0100;
-	warrior->dev.dev = &serio->dev;
+	input_dev->name = "Logitech WingMan Warrior";
+	input_dev->phys = warrior->phys;
+	input_dev->id.bustype = BUS_RS232;
+	input_dev->id.vendor = SERIO_WARRIOR;
+	input_dev->id.product = 0x0001;
+	input_dev->id.version = 0x0100;
+	input_dev->cdev.dev = &serio->dev;
+	input_dev->private = warrior;
 
-	for (i = 0; i < 2; i++) {
-		warrior->dev.absmax[ABS_X+i] = -64;
-		warrior->dev.absmin[ABS_X+i] =  64;
-		warrior->dev.absflat[ABS_X+i] = 8;
-	}
-
-	warrior->dev.absmax[ABS_THROTTLE] = -112;
-	warrior->dev.absmin[ABS_THROTTLE] =  112;
-
-	for (i = 0; i < 2; i++) {
-		warrior->dev.absmax[ABS_HAT0X+i] = -1;
-		warrior->dev.absmin[ABS_HAT0X+i] =  1;
-	}
-
-	warrior->dev.private = warrior;
+	input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REL) | BIT(EV_ABS);
+	input_dev->keybit[LONG(BTN_TRIGGER)] = BIT(BTN_TRIGGER) | BIT(BTN_THUMB) | BIT(BTN_TOP) | BIT(BTN_TOP2);
+	input_dev->relbit[0] = BIT(REL_DIAL);
+	input_set_abs_params(input_dev, ABS_X, -64, 64, 0, 8);
+	input_set_abs_params(input_dev, ABS_Y, -64, 64, 0, 8);
+	input_set_abs_params(input_dev, ABS_THROTTLE, -112, 112, 0, 0);
+	input_set_abs_params(input_dev, ABS_HAT0X, -1, 1, 0, 0);
+	input_set_abs_params(input_dev, ABS_HAT0X, -1, 1, 0, 0);
 
 	serio_set_drvdata(serio, warrior);
 
 	err = serio_open(serio, drv);
-	if (err) {
-		serio_set_drvdata(serio, NULL);
-		kfree(warrior);
-		return err;
-	}
+	if (err)
+		goto fail;
 
-	input_register_device(&warrior->dev);
-
-	printk(KERN_INFO "input: Logitech WingMan Warrior on %s\n", serio->phys);
-
+	input_register_device(warrior->dev);
 	return 0;
+
+ fail:	serio_set_drvdata(serio, NULL);
+	input_free_device(input_dev);
+	kfree(warrior);
+	return err;
 }
 
 /*
diff --git a/drivers/input/keyboard/amikbd.c b/drivers/input/keyboard/amikbd.c
index 4e8e8ea..3d63bc1 100644
--- a/drivers/input/keyboard/amikbd.c
+++ b/drivers/input/keyboard/amikbd.c
@@ -155,10 +155,7 @@
 	[7] = KERN_WARNING "amikbd: keyboard interrupt\n"
 };
 
-static struct input_dev amikbd_dev;
-
-static char *amikbd_name = "Amiga keyboard";
-static char *amikbd_phys = "amikbd/input0";
+static struct input_dev *amikbd_dev;
 
 static irqreturn_t amikbd_interrupt(int irq, void *dummy, struct pt_regs *fp)
 {
@@ -176,16 +173,16 @@
 
 		scancode = amikbd_keycode[scancode];
 
-		input_regs(&amikbd_dev, fp);
+		input_regs(amikbd_dev, fp);
 
 		if (scancode == KEY_CAPSLOCK) {	/* CapsLock is a toggle switch key on Amiga */
-			input_report_key(&amikbd_dev, scancode, 1);
-			input_report_key(&amikbd_dev, scancode, 0);
-			input_sync(&amikbd_dev);
+			input_report_key(amikbd_dev, scancode, 1);
+			input_report_key(amikbd_dev, scancode, 0);
 		} else {
-			input_report_key(&amikbd_dev, scancode, down);
-			input_sync(&amikbd_dev);
+			input_report_key(amikbd_dev, scancode, down);
 		}
+
+		input_sync(amikbd_dev);
 	} else				/* scancodes >= 0x78 are error codes */
 		printk(amikbd_messages[scancode - 0x78]);
 
@@ -202,39 +199,41 @@
 	if (!request_mem_region(CIAA_PHYSADDR-1+0xb00, 0x100, "amikeyb"))
 		return -EBUSY;
 
-	init_input_dev(&amikbd_dev);
+	amikbd_dev = input_dev_allocate();
+	if (!amikbd_dev) {
+		printk(KERN_ERR "amikbd: not enough memory for input device\n");
+		release_mem_region(CIAA_PHYSADDR - 1 + 0xb00, 0x100);
+		return -ENOMEM;
+	}
 
-	amikbd_dev.evbit[0] = BIT(EV_KEY) | BIT(EV_REP);
-	amikbd_dev.keycode = amikbd_keycode;
-	amikbd_dev.keycodesize = sizeof(unsigned char);
-	amikbd_dev.keycodemax = ARRAY_SIZE(amikbd_keycode);
+	amikbd_dev->name = "Amiga Keyboard";
+	amikbd_dev->phys = "amikbd/input0";
+	amikbd_dev->id.bustype = BUS_AMIGA;
+	amikbd_dev->id.vendor = 0x0001;
+	amikbd_dev->id.product = 0x0001;
+	amikbd_dev->id.version = 0x0100;
+
+	amikbd_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REP);
+	amikbd_dev->keycode = amikbd_keycode;
+	amikbd_dev->keycodesize = sizeof(unsigned char);
+	amikbd_dev->keycodemax = ARRAY_SIZE(amikbd_keycode);
 
 	for (i = 0; i < 0x78; i++)
 		if (amikbd_keycode[i])
-			set_bit(amikbd_keycode[i], amikbd_dev.keybit);
+			set_bit(amikbd_keycode[i], amikbd_dev->keybit);
 
 	ciaa.cra &= ~0x41;	 /* serial data in, turn off TA */
 	request_irq(IRQ_AMIGA_CIAA_SP, amikbd_interrupt, 0, "amikbd", amikbd_interrupt);
 
-	amikbd_dev.name = amikbd_name;
-	amikbd_dev.phys = amikbd_phys;
-	amikbd_dev.id.bustype = BUS_AMIGA;
-	amikbd_dev.id.vendor = 0x0001;
-	amikbd_dev.id.product = 0x0001;
-	amikbd_dev.id.version = 0x0100;
-
-	input_register_device(&amikbd_dev);
-
-	printk(KERN_INFO "input: %s\n", amikbd_name);
-
+	input_register_device(amikbd_dev);
 	return 0;
 }
 
 static void __exit amikbd_exit(void)
 {
-	input_unregister_device(&amikbd_dev);
 	free_irq(IRQ_AMIGA_CIAA_SP, amikbd_interrupt);
-	release_mem_region(CIAA_PHYSADDR-1+0xb00, 0x100);
+	input_unregister_device(amikbd_dev);
+	release_mem_region(CIAA_PHYSADDR - 1 + 0xb00, 0x100);
 }
 
 module_init(amikbd_init);
diff --git a/drivers/input/keyboard/atkbd.c b/drivers/input/keyboard/atkbd.c
index 1ad8c2e..820c7fd 100644
--- a/drivers/input/keyboard/atkbd.c
+++ b/drivers/input/keyboard/atkbd.c
@@ -185,12 +185,12 @@
 
 struct atkbd {
 
-	struct ps2dev	ps2dev;
+	struct ps2dev ps2dev;
+	struct input_dev *dev;
 
 	/* Written only during init */
 	char name[64];
 	char phys[32];
-	struct input_dev dev;
 
 	unsigned short id;
 	unsigned char keycode[512];
@@ -290,7 +290,7 @@
 	if (!atkbd->enabled)
 		goto out;
 
-	input_event(&atkbd->dev, EV_MSC, MSC_RAW, code);
+	input_event(atkbd->dev, EV_MSC, MSC_RAW, code);
 
 	if (atkbd->translated) {
 
@@ -326,10 +326,10 @@
 			atkbd->release = 1;
 			goto out;
 		case ATKBD_RET_HANGUEL:
-			atkbd_report_key(&atkbd->dev, regs, KEY_HANGUEL, 3);
+			atkbd_report_key(atkbd->dev, regs, KEY_HANGUEL, 3);
 			goto out;
 		case ATKBD_RET_HANJA:
-			atkbd_report_key(&atkbd->dev, regs, KEY_HANJA, 3);
+			atkbd_report_key(atkbd->dev, regs, KEY_HANJA, 3);
 			goto out;
 		case ATKBD_RET_ERR:
 			printk(KERN_DEBUG "atkbd.c: Keyboard on %s reports too many keys pressed.\n", serio->phys);
@@ -345,7 +345,7 @@
 	}
 
 	if (atkbd->keycode[code] != ATKBD_KEY_NULL)
-		input_event(&atkbd->dev, EV_MSC, MSC_SCAN, code);
+		input_event(atkbd->dev, EV_MSC, MSC_SCAN, code);
 
 	switch (atkbd->keycode[code]) {
 		case ATKBD_KEY_NULL:
@@ -365,7 +365,7 @@
 				       "to make it known.\n",
 				       code & 0x80 ? "e0" : "", code & 0x7f);
 			}
-			input_sync(&atkbd->dev);
+			input_sync(atkbd->dev);
 			break;
 		case ATKBD_SCR_1:
 			scroll = 1 - atkbd->release * 2;
@@ -390,7 +390,7 @@
 			break;
 		default:
 			value = atkbd->release ? 0 :
-				(1 + (!atkbd->softrepeat && test_bit(atkbd->keycode[code], atkbd->dev.key)));
+				(1 + (!atkbd->softrepeat && test_bit(atkbd->keycode[code], atkbd->dev->key)));
 
 			switch (value) {	/* Workaround Toshiba laptop multiple keypress */
 				case 0:
@@ -398,7 +398,7 @@
 					break;
 				case 1:
 					atkbd->last = code;
-					atkbd->time = jiffies + msecs_to_jiffies(atkbd->dev.rep[REP_DELAY]) / 2;
+					atkbd->time = jiffies + msecs_to_jiffies(atkbd->dev->rep[REP_DELAY]) / 2;
 					break;
 				case 2:
 					if (!time_after(jiffies, atkbd->time) && atkbd->last == code)
@@ -406,16 +406,16 @@
 					break;
 			}
 
-			atkbd_report_key(&atkbd->dev, regs, atkbd->keycode[code], value);
+			atkbd_report_key(atkbd->dev, regs, atkbd->keycode[code], value);
 	}
 
 	if (atkbd->scroll) {
-		input_regs(&atkbd->dev, regs);
+		input_regs(atkbd->dev, regs);
 		if (click != -1)
-			input_report_key(&atkbd->dev, BTN_MIDDLE, click);
-		input_report_rel(&atkbd->dev, REL_WHEEL, scroll);
-		input_report_rel(&atkbd->dev, REL_HWHEEL, hscroll);
-		input_sync(&atkbd->dev);
+			input_report_key(atkbd->dev, BTN_MIDDLE, click);
+		input_report_rel(atkbd->dev, REL_WHEEL, scroll);
+		input_report_rel(atkbd->dev, REL_HWHEEL, hscroll);
+		input_sync(atkbd->dev);
 	}
 
 	atkbd->release = 0;
@@ -463,7 +463,6 @@
 
 			return 0;
 
-
 		case EV_REP:
 
 			if (atkbd->softrepeat) return 0;
@@ -693,7 +692,7 @@
 	device_remove_file(&serio->dev, &atkbd_attr_softrepeat);
 	device_remove_file(&serio->dev, &atkbd_attr_softraw);
 
-	input_unregister_device(&atkbd->dev);
+	input_unregister_device(atkbd->dev);
 	serio_close(serio);
 	serio_set_drvdata(serio, NULL);
 	kfree(atkbd);
@@ -701,7 +700,7 @@
 
 
 /*
- * atkbd_set_device_attrs() initializes keyboard's keycode table
+ * atkbd_set_keycode_table() initializes keyboard's keycode table
  * according to the selected scancode set
  */
 
@@ -737,53 +736,58 @@
 
 static void atkbd_set_device_attrs(struct atkbd *atkbd)
 {
+	struct input_dev *input_dev = atkbd->dev;
 	int i;
 
-	memset(&atkbd->dev, 0, sizeof(struct input_dev));
+	if (atkbd->extra)
+		sprintf(atkbd->name, "AT Set 2 Extra keyboard");
+	else
+		sprintf(atkbd->name, "AT %s Set %d keyboard",
+			atkbd->translated ? "Translated" : "Raw", atkbd->set);
 
-	init_input_dev(&atkbd->dev);
+	sprintf(atkbd->phys, "%s/input0", atkbd->ps2dev.serio->phys);
 
-	atkbd->dev.name = atkbd->name;
-	atkbd->dev.phys = atkbd->phys;
-	atkbd->dev.id.bustype = BUS_I8042;
-	atkbd->dev.id.vendor = 0x0001;
-	atkbd->dev.id.product = atkbd->translated ? 1 : atkbd->set;
-	atkbd->dev.id.version = atkbd->id;
-	atkbd->dev.event = atkbd_event;
-	atkbd->dev.private = atkbd;
-	atkbd->dev.dev = &atkbd->ps2dev.serio->dev;
+	input_dev->name = atkbd->name;
+	input_dev->phys = atkbd->phys;
+	input_dev->id.bustype = BUS_I8042;
+	input_dev->id.vendor = 0x0001;
+	input_dev->id.product = atkbd->translated ? 1 : atkbd->set;
+	input_dev->id.version = atkbd->id;
+	input_dev->event = atkbd_event;
+	input_dev->private = atkbd;
+	input_dev->cdev.dev = &atkbd->ps2dev.serio->dev;
 
-	atkbd->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_REP) | BIT(EV_MSC);
+	input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REP) | BIT(EV_MSC);
 
 	if (atkbd->write) {
-		atkbd->dev.evbit[0] |= BIT(EV_LED);
-		atkbd->dev.ledbit[0] = BIT(LED_NUML) | BIT(LED_CAPSL) | BIT(LED_SCROLLL);
+		input_dev->evbit[0] |= BIT(EV_LED);
+		input_dev->ledbit[0] = BIT(LED_NUML) | BIT(LED_CAPSL) | BIT(LED_SCROLLL);
 	}
 
 	if (atkbd->extra)
-		atkbd->dev.ledbit[0] |= BIT(LED_COMPOSE) | BIT(LED_SUSPEND) |
+		input_dev->ledbit[0] |= BIT(LED_COMPOSE) | BIT(LED_SUSPEND) |
 					BIT(LED_SLEEP) | BIT(LED_MUTE) | BIT(LED_MISC);
 
 	if (!atkbd->softrepeat) {
-		atkbd->dev.rep[REP_DELAY] = 250;
-		atkbd->dev.rep[REP_PERIOD] = 33;
+		input_dev->rep[REP_DELAY] = 250;
+		input_dev->rep[REP_PERIOD] = 33;
 	}
 
-	atkbd->dev.mscbit[0] = atkbd->softraw ? BIT(MSC_SCAN) : BIT(MSC_RAW) | BIT(MSC_SCAN);
+	input_dev->mscbit[0] = atkbd->softraw ? BIT(MSC_SCAN) : BIT(MSC_RAW) | BIT(MSC_SCAN);
 
 	if (atkbd->scroll) {
-		atkbd->dev.evbit[0] |= BIT(EV_REL);
-		atkbd->dev.relbit[0] = BIT(REL_WHEEL) | BIT(REL_HWHEEL);
-		set_bit(BTN_MIDDLE, atkbd->dev.keybit);
+		input_dev->evbit[0] |= BIT(EV_REL);
+		input_dev->relbit[0] = BIT(REL_WHEEL) | BIT(REL_HWHEEL);
+		set_bit(BTN_MIDDLE, input_dev->keybit);
 	}
 
-	atkbd->dev.keycode = atkbd->keycode;
-	atkbd->dev.keycodesize = sizeof(unsigned char);
-	atkbd->dev.keycodemax = ARRAY_SIZE(atkbd_set2_keycode);
+	input_dev->keycode = atkbd->keycode;
+	input_dev->keycodesize = sizeof(unsigned char);
+	input_dev->keycodemax = ARRAY_SIZE(atkbd_set2_keycode);
 
 	for (i = 0; i < 512; i++)
 		if (atkbd->keycode[i] && atkbd->keycode[i] < ATKBD_SPECIAL)
-			set_bit(atkbd->keycode[i], atkbd->dev.keybit);
+			set_bit(atkbd->keycode[i], input_dev->keybit);
 }
 
 /*
@@ -796,13 +800,15 @@
 static int atkbd_connect(struct serio *serio, struct serio_driver *drv)
 {
 	struct atkbd *atkbd;
-	int err;
+	struct input_dev *dev;
+	int err = -ENOMEM;
 
-	if (!(atkbd = kmalloc(sizeof(struct atkbd), GFP_KERNEL)))
-		return - ENOMEM;
+	atkbd = kzalloc(sizeof(struct atkbd), GFP_KERNEL);
+	dev = input_allocate_device();
+	if (!atkbd || !dev)
+		goto fail;
 
-	memset(atkbd, 0, sizeof(struct atkbd));
-
+	atkbd->dev = dev;
 	ps2_init(&atkbd->ps2dev, serio);
 
 	switch (serio->id.type) {
@@ -828,19 +834,15 @@
 	serio_set_drvdata(serio, atkbd);
 
 	err = serio_open(serio, drv);
-	if (err) {
-		serio_set_drvdata(serio, NULL);
-		kfree(atkbd);
-		return err;
-	}
+	if (err)
+		goto fail;
 
 	if (atkbd->write) {
 
 		if (atkbd_probe(atkbd)) {
 			serio_close(serio);
-			serio_set_drvdata(serio, NULL);
-			kfree(atkbd);
-			return -ENODEV;
+			err = -ENODEV;
+			goto fail;
 		}
 
 		atkbd->set = atkbd_select_set(atkbd, atkbd_set, atkbd_extra);
@@ -851,19 +853,9 @@
 		atkbd->id = 0xab00;
 	}
 
-	if (atkbd->extra)
-		sprintf(atkbd->name, "AT Set 2 Extra keyboard");
-	else
-		sprintf(atkbd->name, "AT %s Set %d keyboard",
-			atkbd->translated ? "Translated" : "Raw", atkbd->set);
-
-	sprintf(atkbd->phys, "%s/input0", serio->phys);
-
 	atkbd_set_keycode_table(atkbd);
 	atkbd_set_device_attrs(atkbd);
 
-	input_register_device(&atkbd->dev);
-
 	device_create_file(&serio->dev, &atkbd_attr_extra);
 	device_create_file(&serio->dev, &atkbd_attr_scroll);
 	device_create_file(&serio->dev, &atkbd_attr_set);
@@ -872,9 +864,14 @@
 
 	atkbd_enable(atkbd);
 
-	printk(KERN_INFO "input: %s on %s\n", atkbd->name, serio->phys);
+	input_register_device(atkbd->dev);
 
 	return 0;
+
+ fail:	serio_set_drvdata(serio, NULL);
+	input_free_device(dev);
+	kfree(atkbd);
+	return err;
 }
 
 /*
@@ -896,9 +893,9 @@
 	atkbd_disable(atkbd);
 
 	if (atkbd->write) {
-		param[0] = (test_bit(LED_SCROLLL, atkbd->dev.led) ? 1 : 0)
-		         | (test_bit(LED_NUML,    atkbd->dev.led) ? 2 : 0)
-		         | (test_bit(LED_CAPSL,   atkbd->dev.led) ? 4 : 0);
+		param[0] = (test_bit(LED_SCROLLL, atkbd->dev->led) ? 1 : 0)
+		         | (test_bit(LED_NUML,    atkbd->dev->led) ? 2 : 0)
+		         | (test_bit(LED_CAPSL,   atkbd->dev->led) ? 4 : 0);
 
 		if (atkbd_probe(atkbd))
 			return -1;
@@ -1008,6 +1005,7 @@
 
 static ssize_t atkbd_set_extra(struct atkbd *atkbd, const char *buf, size_t count)
 {
+	struct input_dev *new_dev;
 	unsigned long value;
 	char *rest;
 
@@ -1019,12 +1017,19 @@
 		return -EINVAL;
 
 	if (atkbd->extra != value) {
-		/* unregister device as it's properties will change */
-		input_unregister_device(&atkbd->dev);
+		/*
+		 * Since device's properties will change we need to
+		 * unregister old device. But allocate new one first
+		 * to make sure we have it.
+		 */
+		if (!(new_dev = input_allocate_device()))
+			return -ENOMEM;
+		input_unregister_device(atkbd->dev);
+		atkbd->dev = new_dev;
 		atkbd->set = atkbd_select_set(atkbd, atkbd->set, value);
 		atkbd_activate(atkbd);
 		atkbd_set_device_attrs(atkbd);
-		input_register_device(&atkbd->dev);
+		input_register_device(atkbd->dev);
 	}
 	return count;
 }
@@ -1036,6 +1041,7 @@
 
 static ssize_t atkbd_set_scroll(struct atkbd *atkbd, const char *buf, size_t count)
 {
+	struct input_dev *new_dev;
 	unsigned long value;
 	char *rest;
 
@@ -1044,12 +1050,14 @@
 		return -EINVAL;
 
 	if (atkbd->scroll != value) {
-		/* unregister device as it's properties will change */
-		input_unregister_device(&atkbd->dev);
+		if (!(new_dev = input_allocate_device()))
+			return -ENOMEM;
+		input_unregister_device(atkbd->dev);
+		atkbd->dev = new_dev;
 		atkbd->scroll = value;
 		atkbd_set_keycode_table(atkbd);
 		atkbd_set_device_attrs(atkbd);
-		input_register_device(&atkbd->dev);
+		input_register_device(atkbd->dev);
 	}
 	return count;
 }
@@ -1061,6 +1069,7 @@
 
 static ssize_t atkbd_set_set(struct atkbd *atkbd, const char *buf, size_t count)
 {
+	struct input_dev *new_dev;
 	unsigned long value;
 	char *rest;
 
@@ -1072,13 +1081,15 @@
 		return -EINVAL;
 
 	if (atkbd->set != value) {
-		/* unregister device as it's properties will change */
-		input_unregister_device(&atkbd->dev);
+		if (!(new_dev = input_allocate_device()))
+			return -ENOMEM;
+		input_unregister_device(atkbd->dev);
+		atkbd->dev = new_dev;
 		atkbd->set = atkbd_select_set(atkbd, value, atkbd->extra);
 		atkbd_activate(atkbd);
 		atkbd_set_keycode_table(atkbd);
 		atkbd_set_device_attrs(atkbd);
-		input_register_device(&atkbd->dev);
+		input_register_device(atkbd->dev);
 	}
 	return count;
 }
@@ -1090,6 +1101,7 @@
 
 static ssize_t atkbd_set_softrepeat(struct atkbd *atkbd, const char *buf, size_t count)
 {
+	struct input_dev *new_dev;
 	unsigned long value;
 	char *rest;
 
@@ -1101,15 +1113,16 @@
 		return -EINVAL;
 
 	if (atkbd->softrepeat != value) {
-		/* unregister device as it's properties will change */
-		input_unregister_device(&atkbd->dev);
+		if (!(new_dev = input_allocate_device()))
+			return -ENOMEM;
+		input_unregister_device(atkbd->dev);
+		atkbd->dev = new_dev;
 		atkbd->softrepeat = value;
 		if (atkbd->softrepeat)
 			atkbd->softraw = 1;
 		atkbd_set_device_attrs(atkbd);
-		input_register_device(&atkbd->dev);
+		input_register_device(atkbd->dev);
 	}
-
 	return count;
 }
 
@@ -1121,6 +1134,7 @@
 
 static ssize_t atkbd_set_softraw(struct atkbd *atkbd, const char *buf, size_t count)
 {
+	struct input_dev *new_dev;
 	unsigned long value;
 	char *rest;
 
@@ -1129,11 +1143,13 @@
 		return -EINVAL;
 
 	if (atkbd->softraw != value) {
-		/* unregister device as it's properties will change */
-		input_unregister_device(&atkbd->dev);
+		if (!(new_dev = input_allocate_device()))
+			return -ENOMEM;
+		input_unregister_device(atkbd->dev);
+		atkbd->dev = new_dev;
 		atkbd->softraw = value;
 		atkbd_set_device_attrs(atkbd);
-		input_register_device(&atkbd->dev);
+		input_register_device(atkbd->dev);
 	}
 	return count;
 }
diff --git a/drivers/input/keyboard/corgikbd.c b/drivers/input/keyboard/corgikbd.c
index cd4b6e7..3210d29 100644
--- a/drivers/input/keyboard/corgikbd.c
+++ b/drivers/input/keyboard/corgikbd.c
@@ -70,8 +70,7 @@
 
 struct corgikbd {
 	unsigned char keycode[ARRAY_SIZE(corgikbd_keycode)];
-	struct input_dev input;
-	char phys[32];
+	struct input_dev *input;
 
 	spinlock_t lock;
 	struct timer_list timer;
@@ -147,7 +146,7 @@
 	spin_lock_irqsave(&corgikbd_data->lock, flags);
 
 	if (regs)
-		input_regs(&corgikbd_data->input, regs);
+		input_regs(corgikbd_data->input, regs);
 
 	num_pressed = 0;
 	for (col = 0; col < KB_COLS; col++) {
@@ -169,14 +168,14 @@
 			scancode = SCANCODE(row, col);
 			pressed = rowd & KB_ROWMASK(row);
 
-			input_report_key(&corgikbd_data->input, corgikbd_data->keycode[scancode], pressed);
+			input_report_key(corgikbd_data->input, corgikbd_data->keycode[scancode], pressed);
 
 			if (pressed)
 				num_pressed++;
 
 			if (pressed && (corgikbd_data->keycode[scancode] == CORGI_KEY_OFF)
 					&& time_after(jiffies, corgikbd_data->suspend_jiffies + HZ)) {
-				input_event(&corgikbd_data->input, EV_PWR, CORGI_KEY_OFF, 1);
+				input_event(corgikbd_data->input, EV_PWR, CORGI_KEY_OFF, 1);
 				corgikbd_data->suspend_jiffies=jiffies;
 			}
 		}
@@ -185,7 +184,7 @@
 
 	corgikbd_activate_all();
 
-	input_sync(&corgikbd_data->input);
+	input_sync(corgikbd_data->input);
 
 	/* if any keys are pressed, enable the timer */
 	if (num_pressed)
@@ -249,9 +248,9 @@
 		if (hinge_count >= HINGE_STABLE_COUNT) {
 			spin_lock_irqsave(&corgikbd_data->lock, flags);
 
-			input_report_switch(&corgikbd_data->input, SW_0, ((sharpsl_hinge_state & CORGI_SCP_SWA) != 0));
-			input_report_switch(&corgikbd_data->input, SW_1, ((sharpsl_hinge_state & CORGI_SCP_SWB) != 0));
-			input_sync(&corgikbd_data->input);
+			input_report_switch(corgikbd_data->input, SW_0, ((sharpsl_hinge_state & CORGI_SCP_SWA) != 0));
+			input_report_switch(corgikbd_data->input, SW_1, ((sharpsl_hinge_state & CORGI_SCP_SWB) != 0));
+			input_sync(corgikbd_data->input);
 
 			spin_unlock_irqrestore(&corgikbd_data->lock, flags);
 		}
@@ -260,24 +259,22 @@
 }
 
 #ifdef CONFIG_PM
-static int corgikbd_suspend(struct device *dev, pm_message_t state, uint32_t level)
+static int corgikbd_suspend(struct device *dev, pm_message_t state)
 {
-	if (level == SUSPEND_POWER_DOWN) {
-		struct corgikbd *corgikbd = dev_get_drvdata(dev);
-		corgikbd->suspended = 1;
-	}
+	struct corgikbd *corgikbd = dev_get_drvdata(dev);
+	corgikbd->suspended = 1;
+
 	return 0;
 }
 
-static int corgikbd_resume(struct device *dev, uint32_t level)
+static int corgikbd_resume(struct device *dev)
 {
-	if (level == RESUME_POWER_ON) {
-		struct corgikbd *corgikbd = dev_get_drvdata(dev);
+	struct corgikbd *corgikbd = dev_get_drvdata(dev);
 
-		/* Upon resume, ignore the suspend key for a short while */
-		corgikbd->suspend_jiffies=jiffies;
-		corgikbd->suspended = 0;
-	}
+	/* Upon resume, ignore the suspend key for a short while */
+	corgikbd->suspend_jiffies=jiffies;
+	corgikbd->suspended = 0;
+
 	return 0;
 }
 #else
@@ -287,16 +284,21 @@
 
 static int __init corgikbd_probe(struct device *dev)
 {
-	int i;
 	struct corgikbd *corgikbd;
+	struct input_dev *input_dev;
+	int i;
 
 	corgikbd = kzalloc(sizeof(struct corgikbd), GFP_KERNEL);
-	if (!corgikbd)
+	input_dev = input_allocate_device();
+	if (!corgikbd || !input_dev) {
+		kfree(corgikbd);
+		input_free_device(input_dev);
 		return -ENOMEM;
+	}
 
-	dev_set_drvdata(dev,corgikbd);
-	strcpy(corgikbd->phys, "corgikbd/input0");
+	dev_set_drvdata(dev, corgikbd);
 
+	corgikbd->input = input_dev;
 	spin_lock_init(&corgikbd->lock);
 
 	/* Init Keyboard rescan timer */
@@ -311,28 +313,30 @@
 
 	corgikbd->suspend_jiffies=jiffies;
 
-	init_input_dev(&corgikbd->input);
-	corgikbd->input.private = corgikbd;
-	corgikbd->input.name = "Corgi Keyboard";
-	corgikbd->input.dev = dev;
-	corgikbd->input.phys = corgikbd->phys;
-	corgikbd->input.id.bustype = BUS_HOST;
-	corgikbd->input.id.vendor = 0x0001;
-	corgikbd->input.id.product = 0x0001;
-	corgikbd->input.id.version = 0x0100;
-	corgikbd->input.evbit[0] = BIT(EV_KEY) | BIT(EV_REP) | BIT(EV_PWR) | BIT(EV_SW);
-	corgikbd->input.keycode = corgikbd->keycode;
-	corgikbd->input.keycodesize = sizeof(unsigned char);
-	corgikbd->input.keycodemax = ARRAY_SIZE(corgikbd_keycode);
-
 	memcpy(corgikbd->keycode, corgikbd_keycode, sizeof(corgikbd->keycode));
-	for (i = 0; i < ARRAY_SIZE(corgikbd_keycode); i++)
-		set_bit(corgikbd->keycode[i], corgikbd->input.keybit);
-	clear_bit(0, corgikbd->input.keybit);
-	set_bit(SW_0, corgikbd->input.swbit);
-	set_bit(SW_1, corgikbd->input.swbit);
 
-	input_register_device(&corgikbd->input);
+	input_dev->name = "Corgi Keyboard";
+	input_dev->phys = "corgikbd/input0";
+	input_dev->id.bustype = BUS_HOST;
+	input_dev->id.vendor = 0x0001;
+	input_dev->id.product = 0x0001;
+	input_dev->id.version = 0x0100;
+	input_dev->cdev.dev = dev;
+	input_dev->private = corgikbd;
+
+	input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REP) | BIT(EV_PWR) | BIT(EV_SW);
+	input_dev->keycode = corgikbd->keycode;
+	input_dev->keycodesize = sizeof(unsigned char);
+	input_dev->keycodemax = ARRAY_SIZE(corgikbd_keycode);
+
+	for (i = 0; i < ARRAY_SIZE(corgikbd_keycode); i++)
+		set_bit(corgikbd->keycode[i], input_dev->keybit);
+	clear_bit(0, input_dev->keybit);
+	set_bit(SW_0, input_dev->swbit);
+	set_bit(SW_1, input_dev->swbit);
+
+	input_register_device(corgikbd->input);
+
 	mod_timer(&corgikbd->htimer, jiffies + HINGE_SCAN_INTERVAL);
 
 	/* Setup sense interrupts - RisingEdge Detect, sense lines as inputs */
@@ -349,8 +353,6 @@
 	for (i = 0; i < CORGI_KEY_STROBE_NUM; i++)
 		pxa_gpio_mode(CORGI_GPIO_KEY_STROBE(i) | GPIO_OUT | GPIO_DFLT_HIGH);
 
-	printk(KERN_INFO "input: Corgi Keyboard Registered\n");
-
 	return 0;
 }
 
@@ -365,7 +367,7 @@
 	del_timer_sync(&corgikbd->htimer);
 	del_timer_sync(&corgikbd->timer);
 
-	input_unregister_device(&corgikbd->input);
+	input_unregister_device(corgikbd->input);
 
 	kfree(corgikbd);
 
diff --git a/drivers/input/keyboard/lkkbd.c b/drivers/input/keyboard/lkkbd.c
index 098963c..7f06780 100644
--- a/drivers/input/keyboard/lkkbd.c
+++ b/drivers/input/keyboard/lkkbd.c
@@ -102,7 +102,7 @@
 module_param (ctrlclick_volume, int, 0);
 MODULE_PARM_DESC (ctrlclick_volume, "Ctrlclick volume (in %), default is 100%");
 
-static int lk201_compose_is_alt = 0;
+static int lk201_compose_is_alt;
 module_param (lk201_compose_is_alt, int, 0);
 MODULE_PARM_DESC (lk201_compose_is_alt, "If set non-zero, LK201' Compose key "
 		"will act as an Alt key");
@@ -274,7 +274,7 @@
 };
 
 #define CHECK_LED(LED, BITS) do {		\
-	if (test_bit (LED, lk->dev.led))	\
+	if (test_bit (LED, lk->dev->led))	\
 		leds_on |= BITS;		\
 	else					\
 		leds_off |= BITS;		\
@@ -287,7 +287,7 @@
 	lk_keycode_t keycode[LK_NUM_KEYCODES];
 	int ignore_bytes;
 	unsigned char id[LK_NUM_IGNORE_BYTES];
-	struct input_dev dev;
+	struct input_dev *dev;
 	struct serio *serio;
 	struct work_struct tq;
 	char name[64];
@@ -423,8 +423,7 @@
 	DBG (KERN_INFO "Got byte 0x%02x\n", data);
 
 	if (lk->ignore_bytes > 0) {
-		DBG (KERN_INFO "Ignoring a byte on %s\n",
-				lk->name);
+		DBG (KERN_INFO "Ignoring a byte on %s\n", lk->name);
 		lk->id[LK_NUM_IGNORE_BYTES - lk->ignore_bytes--] = data;
 
 		if (lk->ignore_bytes == 0)
@@ -435,14 +434,14 @@
 
 	switch (data) {
 		case LK_ALL_KEYS_UP:
-			input_regs (&lk->dev, regs);
+			input_regs (lk->dev, regs);
 			for (i = 0; i < ARRAY_SIZE (lkkbd_keycode); i++)
 				if (lk->keycode[i] != KEY_RESERVED)
-					input_report_key (&lk->dev, lk->keycode[i], 0);
-			input_sync (&lk->dev);
+					input_report_key (lk->dev, lk->keycode[i], 0);
+			input_sync (lk->dev);
 			break;
 		case LK_METRONOME:
-			DBG (KERN_INFO "Got LK_METRONOME and don't "
+			DBG (KERN_INFO "Got %#d and don't "
 					"know how to handle...\n");
 			break;
 		case LK_OUTPUT_ERROR:
@@ -482,12 +481,12 @@
 
 		default:
 			if (lk->keycode[data] != KEY_RESERVED) {
-				input_regs (&lk->dev, regs);
-				if (!test_bit (lk->keycode[data], lk->dev.key))
-					input_report_key (&lk->dev, lk->keycode[data], 1);
+				input_regs (lk->dev, regs);
+				if (!test_bit (lk->keycode[data], lk->dev->key))
+					input_report_key (lk->dev, lk->keycode[data], 1);
 				else
-					input_report_key (&lk->dev, lk->keycode[data], 0);
-				input_sync (&lk->dev);
+					input_report_key (lk->dev, lk->keycode[data], 0);
+				input_sync (lk->dev);
                         } else
                                 printk (KERN_WARNING "%s: Unknown key with "
 						"scancode 0x%02x on %s.\n",
@@ -605,7 +604,7 @@
 	lk->serio->write (lk->serio, volume_to_hw (lk->bell_volume));
 
 	/* Enable/disable keyclick (and possibly set volume) */
-	if (test_bit (SND_CLICK, lk->dev.snd)) {
+	if (test_bit (SND_CLICK, lk->dev->snd)) {
 		lk->serio->write (lk->serio, LK_CMD_ENABLE_KEYCLICK);
 		lk->serio->write (lk->serio, volume_to_hw (lk->keyclick_volume));
 		lk->serio->write (lk->serio, LK_CMD_ENABLE_CTRCLICK);
@@ -616,7 +615,7 @@
 	}
 
 	/* Sound the bell if needed */
-	if (test_bit (SND_BELL, lk->dev.snd))
+	if (test_bit (SND_BELL, lk->dev->snd))
 		lk->serio->write (lk->serio, LK_CMD_SOUND_BELL);
 }
 
@@ -627,71 +626,70 @@
 lkkbd_connect (struct serio *serio, struct serio_driver *drv)
 {
 	struct lkkbd *lk;
+	struct input_dev *input_dev;
 	int i;
 	int err;
 
-	if (!(lk = kmalloc (sizeof (struct lkkbd), GFP_KERNEL)))
-		return -ENOMEM;
-
-	memset (lk, 0, sizeof (struct lkkbd));
-
-	init_input_dev (&lk->dev);
-	set_bit (EV_KEY, lk->dev.evbit);
-	set_bit (EV_LED, lk->dev.evbit);
-	set_bit (EV_SND, lk->dev.evbit);
-	set_bit (EV_REP, lk->dev.evbit);
-	set_bit (LED_CAPSL, lk->dev.ledbit);
-	set_bit (LED_SLEEP, lk->dev.ledbit);
-	set_bit (LED_COMPOSE, lk->dev.ledbit);
-	set_bit (LED_SCROLLL, lk->dev.ledbit);
-	set_bit (SND_BELL, lk->dev.sndbit);
-	set_bit (SND_CLICK, lk->dev.sndbit);
+	lk = kzalloc (sizeof (struct lkkbd), GFP_KERNEL);
+	input_dev = input_allocate_device ();
+	if (!lk || !input_dev) {
+		err = -ENOMEM;
+		goto fail;
+	}
 
 	lk->serio = serio;
-
+	lk->dev = input_dev;
 	INIT_WORK (&lk->tq, lkkbd_reinit, lk);
-
 	lk->bell_volume = bell_volume;
 	lk->keyclick_volume = keyclick_volume;
 	lk->ctrlclick_volume = ctrlclick_volume;
+	memcpy (lk->keycode, lkkbd_keycode, sizeof (lk_keycode_t) * LK_NUM_KEYCODES);
 
-	lk->dev.keycode = lk->keycode;
-	lk->dev.keycodesize = sizeof (lk_keycode_t);
-	lk->dev.keycodemax = LK_NUM_KEYCODES;
+	strlcpy (lk->name, "DEC LK keyboard", sizeof(lk->name));
+	snprintf (lk->phys, sizeof(lk->phys), "%s/input0", serio->phys);
 
-	lk->dev.event = lkkbd_event;
-	lk->dev.private = lk;
+	input_dev->name = lk->name;
+	input_dev->phys = lk->phys;
+	input_dev->id.bustype = BUS_RS232;
+	input_dev->id.vendor = SERIO_LKKBD;
+	input_dev->id.product = 0;
+	input_dev->id.version = 0x0100;
+	input_dev->cdev.dev = &serio->dev;
+	input_dev->event = lkkbd_event;
+	input_dev->private = lk;
+
+	set_bit (EV_KEY, input_dev->evbit);
+	set_bit (EV_LED, input_dev->evbit);
+	set_bit (EV_SND, input_dev->evbit);
+	set_bit (EV_REP, input_dev->evbit);
+	set_bit (LED_CAPSL, input_dev->ledbit);
+	set_bit (LED_SLEEP, input_dev->ledbit);
+	set_bit (LED_COMPOSE, input_dev->ledbit);
+	set_bit (LED_SCROLLL, input_dev->ledbit);
+	set_bit (SND_BELL, input_dev->sndbit);
+	set_bit (SND_CLICK, input_dev->sndbit);
+
+	input_dev->keycode = lk->keycode;
+	input_dev->keycodesize = sizeof (lk_keycode_t);
+	input_dev->keycodemax = LK_NUM_KEYCODES;
+	for (i = 0; i < LK_NUM_KEYCODES; i++)
+		set_bit (lk->keycode[i], input_dev->keybit);
 
 	serio_set_drvdata (serio, lk);
 
 	err = serio_open (serio, drv);
-	if (err) {
-		serio_set_drvdata (serio, NULL);
-		kfree (lk);
-		return err;
-	}
+	if (err)
+		goto fail;
 
-	sprintf (lk->name, "DEC LK keyboard");
-	sprintf (lk->phys, "%s/input0", serio->phys);
-
-	memcpy (lk->keycode, lkkbd_keycode, sizeof (lk_keycode_t) * LK_NUM_KEYCODES);
-	for (i = 0; i < LK_NUM_KEYCODES; i++)
-		set_bit (lk->keycode[i], lk->dev.keybit);
-
-	lk->dev.name = lk->name;
-	lk->dev.phys = lk->phys;
-	lk->dev.id.bustype = BUS_RS232;
-	lk->dev.id.vendor = SERIO_LKKBD;
-	lk->dev.id.product = 0;
-	lk->dev.id.version = 0x0100;
-	lk->dev.dev = &serio->dev;
-
-	input_register_device (&lk->dev);
-
-	printk (KERN_INFO "input: %s on %s, initiating reset\n", lk->name, serio->phys);
+	input_register_device (lk->dev);
 	lk->serio->write (lk->serio, LK_CMD_POWERCYCLE_RESET);
 
 	return 0;
+
+ fail:	serio_set_drvdata (serio, NULL);
+	input_free_device (input_dev);
+	kfree (lk);
+	return err;
 }
 
 /*
@@ -702,9 +700,11 @@
 {
 	struct lkkbd *lk = serio_get_drvdata (serio);
 
-	input_unregister_device (&lk->dev);
+	input_get_device (lk->dev);
+	input_unregister_device (lk->dev);
 	serio_close (serio);
 	serio_set_drvdata (serio, NULL);
+	input_put_device (lk->dev);
 	kfree (lk);
 }
 
diff --git a/drivers/input/keyboard/maple_keyb.c b/drivers/input/keyboard/maple_keyb.c
index eecbde2..cc6aaf9 100644
--- a/drivers/input/keyboard/maple_keyb.c
+++ b/drivers/input/keyboard/maple_keyb.c
@@ -37,7 +37,7 @@
 
 
 struct dc_kbd {
-	struct input_dev dev;
+	struct input_dev *dev;
 	unsigned char new[8];
 	unsigned char old[8];
 };
@@ -46,30 +46,24 @@
 static void dc_scan_kbd(struct dc_kbd *kbd)
 {
 	int i;
-	struct input_dev *dev = &kbd->dev;
+	struct input_dev *dev = kbd->dev;
 
-	for(i=0; i<8; i++)
-		input_report_key(dev,
-				 dc_kbd_keycode[i+224],
-				 (kbd->new[0]>>i)&1);
+	for (i = 0; i < 8; i++)
+		input_report_key(dev, dc_kbd_keycode[i + 224], (kbd->new[0] >> i) & 1);
 
-	for(i=2; i<8; i++) {
+	for (i = 2; i < 8; i++) {
 
-		if(kbd->old[i]>3&&memscan(kbd->new+2, kbd->old[i], 6)==NULL) {
-			if(dc_kbd_keycode[kbd->old[i]])
-				input_report_key(dev,
-						 dc_kbd_keycode[kbd->old[i]],
-						 0);
+		if (kbd->old[i] > 3 && memscan(kbd->new + 2, kbd->old[i], 6) == NULL) {
+			if (dc_kbd_keycode[kbd->old[i]])
+				input_report_key(dev, dc_kbd_keycode[kbd->old[i]], 0);
 			else
 				printk("Unknown key (scancode %#x) released.",
 				       kbd->old[i]);
 		}
 
-		if(kbd->new[i]>3&&memscan(kbd->old+2, kbd->new[i], 6)!=NULL) {
+		if (kbd->new[i] > 3 && memscan(kbd->old + 2, kbd->new[i], 6) != NULL) {
 			if(dc_kbd_keycode[kbd->new[i]])
-				input_report_key(dev,
-						 dc_kbd_keycode[kbd->new[i]],
-						 1);
+				input_report_key(dev, dc_kbd_keycode[kbd->new[i]], 1);
 			else
 				printk("Unknown key (scancode %#x) pressed.",
 				       kbd->new[i]);
@@ -89,43 +83,39 @@
 	unsigned long *buf = mq->recvbuf;
 
 	if (buf[1] == mapledev->function) {
-		memcpy(kbd->new, buf+2, 8);
+		memcpy(kbd->new, buf + 2, 8);
 		dc_scan_kbd(kbd);
 	}
 }
 
 static int dc_kbd_connect(struct maple_device *dev)
 {
-	int i;
-	unsigned long data = be32_to_cpu(dev->devinfo.function_data[0]);
 	struct dc_kbd *kbd;
+	struct input_dev *input_dev;
+	unsigned long data = be32_to_cpu(dev->devinfo.function_data[0]);
+	int i;
 
-	if (!(kbd = kmalloc(sizeof(struct dc_kbd), GFP_KERNEL)))
-		return -1;
-	memset(kbd, 0, sizeof(struct dc_kbd));
+	dev->private_data = kbd = kzalloc(sizeof(struct dc_kbd), GFP_KERNEL);
+	input_dev = input_allocate_device();
+	if (!kbd || !input_dev) {
+		kfree(kbd);
+		input_free_device(input_dev);
+		return -ENOMEM;
+	}
 
-	dev->private_data = kbd;
+	kbd->dev = input_dev;
 
-	kbd->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_REP);
+	input_dev->name = dev->product_name;
+	input_dev->id.bustype = BUS_MAPLE;
+	input_dev->private = kbd;
+	input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REP);
+	for (i = 0; i < 255; i++)
+		set_bit(dc_kbd_keycode[i], input_dev->keybit);
+	clear_bit(0, input_dev->keybit);
 
-	init_input_dev(&kbd->dev);
-
-	for (i=0; i<255; i++)
-		set_bit(dc_kbd_keycode[i], kbd->dev.keybit);
-
-	clear_bit(0, kbd->dev.keybit);
-
-	kbd->dev.private = kbd;
-
-	kbd->dev.name = dev->product_name;
-	kbd->dev.id.bustype = BUS_MAPLE;
-
-	input_register_device(&kbd->dev);
+	input_register_device(kbd->dev);
 
 	maple_getcond_callback(dev, dc_kbd_callback, 1, MAPLE_FUNC_KEYBOARD);
-
-	printk(KERN_INFO "input: keyboard(0x%lx): %s\n", data, kbd->dev.name);
-
 	return 0;
 }
 
@@ -134,7 +124,7 @@
 {
 	struct dc_kbd *kbd = dev->private_data;
 
-	input_unregister_device(&kbd->dev);
+	input_unregister_device(kbd->dev);
 	kfree(kbd);
 }
 
diff --git a/drivers/input/keyboard/newtonkbd.c b/drivers/input/keyboard/newtonkbd.c
index 2e8ce16..d10983c 100644
--- a/drivers/input/keyboard/newtonkbd.c
+++ b/drivers/input/keyboard/newtonkbd.c
@@ -57,11 +57,9 @@
 	KEY_LEFT, KEY_RIGHT, KEY_DOWN, KEY_UP, 0
 };
 
-static char *nkbd_name = "Newton Keyboard";
-
 struct nkbd {
 	unsigned char keycode[128];
-	struct input_dev dev;
+	struct input_dev *dev;
 	struct serio *serio;
 	char phys[32];
 };
@@ -73,13 +71,13 @@
 
 	/* invalid scan codes are probably the init sequence, so we ignore them */
 	if (nkbd->keycode[data & NKBD_KEY]) {
-		input_regs(&nkbd->dev, regs);
-		input_report_key(&nkbd->dev, nkbd->keycode[data & NKBD_KEY], data & NKBD_PRESS);
-		input_sync(&nkbd->dev);
+		input_regs(nkbd->dev, regs);
+		input_report_key(nkbd->dev, nkbd->keycode[data & NKBD_KEY], data & NKBD_PRESS);
+		input_sync(nkbd->dev);
 	}
 
 	else if (data == 0xe7) /* end of init sequence */
-		printk(KERN_INFO "input: %s on %s\n", nkbd_name, serio->phys);
+		printk(KERN_INFO "input: %s on %s\n", nkbd->dev->name, serio->phys);
 	return IRQ_HANDLED;
 
 }
@@ -87,62 +85,59 @@
 static int nkbd_connect(struct serio *serio, struct serio_driver *drv)
 {
 	struct nkbd *nkbd;
+	struct input_dev *input_dev;
+	int err = -ENOMEM;
 	int i;
-	int err;
 
-	if (!(nkbd = kmalloc(sizeof(struct nkbd), GFP_KERNEL)))
-		return -ENOMEM;
-
-	memset(nkbd, 0, sizeof(struct nkbd));
-
-	nkbd->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_REP);
+	nkbd = kzalloc(sizeof(struct nkbd), GFP_KERNEL);
+	input_dev = input_allocate_device();
+	if (!nkbd || !input_dev)
+		goto fail;
 
 	nkbd->serio = serio;
+	nkbd->dev = input_dev;
+	sprintf(nkbd->phys, "%s/input0", serio->phys);
+	memcpy(nkbd->keycode, nkbd_keycode, sizeof(nkbd->keycode));
 
-	init_input_dev(&nkbd->dev);
-	nkbd->dev.keycode = nkbd->keycode;
-	nkbd->dev.keycodesize = sizeof(unsigned char);
-	nkbd->dev.keycodemax = ARRAY_SIZE(nkbd_keycode);
-	nkbd->dev.private = nkbd;
+	input_dev->name = "Newton Keyboard";
+	input_dev->phys = nkbd->phys;
+	input_dev->id.bustype = BUS_RS232;
+	input_dev->id.vendor = SERIO_NEWTON;
+	input_dev->id.product = 0x0001;
+	input_dev->id.version = 0x0100;
+	input_dev->cdev.dev = &serio->dev;
+	input_dev->private = nkbd;
+
+	input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REP);
+	input_dev->keycode = nkbd->keycode;
+	input_dev->keycodesize = sizeof(unsigned char);
+	input_dev->keycodemax = ARRAY_SIZE(nkbd_keycode);
+	for (i = 0; i < 128; i++)
+		set_bit(nkbd->keycode[i], input_dev->keybit);
+	clear_bit(0, input_dev->keybit);
 
 	serio_set_drvdata(serio, nkbd);
 
 	err = serio_open(serio, drv);
-	if (err) {
-		serio_set_drvdata(serio, NULL);
-		kfree(nkbd);
-		return err;
-	}
+	if (err)
+		goto fail;
 
-	memcpy(nkbd->keycode, nkbd_keycode, sizeof(nkbd->keycode));
-	for (i = 0; i < 128; i++)
-		set_bit(nkbd->keycode[i], nkbd->dev.keybit);
-	clear_bit(0, nkbd->dev.keybit);
-
-	sprintf(nkbd->phys, "%s/input0", serio->phys);
-
-	nkbd->dev.name = nkbd_name;
-	nkbd->dev.phys = nkbd->phys;
-	nkbd->dev.id.bustype = BUS_RS232;
-	nkbd->dev.id.vendor = SERIO_NEWTON;
-	nkbd->dev.id.product = 0x0001;
-	nkbd->dev.id.version = 0x0100;
-	nkbd->dev.dev = &serio->dev;
-
-	input_register_device(&nkbd->dev);
-
-	printk(KERN_INFO "input: %s on %s\n", nkbd_name, serio->phys);
-
+	input_register_device(nkbd->dev);
 	return 0;
+
+ fail:	serio_set_drvdata(serio, NULL);
+	input_free_device(input_dev);
+	kfree(nkbd);
+	return err;
 }
 
 static void nkbd_disconnect(struct serio *serio)
 {
 	struct nkbd *nkbd = serio_get_drvdata(serio);
 
-	input_unregister_device(&nkbd->dev);
 	serio_close(serio);
 	serio_set_drvdata(serio, NULL);
+	input_unregister_device(nkbd->dev);
 	kfree(nkbd);
 }
 
diff --git a/drivers/input/keyboard/spitzkbd.c b/drivers/input/keyboard/spitzkbd.c
index 344f460..cee9c73 100644
--- a/drivers/input/keyboard/spitzkbd.c
+++ b/drivers/input/keyboard/spitzkbd.c
@@ -85,7 +85,7 @@
 
 struct spitzkbd {
 	unsigned char keycode[ARRAY_SIZE(spitzkbd_keycode)];
-	struct input_dev input;
+	struct input_dev *input;
 	char phys[32];
 
 	spinlock_t lock;
@@ -187,8 +187,7 @@
 
 	spin_lock_irqsave(&spitzkbd_data->lock, flags);
 
-	if (regs)
-		input_regs(&spitzkbd_data->input, regs);
+	input_regs(spitzkbd_data->input, regs);
 
 	num_pressed = 0;
 	for (col = 0; col < KB_COLS; col++) {
@@ -210,7 +209,7 @@
 			scancode = SCANCODE(row, col);
 			pressed = rowd & KB_ROWMASK(row);
 
-			input_report_key(&spitzkbd_data->input, spitzkbd_data->keycode[scancode], pressed);
+			input_report_key(spitzkbd_data->input, spitzkbd_data->keycode[scancode], pressed);
 
 			if (pressed)
 				num_pressed++;
@@ -220,15 +219,15 @@
 
 	spitzkbd_activate_all();
 
-	input_report_key(&spitzkbd_data->input, SPITZ_KEY_SYNC, (GPLR(SPITZ_GPIO_SYNC) & GPIO_bit(SPITZ_GPIO_SYNC)) != 0 );
-	input_report_key(&spitzkbd_data->input, KEY_SUSPEND, pwrkey);
+	input_report_key(spitzkbd_data->input, SPITZ_KEY_SYNC, (GPLR(SPITZ_GPIO_SYNC) & GPIO_bit(SPITZ_GPIO_SYNC)) != 0 );
+	input_report_key(spitzkbd_data->input, KEY_SUSPEND, pwrkey);
 
 	if (pwrkey && time_after(jiffies, spitzkbd_data->suspend_jiffies + msecs_to_jiffies(1000))) {
-		input_event(&spitzkbd_data->input, EV_PWR, KEY_SUSPEND, 1);
+		input_event(spitzkbd_data->input, EV_PWR, KEY_SUSPEND, 1);
 		spitzkbd_data->suspend_jiffies = jiffies;
 	}
 
-	input_sync(&spitzkbd_data->input);
+	input_sync(spitzkbd_data->input);
 
 	/* if any keys are pressed, enable the timer */
 	if (num_pressed)
@@ -259,6 +258,7 @@
 static void spitzkbd_timer_callback(unsigned long data)
 {
 	struct spitzkbd *spitzkbd_data = (struct spitzkbd *) data;
+
 	spitzkbd_scankeyboard(spitzkbd_data, NULL);
 }
 
@@ -298,9 +298,9 @@
 	if (hinge_count >= HINGE_STABLE_COUNT) {
 		spin_lock_irqsave(&spitzkbd_data->lock, flags);
 
-		input_report_switch(&spitzkbd_data->input, SW_0, ((GPLR(SPITZ_GPIO_SWA) & GPIO_bit(SPITZ_GPIO_SWA)) != 0));
-		input_report_switch(&spitzkbd_data->input, SW_1, ((GPLR(SPITZ_GPIO_SWB) & GPIO_bit(SPITZ_GPIO_SWB)) != 0));
-		input_sync(&spitzkbd_data->input);
+		input_report_switch(spitzkbd_data->input, SW_0, ((GPLR(SPITZ_GPIO_SWA) & GPIO_bit(SPITZ_GPIO_SWA)) != 0));
+		input_report_switch(spitzkbd_data->input, SW_1, ((GPLR(SPITZ_GPIO_SWB) & GPIO_bit(SPITZ_GPIO_SWB)) != 0));
+		input_sync(spitzkbd_data->input);
 
 		spin_unlock_irqrestore(&spitzkbd_data->lock, flags);
 	} else {
@@ -309,34 +309,32 @@
 }
 
 #ifdef CONFIG_PM
-static int spitzkbd_suspend(struct device *dev, pm_message_t state, uint32_t level)
+static int spitzkbd_suspend(struct device *dev, pm_message_t state)
 {
-	if (level == SUSPEND_POWER_DOWN) {
-		int i;
-		struct spitzkbd *spitzkbd = dev_get_drvdata(dev);
-		spitzkbd->suspended = 1;
+	int i;
+	struct spitzkbd *spitzkbd = dev_get_drvdata(dev);
+	spitzkbd->suspended = 1;
 
-		/* Set Strobe lines as inputs - *except* strobe line 0 leave this
-		   enabled so we can detect a power button press for resume */
-		for (i = 1; i < SPITZ_KEY_STROBE_NUM; i++)
-			pxa_gpio_mode(spitz_strobes[i] | GPIO_IN);
-	}
+	/* Set Strobe lines as inputs - *except* strobe line 0 leave this
+	   enabled so we can detect a power button press for resume */
+	for (i = 1; i < SPITZ_KEY_STROBE_NUM; i++)
+		pxa_gpio_mode(spitz_strobes[i] | GPIO_IN);
+
 	return 0;
 }
 
-static int spitzkbd_resume(struct device *dev, uint32_t level)
+static int spitzkbd_resume(struct device *dev)
 {
-	if (level == RESUME_POWER_ON) {
-		int i;
-		struct spitzkbd *spitzkbd = dev_get_drvdata(dev);
+	int i;
+	struct spitzkbd *spitzkbd = dev_get_drvdata(dev);
 
-		for (i = 0; i < SPITZ_KEY_STROBE_NUM; i++)
-			pxa_gpio_mode(spitz_strobes[i] | GPIO_OUT | GPIO_DFLT_HIGH);
+	for (i = 0; i < SPITZ_KEY_STROBE_NUM; i++)
+		pxa_gpio_mode(spitz_strobes[i] | GPIO_OUT | GPIO_DFLT_HIGH);
 
-		/* Upon resume, ignore the suspend key for a short while */
-		spitzkbd->suspend_jiffies = jiffies;
-		spitzkbd->suspended = 0;
-	}
+	/* Upon resume, ignore the suspend key for a short while */
+	spitzkbd->suspend_jiffies = jiffies;
+	spitzkbd->suspended = 0;
+
 	return 0;
 }
 #else
@@ -346,14 +344,21 @@
 
 static int __init spitzkbd_probe(struct device *dev)
 {
-	int i;
 	struct spitzkbd *spitzkbd;
+	struct input_dev *input_dev;
+	int i;
 
 	spitzkbd = kzalloc(sizeof(struct spitzkbd), GFP_KERNEL);
 	if (!spitzkbd)
 		return -ENOMEM;
 
-	dev_set_drvdata(dev,spitzkbd);
+	input_dev = input_allocate_device();
+	if (!input_dev) {
+		kfree(spitzkbd);
+		return -ENOMEM;
+	}
+
+	dev_set_drvdata(dev, spitzkbd);
 	strcpy(spitzkbd->phys, "spitzkbd/input0");
 
 	spin_lock_init(&spitzkbd->lock);
@@ -368,30 +373,34 @@
 	spitzkbd->htimer.function = spitzkbd_hinge_timer;
 	spitzkbd->htimer.data = (unsigned long) spitzkbd;
 
-	spitzkbd->suspend_jiffies=jiffies;
+	spitzkbd->suspend_jiffies = jiffies;
 
-	init_input_dev(&spitzkbd->input);
-	spitzkbd->input.private = spitzkbd;
-	spitzkbd->input.name = "Spitz Keyboard";
-	spitzkbd->input.dev = dev;
-	spitzkbd->input.phys = spitzkbd->phys;
-	spitzkbd->input.id.bustype = BUS_HOST;
-	spitzkbd->input.id.vendor = 0x0001;
-	spitzkbd->input.id.product = 0x0001;
-	spitzkbd->input.id.version = 0x0100;
-	spitzkbd->input.evbit[0] = BIT(EV_KEY) | BIT(EV_REP) | BIT(EV_PWR) | BIT(EV_SW);
-	spitzkbd->input.keycode = spitzkbd->keycode;
-	spitzkbd->input.keycodesize = sizeof(unsigned char);
-	spitzkbd->input.keycodemax = ARRAY_SIZE(spitzkbd_keycode);
+	spitzkbd->input = input_dev;
+
+	input_dev->private = spitzkbd;
+	input_dev->name = "Spitz Keyboard";
+	input_dev->phys = spitzkbd->phys;
+	input_dev->cdev.dev = dev;
+
+	input_dev->id.bustype = BUS_HOST;
+	input_dev->id.vendor = 0x0001;
+	input_dev->id.product = 0x0001;
+	input_dev->id.version = 0x0100;
+
+	input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REP) | BIT(EV_PWR) | BIT(EV_SW);
+	input_dev->keycode = spitzkbd->keycode;
+	input_dev->keycodesize = sizeof(unsigned char);
+	input_dev->keycodemax = ARRAY_SIZE(spitzkbd_keycode);
 
 	memcpy(spitzkbd->keycode, spitzkbd_keycode, sizeof(spitzkbd->keycode));
 	for (i = 0; i < ARRAY_SIZE(spitzkbd_keycode); i++)
-		set_bit(spitzkbd->keycode[i], spitzkbd->input.keybit);
-	clear_bit(0, spitzkbd->input.keybit);
-	set_bit(SW_0, spitzkbd->input.swbit);
-	set_bit(SW_1, spitzkbd->input.swbit);
+		set_bit(spitzkbd->keycode[i], input_dev->keybit);
+	clear_bit(0, input_dev->keybit);
+	set_bit(SW_0, input_dev->swbit);
+	set_bit(SW_1, input_dev->swbit);
 
-	input_register_device(&spitzkbd->input);
+	input_register_device(input_dev);
+
 	mod_timer(&spitzkbd->htimer, jiffies + msecs_to_jiffies(HINGE_SCAN_INTERVAL));
 
 	/* Setup sense interrupts - RisingEdge Detect, sense lines as inputs */
@@ -444,7 +453,7 @@
 	del_timer_sync(&spitzkbd->htimer);
 	del_timer_sync(&spitzkbd->timer);
 
-	input_unregister_device(&spitzkbd->input);
+	input_unregister_device(spitzkbd->input);
 
 	kfree(spitzkbd);
 
diff --git a/drivers/input/keyboard/sunkbd.c b/drivers/input/keyboard/sunkbd.c
index 4bae5d8..b15b6d8 100644
--- a/drivers/input/keyboard/sunkbd.c
+++ b/drivers/input/keyboard/sunkbd.c
@@ -76,13 +76,14 @@
 
 struct sunkbd {
 	unsigned char keycode[128];
-	struct input_dev dev;
+	struct input_dev *dev;
 	struct serio *serio;
 	struct work_struct tq;
 	wait_queue_head_t wait;
 	char name[64];
 	char phys[32];
 	char type;
+	unsigned char enabled;
 	volatile s8 reset;
 	volatile s8 layout;
 };
@@ -124,10 +125,13 @@
 			break;
 
 		default:
+			if (!sunkbd->enabled)
+				break;
+
 			if (sunkbd->keycode[data & SUNKBD_KEY]) {
-				input_regs(&sunkbd->dev, regs);
-                                input_report_key(&sunkbd->dev, sunkbd->keycode[data & SUNKBD_KEY], !(data & SUNKBD_RELEASE));
-				input_sync(&sunkbd->dev);
+				input_regs(sunkbd->dev, regs);
+                                input_report_key(sunkbd->dev, sunkbd->keycode[data & SUNKBD_KEY], !(data & SUNKBD_RELEASE));
+				input_sync(sunkbd->dev);
                         } else {
                                 printk(KERN_WARNING "sunkbd.c: Unknown key (scancode %#x) %s.\n",
                                         data & SUNKBD_KEY, data & SUNKBD_RELEASE ? "released" : "pressed");
@@ -184,7 +188,7 @@
 	sunkbd->reset = -2;
 	sunkbd->serio->write(sunkbd->serio, SUNKBD_CMD_RESET);
 	wait_event_interruptible_timeout(sunkbd->wait, sunkbd->reset >= 0, HZ);
-	if (sunkbd->reset <0)
+	if (sunkbd->reset < 0)
 		return -1;
 
 	sunkbd->type = sunkbd->reset;
@@ -213,10 +217,17 @@
 
 	sunkbd->serio->write(sunkbd->serio, SUNKBD_CMD_SETLED);
 	sunkbd->serio->write(sunkbd->serio,
-		(!!test_bit(LED_CAPSL, sunkbd->dev.led) << 3) | (!!test_bit(LED_SCROLLL, sunkbd->dev.led) << 2) |
-		(!!test_bit(LED_COMPOSE, sunkbd->dev.led) << 1) | !!test_bit(LED_NUML, sunkbd->dev.led));
-	sunkbd->serio->write(sunkbd->serio, SUNKBD_CMD_NOCLICK - !!test_bit(SND_CLICK, sunkbd->dev.snd));
-	sunkbd->serio->write(sunkbd->serio, SUNKBD_CMD_BELLOFF - !!test_bit(SND_BELL, sunkbd->dev.snd));
+		(!!test_bit(LED_CAPSL, sunkbd->dev->led) << 3) | (!!test_bit(LED_SCROLLL, sunkbd->dev->led) << 2) |
+		(!!test_bit(LED_COMPOSE, sunkbd->dev->led) << 1) | !!test_bit(LED_NUML, sunkbd->dev->led));
+	sunkbd->serio->write(sunkbd->serio, SUNKBD_CMD_NOCLICK - !!test_bit(SND_CLICK, sunkbd->dev->snd));
+	sunkbd->serio->write(sunkbd->serio, SUNKBD_CMD_BELLOFF - !!test_bit(SND_BELL, sunkbd->dev->snd));
+}
+
+static void sunkbd_enable(struct sunkbd *sunkbd, int enable)
+{
+	serio_pause_rx(sunkbd->serio);
+	sunkbd->enabled = 1;
+	serio_continue_rx(sunkbd->serio);
 }
 
 /*
@@ -226,70 +237,64 @@
 static int sunkbd_connect(struct serio *serio, struct serio_driver *drv)
 {
 	struct sunkbd *sunkbd;
+	struct input_dev *input_dev;
+	int err = -ENOMEM;
 	int i;
-	int err;
 
-	if (!(sunkbd = kmalloc(sizeof(struct sunkbd), GFP_KERNEL)))
-		return -ENOMEM;
-
-	memset(sunkbd, 0, sizeof(struct sunkbd));
-
-	init_input_dev(&sunkbd->dev);
-	init_waitqueue_head(&sunkbd->wait);
-
-	sunkbd->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_LED) | BIT(EV_SND) | BIT(EV_REP);
-	sunkbd->dev.ledbit[0] = BIT(LED_CAPSL) | BIT(LED_COMPOSE) | BIT(LED_SCROLLL) | BIT(LED_NUML);
-	sunkbd->dev.sndbit[0] = BIT(SND_CLICK) | BIT(SND_BELL);
+	sunkbd = kzalloc(sizeof(struct sunkbd), GFP_KERNEL);
+	input_dev = input_allocate_device();
+	if (!sunkbd || !input_dev)
+		goto fail;
 
 	sunkbd->serio = serio;
-
+	sunkbd->dev = input_dev;
+	init_waitqueue_head(&sunkbd->wait);
 	INIT_WORK(&sunkbd->tq, sunkbd_reinit, sunkbd);
-
-	sunkbd->dev.keycode = sunkbd->keycode;
-	sunkbd->dev.keycodesize = sizeof(unsigned char);
-	sunkbd->dev.keycodemax = ARRAY_SIZE(sunkbd_keycode);
-
-	sunkbd->dev.event = sunkbd_event;
-	sunkbd->dev.private = sunkbd;
+	snprintf(sunkbd->phys, sizeof(sunkbd->phys), "%s/input0", serio->phys);
 
 	serio_set_drvdata(serio, sunkbd);
 
 	err = serio_open(serio, drv);
-	if (err) {
-		serio_set_drvdata(serio, NULL);
-		kfree(sunkbd);
-		return err;
-	}
+	if (err)
+		goto fail;
 
 	if (sunkbd_initialize(sunkbd) < 0) {
 		serio_close(serio);
-		serio_set_drvdata(serio, NULL);
-		kfree(sunkbd);
-		return -ENODEV;
+		goto fail;
 	}
 
 	sprintf(sunkbd->name, "Sun Type %d keyboard", sunkbd->type);
-
 	memcpy(sunkbd->keycode, sunkbd_keycode, sizeof(sunkbd->keycode));
+
+	input_dev->name = sunkbd->name;
+	input_dev->phys = sunkbd->phys;
+	input_dev->id.bustype = BUS_RS232;
+	input_dev->id.vendor  = SERIO_SUNKBD;
+	input_dev->id.product = sunkbd->type;
+	input_dev->id.version = 0x0100;
+	input_dev->cdev.dev = &serio->dev;
+	input_dev->private = sunkbd;
+	input_dev->event = sunkbd_event;
+
+	input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_LED) | BIT(EV_SND) | BIT(EV_REP);
+	input_dev->ledbit[0] = BIT(LED_CAPSL) | BIT(LED_COMPOSE) | BIT(LED_SCROLLL) | BIT(LED_NUML);
+	input_dev->sndbit[0] = BIT(SND_CLICK) | BIT(SND_BELL);
+
+	input_dev->keycode = sunkbd->keycode;
+	input_dev->keycodesize = sizeof(unsigned char);
+	input_dev->keycodemax = ARRAY_SIZE(sunkbd_keycode);
 	for (i = 0; i < 128; i++)
-		set_bit(sunkbd->keycode[i], sunkbd->dev.keybit);
-	clear_bit(0, sunkbd->dev.keybit);
+		set_bit(sunkbd->keycode[i], input_dev->keybit);
+	clear_bit(0, input_dev->keybit);
 
-	sprintf(sunkbd->phys, "%s/input0", serio->phys);
-
-	sunkbd->dev.name = sunkbd->name;
-	sunkbd->dev.phys = sunkbd->phys;
-	sunkbd->dev.id.bustype = BUS_RS232;
-	sunkbd->dev.id.vendor = SERIO_SUNKBD;
-	sunkbd->dev.id.product = sunkbd->type;
-	sunkbd->dev.id.version = 0x0100;
-	sunkbd->dev.dev = &serio->dev;
-
-	input_register_device(&sunkbd->dev);
-
-	printk(KERN_INFO "input: %s on %s\n", sunkbd->name, serio->phys);
-
+	sunkbd_enable(sunkbd, 1);
+	input_register_device(sunkbd->dev);
 	return 0;
+
+ fail:	serio_set_drvdata(serio, NULL);
+	input_free_device(input_dev);
+	kfree(sunkbd);
+	return err;
 }
 
 /*
@@ -299,7 +304,9 @@
 static void sunkbd_disconnect(struct serio *serio)
 {
 	struct sunkbd *sunkbd = serio_get_drvdata(serio);
-	input_unregister_device(&sunkbd->dev);
+
+	sunkbd_enable(sunkbd, 0);
+	input_unregister_device(sunkbd->dev);
 	serio_close(serio);
 	serio_set_drvdata(serio, NULL);
 	kfree(sunkbd);
diff --git a/drivers/input/keyboard/xtkbd.c b/drivers/input/keyboard/xtkbd.c
index 19eaec7..4135e3e 100644
--- a/drivers/input/keyboard/xtkbd.c
+++ b/drivers/input/keyboard/xtkbd.c
@@ -56,11 +56,9 @@
 	106
 };
 
-static char *xtkbd_name = "XT Keyboard";
-
 struct xtkbd {
 	unsigned char keycode[256];
-	struct input_dev dev;
+	struct input_dev *dev;
 	struct serio *serio;
 	char phys[32];
 };
@@ -77,9 +75,9 @@
 		default:
 
 			if (xtkbd->keycode[data & XTKBD_KEY]) {
-				input_regs(&xtkbd->dev, regs);
-				input_report_key(&xtkbd->dev, xtkbd->keycode[data & XTKBD_KEY], !(data & XTKBD_RELEASE));
-				input_sync(&xtkbd->dev);
+				input_regs(xtkbd->dev, regs);
+				input_report_key(xtkbd->dev, xtkbd->keycode[data & XTKBD_KEY], !(data & XTKBD_RELEASE));
+				input_sync(xtkbd->dev);
 			} else {
 				printk(KERN_WARNING "xtkbd.c: Unknown key (scancode %#x) %s.\n",
 					data & XTKBD_KEY, data & XTKBD_RELEASE ? "released" : "pressed");
@@ -91,62 +89,60 @@
 static int xtkbd_connect(struct serio *serio, struct serio_driver *drv)
 {
 	struct xtkbd *xtkbd;
+	struct input_dev *input_dev;
+	int err = -ENOMEM;
 	int i;
-	int err;
 
-	if (!(xtkbd = kmalloc(sizeof(struct xtkbd), GFP_KERNEL)))
-		return -ENOMEM;
-
-	memset(xtkbd, 0, sizeof(struct xtkbd));
-
-	xtkbd->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_REP);
+	xtkbd = kmalloc(sizeof(struct xtkbd), GFP_KERNEL);
+	input_dev = input_allocate_device();
+	if (!xtkbd || !input_dev)
+		goto fail;
 
 	xtkbd->serio = serio;
+	xtkbd->dev = input_dev;
+	sprintf(xtkbd->phys, "%s/input0", serio->phys);
+	memcpy(xtkbd->keycode, xtkbd_keycode, sizeof(xtkbd->keycode));
 
-	init_input_dev(&xtkbd->dev);
-	xtkbd->dev.keycode = xtkbd->keycode;
-	xtkbd->dev.keycodesize = sizeof(unsigned char);
-	xtkbd->dev.keycodemax = ARRAY_SIZE(xtkbd_keycode);
-	xtkbd->dev.private = xtkbd;
+	input_dev->name = "XT Keyboard";
+	input_dev->phys = xtkbd->phys;
+	input_dev->id.bustype = BUS_XTKBD;
+	input_dev->id.vendor  = 0x0001;
+	input_dev->id.product = 0x0001;
+	input_dev->id.version = 0x0100;
+	input_dev->cdev.dev = &serio->dev;
+	input_dev->private = xtkbd;
+
+	input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REP);
+	input_dev->keycode = xtkbd->keycode;
+	input_dev->keycodesize = sizeof(unsigned char);
+	input_dev->keycodemax = ARRAY_SIZE(xtkbd_keycode);
+
+	for (i = 0; i < 255; i++)
+		set_bit(xtkbd->keycode[i], input_dev->keybit);
+	clear_bit(0, input_dev->keybit);
 
 	serio_set_drvdata(serio, xtkbd);
 
 	err = serio_open(serio, drv);
-	if (err) {
-		serio_set_drvdata(serio, NULL);
-		kfree(xtkbd);
-		return err;
-	}
+	if (err)
+		goto fail;
 
-	memcpy(xtkbd->keycode, xtkbd_keycode, sizeof(xtkbd->keycode));
-	for (i = 0; i < 255; i++)
-		set_bit(xtkbd->keycode[i], xtkbd->dev.keybit);
-	clear_bit(0, xtkbd->dev.keybit);
-
-	sprintf(xtkbd->phys, "%s/input0", serio->phys);
-
-	xtkbd->dev.name = xtkbd_name;
-	xtkbd->dev.phys = xtkbd->phys;
-	xtkbd->dev.id.bustype = BUS_XTKBD;
-	xtkbd->dev.id.vendor = 0x0001;
-	xtkbd->dev.id.product = 0x0001;
-	xtkbd->dev.id.version = 0x0100;
-	xtkbd->dev.dev = &serio->dev;
-
-	input_register_device(&xtkbd->dev);
-
-	printk(KERN_INFO "input: %s on %s\n", xtkbd_name, serio->phys);
-
+	input_register_device(xtkbd->dev);
 	return 0;
+
+ fail:	serio_set_drvdata(serio, NULL);
+	input_free_device(input_dev);
+	kfree(xtkbd);
+	return err;
 }
 
 static void xtkbd_disconnect(struct serio *serio)
 {
 	struct xtkbd *xtkbd = serio_get_drvdata(serio);
 
-	input_unregister_device(&xtkbd->dev);
 	serio_close(serio);
 	serio_set_drvdata(serio, NULL);
+	input_unregister_device(xtkbd->dev);
 	kfree(xtkbd);
 }
 
diff --git a/drivers/input/misc/m68kspkr.c b/drivers/input/misc/m68kspkr.c
index 64abdd9..04489ad 100644
--- a/drivers/input/misc/m68kspkr.c
+++ b/drivers/input/misc/m68kspkr.c
@@ -24,9 +24,7 @@
 MODULE_DESCRIPTION("m68k beeper driver");
 MODULE_LICENSE("GPL");
 
-static char m68kspkr_name[] = "m68k beeper";
-static char m68kspkr_phys[] = "m68k/generic";
-static struct input_dev m68kspkr_dev;
+static struct input_dev *m68kspkr_dev;
 
 static int m68kspkr_event(struct input_dev *dev, unsigned int type, unsigned int code, int value)
 {
@@ -51,32 +49,34 @@
 
 static int __init m68kspkr_init(void)
 {
-        if (!mach_beep){
-		printk("%s: no lowlevel beep support\n", m68kspkr_name);
-		return -1;
+        if (!mach_beep) {
+		printk(KERN_INFO "m68kspkr: no lowlevel beep support\n");
+		return -ENODEV;
         }
 
-	m68kspkr_dev.evbit[0] = BIT(EV_SND);
-	m68kspkr_dev.sndbit[0] = BIT(SND_BELL) | BIT(SND_TONE);
-	m68kspkr_dev.event = m68kspkr_event;
+	m68kspkr_dev = input_allocate_device();
+	if (!m68kspkr_dev)
+		return -ENOMEM;
 
-	m68kspkr_dev.name = m68kspkr_name;
-	m68kspkr_dev.phys = m68kspkr_phys;
-	m68kspkr_dev.id.bustype = BUS_HOST;
-	m68kspkr_dev.id.vendor = 0x001f;
-	m68kspkr_dev.id.product = 0x0001;
-	m68kspkr_dev.id.version = 0x0100;
+	m68kspkr_dev->name = "m68k beeper";
+	m68kspkr_dev->phys = "m68k/generic";
+	m68kspkr_dev->id.bustype = BUS_HOST;
+	m68kspkr_dev->id.vendor = 0x001f;
+	m68kspkr_dev->id.product = 0x0001;
+	m68kspkr_dev->id.version = 0x0100;
 
-	input_register_device(&m68kspkr_dev);
+	m68kspkr_dev->evbit[0] = BIT(EV_SND);
+	m68kspkr_dev->sndbit[0] = BIT(SND_BELL) | BIT(SND_TONE);
+	m68kspkr_dev->event = m68kspkr_event;
 
-        printk(KERN_INFO "input: %s\n", m68kspkr_name);
+	input_register_device(m68kspkr_dev);
 
 	return 0;
 }
 
 static void __exit m68kspkr_exit(void)
 {
-        input_unregister_device(&m68kspkr_dev);
+        input_unregister_device(m68kspkr_dev);
 }
 
 module_init(m68kspkr_init);
diff --git a/drivers/input/misc/pcspkr.c b/drivers/input/misc/pcspkr.c
index 3013194..e34633c 100644
--- a/drivers/input/misc/pcspkr.c
+++ b/drivers/input/misc/pcspkr.c
@@ -23,9 +23,7 @@
 MODULE_DESCRIPTION("PC Speaker beeper driver");
 MODULE_LICENSE("GPL");
 
-static char pcspkr_name[] = "PC Speaker";
-static char pcspkr_phys[] = "isa0061/input0";
-static struct input_dev pcspkr_dev;
+static struct input_dev *pcspkr_dev;
 
 static DEFINE_SPINLOCK(i8253_beep_lock);
 
@@ -68,27 +66,29 @@
 
 static int __init pcspkr_init(void)
 {
-	pcspkr_dev.evbit[0] = BIT(EV_SND);
-	pcspkr_dev.sndbit[0] = BIT(SND_BELL) | BIT(SND_TONE);
-	pcspkr_dev.event = pcspkr_event;
+	pcspkr_dev = input_allocate_device();
+	if (!pcspkr_dev)
+		return -ENOMEM;
 
-	pcspkr_dev.name = pcspkr_name;
-	pcspkr_dev.phys = pcspkr_phys;
-	pcspkr_dev.id.bustype = BUS_ISA;
-	pcspkr_dev.id.vendor = 0x001f;
-	pcspkr_dev.id.product = 0x0001;
-	pcspkr_dev.id.version = 0x0100;
+	pcspkr_dev->name = "PC Speaker";
+	pcspkr_dev->name = "isa0061/input0";
+	pcspkr_dev->id.bustype = BUS_ISA;
+	pcspkr_dev->id.vendor = 0x001f;
+	pcspkr_dev->id.product = 0x0001;
+	pcspkr_dev->id.version = 0x0100;
 
-	input_register_device(&pcspkr_dev);
+	pcspkr_dev->evbit[0] = BIT(EV_SND);
+	pcspkr_dev->sndbit[0] = BIT(SND_BELL) | BIT(SND_TONE);
+	pcspkr_dev->event = pcspkr_event;
 
-        printk(KERN_INFO "input: %s\n", pcspkr_name);
+	input_register_device(pcspkr_dev);
 
 	return 0;
 }
 
 static void __exit pcspkr_exit(void)
 {
-        input_unregister_device(&pcspkr_dev);
+        input_unregister_device(pcspkr_dev);
 	/* turn off the speaker */
 	pcspkr_event(NULL, EV_SND, SND_BELL, 0);
 }
diff --git a/drivers/input/misc/sparcspkr.c b/drivers/input/misc/sparcspkr.c
index cdc3fb3..5778220 100644
--- a/drivers/input/misc/sparcspkr.c
+++ b/drivers/input/misc/sparcspkr.c
@@ -17,28 +17,24 @@
 #endif
 
 MODULE_AUTHOR("David S. Miller <davem@redhat.com>");
-MODULE_DESCRIPTION("PC Speaker beeper driver");
+MODULE_DESCRIPTION("Sparc Speaker beeper driver");
 MODULE_LICENSE("GPL");
 
 static unsigned long beep_iobase;
-
-static char *sparcspkr_isa_name = "Sparc ISA Speaker";
-static char *sparcspkr_ebus_name = "Sparc EBUS Speaker";
-static char *sparcspkr_phys = "sparc/input0";
-static struct input_dev sparcspkr_dev;
+static struct input_dev *sparcspkr_dev;
 
 DEFINE_SPINLOCK(beep_lock);
 
 static void __init init_sparcspkr_struct(void)
 {
-	sparcspkr_dev.evbit[0] = BIT(EV_SND);
-	sparcspkr_dev.sndbit[0] = BIT(SND_BELL) | BIT(SND_TONE);
+	sparcspkr_dev->evbit[0] = BIT(EV_SND);
+	sparcspkr_dev->sndbit[0] = BIT(SND_BELL) | BIT(SND_TONE);
 
-	sparcspkr_dev.phys = sparcspkr_phys;
-	sparcspkr_dev.id.bustype = BUS_ISA;
-	sparcspkr_dev.id.vendor = 0x001f;
-	sparcspkr_dev.id.product = 0x0001;
-	sparcspkr_dev.id.version = 0x0100;
+	sparcspkr_dev->phys = "sparc/input0";
+	sparcspkr_dev->id.bustype = BUS_ISA;
+	sparcspkr_dev->id.vendor = 0x001f;
+	sparcspkr_dev->id.product = 0x0001;
+	sparcspkr_dev->id.version = 0x0100;
 }
 
 static int ebus_spkr_event(struct input_dev *dev, unsigned int type, unsigned int code, int value)
@@ -84,14 +80,15 @@
 {
 	beep_iobase = edev->resource[0].start;
 
-	init_sparcspkr_struct();
+	sparcspkr_dev = input_allocate_device();
+	if (!sparcspkr_dev)
+		return -ENOMEM;
 
-	sparcspkr_dev.name = sparcspkr_ebus_name;
-	sparcspkr_dev.event = ebus_spkr_event;
+	sparcspkr_dev->name = "Sparc EBUS Speaker";
+	sparcspkr_dev->event = ebus_spkr_event;
 
-	input_register_device(&sparcspkr_dev);
+	input_register_device(sparcspkr_dev);
 
-        printk(KERN_INFO "input: %s\n", sparcspkr_ebus_name);
 	return 0;
 }
 
@@ -137,15 +134,17 @@
 {
 	beep_iobase = isa_dev->resource.start;
 
+	sparcspkr_dev = input_allocate_device();
+	if (!sparcspkr_dev)
+		return -ENOMEM;
+
 	init_sparcspkr_struct();
 
-	sparcspkr_dev.name = sparcspkr_isa_name;
-	sparcspkr_dev.event = isa_spkr_event;
-	sparcspkr_dev.id.bustype = BUS_ISA;
+	sparcspkr_dev->name = "Sparc ISA Speaker";
+	sparcspkr_dev->event = isa_spkr_event;
 
 	input_register_device(&sparcspkr_dev);
 
-        printk(KERN_INFO "input: %s\n", sparcspkr_isa_name);
 	return 0;
 }
 #endif
@@ -182,7 +181,7 @@
 
 static void __exit sparcspkr_exit(void)
 {
-	input_unregister_device(&sparcspkr_dev);
+	input_unregister_device(sparcspkr_dev);
 }
 
 module_init(sparcspkr_init);
diff --git a/drivers/input/mouse/alps.c b/drivers/input/mouse/alps.c
index b20783f..4acc7fd 100644
--- a/drivers/input/mouse/alps.c
+++ b/drivers/input/mouse/alps.c
@@ -79,8 +79,8 @@
 {
 	struct alps_data *priv = psmouse->private;
 	unsigned char *packet = psmouse->packet;
-	struct input_dev *dev = &psmouse->dev;
-	struct input_dev *dev2 = &priv->dev2;
+	struct input_dev *dev = psmouse->dev;
+	struct input_dev *dev2 = priv->dev2;
 	int x, y, z, ges, fin, left, right, middle;
 	int back = 0, forward = 0;
 
@@ -379,20 +379,24 @@
 static void alps_disconnect(struct psmouse *psmouse)
 {
 	struct alps_data *priv = psmouse->private;
+
 	psmouse_reset(psmouse);
-	input_unregister_device(&priv->dev2);
+	input_unregister_device(priv->dev2);
 	kfree(priv);
 }
 
 int alps_init(struct psmouse *psmouse)
 {
 	struct alps_data *priv;
+	struct input_dev *dev1 = psmouse->dev, *dev2;
 	int version;
 
-	psmouse->private = priv = kmalloc(sizeof(struct alps_data), GFP_KERNEL);
-	if (!priv)
+	psmouse->private = priv = kzalloc(sizeof(struct alps_data), GFP_KERNEL);
+	dev2 = input_allocate_device();
+	if (!priv || !dev2)
 		goto init_fail;
-	memset(priv, 0, sizeof(struct alps_data));
+
+	priv->dev2 = dev2;
 
 	if (!(priv->i = alps_get_model(psmouse, &version)))
 		goto init_fail;
@@ -411,41 +415,39 @@
 	if ((priv->i->flags & ALPS_PASS) && alps_passthrough_mode(psmouse, 0))
 		goto init_fail;
 
-	psmouse->dev.evbit[LONG(EV_KEY)] |= BIT(EV_KEY);
-	psmouse->dev.keybit[LONG(BTN_TOUCH)] |= BIT(BTN_TOUCH);
-	psmouse->dev.keybit[LONG(BTN_TOOL_FINGER)] |= BIT(BTN_TOOL_FINGER);
-	psmouse->dev.keybit[LONG(BTN_LEFT)] |= BIT(BTN_LEFT) | BIT(BTN_MIDDLE) | BIT(BTN_RIGHT);
+	dev1->evbit[LONG(EV_KEY)] |= BIT(EV_KEY);
+	dev1->keybit[LONG(BTN_TOUCH)] |= BIT(BTN_TOUCH);
+	dev1->keybit[LONG(BTN_TOOL_FINGER)] |= BIT(BTN_TOOL_FINGER);
+	dev1->keybit[LONG(BTN_LEFT)] |= BIT(BTN_LEFT) | BIT(BTN_MIDDLE) | BIT(BTN_RIGHT);
 
-	psmouse->dev.evbit[LONG(EV_ABS)] |= BIT(EV_ABS);
-	input_set_abs_params(&psmouse->dev, ABS_X, 0, 1023, 0, 0);
-	input_set_abs_params(&psmouse->dev, ABS_Y, 0, 767, 0, 0);
-	input_set_abs_params(&psmouse->dev, ABS_PRESSURE, 0, 127, 0, 0);
+	dev1->evbit[LONG(EV_ABS)] |= BIT(EV_ABS);
+	input_set_abs_params(dev1, ABS_X, 0, 1023, 0, 0);
+	input_set_abs_params(dev1, ABS_Y, 0, 767, 0, 0);
+	input_set_abs_params(dev1, ABS_PRESSURE, 0, 127, 0, 0);
 
 	if (priv->i->flags & ALPS_WHEEL) {
-		psmouse->dev.evbit[LONG(EV_REL)] |= BIT(EV_REL);
-		psmouse->dev.relbit[LONG(REL_WHEEL)] |= BIT(REL_WHEEL);
+		dev1->evbit[LONG(EV_REL)] |= BIT(EV_REL);
+		dev1->relbit[LONG(REL_WHEEL)] |= BIT(REL_WHEEL);
 	}
 
 	if (priv->i->flags & (ALPS_FW_BK_1 | ALPS_FW_BK_2)) {
-		psmouse->dev.keybit[LONG(BTN_FORWARD)] |= BIT(BTN_FORWARD);
-		psmouse->dev.keybit[LONG(BTN_BACK)] |= BIT(BTN_BACK);
+		dev1->keybit[LONG(BTN_FORWARD)] |= BIT(BTN_FORWARD);
+		dev1->keybit[LONG(BTN_BACK)] |= BIT(BTN_BACK);
 	}
 
 	sprintf(priv->phys, "%s/input1", psmouse->ps2dev.serio->phys);
-	priv->dev2.phys = priv->phys;
-	priv->dev2.name = (priv->i->flags & ALPS_DUALPOINT) ? "DualPoint Stick" : "PS/2 Mouse";
-	priv->dev2.id.bustype = BUS_I8042;
-	priv->dev2.id.vendor = 0x0002;
-	priv->dev2.id.product = PSMOUSE_ALPS;
-	priv->dev2.id.version = 0x0000;
+	dev2->phys = priv->phys;
+	dev2->name = (priv->i->flags & ALPS_DUALPOINT) ? "DualPoint Stick" : "PS/2 Mouse";
+	dev2->id.bustype = BUS_I8042;
+	dev2->id.vendor  = 0x0002;
+	dev2->id.product = PSMOUSE_ALPS;
+	dev2->id.version = 0x0000;
 
-	priv->dev2.evbit[0] = BIT(EV_KEY) | BIT(EV_REL);
-	priv->dev2.relbit[LONG(REL_X)] |= BIT(REL_X) | BIT(REL_Y);
-	priv->dev2.keybit[LONG(BTN_LEFT)] |= BIT(BTN_LEFT) | BIT(BTN_MIDDLE) | BIT(BTN_RIGHT);
+	dev2->evbit[0] = BIT(EV_KEY) | BIT(EV_REL);
+	dev2->relbit[LONG(REL_X)] |= BIT(REL_X) | BIT(REL_Y);
+	dev2->keybit[LONG(BTN_LEFT)] |= BIT(BTN_LEFT) | BIT(BTN_MIDDLE) | BIT(BTN_RIGHT);
 
-	input_register_device(&priv->dev2);
-
-	printk(KERN_INFO "input: %s on %s\n", priv->dev2.name, psmouse->ps2dev.serio->phys);
+	input_register_device(priv->dev2);
 
 	psmouse->protocol_handler = alps_process_byte;
 	psmouse->disconnect = alps_disconnect;
@@ -455,6 +457,7 @@
 	return 0;
 
 init_fail:
+	input_free_device(dev2);
 	kfree(priv);
 	return -1;
 }
diff --git a/drivers/input/mouse/alps.h b/drivers/input/mouse/alps.h
index aba103d..e428f8d 100644
--- a/drivers/input/mouse/alps.h
+++ b/drivers/input/mouse/alps.h
@@ -22,7 +22,7 @@
 };
 
 struct alps_data {
-	struct input_dev dev2;		/* Relative device */
+	struct input_dev *dev2;		/* Relative device */
 	char name[32];			/* Name */
 	char phys[32];			/* Phys */
 	struct alps_model_info *i; 	/* Info */
diff --git a/drivers/input/mouse/amimouse.c b/drivers/input/mouse/amimouse.c
index e994849..d13d4c8 100644
--- a/drivers/input/mouse/amimouse.c
+++ b/drivers/input/mouse/amimouse.c
@@ -34,10 +34,7 @@
 MODULE_LICENSE("GPL");
 
 static int amimouse_lastx, amimouse_lasty;
-static struct input_dev amimouse_dev;
-
-static char *amimouse_name = "Amiga mouse";
-static char *amimouse_phys = "amimouse/input0";
+static struct input_dev *amimouse_dev;
 
 static irqreturn_t amimouse_interrupt(int irq, void *dummy, struct pt_regs *fp)
 {
@@ -62,16 +59,16 @@
 
 	potgor = custom.potgor;
 
-	input_regs(&amimouse_dev, fp);
+	input_regs(amimouse_dev, fp);
 
-	input_report_rel(&amimouse_dev, REL_X, dx);
-	input_report_rel(&amimouse_dev, REL_Y, dy);
+	input_report_rel(amimouse_dev, REL_X, dx);
+	input_report_rel(amimouse_dev, REL_Y, dy);
 
-	input_report_key(&amimouse_dev, BTN_LEFT,   ciaa.pra & 0x40);
-	input_report_key(&amimouse_dev, BTN_MIDDLE, potgor & 0x0100);
-	input_report_key(&amimouse_dev, BTN_RIGHT,  potgor & 0x0400);
+	input_report_key(amimouse_dev, BTN_LEFT,   ciaa.pra & 0x40);
+	input_report_key(amimouse_dev, BTN_MIDDLE, potgor & 0x0100);
+	input_report_key(amimouse_dev, BTN_RIGHT,  potgor & 0x0400);
 
-	input_sync(&amimouse_dev);
+	input_sync(amimouse_dev);
 
 	return IRQ_HANDLED;
 }
@@ -103,28 +100,30 @@
 	if (!MACH_IS_AMIGA || !AMIGAHW_PRESENT(AMI_MOUSE))
 		return -ENODEV;
 
-	amimouse_dev.evbit[0] = BIT(EV_KEY) | BIT(EV_REL);
-	amimouse_dev.relbit[0] = BIT(REL_X) | BIT(REL_Y);
-	amimouse_dev.keybit[LONG(BTN_LEFT)] = BIT(BTN_LEFT) | BIT(BTN_MIDDLE) | BIT(BTN_RIGHT);
-	amimouse_dev.open = amimouse_open;
-	amimouse_dev.close = amimouse_close;
+	if (!(amimouse_dev = input_allocate_device()))
+		return -ENOMEM;
 
-	amimouse_dev.name = amimouse_name;
-	amimouse_dev.phys = amimouse_phys;
-	amimouse_dev.id.bustype = BUS_AMIGA;
-	amimouse_dev.id.vendor = 0x0001;
-	amimouse_dev.id.product = 0x0002;
-	amimouse_dev.id.version = 0x0100;
+	amimouse_dev->name = "Amiga mouse";
+	amimouse_dev->phys = "amimouse/input0";
+	amimouse_dev->id.bustype = BUS_AMIGA;
+	amimouse_dev->id.vendor = 0x0001;
+	amimouse_dev->id.product = 0x0002;
+	amimouse_dev->id.version = 0x0100;
 
-	input_register_device(&amimouse_dev);
+	amimouse_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REL);
+	amimouse_dev->relbit[0] = BIT(REL_X) | BIT(REL_Y);
+	amimouse_dev->keybit[LONG(BTN_LEFT)] = BIT(BTN_LEFT) | BIT(BTN_MIDDLE) | BIT(BTN_RIGHT);
+	amimouse_dev->open = amimouse_open;
+	amimouse_dev->close = amimouse_close;
 
-        printk(KERN_INFO "input: %s at joy0dat\n", amimouse_name);
+	input_register_device(amimouse_dev);
+
 	return 0;
 }
 
 static void __exit amimouse_exit(void)
 {
-        input_unregister_device(&amimouse_dev);
+        input_unregister_device(amimouse_dev);
 }
 
 module_init(amimouse_init);
diff --git a/drivers/input/mouse/inport.c b/drivers/input/mouse/inport.c
index 1f62c01..afc66f5 100644
--- a/drivers/input/mouse/inport.c
+++ b/drivers/input/mouse/inport.c
@@ -87,7 +87,36 @@
 
 __obsolete_setup("inport_irq=");
 
-static irqreturn_t inport_interrupt(int irq, void *dev_id, struct pt_regs *regs);
+static struct input_dev *inport_dev;
+
+static irqreturn_t inport_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+{
+	unsigned char buttons;
+
+	outb(INPORT_REG_MODE, INPORT_CONTROL_PORT);
+	outb(INPORT_MODE_HOLD | INPORT_MODE_IRQ | INPORT_MODE_BASE, INPORT_DATA_PORT);
+
+	input_regs(inport_dev, regs);
+
+	outb(INPORT_REG_X, INPORT_CONTROL_PORT);
+	input_report_rel(inport_dev, REL_X, inb(INPORT_DATA_PORT));
+
+	outb(INPORT_REG_Y, INPORT_CONTROL_PORT);
+	input_report_rel(inport_dev, REL_Y, inb(INPORT_DATA_PORT));
+
+	outb(INPORT_REG_BTNS, INPORT_CONTROL_PORT);
+	buttons = inb(INPORT_DATA_PORT);
+
+	input_report_key(inport_dev, BTN_MIDDLE, buttons & 1);
+	input_report_key(inport_dev, BTN_LEFT,   buttons & 2);
+	input_report_key(inport_dev, BTN_RIGHT,  buttons & 4);
+
+	outb(INPORT_REG_MODE, INPORT_CONTROL_PORT);
+	outb(INPORT_MODE_IRQ | INPORT_MODE_BASE, INPORT_DATA_PORT);
+
+	input_sync(inport_dev);
+	return IRQ_HANDLED;
+}
 
 static int inport_open(struct input_dev *dev)
 {
@@ -106,54 +135,9 @@
 	free_irq(inport_irq, NULL);
 }
 
-static struct input_dev inport_dev = {
-	.evbit	= { BIT(EV_KEY) | BIT(EV_REL) },
-	.keybit	= { [LONG(BTN_LEFT)] = BIT(BTN_LEFT) | BIT(BTN_MIDDLE) | BIT(BTN_RIGHT) },
-	.relbit	= { BIT(REL_X) | BIT(REL_Y) },
-	.open	= inport_open,
-	.close	= inport_close,
-	.name	= INPORT_NAME,
-	.phys	= "isa023c/input0",
-	.id = {
-		.bustype = BUS_ISA,
-		.vendor  = INPORT_VENDOR,
-		.product = 0x0001,
-		.version = 0x0100,
-	},
-};
-
-static irqreturn_t inport_interrupt(int irq, void *dev_id, struct pt_regs *regs)
-{
-	unsigned char buttons;
-
-	outb(INPORT_REG_MODE, INPORT_CONTROL_PORT);
-	outb(INPORT_MODE_HOLD | INPORT_MODE_IRQ | INPORT_MODE_BASE, INPORT_DATA_PORT);
-
-	input_regs(&inport_dev, regs);
-
-	outb(INPORT_REG_X, INPORT_CONTROL_PORT);
-	input_report_rel(&inport_dev, REL_X, inb(INPORT_DATA_PORT));
-
-	outb(INPORT_REG_Y, INPORT_CONTROL_PORT);
-	input_report_rel(&inport_dev, REL_Y, inb(INPORT_DATA_PORT));
-
-	outb(INPORT_REG_BTNS, INPORT_CONTROL_PORT);
-	buttons = inb(INPORT_DATA_PORT);
-
-	input_report_key(&inport_dev, BTN_MIDDLE, buttons & 1);
-	input_report_key(&inport_dev, BTN_LEFT,   buttons & 2);
-	input_report_key(&inport_dev, BTN_RIGHT,  buttons & 4);
-
-	outb(INPORT_REG_MODE, INPORT_CONTROL_PORT);
-	outb(INPORT_MODE_IRQ | INPORT_MODE_BASE, INPORT_DATA_PORT);
-
-	input_sync(&inport_dev);
-	return IRQ_HANDLED;
-}
-
 static int __init inport_init(void)
 {
-	unsigned char a,b,c;
+	unsigned char a, b, c;
 
 	if (!request_region(INPORT_BASE, INPORT_EXTENT, "inport")) {
 		printk(KERN_ERR "inport.c: Can't allocate ports at %#x\n", INPORT_BASE);
@@ -163,26 +147,44 @@
 	a = inb(INPORT_SIGNATURE_PORT);
 	b = inb(INPORT_SIGNATURE_PORT);
 	c = inb(INPORT_SIGNATURE_PORT);
-	if (( a == b ) || ( a != c )) {
+	if (a == b || a != c) {
 		release_region(INPORT_BASE, INPORT_EXTENT);
 		printk(KERN_ERR "inport.c: Didn't find InPort mouse at %#x\n", INPORT_BASE);
 		return -ENODEV;
 	}
 
+	if (!(inport_dev = input_allocate_device())) {
+		printk(KERN_ERR "inport.c: Not enough memory for input device\n");
+		release_region(INPORT_BASE, INPORT_EXTENT);
+		return -ENOMEM;
+	}
+
+	inport_dev->name = INPORT_NAME;
+	inport_dev->phys = "isa023c/input0";
+	inport_dev->id.bustype = BUS_ISA;
+	inport_dev->id.vendor  = INPORT_VENDOR;
+	inport_dev->id.product = 0x0001;
+	inport_dev->id.version = 0x0100;
+
+	inport_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REL);
+	inport_dev->keybit[LONG(BTN_LEFT)] = BIT(BTN_LEFT) | BIT(BTN_MIDDLE) | BIT(BTN_RIGHT);
+	inport_dev->relbit[0] = BIT(REL_X) | BIT(REL_Y);
+
+	inport_dev->open  = inport_open;
+	inport_dev->close = inport_close;
+
 	outb(INPORT_RESET, INPORT_CONTROL_PORT);
 	outb(INPORT_REG_MODE, INPORT_CONTROL_PORT);
 	outb(INPORT_MODE_BASE, INPORT_DATA_PORT);
 
-	input_register_device(&inport_dev);
-
-	printk(KERN_INFO "input: " INPORT_NAME " at %#x irq %d\n", INPORT_BASE, inport_irq);
+	input_register_device(inport_dev);
 
 	return 0;
 }
 
 static void __exit inport_exit(void)
 {
-	input_unregister_device(&inport_dev);
+	input_unregister_device(inport_dev);
 	release_region(INPORT_BASE, INPORT_EXTENT);
 }
 
diff --git a/drivers/input/mouse/lifebook.c b/drivers/input/mouse/lifebook.c
index bd9df9b..5599142 100644
--- a/drivers/input/mouse/lifebook.c
+++ b/drivers/input/mouse/lifebook.c
@@ -34,7 +34,7 @@
 static psmouse_ret_t lifebook_process_byte(struct psmouse *psmouse, struct pt_regs *regs)
 {
 	unsigned char *packet = psmouse->packet;
-	struct input_dev *dev = &psmouse->dev;
+	struct input_dev *dev = psmouse->dev;
 
 	if (psmouse->pktcnt != 3)
 		return PSMOUSE_GOOD_DATA;
@@ -113,15 +113,17 @@
 
 int lifebook_init(struct psmouse *psmouse)
 {
+	struct input_dev *input_dev = psmouse->dev;
+
 	if (lifebook_absolute_mode(psmouse))
 		return -1;
 
-	psmouse->dev.evbit[0] = BIT(EV_ABS) | BIT(EV_KEY) | BIT(EV_REL);
-	psmouse->dev.keybit[LONG(BTN_LEFT)] = BIT(BTN_LEFT) | BIT(BTN_MIDDLE) | BIT(BTN_RIGHT);
-	psmouse->dev.keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH);
-	psmouse->dev.relbit[0] = BIT(REL_X) | BIT(REL_Y);
-	input_set_abs_params(&psmouse->dev, ABS_X, 0, 1024, 0, 0);
-	input_set_abs_params(&psmouse->dev, ABS_Y, 0, 1024, 0, 0);
+	input_dev->evbit[0] = BIT(EV_ABS) | BIT(EV_KEY) | BIT(EV_REL);
+	input_dev->keybit[LONG(BTN_LEFT)] = BIT(BTN_LEFT) | BIT(BTN_MIDDLE) | BIT(BTN_RIGHT);
+	input_dev->keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH);
+	input_dev->relbit[0] = BIT(REL_X) | BIT(REL_Y);
+	input_set_abs_params(input_dev, ABS_X, 0, 1024, 0, 0);
+	input_set_abs_params(input_dev, ABS_Y, 0, 1024, 0, 0);
 
 	psmouse->protocol_handler = lifebook_process_byte;
 	psmouse->set_resolution = lifebook_set_resolution;
diff --git a/drivers/input/mouse/logibm.c b/drivers/input/mouse/logibm.c
index 8b52431..9c7ce38 100644
--- a/drivers/input/mouse/logibm.c
+++ b/drivers/input/mouse/logibm.c
@@ -77,39 +77,7 @@
 
 __obsolete_setup("logibm_irq=");
 
-static irqreturn_t logibm_interrupt(int irq, void *dev_id, struct pt_regs *regs);
-
-static int logibm_open(struct input_dev *dev)
-{
-	if (request_irq(logibm_irq, logibm_interrupt, 0, "logibm", NULL)) {
-		printk(KERN_ERR "logibm.c: Can't allocate irq %d\n", logibm_irq);
-		return -EBUSY;
-	}
-	outb(LOGIBM_ENABLE_IRQ, LOGIBM_CONTROL_PORT);
-	return 0;
-}
-
-static void logibm_close(struct input_dev *dev)
-{
-	outb(LOGIBM_DISABLE_IRQ, LOGIBM_CONTROL_PORT);
-	free_irq(logibm_irq, NULL);
-}
-
-static struct input_dev logibm_dev = {
-	.evbit	= { BIT(EV_KEY) | BIT(EV_REL) },
-	.keybit = { [LONG(BTN_LEFT)] = BIT(BTN_LEFT) | BIT(BTN_MIDDLE) | BIT(BTN_RIGHT) },
-	.relbit	= { BIT(REL_X) | BIT(REL_Y) },
-	.open	= logibm_open,
-	.close	= logibm_close,
-	.name	= "Logitech bus mouse",
-	.phys	= "isa023c/input0",
-	.id	= {
-		.bustype = BUS_ISA,
-		.vendor  = 0x0003,
-		.product = 0x0001,
-		.version = 0x0100,
-	},
-};
+static struct input_dev *logibm_dev;
 
 static irqreturn_t logibm_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 {
@@ -127,18 +95,34 @@
 	dy |= (buttons & 0xf) << 4;
 	buttons = ~buttons >> 5;
 
-	input_regs(&logibm_dev, regs);
-	input_report_rel(&logibm_dev, REL_X, dx);
-	input_report_rel(&logibm_dev, REL_Y, dy);
-	input_report_key(&logibm_dev, BTN_RIGHT,  buttons & 1);
-	input_report_key(&logibm_dev, BTN_MIDDLE, buttons & 2);
-	input_report_key(&logibm_dev, BTN_LEFT,   buttons & 4);
-	input_sync(&logibm_dev);
+	input_regs(logibm_dev, regs);
+	input_report_rel(logibm_dev, REL_X, dx);
+	input_report_rel(logibm_dev, REL_Y, dy);
+	input_report_key(logibm_dev, BTN_RIGHT,  buttons & 1);
+	input_report_key(logibm_dev, BTN_MIDDLE, buttons & 2);
+	input_report_key(logibm_dev, BTN_LEFT,   buttons & 4);
+	input_sync(logibm_dev);
 
 	outb(LOGIBM_ENABLE_IRQ, LOGIBM_CONTROL_PORT);
 	return IRQ_HANDLED;
 }
 
+static int logibm_open(struct input_dev *dev)
+{
+	if (request_irq(logibm_irq, logibm_interrupt, 0, "logibm", NULL)) {
+		printk(KERN_ERR "logibm.c: Can't allocate irq %d\n", logibm_irq);
+		return -EBUSY;
+	}
+	outb(LOGIBM_ENABLE_IRQ, LOGIBM_CONTROL_PORT);
+	return 0;
+}
+
+static void logibm_close(struct input_dev *dev)
+{
+	outb(LOGIBM_DISABLE_IRQ, LOGIBM_CONTROL_PORT);
+	free_irq(logibm_irq, NULL);
+}
+
 static int __init logibm_init(void)
 {
 	if (!request_region(LOGIBM_BASE, LOGIBM_EXTENT, "logibm")) {
@@ -159,16 +143,34 @@
 	outb(LOGIBM_DEFAULT_MODE, LOGIBM_CONFIG_PORT);
 	outb(LOGIBM_DISABLE_IRQ, LOGIBM_CONTROL_PORT);
 
-	input_register_device(&logibm_dev);
+	if (!(logibm_dev = input_allocate_device())) {
+		printk(KERN_ERR "logibm.c: Not enough memory for input device\n");
+		release_region(LOGIBM_BASE, LOGIBM_EXTENT);
+		return -ENOMEM;
+	}
 
-	printk(KERN_INFO "input: Logitech bus mouse at %#x irq %d\n", LOGIBM_BASE, logibm_irq);
+	logibm_dev->name = "Logitech bus mouse";
+	logibm_dev->phys = "isa023c/input0";
+	logibm_dev->id.bustype = BUS_ISA;
+	logibm_dev->id.vendor  = 0x0003;
+	logibm_dev->id.product = 0x0001;
+	logibm_dev->id.version = 0x0100;
+
+	logibm_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REL);
+	logibm_dev->keybit[LONG(BTN_LEFT)] = BIT(BTN_LEFT) | BIT(BTN_MIDDLE) | BIT(BTN_RIGHT);
+	logibm_dev->relbit[0] = BIT(REL_X) | BIT(REL_Y);
+
+	logibm_dev->open  = logibm_open;
+	logibm_dev->close = logibm_close;
+
+	input_register_device(logibm_dev);
 
 	return 0;
 }
 
 static void __exit logibm_exit(void)
 {
-	input_unregister_device(&logibm_dev);
+	input_unregister_device(logibm_dev);
 	release_region(LOGIBM_BASE, LOGIBM_EXTENT);
 }
 
diff --git a/drivers/input/mouse/logips2pp.c b/drivers/input/mouse/logips2pp.c
index 7df9652..0f69ff4 100644
--- a/drivers/input/mouse/logips2pp.c
+++ b/drivers/input/mouse/logips2pp.c
@@ -40,7 +40,7 @@
 
 static psmouse_ret_t ps2pp_process_byte(struct psmouse *psmouse, struct pt_regs *regs)
 {
-	struct input_dev *dev = &psmouse->dev;
+	struct input_dev *dev = psmouse->dev;
 	unsigned char *packet = psmouse->packet;
 
 	if (psmouse->pktcnt < 3)
@@ -257,25 +257,27 @@
 static void ps2pp_set_model_properties(struct psmouse *psmouse, struct ps2pp_info *model_info,
 				       int using_ps2pp)
 {
+	struct input_dev *input_dev = psmouse->dev;
+
 	if (model_info->features & PS2PP_SIDE_BTN)
-		set_bit(BTN_SIDE, psmouse->dev.keybit);
+		set_bit(BTN_SIDE, input_dev->keybit);
 
 	if (model_info->features & PS2PP_EXTRA_BTN)
-		set_bit(BTN_EXTRA, psmouse->dev.keybit);
+		set_bit(BTN_EXTRA, input_dev->keybit);
 
 	if (model_info->features & PS2PP_TASK_BTN)
-		set_bit(BTN_TASK, psmouse->dev.keybit);
+		set_bit(BTN_TASK, input_dev->keybit);
 
 	if (model_info->features & PS2PP_NAV_BTN) {
-		set_bit(BTN_FORWARD, psmouse->dev.keybit);
-		set_bit(BTN_BACK, psmouse->dev.keybit);
+		set_bit(BTN_FORWARD, input_dev->keybit);
+		set_bit(BTN_BACK, input_dev->keybit);
 	}
 
 	if (model_info->features & PS2PP_WHEEL)
-		set_bit(REL_WHEEL, psmouse->dev.relbit);
+		set_bit(REL_WHEEL, input_dev->relbit);
 
 	if (model_info->features & PS2PP_HWHEEL)
-		set_bit(REL_HWHEEL, psmouse->dev.relbit);
+		set_bit(REL_HWHEEL, input_dev->relbit);
 
 	switch (model_info->kind) {
 		case PS2PP_KIND_WHEEL:
@@ -387,7 +389,7 @@
 		}
 
 		if (buttons < 3)
-			clear_bit(BTN_MIDDLE, psmouse->dev.keybit);
+			clear_bit(BTN_MIDDLE, psmouse->dev->keybit);
 
 		if (model_info)
 			ps2pp_set_model_properties(psmouse, model_info, use_ps2pp);
diff --git a/drivers/input/mouse/maplemouse.c b/drivers/input/mouse/maplemouse.c
index e90c60c..b5b34fe 100644
--- a/drivers/input/mouse/maplemouse.c
+++ b/drivers/input/mouse/maplemouse.c
@@ -41,13 +41,12 @@
 	unsigned long data = be32_to_cpu(dev->devinfo.function_data[0]);
 	struct input_dev *input_dev;
 
-	if (!(input_dev = kmalloc(sizeof(struct input_dev), GFP_KERNEL)))
-		return -1;
+	dev->private_data = input_dev = input_allocate_device();
+	if (!input_dev)
+		return -ENOMEM;
 
 	dev->private_data = input_dev;
 
-	memset(input_dev, 0, sizeof(struct dc_mouse));
-	init_input_dev(input_dev);
 	input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REL);
 	input_dev->keybit[LONG(BTN_MOUSE)] = BIT(BTN_LEFT) | BIT(BTN_RIGHT) | BIT(BTN_MIDDLE);
 	input_dev->relbit[0] = BIT(REL_X) | BIT(REL_Y) | BIT(REL_WHEEL);
@@ -59,8 +58,6 @@
 
 	maple_getcond_callback(dev, dc_mouse_callback, 1, MAPLE_FUNC_MOUSE);
 
-	printk(KERN_INFO "input: mouse(0x%lx): %s\n", data, input_dev->name);
-
 	return 0;
 }
 
@@ -70,7 +67,6 @@
 	struct input_dev *input_dev = dev->private_data;
 
 	input_unregister_device(input_dev);
-	kfree(input_dev);
 }
 
 
diff --git a/drivers/input/mouse/pc110pad.c b/drivers/input/mouse/pc110pad.c
index 93393d5..d284ea7 100644
--- a/drivers/input/mouse/pc110pad.c
+++ b/drivers/input/mouse/pc110pad.c
@@ -53,13 +53,10 @@
 static int pc110pad_irq = 10;
 static int pc110pad_io = 0x15e0;
 
-static struct input_dev pc110pad_dev;
+static struct input_dev *pc110pad_dev;
 static int pc110pad_data[3];
 static int pc110pad_count;
 
-static char *pc110pad_name = "IBM PC110 TouchPad";
-static char *pc110pad_phys = "isa15e0/input0";
-
 static irqreturn_t pc110pad_interrupt(int irq, void *ptr, struct pt_regs *regs)
 {
 	int value     = inb_p(pc110pad_io);
@@ -74,14 +71,14 @@
 	if (pc110pad_count < 3)
 		return IRQ_HANDLED;
 
-	input_regs(&pc110pad_dev, regs);
-	input_report_key(&pc110pad_dev, BTN_TOUCH,
+	input_regs(pc110pad_dev, regs);
+	input_report_key(pc110pad_dev, BTN_TOUCH,
 		pc110pad_data[0] & 0x01);
-	input_report_abs(&pc110pad_dev, ABS_X,
+	input_report_abs(pc110pad_dev, ABS_X,
 		pc110pad_data[1] | ((pc110pad_data[0] << 3) & 0x80) | ((pc110pad_data[0] << 1) & 0x100));
-	input_report_abs(&pc110pad_dev, ABS_Y,
+	input_report_abs(pc110pad_dev, ABS_Y,
 		pc110pad_data[2] | ((pc110pad_data[0] << 4) & 0x80));
-	input_sync(&pc110pad_dev);
+	input_sync(pc110pad_dev);
 
 	pc110pad_count = 0;
 	return IRQ_HANDLED;
@@ -94,9 +91,9 @@
 
 static int pc110pad_open(struct input_dev *dev)
 {
-	pc110pad_interrupt(0,NULL,NULL);
-	pc110pad_interrupt(0,NULL,NULL);
-	pc110pad_interrupt(0,NULL,NULL);
+	pc110pad_interrupt(0, NULL, NULL);
+	pc110pad_interrupt(0, NULL, NULL);
+	pc110pad_interrupt(0, NULL, NULL);
 	outb(PC110PAD_ON, pc110pad_io + 2);
 	pc110pad_count = 0;
 
@@ -127,45 +124,46 @@
 
 	outb(PC110PAD_OFF, pc110pad_io + 2);
 
-	if (request_irq(pc110pad_irq, pc110pad_interrupt, 0, "pc110pad", NULL))
-	{
+	if (request_irq(pc110pad_irq, pc110pad_interrupt, 0, "pc110pad", NULL)) {
 		release_region(pc110pad_io, 4);
 		printk(KERN_ERR "pc110pad: Unable to get irq %d.\n", pc110pad_irq);
 		return -EBUSY;
 	}
 
-        pc110pad_dev.evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
-        pc110pad_dev.absbit[0] = BIT(ABS_X) | BIT(ABS_Y);
-        pc110pad_dev.keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH);
+	if (!(pc110pad_dev = input_allocate_device())) {
+		free_irq(pc110pad_irq, NULL);
+		release_region(pc110pad_io, 4);
+		printk(KERN_ERR "pc110pad: Not enough memory.\n");
+		return -ENOMEM;
+	}
 
-	pc110pad_dev.absmax[ABS_X] = 0x1ff;
-	pc110pad_dev.absmax[ABS_Y] = 0x0ff;
+	pc110pad_dev->name = "IBM PC110 TouchPad";
+	pc110pad_dev->phys = "isa15e0/input0";
+	pc110pad_dev->id.bustype = BUS_ISA;
+	pc110pad_dev->id.vendor = 0x0003;
+	pc110pad_dev->id.product = 0x0001;
+	pc110pad_dev->id.version = 0x0100;
 
-	pc110pad_dev.open = pc110pad_open;
-        pc110pad_dev.close = pc110pad_close;
+	pc110pad_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
+	pc110pad_dev->absbit[0] = BIT(ABS_X) | BIT(ABS_Y);
+	pc110pad_dev->keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH);
 
-	pc110pad_dev.name = pc110pad_name;
-	pc110pad_dev.phys = pc110pad_phys;
-	pc110pad_dev.id.bustype = BUS_ISA;
-	pc110pad_dev.id.vendor = 0x0003;
-	pc110pad_dev.id.product = 0x0001;
-	pc110pad_dev.id.version = 0x0100;
+	pc110pad_dev->absmax[ABS_X] = 0x1ff;
+	pc110pad_dev->absmax[ABS_Y] = 0x0ff;
 
-	input_register_device(&pc110pad_dev);
+	pc110pad_dev->open = pc110pad_open;
+	pc110pad_dev->close = pc110pad_close;
 
-	printk(KERN_INFO "input: %s at %#x irq %d\n",
-		pc110pad_name, pc110pad_io, pc110pad_irq);
+	input_register_device(pc110pad_dev);
 
 	return 0;
 }
 
 static void __exit pc110pad_exit(void)
 {
-	input_unregister_device(&pc110pad_dev);
-
 	outb(PC110PAD_OFF, pc110pad_io + 2);
-
 	free_irq(pc110pad_irq, NULL);
+	input_unregister_device(pc110pad_dev);
 	release_region(pc110pad_io, 4);
 }
 
diff --git a/drivers/input/mouse/psmouse-base.c b/drivers/input/mouse/psmouse-base.c
index af24313..6ee9999 100644
--- a/drivers/input/mouse/psmouse-base.c
+++ b/drivers/input/mouse/psmouse-base.c
@@ -114,7 +114,7 @@
 
 static psmouse_ret_t psmouse_process_byte(struct psmouse *psmouse, struct pt_regs *regs)
 {
-	struct input_dev *dev = &psmouse->dev;
+	struct input_dev *dev = psmouse->dev;
 	unsigned char *packet = psmouse->packet;
 
 	if (psmouse->pktcnt < psmouse->pktsize)
@@ -333,12 +333,11 @@
 		return -1;
 
 	if (set_properties) {
-		set_bit(BTN_EXTRA, psmouse->dev.keybit);
-		set_bit(BTN_SIDE, psmouse->dev.keybit);
-		set_bit(REL_WHEEL, psmouse->dev.relbit);
+		set_bit(BTN_EXTRA, psmouse->dev->keybit);
+		set_bit(BTN_SIDE, psmouse->dev->keybit);
+		set_bit(REL_WHEEL, psmouse->dev->relbit);
 
 		psmouse->vendor = "Genius";
-		psmouse->name = "Wheel Mouse";
 		psmouse->pktsize = 4;
 	}
 
@@ -365,8 +364,8 @@
 		return -1;
 
 	if (set_properties) {
-		set_bit(BTN_MIDDLE, psmouse->dev.keybit);
-		set_bit(REL_WHEEL, psmouse->dev.relbit);
+		set_bit(BTN_MIDDLE, psmouse->dev->keybit);
+		set_bit(REL_WHEEL, psmouse->dev->relbit);
 
 		if (!psmouse->vendor) psmouse->vendor = "Generic";
 		if (!psmouse->name) psmouse->name = "Wheel Mouse";
@@ -398,10 +397,10 @@
 		return -1;
 
 	if (set_properties) {
-		set_bit(BTN_MIDDLE, psmouse->dev.keybit);
-		set_bit(REL_WHEEL, psmouse->dev.relbit);
-		set_bit(BTN_SIDE, psmouse->dev.keybit);
-		set_bit(BTN_EXTRA, psmouse->dev.keybit);
+		set_bit(BTN_MIDDLE, psmouse->dev->keybit);
+		set_bit(REL_WHEEL, psmouse->dev->relbit);
+		set_bit(BTN_SIDE, psmouse->dev->keybit);
+		set_bit(BTN_EXTRA, psmouse->dev->keybit);
 
 		if (!psmouse->vendor) psmouse->vendor = "Generic";
 		if (!psmouse->name) psmouse->name = "Explorer Mouse";
@@ -433,7 +432,7 @@
 		return -1;
 
 	if (set_properties) {
-		set_bit(BTN_EXTRA, psmouse->dev.keybit);
+		set_bit(BTN_EXTRA, psmouse->dev->keybit);
 
 		psmouse->vendor = "Kensington";
 		psmouse->name = "ThinkingMouse";
@@ -839,9 +838,9 @@
 
 	psmouse_set_state(psmouse, PSMOUSE_IGNORE);
 
-	input_unregister_device(&psmouse->dev);
 	serio_close(serio);
 	serio_set_drvdata(serio, NULL);
+	input_unregister_device(psmouse->dev);
 	kfree(psmouse);
 
 	if (parent)
@@ -852,16 +851,14 @@
 
 static int psmouse_switch_protocol(struct psmouse *psmouse, struct psmouse_protocol *proto)
 {
-	memset(&psmouse->dev, 0, sizeof(struct input_dev));
+	struct input_dev *input_dev = psmouse->dev;
 
-	init_input_dev(&psmouse->dev);
+	input_dev->private = psmouse;
+	input_dev->cdev.dev = &psmouse->ps2dev.serio->dev;
 
-	psmouse->dev.private = psmouse;
-	psmouse->dev.dev = &psmouse->ps2dev.serio->dev;
-
-	psmouse->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_REL);
-	psmouse->dev.keybit[LONG(BTN_MOUSE)] = BIT(BTN_LEFT) | BIT(BTN_MIDDLE) | BIT(BTN_RIGHT);
-	psmouse->dev.relbit[0] = BIT(REL_X) | BIT(REL_Y);
+	input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REL);
+	input_dev->keybit[LONG(BTN_MOUSE)] = BIT(BTN_LEFT) | BIT(BTN_MIDDLE) | BIT(BTN_RIGHT);
+	input_dev->relbit[0] = BIT(REL_X) | BIT(REL_Y);
 
 	psmouse->set_rate = psmouse_set_rate;
 	psmouse->set_resolution = psmouse_set_resolution;
@@ -883,12 +880,12 @@
 	sprintf(psmouse->devname, "%s %s %s",
 		psmouse_protocol_by_type(psmouse->type)->name, psmouse->vendor, psmouse->name);
 
-	psmouse->dev.name = psmouse->devname;
-	psmouse->dev.phys = psmouse->phys;
-	psmouse->dev.id.bustype = BUS_I8042;
-	psmouse->dev.id.vendor = 0x0002;
-	psmouse->dev.id.product = psmouse->type;
-	psmouse->dev.id.version = psmouse->model;
+	input_dev->name = psmouse->devname;
+	input_dev->phys = psmouse->phys;
+	input_dev->id.bustype = BUS_I8042;
+	input_dev->id.vendor = 0x0002;
+	input_dev->id.product = psmouse->type;
+	input_dev->id.version = psmouse->model;
 
 	return 0;
 }
@@ -900,7 +897,8 @@
 static int psmouse_connect(struct serio *serio, struct serio_driver *drv)
 {
 	struct psmouse *psmouse, *parent = NULL;
-	int retval;
+	struct input_dev *input_dev;
+	int retval = -ENOMEM;
 
 	down(&psmouse_sem);
 
@@ -913,12 +911,13 @@
 		psmouse_deactivate(parent);
 	}
 
-	if (!(psmouse = kzalloc(sizeof(struct psmouse), GFP_KERNEL))) {
-		retval = -ENOMEM;
+	psmouse = kzalloc(sizeof(struct psmouse), GFP_KERNEL);
+	input_dev = input_allocate_device();
+	if (!psmouse || !input_dev)
 		goto out;
-	}
 
 	ps2_init(&psmouse->ps2dev, serio);
+	psmouse->dev = input_dev;
 	sprintf(psmouse->phys, "%s/input0", serio->phys);
 
 	psmouse_set_state(psmouse, PSMOUSE_INITIALIZING);
@@ -926,16 +925,11 @@
 	serio_set_drvdata(serio, psmouse);
 
 	retval = serio_open(serio, drv);
-	if (retval) {
-		serio_set_drvdata(serio, NULL);
-		kfree(psmouse);
+	if (retval)
 		goto out;
-	}
 
 	if (psmouse_probe(psmouse) < 0) {
 		serio_close(serio);
-		serio_set_drvdata(serio, NULL);
-		kfree(psmouse);
 		retval = -ENODEV;
 		goto out;
 	}
@@ -947,13 +941,11 @@
 
 	psmouse_switch_protocol(psmouse, NULL);
 
-	input_register_device(&psmouse->dev);
-	printk(KERN_INFO "input: %s on %s\n", psmouse->devname, serio->phys);
-
 	psmouse_set_state(psmouse, PSMOUSE_CMD_MODE);
-
 	psmouse_initialize(psmouse);
 
+	input_register_device(psmouse->dev);
+
 	if (parent && parent->pt_activate)
 		parent->pt_activate(parent);
 
@@ -964,6 +956,12 @@
 	retval = 0;
 
 out:
+	if (retval) {
+		serio_set_drvdata(serio, NULL);
+		input_free_device(input_dev);
+		kfree(psmouse);
+	}
+
 	/* If this is a pass-through port the parent needs to be re-activated */
 	if (parent)
 		psmouse_activate(parent);
@@ -1161,6 +1159,7 @@
 {
 	struct serio *serio = psmouse->ps2dev.serio;
 	struct psmouse *parent = NULL;
+	struct input_dev *new_dev;
 	struct psmouse_protocol *proto;
 	int retry = 0;
 
@@ -1170,9 +1169,13 @@
 	if (psmouse->type == proto->type)
 		return count;
 
+	if (!(new_dev = input_allocate_device()))
+		return -ENOMEM;
+
 	while (serio->child) {
 		if (++retry > 3) {
 			printk(KERN_WARNING "psmouse: failed to destroy child port, protocol change aborted.\n");
+			input_free_device(new_dev);
 			return -EIO;
 		}
 
@@ -1182,11 +1185,15 @@
 		serio_pin_driver_uninterruptible(serio);
 		down(&psmouse_sem);
 
-		if (serio->drv != &psmouse_drv)
+		if (serio->drv != &psmouse_drv) {
+			input_free_device(new_dev);
 			return -ENODEV;
+		}
 
-		if (psmouse->type == proto->type)
+		if (psmouse->type == proto->type) {
+			input_free_device(new_dev);
 			return count; /* switched by other thread */
+		}
 	}
 
 	if (serio->parent && serio->id.type == SERIO_PS_PSTHRU) {
@@ -1199,8 +1206,9 @@
 		psmouse->disconnect(psmouse);
 
 	psmouse_set_state(psmouse, PSMOUSE_IGNORE);
-	input_unregister_device(&psmouse->dev);
+	input_unregister_device(psmouse->dev);
 
+	psmouse->dev = new_dev;
 	psmouse_set_state(psmouse, PSMOUSE_INITIALIZING);
 
 	if (psmouse_switch_protocol(psmouse, proto) < 0) {
@@ -1212,8 +1220,7 @@
 	psmouse_initialize(psmouse);
 	psmouse_set_state(psmouse, PSMOUSE_CMD_MODE);
 
-	input_register_device(&psmouse->dev);
-	printk(KERN_INFO "input: %s on %s\n", psmouse->devname, serio->phys);
+	input_register_device(psmouse->dev);
 
 	if (parent && parent->pt_activate)
 		parent->pt_activate(parent);
diff --git a/drivers/input/mouse/psmouse.h b/drivers/input/mouse/psmouse.h
index 45d2bd7..7c4192b 100644
--- a/drivers/input/mouse/psmouse.h
+++ b/drivers/input/mouse/psmouse.h
@@ -36,7 +36,7 @@
 
 struct psmouse {
 	void *private;
-	struct input_dev dev;
+	struct input_dev *dev;
 	struct ps2dev ps2dev;
 	char *vendor;
 	char *name;
diff --git a/drivers/input/mouse/rpcmouse.c b/drivers/input/mouse/rpcmouse.c
index 8fe1212..09b6ffd 100644
--- a/drivers/input/mouse/rpcmouse.c
+++ b/drivers/input/mouse/rpcmouse.c
@@ -34,20 +34,7 @@
 MODULE_LICENSE("GPL");
 
 static short rpcmouse_lastx, rpcmouse_lasty;
-
-static struct input_dev rpcmouse_dev = {
-	.evbit	= { BIT(EV_KEY) | BIT(EV_REL) },
-	.keybit = { [LONG(BTN_LEFT)] = BIT(BTN_LEFT) | BIT(BTN_MIDDLE) | BIT(BTN_RIGHT) },
-	.relbit	= { BIT(REL_X) | BIT(REL_Y) },
-	.name	= "Acorn RiscPC Mouse",
-	.phys	= "rpcmouse/input0",
-	.id	= {
-		.bustype = BUS_HOST,
-		.vendor  = 0x0005,
-		.product = 0x0001,
-		.version = 0x0100,
-	},
-};
+static struct input_dev *rpcmouse_dev;
 
 static irqreturn_t rpcmouse_irq(int irq, void *dev_id, struct pt_regs *regs)
 {
@@ -78,29 +65,41 @@
 	return IRQ_HANDLED;
 }
 
+
 static int __init rpcmouse_init(void)
 {
-	init_input_dev(&rpcmouse_dev);
+	if (!(rpcmouse_dev = input_allocate_device()))
+		return -ENOMEM;
+
+	rpcmouse_dev->name = "Acorn RiscPC Mouse";
+	rpcmouse_dev->phys = "rpcmouse/input0";
+	rpcmouse_dev->id.bustype = BUS_HOST;
+	rpcmouse_dev->id.vendor  = 0x0005;
+	rpcmouse_dev->id.product = 0x0001;
+	rpcmouse_dev->id.version = 0x0100;
+
+	rpcmouse_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REL);
+	rpcmouse_dev->keybit[LONG(BTN_LEFT)] = BIT(BTN_LEFT) | BIT(BTN_MIDDLE) | BIT(BTN_RIGHT);
+	rpcmouse_dev->relbit[0]	= BIT(REL_X) | BIT(REL_Y);
 
 	rpcmouse_lastx = (short) iomd_readl(IOMD_MOUSEX);
 	rpcmouse_lasty = (short) iomd_readl(IOMD_MOUSEY);
 
-	if (request_irq(IRQ_VSYNCPULSE, rpcmouse_irq, SA_SHIRQ, "rpcmouse", &rpcmouse_dev)) {
+	if (request_irq(IRQ_VSYNCPULSE, rpcmouse_irq, SA_SHIRQ, "rpcmouse", rpcmouse_dev)) {
 		printk(KERN_ERR "rpcmouse: unable to allocate VSYNC interrupt\n");
-		return -1;
+		input_free_device(rpcmouse_dev);
+		return -EBUSY;
 	}
 
-	input_register_device(&rpcmouse_dev);
-
-	printk(KERN_INFO "input: Acorn RiscPC mouse\n");
+	input_register_device(rpcmouse_dev);
 
 	return 0;
 }
 
 static void __exit rpcmouse_exit(void)
 {
-	input_unregister_device(&rpcmouse_dev);
-	free_irq(IRQ_VSYNCPULSE, &rpcmouse_dev);
+	free_irq(IRQ_VSYNCPULSE, rpcmouse_dev);
+	input_unregister_device(rpcmouse_dev);
 }
 
 module_init(rpcmouse_init);
diff --git a/drivers/input/mouse/sermouse.c b/drivers/input/mouse/sermouse.c
index d12b93a..4bf5843 100644
--- a/drivers/input/mouse/sermouse.c
+++ b/drivers/input/mouse/sermouse.c
@@ -48,7 +48,7 @@
 					"Logitech MZ++ Mouse"};
 
 struct sermouse {
-	struct input_dev dev;
+	struct input_dev *dev;
 	signed char buf[8];
 	unsigned char count;
 	unsigned char type;
@@ -64,7 +64,7 @@
 
 static void sermouse_process_msc(struct sermouse *sermouse, signed char data, struct pt_regs *regs)
 {
-	struct input_dev *dev = &sermouse->dev;
+	struct input_dev *dev = sermouse->dev;
 	signed char *buf = sermouse->buf;
 
 	input_regs(dev, regs);
@@ -107,7 +107,7 @@
 
 static void sermouse_process_ms(struct sermouse *sermouse, signed char data, struct pt_regs *regs)
 {
-	struct input_dev *dev = &sermouse->dev;
+	struct input_dev *dev = sermouse->dev;
 	signed char *buf = sermouse->buf;
 
 	if (data & 0x40) sermouse->count = 0;
@@ -230,9 +230,9 @@
 {
 	struct sermouse *sermouse = serio_get_drvdata(serio);
 
-	input_unregister_device(&sermouse->dev);
 	serio_close(serio);
 	serio_set_drvdata(serio, NULL);
+	input_unregister_device(sermouse->dev);
 	kfree(sermouse);
 }
 
@@ -244,56 +244,52 @@
 static int sermouse_connect(struct serio *serio, struct serio_driver *drv)
 {
 	struct sermouse *sermouse;
-	unsigned char c;
-	int err;
+	struct input_dev *input_dev;
+	unsigned char c = serio->id.extra;
+	int err = -ENOMEM;
 
-	if (!serio->id.proto || serio->id.proto > SERIO_MZPP)
-		return -ENODEV;
+	sermouse = kzalloc(sizeof(struct sermouse), GFP_KERNEL);
+	input_dev = input_allocate_device();
+	if (!sermouse || !input_dev)
+		goto fail;
 
-	if (!(sermouse = kmalloc(sizeof(struct sermouse), GFP_KERNEL)))
-		return -ENOMEM;
-
-	memset(sermouse, 0, sizeof(struct sermouse));
-
-	init_input_dev(&sermouse->dev);
-	sermouse->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_REL);
-	sermouse->dev.keybit[LONG(BTN_MOUSE)] = BIT(BTN_LEFT) | BIT(BTN_RIGHT);
-	sermouse->dev.relbit[0] = BIT(REL_X) | BIT(REL_Y);
-	sermouse->dev.private = sermouse;
-
-	sermouse->type = serio->id.proto;
-	c = serio->id.extra;
-
-	if (c & 0x01) set_bit(BTN_MIDDLE, sermouse->dev.keybit);
-	if (c & 0x02) set_bit(BTN_SIDE, sermouse->dev.keybit);
-	if (c & 0x04) set_bit(BTN_EXTRA, sermouse->dev.keybit);
-	if (c & 0x10) set_bit(REL_WHEEL, sermouse->dev.relbit);
-	if (c & 0x20) set_bit(REL_HWHEEL, sermouse->dev.relbit);
-
+	sermouse->dev = input_dev;
 	sprintf(sermouse->phys, "%s/input0", serio->phys);
+	sermouse->type = serio->id.proto;
 
-	sermouse->dev.name = sermouse_protocols[sermouse->type];
-	sermouse->dev.phys = sermouse->phys;
-	sermouse->dev.id.bustype = BUS_RS232;
-	sermouse->dev.id.vendor = sermouse->type;
-	sermouse->dev.id.product = c;
-	sermouse->dev.id.version = 0x0100;
-	sermouse->dev.dev = &serio->dev;
+	input_dev->name = sermouse_protocols[sermouse->type];
+	input_dev->phys = sermouse->phys;
+	input_dev->id.bustype = BUS_RS232;
+	input_dev->id.vendor  = sermouse->type;
+	input_dev->id.product = c;
+	input_dev->id.version = 0x0100;
+	input_dev->cdev.dev = &serio->dev;
+
+	input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REL);
+	input_dev->keybit[LONG(BTN_MOUSE)] = BIT(BTN_LEFT) | BIT(BTN_RIGHT);
+	input_dev->relbit[0] = BIT(REL_X) | BIT(REL_Y);
+	input_dev->private = sermouse;
+
+	if (c & 0x01) set_bit(BTN_MIDDLE, input_dev->keybit);
+	if (c & 0x02) set_bit(BTN_SIDE, input_dev->keybit);
+	if (c & 0x04) set_bit(BTN_EXTRA, input_dev->keybit);
+	if (c & 0x10) set_bit(REL_WHEEL, input_dev->relbit);
+	if (c & 0x20) set_bit(REL_HWHEEL, input_dev->relbit);
 
 	serio_set_drvdata(serio, sermouse);
 
 	err = serio_open(serio, drv);
-	if (err) {
-		serio_set_drvdata(serio, NULL);
-		kfree(sermouse);
-		return err;
-	}
+	if (err)
+		goto fail;
 
-	input_register_device(&sermouse->dev);
-
-	printk(KERN_INFO "input: %s on %s\n", sermouse_protocols[sermouse->type], serio->phys);
+	input_register_device(sermouse->dev);
 
 	return 0;
+
+ fail:	serio_set_drvdata(serio, NULL);
+	input_free_device(input_dev);
+	kfree(sermouse);
+	return err;
 }
 
 static struct serio_device_id sermouse_serio_ids[] = {
diff --git a/drivers/input/mouse/synaptics.c b/drivers/input/mouse/synaptics.c
index 0293094..97cdfd6 100644
--- a/drivers/input/mouse/synaptics.c
+++ b/drivers/input/mouse/synaptics.c
@@ -342,7 +342,7 @@
  */
 static void synaptics_process_packet(struct psmouse *psmouse)
 {
-	struct input_dev *dev = &psmouse->dev;
+	struct input_dev *dev = psmouse->dev;
 	struct synaptics_data *priv = psmouse->private;
 	struct synaptics_hw_state hw;
 	int num_fingers;
@@ -473,7 +473,7 @@
 
 static psmouse_ret_t synaptics_process_byte(struct psmouse *psmouse, struct pt_regs *regs)
 {
-	struct input_dev *dev = &psmouse->dev;
+	struct input_dev *dev = psmouse->dev;
 	struct synaptics_data *priv = psmouse->private;
 
 	input_regs(dev, regs);
@@ -645,7 +645,7 @@
 		SYN_ID_MAJOR(priv->identity), SYN_ID_MINOR(priv->identity),
 		priv->model_id, priv->capabilities, priv->ext_cap);
 
-	set_input_params(&psmouse->dev, priv);
+	set_input_params(psmouse->dev, priv);
 
 	psmouse->protocol_handler = synaptics_process_byte;
 	psmouse->set_rate = synaptics_set_rate;
diff --git a/drivers/input/mouse/vsxxxaa.c b/drivers/input/mouse/vsxxxaa.c
index f024be9..36e9442 100644
--- a/drivers/input/mouse/vsxxxaa.c
+++ b/drivers/input/mouse/vsxxxaa.c
@@ -112,7 +112,7 @@
 
 
 struct vsxxxaa {
-	struct input_dev dev;
+	struct input_dev *dev;
 	struct serio *serio;
 #define BUFLEN 15 /* At least 5 is needed for a full tablet packet */
 	unsigned char buf[BUFLEN];
@@ -211,7 +211,7 @@
 static void
 vsxxxaa_handle_REL_packet (struct vsxxxaa *mouse, struct pt_regs *regs)
 {
-	struct input_dev *dev = &mouse->dev;
+	struct input_dev *dev = mouse->dev;
 	unsigned char *buf = mouse->buf;
 	int left, middle, right;
 	int dx, dy;
@@ -269,7 +269,7 @@
 static void
 vsxxxaa_handle_ABS_packet (struct vsxxxaa *mouse, struct pt_regs *regs)
 {
-	struct input_dev *dev = &mouse->dev;
+	struct input_dev *dev = mouse->dev;
 	unsigned char *buf = mouse->buf;
 	int left, middle, right, touch;
 	int x, y;
@@ -323,7 +323,7 @@
 static void
 vsxxxaa_handle_POR_packet (struct vsxxxaa *mouse, struct pt_regs *regs)
 {
-	struct input_dev *dev = &mouse->dev;
+	struct input_dev *dev = mouse->dev;
 	unsigned char *buf = mouse->buf;
 	int left, middle, right;
 	unsigned char error;
@@ -483,9 +483,9 @@
 {
 	struct vsxxxaa *mouse = serio_get_drvdata (serio);
 
-	input_unregister_device (&mouse->dev);
 	serio_close (serio);
 	serio_set_drvdata (serio, NULL);
+	input_unregister_device (mouse->dev);
 	kfree (mouse);
 }
 
@@ -493,61 +493,57 @@
 vsxxxaa_connect (struct serio *serio, struct serio_driver *drv)
 {
 	struct vsxxxaa *mouse;
-	int err;
+	struct input_dev *input_dev;
+	int err = -ENOMEM;
 
-	if (!(mouse = kmalloc (sizeof (struct vsxxxaa), GFP_KERNEL)))
-		return -ENOMEM;
+	mouse = kzalloc (sizeof (struct vsxxxaa), GFP_KERNEL);
+	input_dev = input_allocate_device ();
+	if (!mouse || !input_dev)
+		goto fail;
 
-	memset (mouse, 0, sizeof (struct vsxxxaa));
-
-	init_input_dev (&mouse->dev);
-	set_bit (EV_KEY, mouse->dev.evbit);		/* We have buttons */
-	set_bit (EV_REL, mouse->dev.evbit);
-	set_bit (EV_ABS, mouse->dev.evbit);
-	set_bit (BTN_LEFT, mouse->dev.keybit);		/* We have 3 buttons */
-	set_bit (BTN_MIDDLE, mouse->dev.keybit);
-	set_bit (BTN_RIGHT, mouse->dev.keybit);
-	set_bit (BTN_TOUCH, mouse->dev.keybit);		/* ...and Tablet */
-	set_bit (REL_X, mouse->dev.relbit);
-	set_bit (REL_Y, mouse->dev.relbit);
-	set_bit (ABS_X, mouse->dev.absbit);
-	set_bit (ABS_Y, mouse->dev.absbit);
-
-	mouse->dev.absmin[ABS_X] = 0;
-	mouse->dev.absmax[ABS_X] = 1023;
-	mouse->dev.absmin[ABS_Y] = 0;
-	mouse->dev.absmax[ABS_Y] = 1023;
-
-	mouse->dev.private = mouse;
-
+	mouse->dev = input_dev;
+	mouse->serio = serio;
 	sprintf (mouse->name, "DEC VSXXX-AA/-GA mouse or VSXXX-AB digitizer");
 	sprintf (mouse->phys, "%s/input0", serio->phys);
-	mouse->dev.name = mouse->name;
-	mouse->dev.phys = mouse->phys;
-	mouse->dev.id.bustype = BUS_RS232;
-	mouse->dev.dev = &serio->dev;
-	mouse->serio = serio;
+
+	input_dev->name = mouse->name;
+	input_dev->phys = mouse->phys;
+	input_dev->id.bustype = BUS_RS232;
+	input_dev->cdev.dev = &serio->dev;
+	input_dev->private = mouse;
+
+	set_bit (EV_KEY, input_dev->evbit);		/* We have buttons */
+	set_bit (EV_REL, input_dev->evbit);
+	set_bit (EV_ABS, input_dev->evbit);
+	set_bit (BTN_LEFT, input_dev->keybit);		/* We have 3 buttons */
+	set_bit (BTN_MIDDLE, input_dev->keybit);
+	set_bit (BTN_RIGHT, input_dev->keybit);
+	set_bit (BTN_TOUCH, input_dev->keybit);		/* ...and Tablet */
+	set_bit (REL_X, input_dev->relbit);
+	set_bit (REL_Y, input_dev->relbit);
+	input_set_abs_params (input_dev, ABS_X, 0, 1023, 0, 0);
+	input_set_abs_params (input_dev, ABS_Y, 0, 1023, 0, 0);
 
 	serio_set_drvdata (serio, mouse);
 
 	err = serio_open (serio, drv);
-	if (err) {
-		serio_set_drvdata (serio, NULL);
-		kfree (mouse);
-		return err;
-	}
+	if (err)
+		goto fail;
 
 	/*
 	 * Request selftest. Standard packet format and differential
 	 * mode will be requested after the device ID'ed successfully.
 	 */
-	mouse->serio->write (mouse->serio, 'T'); /* Test */
+	serio->write (serio, 'T'); /* Test */
 
-	input_register_device (&mouse->dev);
-
-	printk (KERN_INFO "input: %s on %s\n", mouse->name, mouse->phys);
+	input_register_device (input_dev);
 
 	return 0;
+
+ fail:	serio_set_drvdata (serio, NULL);
+	input_free_device (input_dev);
+	kfree (mouse);
+	return err;
 }
 
 static struct serio_device_id vsxxaa_serio_ids[] = {
diff --git a/drivers/input/mousedev.c b/drivers/input/mousedev.c
index c6194a9..2d0af44 100644
--- a/drivers/input/mousedev.c
+++ b/drivers/input/mousedev.c
@@ -9,7 +9,7 @@
  * the Free Software Foundation.
  */
 
-#define MOUSEDEV_MINOR_BASE 	32
+#define MOUSEDEV_MINOR_BASE	32
 #define MOUSEDEV_MINORS		32
 #define MOUSEDEV_MIX		31
 
@@ -24,7 +24,6 @@
 #include <linux/random.h>
 #include <linux/major.h>
 #include <linux/device.h>
-#include <linux/devfs_fs_kernel.h>
 #ifdef CONFIG_INPUT_MOUSEDEV_PSAUX
 #include <linux/miscdevice.h>
 #endif
@@ -621,6 +620,7 @@
 static struct input_handle *mousedev_connect(struct input_handler *handler, struct input_dev *dev, struct input_device_id *id)
 {
 	struct mousedev *mousedev;
+	struct class_device *cdev;
 	int minor = 0;
 
 	for (minor = 0; minor < MOUSEDEV_MINORS && mousedev_table[minor]; minor++);
@@ -649,11 +649,13 @@
 
 	mousedev_table[minor] = mousedev;
 
-	devfs_mk_cdev(MKDEV(INPUT_MAJOR, MOUSEDEV_MINOR_BASE + minor),
-			S_IFCHR|S_IRUGO|S_IWUSR, "input/mouse%d", minor);
-	class_device_create(input_class,
+	cdev = class_device_create(&input_class, &dev->cdev,
 			MKDEV(INPUT_MAJOR, MOUSEDEV_MINOR_BASE + minor),
-			dev->dev, "mouse%d", minor);
+			dev->cdev.dev, mousedev->name);
+
+	/* temporary symlink to keep userspace happy */
+	sysfs_create_link(&input_class.subsys.kset.kobj, &cdev->kobj,
+			  mousedev->name);
 
 	return &mousedev->handle;
 }
@@ -663,9 +665,9 @@
 	struct mousedev *mousedev = handle->private;
 	struct mousedev_list *list;
 
-	class_device_destroy(input_class,
+	sysfs_remove_link(&input_class.subsys.kset.kobj, mousedev->name);
+	class_device_destroy(&input_class,
 			MKDEV(INPUT_MAJOR, MOUSEDEV_MINOR_BASE + mousedev->minor));
-	devfs_remove("input/mouse%d", mousedev->minor);
 	mousedev->exist = 0;
 
 	if (mousedev->open) {
@@ -738,9 +740,7 @@
 	mousedev_mix.exist = 1;
 	mousedev_mix.minor = MOUSEDEV_MIX;
 
-	devfs_mk_cdev(MKDEV(INPUT_MAJOR, MOUSEDEV_MINOR_BASE + MOUSEDEV_MIX),
-			S_IFCHR|S_IRUGO|S_IWUSR, "input/mice");
-	class_device_create(input_class,
+	class_device_create(&input_class, NULL,
 			MKDEV(INPUT_MAJOR, MOUSEDEV_MINOR_BASE + MOUSEDEV_MIX), NULL, "mice");
 
 #ifdef CONFIG_INPUT_MOUSEDEV_PSAUX
@@ -759,8 +759,7 @@
 	if (psaux_registered)
 		misc_deregister(&psaux_mouse);
 #endif
-	devfs_remove("input/mice");
-	class_device_destroy(input_class,
+	class_device_destroy(&input_class,
 			MKDEV(INPUT_MAJOR, MOUSEDEV_MINOR_BASE + MOUSEDEV_MIX));
 	input_unregister_handler(&mousedev_handler);
 }
diff --git a/drivers/input/serio/i8042.c b/drivers/input/serio/i8042.c
index 40d451c..4bc40f1 100644
--- a/drivers/input/serio/i8042.c
+++ b/drivers/input/serio/i8042.c
@@ -911,12 +911,10 @@
  * Here we try to restore the original BIOS settings
  */
 
-static int i8042_suspend(struct device *dev, pm_message_t state, u32 level)
+static int i8042_suspend(struct device *dev, pm_message_t state)
 {
-	if (level == SUSPEND_DISABLE) {
-		del_timer_sync(&i8042_timer);
-		i8042_controller_reset();
-	}
+	del_timer_sync(&i8042_timer);
+	i8042_controller_reset();
 
 	return 0;
 }
@@ -926,13 +924,10 @@
  * Here we try to reset everything back to a state in which suspended
  */
 
-static int i8042_resume(struct device *dev, u32 level)
+static int i8042_resume(struct device *dev)
 {
 	int i;
 
-	if (level != RESUME_ENABLE)
-		return 0;
-
 	if (i8042_ctl_test())
 		return -1;
 
diff --git a/drivers/input/touchscreen/corgi_ts.c b/drivers/input/touchscreen/corgi_ts.c
index 4c7fbe5..0ba3e65 100644
--- a/drivers/input/touchscreen/corgi_ts.c
+++ b/drivers/input/touchscreen/corgi_ts.c
@@ -41,8 +41,7 @@
 };
 
 struct corgi_ts {
-	char phys[32];
-	struct input_dev input;
+	struct input_dev *input;
 	struct timer_list timer;
 	struct ts_event tc;
 	int pendown;
@@ -182,14 +181,12 @@
 	if (!corgi_ts->tc.pressure && corgi_ts->pendown == 0)
 		return;
 
-	if (regs)
-		input_regs(&corgi_ts->input, regs);
-
-	input_report_abs(&corgi_ts->input, ABS_X, corgi_ts->tc.x);
-	input_report_abs(&corgi_ts->input, ABS_Y, corgi_ts->tc.y);
-	input_report_abs(&corgi_ts->input, ABS_PRESSURE, corgi_ts->tc.pressure);
-	input_report_key(&corgi_ts->input, BTN_TOUCH, (corgi_ts->pendown != 0));
-	input_sync(&corgi_ts->input);
+	input_regs(corgi_ts->input, regs);
+	input_report_abs(corgi_ts->input, ABS_X, corgi_ts->tc.x);
+	input_report_abs(corgi_ts->input, ABS_Y, corgi_ts->tc.y);
+	input_report_abs(corgi_ts->input, ABS_PRESSURE, corgi_ts->tc.pressure);
+	input_report_key(corgi_ts->input, BTN_TOUCH, (corgi_ts->pendown != 0));
+	input_sync(corgi_ts->input);
 }
 
 static void ts_interrupt_main(struct corgi_ts *corgi_ts, int isTimer, struct pt_regs *regs)
@@ -234,34 +231,32 @@
 }
 
 #ifdef CONFIG_PM
-static int corgits_suspend(struct device *dev, pm_message_t state, uint32_t level)
+static int corgits_suspend(struct device *dev, pm_message_t state)
 {
-	if (level == SUSPEND_POWER_DOWN) {
-		struct corgi_ts *corgi_ts = dev_get_drvdata(dev);
+	struct corgi_ts *corgi_ts = dev_get_drvdata(dev);
 
-		if (corgi_ts->pendown) {
-			del_timer_sync(&corgi_ts->timer);
-			corgi_ts->tc.pressure = 0;
-			new_data(corgi_ts, NULL);
-			corgi_ts->pendown = 0;
-		}
-		corgi_ts->power_mode = PWR_MODE_SUSPEND;
-
-		corgi_ssp_ads7846_putget((1u << ADSCTRL_ADR_SH) | ADSCTRL_STS);
+	if (corgi_ts->pendown) {
+		del_timer_sync(&corgi_ts->timer);
+		corgi_ts->tc.pressure = 0;
+		new_data(corgi_ts, NULL);
+		corgi_ts->pendown = 0;
 	}
+	corgi_ts->power_mode = PWR_MODE_SUSPEND;
+
+	corgi_ssp_ads7846_putget((1u << ADSCTRL_ADR_SH) | ADSCTRL_STS);
+
 	return 0;
 }
 
-static int corgits_resume(struct device *dev, uint32_t level)
+static int corgits_resume(struct device *dev)
 {
-	if (level == RESUME_POWER_ON) {
-		struct corgi_ts *corgi_ts = dev_get_drvdata(dev);
+	struct corgi_ts *corgi_ts = dev_get_drvdata(dev);
 
-		corgi_ssp_ads7846_putget((4u << ADSCTRL_ADR_SH) | ADSCTRL_STS);
-		/* Enable Falling Edge */
-		set_irq_type(corgi_ts->irq_gpio, IRQT_FALLING);
-		corgi_ts->power_mode = PWR_MODE_ACTIVE;
-	}
+	corgi_ssp_ads7846_putget((4u << ADSCTRL_ADR_SH) | ADSCTRL_STS);
+	/* Enable Falling Edge */
+	set_irq_type(corgi_ts->irq_gpio, IRQT_FALLING);
+	corgi_ts->power_mode = PWR_MODE_ACTIVE;
+
 	return 0;
 }
 #else
@@ -273,39 +268,44 @@
 {
 	struct corgi_ts *corgi_ts;
 	struct platform_device *pdev = to_platform_device(dev);
+	struct input_dev *input_dev;
+	int err = -ENOMEM;
 
-	if (!(corgi_ts = kmalloc(sizeof(struct corgi_ts), GFP_KERNEL)))
-		return -ENOMEM;
+	corgi_ts = kzalloc(sizeof(struct corgi_ts), GFP_KERNEL);
+	input_dev = input_allocate_device();
+	if (!corgi_ts || !input_dev)
+		goto fail;
 
 	dev_set_drvdata(dev, corgi_ts);
 
-	memset(corgi_ts, 0, sizeof(struct corgi_ts));
-
 	corgi_ts->machinfo = dev->platform_data;
 	corgi_ts->irq_gpio = platform_get_irq(pdev, 0);
 
 	if (corgi_ts->irq_gpio < 0) {
-		kfree(corgi_ts);
-		return -ENODEV;
+		err = -ENODEV;
+		goto fail;
 	}
 
-	init_input_dev(&corgi_ts->input);
-	corgi_ts->input.evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
-	corgi_ts->input.keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH);
-	input_set_abs_params(&corgi_ts->input, ABS_X, X_AXIS_MIN, X_AXIS_MAX, 0, 0);
-	input_set_abs_params(&corgi_ts->input, ABS_Y, Y_AXIS_MIN, Y_AXIS_MAX, 0, 0);
-	input_set_abs_params(&corgi_ts->input, ABS_PRESSURE, PRESSURE_MIN, PRESSURE_MAX, 0, 0);
+	corgi_ts->input = input_dev;
 
-	strcpy(corgi_ts->phys, "corgits/input0");
+	init_timer(&corgi_ts->timer);
+	corgi_ts->timer.data = (unsigned long) corgi_ts;
+	corgi_ts->timer.function = corgi_ts_timer;
 
-	corgi_ts->input.private = corgi_ts;
-	corgi_ts->input.name = "Corgi Touchscreen";
-	corgi_ts->input.dev = dev;
-	corgi_ts->input.phys = corgi_ts->phys;
-	corgi_ts->input.id.bustype = BUS_HOST;
-	corgi_ts->input.id.vendor = 0x0001;
-	corgi_ts->input.id.product = 0x0002;
-	corgi_ts->input.id.version = 0x0100;
+	input_dev->name = "Corgi Touchscreen";
+	input_dev->phys = "corgits/input0";
+	input_dev->id.bustype = BUS_HOST;
+	input_dev->id.vendor = 0x0001;
+	input_dev->id.product = 0x0002;
+	input_dev->id.version = 0x0100;
+	input_dev->cdev.dev = dev;
+	input_dev->private = corgi_ts;
+
+	input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
+	input_dev->keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH);
+	input_set_abs_params(input_dev, ABS_X, X_AXIS_MIN, X_AXIS_MAX, 0, 0);
+	input_set_abs_params(input_dev, ABS_Y, Y_AXIS_MIN, Y_AXIS_MAX, 0, 0);
+	input_set_abs_params(input_dev, ABS_PRESSURE, PRESSURE_MIN, PRESSURE_MAX, 0, 0);
 
 	pxa_gpio_mode(IRQ_TO_GPIO(corgi_ts->irq_gpio) | GPIO_IN);
 
@@ -319,25 +319,24 @@
 	corgi_ssp_ads7846_putget((5u << ADSCTRL_ADR_SH) | ADSCTRL_STS);
 	mdelay(5);
 
-	init_timer(&corgi_ts->timer);
-	corgi_ts->timer.data = (unsigned long) corgi_ts;
-	corgi_ts->timer.function = corgi_ts_timer;
-
-	input_register_device(&corgi_ts->input);
-	corgi_ts->power_mode = PWR_MODE_ACTIVE;
-
 	if (request_irq(corgi_ts->irq_gpio, ts_interrupt, SA_INTERRUPT, "ts", corgi_ts)) {
-		input_unregister_device(&corgi_ts->input);
-		kfree(corgi_ts);
-		return -EBUSY;
+		err = -EBUSY;
+		goto fail;
 	}
 
+	input_register_device(corgi_ts->input);
+
+	corgi_ts->power_mode = PWR_MODE_ACTIVE;
+
 	/* Enable Falling Edge */
 	set_irq_type(corgi_ts->irq_gpio, IRQT_FALLING);
 
-	printk(KERN_INFO "input: Corgi Touchscreen Registered\n");
-
 	return 0;
+
+ fail:	input_free_device(input_dev);
+	kfree(corgi_ts);
+	return err;
+
 }
 
 static int corgits_remove(struct device *dev)
@@ -347,7 +346,7 @@
 	free_irq(corgi_ts->irq_gpio, NULL);
 	del_timer_sync(&corgi_ts->timer);
 	corgi_ts->machinfo->put_hsync();
-	input_unregister_device(&corgi_ts->input);
+	input_unregister_device(corgi_ts->input);
 	kfree(corgi_ts);
 	return 0;
 }
diff --git a/drivers/input/touchscreen/elo.c b/drivers/input/touchscreen/elo.c
index 3cdc9ca..c86a2eb 100644
--- a/drivers/input/touchscreen/elo.c
+++ b/drivers/input/touchscreen/elo.c
@@ -36,14 +36,12 @@
 
 #define	ELO_MAX_LENGTH	10
 
-static char *elo_name = "Elo Serial TouchScreen";
-
 /*
  * Per-touchscreen data.
  */
 
 struct elo {
-	struct input_dev dev;
+	struct input_dev *dev;
 	struct serio *serio;
 	int id;
 	int idx;
@@ -54,7 +52,7 @@
 
 static void elo_process_data_10(struct elo* elo, unsigned char data, struct pt_regs *regs)
 {
-	struct input_dev *dev = &elo->dev;
+	struct input_dev *dev = elo->dev;
 
 	elo->csum += elo->data[elo->idx] = data;
 
@@ -80,7 +78,7 @@
 				input_report_abs(dev, ABS_X, (elo->data[4] << 8) | elo->data[3]);
 				input_report_abs(dev, ABS_Y, (elo->data[6] << 8) | elo->data[5]);
 				input_report_abs(dev, ABS_PRESSURE, (elo->data[8] << 8) | elo->data[7]);
-				input_report_key(dev, BTN_TOUCH, elo->data[2] & 3);
+				input_report_key(dev, BTN_TOUCH, elo->data[8] || elo->data[7]);
 				input_sync(dev);
 			}
 			elo->idx = 0;
@@ -91,7 +89,7 @@
 
 static void elo_process_data_6(struct elo* elo, unsigned char data, struct pt_regs *regs)
 {
-	struct input_dev *dev = &elo->dev;
+	struct input_dev *dev = elo->dev;
 
 	elo->data[elo->idx] = data;
 
@@ -129,7 +127,7 @@
 		case 5:
 			if ((data & 0xf0) == 0) {
 				input_report_abs(dev, ABS_PRESSURE, elo->data[5]);
-				input_report_key(dev, BTN_TOUCH, elo->data[5]);
+				input_report_key(dev, BTN_TOUCH, !!elo->data[5]);
 			}
 			input_sync(dev);
 			elo->idx = 0;
@@ -139,7 +137,7 @@
 
 static void elo_process_data_3(struct elo* elo, unsigned char data, struct pt_regs *regs)
 {
-	struct input_dev *dev = &elo->dev;
+	struct input_dev *dev = elo->dev;
 
 	elo->data[elo->idx] = data;
 
@@ -191,7 +189,7 @@
 {
 	struct elo* elo = serio_get_drvdata(serio);
 
-	input_unregister_device(&elo->dev);
+	input_unregister_device(elo->dev);
 	serio_close(serio);
 	serio_set_drvdata(serio, NULL);
 	kfree(elo);
@@ -206,67 +204,68 @@
 static int elo_connect(struct serio *serio, struct serio_driver *drv)
 {
 	struct elo *elo;
+	struct input_dev *input_dev;
 	int err;
 
-	if (!(elo = kmalloc(sizeof(struct elo), GFP_KERNEL)))
-		return -ENOMEM;
+	elo = kzalloc(sizeof(struct elo), GFP_KERNEL);
+	input_dev = input_allocate_device();
+	if (!elo || !input_dev) {
+		err = -ENOMEM;
+		goto fail;
+	}
 
-	memset(elo, 0, sizeof(struct elo));
-
-	init_input_dev(&elo->dev);
-	elo->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
-	elo->dev.keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH);
-
+	elo->serio = serio;
 	elo->id = serio->id.id;
+	elo->dev = input_dev;
+	snprintf(elo->phys, sizeof(elo->phys), "%s/input0", serio->phys);
+
+	input_dev->private = elo;
+	input_dev->name = "Elo Serial TouchScreen";
+	input_dev->phys = elo->phys;
+	input_dev->id.bustype = BUS_RS232;
+	input_dev->id.vendor = SERIO_ELO;
+	input_dev->id.product = elo->id;
+	input_dev->id.version = 0x0100;
+	input_dev->cdev.dev = &serio->dev;
+
+	input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
+	input_dev->keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH);
 
 	switch (elo->id) {
 
 		case 0: /* 10-byte protocol */
-			input_set_abs_params(&elo->dev, ABS_X, 96, 4000, 0, 0);
-			input_set_abs_params(&elo->dev, ABS_Y, 96, 4000, 0, 0);
-			input_set_abs_params(&elo->dev, ABS_PRESSURE, 0, 255, 0, 0);
+			input_set_abs_params(input_dev, ABS_X, 96, 4000, 0, 0);
+			input_set_abs_params(input_dev, ABS_Y, 96, 4000, 0, 0);
+			input_set_abs_params(input_dev, ABS_PRESSURE, 0, 255, 0, 0);
 			break;
 
 		case 1: /* 6-byte protocol */
-			input_set_abs_params(&elo->dev, ABS_PRESSURE, 0, 15, 0, 0);
+			input_set_abs_params(input_dev, ABS_PRESSURE, 0, 15, 0, 0);
 
 		case 2: /* 4-byte protocol */
-			input_set_abs_params(&elo->dev, ABS_X, 96, 4000, 0, 0);
-			input_set_abs_params(&elo->dev, ABS_Y, 96, 4000, 0, 0);
+			input_set_abs_params(input_dev, ABS_X, 96, 4000, 0, 0);
+			input_set_abs_params(input_dev, ABS_Y, 96, 4000, 0, 0);
 			break;
 
 		case 3: /* 3-byte protocol */
-			input_set_abs_params(&elo->dev, ABS_X, 0, 255, 0, 0);
-			input_set_abs_params(&elo->dev, ABS_Y, 0, 255, 0, 0);
+			input_set_abs_params(input_dev, ABS_X, 0, 255, 0, 0);
+			input_set_abs_params(input_dev, ABS_Y, 0, 255, 0, 0);
 			break;
 	}
 
-	elo->serio = serio;
-
-	sprintf(elo->phys, "%s/input0", serio->phys);
-
-	elo->dev.private = elo;
-	elo->dev.name = elo_name;
-	elo->dev.phys = elo->phys;
-	elo->dev.id.bustype = BUS_RS232;
-	elo->dev.id.vendor = SERIO_ELO;
-	elo->dev.id.product = elo->id;
-	elo->dev.id.version = 0x0100;
-
 	serio_set_drvdata(serio, elo);
 
 	err = serio_open(serio, drv);
-	if (err) {
-		serio_set_drvdata(serio, NULL);
-		kfree(elo);
-		return err;
-	}
+	if (err)
+		goto fail;
 
-	input_register_device(&elo->dev);
-
-	printk(KERN_INFO "input: %s on %s\n", elo_name, serio->phys);
-
+	input_register_device(elo->dev);
 	return 0;
+
+ fail:	serio_set_drvdata(serio, NULL);
+	input_free_device(input_dev);
+	kfree(elo);
+	return err;
 }
 
 /*
diff --git a/drivers/input/touchscreen/gunze.c b/drivers/input/touchscreen/gunze.c
index 53a27e4..466da19 100644
--- a/drivers/input/touchscreen/gunze.c
+++ b/drivers/input/touchscreen/gunze.c
@@ -48,14 +48,12 @@
 
 #define	GUNZE_MAX_LENGTH	10
 
-static char *gunze_name = "Gunze AHL-51S TouchScreen";
-
 /*
  * Per-touchscreen data.
  */
 
 struct gunze {
-	struct input_dev dev;
+	struct input_dev *dev;
 	struct serio *serio;
 	int idx;
 	unsigned char data[GUNZE_MAX_LENGTH];
@@ -64,7 +62,7 @@
 
 static void gunze_process_packet(struct gunze* gunze, struct pt_regs *regs)
 {
-	struct input_dev *dev = &gunze->dev;
+	struct input_dev *dev = gunze->dev;
 
 	if (gunze->idx != GUNZE_MAX_LENGTH || gunze->data[5] != ',' ||
 		(gunze->data[0] != 'T' && gunze->data[0] != 'R')) {
@@ -100,11 +98,13 @@
 
 static void gunze_disconnect(struct serio *serio)
 {
-	struct gunze* gunze = serio_get_drvdata(serio);
+	struct gunze *gunze = serio_get_drvdata(serio);
 
-	input_unregister_device(&gunze->dev);
+	input_get_device(gunze->dev);
+	input_unregister_device(gunze->dev);
 	serio_close(serio);
 	serio_set_drvdata(serio, NULL);
+	input_put_device(gunze->dev);
 	kfree(gunze);
 }
 
@@ -117,45 +117,45 @@
 static int gunze_connect(struct serio *serio, struct serio_driver *drv)
 {
 	struct gunze *gunze;
+	struct input_dev *input_dev;
 	int err;
 
-	if (!(gunze = kmalloc(sizeof(struct gunze), GFP_KERNEL)))
-		return -ENOMEM;
-
-	memset(gunze, 0, sizeof(struct gunze));
-
-	init_input_dev(&gunze->dev);
-	gunze->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
-	gunze->dev.keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH);
-	input_set_abs_params(&gunze->dev, ABS_X, 24, 1000, 0, 0);
-	input_set_abs_params(&gunze->dev, ABS_Y, 24, 1000, 0, 0);
+	gunze = kzalloc(sizeof(struct gunze), GFP_KERNEL);
+	input_dev = input_allocate_device();
+	if (!gunze || !input_dev) {
+		err = -ENOMEM;
+		goto fail;
+	}
 
 	gunze->serio = serio;
-
+	gunze->dev = input_dev;
 	sprintf(gunze->phys, "%s/input0", serio->phys);
 
-	gunze->dev.private = gunze;
-	gunze->dev.name = gunze_name;
-	gunze->dev.phys = gunze->phys;
-	gunze->dev.id.bustype = BUS_RS232;
-	gunze->dev.id.vendor = SERIO_GUNZE;
-	gunze->dev.id.product = 0x0051;
-	gunze->dev.id.version = 0x0100;
+	input_dev->private = gunze;
+	input_dev->name = "Gunze AHL-51S TouchScreen";
+	input_dev->phys = gunze->phys;
+	input_dev->id.bustype = BUS_RS232;
+	input_dev->id.vendor = SERIO_GUNZE;
+	input_dev->id.product = 0x0051;
+	input_dev->id.version = 0x0100;
+	input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
+	input_dev->keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH);
+	input_set_abs_params(input_dev, ABS_X, 24, 1000, 0, 0);
+	input_set_abs_params(input_dev, ABS_Y, 24, 1000, 0, 0);
 
 	serio_set_drvdata(serio, gunze);
 
 	err = serio_open(serio, drv);
-	if (err) {
-		serio_set_drvdata(serio, NULL);
-		kfree(gunze);
-		return err;
-	}
+	if (err)
+		goto fail;
 
-	input_register_device(&gunze->dev);
-
-	printk(KERN_INFO "input: %s on %s\n", gunze_name, serio->phys);
-
+	input_register_device(gunze->dev);
 	return 0;
+
+ fail:	serio_set_drvdata(serio, NULL);
+	input_free_device(input_dev);
+	kfree(gunze);
+	return err;
 }
 
 /*
diff --git a/drivers/input/touchscreen/h3600_ts_input.c b/drivers/input/touchscreen/h3600_ts_input.c
index bcfa1e3..a18d56b 100644
--- a/drivers/input/touchscreen/h3600_ts_input.c
+++ b/drivers/input/touchscreen/h3600_ts_input.c
@@ -39,7 +39,6 @@
 #include <linux/serio.h>
 #include <linux/init.h>
 #include <linux/delay.h>
-#include <linux/pm.h>
 
 /* SA1100 serial defines */
 #include <asm/arch/hardware.h>
@@ -93,16 +92,12 @@
 #define H3600_SCANCODE_LEFT	8	 /* 8 -> left */
 #define H3600_SCANCODE_DOWN	9	 /* 9 -> down */
 
-static char *h3600_name = "H3600 TouchScreen";
-
 /*
  * Per-touchscreen data.
  */
 struct h3600_dev {
-	struct input_dev dev;
-	struct pm_dev *pm_dev;
+	struct input_dev *dev;
 	struct serio *serio;
-	struct pm_dev *pm_dev;
 	unsigned char event;	/* event ID from packet */
 	unsigned char chksum;
 	unsigned char len;
@@ -163,33 +158,6 @@
 	return 0;
 }
 
-static int suspended = 0;
-static int h3600ts_pm_callback(struct pm_dev *pm_dev, pm_request_t req,
-				void *data)
-{
-	struct input_dev *dev = (struct input_dev *) data;
-
-	switch (req) {
-	case PM_SUSPEND: /* enter D1-D3 */
-		suspended = 1;
-		h3600_flite_power(dev, FLITE_PWR_OFF);
-		break;
-	case PM_BLANK:
-		if (!suspended)
-			h3600_flite_power(dev, FLITE_PWR_OFF);
-		break;
-	case PM_RESUME:  /* enter D0 */
-		/* same as unblank */
-	case PM_UNBLANK:
-		if (suspended) {
-			//initSerial();
-			suspended = 0;
-		}
-		h3600_flite_power(dev, FLITE_PWR_ON);
-		break;
-	}
-	return 0;
-}
 #endif
 
 /*
@@ -199,7 +167,7 @@
  */
 static void h3600ts_process_packet(struct h3600_dev *ts, struct pt_regs *regs)
 {
-	struct input_dev *dev = &ts->dev;
+	struct input_dev *dev = ts->dev;
 	static int touched = 0;
 	int key, down = 0;
 
@@ -295,6 +263,7 @@
 static int h3600ts_event(struct input_dev *dev, unsigned int type,
 			 unsigned int code, int value)
 {
+#if 0
 	struct h3600_dev *ts = dev->private;
 
 	switch (type) {
@@ -304,6 +273,8 @@
 		}
 	}
 	return -1;
+#endif
+	return 0;
 }
 
 /*
@@ -380,14 +351,48 @@
 static int h3600ts_connect(struct serio *serio, struct serio_driver *drv)
 {
 	struct h3600_dev *ts;
+	struct input_dev *input_dev;
 	int err;
 
-	if (!(ts = kmalloc(sizeof(struct h3600_dev), GFP_KERNEL)))
-		return -ENOMEM;
+	ts = kzalloc(sizeof(struct h3600_dev), GFP_KERNEL);
+	input_dev = input_allocate_device();
+	if (!ts || !input_dev) {
+		err = -ENOMEM;
+		goto fail1;
+	}
 
-	memset(ts, 0, sizeof(struct h3600_dev));
+	ts->serio = serio;
+	ts->dev = input_dev;
+	sprintf(ts->phys, "%s/input0", serio->phys);
 
-	init_input_dev(&ts->dev);
+	input_dev->name = "H3600 TouchScreen";
+	input_dev->phys = ts->phys;
+	input_dev->id.bustype = BUS_RS232;
+	input_dev->id.vendor = SERIO_H3600;
+	input_dev->id.product = 0x0666;  /* FIXME !!! We can ask the hardware */
+	input_dev->id.version = 0x0100;
+	input_dev->cdev.dev = &serio->dev;
+	input_dev->private = ts;
+
+	input_dev->event = h3600ts_event;
+
+	input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS) | BIT(EV_LED) | BIT(EV_PWR);
+	input_dev->ledbit[0] = BIT(LED_SLEEP);
+	input_set_abs_params(input_dev, ABS_X, 60, 985, 0, 0);
+	input_set_abs_params(input_dev, ABS_Y, 35, 1024, 0, 0);
+
+	set_bit(KEY_RECORD, input_dev->keybit);
+	set_bit(KEY_Q, input_dev->keybit);
+	set_bit(KEY_PROG1, input_dev->keybit);
+	set_bit(KEY_PROG2, input_dev->keybit);
+	set_bit(KEY_PROG3, input_dev->keybit);
+	set_bit(KEY_UP, input_dev->keybit);
+	set_bit(KEY_RIGHT, input_dev->keybit);
+	set_bit(KEY_LEFT, input_dev->keybit);
+	set_bit(KEY_DOWN, input_dev->keybit);
+	set_bit(KEY_ENTER, input_dev->keybit);
+	set_bit(KEY_SUSPEND, input_dev->keybit);
+	set_bit(BTN_TOUCH, input_dev->keybit);
 
 	/* Device specific stuff */
 	set_GPIO_IRQ_edge(GPIO_BITSY_ACTION_BUTTON, GPIO_BOTH_EDGES);
@@ -397,73 +402,35 @@
 			SA_SHIRQ | SA_INTERRUPT | SA_SAMPLE_RANDOM,
 			"h3600_action", &ts->dev)) {
 		printk(KERN_ERR "h3600ts.c: Could not allocate Action Button IRQ!\n");
-		kfree(ts);
-		return -EBUSY;
+		err = -EBUSY;
+		goto fail2;
 	}
 
 	if (request_irq(IRQ_GPIO_BITSY_NPOWER_BUTTON, npower_button_handler,
 			SA_SHIRQ | SA_INTERRUPT | SA_SAMPLE_RANDOM,
 			"h3600_suspend", &ts->dev)) {
-		free_irq(IRQ_GPIO_BITSY_ACTION_BUTTON, &ts->dev);
 		printk(KERN_ERR "h3600ts.c: Could not allocate Power Button IRQ!\n");
-		kfree(ts);
-		return -EBUSY;
+		err = -EBUSY;
+		goto fail3;
 	}
 
-	/* Now we have things going we setup our input device */
-	ts->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_ABS) | BIT(EV_LED) | BIT(EV_PWR);
-	ts->dev.ledbit[0] = BIT(LED_SLEEP);
-	input_set_abs_params(&ts->dev, ABS_X, 60, 985, 0, 0);
-	input_set_abs_params(&ts->dev, ABS_Y, 35, 1024, 0, 0);
-
-	set_bit(KEY_RECORD, ts->dev.keybit);
-	set_bit(KEY_Q, ts->dev.keybit);
-	set_bit(KEY_PROG1, ts->dev.keybit);
-	set_bit(KEY_PROG2, ts->dev.keybit);
-	set_bit(KEY_PROG3, ts->dev.keybit);
-	set_bit(KEY_UP, ts->dev.keybit);
-	set_bit(KEY_RIGHT, ts->dev.keybit);
-	set_bit(KEY_LEFT, ts->dev.keybit);
-	set_bit(KEY_DOWN, ts->dev.keybit);
-	set_bit(KEY_ENTER, ts->dev.keybit);
-	ts->dev.keybit[LONG(BTN_TOUCH)] |= BIT(BTN_TOUCH);
-	ts->dev.keybit[LONG(KEY_SUSPEND)] |= BIT(KEY_SUSPEND);
-
-	ts->serio = serio;
-
-	sprintf(ts->phys, "%s/input0", serio->phys);
-
-	ts->dev.event = h3600ts_event;
-	ts->dev.private = ts;
-	ts->dev.name = h3600_name;
-	ts->dev.phys = ts->phys;
-	ts->dev.id.bustype = BUS_RS232;
-	ts->dev.id.vendor = SERIO_H3600;
-	ts->dev.id.product = 0x0666;  /* FIXME !!! We can ask the hardware */
-	ts->dev.id.version = 0x0100;
-
 	serio_set_drvdata(serio, ts);
 
 	err = serio_open(serio, drv);
-	if (err) {
-		free_irq(IRQ_GPIO_BITSY_ACTION_BUTTON, ts);
-		free_irq(IRQ_GPIO_BITSY_NPOWER_BUTTON, ts);
-		serio_set_drvdata(serio, NULL);
-		kfree(ts);
+	if (err)
 		return err;
-	}
 
 	//h3600_flite_control(1, 25);     /* default brightness */
-#ifdef CONFIG_PM
-	ts->pm_dev = pm_register(PM_ILLUMINATION_DEV, PM_SYS_LIGHT,
-				h3600ts_pm_callback);
-	printk("registered pm callback\n");
-#endif
-	input_register_device(&ts->dev);
-
-	printk(KERN_INFO "input: %s on %s\n", h3600_name, serio->phys);
+	input_register_device(ts->dev);
 
 	return 0;
+
+fail3:	free_irq(IRQ_GPIO_BITSY_NPOWER_BUTTON, ts->dev);
+fail2:	free_irq(IRQ_GPIO_BITSY_ACTION_BUTTON, ts->dev);
+fail1:	serio_set_drvdata(serio, NULL);
+	input_free_device(input_dev);
+	kfree(ts);
+	return err;
 }
 
 /*
@@ -476,9 +443,11 @@
 
 	free_irq(IRQ_GPIO_BITSY_ACTION_BUTTON, &ts->dev);
 	free_irq(IRQ_GPIO_BITSY_NPOWER_BUTTON, &ts->dev);
-	input_unregister_device(&ts->dev);
+	input_get_device(ts->dev);
+	input_unregister_device(ts->dev);
 	serio_close(serio);
 	serio_set_drvdata(serio, NULL);
+	input_put_device(ts->dev);
 	kfree(ts);
 }
 
diff --git a/drivers/input/touchscreen/hp680_ts_input.c b/drivers/input/touchscreen/hp680_ts_input.c
index 7e14044..957dd5a 100644
--- a/drivers/input/touchscreen/hp680_ts_input.c
+++ b/drivers/input/touchscreen/hp680_ts_input.c
@@ -21,10 +21,8 @@
 
 static void do_softint(void *data);
 
-static struct input_dev hp680_ts_dev;
+static struct input_dev *hp680_ts_dev;
 static DECLARE_WORK(work, do_softint, 0);
-static char *hp680_ts_name = "HP Jornada touchscreen";
-static char *hp680_ts_phys = "input0";
 
 static void do_softint(void *data)
 {
@@ -58,14 +56,14 @@
 	}
 
 	if (touched) {
-		input_report_key(&hp680_ts_dev, BTN_TOUCH, 1);
-		input_report_abs(&hp680_ts_dev, ABS_X, absx);
-		input_report_abs(&hp680_ts_dev, ABS_Y, absy);
+		input_report_key(hp680_ts_dev, BTN_TOUCH, 1);
+		input_report_abs(hp680_ts_dev, ABS_X, absx);
+		input_report_abs(hp680_ts_dev, ABS_Y, absy);
 	} else {
-		input_report_key(&hp680_ts_dev, BTN_TOUCH, 0);
+		input_report_key(hp680_ts_dev, BTN_TOUCH, 0);
 	}
 
-	input_sync(&hp680_ts_dev);
+	input_sync(hp680_ts_dev);
 	enable_irq(HP680_TS_IRQ);
 }
 
@@ -92,27 +90,29 @@
 	scpcr |= SCPCR_TS_ENABLE;
 	ctrl_outw(scpcr, SCPCR);
 
-	memset(&hp680_ts_dev, 0, sizeof(hp680_ts_dev));
-	init_input_dev(&hp680_ts_dev);
+	hp680_ts_dev = input_allocate_device();
+	if (!hp680_ts_dev)
+		return -ENOMEM;
 
-	hp680_ts_dev.evbit[0] = BIT(EV_ABS) | BIT(EV_KEY);
-	hp680_ts_dev.absbit[0] = BIT(ABS_X) | BIT(ABS_Y);
-	hp680_ts_dev.keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH);
+	hp680_ts_dev->evbit[0] = BIT(EV_ABS) | BIT(EV_KEY);
+	hp680_ts_dev->absbit[0] = BIT(ABS_X) | BIT(ABS_Y);
+	hp680_ts_dev->keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH);
 
-	hp680_ts_dev.absmin[ABS_X] = HP680_TS_ABS_X_MIN;
-	hp680_ts_dev.absmin[ABS_Y] = HP680_TS_ABS_Y_MIN;
-	hp680_ts_dev.absmax[ABS_X] = HP680_TS_ABS_X_MAX;
-	hp680_ts_dev.absmax[ABS_Y] = HP680_TS_ABS_Y_MAX;
+	hp680_ts_dev->absmin[ABS_X] = HP680_TS_ABS_X_MIN;
+	hp680_ts_dev->absmin[ABS_Y] = HP680_TS_ABS_Y_MIN;
+	hp680_ts_dev->absmax[ABS_X] = HP680_TS_ABS_X_MAX;
+	hp680_ts_dev->absmax[ABS_Y] = HP680_TS_ABS_Y_MAX;
 
-	hp680_ts_dev.name = hp680_ts_name;
-	hp680_ts_dev.phys = hp680_ts_phys;
-	input_register_device(&hp680_ts_dev);
+	hp680_ts_dev->name = "HP Jornada touchscreen";
+	hp680_ts_dev->phys = "hp680_ts/input0";
 
-	if (request_irq
-	    (HP680_TS_IRQ, hp680_ts_interrupt, SA_INTERRUPT, MODNAME, 0) < 0) {
-		printk(KERN_ERR "hp680_touchscreen.c : Can't allocate irq %d\n",
+	input_register_device(hp680_ts_dev);
+
+	if (request_irq(HP680_TS_IRQ, hp680_ts_interrupt,
+			SA_INTERRUPT, MODNAME, 0) < 0) {
+		printk(KERN_ERR "hp680_touchscreen.c: Can't allocate irq %d\n",
 		       HP680_TS_IRQ);
-		input_unregister_device(&hp680_ts_dev);
+		input_unregister_device(hp680_ts_dev);
 		return -EBUSY;
 	}
 
@@ -124,7 +124,7 @@
 	free_irq(HP680_TS_IRQ, 0);
 	cancel_delayed_work(&work);
 	flush_scheduled_work();
-	input_unregister_device(&hp680_ts_dev);
+	input_unregister_device(hp680_ts_dev);
 }
 
 module_init(hp680_ts_init);
diff --git a/drivers/input/touchscreen/mk712.c b/drivers/input/touchscreen/mk712.c
index afaaebe..4844d25 100644
--- a/drivers/input/touchscreen/mk712.c
+++ b/drivers/input/touchscreen/mk712.c
@@ -77,7 +77,7 @@
 #define MK712_READ_ONE_POINT			0x20
 #define MK712_POWERUP				0x40
 
-static struct input_dev mk712_dev;
+static struct input_dev *mk712_dev;
 static DEFINE_SPINLOCK(mk712_lock);
 
 static irqreturn_t mk712_interrupt(int irq, void *dev_id, struct pt_regs *regs)
@@ -88,7 +88,7 @@
 	static unsigned short last_y;
 
 	spin_lock(&mk712_lock);
-	input_regs(&mk712_dev, regs);
+	input_regs(mk712_dev, regs);
 
 	status = inb(mk712_io + MK712_STATUS);
 
@@ -100,7 +100,7 @@
 	if (~status & MK712_STATUS_TOUCH)
 	{
 		debounce = 1;
-		input_report_key(&mk712_dev, BTN_TOUCH, 0);
+		input_report_key(mk712_dev, BTN_TOUCH, 0);
 		goto end;
 	}
 
@@ -110,15 +110,15 @@
 		goto end;
 	}
 
-	input_report_key(&mk712_dev, BTN_TOUCH, 1);
-	input_report_abs(&mk712_dev, ABS_X, last_x);
-	input_report_abs(&mk712_dev, ABS_Y, last_y);
+	input_report_key(mk712_dev, BTN_TOUCH, 1);
+	input_report_abs(mk712_dev, ABS_X, last_x);
+	input_report_abs(mk712_dev, ABS_Y, last_y);
 
 end:
 
 	last_x = inw(mk712_io + MK712_X) & 0x0fff;
 	last_y = inw(mk712_io + MK712_Y) & 0x0fff;
-	input_sync(&mk712_dev);
+	input_sync(mk712_dev);
 	spin_unlock(&mk712_lock);
 	return IRQ_HANDLED;
 }
@@ -154,30 +154,11 @@
 	spin_unlock_irqrestore(&mk712_lock, flags);
 }
 
-static struct input_dev mk712_dev = {
-	.evbit   = { BIT(EV_KEY) | BIT(EV_ABS) },
-	.keybit  = { [LONG(BTN_TOUCH)] = BIT(BTN_TOUCH) },
-	.absbit  = { BIT(ABS_X) | BIT(ABS_Y) },
-	.open    = mk712_open,
-	.close   = mk712_close,
-	.name    = "ICS MicroClock MK712 TouchScreen",
-	.phys    = "isa0260/input0",
-	.absmin  = { [ABS_X] = 0, [ABS_Y] = 0 },
-	.absmax  = { [ABS_X] = 0xfff, [ABS_Y] = 0xfff },
-	.absfuzz = { [ABS_X] = 88, [ABS_Y] = 88 },
-	.id      = {
-		.bustype = BUS_ISA,
-		.vendor  = 0x0005,
-		.product = 0x0001,
-		.version = 0x0100,
-	},
-};
-
 int __init mk712_init(void)
 {
+	int err;
 
-	if(!request_region(mk712_io, 8, "mk712"))
-	{
+	if (!request_region(mk712_io, 8, "mk712")) {
 		printk(KERN_WARNING "mk712: unable to get IO region\n");
 		return -ENODEV;
 	}
@@ -188,28 +169,49 @@
 	    (inw(mk712_io + MK712_Y) & 0xf000) ||
 	    (inw(mk712_io + MK712_STATUS) & 0xf333)) {
 		printk(KERN_WARNING "mk712: device not present\n");
-		release_region(mk712_io, 8);
-		return -ENODEV;
+		err = -ENODEV;
+		goto fail;
 	}
 
-	if(request_irq(mk712_irq, mk712_interrupt, 0, "mk712", &mk712_dev))
-	{
+	if (!(mk712_dev = input_allocate_device())) {
+		printk(KERN_ERR "mk712: not enough memory\n");
+		err = -ENOMEM;
+		goto fail;
+	}
+
+	mk712_dev->name = "ICS MicroClock MK712 TouchScreen";
+	mk712_dev->phys = "isa0260/input0";
+	mk712_dev->id.bustype = BUS_ISA;
+	mk712_dev->id.vendor  = 0x0005;
+	mk712_dev->id.product = 0x0001;
+	mk712_dev->id.version = 0x0100;
+
+	mk712_dev->open    = mk712_open;
+	mk712_dev->close   = mk712_close;
+
+	mk712_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
+	mk712_dev->keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH);
+	input_set_abs_params(mk712_dev, ABS_X, 0, 0xfff, 88, 0);
+	input_set_abs_params(mk712_dev, ABS_Y, 0, 0xfff, 88, 0);
+
+	if (request_irq(mk712_irq, mk712_interrupt, 0, "mk712", mk712_dev)) {
 		printk(KERN_WARNING "mk712: unable to get IRQ\n");
-		release_region(mk712_io, 8);
-		return -EBUSY;
+		err = -EBUSY;
+		goto fail;
 	}
 
-	input_register_device(&mk712_dev);
-
-	printk(KERN_INFO "input: ICS MicroClock MK712 TouchScreen at %#x irq %d\n", mk712_io, mk712_irq);
-
+	input_register_device(mk712_dev);
 	return 0;
+
+ fail:	input_free_device(mk712_dev);
+	release_region(mk712_io, 8);
+	return err;
 }
 
 static void __exit mk712_exit(void)
 {
-	input_unregister_device(&mk712_dev);
-	free_irq(mk712_irq, &mk712_dev);
+	input_unregister_device(mk712_dev);
+	free_irq(mk712_irq, mk712_dev);
 	release_region(mk712_io, 8);
 }
 
diff --git a/drivers/input/touchscreen/mtouch.c b/drivers/input/touchscreen/mtouch.c
index aa8ee78..1d0d37e 100644
--- a/drivers/input/touchscreen/mtouch.c
+++ b/drivers/input/touchscreen/mtouch.c
@@ -51,14 +51,12 @@
 #define MTOUCH_GET_YC(data) (((data[4])<<7) | data[3])
 #define MTOUCH_GET_TOUCHED(data) (MTOUCH_FORMAT_TABLET_TOUCH_BIT & data[0])
 
-static char *mtouch_name = "MicroTouch Serial TouchScreen";
-
 /*
  * Per-touchscreen data.
  */
 
 struct mtouch {
-	struct input_dev dev;
+	struct input_dev *dev;
 	struct serio *serio;
 	int idx;
 	unsigned char data[MTOUCH_MAX_LENGTH];
@@ -67,7 +65,7 @@
 
 static void mtouch_process_format_tablet(struct mtouch *mtouch, struct pt_regs *regs)
 {
-	struct input_dev *dev = &mtouch->dev;
+	struct input_dev *dev = mtouch->dev;
 
 	if (MTOUCH_FORMAT_TABLET_LENGTH == ++mtouch->idx) {
 		input_regs(dev, regs);
@@ -116,9 +114,11 @@
 {
 	struct mtouch* mtouch = serio_get_drvdata(serio);
 
-	input_unregister_device(&mtouch->dev);
+	input_get_device(mtouch->dev);
+	input_unregister_device(mtouch->dev);
 	serio_close(serio);
 	serio_set_drvdata(serio, NULL);
+	input_put_device(mtouch->dev);
 	kfree(mtouch);
 }
 
@@ -131,46 +131,46 @@
 static int mtouch_connect(struct serio *serio, struct serio_driver *drv)
 {
 	struct mtouch *mtouch;
+	struct input_dev *input_dev;
 	int err;
 
-	if (!(mtouch = kmalloc(sizeof(*mtouch), GFP_KERNEL)))
-		return -ENOMEM;
-
-	memset(mtouch, 0, sizeof(*mtouch));
-
-	init_input_dev(&mtouch->dev);
-	mtouch->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
-	mtouch->dev.keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH);
-
-	input_set_abs_params(&mtouch->dev, ABS_X, MTOUCH_MIN_XC, MTOUCH_MAX_XC, 0, 0);
-	input_set_abs_params(&mtouch->dev, ABS_Y, MTOUCH_MIN_YC, MTOUCH_MAX_YC, 0, 0);
+	mtouch = kzalloc(sizeof(struct mtouch), GFP_KERNEL);
+	input_dev = input_allocate_device();
+	if (!mtouch || !input_dev) {
+		err = -ENOMEM;
+		goto fail;
+	}
 
 	mtouch->serio = serio;
-
+	mtouch->dev = input_dev;
 	sprintf(mtouch->phys, "%s/input0", serio->phys);
 
-	mtouch->dev.private = mtouch;
-	mtouch->dev.name = mtouch_name;
-	mtouch->dev.phys = mtouch->phys;
-	mtouch->dev.id.bustype = BUS_RS232;
-	mtouch->dev.id.vendor = SERIO_MICROTOUCH;
-	mtouch->dev.id.product = 0;
-	mtouch->dev.id.version = 0x0100;
+	input_dev->private = mtouch;
+	input_dev->name = "MicroTouch Serial TouchScreen";
+	input_dev->phys = mtouch->phys;
+	input_dev->id.bustype = BUS_RS232;
+	input_dev->id.vendor = SERIO_MICROTOUCH;
+	input_dev->id.product = 0;
+	input_dev->id.version = 0x0100;
+	input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
+	input_dev->keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH);
+	input_set_abs_params(mtouch->dev, ABS_X, MTOUCH_MIN_XC, MTOUCH_MAX_XC, 0, 0);
+	input_set_abs_params(mtouch->dev, ABS_Y, MTOUCH_MIN_YC, MTOUCH_MAX_YC, 0, 0);
 
 	serio_set_drvdata(serio, mtouch);
 
 	err = serio_open(serio, drv);
-	if (err) {
-		serio_set_drvdata(serio, NULL);
-		kfree(mtouch);
-		return err;
-	}
+	if (err)
+		goto fail;
 
-	input_register_device(&mtouch->dev);
-
-	printk(KERN_INFO "input: %s on %s\n", mtouch->dev.name, serio->phys);
+	input_register_device(mtouch->dev);
 
 	return 0;
+
+ fail:	serio_set_drvdata(serio, NULL);
+	input_free_device(input_dev);
+	kfree(mtouch);
+	return err;
 }
 
 /*
diff --git a/drivers/input/tsdev.c b/drivers/input/tsdev.c
index 50c63a1..ca15479 100644
--- a/drivers/input/tsdev.c
+++ b/drivers/input/tsdev.c
@@ -53,7 +53,6 @@
 #include <linux/random.h>
 #include <linux/time.h>
 #include <linux/device.h>
-#include <linux/devfs_fs_kernel.h>
 
 #ifndef CONFIG_INPUT_TSDEV_SCREEN_X
 #define CONFIG_INPUT_TSDEV_SCREEN_X	240
@@ -369,6 +368,7 @@
 					  struct input_device_id *id)
 {
 	struct tsdev *tsdev;
+	struct class_device *cdev;
 	int minor, delta;
 
 	for (minor = 0; minor < TSDEV_MINORS/2 && tsdev_table[minor];
@@ -410,13 +410,13 @@
 
 	tsdev_table[minor] = tsdev;
 
-	devfs_mk_cdev(MKDEV(INPUT_MAJOR, TSDEV_MINOR_BASE + minor),
-			S_IFCHR|S_IRUGO|S_IWUSR, "input/ts%d", minor);
-	devfs_mk_cdev(MKDEV(INPUT_MAJOR, TSDEV_MINOR_BASE + minor + TSDEV_MINORS/2),
-			S_IFCHR|S_IRUGO|S_IWUSR, "input/tsraw%d", minor);
-	class_device_create(input_class,
+	cdev = class_device_create(&input_class, &dev->cdev,
 			MKDEV(INPUT_MAJOR, TSDEV_MINOR_BASE + minor),
-			dev->dev, "ts%d", minor);
+			dev->cdev.dev, tsdev->name);
+
+	/* temporary symlink to keep userspace happy */
+	sysfs_create_link(&input_class.subsys.kset.kobj, &cdev->kobj,
+			  tsdev->name);
 
 	return &tsdev->handle;
 }
@@ -426,10 +426,9 @@
 	struct tsdev *tsdev = handle->private;
 	struct tsdev_list *list;
 
-	class_device_destroy(input_class,
+	sysfs_remove_link(&input_class.subsys.kset.kobj, tsdev->name);
+	class_device_destroy(&input_class,
 			MKDEV(INPUT_MAJOR, TSDEV_MINOR_BASE + tsdev->minor));
-	devfs_remove("input/ts%d", tsdev->minor);
-	devfs_remove("input/tsraw%d", tsdev->minor);
 	tsdev->exist = 0;
 
 	if (tsdev->open) {
diff --git a/drivers/isdn/capi/capi.c b/drivers/isdn/capi/capi.c
index 04fb606..11ae0fd 100644
--- a/drivers/isdn/capi/capi.c
+++ b/drivers/isdn/capi/capi.c
@@ -1505,7 +1505,7 @@
 		return PTR_ERR(capi_class);
 	}
 
-	class_device_create(capi_class, MKDEV(capi_major, 0), NULL, "capi");
+	class_device_create(capi_class, NULL, MKDEV(capi_major, 0), NULL, "capi");
 	devfs_mk_cdev(MKDEV(capi_major, 0), S_IFCHR | S_IRUSR | S_IWUSR,
 			"isdn/capi20");
 
diff --git a/drivers/macintosh/adb.c b/drivers/macintosh/adb.c
index c0dc1e3..d2ead17 100644
--- a/drivers/macintosh/adb.c
+++ b/drivers/macintosh/adb.c
@@ -905,5 +905,5 @@
 	adb_dev_class = class_create(THIS_MODULE, "adb");
 	if (IS_ERR(adb_dev_class))
 		return;
-	class_device_create(adb_dev_class, MKDEV(ADB_MAJOR, 0), NULL, "adb");
+	class_device_create(adb_dev_class, NULL, MKDEV(ADB_MAJOR, 0), NULL, "adb");
 }
diff --git a/drivers/macintosh/adbhid.c b/drivers/macintosh/adbhid.c
index db654e8..cdb6d02 100644
--- a/drivers/macintosh/adbhid.c
+++ b/drivers/macintosh/adbhid.c
@@ -206,7 +206,7 @@
 };
 
 struct adbhid {
-	struct input_dev input;
+	struct input_dev *input;
 	int id;
 	int default_id;
 	int original_handler_id;
@@ -291,10 +291,10 @@
 
 	switch (keycode) {
 	case ADB_KEY_CAPSLOCK: /* Generate down/up events for CapsLock everytime. */
-		input_regs(&ahid->input, regs);
-		input_report_key(&ahid->input, KEY_CAPSLOCK, 1);
-		input_report_key(&ahid->input, KEY_CAPSLOCK, 0);
-		input_sync(&ahid->input);
+		input_regs(ahid->input, regs);
+		input_report_key(ahid->input, KEY_CAPSLOCK, 1);
+		input_report_key(ahid->input, KEY_CAPSLOCK, 0);
+		input_sync(ahid->input);
 		return;
 #ifdef CONFIG_PPC_PMAC
 	case ADB_KEY_POWER_OLD: /* Power key on PBook 3400 needs remapping */
@@ -347,10 +347,10 @@
 	}
 
 	if (adbhid[id]->keycode[keycode]) {
-		input_regs(&adbhid[id]->input, regs);
-		input_report_key(&adbhid[id]->input,
+		input_regs(adbhid[id]->input, regs);
+		input_report_key(adbhid[id]->input,
 				 adbhid[id]->keycode[keycode], !up_flag);
-		input_sync(&adbhid[id]->input);
+		input_sync(adbhid[id]->input);
 	} else
 		printk(KERN_INFO "Unhandled ADB key (scancode %#02x) %s.\n", keycode,
 		       up_flag ? "released" : "pressed");
@@ -441,20 +441,20 @@
                 break;
 	}
 
-	input_regs(&adbhid[id]->input, regs);
+	input_regs(adbhid[id]->input, regs);
 
-	input_report_key(&adbhid[id]->input, BTN_LEFT,   !((data[1] >> 7) & 1));
-	input_report_key(&adbhid[id]->input, BTN_MIDDLE, !((data[2] >> 7) & 1));
+	input_report_key(adbhid[id]->input, BTN_LEFT,   !((data[1] >> 7) & 1));
+	input_report_key(adbhid[id]->input, BTN_MIDDLE, !((data[2] >> 7) & 1));
 
 	if (nb >= 4 && adbhid[id]->mouse_kind != ADBMOUSE_TRACKPAD)
-		input_report_key(&adbhid[id]->input, BTN_RIGHT,  !((data[3] >> 7) & 1));
+		input_report_key(adbhid[id]->input, BTN_RIGHT,  !((data[3] >> 7) & 1));
 
-	input_report_rel(&adbhid[id]->input, REL_X,
+	input_report_rel(adbhid[id]->input, REL_X,
 			 ((data[2]&0x7f) < 64 ? (data[2]&0x7f) : (data[2]&0x7f)-128 ));
-	input_report_rel(&adbhid[id]->input, REL_Y,
+	input_report_rel(adbhid[id]->input, REL_Y,
 			 ((data[1]&0x7f) < 64 ? (data[1]&0x7f) : (data[1]&0x7f)-128 ));
 
-	input_sync(&adbhid[id]->input);
+	input_sync(adbhid[id]->input);
 }
 
 static void
@@ -467,7 +467,7 @@
 		return;
 	}
 
-	input_regs(&adbhid[id]->input, regs);
+	input_regs(adbhid[id]->input, regs);
 
 	switch (adbhid[id]->original_handler_id) {
 	default:
@@ -477,19 +477,19 @@
 
 		switch (data[1] & 0x0f) {
 		case 0x0:	/* microphone */
-			input_report_key(&adbhid[id]->input, KEY_SOUND, down);
+			input_report_key(adbhid[id]->input, KEY_SOUND, down);
 			break;
 
 		case 0x1:	/* mute */
-			input_report_key(&adbhid[id]->input, KEY_MUTE, down);
+			input_report_key(adbhid[id]->input, KEY_MUTE, down);
 			break;
 
 		case 0x2:	/* volume decrease */
-			input_report_key(&adbhid[id]->input, KEY_VOLUMEDOWN, down);
+			input_report_key(adbhid[id]->input, KEY_VOLUMEDOWN, down);
 			break;
 
 		case 0x3:	/* volume increase */
-			input_report_key(&adbhid[id]->input, KEY_VOLUMEUP, down);
+			input_report_key(adbhid[id]->input, KEY_VOLUMEUP, down);
 			break;
 
 		default:
@@ -513,19 +513,19 @@
 
 		switch (data[1] & 0x0f) {
 		case 0x8:	/* mute */
-			input_report_key(&adbhid[id]->input, KEY_MUTE, down);
+			input_report_key(adbhid[id]->input, KEY_MUTE, down);
 			break;
 
 		case 0x7:	/* volume decrease */
-			input_report_key(&adbhid[id]->input, KEY_VOLUMEDOWN, down);
+			input_report_key(adbhid[id]->input, KEY_VOLUMEDOWN, down);
 			break;
 
 		case 0x6:	/* volume increase */
-			input_report_key(&adbhid[id]->input, KEY_VOLUMEUP, down);
+			input_report_key(adbhid[id]->input, KEY_VOLUMEUP, down);
 			break;
 
 		case 0xb:	/* eject */
-			input_report_key(&adbhid[id]->input, KEY_EJECTCD, down);
+			input_report_key(adbhid[id]->input, KEY_EJECTCD, down);
 			break;
 
 		case 0xa:	/* brightness decrease */
@@ -539,7 +539,7 @@
 				}
 			}
 #endif /* CONFIG_PMAC_BACKLIGHT */
-			input_report_key(&adbhid[id]->input, KEY_BRIGHTNESSDOWN, down);
+			input_report_key(adbhid[id]->input, KEY_BRIGHTNESSDOWN, down);
 			break;
 
 		case 0x9:	/* brightness increase */
@@ -553,19 +553,19 @@
 				}
 			}
 #endif /* CONFIG_PMAC_BACKLIGHT */
-			input_report_key(&adbhid[id]->input, KEY_BRIGHTNESSUP, down);
+			input_report_key(adbhid[id]->input, KEY_BRIGHTNESSUP, down);
 			break;
 
 		case 0xc:	/* videomode switch */
-			input_report_key(&adbhid[id]->input, KEY_SWITCHVIDEOMODE, down);
+			input_report_key(adbhid[id]->input, KEY_SWITCHVIDEOMODE, down);
 			break;
 
 		case 0xd:	/* keyboard illumination toggle */
-			input_report_key(&adbhid[id]->input, KEY_KBDILLUMTOGGLE, down);
+			input_report_key(adbhid[id]->input, KEY_KBDILLUMTOGGLE, down);
 			break;
 
 		case 0xe:	/* keyboard illumination decrease */
-			input_report_key(&adbhid[id]->input, KEY_KBDILLUMDOWN, down);
+			input_report_key(adbhid[id]->input, KEY_KBDILLUMDOWN, down);
 			break;
 
 		case 0xf:
@@ -573,7 +573,7 @@
 			case 0x8f:
 			case 0x0f:
 				/* keyboard illumination increase */
-				input_report_key(&adbhid[id]->input, KEY_KBDILLUMUP, down);
+				input_report_key(adbhid[id]->input, KEY_KBDILLUMUP, down);
 				break;
 
 			case 0x7f:
@@ -596,7 +596,7 @@
 	  break;
 	}
 
-	input_sync(&adbhid[id]->input);
+	input_sync(adbhid[id]->input);
 }
 
 static struct adb_request led_request;
@@ -683,7 +683,7 @@
 			int i;
 			for (i = 1; i < 16; i++) {
 				if (adbhid[i])
-					del_timer_sync(&adbhid[i]->input.timer);
+					del_timer_sync(&adbhid[i]->input->timer);
 			}
 		}
 
@@ -699,153 +699,163 @@
 	return NOTIFY_DONE;
 }
 
-static void
+static int
 adbhid_input_register(int id, int default_id, int original_handler_id,
 		      int current_handler_id, int mouse_kind)
 {
+	struct adbhid *hid;
+	struct input_dev *input_dev;
+	int err;
 	int i;
 
 	if (adbhid[id]) {
 		printk(KERN_ERR "Trying to reregister ADB HID on ID %d\n", id);
-		return;
+		return -EEXIST;
 	}
 
-	if (!(adbhid[id] = kmalloc(sizeof(struct adbhid), GFP_KERNEL)))
-		return;
+	adbhid[id] = hid = kzalloc(sizeof(struct adbhid), GFP_KERNEL);
+	input_dev = input_allocate_device();
+	if (!hid || !input_dev) {
+		err = -ENOMEM;
+		goto fail;
 
-	memset(adbhid[id], 0, sizeof(struct adbhid));
-	sprintf(adbhid[id]->phys, "adb%d:%d.%02x/input", id, default_id, original_handler_id);
+	}
 
-	init_input_dev(&adbhid[id]->input);
+	sprintf(hid->phys, "adb%d:%d.%02x/input", id, default_id, original_handler_id);
 
-	adbhid[id]->id = default_id;
-	adbhid[id]->original_handler_id = original_handler_id;
-	adbhid[id]->current_handler_id = current_handler_id;
-	adbhid[id]->mouse_kind = mouse_kind;
-	adbhid[id]->flags = 0;
-	adbhid[id]->input.private = adbhid[id];
-	adbhid[id]->input.name = adbhid[id]->name;
-	adbhid[id]->input.phys = adbhid[id]->phys;
-	adbhid[id]->input.id.bustype = BUS_ADB;
-	adbhid[id]->input.id.vendor = 0x0001;
-	adbhid[id]->input.id.product = (id << 12) | (default_id << 8) | original_handler_id;
-	adbhid[id]->input.id.version = 0x0100;
+	hid->id = default_id;
+	hid->original_handler_id = original_handler_id;
+	hid->current_handler_id = current_handler_id;
+	hid->mouse_kind = mouse_kind;
+	hid->flags = 0;
+	input_dev->private = hid;
+	input_dev->name = hid->name;
+	input_dev->phys = hid->phys;
+	input_dev->id.bustype = BUS_ADB;
+	input_dev->id.vendor = 0x0001;
+	input_dev->id.product = (id << 12) | (default_id << 8) | original_handler_id;
+	input_dev->id.version = 0x0100;
 
 	switch (default_id) {
 	case ADB_KEYBOARD:
-		if (!(adbhid[id]->keycode = kmalloc(sizeof(adb_to_linux_keycodes), GFP_KERNEL))) {
-			kfree(adbhid[id]);
-			return;
+		hid->keycode = kmalloc(sizeof(adb_to_linux_keycodes), GFP_KERNEL);
+		if (!hid->keycode) {
+			err = -ENOMEM;
+			goto fail;
 		}
 
-		sprintf(adbhid[id]->name, "ADB keyboard");
+		sprintf(hid->name, "ADB keyboard");
 
-		memcpy(adbhid[id]->keycode, adb_to_linux_keycodes, sizeof(adb_to_linux_keycodes));
+		memcpy(hid->keycode, adb_to_linux_keycodes, sizeof(adb_to_linux_keycodes));
 
 		printk(KERN_INFO "Detected ADB keyboard, type ");
 		switch (original_handler_id) {
 		default:
 			printk("<unknown>.\n");
-			adbhid[id]->input.id.version = ADB_KEYBOARD_UNKNOWN;
+			input_dev->id.version = ADB_KEYBOARD_UNKNOWN;
 			break;
 
 		case 0x01: case 0x02: case 0x03: case 0x06: case 0x08:
 		case 0x0C: case 0x10: case 0x18: case 0x1B: case 0x1C:
 		case 0xC0: case 0xC3: case 0xC6:
 			printk("ANSI.\n");
-			adbhid[id]->input.id.version = ADB_KEYBOARD_ANSI;
+			input_dev->id.version = ADB_KEYBOARD_ANSI;
 			break;
 
 		case 0x04: case 0x05: case 0x07: case 0x09: case 0x0D:
 		case 0x11: case 0x14: case 0x19: case 0x1D: case 0xC1:
 		case 0xC4: case 0xC7:
 			printk("ISO, swapping keys.\n");
-			adbhid[id]->input.id.version = ADB_KEYBOARD_ISO;
-			i = adbhid[id]->keycode[10];
-			adbhid[id]->keycode[10] = adbhid[id]->keycode[50];
-			adbhid[id]->keycode[50] = i;
+			input_dev->id.version = ADB_KEYBOARD_ISO;
+			i = hid->keycode[10];
+			hid->keycode[10] = hid->keycode[50];
+			hid->keycode[50] = i;
 			break;
 
 		case 0x12: case 0x15: case 0x16: case 0x17: case 0x1A:
 		case 0x1E: case 0xC2: case 0xC5: case 0xC8: case 0xC9:
 			printk("JIS.\n");
-			adbhid[id]->input.id.version = ADB_KEYBOARD_JIS;
+			input_dev->id.version = ADB_KEYBOARD_JIS;
 			break;
 		}
 
 		for (i = 0; i < 128; i++)
-			if (adbhid[id]->keycode[i])
-				set_bit(adbhid[id]->keycode[i], adbhid[id]->input.keybit);
+			if (hid->keycode[i])
+				set_bit(hid->keycode[i], input_dev->keybit);
 
-		adbhid[id]->input.evbit[0] = BIT(EV_KEY) | BIT(EV_LED) | BIT(EV_REP);
-		adbhid[id]->input.ledbit[0] = BIT(LED_SCROLLL) | BIT(LED_CAPSL) | BIT(LED_NUML);
-		adbhid[id]->input.event = adbhid_kbd_event;
-		adbhid[id]->input.keycodemax = 127;
-		adbhid[id]->input.keycodesize = 1;
+		input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_LED) | BIT(EV_REP);
+		input_dev->ledbit[0] = BIT(LED_SCROLLL) | BIT(LED_CAPSL) | BIT(LED_NUML);
+		input_dev->event = adbhid_kbd_event;
+		input_dev->keycodemax = 127;
+		input_dev->keycodesize = 1;
 		break;
 
 	case ADB_MOUSE:
-		sprintf(adbhid[id]->name, "ADB mouse");
+		sprintf(hid->name, "ADB mouse");
 
-		adbhid[id]->input.evbit[0] = BIT(EV_KEY) | BIT(EV_REL);
-		adbhid[id]->input.keybit[LONG(BTN_MOUSE)] = BIT(BTN_LEFT) | BIT(BTN_MIDDLE) | BIT(BTN_RIGHT);
-		adbhid[id]->input.relbit[0] = BIT(REL_X) | BIT(REL_Y);
+		input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REL);
+		input_dev->keybit[LONG(BTN_MOUSE)] = BIT(BTN_LEFT) | BIT(BTN_MIDDLE) | BIT(BTN_RIGHT);
+		input_dev->relbit[0] = BIT(REL_X) | BIT(REL_Y);
 		break;
 
 	case ADB_MISC:
 		switch (original_handler_id) {
 		case 0x02: /* Adjustable keyboard button device */
-			sprintf(adbhid[id]->name, "ADB adjustable keyboard buttons");
-			adbhid[id]->input.evbit[0] = BIT(EV_KEY) | BIT(EV_REP);
-			set_bit(KEY_SOUND, adbhid[id]->input.keybit);
-			set_bit(KEY_MUTE, adbhid[id]->input.keybit);
-			set_bit(KEY_VOLUMEUP, adbhid[id]->input.keybit);
-			set_bit(KEY_VOLUMEDOWN, adbhid[id]->input.keybit);
+			sprintf(hid->name, "ADB adjustable keyboard buttons");
+			input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REP);
+			set_bit(KEY_SOUND, input_dev->keybit);
+			set_bit(KEY_MUTE, input_dev->keybit);
+			set_bit(KEY_VOLUMEUP, input_dev->keybit);
+			set_bit(KEY_VOLUMEDOWN, input_dev->keybit);
 			break;
 		case 0x1f: /* Powerbook button device */
-			sprintf(adbhid[id]->name, "ADB Powerbook buttons");
-			adbhid[id]->input.evbit[0] = BIT(EV_KEY) | BIT(EV_REP);
-			set_bit(KEY_MUTE, adbhid[id]->input.keybit);
-			set_bit(KEY_VOLUMEUP, adbhid[id]->input.keybit);
-			set_bit(KEY_VOLUMEDOWN, adbhid[id]->input.keybit);
-			set_bit(KEY_BRIGHTNESSUP, adbhid[id]->input.keybit);
-			set_bit(KEY_BRIGHTNESSDOWN, adbhid[id]->input.keybit);
-			set_bit(KEY_EJECTCD, adbhid[id]->input.keybit);
-			set_bit(KEY_SWITCHVIDEOMODE, adbhid[id]->input.keybit);
-			set_bit(KEY_KBDILLUMTOGGLE, adbhid[id]->input.keybit);
-			set_bit(KEY_KBDILLUMDOWN, adbhid[id]->input.keybit);
-			set_bit(KEY_KBDILLUMUP, adbhid[id]->input.keybit);
+			sprintf(hid->name, "ADB Powerbook buttons");
+			input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REP);
+			set_bit(KEY_MUTE, input_dev->keybit);
+			set_bit(KEY_VOLUMEUP, input_dev->keybit);
+			set_bit(KEY_VOLUMEDOWN, input_dev->keybit);
+			set_bit(KEY_BRIGHTNESSUP, input_dev->keybit);
+			set_bit(KEY_BRIGHTNESSDOWN, input_dev->keybit);
+			set_bit(KEY_EJECTCD, input_dev->keybit);
+			set_bit(KEY_SWITCHVIDEOMODE, input_dev->keybit);
+			set_bit(KEY_KBDILLUMTOGGLE, input_dev->keybit);
+			set_bit(KEY_KBDILLUMDOWN, input_dev->keybit);
+			set_bit(KEY_KBDILLUMUP, input_dev->keybit);
 			break;
 		}
-		if (adbhid[id]->name[0])
+		if (hid->name[0])
 			break;
 		/* else fall through */
 
 	default:
 		printk(KERN_INFO "Trying to register unknown ADB device to input layer.\n");
-		kfree(adbhid[id]);
-		return;
+		err = -ENODEV;
+		goto fail;
 	}
 
-	adbhid[id]->input.keycode = adbhid[id]->keycode;
+	input_dev->keycode = hid->keycode;
 
-	input_register_device(&adbhid[id]->input);
-
-	printk(KERN_INFO "input: %s on %s\n",
-	       adbhid[id]->name, adbhid[id]->phys);
+	input_register_device(input_dev);
 
 	if (default_id == ADB_KEYBOARD) {
 		/* HACK WARNING!! This should go away as soon there is an utility
 		 * to control that for event devices.
 		 */
-		adbhid[id]->input.rep[REP_DELAY] = 500;   /* input layer default: 250 */
-		adbhid[id]->input.rep[REP_PERIOD] = 66; /* input layer default: 33 */
+		input_dev->rep[REP_DELAY] = 500;   /* input layer default: 250 */
+		input_dev->rep[REP_PERIOD] = 66; /* input layer default: 33 */
 	}
+
+	return 0;
+
+ fail:	input_free_device(input_dev);
+	kfree(hid);
+	adbhid[id] = NULL;
+	return err;
 }
 
 static void adbhid_input_unregister(int id)
 {
-	input_unregister_device(&adbhid[id]->input);
+	input_unregister_device(adbhid[id]->input);
 	if (adbhid[id]->keycode)
 		kfree(adbhid[id]->keycode);
 	kfree(adbhid[id]);
@@ -858,7 +868,7 @@
 			int cur_handler_id, int mk)
 {
 	if (adbhid[id]) {
-		if (adbhid[id]->input.id.product !=
+		if (adbhid[id]->input->id.product !=
 		    ((id << 12)|(default_id << 8)|org_handler_id)) {
 			adbhid_input_unregister(id);
 			adbhid_input_register(id, default_id, org_handler_id,
diff --git a/drivers/macintosh/mac_hid.c b/drivers/macintosh/mac_hid.c
index 5ad3a5a..a666361 100644
--- a/drivers/macintosh/mac_hid.c
+++ b/drivers/macintosh/mac_hid.c
@@ -16,8 +16,8 @@
 #include <linux/module.h>
 
 
-static struct input_dev emumousebtn;
-static void emumousebtn_input_register(void);
+static struct input_dev *emumousebtn;
+static int emumousebtn_input_register(void);
 static int mouse_emulate_buttons = 0;
 static int mouse_button2_keycode = KEY_RIGHTCTRL;	/* right control key */
 static int mouse_button3_keycode = KEY_RIGHTALT;	/* right option key */
@@ -90,10 +90,10 @@
 		    && (keycode == mouse_button2_keycode
 			|| keycode == mouse_button3_keycode)) {
 			if (mouse_emulate_buttons == 1) {
-			 	input_report_key(&emumousebtn,
+				input_report_key(emumousebtn,
 						 keycode == mouse_button2_keycode ? BTN_MIDDLE : BTN_RIGHT,
 						 down);
-				input_sync(&emumousebtn);
+				input_sync(emumousebtn);
 				return 1;
 			}
 			mouse_last_keycode = down ? keycode : 0;
@@ -105,30 +105,34 @@
 
 EXPORT_SYMBOL(mac_hid_mouse_emulate_buttons);
 
-static void emumousebtn_input_register(void)
+static int emumousebtn_input_register(void)
 {
-	emumousebtn.name = "Macintosh mouse button emulation";
+	emumousebtn = input_allocate_device();
+	if (!emumousebtn)
+		return -ENOMEM;
 
-	init_input_dev(&emumousebtn);
+	emumousebtn->name = "Macintosh mouse button emulation";
+	emumousebtn->id.bustype = BUS_ADB;
+	emumousebtn->id.vendor = 0x0001;
+	emumousebtn->id.product = 0x0001;
+	emumousebtn->id.version = 0x0100;
 
-	emumousebtn.evbit[0] = BIT(EV_KEY) | BIT(EV_REL);
-	emumousebtn.keybit[LONG(BTN_MOUSE)] = BIT(BTN_LEFT) | BIT(BTN_MIDDLE) | BIT(BTN_RIGHT);
-	emumousebtn.relbit[0] = BIT(REL_X) | BIT(REL_Y);
+	emumousebtn->evbit[0] = BIT(EV_KEY) | BIT(EV_REL);
+	emumousebtn->keybit[LONG(BTN_MOUSE)] = BIT(BTN_LEFT) | BIT(BTN_MIDDLE) | BIT(BTN_RIGHT);
+	emumousebtn->relbit[0] = BIT(REL_X) | BIT(REL_Y);
 
-	emumousebtn.id.bustype = BUS_ADB;
-	emumousebtn.id.vendor = 0x0001;
-	emumousebtn.id.product = 0x0001;
-	emumousebtn.id.version = 0x0100;
+	input_register_device(emumousebtn);
 
-	input_register_device(&emumousebtn);
-
-	printk(KERN_INFO "input: Macintosh mouse button emulation\n");
+	return 0;
 }
 
 int __init mac_hid_init(void)
 {
+	int err;
 
-	emumousebtn_input_register();
+	err = emumousebtn_input_register();
+	if (err)
+		return err;
 
 #if defined(CONFIG_SYSCTL)
 	mac_hid_sysctl_header = register_sysctl_table(mac_hid_root_dir, 1);
diff --git a/drivers/media/common/ir-common.c b/drivers/media/common/ir-common.c
index a0e700d..06f4d46 100644
--- a/drivers/media/common/ir-common.c
+++ b/drivers/media/common/ir-common.c
@@ -252,7 +252,6 @@
 	if (ir_codes)
 		memcpy(ir->ir_codes, ir_codes, sizeof(ir->ir_codes));
 
-        init_input_dev(dev);
 	dev->keycode     = ir->ir_codes;
 	dev->keycodesize = sizeof(IR_KEYTAB_TYPE);
 	dev->keycodemax  = IR_KEYTAB_SIZE;
diff --git a/drivers/media/dvb/cinergyT2/cinergyT2.c b/drivers/media/dvb/cinergyT2/cinergyT2.c
index 6db0929..a1607e7 100644
--- a/drivers/media/dvb/cinergyT2/cinergyT2.c
+++ b/drivers/media/dvb/cinergyT2/cinergyT2.c
@@ -137,7 +137,8 @@
 	struct urb *stream_urb [STREAM_URB_COUNT];
 
 #ifdef ENABLE_RC
-	struct input_dev rc_input_dev;
+	struct input_dev *rc_input_dev;
+	char phys[64];
 	struct work_struct rc_query_work;
 	int rc_input_event;
 	u32 rc_last_code;
@@ -683,6 +684,7 @@
 };
 
 #ifdef ENABLE_RC
+
 static void cinergyt2_query_rc (void *data)
 {
 	struct cinergyt2 *cinergyt2 = data;
@@ -703,7 +705,7 @@
 			/* stop key repeat */
 			if (cinergyt2->rc_input_event != KEY_MAX) {
 				dprintk(1, "rc_input_event=%d Up\n", cinergyt2->rc_input_event);
-				input_report_key(&cinergyt2->rc_input_dev,
+				input_report_key(cinergyt2->rc_input_dev,
 						 cinergyt2->rc_input_event, 0);
 				cinergyt2->rc_input_event = KEY_MAX;
 			}
@@ -722,7 +724,7 @@
 			/* keyrepeat bit -> just repeat last rc_input_event */
 		} else {
 			cinergyt2->rc_input_event = KEY_MAX;
-			for (i = 0; i < sizeof(rc_keys) / sizeof(rc_keys[0]); i += 3) {
+			for (i = 0; i < ARRAY_SIZE(rc_keys); i += 3) {
 				if (rc_keys[i + 0] == rc_events[n].type &&
 				    rc_keys[i + 1] == le32_to_cpu(rc_events[n].value)) {
 					cinergyt2->rc_input_event = rc_keys[i + 2];
@@ -736,11 +738,11 @@
 			    cinergyt2->rc_last_code != ~0) {
 				/* emit a key-up so the double event is recognized */
 				dprintk(1, "rc_input_event=%d UP\n", cinergyt2->rc_input_event);
-				input_report_key(&cinergyt2->rc_input_dev,
+				input_report_key(cinergyt2->rc_input_dev,
 						 cinergyt2->rc_input_event, 0);
 			}
 			dprintk(1, "rc_input_event=%d\n", cinergyt2->rc_input_event);
-			input_report_key(&cinergyt2->rc_input_dev,
+			input_report_key(cinergyt2->rc_input_dev,
 					 cinergyt2->rc_input_event, 1);
 			cinergyt2->rc_last_code = rc_events[n].value;
 		}
@@ -752,7 +754,59 @@
 
 	up(&cinergyt2->sem);
 }
-#endif
+
+static int cinergyt2_register_rc(struct cinergyt2 *cinergyt2)
+{
+	struct input_dev *input_dev;
+	int i;
+
+	cinergyt2->rc_input_dev = input_dev = input_allocate_device();
+	if (!input_dev)
+		return -ENOMEM;
+
+	usb_make_path(cinergyt2->udev, cinergyt2->phys, sizeof(cinergyt2->phys));
+	strlcat(cinergyt2->phys, "/input0", sizeof(cinergyt2->phys));
+	cinergyt2->rc_input_event = KEY_MAX;
+	cinergyt2->rc_last_code = ~0;
+	INIT_WORK(&cinergyt2->rc_query_work, cinergyt2_query_rc, cinergyt2);
+
+	input_dev->name = DRIVER_NAME " remote control";
+	input_dev->phys = cinergyt2->phys;
+	input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REP);
+	for (i = 0; ARRAY_SIZE(rc_keys); i += 3)
+		set_bit(rc_keys[i + 2], input_dev->keybit);
+	input_dev->keycodesize = 0;
+	input_dev->keycodemax = 0;
+
+	input_register_device(cinergyt2->rc_input_dev);
+	schedule_delayed_work(&cinergyt2->rc_query_work, HZ/2);
+}
+
+static void cinergyt2_unregister_rc(struct cinergyt2 *cinergyt2)
+{
+	cancel_delayed_work(&cinergyt2->rc_query_work);
+	flush_scheduled_work();
+	input_unregister_device(cinergyt2->rc_input_dev);
+}
+
+static inline void cinergyt2_suspend_rc(struct cinergyt2 *cinergyt2)
+{
+	cancel_delayed_work(&cinergyt2->rc_query_work);
+}
+
+static inline void cinergyt2_resume_rc(struct cinergyt2 *cinergyt2)
+{
+	schedule_delayed_work(&cinergyt2->rc_query_work, HZ/2);
+}
+
+#else
+
+static inline int cinergyt2_register_rc(struct cinergyt2 *cinergyt2) { return 0; }
+static inline void cinergyt2_unregister_rc(struct cinergyt2 *cinergyt2) { }
+static inline void cinergyt2_suspend_rc(struct cinergyt2 *cinergyt2) { }
+static inline void cinergyt2_resume_rc(struct cinergyt2 *cinergyt2) { }
+
+#endif /* ENABLE_RC */
 
 static void cinergyt2_query (void *data)
 {
@@ -789,9 +843,6 @@
 {
 	struct cinergyt2 *cinergyt2;
 	int err;
-#ifdef ENABLE_RC
-	int i;
-#endif
 
 	if (!(cinergyt2 = kmalloc (sizeof(struct cinergyt2), GFP_KERNEL))) {
 		dprintk(1, "out of memory?!?\n");
@@ -846,30 +897,17 @@
 			    &cinergyt2_fe_template, cinergyt2,
 			    DVB_DEVICE_FRONTEND);
 
-#ifdef ENABLE_RC
-	cinergyt2->rc_input_dev.evbit[0] = BIT(EV_KEY) | BIT(EV_REP);
-	cinergyt2->rc_input_dev.keycodesize = 0;
-	cinergyt2->rc_input_dev.keycodemax = 0;
-	cinergyt2->rc_input_dev.name = DRIVER_NAME " remote control";
+	err = cinergyt2_register_rc(cinergyt2);
+	if (err)
+		goto bailout;
 
-	for (i = 0; i < sizeof(rc_keys) / sizeof(rc_keys[0]); i += 3)
-		set_bit(rc_keys[i + 2], cinergyt2->rc_input_dev.keybit);
-
-	input_register_device(&cinergyt2->rc_input_dev);
-
-	cinergyt2->rc_input_event = KEY_MAX;
-	cinergyt2->rc_last_code = ~0;
-
-	INIT_WORK(&cinergyt2->rc_query_work, cinergyt2_query_rc, cinergyt2);
-	schedule_delayed_work(&cinergyt2->rc_query_work, HZ/2);
-#endif
 	return 0;
 
 bailout:
 	dvb_dmxdev_release(&cinergyt2->dmxdev);
 	dvb_dmx_release(&cinergyt2->demux);
-	dvb_unregister_adapter (&cinergyt2->adapter);
-	cinergyt2_free_stream_urbs (cinergyt2);
+	dvb_unregister_adapter(&cinergyt2->adapter);
+	cinergyt2_free_stream_urbs(cinergyt2);
 	kfree(cinergyt2);
 	return -ENOMEM;
 }
@@ -881,11 +919,7 @@
 	if (down_interruptible(&cinergyt2->sem))
 		return;
 
-#ifdef ENABLE_RC
-	cancel_delayed_work(&cinergyt2->rc_query_work);
-	flush_scheduled_work();
-	input_unregister_device(&cinergyt2->rc_input_dev);
-#endif
+	cinergyt2_unregister_rc(cinergyt2);
 
 	cinergyt2->demux.dmx.close(&cinergyt2->demux.dmx);
 	dvb_net_release(&cinergyt2->dvbnet);
@@ -908,9 +942,8 @@
 
 	if (state.event > PM_EVENT_ON) {
 		struct cinergyt2 *cinergyt2 = usb_get_intfdata (intf);
-#ifdef ENABLE_RC
-		cancel_delayed_work(&cinergyt2->rc_query_work);
-#endif
+
+		cinergyt2_suspend_rc(cinergyt2);
 		cancel_delayed_work(&cinergyt2->query_work);
 		if (cinergyt2->streaming)
 			cinergyt2_stop_stream_xfer(cinergyt2);
@@ -938,9 +971,8 @@
 		schedule_delayed_work(&cinergyt2->query_work, HZ/2);
 	}
 
-#ifdef ENABLE_RC
-	schedule_delayed_work(&cinergyt2->rc_query_work, HZ/2);
-#endif
+	cinergyt2_resume_rc(cinergyt2);
+
 	up(&cinergyt2->sem);
 	return 0;
 }
diff --git a/drivers/media/dvb/dvb-core/dvbdev.c b/drivers/media/dvb/dvb-core/dvbdev.c
index 4b7adca..477b4fa 100644
--- a/drivers/media/dvb/dvb-core/dvbdev.c
+++ b/drivers/media/dvb/dvb-core/dvbdev.c
@@ -235,7 +235,7 @@
 			S_IFCHR | S_IRUSR | S_IWUSR,
 			"dvb/adapter%d/%s%d", adap->num, dnames[type], id);
 
-	class_device_create(dvb_class, MKDEV(DVB_MAJOR, nums2minor(adap->num, type, id)),
+	class_device_create(dvb_class, NULL, MKDEV(DVB_MAJOR, nums2minor(adap->num, type, id)),
 			    NULL, "dvb%d.%s%d", adap->num, dnames[type], id);
 
 	dprintk("DVB: register adapter%d/%s%d @ minor: %i (0x%02x)\n",
diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-remote.c b/drivers/media/dvb/dvb-usb/dvb-usb-remote.c
index fc7800f..e5c6d98 100644
--- a/drivers/media/dvb/dvb-usb/dvb-usb-remote.c
+++ b/drivers/media/dvb/dvb-usb/dvb-usb-remote.c
@@ -39,9 +39,9 @@
 			d->last_event = event;
 		case REMOTE_KEY_REPEAT:
 			deb_rc("key repeated\n");
-			input_event(&d->rc_input_dev, EV_KEY, d->last_event, 1);
-			input_event(&d->rc_input_dev, EV_KEY, d->last_event, 0);
-			input_sync(&d->rc_input_dev);
+			input_event(d->rc_input_dev, EV_KEY, event, 1);
+			input_event(d->rc_input_dev, EV_KEY, d->last_event, 0);
+			input_sync(d->rc_input_dev);
 			break;
 		default:
 			break;
@@ -53,8 +53,8 @@
 			deb_rc("NO KEY PRESSED\n");
 			if (d->last_state != REMOTE_NO_KEY_PRESSED) {
 				deb_rc("releasing event %d\n",d->last_event);
-				input_event(&d->rc_input_dev, EV_KEY, d->last_event, 0);
-				input_sync(&d->rc_input_dev);
+				input_event(d->rc_input_dev, EV_KEY, d->last_event, 0);
+				input_sync(d->rc_input_dev);
 			}
 			d->last_state = REMOTE_NO_KEY_PRESSED;
 			d->last_event = 0;
@@ -63,8 +63,8 @@
 			deb_rc("KEY PRESSED\n");
 			deb_rc("pressing event %d\n",event);
 
-			input_event(&d->rc_input_dev, EV_KEY, event, 1);
-			input_sync(&d->rc_input_dev);
+			input_event(d->rc_input_dev, EV_KEY, event, 1);
+			input_sync(d->rc_input_dev);
 
 			d->last_event = event;
 			d->last_state = REMOTE_KEY_PRESSED;
@@ -73,8 +73,8 @@
 			deb_rc("KEY_REPEAT\n");
 			if (d->last_state != REMOTE_NO_KEY_PRESSED) {
 				deb_rc("repeating event %d\n",d->last_event);
-				input_event(&d->rc_input_dev, EV_KEY, d->last_event, 2);
-				input_sync(&d->rc_input_dev);
+				input_event(d->rc_input_dev, EV_KEY, d->last_event, 2);
+				input_sync(d->rc_input_dev);
 				d->last_state = REMOTE_KEY_REPEAT;
 			}
 		default:
@@ -89,24 +89,30 @@
 int dvb_usb_remote_init(struct dvb_usb_device *d)
 {
 	int i;
+
 	if (d->props.rc_key_map == NULL ||
 		d->props.rc_query == NULL ||
 		dvb_usb_disable_rc_polling)
 		return 0;
 
-	/* Initialise the remote-control structures.*/
-	init_input_dev(&d->rc_input_dev);
+	usb_make_path(d->udev, d->rc_phys, sizeof(d->rc_phys));
+	strlcpy(d->rc_phys, "/ir0", sizeof(d->rc_phys));
 
-	d->rc_input_dev.evbit[0] = BIT(EV_KEY);
-	d->rc_input_dev.keycodesize = sizeof(unsigned char);
-	d->rc_input_dev.keycodemax = KEY_MAX;
-	d->rc_input_dev.name = "IR-receiver inside an USB DVB receiver";
+	d->rc_input_dev = input_allocate_device();
+	if (!d->rc_input_dev)
+		return -ENOMEM;
+
+	d->rc_input_dev->evbit[0] = BIT(EV_KEY);
+	d->rc_input_dev->keycodesize = sizeof(unsigned char);
+	d->rc_input_dev->keycodemax = KEY_MAX;
+	d->rc_input_dev->name = "IR-receiver inside an USB DVB receiver";
+	d->rc_input_dev->phys = d->rc_phys;
 
 	/* set the bits for the keys */
-	deb_rc("key map size: %d\n",d->props.rc_key_map_size);
+	deb_rc("key map size: %d\n", d->props.rc_key_map_size);
 	for (i = 0; i < d->props.rc_key_map_size; i++) {
 		deb_rc("setting bit for event %d item %d\n",d->props.rc_key_map[i].event, i);
-		set_bit(d->props.rc_key_map[i].event, d->rc_input_dev.keybit);
+		set_bit(d->props.rc_key_map[i].event, d->rc_input_dev->keybit);
 	}
 
 	/* Start the remote-control polling. */
@@ -114,14 +120,14 @@
 		d->props.rc_interval = 100; /* default */
 
 	/* setting these two values to non-zero, we have to manage key repeats */
-	d->rc_input_dev.rep[REP_PERIOD] = d->props.rc_interval;
-	d->rc_input_dev.rep[REP_DELAY]  = d->props.rc_interval + 150;
+	d->rc_input_dev->rep[REP_PERIOD] = d->props.rc_interval;
+	d->rc_input_dev->rep[REP_DELAY]  = d->props.rc_interval + 150;
 
-	input_register_device(&d->rc_input_dev);
+	input_register_device(d->rc_input_dev);
 
 	INIT_WORK(&d->rc_query_work, dvb_usb_read_remote_control, d);
 
-	info("schedule remote query interval to %d msecs.",d->props.rc_interval);
+	info("schedule remote query interval to %d msecs.", d->props.rc_interval);
 	schedule_delayed_work(&d->rc_query_work,msecs_to_jiffies(d->props.rc_interval));
 
 	d->state |= DVB_USB_STATE_REMOTE;
@@ -134,7 +140,7 @@
 	if (d->state & DVB_USB_STATE_REMOTE) {
 		cancel_delayed_work(&d->rc_query_work);
 		flush_scheduled_work();
-		input_unregister_device(&d->rc_input_dev);
+		input_unregister_device(d->rc_input_dev);
 	}
 	d->state &= ~DVB_USB_STATE_REMOTE;
 	return 0;
diff --git a/drivers/media/dvb/dvb-usb/dvb-usb.h b/drivers/media/dvb/dvb-usb/dvb-usb.h
index 0e4f103..b4a1a98 100644
--- a/drivers/media/dvb/dvb-usb/dvb-usb.h
+++ b/drivers/media/dvb/dvb-usb/dvb-usb.h
@@ -300,7 +300,8 @@
 	int (*fe_init)  (struct dvb_frontend *);
 
 	/* remote control */
-	struct input_dev rc_input_dev;
+	struct input_dev *rc_input_dev;
+	char rc_phys[64];
 	struct work_struct rc_query_work;
 	u32 last_event;
 	int last_state;
diff --git a/drivers/media/dvb/ttpci/av7110_ir.c b/drivers/media/dvb/ttpci/av7110_ir.c
index 357a372..f5e59fc 100644
--- a/drivers/media/dvb/ttpci/av7110_ir.c
+++ b/drivers/media/dvb/ttpci/av7110_ir.c
@@ -15,7 +15,7 @@
 
 static int av_cnt;
 static struct av7110 *av_list[4];
-static struct input_dev input_dev;
+static struct input_dev *input_dev;
 
 static u16 key_map [256] = {
 	KEY_0, KEY_1, KEY_2, KEY_3, KEY_4, KEY_5, KEY_6, KEY_7,
@@ -43,10 +43,10 @@
 
 static void av7110_emit_keyup(unsigned long data)
 {
-	if (!data || !test_bit(data, input_dev.key))
+	if (!data || !test_bit(data, input_dev->key))
 		return;
 
-	input_event(&input_dev, EV_KEY, data, !!0);
+	input_event(input_dev, EV_KEY, data, !!0);
 }
 
 
@@ -112,13 +112,13 @@
 	if (timer_pending(&keyup_timer)) {
 		del_timer(&keyup_timer);
 		if (keyup_timer.data != keycode || new_toggle != old_toggle) {
-			input_event(&input_dev, EV_KEY, keyup_timer.data, !!0);
-			input_event(&input_dev, EV_KEY, keycode, !0);
+			input_event(input_dev, EV_KEY, keyup_timer.data, !!0);
+			input_event(input_dev, EV_KEY, keycode, !0);
 		} else
-			input_event(&input_dev, EV_KEY, keycode, 2);
+			input_event(input_dev, EV_KEY, keycode, 2);
 
 	} else
-		input_event(&input_dev, EV_KEY, keycode, !0);
+		input_event(input_dev, EV_KEY, keycode, !0);
 
 	keyup_timer.expires = jiffies + UP_TIMEOUT;
 	keyup_timer.data = keycode;
@@ -132,13 +132,13 @@
 {
 	int i;
 
-	memset(input_dev.keybit, 0, sizeof(input_dev.keybit));
+	memset(input_dev->keybit, 0, sizeof(input_dev->keybit));
 
-	for (i = 0; i < sizeof(key_map) / sizeof(key_map[0]); i++) {
+	for (i = 0; i < ARRAY_SIZE(key_map); i++) {
 		if (key_map[i] > KEY_MAX)
 			key_map[i] = 0;
 		else if (key_map[i] > KEY_RESERVED)
-			set_bit(key_map[i], input_dev.keybit);
+			set_bit(key_map[i], input_dev->keybit);
 	}
 }
 
@@ -216,12 +216,17 @@
 		init_timer(&keyup_timer);
 		keyup_timer.data = 0;
 
-		input_dev.name = "DVB on-card IR receiver";
-		set_bit(EV_KEY, input_dev.evbit);
-		set_bit(EV_REP, input_dev.evbit);
+		input_dev = input_allocate_device();
+		if (!input_dev)
+			return -ENOMEM;
+
+		input_dev->name = "DVB on-card IR receiver";
+
+		set_bit(EV_KEY, input_dev->evbit);
+		set_bit(EV_REP, input_dev->evbit);
 		input_register_keys();
-		input_register_device(&input_dev);
-		input_dev.timer.function = input_repeat_key;
+		input_register_device(input_dev);
+		input_dev->timer.function = input_repeat_key;
 
 		e = create_proc_entry("av7110_ir", S_IFREG | S_IRUGO | S_IWUSR, NULL);
 		if (e) {
@@ -256,7 +261,7 @@
 	if (av_cnt == 1) {
 		del_timer_sync(&keyup_timer);
 		remove_proc_entry("av7110_ir", NULL);
-		input_unregister_device(&input_dev);
+		input_unregister_device(input_dev);
 	}
 
 	av_cnt--;
diff --git a/drivers/media/dvb/ttpci/budget-ci.c b/drivers/media/dvb/ttpci/budget-ci.c
index 2980db3..51c30ba 100644
--- a/drivers/media/dvb/ttpci/budget-ci.c
+++ b/drivers/media/dvb/ttpci/budget-ci.c
@@ -64,7 +64,7 @@
 
 struct budget_ci {
 	struct budget budget;
-	struct input_dev input_dev;
+	struct input_dev *input_dev;
 	struct tasklet_struct msp430_irq_tasklet;
 	struct tasklet_struct ciintf_irq_tasklet;
 	int slot_status;
@@ -145,7 +145,7 @@
 static void msp430_ir_interrupt(unsigned long data)
 {
 	struct budget_ci *budget_ci = (struct budget_ci *) data;
-	struct input_dev *dev = &budget_ci->input_dev;
+	struct input_dev *dev = budget_ci->input_dev;
 	unsigned int code =
 		ttpci_budget_debiread(&budget_ci->budget, DEBINOSWAP, DEBIADDR_IR, 2, 1, 0) >> 8;
 
@@ -181,25 +181,27 @@
 static int msp430_ir_init(struct budget_ci *budget_ci)
 {
 	struct saa7146_dev *saa = budget_ci->budget.dev;
+	struct input_dev *input_dev;
 	int i;
 
-	memset(&budget_ci->input_dev, 0, sizeof(struct input_dev));
+	budget_ci->input_dev = input_dev = input_allocate_device();
+	if (!input_dev)
+		return -ENOMEM;
 
 	sprintf(budget_ci->ir_dev_name, "Budget-CI dvb ir receiver %s", saa->name);
-	budget_ci->input_dev.name = budget_ci->ir_dev_name;
 
-	set_bit(EV_KEY, budget_ci->input_dev.evbit);
+	input_dev->name = budget_ci->ir_dev_name;
 
-	for (i = 0; i < sizeof(key_map) / sizeof(*key_map); i++)
+	set_bit(EV_KEY, input_dev->evbit);
+	for (i = 0; i < ARRAY_SIZE(key_map); i++)
 		if (key_map[i])
-			set_bit(key_map[i], budget_ci->input_dev.keybit);
+			set_bit(key_map[i], input_dev->keybit);
 
-	input_register_device(&budget_ci->input_dev);
+	input_register_device(budget_ci->input_dev);
 
-	budget_ci->input_dev.timer.function = msp430_ir_debounce;
+	input_dev->timer.function = msp430_ir_debounce;
 
 	saa7146_write(saa, IER, saa7146_read(saa, IER) | MASK_06);
-
 	saa7146_setgpio(saa, 3, SAA7146_GPIO_IRQHI);
 
 	return 0;
@@ -208,7 +210,7 @@
 static void msp430_ir_deinit(struct budget_ci *budget_ci)
 {
 	struct saa7146_dev *saa = budget_ci->budget.dev;
-	struct input_dev *dev = &budget_ci->input_dev;
+	struct input_dev *dev = budget_ci->input_dev;
 
 	saa7146_write(saa, IER, saa7146_read(saa, IER) & ~MASK_06);
 	saa7146_setgpio(saa, 3, SAA7146_GPIO_INPUT);
diff --git a/drivers/media/dvb/ttusb-dec/ttusb_dec.c b/drivers/media/dvb/ttusb-dec/ttusb_dec.c
index 3d08fc8..832d179 100644
--- a/drivers/media/dvb/ttusb-dec/ttusb_dec.c
+++ b/drivers/media/dvb/ttusb-dec/ttusb_dec.c
@@ -152,7 +152,8 @@
 	struct list_head	filter_info_list;
 	spinlock_t		filter_info_list_lock;
 
-	struct input_dev	rc_input_dev;
+	struct input_dev	*rc_input_dev;
+	char			rc_phys[64];
 
 	int			active; /* Loaded successfully */
 };
@@ -235,9 +236,9 @@
 		 * this should/could be added later ...
 		 * for now lets report each signal as a key down and up*/
 		dprintk("%s:rc signal:%d\n", __FUNCTION__, buffer[4]);
-		input_report_key(&dec->rc_input_dev,rc_keys[buffer[4]-1],1);
-		input_report_key(&dec->rc_input_dev,rc_keys[buffer[4]-1],0);
-		input_sync(&dec->rc_input_dev);
+		input_report_key(dec->rc_input_dev, rc_keys[buffer[4] - 1], 1);
+		input_report_key(dec->rc_input_dev, rc_keys[buffer[4] - 1], 0);
+		input_sync(dec->rc_input_dev);
 	}
 
 exit:	retval = usb_submit_urb(urb, GFP_ATOMIC);
@@ -1181,29 +1182,38 @@
 		     (unsigned long)dec);
 }
 
-static void ttusb_init_rc( struct ttusb_dec *dec)
+static int ttusb_init_rc(struct ttusb_dec *dec)
 {
+	struct input_dev *input_dev;
 	u8 b[] = { 0x00, 0x01 };
 	int i;
 
-	init_input_dev(&dec->rc_input_dev);
+	usb_make_path(dec->udev, dec->rc_phys, sizeof(dec->rc_phys));
+	strlcpy(dec->rc_phys, "/input0", sizeof(dec->rc_phys));
 
-	dec->rc_input_dev.name = "ttusb_dec remote control";
-	dec->rc_input_dev.evbit[0] = BIT(EV_KEY);
-	dec->rc_input_dev.keycodesize = sizeof(u16);
-	dec->rc_input_dev.keycodemax = 0x1a;
-	dec->rc_input_dev.keycode = rc_keys;
+	dec->rc_input_dev = input_dev = input_allocate_device();
+	if (!input_dev)
+		return -ENOMEM;
 
-	 for (i = 0; i < sizeof(rc_keys)/sizeof(rc_keys[0]); i++)
-                set_bit(rc_keys[i], dec->rc_input_dev.keybit);
+	input_dev->name = "ttusb_dec remote control";
+	input_dev->phys = dec->rc_phys;
+	input_dev->evbit[0] = BIT(EV_KEY);
+	input_dev->keycodesize = sizeof(u16);
+	input_dev->keycodemax = 0x1a;
+	input_dev->keycode = rc_keys;
 
-	input_register_device(&dec->rc_input_dev);
+	for (i = 0; i < ARRAY_SIZE(rc_keys); i++)
+                set_bit(rc_keys[i], input_dev->keybit);
 
-	if(usb_submit_urb(dec->irq_urb,GFP_KERNEL)) {
+	input_register_device(input_dev);
+
+	if (usb_submit_urb(dec->irq_urb, GFP_KERNEL))
 		printk("%s: usb_submit_urb failed\n",__FUNCTION__);
-	}
+
 	/* enable irq pipe */
 	ttusb_dec_send_command(dec,0xb0,sizeof(b),b,NULL,NULL);
+
+	return 0;
 }
 
 static void ttusb_dec_init_v_pes(struct ttusb_dec *dec)
@@ -1513,7 +1523,7 @@
 	  * As the irq is submitted after the interface is changed,
 	  * this is the best method i figured out.
 	  * Any others?*/
-	if(dec->interface == TTUSB_DEC_INTERFACE_IN)
+	if (dec->interface == TTUSB_DEC_INTERFACE_IN)
 		usb_kill_urb(dec->irq_urb);
 
 	usb_free_urb(dec->irq_urb);
@@ -1521,7 +1531,10 @@
 	usb_buffer_free(dec->udev,IRQ_PACKET_SIZE,
 		           dec->irq_buffer, dec->irq_dma_handle);
 
-	input_unregister_device(&dec->rc_input_dev);
+	if (dec->rc_input_dev) {
+		input_unregister_device(dec->rc_input_dev);
+		dec->rc_input_dev = NULL;
+	}
 }
 
 
@@ -1659,7 +1672,7 @@
 
 	ttusb_dec_set_interface(dec, TTUSB_DEC_INTERFACE_IN);
 
-	if(enable_rc)
+	if (enable_rc)
 		ttusb_init_rc(dec);
 
 	return 0;
diff --git a/drivers/media/video/bttvp.h b/drivers/media/video/bttvp.h
index 7a312f7..e0e7c7a 100644
--- a/drivers/media/video/bttvp.h
+++ b/drivers/media/video/bttvp.h
@@ -240,7 +240,7 @@
 
 /* for gpio-connected remote control */
 struct bttv_input {
-	struct input_dev      dev;
+	struct input_dev      *dev;
 	struct ir_input_state ir;
 	char                  name[32];
 	char                  phys[32];
diff --git a/drivers/media/video/cx88/cx88-input.c b/drivers/media/video/cx88/cx88-input.c
index d81b21d..c27fe4c3 100644
--- a/drivers/media/video/cx88/cx88-input.c
+++ b/drivers/media/video/cx88/cx88-input.c
@@ -260,7 +260,7 @@
 
 struct cx88_IR {
 	struct cx88_core *core;
-	struct input_dev input;
+	struct input_dev *input;
 	struct ir_input_state ir;
 	char name[32];
 	char phys[32];
@@ -315,23 +315,23 @@
 	if (ir->mask_keydown) {
 		/* bit set on keydown */
 		if (gpio & ir->mask_keydown) {
-			ir_input_keydown(&ir->input, &ir->ir, data, data);
+			ir_input_keydown(ir->input, &ir->ir, data, data);
 		} else {
-			ir_input_nokey(&ir->input, &ir->ir);
+			ir_input_nokey(ir->input, &ir->ir);
 		}
 
 	} else if (ir->mask_keyup) {
 		/* bit cleared on keydown */
 		if (0 == (gpio & ir->mask_keyup)) {
-			ir_input_keydown(&ir->input, &ir->ir, data, data);
+			ir_input_keydown(ir->input, &ir->ir, data, data);
 		} else {
-			ir_input_nokey(&ir->input, &ir->ir);
+			ir_input_nokey(ir->input, &ir->ir);
 		}
 
 	} else {
 		/* can't distinguish keydown/up :-/ */
-		ir_input_keydown(&ir->input, &ir->ir, data, data);
-		ir_input_nokey(&ir->input, &ir->ir);
+		ir_input_keydown(ir->input, &ir->ir, data, data);
+		ir_input_nokey(ir->input, &ir->ir);
 	}
 }
 
@@ -357,13 +357,19 @@
 int cx88_ir_init(struct cx88_core *core, struct pci_dev *pci)
 {
 	struct cx88_IR *ir;
+	struct input_dev *input_dev;
 	IR_KEYTAB_TYPE *ir_codes = NULL;
 	int ir_type = IR_TYPE_OTHER;
 
-	ir = kmalloc(sizeof(*ir), GFP_KERNEL);
-	if (NULL == ir)
+	ir = kzalloc(sizeof(*ir), GFP_KERNEL);
+	input_dev = input_allocate_device();
+	if (!ir || !input_dev) {
+		kfree(ir);
+		input_free_device(input_dev);
 		return -ENOMEM;
-	memset(ir, 0, sizeof(*ir));
+	}
+
+	ir->input = input_dev;
 
 	/* detect & configure */
 	switch (core->board) {
@@ -425,6 +431,7 @@
 
 	if (NULL == ir_codes) {
 		kfree(ir);
+		input_free_device(input_dev);
 		return -ENODEV;
 	}
 
@@ -433,19 +440,19 @@
 		 cx88_boards[core->board].name);
 	snprintf(ir->phys, sizeof(ir->phys), "pci-%s/ir0", pci_name(pci));
 
-	ir_input_init(&ir->input, &ir->ir, ir_type, ir_codes);
-	ir->input.name = ir->name;
-	ir->input.phys = ir->phys;
-	ir->input.id.bustype = BUS_PCI;
-	ir->input.id.version = 1;
+	ir_input_init(input_dev, &ir->ir, ir_type, ir_codes);
+	input_dev->name = ir->name;
+	input_dev->phys = ir->phys;
+	input_dev->id.bustype = BUS_PCI;
+	input_dev->id.version = 1;
 	if (pci->subsystem_vendor) {
-		ir->input.id.vendor = pci->subsystem_vendor;
-		ir->input.id.product = pci->subsystem_device;
+		input_dev->id.vendor = pci->subsystem_vendor;
+		input_dev->id.product = pci->subsystem_device;
 	} else {
-		ir->input.id.vendor = pci->vendor;
-		ir->input.id.product = pci->device;
+		input_dev->id.vendor = pci->vendor;
+		input_dev->id.product = pci->device;
 	}
-	ir->input.dev = &pci->dev;
+	input_dev->cdev.dev = &pci->dev;
 
 	/* record handles to ourself */
 	ir->core = core;
@@ -465,8 +472,7 @@
 	}
 
 	/* all done */
-	input_register_device(&ir->input);
-	printk("%s: registered IR remote control\n", core->name);
+	input_register_device(ir->input);
 
 	return 0;
 }
@@ -484,7 +490,7 @@
 		flush_scheduled_work();
 	}
 
-	input_unregister_device(&ir->input);
+	input_unregister_device(ir->input);
 	kfree(ir);
 
 	/* done */
@@ -515,7 +521,7 @@
 	if (!ir->scount) {
 		/* nothing to sample */
 		if (ir->ir.keypressed && time_after(jiffies, ir->release))
-			ir_input_nokey(&ir->input, &ir->ir);
+			ir_input_nokey(ir->input, &ir->ir);
 		return;
 	}
 
@@ -557,7 +563,7 @@
 
 		ir_dprintk("Key Code: %x\n", (ircode >> 16) & 0x7f);
 
-		ir_input_keydown(&ir->input, &ir->ir, (ircode >> 16) & 0x7f, (ircode >> 16) & 0xff);
+		ir_input_keydown(ir->input, &ir->ir, (ircode >> 16) & 0x7f, (ircode >> 16) & 0xff);
 		ir->release = jiffies + msecs_to_jiffies(120);
 		break;
 	case CX88_BOARD_HAUPPAUGE:
@@ -566,7 +572,7 @@
 		ir_dprintk("biphase decoded: %x\n", ircode);
 		if ((ircode & 0xfffff000) != 0x3000)
 			break;
-		ir_input_keydown(&ir->input, &ir->ir, ircode & 0x3f, ircode);
+		ir_input_keydown(ir->input, &ir->ir, ircode & 0x3f, ircode);
 		ir->release = jiffies + msecs_to_jiffies(120);
 		break;
 	}
diff --git a/drivers/media/video/ir-kbd-gpio.c b/drivers/media/video/ir-kbd-gpio.c
index cf292da..234151e 100644
--- a/drivers/media/video/ir-kbd-gpio.c
+++ b/drivers/media/video/ir-kbd-gpio.c
@@ -158,7 +158,7 @@
 
 struct IR {
 	struct bttv_sub_device  *sub;
-	struct input_dev        input;
+	struct input_dev        *input;
 	struct ir_input_state   ir;
 	char                    name[32];
 	char                    phys[32];
@@ -217,23 +217,23 @@
 	if (ir->mask_keydown) {
 		/* bit set on keydown */
 		if (gpio & ir->mask_keydown) {
-			ir_input_keydown(&ir->input,&ir->ir,data,data);
+			ir_input_keydown(ir->input, &ir->ir, data, data);
 		} else {
-			ir_input_nokey(&ir->input,&ir->ir);
+			ir_input_nokey(ir->input, &ir->ir);
 		}
 
 	} else if (ir->mask_keyup) {
 		/* bit cleared on keydown */
 		if (0 == (gpio & ir->mask_keyup)) {
-			ir_input_keydown(&ir->input,&ir->ir,data,data);
+			ir_input_keydown(ir->input, &ir->ir, data, data);
 		} else {
-			ir_input_nokey(&ir->input,&ir->ir);
+			ir_input_nokey(ir->input, &ir->ir);
 		}
 
 	} else {
 		/* can't disturgissh keydown/up :-/ */
-		ir_input_keydown(&ir->input,&ir->ir,data,data);
-		ir_input_nokey(&ir->input,&ir->ir);
+		ir_input_keydown(ir->input, &ir->ir, data, data);
+		ir_input_nokey(ir->input, &ir->ir);
 	}
 }
 
@@ -268,13 +268,17 @@
 {
 	struct bttv_sub_device *sub = to_bttv_sub_dev(dev);
 	struct IR *ir;
+	struct input_dev *input_dev;
 	IR_KEYTAB_TYPE *ir_codes = NULL;
 	int ir_type = IR_TYPE_OTHER;
 
-	ir = kmalloc(sizeof(*ir),GFP_KERNEL);
-	if (NULL == ir)
+	ir = kzalloc(sizeof(*ir), GFP_KERNEL);
+	input_dev = input_allocate_device();
+	if (!ir || !input_dev) {
+		kfree(ir);
+		input_free_device(input_dev);
 		return -ENOMEM;
-	memset(ir,0,sizeof(*ir));
+	}
 
 	/* detect & configure */
 	switch (sub->core->type) {
@@ -328,6 +332,7 @@
 	}
 	if (NULL == ir_codes) {
 		kfree(ir);
+		input_free_device(input_dev);
 		return -ENODEV;
 	}
 
@@ -341,19 +346,19 @@
 	snprintf(ir->phys, sizeof(ir->phys), "pci-%s/ir0",
 		 pci_name(sub->core->pci));
 
-	ir_input_init(&ir->input, &ir->ir, ir_type, ir_codes);
-	ir->input.name = ir->name;
-	ir->input.phys = ir->phys;
-	ir->input.id.bustype = BUS_PCI;
-	ir->input.id.version = 1;
+	ir_input_init(input_dev, &ir->ir, ir_type, ir_codes);
+	input_dev->name = ir->name;
+	input_dev->phys = ir->phys;
+	input_dev->id.bustype = BUS_PCI;
+	input_dev->id.version = 1;
 	if (sub->core->pci->subsystem_vendor) {
-		ir->input.id.vendor  = sub->core->pci->subsystem_vendor;
-		ir->input.id.product = sub->core->pci->subsystem_device;
+		input_dev->id.vendor  = sub->core->pci->subsystem_vendor;
+		input_dev->id.product = sub->core->pci->subsystem_device;
 	} else {
-		ir->input.id.vendor  = sub->core->pci->vendor;
-		ir->input.id.product = sub->core->pci->device;
+		input_dev->id.vendor  = sub->core->pci->vendor;
+		input_dev->id.product = sub->core->pci->device;
 	}
-	ir->input.dev = &sub->core->pci->dev;
+	input_dev->cdev.dev = &sub->core->pci->dev;
 
 	if (ir->polling) {
 		INIT_WORK(&ir->work, ir_work, ir);
@@ -364,9 +369,8 @@
 	}
 
 	/* all done */
-	dev_set_drvdata(dev,ir);
-	input_register_device(&ir->input);
-	printk(DEVNAME ": %s detected at %s\n",ir->input.name,ir->input.phys);
+	dev_set_drvdata(dev, ir);
+	input_register_device(ir->input);
 
 	return 0;
 }
@@ -380,7 +384,7 @@
 		flush_scheduled_work();
 	}
 
-	input_unregister_device(&ir->input);
+	input_unregister_device(ir->input);
 	kfree(ir);
 	return 0;
 }
diff --git a/drivers/media/video/ir-kbd-i2c.c b/drivers/media/video/ir-kbd-i2c.c
index 67105b9..9703d3d 100644
--- a/drivers/media/video/ir-kbd-i2c.c
+++ b/drivers/media/video/ir-kbd-i2c.c
@@ -121,10 +121,9 @@
 
 };
 
-struct IR;
 struct IR {
 	struct i2c_client      c;
-	struct input_dev       input;
+	struct input_dev       *input;
 	struct ir_input_state  ir;
 
 	struct work_struct     work;
@@ -271,9 +270,9 @@
 	}
 
 	if (0 == rc) {
-		ir_input_nokey(&ir->input,&ir->ir);
+		ir_input_nokey(ir->input, &ir->ir);
 	} else {
-		ir_input_keydown(&ir->input,&ir->ir, ir_key, ir_raw);
+		ir_input_keydown(ir->input, &ir->ir, ir_key, ir_raw);
 	}
 }
 
@@ -318,11 +317,18 @@
 	char *name;
 	int ir_type;
         struct IR *ir;
+	struct input_dev *input_dev;
 
-        if (NULL == (ir = kmalloc(sizeof(struct IR),GFP_KERNEL)))
+	ir = kzalloc(sizeof(struct IR), GFP_KERNEL);
+	input_dev = input_allocate_device();
+	if (!ir || !input_dev) {
+		kfree(ir);
+		input_free_device(input_dev);
                 return -ENOMEM;
-	memset(ir,0,sizeof(*ir));
+	}
+
 	ir->c = client_template;
+	ir->input = input_dev;
 
 	i2c_set_clientdata(&ir->c, ir);
 	ir->c.adapter = adap;
@@ -375,13 +381,12 @@
 		 ir->c.dev.bus_id);
 
 	/* init + register input device */
-	ir_input_init(&ir->input,&ir->ir,ir_type,ir_codes);
-	ir->input.id.bustype = BUS_I2C;
-	ir->input.name       = ir->c.name;
-	ir->input.phys       = ir->phys;
-	input_register_device(&ir->input);
-	printk(DEVNAME ": %s detected at %s [%s]\n",
-	       ir->input.name,ir->input.phys,adap->name);
+	ir_input_init(input_dev, &ir->ir, ir_type, ir_codes);
+	input_dev->id.bustype	= BUS_I2C;
+	input_dev->name		= ir->c.name;
+	input_dev->phys		= ir->phys;
+
+	input_register_device(ir->input);
 
 	/* start polling via eventd */
 	INIT_WORK(&ir->work, ir_work, ir);
@@ -402,7 +407,7 @@
 	flush_scheduled_work();
 
 	/* unregister devices */
-	input_unregister_device(&ir->input);
+	input_unregister_device(ir->input);
 	i2c_detach_client(&ir->c);
 
 	/* free memory */
diff --git a/drivers/media/video/msp3400.c b/drivers/media/video/msp3400.c
index f0d43fc..262890c 100644
--- a/drivers/media/video/msp3400.c
+++ b/drivers/media/video/msp3400.c
@@ -1420,8 +1420,8 @@
 static int msp_probe(struct i2c_adapter *adap);
 static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg);
 
-static int msp_suspend(struct device * dev, pm_message_t state, u32 level);
-static int msp_resume(struct device * dev, u32 level);
+static int msp_suspend(struct device * dev, pm_message_t state);
+static int msp_resume(struct device * dev);
 
 static void msp_wake_thread(struct i2c_client *client);
 
@@ -1821,7 +1821,7 @@
 	return 0;
 }
 
-static int msp_suspend(struct device * dev, pm_message_t state, u32 level)
+static int msp_suspend(struct device * dev, pm_message_t state)
 {
 	struct i2c_client *c = container_of(dev, struct i2c_client, dev);
 
@@ -1830,7 +1830,7 @@
 	return 0;
 }
 
-static int msp_resume(struct device * dev, u32 level)
+static int msp_resume(struct device * dev)
 {
 	struct i2c_client *c = container_of(dev, struct i2c_client, dev);
 
diff --git a/drivers/media/video/saa7134/saa7134-input.c b/drivers/media/video/saa7134/saa7134-input.c
index 1f456c4..242cb23 100644
--- a/drivers/media/video/saa7134/saa7134-input.c
+++ b/drivers/media/video/saa7134/saa7134-input.c
@@ -425,9 +425,9 @@
 
 	if ((ir->mask_keydown  &&  (0 != (gpio & ir->mask_keydown))) ||
 	    (ir->mask_keyup    &&  (0 == (gpio & ir->mask_keyup)))) {
-		ir_input_keydown(&ir->dev,&ir->ir,data,data);
+		ir_input_keydown(ir->dev, &ir->ir, data, data);
 	} else {
-		ir_input_nokey(&ir->dev,&ir->ir);
+		ir_input_nokey(ir->dev, &ir->ir);
 	}
 	return 0;
 }
@@ -456,6 +456,7 @@
 int saa7134_input_init1(struct saa7134_dev *dev)
 {
 	struct saa7134_ir *ir;
+	struct input_dev *input_dev;
 	IR_KEYTAB_TYPE *ir_codes = NULL;
 	u32 mask_keycode = 0;
 	u32 mask_keydown = 0;
@@ -535,10 +536,13 @@
 		return -ENODEV;
 	}
 
-	ir = kmalloc(sizeof(*ir),GFP_KERNEL);
-	if (NULL == ir)
+	ir = kzalloc(sizeof(*ir), GFP_KERNEL);
+	input_dev = input_allocate_device();
+	if (!ir || !input_dev) {
+		kfree(ir);
+		input_free_device(input_dev);
 		return -ENOMEM;
-	memset(ir,0,sizeof(*ir));
+	}
 
 	/* init hardware-specific stuff */
 	ir->mask_keycode = mask_keycode;
@@ -552,19 +556,19 @@
 	snprintf(ir->phys, sizeof(ir->phys), "pci-%s/ir0",
 		 pci_name(dev->pci));
 
-	ir_input_init(&ir->dev, &ir->ir, ir_type, ir_codes);
-	ir->dev.name = ir->name;
-	ir->dev.phys = ir->phys;
-	ir->dev.id.bustype = BUS_PCI;
-	ir->dev.id.version = 1;
+	ir_input_init(input_dev, &ir->ir, ir_type, ir_codes);
+	input_dev->name = ir->name;
+	input_dev->phys = ir->phys;
+	input_dev->id.bustype = BUS_PCI;
+	input_dev->id.version = 1;
 	if (dev->pci->subsystem_vendor) {
-		ir->dev.id.vendor  = dev->pci->subsystem_vendor;
-		ir->dev.id.product = dev->pci->subsystem_device;
+		input_dev->id.vendor  = dev->pci->subsystem_vendor;
+		input_dev->id.product = dev->pci->subsystem_device;
 	} else {
-		ir->dev.id.vendor  = dev->pci->vendor;
-		ir->dev.id.product = dev->pci->device;
+		input_dev->id.vendor  = dev->pci->vendor;
+		input_dev->id.product = dev->pci->device;
 	}
-	ir->dev.dev = &dev->pci->dev;
+	input_dev->cdev.dev = &dev->pci->dev;
 
 	/* all done */
 	dev->remote = ir;
@@ -576,8 +580,7 @@
 		add_timer(&ir->timer);
 	}
 
-	input_register_device(&dev->remote->dev);
-	printk("%s: registered input device for IR\n",dev->name);
+	input_register_device(ir->dev);
 	return 0;
 }
 
@@ -586,9 +589,9 @@
 	if (NULL == dev->remote)
 		return;
 
-	input_unregister_device(&dev->remote->dev);
 	if (dev->remote->polling)
 		del_timer_sync(&dev->remote->timer);
+	input_unregister_device(dev->remote->dev);
 	kfree(dev->remote);
 	dev->remote = NULL;
 }
diff --git a/drivers/media/video/saa7134/saa7134.h b/drivers/media/video/saa7134/saa7134.h
index 3ea0914..860b895 100644
--- a/drivers/media/video/saa7134/saa7134.h
+++ b/drivers/media/video/saa7134/saa7134.h
@@ -351,7 +351,7 @@
 
 /* IR input */
 struct saa7134_ir {
-	struct input_dev           dev;
+	struct input_dev           *dev;
 	struct ir_input_state      ir;
 	char                       name[32];
 	char                       phys[32];
diff --git a/drivers/media/video/tda9887.c b/drivers/media/video/tda9887.c
index 0456dda..94053f1 100644
--- a/drivers/media/video/tda9887.c
+++ b/drivers/media/video/tda9887.c
@@ -784,13 +784,13 @@
 	return 0;
 }
 
-static int tda9887_suspend(struct device * dev, pm_message_t state, u32 level)
+static int tda9887_suspend(struct device * dev, pm_message_t state)
 {
 	dprintk("tda9887: suspend\n");
 	return 0;
 }
 
-static int tda9887_resume(struct device * dev, u32 level)
+static int tda9887_resume(struct device * dev)
 {
 	struct i2c_client *c = container_of(dev, struct i2c_client, dev);
 	struct tda9887 *t = i2c_get_clientdata(c);
diff --git a/drivers/media/video/tuner-core.c b/drivers/media/video/tuner-core.c
index 0557202..ad85bef 100644
--- a/drivers/media/video/tuner-core.c
+++ b/drivers/media/video/tuner-core.c
@@ -697,7 +697,7 @@
 	return 0;
 }
 
-static int tuner_suspend(struct device *dev, pm_message_t state, u32 level)
+static int tuner_suspend(struct device *dev, pm_message_t state)
 {
 	struct i2c_client *c = container_of (dev, struct i2c_client, dev);
 	struct tuner *t = i2c_get_clientdata (c);
@@ -707,7 +707,7 @@
 	return 0;
 }
 
-static int tuner_resume(struct device *dev, u32 level)
+static int tuner_resume(struct device *dev)
 {
 	struct i2c_client *c = container_of (dev, struct i2c_client, dev);
 	struct tuner *t = i2c_get_clientdata (c);
diff --git a/drivers/message/i2o/core.h b/drivers/message/i2o/core.h
index c5bcfd7..9eefedb 100644
--- a/drivers/message/i2o/core.h
+++ b/drivers/message/i2o/core.h
@@ -36,9 +36,6 @@
 extern void i2o_device_remove(struct i2o_device *);
 extern int i2o_device_parse_lct(struct i2o_controller *);
 
-extern int i2o_device_init(void);
-extern void i2o_device_exit(void);
-
 /* IOP */
 extern struct i2o_controller *i2o_iop_alloc(void);
 extern void i2o_iop_free(struct i2o_controller *);
diff --git a/drivers/message/i2o/device.c b/drivers/message/i2o/device.c
index 21f16ba..d987996 100644
--- a/drivers/message/i2o/device.c
+++ b/drivers/message/i2o/device.c
@@ -45,10 +45,10 @@
 	writel(type, &msg->body[0]);
 
 	return i2o_msg_post_wait(dev->iop, m, 60);
-};
+}
 
 /**
- * 	i2o_device_claim - claim a device for use by an OSM
+ *	i2o_device_claim - claim a device for use by an OSM
  *	@dev: I2O device to claim
  *	@drv: I2O driver which wants to claim the device
  *
@@ -73,7 +73,7 @@
 	up(&dev->lock);
 
 	return rc;
-};
+}
 
 /**
  *	i2o_device_claim_release - release a device that the OSM is using
@@ -119,7 +119,8 @@
 	up(&dev->lock);
 
 	return rc;
-};
+}
+
 
 /**
  *	i2o_device_release - release the memory for a I2O device
@@ -135,39 +136,47 @@
 	pr_debug("i2o: device %s released\n", dev->bus_id);
 
 	kfree(i2o_dev);
-};
+}
+
 
 /**
- *	i2o_device_class_release - Remove I2O device attributes
- *	@cd: I2O class device which is added to the I2O device class
+ *	i2o_device_class_show_class_id - Displays class id of I2O device
+ *	@cd: class device of which the class id should be displayed
+ *	@buf: buffer into which the class id should be printed
  *
- *	Removes attributes from the I2O device again. Also search each device
- *	on the controller for I2O devices which refert to this device as parent
- *	or user and remove this links also.
+ *	Returns the number of bytes which are printed into the buffer.
  */
-static void i2o_device_class_release(struct class_device *cd)
+static ssize_t i2o_device_show_class_id(struct device *dev,
+					struct device_attribute *attr,
+					char *buf)
 {
-	struct i2o_device *i2o_dev, *tmp;
-	struct i2o_controller *c;
+	struct i2o_device *i2o_dev = to_i2o_device(dev);
 
-	i2o_dev = to_i2o_device(cd->dev);
-	c = i2o_dev->iop;
+	sprintf(buf, "0x%03x\n", i2o_dev->lct_data.class_id);
+	return strlen(buf) + 1;
+}
 
-	sysfs_remove_link(&i2o_dev->device.kobj, "parent");
-	sysfs_remove_link(&i2o_dev->device.kobj, "user");
+/**
+ *	i2o_device_class_show_tid - Displays TID of I2O device
+ *	@cd: class device of which the TID should be displayed
+ *	@buf: buffer into which the class id should be printed
+ *
+ *	Returns the number of bytes which are printed into the buffer.
+ */
+static ssize_t i2o_device_show_tid(struct device *dev,
+				   struct device_attribute *attr,
+				   char *buf)
+{
+	struct i2o_device *i2o_dev = to_i2o_device(dev);
 
-	list_for_each_entry(tmp, &c->devices, list) {
-		if (tmp->lct_data.parent_tid == i2o_dev->lct_data.tid)
-			sysfs_remove_link(&tmp->device.kobj, "parent");
-		if (tmp->lct_data.user_tid == i2o_dev->lct_data.tid)
-			sysfs_remove_link(&tmp->device.kobj, "user");
-	}
-};
+	sprintf(buf, "0x%03x\n", i2o_dev->lct_data.tid);
+	return strlen(buf) + 1;
+}
 
-/* I2O device class */
-static struct class i2o_device_class = {
-	.name = "i2o_device",
-	.release = i2o_device_class_release
+struct device_attribute i2o_device_attrs[] = {
+	__ATTR(class_id, S_IRUGO, i2o_device_show_class_id, NULL),
+	__ATTR(tid, S_IRUGO, i2o_device_show_tid, NULL),
+	__ATTR_NULL
 };
 
 /**
@@ -193,11 +202,69 @@
 
 	dev->device.bus = &i2o_bus_type;
 	dev->device.release = &i2o_device_release;
-	dev->classdev.class = &i2o_device_class;
-	dev->classdev.dev = &dev->device;
 
 	return dev;
-};
+}
+
+/**
+ *	i2o_setup_sysfs_links - Adds attributes to the I2O device
+ *	@cd: I2O class device which is added to the I2O device class
+ *
+ *	This function get called when a I2O device is added to the class. It
+ *	creates the attributes for each device and creates user/parent symlink
+ *	if necessary.
+ *
+ *	Returns 0 on success or negative error code on failure.
+ */
+static void i2o_setup_sysfs_links(struct i2o_device *i2o_dev)
+{
+	struct i2o_controller *c = i2o_dev->iop;
+	struct i2o_device *tmp;
+
+	/* create user entries for this device */
+	tmp = i2o_iop_find_device(i2o_dev->iop, i2o_dev->lct_data.user_tid);
+	if (tmp && tmp != i2o_dev)
+		sysfs_create_link(&i2o_dev->device.kobj,
+				  &tmp->device.kobj, "user");
+
+	/* create user entries refering to this device */
+	list_for_each_entry(tmp, &c->devices, list)
+		if (tmp->lct_data.user_tid == i2o_dev->lct_data.tid &&
+		    tmp != i2o_dev)
+			sysfs_create_link(&tmp->device.kobj,
+					  &i2o_dev->device.kobj, "user");
+
+	/* create parent entries for this device */
+	tmp = i2o_iop_find_device(i2o_dev->iop, i2o_dev->lct_data.parent_tid);
+	if (tmp && tmp != i2o_dev)
+		sysfs_create_link(&i2o_dev->device.kobj,
+				  &tmp->device.kobj, "parent");
+
+	/* create parent entries refering to this device */
+	list_for_each_entry(tmp, &c->devices, list)
+		if (tmp->lct_data.parent_tid == i2o_dev->lct_data.tid &&
+		    tmp != i2o_dev)
+		sysfs_create_link(&tmp->device.kobj,
+				  &i2o_dev->device.kobj, "parent");
+}
+
+static void i2o_remove_sysfs_links(struct i2o_device *i2o_dev)
+{
+	struct i2o_controller *c = i2o_dev->iop;
+	struct i2o_device *tmp;
+
+	sysfs_remove_link(&i2o_dev->device.kobj, "parent");
+	sysfs_remove_link(&i2o_dev->device.kobj, "user");
+
+	list_for_each_entry(tmp, &c->devices, list) {
+		if (tmp->lct_data.parent_tid == i2o_dev->lct_data.tid)
+			sysfs_remove_link(&tmp->device.kobj, "parent");
+		if (tmp->lct_data.user_tid == i2o_dev->lct_data.tid)
+			sysfs_remove_link(&tmp->device.kobj, "user");
+	}
+}
+
+
 
 /**
  *	i2o_device_add - allocate a new I2O device and add it to the IOP
@@ -222,28 +289,25 @@
 	}
 
 	dev->lct_data = *entry;
+	dev->iop = c;
 
 	snprintf(dev->device.bus_id, BUS_ID_SIZE, "%d:%03x", c->unit,
 		 dev->lct_data.tid);
 
-	snprintf(dev->classdev.class_id, BUS_ID_SIZE, "%d:%03x", c->unit,
-		 dev->lct_data.tid);
-
-	dev->iop = c;
 	dev->device.parent = &c->device;
 
 	device_register(&dev->device);
 
 	list_add_tail(&dev->list, &c->devices);
 
-	class_device_register(&dev->classdev);
+	i2o_setup_sysfs_links(dev);
 
 	i2o_driver_notify_device_add_all(dev);
 
 	pr_debug("i2o: device %s added\n", dev->device.bus_id);
 
 	return dev;
-};
+}
 
 /**
  *	i2o_device_remove - remove an I2O device from the I2O core
@@ -256,10 +320,10 @@
 void i2o_device_remove(struct i2o_device *i2o_dev)
 {
 	i2o_driver_notify_device_remove_all(i2o_dev);
-	class_device_unregister(&i2o_dev->classdev);
+	i2o_remove_sysfs_links(i2o_dev);
 	list_del(&i2o_dev->list);
 	device_unregister(&i2o_dev->device);
-};
+}
 
 /**
  *	i2o_device_parse_lct - Parse a previously fetched LCT and create devices
@@ -337,99 +401,8 @@
 	up(&c->lct_lock);
 
 	return 0;
-};
+}
 
-/**
- *	i2o_device_class_show_class_id - Displays class id of I2O device
- *	@cd: class device of which the class id should be displayed
- *	@buf: buffer into which the class id should be printed
- *
- *	Returns the number of bytes which are printed into the buffer.
- */
-static ssize_t i2o_device_class_show_class_id(struct class_device *cd,
-					      char *buf)
-{
-	struct i2o_device *dev = to_i2o_device(cd->dev);
-
-	sprintf(buf, "0x%03x\n", dev->lct_data.class_id);
-	return strlen(buf) + 1;
-};
-
-/**
- *	i2o_device_class_show_tid - Displays TID of I2O device
- *	@cd: class device of which the TID should be displayed
- *	@buf: buffer into which the class id should be printed
- *
- *	Returns the number of bytes which are printed into the buffer.
- */
-static ssize_t i2o_device_class_show_tid(struct class_device *cd, char *buf)
-{
-	struct i2o_device *dev = to_i2o_device(cd->dev);
-
-	sprintf(buf, "0x%03x\n", dev->lct_data.tid);
-	return strlen(buf) + 1;
-};
-
-/* I2O device class attributes */
-static CLASS_DEVICE_ATTR(class_id, S_IRUGO, i2o_device_class_show_class_id,
-			 NULL);
-static CLASS_DEVICE_ATTR(tid, S_IRUGO, i2o_device_class_show_tid, NULL);
-
-/**
- *	i2o_device_class_add - Adds attributes to the I2O device
- *	@cd: I2O class device which is added to the I2O device class
- *
- *	This function get called when a I2O device is added to the class. It
- *	creates the attributes for each device and creates user/parent symlink
- *	if necessary.
- *
- *	Returns 0 on success or negative error code on failure.
- */
-static int i2o_device_class_add(struct class_device *cd)
-{
-	struct i2o_device *i2o_dev, *tmp;
-	struct i2o_controller *c;
-
-	i2o_dev = to_i2o_device(cd->dev);
-	c = i2o_dev->iop;
-
-	class_device_create_file(cd, &class_device_attr_class_id);
-	class_device_create_file(cd, &class_device_attr_tid);
-
-	/* create user entries for this device */
-	tmp = i2o_iop_find_device(i2o_dev->iop, i2o_dev->lct_data.user_tid);
-	if (tmp && (tmp != i2o_dev))
-		sysfs_create_link(&i2o_dev->device.kobj, &tmp->device.kobj,
-				  "user");
-
-	/* create user entries refering to this device */
-	list_for_each_entry(tmp, &c->devices, list)
-	    if ((tmp->lct_data.user_tid == i2o_dev->lct_data.tid)
-		&& (tmp != i2o_dev))
-		sysfs_create_link(&tmp->device.kobj,
-				  &i2o_dev->device.kobj, "user");
-
-	/* create parent entries for this device */
-	tmp = i2o_iop_find_device(i2o_dev->iop, i2o_dev->lct_data.parent_tid);
-	if (tmp && (tmp != i2o_dev))
-		sysfs_create_link(&i2o_dev->device.kobj, &tmp->device.kobj,
-				  "parent");
-
-	/* create parent entries refering to this device */
-	list_for_each_entry(tmp, &c->devices, list)
-	    if ((tmp->lct_data.parent_tid == i2o_dev->lct_data.tid)
-		&& (tmp != i2o_dev))
-		sysfs_create_link(&tmp->device.kobj,
-				  &i2o_dev->device.kobj, "parent");
-
-	return 0;
-};
-
-/* I2O device class interface */
-static struct class_interface i2o_device_class_interface = {
-	.class = &i2o_device_class,
-	.add = i2o_device_class_add
-};
 
 /*
  *	Run time support routines
@@ -553,11 +526,11 @@
 }
 
 /*
- * 	if oper == I2O_PARAMS_TABLE_GET, get from all rows
- * 		if fieldcount == -1 return all fields
+ *	if oper == I2O_PARAMS_TABLE_GET, get from all rows
+ *		if fieldcount == -1 return all fields
  *			ibuf and ibuflen are unused (use NULL, 0)
- * 		else return specific fields
- *  			ibuf contains fieldindexes
+ *		else return specific fields
+ *			ibuf contains fieldindexes
  *
  * 	if oper == I2O_PARAMS_LIST_GET, get from specific rows
  * 		if fieldcount == -1 return all fields
@@ -602,35 +575,6 @@
 	return size;
 }
 
-/**
- *	i2o_device_init - Initialize I2O devices
- *
- *	Registers the I2O device class.
- *
- *	Returns 0 on success or negative error code on failure.
- */
-int i2o_device_init(void)
-{
-	int rc;
-
-	rc = class_register(&i2o_device_class);
-	if (rc)
-		return rc;
-
-	return class_interface_register(&i2o_device_class_interface);
-};
-
-/**
- *	i2o_device_exit - I2O devices exit function
- *
- *	Unregisters the I2O device class.
- */
-void i2o_device_exit(void)
-{
-	class_interface_register(&i2o_device_class_interface);
-	class_unregister(&i2o_device_class);
-};
-
 EXPORT_SYMBOL(i2o_device_claim);
 EXPORT_SYMBOL(i2o_device_claim_release);
 EXPORT_SYMBOL(i2o_parm_field_get);
diff --git a/drivers/message/i2o/driver.c b/drivers/message/i2o/driver.c
index 739bfde..0079a4b 100644
--- a/drivers/message/i2o/driver.c
+++ b/drivers/message/i2o/driver.c
@@ -58,9 +58,12 @@
 };
 
 /* I2O bus type */
+extern struct device_attribute i2o_device_attrs[];
+
 struct bus_type i2o_bus_type = {
 	.name = "i2o",
 	.match = i2o_bus_match,
+	.dev_attrs = i2o_device_attrs,
 };
 
 /**
diff --git a/drivers/message/i2o/iop.c b/drivers/message/i2o/iop.c
index 42f8b81..361da8d 100644
--- a/drivers/message/i2o/iop.c
+++ b/drivers/message/i2o/iop.c
@@ -833,6 +833,7 @@
 	list_for_each_entry_safe(dev, tmp, &c->devices, list)
 	    i2o_device_remove(dev);
 
+	class_device_unregister(c->classdev);
 	device_del(&c->device);
 
 	/* Ask the IOP to switch to RESET state */
@@ -1077,9 +1078,7 @@
 };
 
 /* I2O controller class */
-static struct class i2o_controller_class = {
-	.name = "i2o_controller",
-};
+static struct class *i2o_controller_class;
 
 /**
  *	i2o_iop_alloc - Allocate and initialize a i2o_controller struct
@@ -1110,14 +1109,10 @@
 	sprintf(c->name, "iop%d", c->unit);
 
 	device_initialize(&c->device);
-	class_device_initialize(&c->classdev);
 
 	c->device.release = &i2o_iop_release;
-	c->classdev.class = &i2o_controller_class;
-	c->classdev.dev = &c->device;
 
 	snprintf(c->device.bus_id, BUS_ID_SIZE, "iop%d", c->unit);
-	snprintf(c->classdev.class_id, BUS_ID_SIZE, "iop%d", c->unit);
 
 #if BITS_PER_LONG == 64
 	spin_lock_init(&c->context_list_lock);
@@ -1146,7 +1141,9 @@
 		goto iop_reset;
 	}
 
-	if ((rc = class_device_add(&c->classdev))) {
+	c->classdev = class_device_create(i2o_controller_class, NULL, MKDEV(0,0),
+			&c->device, "iop%d", c->unit);
+	if (IS_ERR(c->classdev)) {
 		osm_err("%s: could not add controller class\n", c->name);
 		goto device_del;
 	}
@@ -1184,7 +1181,7 @@
 	return 0;
 
       class_del:
-	class_device_del(&c->classdev);
+	class_device_unregister(c->classdev);
 
       device_del:
 	device_del(&c->device);
@@ -1246,13 +1243,10 @@
 
 	printk(KERN_INFO OSM_DESCRIPTION " v" OSM_VERSION "\n");
 
-	rc = i2o_device_init();
-	if (rc)
-		goto exit;
-
-	if ((rc = class_register(&i2o_controller_class))) {
+	i2o_controller_class = class_create(THIS_MODULE, "i2o_controller");
+	if (IS_ERR(i2o_controller_class)) {
 		osm_err("can't register class i2o_controller\n");
-		goto device_exit;
+		goto exit;
 	}
 
 	if ((rc = i2o_driver_init()))
@@ -1273,10 +1267,7 @@
 	i2o_driver_exit();
 
       class_exit:
-	class_unregister(&i2o_controller_class);
-
-      device_exit:
-	i2o_device_exit();
+	class_destroy(i2o_controller_class);
 
       exit:
 	return rc;
@@ -1292,8 +1283,7 @@
 	i2o_pci_exit();
 	i2o_exec_exit();
 	i2o_driver_exit();
-	class_unregister(&i2o_controller_class);
-	i2o_device_exit();
+	class_destroy(i2o_controller_class);
 };
 
 module_init(i2o_iop_init);
diff --git a/drivers/mfd/mcp-sa11x0.c b/drivers/mfd/mcp-sa11x0.c
index e9806fb..720e7a3 100644
--- a/drivers/mfd/mcp-sa11x0.c
+++ b/drivers/mfd/mcp-sa11x0.c
@@ -219,26 +219,24 @@
 	return 0;
 }
 
-static int mcp_sa11x0_suspend(struct device *dev, pm_message_t state, u32 level)
+static int mcp_sa11x0_suspend(struct device *dev, pm_message_t state)
 {
 	struct mcp *mcp = dev_get_drvdata(dev);
 
-	if (level == SUSPEND_DISABLE) {
-		priv(mcp)->mccr0 = Ser4MCCR0;
-		priv(mcp)->mccr1 = Ser4MCCR1;
-		Ser4MCCR0 &= ~MCCR0_MCE;
-	}
+	priv(mcp)->mccr0 = Ser4MCCR0;
+	priv(mcp)->mccr1 = Ser4MCCR1;
+	Ser4MCCR0 &= ~MCCR0_MCE;
+
 	return 0;
 }
 
-static int mcp_sa11x0_resume(struct device *dev, u32 level)
+static int mcp_sa11x0_resume(struct device *dev)
 {
 	struct mcp *mcp = dev_get_drvdata(dev);
 
-	if (level == RESUME_RESTORE_STATE) {
-		Ser4MCCR1 = priv(mcp)->mccr1;
-		Ser4MCCR0 = priv(mcp)->mccr0;
-	}
+	Ser4MCCR1 = priv(mcp)->mccr1;
+	Ser4MCCR0 = priv(mcp)->mccr0;
+
 	return 0;
 }
 
diff --git a/drivers/mfd/ucb1x00-ts.c b/drivers/mfd/ucb1x00-ts.c
index a260f83..585cded 100644
--- a/drivers/mfd/ucb1x00-ts.c
+++ b/drivers/mfd/ucb1x00-ts.c
@@ -40,7 +40,7 @@
 
 
 struct ucb1x00_ts {
-	struct input_dev	idev;
+	struct input_dev	*idev;
 	struct ucb1x00		*ucb;
 
 	wait_queue_head_t	irq_wait;
@@ -56,16 +56,16 @@
 
 static inline void ucb1x00_ts_evt_add(struct ucb1x00_ts *ts, u16 pressure, u16 x, u16 y)
 {
-	input_report_abs(&ts->idev, ABS_X, x);
-	input_report_abs(&ts->idev, ABS_Y, y);
-	input_report_abs(&ts->idev, ABS_PRESSURE, pressure);
-	input_sync(&ts->idev);
+	input_report_abs(ts->idev, ABS_X, x);
+	input_report_abs(ts->idev, ABS_Y, y);
+	input_report_abs(ts->idev, ABS_PRESSURE, pressure);
+	input_sync(ts->idev);
 }
 
 static inline void ucb1x00_ts_event_release(struct ucb1x00_ts *ts)
 {
-	input_report_abs(&ts->idev, ABS_PRESSURE, 0);
-	input_sync(&ts->idev);
+	input_report_abs(ts->idev, ABS_PRESSURE, 0);
+	input_sync(ts->idev);
 }
 
 /*
@@ -341,26 +341,30 @@
 {
 	struct ucb1x00_ts *ts;
 
-	ts = kmalloc(sizeof(struct ucb1x00_ts), GFP_KERNEL);
+	ts = kzalloc(sizeof(struct ucb1x00_ts), GFP_KERNEL);
 	if (!ts)
 		return -ENOMEM;
 
-	memset(ts, 0, sizeof(struct ucb1x00_ts));
+	ts->idev = input_allocate_device();
+	if (!ts->idev) {
+		kfree(ts);
+		return -ENOMEM;
+	}
 
 	ts->ucb = dev->ucb;
 	ts->adcsync = adcsync ? UCB_SYNC : UCB_NOSYNC;
 
-	ts->idev.name       = "Touchscreen panel";
-	ts->idev.id.product = ts->ucb->id;
-	ts->idev.open       = ucb1x00_ts_open;
-	ts->idev.close      = ucb1x00_ts_close;
+	ts->idev->name       = "Touchscreen panel";
+	ts->idev->id.product = ts->ucb->id;
+	ts->idev->open       = ucb1x00_ts_open;
+	ts->idev->close      = ucb1x00_ts_close;
 
-	__set_bit(EV_ABS, ts->idev.evbit);
-	__set_bit(ABS_X, ts->idev.absbit);
-	__set_bit(ABS_Y, ts->idev.absbit);
-	__set_bit(ABS_PRESSURE, ts->idev.absbit);
+	__set_bit(EV_ABS, ts->idev->evbit);
+	__set_bit(ABS_X, ts->idev->absbit);
+	__set_bit(ABS_Y, ts->idev->absbit);
+	__set_bit(ABS_PRESSURE, ts->idev->absbit);
 
-	input_register_device(&ts->idev);
+	input_register_device(ts->idev);
 
 	dev->priv = ts;
 
@@ -370,7 +374,8 @@
 static void ucb1x00_ts_remove(struct ucb1x00_dev *dev)
 {
 	struct ucb1x00_ts *ts = dev->priv;
-	input_unregister_device(&ts->idev);
+
+	input_unregister_device(ts->idev);
 	kfree(ts);
 }
 
diff --git a/drivers/mmc/pxamci.c b/drivers/mmc/pxamci.c
index b53af57..8eba373 100644
--- a/drivers/mmc/pxamci.c
+++ b/drivers/mmc/pxamci.c
@@ -571,23 +571,23 @@
 }
 
 #ifdef CONFIG_PM
-static int pxamci_suspend(struct device *dev, pm_message_t state, u32 level)
+static int pxamci_suspend(struct device *dev, pm_message_t state)
 {
 	struct mmc_host *mmc = dev_get_drvdata(dev);
 	int ret = 0;
 
-	if (mmc && level == SUSPEND_DISABLE)
+	if (mmc)
 		ret = mmc_suspend_host(mmc, state);
 
 	return ret;
 }
 
-static int pxamci_resume(struct device *dev, u32 level)
+static int pxamci_resume(struct device *dev)
 {
 	struct mmc_host *mmc = dev_get_drvdata(dev);
 	int ret = 0;
 
-	if (mmc && level == RESUME_ENABLE)
+	if (mmc)
 		ret = mmc_resume_host(mmc);
 
 	return ret;
diff --git a/drivers/mmc/wbsd.c b/drivers/mmc/wbsd.c
index 3cbca7c..25f7ce7 100644
--- a/drivers/mmc/wbsd.c
+++ b/drivers/mmc/wbsd.c
@@ -1955,14 +1955,14 @@
  */
 
 #ifdef CONFIG_PM
-static int wbsd_suspend(struct device *dev, pm_message_t state, u32 level)
+static int wbsd_suspend(struct device *dev, pm_message_t state)
 {
 	DBGF("Not yet supported\n");
 
 	return 0;
 }
 
-static int wbsd_resume(struct device *dev, u32 level)
+static int wbsd_resume(struct device *dev)
 {
 	DBGF("Not yet supported\n");
 
diff --git a/drivers/mtd/maps/sa1100-flash.c b/drivers/mtd/maps/sa1100-flash.c
index 9133351..6a8e0ca 100644
--- a/drivers/mtd/maps/sa1100-flash.c
+++ b/drivers/mtd/maps/sa1100-flash.c
@@ -403,21 +403,21 @@
 }
 
 #ifdef CONFIG_PM
-static int sa1100_mtd_suspend(struct device *dev, pm_message_t state, u32 level)
+static int sa1100_mtd_suspend(struct device *dev, pm_message_t state)
 {
 	struct sa_info *info = dev_get_drvdata(dev);
 	int ret = 0;
 
-	if (info && level == SUSPEND_SAVE_STATE)
+	if (info)
 		ret = info->mtd->suspend(info->mtd);
 
 	return ret;
 }
 
-static int sa1100_mtd_resume(struct device *dev, u32 level)
+static int sa1100_mtd_resume(struct device *dev)
 {
 	struct sa_info *info = dev_get_drvdata(dev);
-	if (info && level == RESUME_RESTORE_STATE)
+	if (info)
 		info->mtd->resume(info->mtd);
 	return 0;
 }
diff --git a/drivers/mtd/mtdchar.c b/drivers/mtd/mtdchar.c
index 1ed602a..c534fd5 100644
--- a/drivers/mtd/mtdchar.c
+++ b/drivers/mtd/mtdchar.c
@@ -24,10 +24,10 @@
 	if (!mtd)
 		return;
 
-	class_device_create(mtd_class, MKDEV(MTD_CHAR_MAJOR, mtd->index*2),
+	class_device_create(mtd_class, NULL, MKDEV(MTD_CHAR_MAJOR, mtd->index*2),
 			    NULL, "mtd%d", mtd->index);
 	
-	class_device_create(mtd_class, 
+	class_device_create(mtd_class, NULL,
 			    MKDEV(MTD_CHAR_MAJOR, mtd->index*2+1),
 			    NULL, "mtd%dro", mtd->index);
 }
diff --git a/drivers/net/dm9000.c b/drivers/net/dm9000.c
index e54fc10..abce1f7 100644
--- a/drivers/net/dm9000.c
+++ b/drivers/net/dm9000.c
@@ -1140,11 +1140,11 @@
 }
 
 static int
-dm9000_drv_suspend(struct device *dev, pm_message_t state, u32 level)
+dm9000_drv_suspend(struct device *dev, pm_message_t state)
 {
 	struct net_device *ndev = dev_get_drvdata(dev);
 
-	if (ndev && level == SUSPEND_DISABLE) {
+	if (ndev) {
 		if (netif_running(ndev)) {
 			netif_device_detach(ndev);
 			dm9000_shutdown(ndev);
@@ -1154,12 +1154,12 @@
 }
 
 static int
-dm9000_drv_resume(struct device *dev, u32 level)
+dm9000_drv_resume(struct device *dev)
 {
 	struct net_device *ndev = dev_get_drvdata(dev);
 	board_info_t *db = (board_info_t *) ndev->priv;
 
-	if (ndev && level == RESUME_ENABLE) {
+	if (ndev) {
 
 		if (netif_running(ndev)) {
 			dm9000_reset(db);
diff --git a/drivers/net/irda/sa1100_ir.c b/drivers/net/irda/sa1100_ir.c
index 8d34ac6..0688330 100644
--- a/drivers/net/irda/sa1100_ir.c
+++ b/drivers/net/irda/sa1100_ir.c
@@ -291,12 +291,12 @@
 /*
  * Suspend the IrDA interface.
  */
-static int sa1100_irda_suspend(struct device *_dev, pm_message_t state, u32 level)
+static int sa1100_irda_suspend(struct device *_dev, pm_message_t state)
 {
 	struct net_device *dev = dev_get_drvdata(_dev);
 	struct sa1100_irda *si;
 
-	if (!dev || level != SUSPEND_DISABLE)
+	if (!dev)
 		return 0;
 
 	si = dev->priv;
@@ -316,12 +316,12 @@
 /*
  * Resume the IrDA interface.
  */
-static int sa1100_irda_resume(struct device *_dev, u32 level)
+static int sa1100_irda_resume(struct device *_dev)
 {
 	struct net_device *dev = dev_get_drvdata(_dev);
 	struct sa1100_irda *si;
 
-	if (!dev || level != RESUME_ENABLE)
+	if (!dev)
 		return 0;
 
 	si = dev->priv;
diff --git a/drivers/net/irda/smsc-ircc2.c b/drivers/net/irda/smsc-ircc2.c
index dd89bda..bbac720 100644
--- a/drivers/net/irda/smsc-ircc2.c
+++ b/drivers/net/irda/smsc-ircc2.c
@@ -213,8 +213,8 @@
 
 /* Power Management */
 
-static int smsc_ircc_suspend(struct device *dev, pm_message_t state, u32 level);
-static int smsc_ircc_resume(struct device *dev, u32 level);
+static int smsc_ircc_suspend(struct device *dev, pm_message_t state);
+static int smsc_ircc_resume(struct device *dev);
 
 static struct device_driver smsc_ircc_driver = {
 	.name		= SMSC_IRCC2_DRIVER_NAME,
@@ -1646,13 +1646,13 @@
 	return 0;
 }
 
-static int smsc_ircc_suspend(struct device *dev, pm_message_t state, u32 level)
+static int smsc_ircc_suspend(struct device *dev, pm_message_t state)
 {
 	struct smsc_ircc_cb *self = dev_get_drvdata(dev);
 
 	IRDA_MESSAGE("%s, Suspending\n", driver_name);
 
-	if (level == SUSPEND_DISABLE && !self->io.suspended) {
+	if (!self->io.suspended) {
 		smsc_ircc_net_close(self->netdev);
 		self->io.suspended = 1;
 	}
@@ -1660,11 +1660,11 @@
 	return 0;
 }
 
-static int smsc_ircc_resume(struct device *dev, u32 level)
+static int smsc_ircc_resume(struct device *dev)
 {
 	struct smsc_ircc_cb *self = dev_get_drvdata(dev);
 
-	if (level == RESUME_ENABLE && self->io.suspended) {
+	if (self->io.suspended) {
 
 		smsc_ircc_net_open(self->netdev);
 		self->io.suspended = 0;
diff --git a/drivers/net/phy/mdio_bus.c b/drivers/net/phy/mdio_bus.c
index 9063067..ad93b0d 100644
--- a/drivers/net/phy/mdio_bus.c
+++ b/drivers/net/phy/mdio_bus.c
@@ -133,13 +133,9 @@
 	int ret = 0;
 	struct device_driver *drv = dev->driver;
 
-	if (drv && drv->suspend) {
-		ret = drv->suspend(dev, state, SUSPEND_DISABLE);
-		if (ret == 0)
-			ret = drv->suspend(dev, state, SUSPEND_SAVE_STATE);
-		if (ret == 0)
-			ret = drv->suspend(dev, state, SUSPEND_POWER_DOWN);
-	}
+	if (drv && drv->suspend)
+		ret = drv->suspend(dev, state);
+
 	return ret;
 }
 
@@ -148,13 +144,9 @@
 	int ret = 0;
 	struct device_driver *drv = dev->driver;
 
-	if (drv && drv->resume) {
-		ret = drv->resume(dev, RESUME_POWER_ON);
-		if (ret == 0)
-			ret = drv->resume(dev, RESUME_RESTORE_STATE);
-		if (ret == 0)
-			ret = drv->resume(dev, RESUME_ENABLE);
-	}
+	if (drv && drv->resume)
+		ret = drv->resume(dev);
+
 	return ret;
 }
 
diff --git a/drivers/net/ppp_generic.c b/drivers/net/ppp_generic.c
index 0df7e92..d3c9958 100644
--- a/drivers/net/ppp_generic.c
+++ b/drivers/net/ppp_generic.c
@@ -863,7 +863,7 @@
 			err = PTR_ERR(ppp_class);
 			goto out_chrdev;
 		}
-		class_device_create(ppp_class, MKDEV(PPP_MAJOR, 0), NULL, "ppp");
+		class_device_create(ppp_class, NULL, MKDEV(PPP_MAJOR, 0), NULL, "ppp");
 		err = devfs_mk_cdev(MKDEV(PPP_MAJOR, 0),
 				S_IFCHR|S_IRUSR|S_IWUSR, "ppp");
 		if (err)
diff --git a/drivers/net/smc91x.c b/drivers/net/smc91x.c
index 1438fdd..0ddaa61 100644
--- a/drivers/net/smc91x.c
+++ b/drivers/net/smc91x.c
@@ -2291,11 +2291,11 @@
 	return 0;
 }
 
-static int smc_drv_suspend(struct device *dev, pm_message_t state, u32 level)
+static int smc_drv_suspend(struct device *dev, pm_message_t state)
 {
 	struct net_device *ndev = dev_get_drvdata(dev);
 
-	if (ndev && level == SUSPEND_DISABLE) {
+	if (ndev) {
 		if (netif_running(ndev)) {
 			netif_device_detach(ndev);
 			smc_shutdown(ndev);
@@ -2305,12 +2305,12 @@
 	return 0;
 }
 
-static int smc_drv_resume(struct device *dev, u32 level)
+static int smc_drv_resume(struct device *dev)
 {
 	struct platform_device *pdev = to_platform_device(dev);
 	struct net_device *ndev = dev_get_drvdata(dev);
 
-	if (ndev && level == RESUME_ENABLE) {
+	if (ndev) {
 		struct smc_local *lp = netdev_priv(ndev);
 		smc_enable_device(pdev);
 		if (netif_running(ndev)) {
diff --git a/drivers/net/wan/cosa.c b/drivers/net/wan/cosa.c
index ae9e897..e392ee8 100644
--- a/drivers/net/wan/cosa.c
+++ b/drivers/net/wan/cosa.c
@@ -400,7 +400,7 @@
 		goto out_chrdev;
 	}
 	for (i=0; i<nr_cards; i++) {
-		class_device_create(cosa_class, MKDEV(cosa_major, i),
+		class_device_create(cosa_class, NULL, MKDEV(cosa_major, i),
 				NULL, "cosa%d", i);
 		err = devfs_mk_cdev(MKDEV(cosa_major, i),
 				S_IFCHR|S_IRUSR|S_IWUSR,
diff --git a/drivers/pci/pcie/portdrv_core.c b/drivers/pci/pcie/portdrv_core.c
index 393e0ce..14f05d2 100644
--- a/drivers/pci/pcie/portdrv_core.c
+++ b/drivers/pci/pcie/portdrv_core.c
@@ -61,7 +61,7 @@
 
 static void pcie_port_shutdown_service(struct device *dev) {}
 
-static int pcie_port_suspend_service(struct device *dev, pm_message_t state, u32 level)
+static int pcie_port_suspend_service(struct device *dev, pm_message_t state)
 {
 	struct pcie_device *pciedev;
 	struct pcie_port_service_driver *driver;
@@ -76,7 +76,7 @@
 	return 0;
 }
 
-static int pcie_port_resume_service(struct device *dev, u32 level)
+static int pcie_port_resume_service(struct device *dev)
 {
 	struct pcie_device *pciedev;
 	struct pcie_port_service_driver *driver;
diff --git a/drivers/pcmcia/au1000_generic.c b/drivers/pcmcia/au1000_generic.c
index 470ef75..d90a634 100644
--- a/drivers/pcmcia/au1000_generic.c
+++ b/drivers/pcmcia/au1000_generic.c
@@ -519,30 +519,13 @@
 }
 
 
-static int au1x00_drv_pcmcia_suspend(struct device *dev, pm_message_t state, u32 level)
-{
-	int ret = 0;
-	if (level == SUSPEND_SAVE_STATE)
-		ret = pcmcia_socket_dev_suspend(dev, state);
-	return ret;
-}
-
-static int au1x00_drv_pcmcia_resume(struct device *dev, u32 level)
-{
-	int ret = 0;
-	if (level == RESUME_RESTORE_STATE)
-		ret = pcmcia_socket_dev_resume(dev);
-	return ret;
-}
-
-
 static struct device_driver au1x00_pcmcia_driver = {
 	.probe		= au1x00_drv_pcmcia_probe,
 	.remove		= au1x00_drv_pcmcia_remove,
 	.name		= "au1x00-pcmcia",
 	.bus		= &platform_bus_type,
-	.suspend	= au1x00_drv_pcmcia_suspend,
-	.resume		= au1x00_drv_pcmcia_resume
+	.suspend	= pcmcia_socket_dev_suspend,
+	.resume		= pcmcia_socket_dev_resume,
 };
 
 static struct platform_device au1x00_device = {
diff --git a/drivers/pcmcia/ds.c b/drivers/pcmcia/ds.c
index 080608c..39d096b 100644
--- a/drivers/pcmcia/ds.c
+++ b/drivers/pcmcia/ds.c
@@ -1157,7 +1157,8 @@
 	.requery = pcmcia_bus_rescan,
 };
 
-static int __devinit pcmcia_bus_add_socket(struct class_device *class_dev)
+static int __devinit pcmcia_bus_add_socket(struct class_device *class_dev,
+					   struct class_interface *class_intf)
 {
 	struct pcmcia_socket *socket = class_get_devdata(class_dev);
 	int ret;
@@ -1192,7 +1193,8 @@
 	return 0;
 }
 
-static void pcmcia_bus_remove_socket(struct class_device *class_dev)
+static void pcmcia_bus_remove_socket(struct class_device *class_dev,
+				     struct class_interface *class_intf)
 {
 	struct pcmcia_socket *socket = class_get_devdata(class_dev);
 
diff --git a/drivers/pcmcia/hd64465_ss.c b/drivers/pcmcia/hd64465_ss.c
index 316f8bc..b57a0b9 100644
--- a/drivers/pcmcia/hd64465_ss.c
+++ b/drivers/pcmcia/hd64465_ss.c
@@ -844,27 +844,11 @@
 	local_irq_restore(flags);
 }
 
-static int hd64465_suspend(struct device *dev, pm_message_t state, u32 level)
-{
-	int ret = 0;
-	if (level == SUSPEND_SAVE_STATE)
-		ret = pcmcia_socket_dev_suspend(dev, state);
-	return ret;
-}
-
-static int hd64465_resume(struct device *dev, u32 level)
-{
-	int ret = 0;
-	if (level == RESUME_RESTORE_STATE)
-		ret = pcmcia_socket_dev_resume(dev);
-	return ret;
-}
-
 static struct device_driver hd64465_driver = {
 	.name = "hd64465-pcmcia",
 	.bus = &platform_bus_type,
-	.suspend = hd64465_suspend,
-	.resume = hd64465_resume,
+	.suspend = pcmcia_socket_dev_suspend,
+	.resume = pcmcia_socket_dev_resume,
 };
 
 static struct platform_device hd64465_device = {
diff --git a/drivers/pcmcia/i82365.c b/drivers/pcmcia/i82365.c
index a713015..4a41f67 100644
--- a/drivers/pcmcia/i82365.c
+++ b/drivers/pcmcia/i82365.c
@@ -1332,27 +1332,11 @@
 
 /*====================================================================*/
 
-static int i82365_suspend(struct device *dev, pm_message_t state, u32 level)
-{
-	int ret = 0;
-	if (level == SUSPEND_SAVE_STATE)
-		ret = pcmcia_socket_dev_suspend(dev, state);
-	return ret;
-}
-
-static int i82365_resume(struct device *dev, u32 level)
-{
-	int ret = 0;
-	if (level == RESUME_RESTORE_STATE)
-		ret = pcmcia_socket_dev_resume(dev);
-	return ret;
-}
-
 static struct device_driver i82365_driver = {
 	.name = "i82365",
 	.bus = &platform_bus_type,
-	.suspend = i82365_suspend,
-	.resume = i82365_resume,
+	.suspend = pcmcia_socket_dev_suspend,
+	.resume = pcmcia_socket_dev_resume,
 };
 
 static struct platform_device i82365_device = {
diff --git a/drivers/pcmcia/m32r_cfc.c b/drivers/pcmcia/m32r_cfc.c
index 65f3ee3..c6ed70e 100644
--- a/drivers/pcmcia/m32r_cfc.c
+++ b/drivers/pcmcia/m32r_cfc.c
@@ -731,28 +731,11 @@
 
 /*====================================================================*/
 
-static int m32r_pcc_suspend(struct device *dev, pm_message_t state, u32 level)
-{
-	int ret = 0;
-	if (level == SUSPEND_SAVE_STATE)
-		ret = pcmcia_socket_dev_suspend(dev, state);
-	return ret;
-}
-
-static int m32r_pcc_resume(struct device *dev, u32 level)
-{
-	int ret = 0;
-	if (level == RESUME_RESTORE_STATE)
-		ret = pcmcia_socket_dev_resume(dev);
-	return ret;
-}
-
-
 static struct device_driver pcc_driver = {
 	.name = "cfc",
 	.bus = &platform_bus_type,
-	.suspend = m32r_pcc_suspend,
-	.resume = m32r_pcc_resume,
+	.suspend = pcmcia_socket_dev_suspend,
+	.resume = pcmcia_socket_dev_resume,
 };
 
 static struct platform_device pcc_device = {
diff --git a/drivers/pcmcia/m32r_pcc.c b/drivers/pcmcia/m32r_pcc.c
index 7b14d7e..3397ff2 100644
--- a/drivers/pcmcia/m32r_pcc.c
+++ b/drivers/pcmcia/m32r_pcc.c
@@ -695,28 +695,11 @@
 
 /*====================================================================*/
 
-static int m32r_pcc_suspend(struct device *dev, pm_message_t state, u32 level)
-{
-	int ret = 0;
-	if (level == SUSPEND_SAVE_STATE)
-		ret = pcmcia_socket_dev_suspend(dev, state);
-	return ret;
-}
-
-static int m32r_pcc_resume(struct device *dev, u32 level)
-{
-	int ret = 0;
-	if (level == RESUME_RESTORE_STATE)
-		ret = pcmcia_socket_dev_resume(dev);
-	return ret;
-}
-
-
 static struct device_driver pcc_driver = {
 	.name = "pcc",
 	.bus = &platform_bus_type,
-	.suspend = m32r_pcc_suspend,
-	.resume = m32r_pcc_resume,
+	.suspend = pcmcia_socket_dev_suspend,
+	.resume = pcmcia_socket_dev_resume,
 };
 
 static struct platform_device pcc_device = {
diff --git a/drivers/pcmcia/omap_cf.c b/drivers/pcmcia/omap_cf.c
index 94be9e5..2558c3c 100644
--- a/drivers/pcmcia/omap_cf.c
+++ b/drivers/pcmcia/omap_cf.c
@@ -329,27 +329,13 @@
 	return 0;
 }
 
-static int omap_cf_suspend(struct device *dev, pm_message_t mesg, u32 level)
-{
-	if (level != SUSPEND_SAVE_STATE)
-		return 0;
-	return pcmcia_socket_dev_suspend(dev, mesg);
-}
-
-static int omap_cf_resume(struct device *dev, u32 level)
-{
-	if (level != RESUME_RESTORE_STATE)
-		return 0;
-	return pcmcia_socket_dev_resume(dev);
-}
-
 static struct device_driver omap_cf_driver = {
 	.name		= (char *) driver_name,
 	.bus		= &platform_bus_type,
 	.probe		= omap_cf_probe,
 	.remove		= __devexit_p(omap_cf_remove),
-	.suspend 	= omap_cf_suspend,
-	.resume 	= omap_cf_resume,
+	.suspend 	= pcmcia_socket_dev_suspend,
+	.resume 	= pcmcia_socket_dev_resume,
 };
 
 static int __init omap_cf_init(void)
diff --git a/drivers/pcmcia/pxa2xx_base.c b/drivers/pcmcia/pxa2xx_base.c
index 325c992..c2a12d5 100644
--- a/drivers/pcmcia/pxa2xx_base.c
+++ b/drivers/pcmcia/pxa2xx_base.c
@@ -205,32 +205,20 @@
 }
 EXPORT_SYMBOL(pxa2xx_drv_pcmcia_probe);
 
-static int pxa2xx_drv_pcmcia_suspend(struct device *dev, pm_message_t state, u32 level)
+static int pxa2xx_drv_pcmcia_resume(struct device *dev)
 {
-	int ret = 0;
-	if (level == SUSPEND_SAVE_STATE)
-		ret = pcmcia_socket_dev_suspend(dev, state);
-	return ret;
-}
+	struct pcmcia_low_level *ops = dev->platform_data;
+	int nr = ops ? ops->nr : 0;
 
-static int pxa2xx_drv_pcmcia_resume(struct device *dev, u32 level)
-{
-	int ret = 0;
-	if (level == RESUME_RESTORE_STATE)
-	{
-		struct pcmcia_low_level *ops = dev->platform_data;
-		int nr = ops ? ops->nr : 0;
+	MECR = nr > 1 ? MECR_CIT | MECR_NOS : (nr > 0 ? MECR_CIT : 0);
 
-		MECR = nr > 1 ? MECR_CIT | MECR_NOS : (nr > 0 ? MECR_CIT : 0);
-		ret = pcmcia_socket_dev_resume(dev);
-	}
-	return ret;
+	return pcmcia_socket_dev_resume(dev);
 }
 
 static struct device_driver pxa2xx_pcmcia_driver = {
 	.probe		= pxa2xx_drv_pcmcia_probe,
 	.remove		= soc_common_drv_pcmcia_remove,
-	.suspend 	= pxa2xx_drv_pcmcia_suspend,
+	.suspend 	= pcmcia_socket_dev_suspend,
 	.resume 	= pxa2xx_drv_pcmcia_resume,
 	.name		= "pxa2xx-pcmcia",
 	.bus		= &platform_bus_type,
diff --git a/drivers/pcmcia/rsrc_nonstatic.c b/drivers/pcmcia/rsrc_nonstatic.c
index f9a5c70..fc87e7e 100644
--- a/drivers/pcmcia/rsrc_nonstatic.c
+++ b/drivers/pcmcia/rsrc_nonstatic.c
@@ -994,7 +994,8 @@
 	NULL,
 };
 
-static int __devinit pccard_sysfs_add_rsrc(struct class_device *class_dev)
+static int __devinit pccard_sysfs_add_rsrc(struct class_device *class_dev,
+					   struct class_interface *class_intf)
 {
 	struct pcmcia_socket *s = class_get_devdata(class_dev);
 	struct class_device_attribute **attr;
@@ -1011,7 +1012,8 @@
 	return ret;
 }
 
-static void __devexit pccard_sysfs_remove_rsrc(struct class_device *class_dev)
+static void __devexit pccard_sysfs_remove_rsrc(struct class_device *class_dev,
+					       struct class_interface *class_intf)
 {
 	struct pcmcia_socket *s = class_get_devdata(class_dev);
 	struct class_device_attribute **attr;
diff --git a/drivers/pcmcia/sa1100_generic.c b/drivers/pcmcia/sa1100_generic.c
index d4ed508..b768fa8 100644
--- a/drivers/pcmcia/sa1100_generic.c
+++ b/drivers/pcmcia/sa1100_generic.c
@@ -74,29 +74,13 @@
 	return ret;
 }
 
-static int sa11x0_drv_pcmcia_suspend(struct device *dev, pm_message_t state, u32 level)
-{
-	int ret = 0;
-	if (level == SUSPEND_SAVE_STATE)
-		ret = pcmcia_socket_dev_suspend(dev, state);
-	return ret;
-}
-
-static int sa11x0_drv_pcmcia_resume(struct device *dev, u32 level)
-{
-	int ret = 0;
-	if (level == RESUME_RESTORE_STATE)
-		ret = pcmcia_socket_dev_resume(dev);
-	return ret;
-}
-
 static struct device_driver sa11x0_pcmcia_driver = {
 	.probe		= sa11x0_drv_pcmcia_probe,
 	.remove		= soc_common_drv_pcmcia_remove,
 	.name		= "sa11x0-pcmcia",
 	.bus		= &platform_bus_type,
-	.suspend 	= sa11x0_drv_pcmcia_suspend,
-	.resume 	= sa11x0_drv_pcmcia_resume,
+	.suspend 	= pcmcia_socket_dev_suspend,
+	.resume 	= pcmcia_socket_dev_resume,
 };
 
 /* sa11x0_pcmcia_init()
diff --git a/drivers/pcmcia/socket_sysfs.c b/drivers/pcmcia/socket_sysfs.c
index 1040a6c..4a3150a 100644
--- a/drivers/pcmcia/socket_sysfs.c
+++ b/drivers/pcmcia/socket_sysfs.c
@@ -341,7 +341,8 @@
 	.write = pccard_store_cis,
 };
 
-static int __devinit pccard_sysfs_add_socket(struct class_device *class_dev)
+static int __devinit pccard_sysfs_add_socket(struct class_device *class_dev,
+					     struct class_interface *class_intf)
 {
 	struct class_device_attribute **attr;
 	int ret = 0;
@@ -357,7 +358,8 @@
 	return ret;
 }
 
-static void __devexit pccard_sysfs_remove_socket(struct class_device *class_dev)
+static void __devexit pccard_sysfs_remove_socket(struct class_device *class_dev,
+						 struct class_interface *class_intf)
 {
 	struct class_device_attribute **attr;
 
diff --git a/drivers/pcmcia/tcic.c b/drivers/pcmcia/tcic.c
index d5a61ea..f158b67 100644
--- a/drivers/pcmcia/tcic.c
+++ b/drivers/pcmcia/tcic.c
@@ -372,27 +372,11 @@
 
 /*====================================================================*/
 
-static int tcic_drv_suspend(struct device *dev, pm_message_t state, u32 level)
-{
-	int ret = 0;
-	if (level == SUSPEND_SAVE_STATE)
-		ret = pcmcia_socket_dev_suspend(dev, state);
-	return ret;
-}
-
-static int tcic_drv_resume(struct device *dev, u32 level)
-{
-	int ret = 0;
-	if (level == RESUME_RESTORE_STATE)
-		ret = pcmcia_socket_dev_resume(dev);
-	return ret;
-}
-
 static struct device_driver tcic_driver = {
 	.name = "tcic-pcmcia",
 	.bus = &platform_bus_type,
-	.suspend = tcic_drv_suspend,
-	.resume = tcic_drv_resume,
+	.suspend = pcmcia_socket_dev_suspend,
+	.resume = pcmcia_socket_dev_resume,
 };
 
 static struct platform_device tcic_device = {
diff --git a/drivers/pcmcia/vrc4171_card.c b/drivers/pcmcia/vrc4171_card.c
index 17bb2da..3d2dca6 100644
--- a/drivers/pcmcia/vrc4171_card.c
+++ b/drivers/pcmcia/vrc4171_card.c
@@ -774,31 +774,11 @@
 
 __setup("vrc4171_card=", vrc4171_card_setup);
 
-static int vrc4171_card_suspend(struct device *dev, pm_message_t state, u32 level)
-{
-	int retval = 0;
-
-	if (level == SUSPEND_SAVE_STATE)
-		retval = pcmcia_socket_dev_suspend(dev, state);
-
-	return retval;
-}
-
-static int vrc4171_card_resume(struct device *dev, u32 level)
-{
-	int retval = 0;
-
-	if (level == RESUME_RESTORE_STATE)
-		retval = pcmcia_socket_dev_resume(dev);
-
-	return retval;
-}
-
 static struct device_driver vrc4171_card_driver = {
 	.name		= vrc4171_card_name,
 	.bus		= &platform_bus_type,
-	.suspend	= vrc4171_card_suspend,
-	.resume		= vrc4171_card_resume,
+	.suspend	= pcmcia_socket_dev_suspend,
+	.resume		= pcmcia_socket_dev_resume,
 };
 
 static int __devinit vrc4171_card_init(void)
diff --git a/drivers/s390/char/tape_class.c b/drivers/s390/char/tape_class.c
index ed0cb1f..fcaee44 100644
--- a/drivers/s390/char/tape_class.c
+++ b/drivers/s390/char/tape_class.c
@@ -72,6 +72,7 @@
 
 	tcd->class_device = class_device_create(
 				tape_class,
+				NULL,
 				tcd->char_device->dev,
 				device,
 				"%s", tcd->device_name
diff --git a/drivers/s390/char/vmlogrdr.c b/drivers/s390/char/vmlogrdr.c
index 491f00c..a107fec 100644
--- a/drivers/s390/char/vmlogrdr.c
+++ b/drivers/s390/char/vmlogrdr.c
@@ -787,6 +787,7 @@
 		return ret;
 	}
 	priv->class_device = class_device_create(
+				NULL,
 				vmlogrdr_class,
 				MKDEV(vmlogrdr_major, priv->minor_num),
 				dev,
diff --git a/drivers/scsi/ch.c b/drivers/scsi/ch.c
index da6e51c..540147c 100644
--- a/drivers/scsi/ch.c
+++ b/drivers/scsi/ch.c
@@ -936,7 +936,7 @@
 	if (init)
 		ch_init_elem(ch);
 
-	class_device_create(ch_sysfs_class,
+	class_device_create(ch_sysfs_class, NULL,
 			    MKDEV(SCSI_CHANGER_MAJOR,ch->minor),
 			    dev, "s%s", ch->name);
 
diff --git a/drivers/scsi/osst.c b/drivers/scsi/osst.c
index af11331..172839f 100644
--- a/drivers/scsi/osst.c
+++ b/drivers/scsi/osst.c
@@ -5629,7 +5629,7 @@
 
 	if (!osst_sysfs_valid) return;
 
-	osst_class_member = class_device_create(osst_sysfs_class, dev, device, "%s", name);
+	osst_class_member = class_device_create(osst_sysfs_class, NULL, dev, device, "%s", name);
 	if (IS_ERR(osst_class_member)) {
 		printk(KERN_WARNING "osst :W: Unable to add sysfs class member %s\n", name);
 		return;
diff --git a/drivers/scsi/sg.c b/drivers/scsi/sg.c
index fd56b7e..861e51375 100644
--- a/drivers/scsi/sg.c
+++ b/drivers/scsi/sg.c
@@ -104,8 +104,8 @@
 
 #define SG_DEV_ARR_LUMP 32	/* amount to over allocate sg_dev_arr by */
 
-static int sg_add(struct class_device *);
-static void sg_remove(struct class_device *);
+static int sg_add(struct class_device *, struct class_interface *);
+static void sg_remove(struct class_device *, struct class_interface *);
 
 static Scsi_Request *dummy_cmdp;	/* only used for sizeof */
 
@@ -1506,7 +1506,7 @@
 }
 
 static int
-sg_add(struct class_device *cl_dev)
+sg_add(struct class_device *cl_dev, struct class_interface *cl_intf)
 {
 	struct scsi_device *scsidp = to_scsi_device(cl_dev->dev);
 	struct gendisk *disk;
@@ -1550,7 +1550,7 @@
 	if (sg_sysfs_valid) {
 		struct class_device * sg_class_member;
 
-		sg_class_member = class_device_create(sg_sysfs_class,
+		sg_class_member = class_device_create(sg_sysfs_class, NULL,
 				MKDEV(SCSI_GENERIC_MAJOR, k), 
 				cl_dev->dev, "%s", 
 				disk->disk_name);
@@ -1582,7 +1582,7 @@
 }
 
 static void
-sg_remove(struct class_device *cl_dev)
+sg_remove(struct class_device *cl_dev, struct class_interface *cl_intf)
 {
 	struct scsi_device *scsidp = to_scsi_device(cl_dev->dev);
 	Sg_device *sdp = NULL;
diff --git a/drivers/scsi/st.c b/drivers/scsi/st.c
index 927d700..5eb54d8 100644
--- a/drivers/scsi/st.c
+++ b/drivers/scsi/st.c
@@ -4377,7 +4377,7 @@
 		snprintf(name, 10, "%s%s%s", rew ? "n" : "",
 			 STp->disk->disk_name, st_formats[i]);
 		st_class_member =
-			class_device_create(st_sysfs_class,
+			class_device_create(st_sysfs_class, NULL,
 					    MKDEV(SCSI_TAPE_MAJOR,
 						  TAPE_MINOR(dev_num, mode, rew)),
 					    &STp->device->sdev_gendev, "%s", name);
diff --git a/drivers/serial/8250.c b/drivers/serial/8250.c
index 4d75cdf..afb7ddf 100644
--- a/drivers/serial/8250.c
+++ b/drivers/serial/8250.c
@@ -2358,13 +2358,10 @@
 	return 0;
 }
 
-static int serial8250_suspend(struct device *dev, pm_message_t state, u32 level)
+static int serial8250_suspend(struct device *dev, pm_message_t state)
 {
 	int i;
 
-	if (level != SUSPEND_DISABLE)
-		return 0;
-
 	for (i = 0; i < UART_NR; i++) {
 		struct uart_8250_port *up = &serial8250_ports[i];
 
@@ -2375,13 +2372,10 @@
 	return 0;
 }
 
-static int serial8250_resume(struct device *dev, u32 level)
+static int serial8250_resume(struct device *dev)
 {
 	int i;
 
-	if (level != RESUME_ENABLE)
-		return 0;
-
 	for (i = 0; i < UART_NR; i++) {
 		struct uart_8250_port *up = &serial8250_ports[i];
 
diff --git a/drivers/serial/imx.c b/drivers/serial/imx.c
index bdb4e45..5b3933b 100644
--- a/drivers/serial/imx.c
+++ b/drivers/serial/imx.c
@@ -921,21 +921,21 @@
 	.cons           = IMX_CONSOLE,
 };
 
-static int serial_imx_suspend(struct device *_dev, pm_message_t state, u32 level)
+static int serial_imx_suspend(struct device *_dev, pm_message_t state)
 {
         struct imx_port *sport = dev_get_drvdata(_dev);
 
-        if (sport && level == SUSPEND_DISABLE)
+        if (sport)
                 uart_suspend_port(&imx_reg, &sport->port);
 
         return 0;
 }
 
-static int serial_imx_resume(struct device *_dev, u32 level)
+static int serial_imx_resume(struct device *_dev)
 {
         struct imx_port *sport = dev_get_drvdata(_dev);
 
-        if (sport && level == RESUME_ENABLE)
+        if (sport)
                 uart_resume_port(&imx_reg, &sport->port);
 
         return 0;
diff --git a/drivers/serial/mpc52xx_uart.c b/drivers/serial/mpc52xx_uart.c
index 0585ab2..8a79968 100644
--- a/drivers/serial/mpc52xx_uart.c
+++ b/drivers/serial/mpc52xx_uart.c
@@ -781,22 +781,22 @@
 
 #ifdef CONFIG_PM
 static int
-mpc52xx_uart_suspend(struct device *dev, pm_message_t state, u32 level)
+mpc52xx_uart_suspend(struct device *dev, pm_message_t state)
 {
 	struct uart_port *port = (struct uart_port *) dev_get_drvdata(dev);
 
-	if (sport && level == SUSPEND_DISABLE)
+	if (sport)
 		uart_suspend_port(&mpc52xx_uart_driver, port);
 
 	return 0;
 }
 
 static int
-mpc52xx_uart_resume(struct device *dev, u32 level)
+mpc52xx_uart_resume(struct device *dev)
 {
 	struct uart_port *port = (struct uart_port *) dev_get_drvdata(dev);
 
-	if (port && level == RESUME_ENABLE)
+	if (port)
 		uart_resume_port(&mpc52xx_uart_driver, port);
 
 	return 0;
diff --git a/drivers/serial/pxa.c b/drivers/serial/pxa.c
index 005f027..8cc4ced 100644
--- a/drivers/serial/pxa.c
+++ b/drivers/serial/pxa.c
@@ -805,21 +805,21 @@
 	.cons		= PXA_CONSOLE,
 };
 
-static int serial_pxa_suspend(struct device *_dev, pm_message_t state, u32 level)
+static int serial_pxa_suspend(struct device *_dev, pm_message_t state)
 {
         struct uart_pxa_port *sport = dev_get_drvdata(_dev);
 
-        if (sport && level == SUSPEND_DISABLE)
+        if (sport)
                 uart_suspend_port(&serial_pxa_reg, &sport->port);
 
         return 0;
 }
 
-static int serial_pxa_resume(struct device *_dev, u32 level)
+static int serial_pxa_resume(struct device *_dev)
 {
         struct uart_pxa_port *sport = dev_get_drvdata(_dev);
 
-        if (sport && level == RESUME_ENABLE)
+        if (sport)
                 uart_resume_port(&serial_pxa_reg, &sport->port);
 
         return 0;
diff --git a/drivers/serial/s3c2410.c b/drivers/serial/s3c2410.c
index 52692aa..06a17df 100644
--- a/drivers/serial/s3c2410.c
+++ b/drivers/serial/s3c2410.c
@@ -1134,23 +1134,22 @@
 
 #ifdef CONFIG_PM
 
-static int s3c24xx_serial_suspend(struct device *dev, pm_message_t state,
-				  u32 level)
+static int s3c24xx_serial_suspend(struct device *dev, pm_message_t state)
 {
 	struct uart_port *port = s3c24xx_dev_to_port(dev);
 
-	if (port && level == SUSPEND_DISABLE)
+	if (port)
 		uart_suspend_port(&s3c24xx_uart_drv, port);
 
 	return 0;
 }
 
-static int s3c24xx_serial_resume(struct device *dev, u32 level)
+static int s3c24xx_serial_resume(struct device *dev)
 {
 	struct uart_port *port = s3c24xx_dev_to_port(dev);
 	struct s3c24xx_uart_port *ourport = to_ourport(port);
 
-	if (port && level == RESUME_ENABLE) {
+	if (port) {
 		clk_enable(ourport->clk);
 		s3c24xx_serial_resetport(port, s3c24xx_port_to_cfg(port));
 		clk_disable(ourport->clk);
diff --git a/drivers/serial/sa1100.c b/drivers/serial/sa1100.c
index dd8aed2..c4a789e 100644
--- a/drivers/serial/sa1100.c
+++ b/drivers/serial/sa1100.c
@@ -834,21 +834,21 @@
 	.cons			= SA1100_CONSOLE,
 };
 
-static int sa1100_serial_suspend(struct device *_dev, pm_message_t state, u32 level)
+static int sa1100_serial_suspend(struct device *_dev, pm_message_t state)
 {
 	struct sa1100_port *sport = dev_get_drvdata(_dev);
 
-	if (sport && level == SUSPEND_DISABLE)
+	if (sport)
 		uart_suspend_port(&sa1100_reg, &sport->port);
 
 	return 0;
 }
 
-static int sa1100_serial_resume(struct device *_dev, u32 level)
+static int sa1100_serial_resume(struct device *_dev)
 {
 	struct sa1100_port *sport = dev_get_drvdata(_dev);
 
-	if (sport && level == RESUME_ENABLE)
+	if (sport)
 		uart_resume_port(&sa1100_reg, &sport->port);
 
 	return 0;
diff --git a/drivers/serial/vr41xx_siu.c b/drivers/serial/vr41xx_siu.c
index 0c5d65a..2b623ab 100644
--- a/drivers/serial/vr41xx_siu.c
+++ b/drivers/serial/vr41xx_siu.c
@@ -976,14 +976,11 @@
 	return 0;
 }
 
-static int siu_suspend(struct device *dev, pm_message_t state, u32 level)
+static int siu_suspend(struct device *dev, pm_message_t state)
 {
 	struct uart_port *port;
 	int i;
 
-	if (level != SUSPEND_DISABLE)
-		return 0;
-
 	for (i = 0; i < siu_uart_driver.nr; i++) {
 		port = &siu_uart_ports[i];
 		if ((port->type == PORT_VR41XX_SIU ||
@@ -995,14 +992,11 @@
 	return 0;
 }
 
-static int siu_resume(struct device *dev, u32 level)
+static int siu_resume(struct device *dev)
 {
 	struct uart_port *port;
 	int i;
 
-	if (level != RESUME_ENABLE)
-		return 0;
-
 	for (i = 0; i < siu_uart_driver.nr; i++) {
 		port = &siu_uart_ports[i];
 		if ((port->type == PORT_VR41XX_SIU ||
diff --git a/drivers/usb/core/devio.c b/drivers/usb/core/devio.c
index 487ff67..befe0c7 100644
--- a/drivers/usb/core/devio.c
+++ b/drivers/usb/core/devio.c
@@ -1509,7 +1509,7 @@
 {
 	int minor = ((dev->bus->busnum-1) * 128) + (dev->devnum-1);
 
-	dev->class_dev = class_device_create(usb_device_class,
+	dev->class_dev = class_device_create(usb_device_class, NULL,
 				MKDEV(USB_DEVICE_MAJOR, minor), &dev->dev,
 				"usbdev%d.%d", dev->bus->busnum, dev->devnum);
 
diff --git a/drivers/usb/core/file.c b/drivers/usb/core/file.c
index 65ca131..78cb4be 100644
--- a/drivers/usb/core/file.c
+++ b/drivers/usb/core/file.c
@@ -172,7 +172,9 @@
 		++temp;
 	else
 		temp = name;
-	intf->class_dev = class_device_create(usb_class, MKDEV(USB_MAJOR, minor), &intf->dev, "%s", temp);
+	intf->class_dev = class_device_create(usb_class, NULL,
+					      MKDEV(USB_MAJOR, minor),
+					      &intf->dev, "%s", temp);
 	if (IS_ERR(intf->class_dev)) {
 		spin_lock (&minor_lock);
 		usb_minors[intf->minor] = NULL;
diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c
index ff19d64..14c47a1 100644
--- a/drivers/usb/core/hcd.c
+++ b/drivers/usb/core/hcd.c
@@ -782,7 +782,8 @@
 		return -E2BIG;
 	}
 
-	bus->class_dev = class_device_create(usb_host_class, MKDEV(0,0), bus->controller, "usb_host%d", busnum);
+	bus->class_dev = class_device_create(usb_host_class, NULL, MKDEV(0,0),
+					     bus->controller, "usb_host%d", busnum);
 	if (IS_ERR(bus->class_dev)) {
 		clear_bit(busnum, busmap.busmap);
 		up(&usb_bus_list_lock);
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
index a12cab5..c3e2024 100644
--- a/drivers/usb/core/hub.c
+++ b/drivers/usb/core/hub.c
@@ -1020,9 +1020,15 @@
 	spin_lock_irqsave(&device_state_lock, flags);
 	if (udev->state == USB_STATE_NOTATTACHED)
 		;	/* do nothing */
-	else if (new_state != USB_STATE_NOTATTACHED)
+	else if (new_state != USB_STATE_NOTATTACHED) {
 		udev->state = new_state;
-	else
+		if (new_state == USB_STATE_CONFIGURED)
+			device_init_wakeup(&udev->dev,
+				(udev->actconfig->desc.bmAttributes
+				 & USB_CONFIG_ATT_WAKEUP));
+		else if (new_state != USB_STATE_SUSPENDED)
+			device_init_wakeup(&udev->dev, 0);
+	} else
 		recursively_mark_NOTATTACHED(udev);
 	spin_unlock_irqrestore(&device_state_lock, flags);
 }
@@ -1546,11 +1552,7 @@
 	 * NOTE:  OTG devices may issue remote wakeup (or SRP) even when
 	 * we don't explicitly enable it here.
 	 */
-	if (udev->actconfig
-			// && FIXME (remote wakeup enabled on this bus)
-			// ... currently assuming it's always appropriate
-			&& (udev->actconfig->desc.bmAttributes
-				& USB_CONFIG_ATT_WAKEUP) != 0) {
+	if (device_may_wakeup(&udev->dev)) {
 		status = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
 				USB_REQ_SET_FEATURE, USB_RECIP_DEVICE,
 				USB_DEVICE_REMOTE_WAKEUP, 0,
diff --git a/drivers/usb/gadget/dummy_hcd.c b/drivers/usb/gadget/dummy_hcd.c
index 8d9d8ee..5032017 100644
--- a/drivers/usb/gadget/dummy_hcd.c
+++ b/drivers/usb/gadget/dummy_hcd.c
@@ -935,14 +935,10 @@
 	return 0;
 }
 
-static int dummy_udc_suspend (struct device *dev, pm_message_t state,
-		u32 level)
+static int dummy_udc_suspend (struct device *dev, pm_message_t state)
 {
 	struct dummy	*dum = dev_get_drvdata(dev);
 
-	if (level != SUSPEND_DISABLE)
-		return 0;
-
 	dev_dbg (dev, "%s\n", __FUNCTION__);
 	spin_lock_irq (&dum->lock);
 	dum->udc_suspended = 1;
@@ -954,13 +950,10 @@
 	return 0;
 }
 
-static int dummy_udc_resume (struct device *dev, u32 level)
+static int dummy_udc_resume (struct device *dev)
 {
 	struct dummy	*dum = dev_get_drvdata(dev);
 
-	if (level != RESUME_ENABLE)
-		return 0;
-
 	dev_dbg (dev, "%s\n", __FUNCTION__);
 	spin_lock_irq (&dum->lock);
 	dum->udc_suspended = 0;
@@ -1936,14 +1929,10 @@
 	return 0;
 }
 
-static int dummy_hcd_suspend (struct device *dev, pm_message_t state,
-		u32 level)
+static int dummy_hcd_suspend (struct device *dev, pm_message_t state)
 {
 	struct usb_hcd		*hcd;
 
-	if (level != SUSPEND_DISABLE)
-		return 0;
-
 	dev_dbg (dev, "%s\n", __FUNCTION__);
 	hcd = dev_get_drvdata (dev);
 
@@ -1958,13 +1947,10 @@
 	return 0;
 }
 
-static int dummy_hcd_resume (struct device *dev, u32 level)
+static int dummy_hcd_resume (struct device *dev)
 {
 	struct usb_hcd		*hcd;
 
-	if (level != RESUME_ENABLE)
-		return 0;
-
 	dev_dbg (dev, "%s\n", __FUNCTION__);
 	hcd = dev_get_drvdata (dev);
 	hcd->state = HC_STATE_RUNNING;
diff --git a/drivers/usb/gadget/omap_udc.c b/drivers/usb/gadget/omap_udc.c
index 287c590..b7885dc 100644
--- a/drivers/usb/gadget/omap_udc.c
+++ b/drivers/usb/gadget/omap_udc.c
@@ -2909,12 +2909,10 @@
  * may involve talking to an external transceiver (e.g. isp1301).
  */
 
-static int omap_udc_suspend(struct device *dev, pm_message_t message, u32 level)
+static int omap_udc_suspend(struct device *dev, pm_message_t message)
 {
 	u32	devstat;
 
-	if (level != SUSPEND_POWER_DOWN)
-		return 0;
 	devstat = UDC_DEVSTAT_REG;
 
 	/* we're requesting 48 MHz clock if the pullup is enabled
@@ -2931,11 +2929,8 @@
 	return 0;
 }
 
-static int omap_udc_resume(struct device *dev, u32 level)
+static int omap_udc_resume(struct device *dev)
 {
-	if (level != RESUME_POWER_ON)
-		return 0;
-
 	DBG("resume + wakeup/SRP\n");
 	omap_pullup(&udc->gadget, 1);
 
diff --git a/drivers/usb/gadget/pxa2xx_udc.c b/drivers/usb/gadget/pxa2xx_udc.c
index 3d4d89c..6470285 100644
--- a/drivers/usb/gadget/pxa2xx_udc.c
+++ b/drivers/usb/gadget/pxa2xx_udc.c
@@ -2602,24 +2602,23 @@
  * VBUS IRQs should probably be ignored so that the PXA device just acts
  * "dead" to USB hosts until system resume.
  */
-static int pxa2xx_udc_suspend(struct device *dev, pm_message_t state, u32 level)
+static int pxa2xx_udc_suspend(struct device *dev, pm_message_t state)
 {
 	struct pxa2xx_udc	*udc = dev_get_drvdata(dev);
 
-	if (level == SUSPEND_POWER_DOWN) {
-		if (!udc->mach->udc_command)
-			WARN("USB host won't detect disconnect!\n");
-		pullup(udc, 0);
-	}
+	if (!udc->mach->udc_command)
+		WARN("USB host won't detect disconnect!\n");
+	pullup(udc, 0);
+
 	return 0;
 }
 
-static int pxa2xx_udc_resume(struct device *dev, u32 level)
+static int pxa2xx_udc_resume(struct device *dev)
 {
 	struct pxa2xx_udc	*udc = dev_get_drvdata(dev);
 
-	if (level == RESUME_POWER_ON)
-		pullup(udc, 1);
+	pullup(udc, 1);
+
 	return 0;
 }
 
diff --git a/drivers/usb/host/isp116x-hcd.c b/drivers/usb/host/isp116x-hcd.c
index 2548d94..642f350 100644
--- a/drivers/usb/host/isp116x-hcd.c
+++ b/drivers/usb/host/isp116x-hcd.c
@@ -1774,15 +1774,12 @@
 /*
   Suspend of platform device
 */
-static int isp116x_suspend(struct device *dev, pm_message_t state, u32 phase)
+static int isp116x_suspend(struct device *dev, pm_message_t state)
 {
 	int ret = 0;
 	struct usb_hcd *hcd = dev_get_drvdata(dev);
 
-	VDBG("%s: state %x, phase %x\n", __func__, state, phase);
-
-	if (phase != SUSPEND_DISABLE && phase != SUSPEND_POWER_DOWN)
-		return 0;
+	VDBG("%s: state %x\n", __func__, state);
 
 	ret = usb_suspend_device(hcd->self.root_hub, state);
 	if (!ret) {
@@ -1797,15 +1794,12 @@
 /*
   Resume platform device
 */
-static int isp116x_resume(struct device *dev, u32 phase)
+static int isp116x_resume(struct device *dev)
 {
 	int ret = 0;
 	struct usb_hcd *hcd = dev_get_drvdata(dev);
 
-	VDBG("%s:  state %x, phase %x\n", __func__, dev->power.power_state,
-	     phase);
-	if (phase != RESUME_POWER_ON)
-		return 0;
+	VDBG("%s:  state %x\n", __func__, dev->power.power_state);
 
 	ret = usb_resume_device(hcd->self.root_hub);
 	if (!ret) {
diff --git a/drivers/usb/host/ohci-omap.c b/drivers/usb/host/ohci-omap.c
index d8f3ba7..a574216 100644
--- a/drivers/usb/host/ohci-omap.c
+++ b/drivers/usb/host/ohci-omap.c
@@ -455,14 +455,11 @@
 
 #ifdef	CONFIG_PM
 
-static int ohci_omap_suspend(struct device *dev, pm_message_t message, u32 level)
+static int ohci_omap_suspend(struct device *dev, pm_message_t message)
 {
 	struct ohci_hcd	*ohci = hcd_to_ohci(dev_get_drvdata(dev));
 	int		status = -EINVAL;
 
-	if (level != SUSPEND_POWER_DOWN)
-		return 0;
-
 	down(&ohci_to_hcd(ohci)->self.root_hub->serialize);
 	status = ohci_hub_suspend(ohci_to_hcd(ohci));
 	if (status == 0) {
@@ -476,14 +473,11 @@
 	return status;
 }
 
-static int ohci_omap_resume(struct device *dev, u32 level)
+static int ohci_omap_resume(struct device *dev)
 {
 	struct ohci_hcd	*ohci = hcd_to_ohci(dev_get_drvdata(dev));
 	int		status = 0;
 
-	if (level != RESUME_POWER_ON)
-		return 0;
-
 	if (time_before(jiffies, ohci->next_statechange))
 		msleep(5);
 	ohci->next_statechange = jiffies;
diff --git a/drivers/usb/host/ohci-pxa27x.c b/drivers/usb/host/ohci-pxa27x.c
index 2fdb262..f042261 100644
--- a/drivers/usb/host/ohci-pxa27x.c
+++ b/drivers/usb/host/ohci-pxa27x.c
@@ -309,7 +309,7 @@
 	return 0;
 }
 
-static int ohci_hcd_pxa27x_drv_suspend(struct device *dev, pm_message_t state, u32 level)
+static int ohci_hcd_pxa27x_drv_suspend(struct device *dev, pm_message_t state)
 {
 //	struct platform_device *pdev = to_platform_device(dev);
 //	struct usb_hcd *hcd = dev_get_drvdata(dev);
@@ -318,7 +318,7 @@
 	return 0;
 }
 
-static int ohci_hcd_pxa27x_drv_resume(struct device *dev, u32 level)
+static int ohci_hcd_pxa27x_drv_resume(struct device *dev)
 {
 //	struct platform_device *pdev = to_platform_device(dev);
 //	struct usb_hcd *hcd = dev_get_drvdata(dev);
diff --git a/drivers/usb/host/sl811-hcd.c b/drivers/usb/host/sl811-hcd.c
index cad8585..b5e7a47 100644
--- a/drivers/usb/host/sl811-hcd.c
+++ b/drivers/usb/host/sl811-hcd.c
@@ -1784,15 +1784,12 @@
  */
 
 static int
-sl811h_suspend(struct device *dev, pm_message_t state, u32 phase)
+sl811h_suspend(struct device *dev, pm_message_t state)
 {
 	struct usb_hcd	*hcd = dev_get_drvdata(dev);
 	struct sl811	*sl811 = hcd_to_sl811(hcd);
 	int		retval = 0;
 
-	if (phase != SUSPEND_POWER_DOWN)
-		return retval;
-
 	if (state.event == PM_EVENT_FREEZE)
 		retval = sl811h_hub_suspend(hcd);
 	else if (state.event == PM_EVENT_SUSPEND)
@@ -1803,14 +1800,11 @@
 }
 
 static int
-sl811h_resume(struct device *dev, u32 phase)
+sl811h_resume(struct device *dev)
 {
 	struct usb_hcd	*hcd = dev_get_drvdata(dev);
 	struct sl811	*sl811 = hcd_to_sl811(hcd);
 
-	if (phase != RESUME_POWER_ON)
-		return 0;
-
 	/* with no "check to see if VBUS is still powered" board hook,
 	 * let's assume it'd only be powered to enable remote wakeup.
 	 */
diff --git a/drivers/usb/input/acecad.c b/drivers/usb/input/acecad.c
index 74f8760..a32558b 100644
--- a/drivers/usb/input/acecad.c
+++ b/drivers/usb/input/acecad.c
@@ -53,7 +53,7 @@
 	char name[128];
 	char phys[64];
 	struct usb_device *usbdev;
-	struct input_dev dev;
+	struct input_dev *input;
 	struct urb *irq;
 
 	signed char *data;
@@ -64,7 +64,7 @@
 {
 	struct usb_acecad *acecad = urb->context;
 	unsigned char *data = acecad->data;
-	struct input_dev *dev = &acecad->dev;
+	struct input_dev *dev = acecad->input;
 	int prox, status;
 
 	switch (urb->status) {
@@ -135,8 +135,8 @@
 	struct usb_host_interface *interface = intf->cur_altsetting;
 	struct usb_endpoint_descriptor *endpoint;
 	struct usb_acecad *acecad;
+	struct input_dev *input_dev;
 	int pipe, maxp;
-	char path[64];
 
 	if (interface->desc.bNumEndpoints != 1)
 		return -ENODEV;
@@ -153,8 +153,9 @@
 	maxp = usb_maxpacket(dev, pipe, usb_pipeout(pipe));
 
 	acecad = kzalloc(sizeof(struct usb_acecad), GFP_KERNEL);
-	if (!acecad)
-		return -ENOMEM;
+	input_dev = input_allocate_device();
+	if (!acecad || !input_dev)
+		goto fail1;
 
 	acecad->data = usb_buffer_alloc(dev, 8, SLAB_KERNEL, &acecad->data_dma);
 	if (!acecad->data)
@@ -164,6 +165,9 @@
 	if (!acecad->irq)
 		goto fail2;
 
+	acecad->usbdev = dev;
+	acecad->input = input_dev;
+
 	if (dev->manufacturer)
 		strlcpy(acecad->name, dev->manufacturer, sizeof(acecad->name));
 
@@ -173,48 +177,48 @@
 		strlcat(acecad->name, dev->product, sizeof(acecad->name));
 	}
 
-	usb_make_path(dev, path, sizeof(path));
-	snprintf(acecad->phys, sizeof(acecad->phys), "%s/input0", path);
+	usb_make_path(dev, acecad->phys, sizeof(acecad->phys));
+	strlcat(acecad->phys, "/input0", sizeof(acecad->phys));
 
-	acecad->usbdev = dev;
+	input_dev->name = acecad->name;
+	input_dev->phys = acecad->phys;
+	usb_to_input_id(dev, &input_dev->id);
+	input_dev->cdev.dev = &intf->dev;
+	input_dev->private = acecad;
 
-	acecad->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
-	acecad->dev.absbit[0] = BIT(ABS_X) | BIT(ABS_Y) | BIT(ABS_PRESSURE);
-	acecad->dev.keybit[LONG(BTN_LEFT)] = BIT(BTN_LEFT) | BIT(BTN_RIGHT) | BIT(BTN_MIDDLE);
-	acecad->dev.keybit[LONG(BTN_DIGI)] = BIT(BTN_TOOL_PEN) |BIT(BTN_TOUCH) | BIT(BTN_STYLUS) | BIT(BTN_STYLUS2);
+	input_dev->open = usb_acecad_open;
+	input_dev->close = usb_acecad_close;
+
+	input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
+	input_dev->absbit[0] = BIT(ABS_X) | BIT(ABS_Y) | BIT(ABS_PRESSURE);
+	input_dev->keybit[LONG(BTN_LEFT)] = BIT(BTN_LEFT) | BIT(BTN_RIGHT) | BIT(BTN_MIDDLE);
+	input_dev->keybit[LONG(BTN_DIGI)] = BIT(BTN_TOOL_PEN) |BIT(BTN_TOUCH) | BIT(BTN_STYLUS) | BIT(BTN_STYLUS2);
 
 	switch (id->driver_info) {
 		case 0:
-			acecad->dev.absmax[ABS_X] = 5000;
-			acecad->dev.absmax[ABS_Y] = 3750;
-			acecad->dev.absmax[ABS_PRESSURE] = 512;
+			input_dev->absmax[ABS_X] = 5000;
+			input_dev->absmax[ABS_Y] = 3750;
+			input_dev->absmax[ABS_PRESSURE] = 512;
 			if (!strlen(acecad->name))
 				snprintf(acecad->name, sizeof(acecad->name),
 					"USB Acecad Flair Tablet %04x:%04x",
-					dev->descriptor.idVendor, dev->descriptor.idProduct);
+					le16_to_cpu(dev->descriptor.idVendor),
+					le16_to_cpu(dev->descriptor.idProduct));
 			break;
 		case 1:
-			acecad->dev.absmax[ABS_X] = 3000;
-			acecad->dev.absmax[ABS_Y] = 2250;
-			acecad->dev.absmax[ABS_PRESSURE] = 1024;
+			input_dev->absmax[ABS_X] = 3000;
+			input_dev->absmax[ABS_Y] = 2250;
+			input_dev->absmax[ABS_PRESSURE] = 1024;
 			if (!strlen(acecad->name))
 				snprintf(acecad->name, sizeof(acecad->name),
 					"USB Acecad 302 Tablet %04x:%04x",
-					dev->descriptor.idVendor, dev->descriptor.idProduct);
+					le16_to_cpu(dev->descriptor.idVendor),
+					le16_to_cpu(dev->descriptor.idProduct));
 			break;
 	}
 
-	acecad->dev.absfuzz[ABS_X] = 4;
-	acecad->dev.absfuzz[ABS_Y] = 4;
-
-	acecad->dev.private = acecad;
-	acecad->dev.open = usb_acecad_open;
-	acecad->dev.close = usb_acecad_close;
-
-	acecad->dev.name = acecad->name;
-	acecad->dev.phys = acecad->phys;
-	usb_to_input_id(dev, &acecad->dev.id);
-	acecad->dev.dev = &intf->dev;
+	input_dev->absfuzz[ABS_X] = 4;
+	input_dev->absfuzz[ABS_Y] = 4;
 
 	usb_fill_int_urb(acecad->irq, dev, pipe,
 			acecad->data, maxp > 8 ? 8 : maxp,
@@ -222,17 +226,15 @@
 	acecad->irq->transfer_dma = acecad->data_dma;
 	acecad->irq->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
 
-	input_register_device(&acecad->dev);
-
-	printk(KERN_INFO "input: %s with packet size %d on %s\n",
-		acecad->name, maxp, path);
+	input_register_device(acecad->input);
 
 	usb_set_intfdata(intf, acecad);
 
 	return 0;
 
  fail2:	usb_buffer_free(dev, 8, acecad->data, acecad->data_dma);
- fail1:	kfree(acecad);
+ fail1: input_free_device(input_dev);
+	kfree(acecad);
 	return -ENOMEM;
 }
 
@@ -243,7 +245,7 @@
 	usb_set_intfdata(intf, NULL);
 	if (acecad) {
 		usb_kill_urb(acecad->irq);
-		input_unregister_device(&acecad->dev);
+		input_unregister_device(acecad->input);
 		usb_free_urb(acecad->irq);
 		usb_buffer_free(interface_to_usbdev(intf), 10, acecad->data, acecad->data_dma);
 		kfree(acecad);
diff --git a/drivers/usb/input/aiptek.c b/drivers/usb/input/aiptek.c
index cd0cbfe..1c52053 100644
--- a/drivers/usb/input/aiptek.c
+++ b/drivers/usb/input/aiptek.c
@@ -317,7 +317,7 @@
 };
 
 struct aiptek {
-	struct input_dev inputdev;		/* input device struct           */
+	struct input_dev *inputdev;		/* input device struct           */
 	struct usb_device *usbdev;		/* usb device struct             */
 	struct urb *urb;			/* urb for incoming reports      */
 	dma_addr_t data_dma;			/* our dma stuffage              */
@@ -402,7 +402,7 @@
 {
 	struct aiptek *aiptek = urb->context;
 	unsigned char *data = aiptek->data;
-	struct input_dev *inputdev = &aiptek->inputdev;
+	struct input_dev *inputdev = aiptek->inputdev;
 	int jitterable = 0;
 	int retval, macro, x, y, z, left, right, middle, p, dv, tip, bs, pck;
 
@@ -955,20 +955,20 @@
 	/* Query getXextension */
 	if ((ret = aiptek_query(aiptek, 0x01, 0x00)) < 0)
 		return ret;
-	aiptek->inputdev.absmin[ABS_X] = 0;
-	aiptek->inputdev.absmax[ABS_X] = ret - 1;
+	aiptek->inputdev->absmin[ABS_X] = 0;
+	aiptek->inputdev->absmax[ABS_X] = ret - 1;
 
 	/* Query getYextension */
 	if ((ret = aiptek_query(aiptek, 0x01, 0x01)) < 0)
 		return ret;
-	aiptek->inputdev.absmin[ABS_Y] = 0;
-	aiptek->inputdev.absmax[ABS_Y] = ret - 1;
+	aiptek->inputdev->absmin[ABS_Y] = 0;
+	aiptek->inputdev->absmax[ABS_Y] = ret - 1;
 
 	/* Query getPressureLevels */
 	if ((ret = aiptek_query(aiptek, 0x08, 0x00)) < 0)
 		return ret;
-	aiptek->inputdev.absmin[ABS_PRESSURE] = 0;
-	aiptek->inputdev.absmax[ABS_PRESSURE] = ret - 1;
+	aiptek->inputdev->absmin[ABS_PRESSURE] = 0;
+	aiptek->inputdev->absmax[ABS_PRESSURE] = ret - 1;
 
 	/* Depending on whether we are in absolute or relative mode, we will
 	 * do a switchToTablet(absolute) or switchToMouse(relative) command.
@@ -1025,8 +1025,8 @@
 		return 0;
 
 	return snprintf(buf, PAGE_SIZE, "%dx%d\n",
-			aiptek->inputdev.absmax[ABS_X] + 1,
-			aiptek->inputdev.absmax[ABS_Y] + 1);
+			aiptek->inputdev->absmax[ABS_X] + 1,
+			aiptek->inputdev->absmax[ABS_Y] + 1);
 }
 
 /* These structs define the sysfs files, param #1 is the name of the
@@ -1048,7 +1048,7 @@
 		return 0;
 
 	return snprintf(buf, PAGE_SIZE, "0x%04x\n",
-			aiptek->inputdev.id.product);
+			aiptek->inputdev->id.product);
 }
 
 static DEVICE_ATTR(product_id, S_IRUGO, show_tabletProductId, NULL);
@@ -1063,7 +1063,7 @@
 	if (aiptek == NULL)
 		return 0;
 
-	return snprintf(buf, PAGE_SIZE, "0x%04x\n", aiptek->inputdev.id.vendor);
+	return snprintf(buf, PAGE_SIZE, "0x%04x\n", aiptek->inputdev->id.vendor);
 }
 
 static DEVICE_ATTR(vendor_id, S_IRUGO, show_tabletVendorId, NULL);
@@ -1977,7 +1977,6 @@
 	struct input_dev *inputdev;
 	struct input_handle *inputhandle;
 	struct list_head *node, *next;
-	char path[64 + 1];
 	int i;
 	int speeds[] = { 0,
 		AIPTEK_PROGRAMMABLE_DELAY_50,
@@ -1996,24 +1995,26 @@
 	 */
 	speeds[0] = programmableDelay;
 
-	if ((aiptek = kmalloc(sizeof(struct aiptek), GFP_KERNEL)) == NULL)
-		return -ENOMEM;
-	memset(aiptek, 0, sizeof(struct aiptek));
+	aiptek = kzalloc(sizeof(struct aiptek), GFP_KERNEL);
+	inputdev = input_allocate_device();
+	if (!aiptek || !inputdev)
+		goto fail1;
 
 	aiptek->data = usb_buffer_alloc(usbdev, AIPTEK_PACKET_LENGTH,
 					SLAB_ATOMIC, &aiptek->data_dma);
-	if (aiptek->data == NULL) {
-		kfree(aiptek);
-		return -ENOMEM;
-	}
+	if (!aiptek->data)
+		goto fail1;
 
 	aiptek->urb = usb_alloc_urb(0, GFP_KERNEL);
-	if (aiptek->urb == NULL) {
-		usb_buffer_free(usbdev, AIPTEK_PACKET_LENGTH, aiptek->data,
-				aiptek->data_dma);
-		kfree(aiptek);
-		return -ENOMEM;
-	}
+	if (!aiptek->urb)
+		goto fail2;
+
+	aiptek->inputdev = inputdev;
+	aiptek->usbdev = usbdev;
+	aiptek->ifnum = intf->altsetting[0].desc.bInterfaceNumber;
+	aiptek->inDelay = 0;
+	aiptek->endDelay = 0;
+	aiptek->previousJitterable = 0;
 
 	/* Set up the curSettings struct. Said struct contains the current
 	 * programmable parameters. The newSetting struct contains changes
@@ -2036,31 +2037,48 @@
 
 	/* Both structs should have equivalent settings
 	 */
-	memcpy(&aiptek->newSetting, &aiptek->curSetting,
-	       sizeof(struct aiptek_settings));
+	aiptek->newSetting = aiptek->curSetting;
+
+	/* Determine the usb devices' physical path.
+	 * Asketh not why we always pretend we're using "../input0",
+	 * but I suspect this will have to be refactored one
+	 * day if a single USB device can be a keyboard & a mouse
+	 * & a tablet, and the inputX number actually will tell
+	 * us something...
+	 */
+	usb_make_path(usbdev, aiptek->features.usbPath,
+			sizeof(aiptek->features.usbPath));
+	strlcat(aiptek->features.usbPath, "/input0",
+		sizeof(aiptek->features.usbPath));
+
+	/* Set up client data, pointers to open and close routines
+	 * for the input device.
+	 */
+	inputdev->name = "Aiptek";
+	inputdev->phys = aiptek->features.usbPath;
+	usb_to_input_id(usbdev, &inputdev->id);
+	inputdev->cdev.dev = &intf->dev;
+	inputdev->private = aiptek;
+	inputdev->open = aiptek_open;
+	inputdev->close = aiptek_close;
 
 	/* Now program the capacities of the tablet, in terms of being
 	 * an input device.
 	 */
-	aiptek->inputdev.evbit[0] |= BIT(EV_KEY)
+	inputdev->evbit[0] |= BIT(EV_KEY)
 	    | BIT(EV_ABS)
 	    | BIT(EV_REL)
 	    | BIT(EV_MSC);
 
-	aiptek->inputdev.absbit[0] |=
-	    (BIT(ABS_X) |
-	     BIT(ABS_Y) |
-	     BIT(ABS_PRESSURE) |
-	     BIT(ABS_TILT_X) |
-	     BIT(ABS_TILT_Y) | BIT(ABS_WHEEL) | BIT(ABS_MISC));
+	inputdev->absbit[0] |= BIT(ABS_MISC);
 
-	aiptek->inputdev.relbit[0] |=
+	inputdev->relbit[0] |=
 	    (BIT(REL_X) | BIT(REL_Y) | BIT(REL_WHEEL) | BIT(REL_MISC));
 
-	aiptek->inputdev.keybit[LONG(BTN_LEFT)] |=
+	inputdev->keybit[LONG(BTN_LEFT)] |=
 	    (BIT(BTN_LEFT) | BIT(BTN_RIGHT) | BIT(BTN_MIDDLE));
 
-	aiptek->inputdev.keybit[LONG(BTN_DIGI)] |=
+	inputdev->keybit[LONG(BTN_DIGI)] |=
 	    (BIT(BTN_TOOL_PEN) |
 	     BIT(BTN_TOOL_RUBBER) |
 	     BIT(BTN_TOOL_PENCIL) |
@@ -2070,70 +2088,26 @@
 	     BIT(BTN_TOOL_LENS) |
 	     BIT(BTN_TOUCH) | BIT(BTN_STYLUS) | BIT(BTN_STYLUS2));
 
-	aiptek->inputdev.mscbit[0] = BIT(MSC_SERIAL);
+	inputdev->mscbit[0] = BIT(MSC_SERIAL);
 
 	/* Programming the tablet macro keys needs to be done with a for loop
 	 * as the keycodes are discontiguous.
 	 */
 	for (i = 0; i < sizeof(macroKeyEvents) / sizeof(macroKeyEvents[0]); ++i)
-		set_bit(macroKeyEvents[i], aiptek->inputdev.keybit);
+		set_bit(macroKeyEvents[i], inputdev->keybit);
 
-	/* Set up client data, pointers to open and close routines
-	 * for the input device.
-	 */
-	aiptek->inputdev.private = aiptek;
-	aiptek->inputdev.open = aiptek_open;
-	aiptek->inputdev.close = aiptek_close;
-
-	/* Determine the usb devices' physical path.
-	 * Asketh not why we always pretend we're using "../input0",
-	 * but I suspect this will have to be refactored one
-	 * day if a single USB device can be a keyboard & a mouse
-	 * & a tablet, and the inputX number actually will tell
-	 * us something...
-	 */
-	if (usb_make_path(usbdev, path, 64) > 0)
-		sprintf(aiptek->features.usbPath, "%s/input0", path);
-
-	/* Program the input device coordinate capacities. We do not yet
+	/*
+	 * Program the input device coordinate capacities. We do not yet
 	 * know what maximum X, Y, and Z values are, so we're putting fake
 	 * values in. Later, we'll ask the tablet to put in the correct
 	 * values.
 	 */
-	aiptek->inputdev.absmin[ABS_X] = 0;
-	aiptek->inputdev.absmax[ABS_X] = 2999;
-	aiptek->inputdev.absmin[ABS_Y] = 0;
-	aiptek->inputdev.absmax[ABS_Y] = 2249;
-	aiptek->inputdev.absmin[ABS_PRESSURE] = 0;
-	aiptek->inputdev.absmax[ABS_PRESSURE] = 511;
-	aiptek->inputdev.absmin[ABS_TILT_X] = AIPTEK_TILT_MIN;
-	aiptek->inputdev.absmax[ABS_TILT_X] = AIPTEK_TILT_MAX;
-	aiptek->inputdev.absmin[ABS_TILT_Y] = AIPTEK_TILT_MIN;
-	aiptek->inputdev.absmax[ABS_TILT_Y] = AIPTEK_TILT_MAX;
-	aiptek->inputdev.absmin[ABS_WHEEL] = AIPTEK_WHEEL_MIN;
-	aiptek->inputdev.absmax[ABS_WHEEL] = AIPTEK_WHEEL_MAX - 1;
-	aiptek->inputdev.absfuzz[ABS_X] = 0;
-	aiptek->inputdev.absfuzz[ABS_Y] = 0;
-	aiptek->inputdev.absfuzz[ABS_PRESSURE] = 0;
-	aiptek->inputdev.absfuzz[ABS_TILT_X] = 0;
-	aiptek->inputdev.absfuzz[ABS_TILT_Y] = 0;
-	aiptek->inputdev.absfuzz[ABS_WHEEL] = 0;
-	aiptek->inputdev.absflat[ABS_X] = 0;
-	aiptek->inputdev.absflat[ABS_Y] = 0;
-	aiptek->inputdev.absflat[ABS_PRESSURE] = 0;
-	aiptek->inputdev.absflat[ABS_TILT_X] = 0;
-	aiptek->inputdev.absflat[ABS_TILT_Y] = 0;
-	aiptek->inputdev.absflat[ABS_WHEEL] = 0;
-	aiptek->inputdev.name = "Aiptek";
-	aiptek->inputdev.phys = aiptek->features.usbPath;
-	usb_to_input_id(usbdev, &aiptek->inputdev.id);
-	aiptek->inputdev.dev = &intf->dev;
-
-	aiptek->usbdev = usbdev;
-	aiptek->ifnum = intf->altsetting[0].desc.bInterfaceNumber;
-	aiptek->inDelay = 0;
-	aiptek->endDelay = 0;
-	aiptek->previousJitterable = 0;
+	input_set_abs_params(inputdev, ABS_X, 0, 2999, 0, 0);
+	input_set_abs_params(inputdev, ABS_X, 0, 2249, 0, 0);
+	input_set_abs_params(inputdev, ABS_PRESSURE, 0, 511, 0, 0);
+	input_set_abs_params(inputdev, ABS_TILT_X, AIPTEK_TILT_MIN, AIPTEK_TILT_MAX, 0, 0);
+	input_set_abs_params(inputdev, ABS_TILT_Y, AIPTEK_TILT_MIN, AIPTEK_TILT_MAX, 0, 0);
+	input_set_abs_params(inputdev, ABS_WHEEL, AIPTEK_WHEEL_MIN, AIPTEK_WHEEL_MAX - 1, 0, 0);
 
 	endpoint = &intf->altsetting[0].endpoint[0].desc;
 
@@ -2150,28 +2124,6 @@
 	aiptek->urb->transfer_dma = aiptek->data_dma;
 	aiptek->urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
 
-	/* Register the tablet as an Input Device
-	 */
-	input_register_device(&aiptek->inputdev);
-
-	/* We now will look for the evdev device which is mapped to
-	 * the tablet. The partial name is kept in the link list of
-	 * input_handles associated with this input device.
-	 * What identifies an evdev input_handler is that it begins
-	 * with 'event', continues with a digit, and that in turn
-	 * is mapped to /{devfs}/input/eventN.
-	 */
-	inputdev = &aiptek->inputdev;
-	list_for_each_safe(node, next, &inputdev->h_list) {
-		inputhandle = to_handle(node);
-		if (strncmp(inputhandle->name, "event", 5) == 0) {
-			strcpy(aiptek->features.inputPath, inputhandle->name);
-			break;
-		}
-	}
-
-	info("input: Aiptek on %s (%s)\n", path, aiptek->features.inputPath);
-
 	/* Program the tablet. This sets the tablet up in the mode
 	 * specified in newSetting, and also queries the tablet's
 	 * physical capacities.
@@ -2186,13 +2138,32 @@
 	for (i = 0; i < sizeof(speeds) / sizeof(speeds[0]); ++i) {
 		aiptek->curSetting.programmableDelay = speeds[i];
 		(void)aiptek_program_tablet(aiptek);
-		if (aiptek->inputdev.absmax[ABS_X] > 0) {
+		if (aiptek->inputdev->absmax[ABS_X] > 0) {
 			info("input: Aiptek using %d ms programming speed\n",
 			     aiptek->curSetting.programmableDelay);
 			break;
 		}
 	}
 
+	/* Register the tablet as an Input Device
+	 */
+	input_register_device(aiptek->inputdev);
+
+	/* We now will look for the evdev device which is mapped to
+	 * the tablet. The partial name is kept in the link list of
+	 * input_handles associated with this input device.
+	 * What identifies an evdev input_handler is that it begins
+	 * with 'event', continues with a digit, and that in turn
+	 * is mapped to /{devfs}/input/eventN.
+	 */
+	list_for_each_safe(node, next, &inputdev->h_list) {
+		inputhandle = to_handle(node);
+		if (strncmp(inputhandle->name, "event", 5) == 0) {
+			strcpy(aiptek->features.inputPath, inputhandle->name);
+			break;
+		}
+	}
+
 	/* Associate this driver's struct with the usb interface.
 	 */
 	usb_set_intfdata(intf, aiptek);
@@ -2207,6 +2178,12 @@
 		info("aiptek: error loading 'evdev' module");
 
 	return 0;
+
+fail2:	usb_buffer_free(usbdev, AIPTEK_PACKET_LENGTH, aiptek->data,
+			aiptek->data_dma);
+fail1:	input_free_device(inputdev);
+	kfree(aiptek);
+	return -ENOMEM;
 }
 
 /* Forward declaration */
@@ -2234,7 +2211,7 @@
 		/* Free & unhook everything from the system.
 		 */
 		usb_kill_urb(aiptek->urb);
-		input_unregister_device(&aiptek->inputdev);
+		input_unregister_device(aiptek->inputdev);
 		aiptek_delete_files(&intf->dev);
 		usb_free_urb(aiptek->urb);
 		usb_buffer_free(interface_to_usbdev(intf),
diff --git a/drivers/usb/input/appletouch.c b/drivers/usb/input/appletouch.c
index e03c1c5..15840db 100644
--- a/drivers/usb/input/appletouch.c
+++ b/drivers/usb/input/appletouch.c
@@ -39,7 +39,7 @@
 #define APPLE_VENDOR_ID		0x05AC
 
 #define ATP_DEVICE(prod)					\
-	.match_flags = USB_DEVICE_ID_MATCH_DEVICE |   		\
+	.match_flags = USB_DEVICE_ID_MATCH_DEVICE |		\
 		       USB_DEVICE_ID_MATCH_INT_CLASS |		\
 		       USB_DEVICE_ID_MATCH_INT_PROTOCOL,	\
 	.idVendor = APPLE_VENDOR_ID,				\
@@ -78,9 +78,9 @@
  * We try to keep the touchpad aspect ratio while still doing only simple
  * arithmetics.
  * The factors below give coordinates like:
- * 	0 <= x <  960 on 12" and 15" Powerbooks
- * 	0 <= x < 1600 on 17" Powerbooks
- * 	0 <= y <  646
+ *	0 <= x <  960 on 12" and 15" Powerbooks
+ *	0 <= x < 1600 on 17" Powerbooks
+ *	0 <= y <  646
  */
 #define ATP_XFACT	64
 #define ATP_YFACT	43
@@ -93,11 +93,12 @@
 
 /* Structure to hold all of our device specific stuff */
 struct atp {
+	char			phys[64];
 	struct usb_device *	udev;		/* usb device */
 	struct urb *		urb;		/* usb request block */
 	signed char *		data;		/* transferred data */
 	int			open;		/* non-zero if opened */
-	struct input_dev	input;		/* input dev */
+	struct input_dev	*input;		/* input dev */
 	int			valid;		/* are the sensors valid ? */
 	int			x_old;		/* last reported x/y, */
 	int			y_old;		/* used for smoothing */
@@ -114,11 +115,11 @@
 		int i;							\
 		printk("appletouch: %s %lld", msg, (long long)jiffies); \
 		for (i = 0; i < ATP_XSENSORS + ATP_YSENSORS; i++)	\
-			printk(" %02x", tab[i]); 			\
-		printk("\n"); 						\
+			printk(" %02x", tab[i]);			\
+		printk("\n");						\
 	}
 
-#define dprintk(format, a...) 						\
+#define dprintk(format, a...)						\
 	do {								\
 		if (debug) printk(format, ##a);				\
 	} while (0)
@@ -219,8 +220,8 @@
 		for (i = 16; i < ATP_XSENSORS; i++)
 			if (dev->xy_cur[i]) {
 				printk("appletouch: 17\" model detected.\n");
-				input_set_abs_params(&dev->input, ABS_X, 0,
-				     		     (ATP_XSENSORS - 1) *
+				input_set_abs_params(dev->input, ABS_X, 0,
+						     (ATP_XSENSORS - 1) *
 						     ATP_XFACT - 1,
 						     ATP_FUZZ, 0);
 				break;
@@ -260,12 +261,12 @@
 				       "Xz: %3d Yz: %3d\n",
 				       x, y, x_z, y_z);
 
-			input_report_key(&dev->input, BTN_TOUCH, 1);
-			input_report_abs(&dev->input, ABS_X, x);
-			input_report_abs(&dev->input, ABS_Y, y);
-			input_report_abs(&dev->input, ABS_PRESSURE,
+			input_report_key(dev->input, BTN_TOUCH, 1);
+			input_report_abs(dev->input, ABS_X, x);
+			input_report_abs(dev->input, ABS_Y, y);
+			input_report_abs(dev->input, ABS_PRESSURE,
 					 min(ATP_PRESSURE, x_z + y_z));
-			atp_report_fingers(&dev->input, max(x_f, y_f));
+			atp_report_fingers(dev->input, max(x_f, y_f));
 		}
 		dev->x_old = x;
 		dev->y_old = y;
@@ -273,17 +274,17 @@
 	else if (!x && !y) {
 
 		dev->x_old = dev->y_old = -1;
-		input_report_key(&dev->input, BTN_TOUCH, 0);
-		input_report_abs(&dev->input, ABS_PRESSURE, 0);
-		atp_report_fingers(&dev->input, 0);
+		input_report_key(dev->input, BTN_TOUCH, 0);
+		input_report_abs(dev->input, ABS_PRESSURE, 0);
+		atp_report_fingers(dev->input, 0);
 
 		/* reset the accumulator on release */
 		memset(dev->xy_acc, 0, sizeof(dev->xy_acc));
 	}
 
-	input_report_key(&dev->input, BTN_LEFT, !!dev->data[80]);
+	input_report_key(dev->input, BTN_LEFT, !!dev->data[80]);
 
-	input_sync(&dev->input);
+	input_sync(dev->input);
 
 exit:
 	retval = usb_submit_urb(dev->urb, GFP_ATOMIC);
@@ -314,21 +315,14 @@
 
 static int atp_probe(struct usb_interface *iface, const struct usb_device_id *id)
 {
-	struct atp *dev = NULL;
+	struct atp *dev;
+	struct input_dev *input_dev;
+	struct usb_device *udev = interface_to_usbdev(iface);
 	struct usb_host_interface *iface_desc;
 	struct usb_endpoint_descriptor *endpoint;
 	int int_in_endpointAddr = 0;
 	int i, retval = -ENOMEM;
 
-	/* allocate memory for our device state and initialize it */
-	dev = kmalloc(sizeof(struct atp), GFP_KERNEL);
-	if (dev == NULL) {
-		err("Out of memory");
-		goto err_kmalloc;
-	}
-	memset(dev, 0, sizeof(struct atp));
-
-	dev->udev = interface_to_usbdev(iface);
 
 	/* set up the endpoint information */
 	/* use only the first interrupt-in endpoint */
@@ -345,70 +339,82 @@
 		}
 	}
 	if (!int_in_endpointAddr) {
-		retval = -EIO;
 		err("Could not find int-in endpoint");
-		goto err_endpoint;
+		return -EIO;
 	}
 
-	/* save our data pointer in this interface device */
-	usb_set_intfdata(iface, dev);
+	/* allocate memory for our device state and initialize it */
+	dev = kzalloc(sizeof(struct atp), GFP_KERNEL);
+	input_dev = input_allocate_device();
+	if (!dev || !input_dev) {
+		err("Out of memory");
+		goto err_free_devs;
+	}
+
+	dev->udev = udev;
+	dev->input = input_dev;
 
 	dev->urb = usb_alloc_urb(0, GFP_KERNEL);
 	if (!dev->urb) {
 		retval = -ENOMEM;
-		goto err_usballoc;
+		goto err_free_devs;
 	}
+
 	dev->data = usb_buffer_alloc(dev->udev, ATP_DATASIZE, GFP_KERNEL,
 				     &dev->urb->transfer_dma);
 	if (!dev->data) {
 		retval = -ENOMEM;
-		goto err_usbbufalloc;
+		goto err_free_urb;
 	}
-	usb_fill_int_urb(dev->urb, dev->udev,
-			 usb_rcvintpipe(dev->udev, int_in_endpointAddr),
+
+	usb_fill_int_urb(dev->urb, udev,
+			 usb_rcvintpipe(udev, int_in_endpointAddr),
 			 dev->data, ATP_DATASIZE, atp_complete, dev, 1);
 
-	init_input_dev(&dev->input);
-	dev->input.name = "appletouch";
-	dev->input.dev = &iface->dev;
-	dev->input.private = dev;
-	dev->input.open = atp_open;
-	dev->input.close = atp_close;
+	usb_make_path(udev, dev->phys, sizeof(dev->phys));
+	strlcat(dev->phys, "/input0", sizeof(dev->phys));
 
-	usb_to_input_id(dev->udev, &dev->input.id);
+	input_dev->name = "appletouch";
+	input_dev->phys = dev->phys;
+	usb_to_input_id(dev->udev, &input_dev->id);
+	input_dev->cdev.dev = &iface->dev;
 
-	set_bit(EV_ABS, dev->input.evbit);
+	input_dev->private = dev;
+	input_dev->open = atp_open;
+	input_dev->close = atp_close;
+
+	set_bit(EV_ABS, input_dev->evbit);
 
 	/*
 	 * 12" and 15" Powerbooks only have 16 x sensors,
 	 * 17" models are detected later.
 	 */
-	input_set_abs_params(&dev->input, ABS_X, 0,
+	input_set_abs_params(input_dev, ABS_X, 0,
 			     (16 - 1) * ATP_XFACT - 1, ATP_FUZZ, 0);
-	input_set_abs_params(&dev->input, ABS_Y, 0,
+	input_set_abs_params(input_dev, ABS_Y, 0,
 			     (ATP_YSENSORS - 1) * ATP_YFACT - 1, ATP_FUZZ, 0);
-	input_set_abs_params(&dev->input, ABS_PRESSURE, 0, ATP_PRESSURE, 0, 0);
+	input_set_abs_params(input_dev, ABS_PRESSURE, 0, ATP_PRESSURE, 0, 0);
 
-	set_bit(EV_KEY, dev->input.evbit);
-	set_bit(BTN_TOUCH, dev->input.keybit);
-	set_bit(BTN_TOOL_FINGER, dev->input.keybit);
-	set_bit(BTN_TOOL_DOUBLETAP, dev->input.keybit);
-	set_bit(BTN_TOOL_TRIPLETAP, dev->input.keybit);
-	set_bit(BTN_LEFT, dev->input.keybit);
+	set_bit(EV_KEY, input_dev->evbit);
+	set_bit(BTN_TOUCH, input_dev->keybit);
+	set_bit(BTN_TOOL_FINGER, input_dev->keybit);
+	set_bit(BTN_TOOL_DOUBLETAP, input_dev->keybit);
+	set_bit(BTN_TOOL_TRIPLETAP, input_dev->keybit);
+	set_bit(BTN_LEFT, input_dev->keybit);
 
-	input_register_device(&dev->input);
+	input_register_device(dev->input);
 
-	printk(KERN_INFO "input: appletouch connected\n");
+	/* save our data pointer in this interface device */
+	usb_set_intfdata(iface, dev);
 
 	return 0;
 
-err_usbbufalloc:
+ err_free_urb:
 	usb_free_urb(dev->urb);
-err_usballoc:
+ err_free_devs:
 	usb_set_intfdata(iface, NULL);
-err_endpoint:
 	kfree(dev);
-err_kmalloc:
+	input_free_device(input_dev);
 	return retval;
 }
 
@@ -419,7 +425,7 @@
 	usb_set_intfdata(iface, NULL);
 	if (dev) {
 		usb_kill_urb(dev->urb);
-		input_unregister_device(&dev->input);
+		input_unregister_device(dev->input);
 		usb_free_urb(dev->urb);
 		usb_buffer_free(dev->udev, ATP_DATASIZE,
 				dev->data, dev->urb->transfer_dma);
diff --git a/drivers/usb/input/ati_remote.c b/drivers/usb/input/ati_remote.c
index fd99681..9a2a47d 100644
--- a/drivers/usb/input/ati_remote.c
+++ b/drivers/usb/input/ati_remote.c
@@ -112,7 +112,6 @@
 
 #define NAME_BUFSIZE      80    /* size of product name, path buffers */
 #define DATA_BUFSIZE      63    /* size of URB data buffers */
-#define ATI_INPUTNUM      1     /* Which input device to register as */
 
 static unsigned long channel_mask;
 module_param(channel_mask, ulong, 0444);
@@ -162,7 +161,7 @@
 static DECLARE_MUTEX(disconnect_sem);
 
 struct ati_remote {
-	struct input_dev idev;
+	struct input_dev *idev;
 	struct usb_device *udev;
 	struct usb_interface *interface;
 
@@ -198,15 +197,13 @@
 #define KIND_ACCEL      7   /* Directional keypad - left, right, up, down.*/
 
 /* Translation table from hardware messages to input events. */
-static struct
-{
+static struct {
 	short kind;
 	unsigned char data1, data2;
 	int type;
 	unsigned int code;
 	int value;
-}  ati_remote_tbl[] =
-{
+}  ati_remote_tbl[] = {
 	/* Directional control pad axes */
 	{KIND_ACCEL,   0x35, 0x70, EV_REL, REL_X, -1},	 /* left */
 	{KIND_ACCEL,   0x36, 0x71, EV_REL, REL_X, 1},    /* right */
@@ -286,7 +283,6 @@
 
 /* Local function prototypes */
 static void ati_remote_dump		(unsigned char *data, unsigned int actual_length);
-static void ati_remote_delete		(struct ati_remote *dev);
 static int ati_remote_open		(struct input_dev *inputdev);
 static void ati_remote_close		(struct input_dev *inputdev);
 static int ati_remote_sendpacket	(struct ati_remote *ati_remote, u16 cmd, unsigned char *data);
@@ -428,7 +424,7 @@
 {
 	struct ati_remote *ati_remote = urb->context;
 	unsigned char *data= ati_remote->inbuf;
-	struct input_dev *dev = &ati_remote->idev;
+	struct input_dev *dev = ati_remote->idev;
 	int index, acc;
 	int remote_num;
 
@@ -587,17 +583,42 @@
 }
 
 /*
- *	ati_remote_delete
+ *	ati_remote_alloc_buffers
  */
-static void ati_remote_delete(struct ati_remote *ati_remote)
+static int ati_remote_alloc_buffers(struct usb_device *udev,
+				    struct ati_remote *ati_remote)
+{
+	ati_remote->inbuf = usb_buffer_alloc(udev, DATA_BUFSIZE, SLAB_ATOMIC,
+					     &ati_remote->inbuf_dma);
+	if (!ati_remote->inbuf)
+		return -1;
+
+	ati_remote->outbuf = usb_buffer_alloc(udev, DATA_BUFSIZE, SLAB_ATOMIC,
+					      &ati_remote->outbuf_dma);
+	if (!ati_remote->outbuf)
+		return -1;
+
+	ati_remote->irq_urb = usb_alloc_urb(0, GFP_KERNEL);
+	if (!ati_remote->irq_urb)
+		return -1;
+
+	ati_remote->out_urb = usb_alloc_urb(0, GFP_KERNEL);
+	if (!ati_remote->out_urb)
+		return -1;
+
+	return 0;
+}
+
+/*
+ *	ati_remote_free_buffers
+ */
+static void ati_remote_free_buffers(struct ati_remote *ati_remote)
 {
 	if (ati_remote->irq_urb)
-		usb_kill_urb(ati_remote->irq_urb);
+		usb_free_urb(ati_remote->irq_urb);
 
 	if (ati_remote->out_urb)
-		usb_kill_urb(ati_remote->out_urb);
-
-	input_unregister_device(&ati_remote->idev);
+		usb_free_urb(ati_remote->out_urb);
 
 	if (ati_remote->inbuf)
 		usb_buffer_free(ati_remote->udev, DATA_BUFSIZE,
@@ -605,20 +626,12 @@
 
 	if (ati_remote->outbuf)
 		usb_buffer_free(ati_remote->udev, DATA_BUFSIZE,
-				ati_remote->outbuf, ati_remote->outbuf_dma);
-
-	if (ati_remote->irq_urb)
-		usb_free_urb(ati_remote->irq_urb);
-
-	if (ati_remote->out_urb)
-		usb_free_urb(ati_remote->out_urb);
-
-	kfree(ati_remote);
+				ati_remote->inbuf, ati_remote->outbuf_dma);
 }
 
 static void ati_remote_input_init(struct ati_remote *ati_remote)
 {
-	struct input_dev *idev = &(ati_remote->idev);
+	struct input_dev *idev = ati_remote->idev;
 	int i;
 
 	idev->evbit[0] = BIT(EV_KEY) | BIT(EV_REL);
@@ -637,7 +650,7 @@
 	idev->phys = ati_remote->phys;
 
 	usb_to_input_id(ati_remote->udev, &idev->id);
-	idev->dev = &ati_remote->udev->dev;
+	idev->cdev.dev = &ati_remote->udev->dev;
 }
 
 static int ati_remote_initialize(struct ati_remote *ati_remote)
@@ -674,7 +687,7 @@
 	    (ati_remote_sendpacket(ati_remote, 0x8007, init2))) {
 		dev_err(&ati_remote->interface->dev,
 			 "Initializing ati_remote hardware failed.\n");
-		return 1;
+		return -EIO;
 	}
 
 	return 0;
@@ -686,95 +699,83 @@
 static int ati_remote_probe(struct usb_interface *interface, const struct usb_device_id *id)
 {
 	struct usb_device *udev = interface_to_usbdev(interface);
-	struct ati_remote *ati_remote = NULL;
-	struct usb_host_interface *iface_host;
-	int retval = -ENOMEM;
-	char path[64];
+	struct usb_host_interface *iface_host = interface->cur_altsetting;
+	struct usb_endpoint_descriptor *endpoint_in, *endpoint_out;
+	struct ati_remote *ati_remote;
+	struct input_dev *input_dev;
+	int err = -ENOMEM;
 
-	/* Allocate and clear an ati_remote struct */
-	if (!(ati_remote = kmalloc(sizeof (struct ati_remote), GFP_KERNEL)))
-		return -ENOMEM;
-	memset(ati_remote, 0x00, sizeof (struct ati_remote));
-
-	iface_host = interface->cur_altsetting;
 	if (iface_host->desc.bNumEndpoints != 2) {
 		err("%s: Unexpected desc.bNumEndpoints\n", __FUNCTION__);
-		retval = -ENODEV;
-		goto error;
+		return -ENODEV;
 	}
 
-	ati_remote->endpoint_in = &(iface_host->endpoint[0].desc);
-	ati_remote->endpoint_out = &(iface_host->endpoint[1].desc);
-	ati_remote->udev = udev;
-	ati_remote->interface = interface;
+	endpoint_in = &iface_host->endpoint[0].desc;
+	endpoint_out = &iface_host->endpoint[1].desc;
 
-	if (!(ati_remote->endpoint_in->bEndpointAddress & 0x80)) {
+	if (!(endpoint_in->bEndpointAddress & USB_DIR_IN)) {
 		err("%s: Unexpected endpoint_in->bEndpointAddress\n", __FUNCTION__);
-		retval = -ENODEV;
-		goto error;
+		return -ENODEV;
 	}
-	if ((ati_remote->endpoint_in->bmAttributes & 3) != 3) {
+	if ((endpoint_in->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) != USB_ENDPOINT_XFER_INT) {
 		err("%s: Unexpected endpoint_in->bmAttributes\n", __FUNCTION__);
-		retval = -ENODEV;
-		goto error;
+		return -ENODEV;
 	}
-	if (le16_to_cpu(ati_remote->endpoint_in->wMaxPacketSize) == 0) {
+	if (le16_to_cpu(endpoint_in->wMaxPacketSize) == 0) {
 		err("%s: endpoint_in message size==0? \n", __FUNCTION__);
-		retval = -ENODEV;
-		goto error;
+		return -ENODEV;
 	}
 
+	ati_remote = kzalloc(sizeof (struct ati_remote), GFP_KERNEL);
+	input_dev = input_allocate_device();
+	if (!ati_remote || !input_dev)
+		goto fail1;
+
 	/* Allocate URB buffers, URBs */
-	ati_remote->inbuf = usb_buffer_alloc(udev, DATA_BUFSIZE, SLAB_ATOMIC,
-					     &ati_remote->inbuf_dma);
-	if (!ati_remote->inbuf)
-		goto error;
+	if (ati_remote_alloc_buffers(udev, ati_remote))
+		goto fail2;
 
-	ati_remote->outbuf = usb_buffer_alloc(udev, DATA_BUFSIZE, SLAB_ATOMIC,
-					      &ati_remote->outbuf_dma);
-	if (!ati_remote->outbuf)
-		goto error;
+	ati_remote->endpoint_in = endpoint_in;
+	ati_remote->endpoint_out = endpoint_out;
+	ati_remote->udev = udev;
+	ati_remote->idev = input_dev;
+	ati_remote->interface = interface;
 
-	ati_remote->irq_urb = usb_alloc_urb(0, GFP_KERNEL);
-	if (!ati_remote->irq_urb)
-		goto error;
+	usb_make_path(udev, ati_remote->phys, sizeof(ati_remote->phys));
+	strlcpy(ati_remote->phys, "/input0", sizeof(ati_remote->phys));
 
-	ati_remote->out_urb = usb_alloc_urb(0, GFP_KERNEL);
-	if (!ati_remote->out_urb)
-		goto error;
-
-	usb_make_path(udev, path, NAME_BUFSIZE);
-	sprintf(ati_remote->phys, "%s/input%d", path, ATI_INPUTNUM);
 	if (udev->manufacturer)
-		strcat(ati_remote->name, udev->manufacturer);
+		strlcpy(ati_remote->name, udev->manufacturer, sizeof(ati_remote->name));
 
 	if (udev->product)
-		sprintf(ati_remote->name, "%s %s", ati_remote->name, udev->product);
+		snprintf(ati_remote->name, sizeof(ati_remote->name),
+			 "%s %s", ati_remote->name, udev->product);
 
 	if (!strlen(ati_remote->name))
-		sprintf(ati_remote->name, DRIVER_DESC "(%04x,%04x)",
+		snprintf(ati_remote->name, sizeof(ati_remote->name),
+			DRIVER_DESC "(%04x,%04x)",
 			le16_to_cpu(ati_remote->udev->descriptor.idVendor),
 			le16_to_cpu(ati_remote->udev->descriptor.idProduct));
 
+	ati_remote_input_init(ati_remote);
+
 	/* Device Hardware Initialization - fills in ati_remote->idev from udev. */
-	retval = ati_remote_initialize(ati_remote);
-	if (retval)
-		goto error;
+	err = ati_remote_initialize(ati_remote);
+	if (err)
+		goto fail3;
 
 	/* Set up and register input device */
-	ati_remote_input_init(ati_remote);
-	input_register_device(&ati_remote->idev);
-
-	dev_info(&ati_remote->interface->dev, "Input registered: %s on %s\n",
-		 ati_remote->name, path);
+	input_register_device(ati_remote->idev);
 
 	usb_set_intfdata(interface, ati_remote);
+	return 0;
 
-error:
-	if (retval)
-		ati_remote_delete(ati_remote);
-
-	return retval;
+fail3:	usb_kill_urb(ati_remote->irq_urb);
+	usb_kill_urb(ati_remote->out_urb);
+fail2:	ati_remote_free_buffers(ati_remote);
+fail1:	input_free_device(input_dev);
+	kfree(ati_remote);
+	return err;
 }
 
 /*
@@ -791,7 +792,11 @@
 		return;
 	}
 
-	ati_remote_delete(ati_remote);
+	usb_kill_urb(ati_remote->irq_urb);
+	usb_kill_urb(ati_remote->out_urb);
+	input_unregister_device(ati_remote->idev);
+	ati_remote_free_buffers(ati_remote);
+	kfree(ati_remote);
 }
 
 /*
diff --git a/drivers/usb/input/hid-core.c b/drivers/usb/input/hid-core.c
index 41f92b9..411a064 100644
--- a/drivers/usb/input/hid-core.c
+++ b/drivers/usb/input/hid-core.c
@@ -1619,8 +1619,8 @@
 	struct hid_descriptor *hdesc;
 	struct hid_device *hid;
 	unsigned quirks = 0, rsize = 0;
-	char *buf, *rdesc;
-	int n, insize = 0;
+	char *rdesc;
+	int n, len, insize = 0;
 
 	for (n = 0; hid_blacklist[n].idVendor; n++)
 		if ((hid_blacklist[n].idVendor == le16_to_cpu(dev->descriptor.idVendor)) &&
@@ -1630,10 +1630,11 @@
 	if (quirks & HID_QUIRK_IGNORE)
 		return NULL;
 
-	if (usb_get_extra_descriptor(interface, HID_DT_HID, &hdesc) && ((!interface->desc.bNumEndpoints) ||
-		usb_get_extra_descriptor(&interface->endpoint[0], HID_DT_HID, &hdesc))) {
-			dbg("class descriptor not present\n");
-			return NULL;
+	if (usb_get_extra_descriptor(interface, HID_DT_HID, &hdesc) &&
+	    (!interface->desc.bNumEndpoints ||
+	     usb_get_extra_descriptor(&interface->endpoint[0], HID_DT_HID, &hdesc))) {
+		dbg("class descriptor not present\n");
+		return NULL;
 	}
 
 	for (n = 0; n < hdesc->bNumDescriptors; n++)
@@ -1749,32 +1750,34 @@
 
 	hid->name[0] = 0;
 
-	if (!(buf = kmalloc(64, GFP_KERNEL)))
-		goto fail;
+	if (dev->manufacturer)
+		strlcpy(hid->name, dev->manufacturer, sizeof(hid->name));
 
-	if (dev->manufacturer) {
-		strcat(hid->name, dev->manufacturer);
-		if (dev->product)
-			snprintf(hid->name, 64, "%s %s", hid->name, dev->product);
-	} else if (dev->product) {
-			snprintf(hid->name, 128, "%s", dev->product);
-	} else
-		snprintf(hid->name, 128, "%04x:%04x",
-			le16_to_cpu(dev->descriptor.idVendor),
-			le16_to_cpu(dev->descriptor.idProduct));
+	if (dev->product) {
+		if (dev->manufacturer)
+			strlcat(hid->name, " ", sizeof(hid->name));
+		strlcat(hid->name, dev->product, sizeof(hid->name));
+	}
 
-	usb_make_path(dev, buf, 64);
-	snprintf(hid->phys, 64, "%s/input%d", buf,
-			intf->altsetting[0].desc.bInterfaceNumber);
+	if (!strlen(hid->name))
+		snprintf(hid->name, sizeof(hid->name), "HID %04x:%04x",
+			 le16_to_cpu(dev->descriptor.idVendor),
+			 le16_to_cpu(dev->descriptor.idProduct));
+
+	usb_make_path(dev, hid->phys, sizeof(hid->phys));
+	strlcat(hid->phys, "/input", sizeof(hid->phys));
+	len = strlen(hid->phys);
+	if (len < sizeof(hid->phys) - 1)
+		snprintf(hid->phys + len, sizeof(hid->phys) - len,
+			 "%d", intf->altsetting[0].desc.bInterfaceNumber);
 
 	if (usb_string(dev, dev->descriptor.iSerialNumber, hid->uniq, 64) <= 0)
 		hid->uniq[0] = 0;
 
-	kfree(buf);
-
 	hid->urbctrl = usb_alloc_urb(0, GFP_KERNEL);
 	if (!hid->urbctrl)
 		goto fail;
+
 	usb_fill_control_urb(hid->urbctrl, dev, 0, (void *) hid->cr,
 			     hid->ctrlbuf, 1, hid_ctrl, hid);
 	hid->urbctrl->setup_dma = hid->cr_dma;
diff --git a/drivers/usb/input/hid-input.c b/drivers/usb/input/hid-input.c
index 0b64522..9ff25eb 100644
--- a/drivers/usb/input/hid-input.c
+++ b/drivers/usb/input/hid-input.c
@@ -76,8 +76,8 @@
 static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_field *field,
 				     struct hid_usage *usage)
 {
-	struct input_dev *input = &hidinput->input;
-	struct hid_device *device = hidinput->input.private;
+	struct input_dev *input = hidinput->input;
+	struct hid_device *device = input->private;
 	int max = 0, code;
 	unsigned long *bit = NULL;
 
@@ -461,7 +461,8 @@
 
 	if (!field->hidinput)
 		return;
-	input = &field->hidinput->input;
+
+	input = field->hidinput->input;
 
 	input_regs(input, regs);
 
@@ -533,13 +534,10 @@
 
 void hidinput_report_event(struct hid_device *hid, struct hid_report *report)
 {
-	struct list_head *lh;
 	struct hid_input *hidinput;
 
-	list_for_each (lh, &hid->inputs) {
-		hidinput = list_entry(lh, struct hid_input, list);
-		input_sync(&hidinput->input);
-	}
+	list_for_each_entry(hidinput, &hid->inputs, list)
+		input_sync(hidinput->input);
 }
 
 static int hidinput_find_field(struct hid_device *hid, unsigned int type, unsigned int code, struct hid_field **field)
@@ -604,6 +602,7 @@
 	struct usb_device *dev = hid->dev;
 	struct hid_report *report;
 	struct hid_input *hidinput = NULL;
+	struct input_dev *input_dev;
 	int i, j, k;
 
 	INIT_LIST_HEAD(&hid->inputs);
@@ -624,25 +623,28 @@
 				continue;
 
 			if (!hidinput) {
-				hidinput = kmalloc(sizeof(*hidinput), GFP_KERNEL);
-				if (!hidinput) {
+				hidinput = kzalloc(sizeof(*hidinput), GFP_KERNEL);
+				input_dev = input_allocate_device();
+				if (!hidinput || !input_dev) {
+					kfree(hidinput);
+					input_free_device(input_dev);
 					err("Out of memory during hid input probe");
 					return -1;
 				}
-				memset(hidinput, 0, sizeof(*hidinput));
 
+				input_dev->private = hid;
+				input_dev->event = hidinput_input_event;
+				input_dev->open = hidinput_open;
+				input_dev->close = hidinput_close;
+
+				input_dev->name = hid->name;
+				input_dev->phys = hid->phys;
+				input_dev->uniq = hid->uniq;
+				usb_to_input_id(dev, &input_dev->id);
+				input_dev->cdev.dev = &hid->intf->dev;
+
+				hidinput->input = input_dev;
 				list_add_tail(&hidinput->list, &hid->inputs);
-
-				hidinput->input.private = hid;
-				hidinput->input.event = hidinput_input_event;
-				hidinput->input.open = hidinput_open;
-				hidinput->input.close = hidinput_close;
-
-				hidinput->input.name = hid->name;
-				hidinput->input.phys = hid->phys;
-				hidinput->input.uniq = hid->uniq;
-				usb_to_input_id(dev, &hidinput->input.id);
-				hidinput->input.dev = &hid->intf->dev;
 			}
 
 			for (i = 0; i < report->maxfield; i++)
@@ -657,7 +659,7 @@
 				 * UGCI) cram a lot of unrelated inputs into the
 				 * same interface. */
 				hidinput->report = report;
-				input_register_device(&hidinput->input);
+				input_register_device(hidinput->input);
 				hidinput = NULL;
 			}
 		}
@@ -667,7 +669,7 @@
 	 * only useful in this case, and not for multi-input quirks. */
 	if (hidinput) {
 		hid_ff_init(hid);
-		input_register_device(&hidinput->input);
+		input_register_device(hidinput->input);
 	}
 
 	return 0;
@@ -675,13 +677,11 @@
 
 void hidinput_disconnect(struct hid_device *hid)
 {
-	struct list_head *lh, *next;
-	struct hid_input *hidinput;
+	struct hid_input *hidinput, *next;
 
-	list_for_each_safe(lh, next, &hid->inputs) {
-		hidinput = list_entry(lh, struct hid_input, list);
-		input_unregister_device(&hidinput->input);
+	list_for_each_entry_safe(hidinput, next, &hid->inputs, list) {
 		list_del(&hidinput->list);
+		input_unregister_device(hidinput->input);
 		kfree(hidinput);
 	}
 }
diff --git a/drivers/usb/input/hid-lgff.c b/drivers/usb/input/hid-lgff.c
index 0c4c77a..f82c9c9 100644
--- a/drivers/usb/input/hid-lgff.c
+++ b/drivers/usb/input/hid-lgff.c
@@ -255,22 +255,19 @@
 	u16 idVendor = le16_to_cpu(hid->dev->descriptor.idVendor);
 	u16 idProduct = le16_to_cpu(hid->dev->descriptor.idProduct);
 	struct hid_input *hidinput = list_entry(hid->inputs.next, struct hid_input, list);
+	struct input_dev *input_dev = hidinput->input;
 
 	while (dev->idVendor && (idVendor != dev->idVendor || idProduct != dev->idProduct))
 		dev++;
 
-	ff = dev->ff;
+	for (ff = dev->ff; *ff >= 0; ff++)
+		set_bit(*ff, input_dev->ffbit);
 
-	while (*ff >= 0) {
-		set_bit(*ff, hidinput->input.ffbit);
-		++ff;
-	}
+	input_dev->upload_effect = hid_lgff_upload_effect;
+	input_dev->flush = hid_lgff_flush;
 
-	hidinput->input.upload_effect = hid_lgff_upload_effect;
-	hidinput->input.flush = hid_lgff_flush;
-
-	set_bit(EV_FF, hidinput->input.evbit);
-	hidinput->input.ff_effects_max = LGFF_EFFECTS;
+	set_bit(EV_FF, input_dev->evbit);
+	input_dev->ff_effects_max = LGFF_EFFECTS;
 }
 
 static void hid_lgff_exit(struct hid_device* hid)
diff --git a/drivers/usb/input/hid-tmff.c b/drivers/usb/input/hid-tmff.c
index 8f6a0a6..023fd5a 100644
--- a/drivers/usb/input/hid-tmff.c
+++ b/drivers/usb/input/hid-tmff.c
@@ -111,6 +111,7 @@
 	struct tmff_device *private;
 	struct list_head *pos;
 	struct hid_input *hidinput = list_entry(hid->inputs.next, struct hid_input, list);
+	struct input_dev *input_dev = hidinput->input;
 
 	private = kmalloc(sizeof(struct tmff_device), GFP_KERNEL);
 	if (!private)
@@ -155,7 +156,7 @@
 					private->report = report;
 					private->rumble = field;
 
-					set_bit(FF_RUMBLE, hidinput->input.ffbit);
+					set_bit(FF_RUMBLE, input_dev->ffbit);
 					break;
 
 				default:
@@ -164,11 +165,11 @@
 			}
 
 			/* Fallthrough to here only when a valid usage is found */
-			hidinput->input.upload_effect = hid_tmff_upload_effect;
-			hidinput->input.flush = hid_tmff_flush;
+			input_dev->upload_effect = hid_tmff_upload_effect;
+			input_dev->flush = hid_tmff_flush;
 
-			set_bit(EV_FF, hidinput->input.evbit);
-			hidinput->input.ff_effects_max = TMFF_EFFECTS;
+			set_bit(EV_FF, input_dev->evbit);
+			input_dev->ff_effects_max = TMFF_EFFECTS;
 		}
 	}
 
diff --git a/drivers/usb/input/hid.h b/drivers/usb/input/hid.h
index ec2412c..ee48a22 100644
--- a/drivers/usb/input/hid.h
+++ b/drivers/usb/input/hid.h
@@ -371,7 +371,7 @@
 struct hid_input {
 	struct list_head list;
 	struct hid_report *report;
-	struct input_dev input;
+	struct input_dev *input;
 };
 
 struct hid_device {							/* device report descriptor */
diff --git a/drivers/usb/input/itmtouch.c b/drivers/usb/input/itmtouch.c
index becb87e..3b58185 100644
--- a/drivers/usb/input/itmtouch.c
+++ b/drivers/usb/input/itmtouch.c
@@ -73,7 +73,7 @@
 
 struct itmtouch_dev {
 	struct usb_device	*usbdev; /* usb device */
-	struct input_dev	inputdev; /* input device */
+	struct input_dev	*inputdev; /* input device */
 	struct urb		*readurb; /* urb */
 	char			rbuf[ITM_BUFSIZE]; /* data */
 	int			users;
@@ -88,9 +88,9 @@
 
 static void itmtouch_irq(struct urb *urb, struct pt_regs *regs)
 {
-	struct itmtouch_dev * itmtouch = urb->context;
+	struct itmtouch_dev *itmtouch = urb->context;
 	unsigned char *data = urb->transfer_buffer;
-	struct input_dev *dev = &itmtouch->inputdev;
+	struct input_dev *dev = itmtouch->inputdev;
 	int retval;
 
 	switch (urb->status) {
@@ -156,49 +156,62 @@
 static int itmtouch_probe(struct usb_interface *intf, const struct usb_device_id *id)
 {
 	struct itmtouch_dev *itmtouch;
+	struct input_dev *input_dev;
 	struct usb_host_interface *interface;
 	struct usb_endpoint_descriptor *endpoint;
 	struct usb_device *udev = interface_to_usbdev(intf);
 	unsigned int pipe;
 	unsigned int maxp;
-	char path[PATH_SIZE];
 
 	interface = intf->cur_altsetting;
 	endpoint = &interface->endpoint[0].desc;
 
-	if (!(itmtouch = kzalloc(sizeof(struct itmtouch_dev), GFP_KERNEL))) {
+	itmtouch = kzalloc(sizeof(struct itmtouch_dev), GFP_KERNEL);
+	input_dev = input_allocate_device();
+	if (!itmtouch || !input_dev) {
 		err("%s - Out of memory.", __FUNCTION__);
-		return -ENOMEM;
+		goto fail;
 	}
 
 	itmtouch->usbdev = udev;
+	itmtouch->inputdev = input_dev;
 
-	itmtouch->inputdev.private = itmtouch;
-	itmtouch->inputdev.open = itmtouch_open;
-	itmtouch->inputdev.close = itmtouch_close;
+	if (udev->manufacturer)
+		strlcpy(itmtouch->name, udev->manufacturer, sizeof(itmtouch->name));
 
-	usb_make_path(udev, path, PATH_SIZE);
-
-	itmtouch->inputdev.evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
-	itmtouch->inputdev.absbit[0] = BIT(ABS_X) | BIT(ABS_Y) | BIT(ABS_PRESSURE);
-	itmtouch->inputdev.keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH);
-
-	itmtouch->inputdev.name = itmtouch->name;
-	itmtouch->inputdev.phys = itmtouch->phys;
-	usb_to_input_id(udev, &itmtouch->inputdev.id);
-	itmtouch->inputdev.dev = &intf->dev;
+	if (udev->product) {
+		if (udev->manufacturer)
+			strlcat(itmtouch->name, " ", sizeof(itmtouch->name));
+		strlcat(itmtouch->name, udev->product, sizeof(itmtouch->name));
+	}
 
 	if (!strlen(itmtouch->name))
 		sprintf(itmtouch->name, "USB ITM touchscreen");
 
+	usb_make_path(udev, itmtouch->phys, sizeof(itmtouch->phys));
+	strlcpy(itmtouch->phys, "/input0", sizeof(itmtouch->phys));
+
+	input_dev->name = itmtouch->name;
+	input_dev->phys = itmtouch->phys;
+	usb_to_input_id(udev, &input_dev->id);
+	input_dev->cdev.dev = &intf->dev;
+	input_dev->private = itmtouch;
+
+	input_dev->open = itmtouch_open;
+	input_dev->close = itmtouch_close;
+
+	input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
+	input_dev->absbit[0] = BIT(ABS_X) | BIT(ABS_Y) | BIT(ABS_PRESSURE);
+	input_dev->keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH);
+
 	/* device limits */
 	/* as specified by the ITM datasheet, X and Y are 12bit,
 	 * Z (pressure) is 8 bit. However, the fields are defined up
 	 * to 14 bits for future possible expansion.
 	 */
-	input_set_abs_params(&itmtouch->inputdev, ABS_X, 0, 0x0FFF, 2, 0);
-	input_set_abs_params(&itmtouch->inputdev, ABS_Y, 0, 0x0FFF, 2, 0);
-	input_set_abs_params(&itmtouch->inputdev, ABS_PRESSURE, 0, 0xFF, 2, 0);
+	input_set_abs_params(input_dev, ABS_X, 0, 0x0FFF, 2, 0);
+	input_set_abs_params(input_dev, ABS_Y, 0, 0x0FFF, 2, 0);
+	input_set_abs_params(input_dev, ABS_PRESSURE, 0, 0xFF, 2, 0);
 
 	/* initialise the URB so we can read from the transport stream */
 	pipe = usb_rcvintpipe(itmtouch->usbdev, endpoint->bEndpointAddress);
@@ -208,22 +221,23 @@
 		maxp = ITM_BUFSIZE;
 
 	itmtouch->readurb = usb_alloc_urb(0, GFP_KERNEL);
-
 	if (!itmtouch->readurb) {
 		dbg("%s - usb_alloc_urb failed: itmtouch->readurb", __FUNCTION__);
-		kfree(itmtouch);
-		return -ENOMEM;
+		goto fail;
 	}
 
 	usb_fill_int_urb(itmtouch->readurb, itmtouch->usbdev, pipe, itmtouch->rbuf,
 			 maxp, itmtouch_irq, itmtouch, endpoint->bInterval);
 
-	input_register_device(&itmtouch->inputdev);
+	input_register_device(itmtouch->inputdev);
 
-	printk(KERN_INFO "itmtouch: %s registered on %s\n", itmtouch->name, path);
 	usb_set_intfdata(intf, itmtouch);
 
 	return 0;
+
+ fail:	input_free_device(input_dev);
+	kfree(itmtouch);
+	return -ENOMEM;
 }
 
 static void itmtouch_disconnect(struct usb_interface *intf)
@@ -233,7 +247,7 @@
 	usb_set_intfdata(intf, NULL);
 
 	if (itmtouch) {
-		input_unregister_device(&itmtouch->inputdev);
+		input_unregister_device(itmtouch->inputdev);
 		usb_kill_urb(itmtouch->readurb);
 		usb_free_urb(itmtouch->readurb);
 		kfree(itmtouch);
diff --git a/drivers/usb/input/kbtab.c b/drivers/usb/input/kbtab.c
index b6f6ac8..a248664 100644
--- a/drivers/usb/input/kbtab.c
+++ b/drivers/usb/input/kbtab.c
@@ -34,7 +34,7 @@
 struct kbtab {
 	signed char *data;
 	dma_addr_t data_dma;
-	struct input_dev dev;
+	struct input_dev *dev;
 	struct usb_device *usbdev;
 	struct urb *irq;
 	int x, y;
@@ -48,7 +48,7 @@
 {
 	struct kbtab *kbtab = urb->context;
 	unsigned char *data = kbtab->data;
-	struct input_dev *dev = &kbtab->dev;
+	struct input_dev *dev = kbtab->dev;
 	int retval;
 
 	switch (urb->status) {
@@ -124,53 +124,43 @@
 	struct usb_device *dev = interface_to_usbdev(intf);
 	struct usb_endpoint_descriptor *endpoint;
 	struct kbtab *kbtab;
-	char path[64];
+	struct input_dev *input_dev;
 
-	if (!(kbtab = kmalloc(sizeof(struct kbtab), GFP_KERNEL)))
-		return -ENOMEM;
-	memset(kbtab, 0, sizeof(struct kbtab));
+	kbtab = kzalloc(sizeof(struct kbtab), GFP_KERNEL);
+	input_dev = input_allocate_device();
+	if (!kbtab || !input_dev)
+		goto fail1;
 
 	kbtab->data = usb_buffer_alloc(dev, 8, GFP_KERNEL, &kbtab->data_dma);
-	if (!kbtab->data) {
-		kfree(kbtab);
-		return -ENOMEM;
-	}
+	if (!kbtab->data)
+		goto fail1;
 
 	kbtab->irq = usb_alloc_urb(0, GFP_KERNEL);
-	if (!kbtab->irq) {
-		usb_buffer_free(dev, 10, kbtab->data, kbtab->data_dma);
-		kfree(kbtab);
-		return -ENOMEM;
-	}
+	if (!kbtab->irq)
+		goto fail2;
 
-	kbtab->dev.evbit[0] |= BIT(EV_KEY) | BIT(EV_ABS) | BIT(EV_MSC);
-	kbtab->dev.absbit[0] |= BIT(ABS_X) | BIT(ABS_Y) | BIT(ABS_PRESSURE);
-
-	kbtab->dev.keybit[LONG(BTN_LEFT)] |= BIT(BTN_LEFT) | BIT(BTN_RIGHT) | BIT(BTN_MIDDLE);
-
-	kbtab->dev.keybit[LONG(BTN_DIGI)] |= BIT(BTN_TOOL_PEN) | BIT(BTN_TOUCH);
-
-	kbtab->dev.mscbit[0] |= BIT(MSC_SERIAL);
-
-	kbtab->dev.absmax[ABS_X] = 0x2000;
-	kbtab->dev.absmax[ABS_Y] = 0x1750;
-	kbtab->dev.absmax[ABS_PRESSURE] = 0xff;
-
-	kbtab->dev.absfuzz[ABS_X] = 4;
-	kbtab->dev.absfuzz[ABS_Y] = 4;
-
-	kbtab->dev.private = kbtab;
-	kbtab->dev.open = kbtab_open;
-	kbtab->dev.close = kbtab_close;
-
-	usb_make_path(dev, path, 64);
-	sprintf(kbtab->phys, "%s/input0", path);
-
-	kbtab->dev.name = "KB Gear Tablet";
-	kbtab->dev.phys = kbtab->phys;
-	usb_to_input_id(dev, &kbtab->dev.id);
-	kbtab->dev.dev = &intf->dev;
 	kbtab->usbdev = dev;
+	kbtab->dev = input_dev;
+
+	usb_make_path(dev, kbtab->phys, sizeof(kbtab->phys));
+	strlcat(kbtab->phys, "/input0", sizeof(kbtab->phys));
+
+	input_dev->name = "KB Gear Tablet";
+	input_dev->phys = kbtab->phys;
+	usb_to_input_id(dev, &input_dev->id);
+	input_dev->cdev.dev = &intf->dev;
+	input_dev->private = kbtab;
+
+	input_dev->open = kbtab_open;
+	input_dev->close = kbtab_close;
+
+	input_dev->evbit[0] |= BIT(EV_KEY) | BIT(EV_ABS) | BIT(EV_MSC);
+	input_dev->keybit[LONG(BTN_LEFT)] |= BIT(BTN_LEFT) | BIT(BTN_RIGHT) | BIT(BTN_MIDDLE);
+	input_dev->keybit[LONG(BTN_DIGI)] |= BIT(BTN_TOOL_PEN) | BIT(BTN_TOUCH);
+	input_dev->mscbit[0] |= BIT(MSC_SERIAL);
+	input_set_abs_params(input_dev, ABS_X, 0, 0x2000, 4, 0);
+	input_set_abs_params(input_dev, ABS_X, 0, 0x1750, 4, 0);
+	input_set_abs_params(input_dev, ABS_PRESSURE, 0, 0xff, 0, 0);
 
 	endpoint = &intf->cur_altsetting->endpoint[0].desc;
 
@@ -181,23 +171,25 @@
 	kbtab->irq->transfer_dma = kbtab->data_dma;
 	kbtab->irq->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
 
-	input_register_device(&kbtab->dev);
-
-	printk(KERN_INFO "input: KB Gear Tablet on %s\n",  path);
+	input_register_device(kbtab->dev);
 
 	usb_set_intfdata(intf, kbtab);
-
 	return 0;
+
+fail2:	usb_buffer_free(dev, 10, kbtab->data, kbtab->data_dma);
+fail1:	input_free_device(input_dev);
+	kfree(kbtab);
+	return -ENOMEM;
 }
 
 static void kbtab_disconnect(struct usb_interface *intf)
 {
-	struct kbtab *kbtab = usb_get_intfdata (intf);
+	struct kbtab *kbtab = usb_get_intfdata(intf);
 
 	usb_set_intfdata(intf, NULL);
 	if (kbtab) {
 		usb_kill_urb(kbtab->irq);
-		input_unregister_device(&kbtab->dev);
+		input_unregister_device(kbtab->dev);
 		usb_free_urb(kbtab->irq);
 		usb_buffer_free(interface_to_usbdev(intf), 10, kbtab->data, kbtab->data_dma);
 		kfree(kbtab);
diff --git a/drivers/usb/input/keyspan_remote.c b/drivers/usb/input/keyspan_remote.c
index 99de1b3..5b8d65f 100644
--- a/drivers/usb/input/keyspan_remote.c
+++ b/drivers/usb/input/keyspan_remote.c
@@ -20,6 +20,7 @@
 #include <linux/moduleparam.h>
 #include <linux/input.h>
 #include <linux/usb.h>
+#include <linux/usb_input.h>
 
 #define DRIVER_VERSION	"v0.1"
 #define DRIVER_AUTHOR	"Michael Downey <downey@zymeta.com>"
@@ -75,7 +76,7 @@
 	char				name[128];
 	char				phys[64];
 	struct usb_device*		udev;
-	struct input_dev		input;
+	struct input_dev		*input;
 	struct usb_interface*		interface;
 	struct usb_endpoint_descriptor* in_endpoint;
 	struct urb*			irq_urb;
@@ -136,12 +137,11 @@
  */
 static void keyspan_print(struct usb_keyspan* dev) /*unsigned char* data)*/
 {
-	char codes[4*RECV_SIZE];
+	char codes[4 * RECV_SIZE];
 	int i;
 
-	for (i = 0; i < RECV_SIZE; i++) {
-		snprintf(codes+i*3, 4, "%02x ", dev->in_buffer[i]);
-	}
+	for (i = 0; i < RECV_SIZE; i++)
+		snprintf(codes + i * 3, 4, "%02x ", dev->in_buffer[i]);
 
 	dev_info(&dev->udev->dev, "%s\n", codes);
 }
@@ -153,7 +153,7 @@
 static int keyspan_load_tester(struct usb_keyspan* dev, int bits_needed)
 {
 	if (dev->data.bits_left >= bits_needed)
-		return(0);
+		return 0;
 
 	/*
 	 * Somehow we've missed the last message. The message will be repeated
@@ -162,7 +162,7 @@
 	if (dev->data.pos >= dev->data.len) {
 		dev_dbg(&dev->udev, "%s - Error ran out of data. pos: %d, len: %d\n",
 			__FUNCTION__, dev->data.pos, dev->data.len);
-		return(-1);
+		return -1;
 	}
 
 	/* Load as much as we can into the tester. */
@@ -172,7 +172,7 @@
 		dev->data.bits_left += 8;
 	}
 
-	return(0);
+	return 0;
 }
 
 /*
@@ -311,10 +311,10 @@
 			__FUNCTION__, message.system, message.button, message.toggle);
 
 		if (message.toggle != remote->toggle) {
-			input_regs(&remote->input, regs);
-			input_report_key(&remote->input, keyspan_key_table[message.button], 1);
-			input_report_key(&remote->input, keyspan_key_table[message.button], 0);
-			input_sync(&remote->input);
+			input_regs(remote->input, regs);
+			input_report_key(remote->input, keyspan_key_table[message.button], 1);
+			input_report_key(remote->input, keyspan_key_table[message.button], 0);
+			input_sync(remote->input);
 			remote->toggle = message.toggle;
 		}
 
@@ -397,14 +397,9 @@
 {
 	struct usb_keyspan *remote = dev->private;
 
-	if (remote->open++)
-		return 0;
-
 	remote->irq_urb->dev = remote->udev;
-	if (usb_submit_urb(remote->irq_urb, GFP_KERNEL)) {
-		remote->open--;
+	if (usb_submit_urb(remote->irq_urb, GFP_KERNEL))
 		return -EIO;
-	}
 
 	return 0;
 }
@@ -413,8 +408,26 @@
 {
 	struct usb_keyspan *remote = dev->private;
 
-	if (!--remote->open)
-		usb_kill_urb(remote->irq_urb);
+	usb_kill_urb(remote->irq_urb);
+}
+
+static struct usb_endpoint_descriptor *keyspan_get_in_endpoint(struct usb_host_interface *iface)
+{
+
+	struct usb_endpoint_descriptor *endpoint;
+	int i;
+
+	for (i = 0; i < iface->desc.bNumEndpoints; ++i) {
+		endpoint = &iface->endpoint[i].desc;
+
+		if ((endpoint->bEndpointAddress & USB_DIR_IN) &&
+		    ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == USB_ENDPOINT_XFER_INT)) {
+			/* we found our interrupt in endpoint */
+			return endpoint;
+		}
+	}
+
+	return NULL;
 }
 
 /*
@@ -422,110 +435,78 @@
  */
 static int keyspan_probe(struct usb_interface *interface, const struct usb_device_id *id)
 {
-	int i;
-	int retval = -ENOMEM;
-	char path[64];
-	char *buf;
-	struct usb_keyspan *remote = NULL;
-	struct usb_host_interface *iface_desc;
+	struct usb_device *udev = interface_to_usbdev(interface);
 	struct usb_endpoint_descriptor *endpoint;
-	struct usb_device *udev = usb_get_dev(interface_to_usbdev(interface));
+	struct usb_keyspan *remote;
+	struct input_dev *input_dev;
+	int i, retval;
 
-	/* allocate memory for our device state and initialize it */
-	remote = kmalloc(sizeof(*remote), GFP_KERNEL);
-	if (remote == NULL) {
-		err("Out of memory\n");
-		goto error;
+	endpoint = keyspan_get_in_endpoint(interface->cur_altsetting);
+	if (!endpoint)
+		return -ENODEV;
+
+	remote = kzalloc(sizeof(*remote), GFP_KERNEL);
+	input_dev = input_allocate_device();
+	if (!remote || !input_dev) {
+		retval = -ENOMEM;
+		goto fail1;
 	}
-	memset(remote, 0x00, sizeof(*remote));
 
 	remote->udev = udev;
+	remote->input = input_dev;
 	remote->interface = interface;
+	remote->in_endpoint = endpoint;
 	remote->toggle = -1;	/* Set to -1 so we will always not match the toggle from the first remote message. */
 
-	/* set up the endpoint information */
-	/* use only the first in interrupt endpoint */
-	iface_desc = interface->cur_altsetting;
-	for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) {
-		endpoint = &iface_desc->endpoint[i].desc;
-
-		if (!remote->in_endpoint &&
-		    (endpoint->bEndpointAddress & USB_DIR_IN) &&
-		    ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == USB_ENDPOINT_XFER_INT)) {
-			/* we found our interrupt in endpoint */
-			remote->in_endpoint = endpoint;
-
-			remote->in_buffer = usb_buffer_alloc(remote->udev, RECV_SIZE, SLAB_ATOMIC, &remote->in_dma);
-			if (!remote->in_buffer) {
-				retval = -ENOMEM;
-				goto error;
-			}
-		}
-	}
-
-	if (!remote->in_endpoint) {
-		err("Could not find interrupt input endpoint.\n");
-		retval = -ENODEV;
-		goto error;
+	remote->in_buffer = usb_buffer_alloc(udev, RECV_SIZE, SLAB_ATOMIC, &remote->in_dma);
+	if (!remote->in_buffer) {
+		retval = -ENOMEM;
+		goto fail1;
 	}
 
 	remote->irq_urb = usb_alloc_urb(0, GFP_KERNEL);
 	if (!remote->irq_urb) {
-		err("Failed to allocate urb.\n");
 		retval = -ENOMEM;
-		goto error;
+		goto fail2;
 	}
 
-	retval = keyspan_setup(remote->udev);
+	retval = keyspan_setup(udev);
 	if (retval) {
-		err("Failed to setup device.\n");
 		retval = -ENODEV;
-		goto error;
+		goto fail3;
 	}
 
-	/*
-	 * Setup the input system with the bits we are going to be reporting
-	 */
-	remote->input.evbit[0] = BIT(EV_KEY);		/* We will only report KEY events. */
-	for (i = 0; i < 32; ++i) {
-		if (keyspan_key_table[i] != KEY_RESERVED) {
-			set_bit(keyspan_key_table[i], remote->input.keybit);
-		}
+	if (udev->manufacturer)
+		strlcpy(remote->name, udev->manufacturer, sizeof(remote->name));
+
+	if (udev->product) {
+		if (udev->manufacturer)
+			strlcat(remote->name, " ", sizeof(remote->name));
+		strlcat(remote->name, udev->product, sizeof(remote->name));
 	}
 
-	remote->input.private = remote;
-	remote->input.open = keyspan_open;
-	remote->input.close = keyspan_close;
-
-	usb_make_path(remote->udev, path, 64);
-	sprintf(remote->phys, "%s/input0", path);
-
-	remote->input.name = remote->name;
-	remote->input.phys = remote->phys;
-	remote->input.id.bustype = BUS_USB;
-	remote->input.id.vendor = le16_to_cpu(remote->udev->descriptor.idVendor);
-	remote->input.id.product = le16_to_cpu(remote->udev->descriptor.idProduct);
-	remote->input.id.version = le16_to_cpu(remote->udev->descriptor.bcdDevice);
-
-	if (!(buf = kmalloc(63, GFP_KERNEL))) {
-		usb_buffer_free(remote->udev, RECV_SIZE, remote->in_buffer, remote->in_dma);
-		kfree(remote);
-		return -ENOMEM;
-	}
-
-	if (remote->udev->descriptor.iManufacturer &&
-	    usb_string(remote->udev, remote->udev->descriptor.iManufacturer, buf, 63) > 0)
-		strcat(remote->name, buf);
-
-	if (remote->udev->descriptor.iProduct &&
-	    usb_string(remote->udev, remote->udev->descriptor.iProduct, buf, 63) > 0)
-		sprintf(remote->name, "%s %s", remote->name, buf);
-
 	if (!strlen(remote->name))
-		sprintf(remote->name, "USB Keyspan Remote %04x:%04x",
-			remote->input.id.vendor, remote->input.id.product);
+		snprintf(remote->name, sizeof(remote->name),
+			 "USB Keyspan Remote %04x:%04x",
+			 le16_to_cpu(udev->descriptor.idVendor),
+			 le16_to_cpu(udev->descriptor.idProduct));
 
-	kfree(buf);
+	usb_make_path(udev, remote->phys, sizeof(remote->phys));
+	strlcat(remote->phys, "/input0", sizeof(remote->phys));
+
+	input_dev->name = remote->name;
+	input_dev->phys = remote->phys;
+	usb_to_input_id(udev, &input_dev->id);
+	input_dev->cdev.dev = &interface->dev;
+
+	input_dev->evbit[0] = BIT(EV_KEY);		/* We will only report KEY events. */
+	for (i = 0; i < ARRAY_SIZE(keyspan_key_table); i++)
+		if (keyspan_key_table[i] != KEY_RESERVED)
+			set_bit(keyspan_key_table[i], input_dev->keybit);
+
+	input_dev->private = remote;
+	input_dev->open = keyspan_open;
+	input_dev->close = keyspan_close;
 
 	/*
 	 * Initialize the URB to access the device. The urb gets sent to the device in keyspan_open()
@@ -538,27 +519,17 @@
 	remote->irq_urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
 
 	/* we can register the device now, as it is ready */
-	input_register_device(&remote->input);
+	input_register_device(remote->input);
 
 	/* save our data pointer in this interface device */
 	usb_set_intfdata(interface, remote);
 
-	/* let the user know what node this device is now attached to */
-	info("connected: %s on %s", remote->name, path);
 	return 0;
 
-error:
-	/*
-	 * In case of error we need to clean up any allocated buffers
-	 */
-	if (remote->irq_urb)
-		usb_free_urb(remote->irq_urb);
-
-	if (remote->in_buffer)
-		usb_buffer_free(remote->udev, RECV_SIZE, remote->in_buffer, remote->in_dma);
-
-	if (remote)
-		kfree(remote);
+ fail3:	usb_free_urb(remote->irq_urb);
+ fail2:	usb_buffer_free(udev, RECV_SIZE, remote->in_buffer, remote->in_dma);
+ fail1:	kfree(remote);
+	input_free_device(input_dev);
 
 	return retval;
 }
@@ -570,23 +541,16 @@
 {
 	struct usb_keyspan *remote;
 
-	/* prevent keyspan_open() from racing keyspan_disconnect() */
-	lock_kernel();
-
 	remote = usb_get_intfdata(interface);
 	usb_set_intfdata(interface, NULL);
 
 	if (remote) {	/* We have a valid driver structure so clean up everything we allocated. */
-		input_unregister_device(&remote->input);
+		input_unregister_device(remote->input);
 		usb_kill_urb(remote->irq_urb);
 		usb_free_urb(remote->irq_urb);
-		usb_buffer_free(interface_to_usbdev(interface), RECV_SIZE, remote->in_buffer, remote->in_dma);
+		usb_buffer_free(remote->udev, RECV_SIZE, remote->in_buffer, remote->in_dma);
 		kfree(remote);
 	}
-
-	unlock_kernel();
-
-	info("USB Keyspan now disconnected");
 }
 
 /*
diff --git a/drivers/usb/input/mtouchusb.c b/drivers/usb/input/mtouchusb.c
index ff92750..7fce526 100644
--- a/drivers/usb/input/mtouchusb.c
+++ b/drivers/usb/input/mtouchusb.c
@@ -98,7 +98,7 @@
 	dma_addr_t data_dma;
 	struct urb *irq;
 	struct usb_device *udev;
-	struct input_dev input;
+	struct input_dev *input;
 	char name[128];
 	char phys[64];
 };
@@ -135,14 +135,14 @@
 		goto exit;
 	}
 
-	input_regs(&mtouch->input, regs);
-	input_report_key(&mtouch->input, BTN_TOUCH,
+	input_regs(mtouch->input, regs);
+	input_report_key(mtouch->input, BTN_TOUCH,
 			 MTOUCHUSB_GET_TOUCHED(mtouch->data));
-	input_report_abs(&mtouch->input, ABS_X, MTOUCHUSB_GET_XC(mtouch->data));
-	input_report_abs(&mtouch->input, ABS_Y,
+	input_report_abs(mtouch->input, ABS_X, MTOUCHUSB_GET_XC(mtouch->data));
+	input_report_abs(mtouch->input, ABS_Y,
 			 (raw_coordinates ? MTOUCHUSB_MAX_RAW_YC : MTOUCHUSB_MAX_CALIB_YC)
 			 - MTOUCHUSB_GET_YC(mtouch->data));
-	input_sync(&mtouch->input);
+	input_sync(mtouch->input);
 
 exit:
 	retval = usb_submit_urb(urb, GFP_ATOMIC);
@@ -195,10 +195,10 @@
 static int mtouchusb_probe(struct usb_interface *intf, const struct usb_device_id *id)
 {
 	struct mtouch_usb *mtouch;
+	struct input_dev *input_dev;
 	struct usb_host_interface *interface;
 	struct usb_endpoint_descriptor *endpoint;
 	struct usb_device *udev = interface_to_usbdev(intf);
-	char path[64];
 	int nRet;
 
 	dbg("%s - called", __FUNCTION__);
@@ -209,57 +209,55 @@
 	dbg("%s - setting endpoint", __FUNCTION__);
 	endpoint = &interface->endpoint[0].desc;
 
-	if (!(mtouch = kmalloc(sizeof(struct mtouch_usb), GFP_KERNEL))) {
+	mtouch = kzalloc(sizeof(struct mtouch_usb), GFP_KERNEL);
+	input_dev = input_allocate_device();
+	if (!mtouch || !input_dev) {
 		err("%s - Out of memory.", __FUNCTION__);
-		return -ENOMEM;
+		goto fail1;
 	}
 
-	memset(mtouch, 0, sizeof(struct mtouch_usb));
-	mtouch->udev = udev;
-
 	dbg("%s - allocating buffers", __FUNCTION__);
-	if (mtouchusb_alloc_buffers(udev, mtouch)) {
-		mtouchusb_free_buffers(udev, mtouch);
-		kfree(mtouch);
-		return -ENOMEM;
-	}
+	if (mtouchusb_alloc_buffers(udev, mtouch))
+		goto fail2;
 
-	mtouch->input.private = mtouch;
-	mtouch->input.open = mtouchusb_open;
-	mtouch->input.close = mtouchusb_close;
-
-	usb_make_path(udev, path, 64);
-	sprintf(mtouch->phys, "%s/input0", path);
-
-	mtouch->input.name = mtouch->name;
-	mtouch->input.phys = mtouch->phys;
-	usb_to_input_id(udev, &mtouch->input.id);
-	mtouch->input.dev = &intf->dev;
-
-	mtouch->input.evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
-	mtouch->input.absbit[0] = BIT(ABS_X) | BIT(ABS_Y);
-	mtouch->input.keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH);
-
-	/* Used to Scale Compensated Data and Flip Y */
-	mtouch->input.absmin[ABS_X] = MTOUCHUSB_MIN_XC;
-	mtouch->input.absmax[ABS_X] = raw_coordinates ?
-					MTOUCHUSB_MAX_RAW_XC : MTOUCHUSB_MAX_CALIB_XC;
-	mtouch->input.absfuzz[ABS_X] = MTOUCHUSB_XC_FUZZ;
-	mtouch->input.absflat[ABS_X] = MTOUCHUSB_XC_FLAT;
-	mtouch->input.absmin[ABS_Y] = MTOUCHUSB_MIN_YC;
-	mtouch->input.absmax[ABS_Y] = raw_coordinates ?
-					MTOUCHUSB_MAX_RAW_YC : MTOUCHUSB_MAX_CALIB_YC;
-	mtouch->input.absfuzz[ABS_Y] = MTOUCHUSB_YC_FUZZ;
-	mtouch->input.absflat[ABS_Y] = MTOUCHUSB_YC_FLAT;
+	mtouch->udev = udev;
+	mtouch->input = input_dev;
 
 	if (udev->manufacturer)
-		strcat(mtouch->name, udev->manufacturer);
-	if (udev->product)
-		sprintf(mtouch->name, "%s %s", mtouch->name, udev->product);
+		strlcpy(mtouch->name, udev->manufacturer, sizeof(mtouch->name));
+
+	if (udev->product) {
+		if (udev->manufacturer)
+			strlcat(mtouch->name, " ", sizeof(mtouch->name));
+		strlcat(mtouch->name, udev->product, sizeof(mtouch->name));
+	}
 
 	if (!strlen(mtouch->name))
-		sprintf(mtouch->name, "USB Touchscreen %04x:%04x",
-			mtouch->input.id.vendor, mtouch->input.id.product);
+		snprintf(mtouch->name, sizeof(mtouch->name),
+			"USB Touchscreen %04x:%04x",
+			le16_to_cpu(udev->descriptor.idVendor),
+			le16_to_cpu(udev->descriptor.idProduct));
+
+	usb_make_path(udev, mtouch->phys, sizeof(mtouch->phys));
+	strlcpy(mtouch->phys, "/input0", sizeof(mtouch->phys));
+
+	input_dev->name = mtouch->name;
+	input_dev->phys = mtouch->phys;
+	usb_to_input_id(udev, &input_dev->id);
+	input_dev->cdev.dev = &intf->dev;
+	input_dev->private = mtouch;
+
+	input_dev->open = mtouchusb_open;
+	input_dev->close = mtouchusb_close;
+
+	input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
+	input_dev->keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH);
+	input_set_abs_params(input_dev, ABS_X, MTOUCHUSB_MIN_XC,
+		raw_coordinates ? MTOUCHUSB_MAX_RAW_XC : MTOUCHUSB_MAX_CALIB_XC,
+				MTOUCHUSB_XC_FUZZ, MTOUCHUSB_XC_FLAT);
+	input_set_abs_params(input_dev, ABS_Y, MTOUCHUSB_MIN_YC,
+		raw_coordinates ? MTOUCHUSB_MAX_RAW_YC : MTOUCHUSB_MAX_CALIB_YC,
+		MTOUCHUSB_YC_FUZZ, MTOUCHUSB_YC_FLAT);
 
 	nRet = usb_control_msg(mtouch->udev, usb_rcvctrlpipe(udev, 0),
 			       MTOUCHUSB_RESET,
@@ -272,9 +270,7 @@
 	mtouch->irq = usb_alloc_urb(0, GFP_KERNEL);
 	if (!mtouch->irq) {
 		dbg("%s - usb_alloc_urb failed: mtouch->irq", __FUNCTION__);
-		mtouchusb_free_buffers(udev, mtouch);
-		kfree(mtouch);
-		return -ENOMEM;
+		goto fail2;
 	}
 
 	dbg("%s - usb_fill_int_urb", __FUNCTION__);
@@ -284,7 +280,7 @@
 			 mtouchusb_irq, mtouch, endpoint->bInterval);
 
 	dbg("%s - input_register_device", __FUNCTION__);
-	input_register_device(&mtouch->input);
+	input_register_device(mtouch->input);
 
 	nRet = usb_control_msg(mtouch->udev, usb_rcvctrlpipe(udev, 0),
 			       MTOUCHUSB_ASYNC_REPORT,
@@ -293,10 +289,13 @@
 	dbg("%s - usb_control_msg - MTOUCHUSB_ASYNC_REPORT - bytes|err: %d",
 	    __FUNCTION__, nRet);
 
-	printk(KERN_INFO "input: %s on %s\n", mtouch->name, path);
 	usb_set_intfdata(intf, mtouch);
-
 	return 0;
+
+fail2:	mtouchusb_free_buffers(udev, mtouch);
+fail1:	input_free_device(input_dev);
+	kfree(mtouch);
+	return -ENOMEM;
 }
 
 static void mtouchusb_disconnect(struct usb_interface *intf)
@@ -308,7 +307,7 @@
 	if (mtouch) {
 		dbg("%s - mtouch is initialized, cleaning up", __FUNCTION__);
 		usb_kill_urb(mtouch->irq);
-		input_unregister_device(&mtouch->input);
+		input_unregister_device(mtouch->input);
 		usb_free_urb(mtouch->irq);
 		mtouchusb_free_buffers(interface_to_usbdev(intf), mtouch);
 		kfree(mtouch);
diff --git a/drivers/usb/input/pid.c b/drivers/usb/input/pid.c
index acc71ec..a00672c 100644
--- a/drivers/usb/input/pid.c
+++ b/drivers/usb/input/pid.c
@@ -262,6 +262,7 @@
 {
 	struct hid_ff_pid *private;
 	struct hid_input *hidinput = list_entry(&hid->inputs, struct hid_input, list);
+	struct input_dev *input_dev = hidinput->input;
 
 	private = hid->ff_private = kzalloc(sizeof(struct hid_ff_pid), GFP_KERNEL);
 	if (!private)
@@ -281,11 +282,12 @@
 	usb_fill_control_urb(private->urbffout, hid->dev, 0,
 			     (void *)&private->ffcr, private->ctrl_buffer, 8,
 			     hid_pid_ctrl_out, hid);
-	hidinput->input.upload_effect = hid_pid_upload_effect;
-	hidinput->input.flush = hid_pid_flush;
-	hidinput->input.ff_effects_max = 8;	// A random default
-	set_bit(EV_FF, hidinput->input.evbit);
-	set_bit(EV_FF_STATUS, hidinput->input.evbit);
+
+	input_dev->upload_effect = hid_pid_upload_effect;
+	input_dev->flush = hid_pid_flush;
+	input_dev->ff_effects_max = 8;	// A random default
+	set_bit(EV_FF, input_dev->evbit);
+	set_bit(EV_FF_STATUS, input_dev->evbit);
 
 	spin_lock_init(&private->lock);
 
diff --git a/drivers/usb/input/powermate.c b/drivers/usb/input/powermate.c
index ad4afe7..b747623 100644
--- a/drivers/usb/input/powermate.c
+++ b/drivers/usb/input/powermate.c
@@ -68,7 +68,7 @@
 	struct usb_ctrlrequest *configcr;
 	dma_addr_t configcr_dma;
 	struct usb_device *udev;
-	struct input_dev input;
+	struct input_dev *input;
 	spinlock_t lock;
 	int static_brightness;
 	int pulse_speed;
@@ -106,10 +106,10 @@
 	}
 
 	/* handle updates to device state */
-	input_regs(&pm->input, regs);
-	input_report_key(&pm->input, BTN_0, pm->data[0] & 0x01);
-	input_report_rel(&pm->input, REL_DIAL, pm->data[1]);
-	input_sync(&pm->input);
+	input_regs(pm->input, regs);
+	input_report_key(pm->input, BTN_0, pm->data[0] & 0x01);
+	input_report_rel(pm->input, REL_DIAL, pm->data[1]);
+	input_sync(pm->input);
 
 exit:
 	retval = usb_submit_urb (urb, GFP_ATOMIC);
@@ -153,10 +153,10 @@
 
 		   Only values of 'arg' quite close to 255 are particularly useful/spectacular.
 		*/
-		if (pm->pulse_speed < 255){
+		if (pm->pulse_speed < 255) {
 			op = 0;                   // divide
 			arg = 255 - pm->pulse_speed;
-		} else if (pm->pulse_speed > 255){
+		} else if (pm->pulse_speed > 255) {
 			op = 2;                   // multiply
 			arg = pm->pulse_speed - 255;
 		} else {
@@ -166,11 +166,11 @@
 		pm->configcr->wValue = cpu_to_le16( (pm->pulse_table << 8) | SET_PULSE_MODE );
 		pm->configcr->wIndex = cpu_to_le16( (arg << 8) | op );
 		pm->requires_update &= ~UPDATE_PULSE_MODE;
-	}else if (pm->requires_update & UPDATE_STATIC_BRIGHTNESS){
+	} else if (pm->requires_update & UPDATE_STATIC_BRIGHTNESS) {
 		pm->configcr->wValue = cpu_to_le16( SET_STATIC_BRIGHTNESS );
 		pm->configcr->wIndex = cpu_to_le16( pm->static_brightness );
 		pm->requires_update &= ~UPDATE_STATIC_BRIGHTNESS;
-	}else{
+	} else {
 		printk(KERN_ERR "powermate: unknown update required");
 		pm->requires_update = 0; /* fudge the bug */
 		return;
@@ -228,19 +228,19 @@
 	spin_lock_irqsave(&pm->lock, flags);
 
 	/* mark state updates which are required */
-	if (static_brightness != pm->static_brightness){
+	if (static_brightness != pm->static_brightness) {
 		pm->static_brightness = static_brightness;
 		pm->requires_update |= UPDATE_STATIC_BRIGHTNESS;
 	}
-	if (pulse_asleep != pm->pulse_asleep){
+	if (pulse_asleep != pm->pulse_asleep) {
 		pm->pulse_asleep = pulse_asleep;
 		pm->requires_update |= (UPDATE_PULSE_ASLEEP | UPDATE_STATIC_BRIGHTNESS);
 	}
-	if (pulse_awake != pm->pulse_awake){
+	if (pulse_awake != pm->pulse_awake) {
 		pm->pulse_awake = pulse_awake;
 		pm->requires_update |= (UPDATE_PULSE_AWAKE | UPDATE_STATIC_BRIGHTNESS);
 	}
-	if (pulse_speed != pm->pulse_speed || pulse_table != pm->pulse_table){
+	if (pulse_speed != pm->pulse_speed || pulse_table != pm->pulse_table) {
 		pm->pulse_speed = pulse_speed;
 		pm->pulse_table = pulse_table;
 		pm->requires_update |= UPDATE_PULSE_MODE;
@@ -283,6 +283,7 @@
 				    SLAB_ATOMIC, &pm->data_dma);
 	if (!pm->data)
 		return -1;
+
 	pm->configcr = usb_buffer_alloc(udev, sizeof(*(pm->configcr)),
 					SLAB_ATOMIC, &pm->configcr_dma);
 	if (!pm->configcr)
@@ -308,8 +309,9 @@
 	struct usb_host_interface *interface;
 	struct usb_endpoint_descriptor *endpoint;
 	struct powermate_device *pm;
+	struct input_dev *input_dev;
 	int pipe, maxp;
-	char path[64];
+	int err = -ENOMEM;
 
 	interface = intf->cur_altsetting;
 	endpoint = &interface->endpoint[0].desc;
@@ -323,42 +325,61 @@
 		0, interface->desc.bInterfaceNumber, NULL, 0,
 		USB_CTRL_SET_TIMEOUT);
 
-	if (!(pm = kmalloc(sizeof(struct powermate_device), GFP_KERNEL)))
-		return -ENOMEM;
+	pm = kzalloc(sizeof(struct powermate_device), GFP_KERNEL);
+	input_dev = input_allocate_device();
+	if (!pm || !input_dev)
+		goto fail1;
 
-	memset(pm, 0, sizeof(struct powermate_device));
-	pm->udev = udev;
-
-	if (powermate_alloc_buffers(udev, pm)) {
-		powermate_free_buffers(udev, pm);
-		kfree(pm);
-		return -ENOMEM;
-	}
+	if (powermate_alloc_buffers(udev, pm))
+		goto fail2;
 
 	pm->irq = usb_alloc_urb(0, GFP_KERNEL);
-	if (!pm->irq) {
-		powermate_free_buffers(udev, pm);
-		kfree(pm);
-		return -ENOMEM;
-	}
+	if (!pm->irq)
+		goto fail2;
 
 	pm->config = usb_alloc_urb(0, GFP_KERNEL);
-	if (!pm->config) {
-		usb_free_urb(pm->irq);
-		powermate_free_buffers(udev, pm);
-		kfree(pm);
-		return -ENOMEM;
-	}
+	if (!pm->config)
+		goto fail3;
+
+	pm->udev = udev;
+	pm->input = input_dev;
+
+	usb_make_path(udev, pm->phys, sizeof(pm->phys));
+	strlcpy(pm->phys, "/input0", sizeof(pm->phys));
 
 	spin_lock_init(&pm->lock);
-	init_input_dev(&pm->input);
+
+	switch (le16_to_cpu(udev->descriptor.idProduct)) {
+	case POWERMATE_PRODUCT_NEW:
+		input_dev->name = pm_name_powermate;
+		break;
+	case POWERMATE_PRODUCT_OLD:
+		input_dev->name = pm_name_soundknob;
+		break;
+	default:
+		input_dev->name = pm_name_soundknob;
+		printk(KERN_WARNING "powermate: unknown product id %04x\n",
+		       le16_to_cpu(udev->descriptor.idProduct));
+	}
+
+	input_dev->phys = pm->phys;
+	usb_to_input_id(udev, &input_dev->id);
+	input_dev->cdev.dev = &intf->dev;
+	input_dev->private = pm;
+
+	input_dev->event = powermate_input_event;
+
+	input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REL) | BIT(EV_MSC);
+	input_dev->keybit[LONG(BTN_0)] = BIT(BTN_0);
+	input_dev->relbit[LONG(REL_DIAL)] = BIT(REL_DIAL);
+	input_dev->mscbit[LONG(MSC_PULSELED)] = BIT(MSC_PULSELED);
 
 	/* get a handle to the interrupt data pipe */
 	pipe = usb_rcvintpipe(udev, endpoint->bEndpointAddress);
 	maxp = usb_maxpacket(udev, pipe, usb_pipeout(pipe));
 
-	if(maxp < POWERMATE_PAYLOAD_SIZE_MIN || maxp > POWERMATE_PAYLOAD_SIZE_MAX){
-		printk("powermate: Expected payload of %d--%d bytes, found %d bytes!\n",
+	if (maxp < POWERMATE_PAYLOAD_SIZE_MIN || maxp > POWERMATE_PAYLOAD_SIZE_MAX) {
+		printk(KERN_WARNING "powermate: Expected payload of %d--%d bytes, found %d bytes!\n",
 			POWERMATE_PAYLOAD_SIZE_MIN, POWERMATE_PAYLOAD_SIZE_MAX, maxp);
 		maxp = POWERMATE_PAYLOAD_SIZE_MAX;
 	}
@@ -371,35 +392,11 @@
 
 	/* register our interrupt URB with the USB system */
 	if (usb_submit_urb(pm->irq, GFP_KERNEL)) {
-		powermate_free_buffers(udev, pm);
-		kfree(pm);
-		return -EIO; /* failure */
+		err = -EIO;
+		goto fail4;
 	}
 
-	switch (le16_to_cpu(udev->descriptor.idProduct)) {
-	case POWERMATE_PRODUCT_NEW: pm->input.name = pm_name_powermate; break;
-	case POWERMATE_PRODUCT_OLD: pm->input.name = pm_name_soundknob; break;
-	default:
-		pm->input.name = pm_name_soundknob;
-		printk(KERN_WARNING "powermate: unknown product id %04x\n",
-		       le16_to_cpu(udev->descriptor.idProduct));
-	}
-
-	pm->input.private = pm;
-	pm->input.evbit[0] = BIT(EV_KEY) | BIT(EV_REL) | BIT(EV_MSC);
-	pm->input.keybit[LONG(BTN_0)] = BIT(BTN_0);
-	pm->input.relbit[LONG(REL_DIAL)] = BIT(REL_DIAL);
-	pm->input.mscbit[LONG(MSC_PULSELED)] = BIT(MSC_PULSELED);
-	usb_to_input_id(udev, &pm->input.id);
-	pm->input.event = powermate_input_event;
-	pm->input.dev = &intf->dev;
-	pm->input.phys = pm->phys;
-
-	input_register_device(&pm->input);
-
-	usb_make_path(udev, path, 64);
-	snprintf(pm->phys, 64, "%s/input0", path);
-	printk(KERN_INFO "input: %s on %s\n", pm->input.name, pm->input.phys);
+	input_register_device(pm->input);
 
 	/* force an update of everything */
 	pm->requires_update = UPDATE_PULSE_ASLEEP | UPDATE_PULSE_AWAKE | UPDATE_PULSE_MODE | UPDATE_STATIC_BRIGHTNESS;
@@ -407,6 +404,13 @@
 
 	usb_set_intfdata(intf, pm);
 	return 0;
+
+fail4:	usb_free_urb(pm->config);
+fail3:	usb_free_urb(pm->irq);
+fail2:	powermate_free_buffers(udev, pm);
+fail1:	input_free_device(input_dev);
+	kfree(pm);
+	return err;
 }
 
 /* Called when a USB device we've accepted ownership of is removed */
@@ -418,7 +422,7 @@
 	if (pm) {
 		pm->requires_update = 0;
 		usb_kill_urb(pm->irq);
-		input_unregister_device(&pm->input);
+		input_unregister_device(pm->input);
 		usb_free_urb(pm->irq);
 		usb_free_urb(pm->config);
 		powermate_free_buffers(interface_to_usbdev(intf), pm);
diff --git a/drivers/usb/input/touchkitusb.c b/drivers/usb/input/touchkitusb.c
index 4276c24..3766ccc 100644
--- a/drivers/usb/input/touchkitusb.c
+++ b/drivers/usb/input/touchkitusb.c
@@ -68,7 +68,7 @@
 	dma_addr_t data_dma;
 	struct urb *irq;
 	struct usb_device *udev;
-	struct input_dev input;
+	struct input_dev *input;
 	char name[128];
 	char phys[64];
 };
@@ -115,12 +115,12 @@
 		y = TOUCHKIT_GET_Y(touchkit->data);
 	}
 
-	input_regs(&touchkit->input, regs);
-	input_report_key(&touchkit->input, BTN_TOUCH,
+	input_regs(touchkit->input, regs);
+	input_report_key(touchkit->input, BTN_TOUCH,
 	                 TOUCHKIT_GET_TOUCHED(touchkit->data));
-	input_report_abs(&touchkit->input, ABS_X, x);
-	input_report_abs(&touchkit->input, ABS_Y, y);
-	input_sync(&touchkit->input);
+	input_report_abs(touchkit->input, ABS_X, x);
+	input_report_abs(touchkit->input, ABS_Y, y);
+	input_sync(touchkit->input);
 
 exit:
 	retval = usb_submit_urb(urb, GFP_ATOMIC);
@@ -171,87 +171,81 @@
 static int touchkit_probe(struct usb_interface *intf,
 			  const struct usb_device_id *id)
 {
-	int ret;
 	struct touchkit_usb *touchkit;
+	struct input_dev *input_dev;
 	struct usb_host_interface *interface;
 	struct usb_endpoint_descriptor *endpoint;
 	struct usb_device *udev = interface_to_usbdev(intf);
-	char path[64];
 
 	interface = intf->cur_altsetting;
 	endpoint = &interface->endpoint[0].desc;
 
-	touchkit = kmalloc(sizeof(struct touchkit_usb), GFP_KERNEL);
-	if (!touchkit)
-		return -ENOMEM;
-
-	memset(touchkit, 0, sizeof(struct touchkit_usb));
-	touchkit->udev = udev;
-
-	if (touchkit_alloc_buffers(udev, touchkit)) {
-		ret = -ENOMEM;
+	touchkit = kzalloc(sizeof(struct touchkit_usb), GFP_KERNEL);
+	input_dev = input_allocate_device();
+	if (!touchkit || !input_dev)
 		goto out_free;
-	}
 
-	touchkit->input.private = touchkit;
-	touchkit->input.open = touchkit_open;
-	touchkit->input.close = touchkit_close;
-
-	usb_make_path(udev, path, 64);
-	sprintf(touchkit->phys, "%s/input0", path);
-
-	touchkit->input.name = touchkit->name;
-	touchkit->input.phys = touchkit->phys;
-	usb_to_input_id(udev, &touchkit->input.id);
-	touchkit->input.dev = &intf->dev;
-
-	touchkit->input.evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
-	touchkit->input.absbit[0] = BIT(ABS_X) | BIT(ABS_Y);
-	touchkit->input.keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH);
-
-	/* Used to Scale Compensated Data */
-	touchkit->input.absmin[ABS_X] = TOUCHKIT_MIN_XC;
-	touchkit->input.absmax[ABS_X] = TOUCHKIT_MAX_XC;
-	touchkit->input.absfuzz[ABS_X] = TOUCHKIT_XC_FUZZ;
-	touchkit->input.absflat[ABS_X] = TOUCHKIT_XC_FLAT;
-	touchkit->input.absmin[ABS_Y] = TOUCHKIT_MIN_YC;
-	touchkit->input.absmax[ABS_Y] = TOUCHKIT_MAX_YC;
-	touchkit->input.absfuzz[ABS_Y] = TOUCHKIT_YC_FUZZ;
-	touchkit->input.absflat[ABS_Y] = TOUCHKIT_YC_FLAT;
-
-	if (udev->manufacturer)
-		strcat(touchkit->name, udev->manufacturer);
-	if (udev->product)
-		sprintf(touchkit->name, "%s %s", touchkit->name, udev->product);
-
-	if (!strlen(touchkit->name))
-		sprintf(touchkit->name, "USB Touchscreen %04x:%04x",
-		        touchkit->input.id.vendor, touchkit->input.id.product);
+	if (touchkit_alloc_buffers(udev, touchkit))
+		goto out_free;
 
 	touchkit->irq = usb_alloc_urb(0, GFP_KERNEL);
 	if (!touchkit->irq) {
 		dbg("%s - usb_alloc_urb failed: touchkit->irq", __FUNCTION__);
-		ret = -ENOMEM;
 		goto out_free_buffers;
 	}
 
+	touchkit->udev = udev;
+	touchkit->input = input_dev;
+
+	if (udev->manufacturer)
+		strlcpy(touchkit->name, udev->manufacturer, sizeof(touchkit->name));
+
+	if (udev->product) {
+		if (udev->manufacturer)
+			strlcat(touchkit->name, " ", sizeof(touchkit->name));
+		strlcat(touchkit->name, udev->product, sizeof(touchkit->name));
+	}
+
+	if (!strlen(touchkit->name))
+		snprintf(touchkit->name, sizeof(touchkit->name),
+			"USB Touchscreen %04x:%04x",
+			 le16_to_cpu(udev->descriptor.idVendor),
+			 le16_to_cpu(udev->descriptor.idProduct));
+
+	usb_make_path(udev, touchkit->phys, sizeof(touchkit->phys));
+	strlcpy(touchkit->phys, "/input0", sizeof(touchkit->phys));
+
+	input_dev->name = touchkit->name;
+	input_dev->phys = touchkit->phys;
+	usb_to_input_id(udev, &input_dev->id);
+	input_dev->cdev.dev = &intf->dev;
+	input_dev->private = touchkit;
+	input_dev->open = touchkit_open;
+	input_dev->close = touchkit_close;
+
+	input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
+	input_dev->keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH);
+	input_set_abs_params(input_dev, ABS_X, TOUCHKIT_MIN_XC, TOUCHKIT_MAX_XC,
+				TOUCHKIT_XC_FUZZ, TOUCHKIT_XC_FLAT);
+	input_set_abs_params(input_dev, ABS_Y, TOUCHKIT_MIN_YC, TOUCHKIT_MAX_YC,
+				TOUCHKIT_YC_FUZZ, TOUCHKIT_YC_FLAT);
+
 	usb_fill_int_urb(touchkit->irq, touchkit->udev,
-	                 usb_rcvintpipe(touchkit->udev, 0x81),
-	                 touchkit->data, TOUCHKIT_REPORT_DATA_SIZE,
-	                 touchkit_irq, touchkit, endpoint->bInterval);
+			 usb_rcvintpipe(touchkit->udev, 0x81),
+			 touchkit->data, TOUCHKIT_REPORT_DATA_SIZE,
+			 touchkit_irq, touchkit, endpoint->bInterval);
 
-	input_register_device(&touchkit->input);
+	input_register_device(touchkit->input);
 
-	printk(KERN_INFO "input: %s on %s\n", touchkit->name, path);
 	usb_set_intfdata(intf, touchkit);
-
 	return 0;
 
 out_free_buffers:
 	touchkit_free_buffers(udev, touchkit);
 out_free:
+	input_free_device(input_dev);
 	kfree(touchkit);
-	return ret;
+	return -ENOMEM;
 }
 
 static void touchkit_disconnect(struct usb_interface *intf)
@@ -265,8 +259,8 @@
 
 	dbg("%s - touchkit is initialized, cleaning up", __FUNCTION__);
 	usb_set_intfdata(intf, NULL);
-	input_unregister_device(&touchkit->input);
 	usb_kill_urb(touchkit->irq);
+	input_unregister_device(touchkit->input);
 	usb_free_urb(touchkit->irq);
 	touchkit_free_buffers(interface_to_usbdev(intf), touchkit);
 	kfree(touchkit);
diff --git a/drivers/usb/input/usbkbd.c b/drivers/usb/input/usbkbd.c
index 28987f1..226b6f9 100644
--- a/drivers/usb/input/usbkbd.c
+++ b/drivers/usb/input/usbkbd.c
@@ -66,7 +66,7 @@
 };
 
 struct usb_kbd {
-	struct input_dev dev;
+	struct input_dev *dev;
 	struct usb_device *usbdev;
 	unsigned char old[8];
 	struct urb *irq, *led;
@@ -99,29 +99,29 @@
 		goto resubmit;
 	}
 
-	input_regs(&kbd->dev, regs);
+	input_regs(kbd->dev, regs);
 
 	for (i = 0; i < 8; i++)
-		input_report_key(&kbd->dev, usb_kbd_keycode[i + 224], (kbd->new[0] >> i) & 1);
+		input_report_key(kbd->dev, usb_kbd_keycode[i + 224], (kbd->new[0] >> i) & 1);
 
 	for (i = 2; i < 8; i++) {
 
 		if (kbd->old[i] > 3 && memscan(kbd->new + 2, kbd->old[i], 6) == kbd->new + 8) {
 			if (usb_kbd_keycode[kbd->old[i]])
-				input_report_key(&kbd->dev, usb_kbd_keycode[kbd->old[i]], 0);
+				input_report_key(kbd->dev, usb_kbd_keycode[kbd->old[i]], 0);
 			else
 				info("Unknown key (scancode %#x) released.", kbd->old[i]);
 		}
 
 		if (kbd->new[i] > 3 && memscan(kbd->old + 2, kbd->new[i], 6) == kbd->old + 8) {
 			if (usb_kbd_keycode[kbd->new[i]])
-				input_report_key(&kbd->dev, usb_kbd_keycode[kbd->new[i]], 1);
+				input_report_key(kbd->dev, usb_kbd_keycode[kbd->new[i]], 1);
 			else
 				info("Unknown key (scancode %#x) pressed.", kbd->new[i]);
 		}
 	}
 
-	input_sync(&kbd->dev);
+	input_sync(kbd->dev);
 
 	memcpy(kbd->old, kbd->new, 8);
 
@@ -227,12 +227,12 @@
 static int usb_kbd_probe(struct usb_interface *iface,
 			 const struct usb_device_id *id)
 {
-	struct usb_device * dev = interface_to_usbdev(iface);
+	struct usb_device *dev = interface_to_usbdev(iface);
 	struct usb_host_interface *interface;
 	struct usb_endpoint_descriptor *endpoint;
 	struct usb_kbd *kbd;
+	struct input_dev *input_dev;
 	int i, pipe, maxp;
-	char path[64];
 
 	interface = iface->cur_altsetting;
 
@@ -240,37 +240,59 @@
 		return -ENODEV;
 
 	endpoint = &interface->endpoint[0].desc;
-	if (!(endpoint->bEndpointAddress & 0x80))
+	if (!(endpoint->bEndpointAddress & USB_DIR_IN))
 		return -ENODEV;
-	if ((endpoint->bmAttributes & 3) != 3)
+	if ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) != USB_ENDPOINT_XFER_INT)
 		return -ENODEV;
 
 	pipe = usb_rcvintpipe(dev, endpoint->bEndpointAddress);
 	maxp = usb_maxpacket(dev, pipe, usb_pipeout(pipe));
 
-	if (!(kbd = kmalloc(sizeof(struct usb_kbd), GFP_KERNEL)))
-		return -ENOMEM;
-	memset(kbd, 0, sizeof(struct usb_kbd));
+	kbd = kzalloc(sizeof(struct usb_kbd), GFP_KERNEL);
+	input_dev = input_allocate_device();
+	if (!kbd || !input_dev)
+		goto fail1;
 
-	if (usb_kbd_alloc_mem(dev, kbd)) {
-		usb_kbd_free_mem(dev, kbd);
-		kfree(kbd);
-		return -ENOMEM;
-	}
+	if (usb_kbd_alloc_mem(dev, kbd))
+		goto fail2;
 
 	kbd->usbdev = dev;
+	kbd->dev = input_dev;
 
-	kbd->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_LED) | BIT(EV_REP);
-	kbd->dev.ledbit[0] = BIT(LED_NUML) | BIT(LED_CAPSL) | BIT(LED_SCROLLL) | BIT(LED_COMPOSE) | BIT(LED_KANA);
+	if (dev->manufacturer)
+		strlcpy(kbd->name, dev->manufacturer, sizeof(kbd->name));
+
+	if (dev->product) {
+		if (dev->manufacturer)
+			strlcat(kbd->name, " ", sizeof(kbd->name));
+		strlcat(kbd->name, dev->product, sizeof(kbd->name));
+	}
+
+	if (!strlen(kbd->name))
+		snprintf(kbd->name, sizeof(kbd->name),
+			 "USB HIDBP Keyboard %04x:%04x",
+			 le16_to_cpu(dev->descriptor.idVendor),
+			 le16_to_cpu(dev->descriptor.idProduct));
+
+	usb_make_path(dev, kbd->phys, sizeof(kbd->phys));
+	strlcpy(kbd->phys, "/input0", sizeof(kbd->phys));
+
+	input_dev->name = kbd->name;
+	input_dev->phys = kbd->phys;
+	usb_to_input_id(dev, &input_dev->id);
+	input_dev->cdev.dev = &iface->dev;
+	input_dev->private = kbd;
+
+	input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_LED) | BIT(EV_REP);
+	input_dev->ledbit[0] = BIT(LED_NUML) | BIT(LED_CAPSL) | BIT(LED_SCROLLL) | BIT(LED_COMPOSE) | BIT(LED_KANA);
 
 	for (i = 0; i < 255; i++)
-		set_bit(usb_kbd_keycode[i], kbd->dev.keybit);
-	clear_bit(0, kbd->dev.keybit);
+		set_bit(usb_kbd_keycode[i], input_dev->keybit);
+	clear_bit(0, input_dev->keybit);
 
-	kbd->dev.private = kbd;
-	kbd->dev.event = usb_kbd_event;
-	kbd->dev.open = usb_kbd_open;
-	kbd->dev.close = usb_kbd_close;
+	input_dev->event = usb_kbd_event;
+	input_dev->open = usb_kbd_open;
+	input_dev->close = usb_kbd_close;
 
 	usb_fill_int_urb(kbd->irq, dev, pipe,
 			 kbd->new, (maxp > 8 ? 8 : maxp),
@@ -284,37 +306,22 @@
 	kbd->cr->wIndex = cpu_to_le16(interface->desc.bInterfaceNumber);
 	kbd->cr->wLength = cpu_to_le16(1);
 
-	usb_make_path(dev, path, 64);
-	sprintf(kbd->phys, "%s/input0", path);
-
-	kbd->dev.name = kbd->name;
-	kbd->dev.phys = kbd->phys;
-	usb_to_input_id(dev, &kbd->dev.id);
-	kbd->dev.dev = &iface->dev;
-
-	if (dev->manufacturer)
-		strcat(kbd->name, dev->manufacturer);
-	if (dev->product)
-		sprintf(kbd->name, "%s %s", kbd->name, dev->product);
-
-	if (!strlen(kbd->name))
-		sprintf(kbd->name, "USB HIDBP Keyboard %04x:%04x",
-			kbd->dev.id.vendor, kbd->dev.id.product);
-
 	usb_fill_control_urb(kbd->led, dev, usb_sndctrlpipe(dev, 0),
 			     (void *) kbd->cr, kbd->leds, 1,
 			     usb_kbd_led, kbd);
 	kbd->led->setup_dma = kbd->cr_dma;
 	kbd->led->transfer_dma = kbd->leds_dma;
-	kbd->led->transfer_flags |= (URB_NO_TRANSFER_DMA_MAP
-				| URB_NO_SETUP_DMA_MAP);
+	kbd->led->transfer_flags |= (URB_NO_TRANSFER_DMA_MAP | URB_NO_SETUP_DMA_MAP);
 
-	input_register_device(&kbd->dev);
-
-	printk(KERN_INFO "input: %s on %s\n", kbd->name, path);
+	input_register_device(kbd->dev);
 
 	usb_set_intfdata(iface, kbd);
 	return 0;
+
+fail2:	usb_kbd_free_mem(dev, kbd);
+fail1:	input_free_device(input_dev);
+	kfree(kbd);
+	return -ENOMEM;
 }
 
 static void usb_kbd_disconnect(struct usb_interface *intf)
@@ -324,7 +331,7 @@
 	usb_set_intfdata(intf, NULL);
 	if (kbd) {
 		usb_kill_urb(kbd->irq);
-		input_unregister_device(&kbd->dev);
+		input_unregister_device(kbd->dev);
 		usb_kbd_free_mem(interface_to_usbdev(intf), kbd);
 		kfree(kbd);
 	}
diff --git a/drivers/usb/input/usbmouse.c b/drivers/usb/input/usbmouse.c
index 4104dec..230f6b1 100644
--- a/drivers/usb/input/usbmouse.c
+++ b/drivers/usb/input/usbmouse.c
@@ -50,7 +50,7 @@
 	char name[128];
 	char phys[64];
 	struct usb_device *usbdev;
-	struct input_dev dev;
+	struct input_dev *dev;
 	struct urb *irq;
 
 	signed char *data;
@@ -61,7 +61,7 @@
 {
 	struct usb_mouse *mouse = urb->context;
 	signed char *data = mouse->data;
-	struct input_dev *dev = &mouse->dev;
+	struct input_dev *dev = mouse->dev;
 	int status;
 
 	switch (urb->status) {
@@ -115,14 +115,14 @@
 	usb_kill_urb(mouse->irq);
 }
 
-static int usb_mouse_probe(struct usb_interface * intf, const struct usb_device_id * id)
+static int usb_mouse_probe(struct usb_interface *intf, const struct usb_device_id *id)
 {
-	struct usb_device * dev = interface_to_usbdev(intf);
+	struct usb_device *dev = interface_to_usbdev(intf);
 	struct usb_host_interface *interface;
 	struct usb_endpoint_descriptor *endpoint;
 	struct usb_mouse *mouse;
+	struct input_dev *input_dev;
 	int pipe, maxp;
-	char path[64];
 
 	interface = intf->cur_altsetting;
 
@@ -130,59 +130,62 @@
 		return -ENODEV;
 
 	endpoint = &interface->endpoint[0].desc;
-	if (!(endpoint->bEndpointAddress & 0x80))
+	if (!(endpoint->bEndpointAddress & USB_DIR_IN))
 		return -ENODEV;
-	if ((endpoint->bmAttributes & 3) != 3)
+	if ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) != USB_ENDPOINT_XFER_INT)
 		return -ENODEV;
 
 	pipe = usb_rcvintpipe(dev, endpoint->bEndpointAddress);
 	maxp = usb_maxpacket(dev, pipe, usb_pipeout(pipe));
 
-	if (!(mouse = kmalloc(sizeof(struct usb_mouse), GFP_KERNEL)))
-		return -ENOMEM;
-	memset(mouse, 0, sizeof(struct usb_mouse));
+	mouse = kzalloc(sizeof(struct usb_mouse), GFP_KERNEL);
+	input_dev = input_allocate_device();
+	if (!mouse || !input_dev)
+		goto fail1;
 
 	mouse->data = usb_buffer_alloc(dev, 8, SLAB_ATOMIC, &mouse->data_dma);
-	if (!mouse->data) {
-		kfree(mouse);
-		return -ENOMEM;
-	}
+	if (!mouse->data)
+		goto fail1;
 
 	mouse->irq = usb_alloc_urb(0, GFP_KERNEL);
-	if (!mouse->irq) {
-		usb_buffer_free(dev, 8, mouse->data, mouse->data_dma);
-		kfree(mouse);
-		return -ENODEV;
-	}
+	if (!mouse->irq)
+		goto fail2;
 
 	mouse->usbdev = dev;
-
-	mouse->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_REL);
-	mouse->dev.keybit[LONG(BTN_MOUSE)] = BIT(BTN_LEFT) | BIT(BTN_RIGHT) | BIT(BTN_MIDDLE);
-	mouse->dev.relbit[0] = BIT(REL_X) | BIT(REL_Y);
-	mouse->dev.keybit[LONG(BTN_MOUSE)] |= BIT(BTN_SIDE) | BIT(BTN_EXTRA);
-	mouse->dev.relbit[0] |= BIT(REL_WHEEL);
-
-	mouse->dev.private = mouse;
-	mouse->dev.open = usb_mouse_open;
-	mouse->dev.close = usb_mouse_close;
-
-	usb_make_path(dev, path, 64);
-	sprintf(mouse->phys, "%s/input0", path);
-
-	mouse->dev.name = mouse->name;
-	mouse->dev.phys = mouse->phys;
-	usb_to_input_id(dev, &mouse->dev.id);
-	mouse->dev.dev = &intf->dev;
+	mouse->dev = input_dev;
 
 	if (dev->manufacturer)
-		strcat(mouse->name, dev->manufacturer);
-	if (dev->product)
-		sprintf(mouse->name, "%s %s", mouse->name, dev->product);
+		strlcpy(mouse->name, dev->manufacturer, sizeof(mouse->name));
+
+	if (dev->product) {
+		if (dev->manufacturer)
+			strlcat(mouse->name, " ", sizeof(mouse->name));
+		strlcat(mouse->name, dev->product, sizeof(mouse->name));
+	}
 
 	if (!strlen(mouse->name))
-		sprintf(mouse->name, "USB HIDBP Mouse %04x:%04x",
-			mouse->dev.id.vendor, mouse->dev.id.product);
+		snprintf(mouse->name, sizeof(mouse->name),
+			 "USB HIDBP Mouse %04x:%04x",
+			 le16_to_cpu(dev->descriptor.idVendor),
+			 le16_to_cpu(dev->descriptor.idProduct));
+
+	usb_make_path(dev, mouse->phys, sizeof(mouse->phys));
+	strlcat(mouse->phys, "/input0", sizeof(mouse->phys));
+
+	input_dev->name = mouse->name;
+	input_dev->phys = mouse->phys;
+	usb_to_input_id(dev, &input_dev->id);
+	input_dev->cdev.dev = &intf->dev;
+
+	input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REL);
+	input_dev->keybit[LONG(BTN_MOUSE)] = BIT(BTN_LEFT) | BIT(BTN_RIGHT) | BIT(BTN_MIDDLE);
+	input_dev->relbit[0] = BIT(REL_X) | BIT(REL_Y);
+	input_dev->keybit[LONG(BTN_MOUSE)] |= BIT(BTN_SIDE) | BIT(BTN_EXTRA);
+	input_dev->relbit[0] |= BIT(REL_WHEEL);
+
+	input_dev->private = mouse;
+	input_dev->open = usb_mouse_open;
+	input_dev->close = usb_mouse_close;
 
 	usb_fill_int_urb(mouse->irq, dev, pipe, mouse->data,
 			 (maxp > 8 ? 8 : maxp),
@@ -190,11 +193,15 @@
 	mouse->irq->transfer_dma = mouse->data_dma;
 	mouse->irq->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
 
-	input_register_device(&mouse->dev);
-	printk(KERN_INFO "input: %s on %s\n", mouse->name, path);
+	input_register_device(mouse->dev);
 
 	usb_set_intfdata(intf, mouse);
 	return 0;
+
+fail2:	usb_buffer_free(dev, 8, mouse->data, mouse->data_dma);
+fail1:	input_free_device(input_dev);
+	kfree(mouse);
+	return -ENOMEM;
 }
 
 static void usb_mouse_disconnect(struct usb_interface *intf)
@@ -204,7 +211,7 @@
 	usb_set_intfdata(intf, NULL);
 	if (mouse) {
 		usb_kill_urb(mouse->irq);
-		input_unregister_device(&mouse->dev);
+		input_unregister_device(mouse->dev);
 		usb_free_urb(mouse->irq);
 		usb_buffer_free(interface_to_usbdev(intf), 8, mouse->data, mouse->data_dma);
 		kfree(mouse);
diff --git a/drivers/usb/input/wacom.c b/drivers/usb/input/wacom.c
index 3b266af..ea0f757 100644
--- a/drivers/usb/input/wacom.c
+++ b/drivers/usb/input/wacom.c
@@ -111,7 +111,7 @@
 struct wacom {
 	signed char *data;
 	dma_addr_t data_dma;
-	struct input_dev dev;
+	struct input_dev *dev;
 	struct usb_device *usbdev;
 	struct urb *irq;
 	struct wacom_features *features;
@@ -135,7 +135,7 @@
 {
 	struct wacom *wacom = urb->context;
 	unsigned char *data = wacom->data;
-	struct input_dev *dev = &wacom->dev;
+	struct input_dev *dev = wacom->dev;
 	int prox, pressure;
 	int retval;
 
@@ -225,7 +225,7 @@
 {
 	struct wacom *wacom = urb->context;
 	unsigned char *data = wacom->data;
-	struct input_dev *dev = &wacom->dev;
+	struct input_dev *dev = wacom->dev;
 	int retval;
 
 	switch (urb->status) {
@@ -275,7 +275,7 @@
 {
 	struct wacom *wacom = urb->context;
 	unsigned char *data = wacom->data;
-	struct input_dev *dev = &wacom->dev;
+	struct input_dev *dev = wacom->dev;
 	int retval;
 
 	switch (urb->status) {
@@ -318,7 +318,7 @@
 {
 	struct wacom *wacom = urb->context;
 	unsigned char *data = wacom->data;
-	struct input_dev *dev = &wacom->dev;
+	struct input_dev *dev = wacom->dev;
 	int x, y;
 	int retval;
 
@@ -397,7 +397,7 @@
 {
 	struct wacom *wacom = urb->context;
 	unsigned char *data = wacom->data;
-	struct input_dev *dev = &wacom->dev;
+	struct input_dev *dev = wacom->dev;
 	int idx;
 
 	/* tool number */
@@ -479,7 +479,7 @@
 {
 	struct wacom *wacom = urb->context;
 	unsigned char *data = wacom->data;
-	struct input_dev *dev = &wacom->dev;
+	struct input_dev *dev = wacom->dev;
 	unsigned int t;
 
 	/* general pen packet */
@@ -509,7 +509,7 @@
 {
 	struct wacom *wacom = urb->context;
 	unsigned char *data = wacom->data;
-	struct input_dev *dev = &wacom->dev;
+	struct input_dev *dev = wacom->dev;
 	unsigned int t;
 	int idx;
 	int retval;
@@ -738,95 +738,83 @@
 {
 	struct usb_device *dev = interface_to_usbdev(intf);
 	struct usb_endpoint_descriptor *endpoint;
-	char rep_data[2] = {0x02, 0x02};
 	struct wacom *wacom;
-	char path[64];
+	struct input_dev *input_dev;
+	char rep_data[2] = {0x02, 0x02};
 
-	if (!(wacom = kmalloc(sizeof(struct wacom), GFP_KERNEL)))
-		return -ENOMEM;
-	memset(wacom, 0, sizeof(struct wacom));
+	wacom = kzalloc(sizeof(struct wacom), GFP_KERNEL);
+	input_dev = input_allocate_device();
+	if (!wacom || !input_dev)
+		goto fail1;
 
 	wacom->data = usb_buffer_alloc(dev, 10, GFP_KERNEL, &wacom->data_dma);
-	if (!wacom->data) {
-		kfree(wacom);
-		return -ENOMEM;
-	}
+	if (!wacom->data)
+		goto fail1;
 
 	wacom->irq = usb_alloc_urb(0, GFP_KERNEL);
-	if (!wacom->irq) {
-		usb_buffer_free(dev, 10, wacom->data, wacom->data_dma);
-		kfree(wacom);
-		return -ENOMEM;
-	}
+	if (!wacom->irq)
+		goto fail2;
+
+	wacom->usbdev = dev;
+	wacom->dev = input_dev;
+	usb_make_path(dev, wacom->phys, sizeof(wacom->phys));
+	strlcat(wacom->phys, "/input0", sizeof(wacom->phys));
 
 	wacom->features = wacom_features + (id - wacom_ids);
+	if (wacom->features->pktlen > 10)
+		BUG();
 
-	wacom->dev.evbit[0] |= BIT(EV_KEY) | BIT(EV_ABS);
-	wacom->dev.absbit[0] |= BIT(ABS_X) | BIT(ABS_Y) | BIT(ABS_PRESSURE);
-	wacom->dev.keybit[LONG(BTN_DIGI)] |= BIT(BTN_TOOL_PEN) | BIT(BTN_TOUCH) | BIT(BTN_STYLUS);
+	input_dev->name = wacom->features->name;
+	usb_to_input_id(dev, &input_dev->id);
+
+	input_dev->cdev.dev = &intf->dev;
+	input_dev->private = wacom;
+	input_dev->open = wacom_open;
+	input_dev->close = wacom_close;
+
+	input_dev->evbit[0] |= BIT(EV_KEY) | BIT(EV_ABS);
+	input_dev->keybit[LONG(BTN_DIGI)] |= BIT(BTN_TOOL_PEN) | BIT(BTN_TOUCH) | BIT(BTN_STYLUS);
+	input_set_abs_params(input_dev, ABS_X, 0, wacom->features->y_max, 4, 0);
+	input_set_abs_params(input_dev, ABS_Y, 0, wacom->features->y_max, 4, 0);
+	input_set_abs_params(input_dev, ABS_PRESSURE, 0, wacom->features->pressure_max, 0, 0);
 
 	switch (wacom->features->type) {
 		case GRAPHIRE:
-			wacom->dev.evbit[0] |= BIT(EV_REL);
-			wacom->dev.relbit[0] |= BIT(REL_WHEEL);
-			wacom->dev.absbit[0] |= BIT(ABS_DISTANCE);
-			wacom->dev.keybit[LONG(BTN_LEFT)] |= BIT(BTN_LEFT) | BIT(BTN_RIGHT) | BIT(BTN_MIDDLE);
-			wacom->dev.keybit[LONG(BTN_DIGI)] |= BIT(BTN_TOOL_RUBBER) | BIT(BTN_TOOL_MOUSE) | BIT(BTN_STYLUS2);
+			input_dev->evbit[0] |= BIT(EV_REL);
+			input_dev->relbit[0] |= BIT(REL_WHEEL);
+			input_dev->keybit[LONG(BTN_LEFT)] |= BIT(BTN_LEFT) | BIT(BTN_RIGHT) | BIT(BTN_MIDDLE);
+			input_dev->keybit[LONG(BTN_DIGI)] |= BIT(BTN_TOOL_RUBBER) | BIT(BTN_TOOL_MOUSE) | BIT(BTN_STYLUS2);
+			input_set_abs_params(input_dev, ABS_DISTANCE, 0, wacom->features->distance_max, 0, 0);
 			break;
 
 		case INTUOS3:
 		case CINTIQ:
-			wacom->dev.keybit[LONG(BTN_DIGI)] |= BIT(BTN_TOOL_FINGER);
-			wacom->dev.keybit[LONG(BTN_LEFT)] |= BIT(BTN_0) | BIT(BTN_1) | BIT(BTN_2) | BIT(BTN_3) | BIT(BTN_4) | BIT(BTN_5) | BIT(BTN_6) | BIT(BTN_7);
-			wacom->dev.absbit[0] |= BIT(ABS_RX) | BIT(ABS_RY);
+			input_dev->keybit[LONG(BTN_DIGI)] |= BIT(BTN_TOOL_FINGER);
+			input_dev->keybit[LONG(BTN_LEFT)] |= BIT(BTN_0) | BIT(BTN_1) | BIT(BTN_2) | BIT(BTN_3) | BIT(BTN_4) | BIT(BTN_5) | BIT(BTN_6) | BIT(BTN_7);
+			input_set_abs_params(input_dev, ABS_RX, 0, 4097, 0, 0);
+			input_set_abs_params(input_dev, ABS_RY, 0, 4097, 0, 0);
 			/* fall through */
 
 		case INTUOS:
-			wacom->dev.evbit[0] |= BIT(EV_MSC) | BIT(EV_REL);
-			wacom->dev.mscbit[0] |= BIT(MSC_SERIAL);
-			wacom->dev.relbit[0] |= BIT(REL_WHEEL);
-			wacom->dev.keybit[LONG(BTN_LEFT)] |= BIT(BTN_LEFT) | BIT(BTN_RIGHT) | BIT(BTN_MIDDLE) | BIT(BTN_SIDE) | BIT(BTN_EXTRA);
-			wacom->dev.keybit[LONG(BTN_DIGI)] |= BIT(BTN_TOOL_RUBBER) | BIT(BTN_TOOL_MOUSE)	| BIT(BTN_TOOL_BRUSH)
+			input_dev->evbit[0] |= BIT(EV_MSC) | BIT(EV_REL);
+			input_dev->mscbit[0] |= BIT(MSC_SERIAL);
+			input_dev->relbit[0] |= BIT(REL_WHEEL);
+			input_dev->keybit[LONG(BTN_LEFT)] |= BIT(BTN_LEFT) | BIT(BTN_RIGHT) | BIT(BTN_MIDDLE) | BIT(BTN_SIDE) | BIT(BTN_EXTRA);
+			input_dev->keybit[LONG(BTN_DIGI)] |= BIT(BTN_TOOL_RUBBER) | BIT(BTN_TOOL_MOUSE)	| BIT(BTN_TOOL_BRUSH)
 							  | BIT(BTN_TOOL_PENCIL) | BIT(BTN_TOOL_AIRBRUSH) | BIT(BTN_TOOL_LENS) | BIT(BTN_STYLUS2);
-			wacom->dev.absbit[0] |= BIT(ABS_DISTANCE) | BIT(ABS_WHEEL) | BIT(ABS_TILT_X) | BIT(ABS_TILT_Y) | BIT(ABS_RZ) | BIT(ABS_THROTTLE);
+			input_set_abs_params(input_dev, ABS_DISTANCE, 0, wacom->features->distance_max, 0, 0);
+			input_set_abs_params(input_dev, ABS_WHEEL, 0, 1023, 0, 0);
+			input_set_abs_params(input_dev, ABS_TILT_X, 0, 127, 0, 0);
+			input_set_abs_params(input_dev, ABS_TILT_Y, 0, 127, 0, 0);
+			input_set_abs_params(input_dev, ABS_RZ, -900, 899, 0, 0);
+			input_set_abs_params(input_dev, ABS_THROTTLE, -1023, 1023, 0, 0);
 			break;
 
 		case PL:
-			wacom->dev.keybit[LONG(BTN_DIGI)] |= BIT(BTN_STYLUS2) | BIT(BTN_TOOL_RUBBER);
+			input_dev->keybit[LONG(BTN_DIGI)] |= BIT(BTN_STYLUS2) | BIT(BTN_TOOL_RUBBER);
 			break;
 	}
 
-	wacom->dev.absmax[ABS_X] = wacom->features->x_max;
-	wacom->dev.absmax[ABS_Y] = wacom->features->y_max;
-	wacom->dev.absmax[ABS_PRESSURE] = wacom->features->pressure_max;
-	wacom->dev.absmax[ABS_DISTANCE] = wacom->features->distance_max;
-	wacom->dev.absmax[ABS_TILT_X] = 127;
-	wacom->dev.absmax[ABS_TILT_Y] = 127;
-	wacom->dev.absmax[ABS_WHEEL] = 1023;
-
-	wacom->dev.absmax[ABS_RX] = 4097;
-	wacom->dev.absmax[ABS_RY] = 4097;
-	wacom->dev.absmin[ABS_RZ] = -900;
-	wacom->dev.absmax[ABS_RZ] = 899;
-	wacom->dev.absmin[ABS_THROTTLE] = -1023;
-	wacom->dev.absmax[ABS_THROTTLE] = 1023;
-
-	wacom->dev.absfuzz[ABS_X] = 4;
-	wacom->dev.absfuzz[ABS_Y] = 4;
-
-	wacom->dev.private = wacom;
-	wacom->dev.open = wacom_open;
-	wacom->dev.close = wacom_close;
-
-	usb_make_path(dev, path, 64);
-	sprintf(wacom->phys, "%s/input0", path);
-
-	wacom->dev.name = wacom->features->name;
-	wacom->dev.phys = wacom->phys;
-	usb_to_input_id(dev, &wacom->dev.id);
-	wacom->dev.dev = &intf->dev;
-	wacom->usbdev = dev;
-
 	endpoint = &intf->cur_altsetting->endpoint[0].desc;
 
 	if (wacom->features->pktlen > 10)
@@ -839,18 +827,20 @@
 	wacom->irq->transfer_dma = wacom->data_dma;
 	wacom->irq->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
 
-	input_register_device(&wacom->dev);
+	input_register_device(wacom->dev);
 
 	/* ask the tablet to report tablet data */
 	usb_set_report(intf, 3, 2, rep_data, 2);
 	/* repeat once (not sure why the first call often fails) */
 	usb_set_report(intf, 3, 2, rep_data, 2);
 
-	printk(KERN_INFO "input: %s on %s\n", wacom->features->name, path);
-
 	usb_set_intfdata(intf, wacom);
-
 	return 0;
+
+fail2:	usb_buffer_free(dev, 10, wacom->data, wacom->data_dma);
+fail1:	input_free_device(input_dev);
+	kfree(wacom);
+	return -ENOMEM;
 }
 
 static void wacom_disconnect(struct usb_interface *intf)
@@ -860,7 +850,7 @@
 	usb_set_intfdata(intf, NULL);
 	if (wacom) {
 		usb_kill_urb(wacom->irq);
-		input_unregister_device(&wacom->dev);
+		input_unregister_device(wacom->dev);
 		usb_free_urb(wacom->irq);
 		usb_buffer_free(interface_to_usbdev(intf), 10, wacom->data, wacom->data_dma);
 		kfree(wacom);
diff --git a/drivers/usb/input/xpad.c b/drivers/usb/input/xpad.c
index 18125e0..43112f0 100644
--- a/drivers/usb/input/xpad.c
+++ b/drivers/usb/input/xpad.c
@@ -103,7 +103,7 @@
 MODULE_DEVICE_TABLE (usb, xpad_table);
 
 struct usb_xpad {
-	struct input_dev dev;			/* input device interface */
+	struct input_dev *dev;			/* input device interface */
 	struct usb_device *udev;		/* usb device */
 
 	struct urb *irq_in;			/* urb for interrupt in report */
@@ -125,7 +125,7 @@
 
 static void xpad_process_packet(struct usb_xpad *xpad, u16 cmd, unsigned char *data, struct pt_regs *regs)
 {
-	struct input_dev *dev = &xpad->dev;
+	struct input_dev *dev = xpad->dev;
 
 	input_regs(dev, regs);
 
@@ -214,9 +214,9 @@
 static int xpad_probe(struct usb_interface *intf, const struct usb_device_id *id)
 {
 	struct usb_device *udev = interface_to_usbdev (intf);
-	struct usb_xpad *xpad = NULL;
+	struct usb_xpad *xpad;
+	struct input_dev *input_dev;
 	struct usb_endpoint_descriptor *ep_irq_in;
-	char path[64];
 	int i;
 
 	for (i = 0; xpad_device[i].idVendor; i++) {
@@ -225,29 +225,63 @@
 			break;
 	}
 
-	if ((xpad = kmalloc (sizeof(struct usb_xpad), GFP_KERNEL)) == NULL) {
-		err("cannot allocate memory for new pad");
-		return -ENOMEM;
-	}
-	memset(xpad, 0, sizeof(struct usb_xpad));
+	xpad = kzalloc(sizeof(struct usb_xpad), GFP_KERNEL);
+	input_dev = input_allocate_device();
+	if (!xpad || !input_dev)
+		goto fail1;
 
 	xpad->idata = usb_buffer_alloc(udev, XPAD_PKT_LEN,
 				       SLAB_ATOMIC, &xpad->idata_dma);
-	if (!xpad->idata) {
-		kfree(xpad);
-		return -ENOMEM;
-	}
+	if (!xpad->idata)
+		goto fail1;
 
 	xpad->irq_in = usb_alloc_urb(0, GFP_KERNEL);
-        if (!xpad->irq_in) {
-		err("cannot allocate memory for new pad irq urb");
-		usb_buffer_free(udev, XPAD_PKT_LEN, xpad->idata, xpad->idata_dma);
-                kfree(xpad);
-		return -ENOMEM;
-        }
+	if (!xpad->irq_in)
+		goto fail2;
+
+	xpad->udev = udev;
+	xpad->dev = input_dev;
+	usb_make_path(udev, xpad->phys, sizeof(xpad->phys));
+	strlcat(xpad->phys, "/input0", sizeof(xpad->phys));
+
+	input_dev->name = xpad_device[i].name;
+	input_dev->phys = xpad->phys;
+	usb_to_input_id(udev, &input_dev->id);
+	input_dev->cdev.dev = &intf->dev;
+	input_dev->private = xpad;
+	input_dev->open = xpad_open;
+	input_dev->close = xpad_close;
+
+	input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
+
+	for (i = 0; xpad_btn[i] >= 0; i++)
+		set_bit(xpad_btn[i], input_dev->keybit);
+
+	for (i = 0; xpad_abs[i] >= 0; i++) {
+
+		signed short t = xpad_abs[i];
+
+		set_bit(t, input_dev->absbit);
+
+		switch (t) {
+			case ABS_X:
+			case ABS_Y:
+			case ABS_RX:
+			case ABS_RY:	/* the two sticks */
+				input_set_abs_params(input_dev, t, -32768, 32767, 16, 128);
+				break;
+			case ABS_Z:
+			case ABS_RZ:	/* the triggers */
+				input_set_abs_params(input_dev, t, 0, 255, 0, 0);
+				break;
+			case ABS_HAT0X:
+			case ABS_HAT0Y:	/* the d-pad */
+				input_set_abs_params(input_dev, t, -1, 1, 0, 0);
+				break;
+		}
+	}
 
 	ep_irq_in = &intf->cur_altsetting->endpoint[0].desc;
-
 	usb_fill_int_urb(xpad->irq_in, udev,
 			 usb_rcvintpipe(udev, ep_irq_in->bEndpointAddress),
 			 xpad->idata, XPAD_PKT_LEN, xpad_irq_in,
@@ -255,59 +289,16 @@
 	xpad->irq_in->transfer_dma = xpad->idata_dma;
 	xpad->irq_in->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
 
-	xpad->udev = udev;
-
-	usb_to_input_id(udev, &xpad->dev.id);
-	xpad->dev.dev = &intf->dev;
-	xpad->dev.private = xpad;
-	xpad->dev.name = xpad_device[i].name;
-	xpad->dev.phys = xpad->phys;
-	xpad->dev.open = xpad_open;
-	xpad->dev.close = xpad_close;
-
-	usb_make_path(udev, path, 64);
-	snprintf(xpad->phys, 64,  "%s/input0", path);
-
-	xpad->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
-
-	for (i = 0; xpad_btn[i] >= 0; i++)
-		set_bit(xpad_btn[i], xpad->dev.keybit);
-
-	for (i = 0; xpad_abs[i] >= 0; i++) {
-
-		signed short t = xpad_abs[i];
-
-		set_bit(t, xpad->dev.absbit);
-
-		switch (t) {
-			case ABS_X:
-			case ABS_Y:
-			case ABS_RX:
-			case ABS_RY:	/* the two sticks */
-				xpad->dev.absmax[t] =  32767;
-				xpad->dev.absmin[t] = -32768;
-				xpad->dev.absflat[t] = 128;
-				xpad->dev.absfuzz[t] = 16;
-				break;
-			case ABS_Z:
-			case ABS_RZ:	/* the triggers */
-				xpad->dev.absmax[t] = 255;
-				xpad->dev.absmin[t] = 0;
-				break;
-			case ABS_HAT0X:
-			case ABS_HAT0Y:	/* the d-pad */
-				xpad->dev.absmax[t] =  1;
-				xpad->dev.absmin[t] = -1;
-				break;
-		}
-	}
-
-	input_register_device(&xpad->dev);
-
-	printk(KERN_INFO "input: %s on %s", xpad->dev.name, path);
+	input_register_device(xpad->dev);
 
 	usb_set_intfdata(intf, xpad);
 	return 0;
+
+fail2:	usb_buffer_free(udev, XPAD_PKT_LEN, xpad->idata, xpad->idata_dma);
+fail1:	input_free_device(input_dev);
+	kfree(xpad);
+	return -ENOMEM;
+
 }
 
 static void xpad_disconnect(struct usb_interface *intf)
@@ -317,7 +308,7 @@
 	usb_set_intfdata(intf, NULL);
 	if (xpad) {
 		usb_kill_urb(xpad->irq_in);
-		input_unregister_device(&xpad->dev);
+		input_unregister_device(xpad->dev);
 		usb_free_urb(xpad->irq_in);
 		usb_buffer_free(interface_to_usbdev(intf), XPAD_PKT_LEN, xpad->idata, xpad->idata_dma);
 		kfree(xpad);
diff --git a/drivers/usb/input/yealink.c b/drivers/usb/input/yealink.c
index 58a176e..f526aeb 100644
--- a/drivers/usb/input/yealink.c
+++ b/drivers/usb/input/yealink.c
@@ -54,6 +54,7 @@
 #include <linux/module.h>
 #include <linux/rwsem.h>
 #include <linux/usb.h>
+#include <linux/usb_input.h>
 
 #include "map_to_7segment.h"
 #include "yealink.h"
@@ -101,12 +102,12 @@
 };
 
 struct yealink_dev {
-	struct input_dev idev;		/* input device */
+	struct input_dev *idev;		/* input device */
 	struct usb_device *udev;	/* usb device */
 
 	/* irq input channel */
 	struct yld_ctl_packet	*irq_data;
-	dma_addr_t 		irq_dma;
+	dma_addr_t		irq_dma;
 	struct urb		*urb_irq;
 
 	/* control output channel */
@@ -237,7 +238,7 @@
  */
 static void report_key(struct yealink_dev *yld, int key, struct pt_regs *regs)
 {
-	struct input_dev *idev = &yld->idev;
+	struct input_dev *idev = yld->idev;
 
 	input_regs(idev, regs);
 	if (yld->key_code >= 0) {
@@ -809,8 +810,12 @@
 	}
         if (yld->urb_ctl)
 		usb_free_urb(yld->urb_ctl);
-        if (yld->idev.dev)
-		input_unregister_device(&yld->idev);
+        if (yld->idev) {
+		if (err)
+			input_free_device(yld->idev);
+		else
+			input_unregister_device(yld->idev);
+	}
 	if (yld->ctl_req)
 		usb_buffer_free(yld->udev, sizeof(*(yld->ctl_req)),
 				yld->ctl_req, yld->ctl_req_dma);
@@ -857,7 +862,7 @@
 	struct usb_host_interface *interface;
 	struct usb_endpoint_descriptor *endpoint;
 	struct yealink_dev *yld;
-	char path[64];
+	struct input_dev *input_dev;
 	int ret, pipe, i;
 
 	i = usb_match(udev);
@@ -866,17 +871,21 @@
 
 	interface = intf->cur_altsetting;
 	endpoint = &interface->endpoint[0].desc;
-	if (!(endpoint->bEndpointAddress & 0x80))
+	if (!(endpoint->bEndpointAddress & USB_DIR_IN))
 		return -EIO;
-	if ((endpoint->bmAttributes & 3) != 3)
+	if ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) != USB_ENDPOINT_XFER_INT)
 		return -EIO;
 
-	if ((yld = kmalloc(sizeof(struct yealink_dev), GFP_KERNEL)) == NULL)
+	yld = kzalloc(sizeof(struct yealink_dev), GFP_KERNEL);
+	if (!yld)
 		return -ENOMEM;
 
-	memset(yld, 0, sizeof(*yld));
 	yld->udev = udev;
 
+	yld->idev = input_dev = input_allocate_device();
+	if (!input_dev)
+		return usb_cleanup(yld, -ENOMEM);
+
 	/* allocate usb buffers */
 	yld->irq_data = usb_buffer_alloc(udev, USB_PKT_LEN,
 					SLAB_ATOMIC, &yld->irq_dma);
@@ -935,42 +944,37 @@
 	yld->urb_ctl->dev = udev;
 
 	/* find out the physical bus location */
-	if (usb_make_path(udev, path, sizeof(path)) > 0)
-		snprintf(yld->phys, sizeof(yld->phys)-1,  "%s/input0", path);
+	usb_make_path(udev, yld->phys, sizeof(yld->phys));
+	strlcat(yld->phys,  "/input0", sizeof(yld->phys));
 
 	/* register settings for the input device */
-	init_input_dev(&yld->idev);
-	yld->idev.private	= yld;
-	yld->idev.id.bustype	= BUS_USB;
-	yld->idev.id.vendor	= le16_to_cpu(udev->descriptor.idVendor);
-	yld->idev.id.product	= le16_to_cpu(udev->descriptor.idProduct);
-	yld->idev.id.version	= le16_to_cpu(udev->descriptor.bcdDevice);
-	yld->idev.dev		= &intf->dev;
-	yld->idev.name		= yld_device[i].name;
-	yld->idev.phys		= yld->phys;
-	/* yld->idev.event		= input_ev;	TODO */
-	yld->idev.open		= input_open;
-	yld->idev.close		= input_close;
+	input_dev->name = yld_device[i].name;
+	input_dev->phys = yld->phys;
+	usb_to_input_id(udev, &input_dev->id);
+	input_dev->cdev.dev = &intf->dev;
+
+	input_dev->private = yld;
+	input_dev->open = input_open;
+	input_dev->close = input_close;
+	/* input_dev->event = input_ev;	TODO */
 
 	/* register available key events */
-	yld->idev.evbit[0] = BIT(EV_KEY);
+	input_dev->evbit[0] = BIT(EV_KEY);
 	for (i = 0; i < 256; i++) {
 		int k = map_p1k_to_key(i);
 		if (k >= 0) {
-			set_bit(k & 0xff, yld->idev.keybit);
+			set_bit(k & 0xff, input_dev->keybit);
 			if (k >> 8)
-				set_bit(k >> 8, yld->idev.keybit);
+				set_bit(k >> 8, input_dev->keybit);
 		}
 	}
 
-	printk(KERN_INFO "input: %s on %s\n", yld->idev.name, path);
-
-	input_register_device(&yld->idev);
+	input_register_device(yld->idev);
 
 	usb_set_intfdata(intf, yld);
 
 	/* clear visible elements */
-	for (i=0; i<ARRAY_SIZE(lcdMap); i++)
+	for (i = 0; i < ARRAY_SIZE(lcdMap); i++)
 		setChar(yld, i, ' ');
 
 	/* display driver version on LCD line 3 */
diff --git a/drivers/usb/media/konicawc.c b/drivers/usb/media/konicawc.c
index 20ac9e1..9fe2c27 100644
--- a/drivers/usb/media/konicawc.c
+++ b/drivers/usb/media/konicawc.c
@@ -119,7 +119,7 @@
 	int yplanesz;		/* Number of bytes in the Y plane */
 	unsigned int buttonsts:1;
 #ifdef CONFIG_INPUT
-	struct input_dev input;
+	struct input_dev *input;
 	char input_physname[64];
 #endif
 };
@@ -218,6 +218,57 @@
 	konicawc_camera_on(uvd);
 }
 
+#ifdef CONFIG_INPUT
+
+static void konicawc_register_input(struct konicawc *cam, struct usb_device *dev)
+{
+	struct input_dev *input_dev;
+
+	usb_make_path(dev, cam->input_physname, sizeof(cam->input_physname));
+	strncat(cam->input_physname, "/input0", sizeof(cam->input_physname));
+
+	cam->input = input_dev = input_allocate_device();
+	if (!input_dev) {
+		warn("Not enough memory for camera's input device\n");
+		return;
+	}
+
+	input_dev->name = "Konicawc snapshot button";
+	input_dev->phys = cam->input_physname;
+	usb_to_input_id(dev, &input_dev->id);
+	input_dev->cdev.dev = &dev->dev;
+
+	input_dev->evbit[0] = BIT(EV_KEY);
+	input_dev->keybit[LONG(BTN_0)] = BIT(BTN_0);
+
+	input_dev->private = cam;
+
+	input_register_device(cam->input);
+}
+
+static void konicawc_unregister_input(struct konicawc *cam)
+{
+	if (cam->input) {
+		input_unregister_device(cam->input);
+		cam->input = NULL;
+	}
+}
+
+static void konicawc_report_buttonstat(struct konicawc *cam)
+{
+	if (cam->input) {
+		input_report_key(cam->input, BTN_0, cam->buttonsts);
+		input_sync(cam->input);
+	}
+}
+
+#else
+
+static inline void konicawc_register_input(struct konicawc *cam, struct usb_device *dev) { }
+static inline void konicawc_unregister_input(struct konicawc *cam) { }
+static inline void konicawc_report_buttonstat(struct konicawc *cam) { }
+
+#endif /* CONFIG_INPUT */
 
 static int konicawc_compress_iso(struct uvd *uvd, struct urb *dataurb, struct urb *stsurb)
 {
@@ -273,10 +324,7 @@
 		if(button != cam->buttonsts) {
 			DEBUG(2, "button: %sclicked", button ? "" : "un");
 			cam->buttonsts = button;
-#ifdef CONFIG_INPUT
-			input_report_key(&cam->input, BTN_0, cam->buttonsts);
-			input_sync(&cam->input);
-#endif
+			konicawc_report_buttonstat(cam);
 		}
 
 		if(sts == 0x01) { /* drop frame */
@@ -645,9 +693,9 @@
 	RingQueue_Flush(&uvd->dp);
 	cam->lastframe = -2;
 	if(uvd->curframe != -1) {
-	  uvd->frame[uvd->curframe].curline = 0;
-	  uvd->frame[uvd->curframe].seqRead_Length = 0;
-	  uvd->frame[uvd->curframe].seqRead_Index = 0;
+		uvd->frame[uvd->curframe].curline = 0;
+		uvd->frame[uvd->curframe].seqRead_Length = 0;
+		uvd->frame[uvd->curframe].seqRead_Index = 0;
 	}
 
 	konicawc_start_data(uvd);
@@ -718,7 +766,6 @@
 	DEBUG(1, "setting initial values");
 }
 
-
 static int konicawc_probe(struct usb_interface *intf, const struct usb_device_id *devid)
 {
 	struct usb_device *dev = interface_to_usbdev(intf);
@@ -839,21 +886,8 @@
 			err("usbvideo_RegisterVideoDevice() failed.");
 			uvd = NULL;
 		}
-#ifdef CONFIG_INPUT
-		/* Register input device for button */
-		memset(&cam->input, 0, sizeof(struct input_dev));
-		cam->input.name = "Konicawc snapshot button";
-		cam->input.private = cam;
-		cam->input.evbit[0] = BIT(EV_KEY);
-		cam->input.keybit[LONG(BTN_0)] = BIT(BTN_0);
-		usb_to_input_id(dev, &cam->input.id);
-		input_register_device(&cam->input);
-		
-		usb_make_path(dev, cam->input_physname, 56);
-		strcat(cam->input_physname, "/input0");
-		cam->input.phys = cam->input_physname;
-		info("konicawc: %s on %s\n", cam->input.name, cam->input.phys);
-#endif
+
+		konicawc_register_input(cam, dev);
 	}
 
 	if (uvd) {
@@ -869,10 +903,9 @@
 	int i;
 	struct konicawc *cam = (struct konicawc *)uvd->user_data;
 
-#ifdef CONFIG_INPUT
-	input_unregister_device(&cam->input);
-#endif
-	for (i=0; i < USBVIDEO_NUMSBUF; i++) {
+	konicawc_unregister_input(cam);
+
+	for (i = 0; i < USBVIDEO_NUMSBUF; i++) {
 		usb_free_urb(cam->sts_urb[i]);
 		cam->sts_urb[i] = NULL;
 	}
diff --git a/drivers/usb/storage/onetouch.c b/drivers/usb/storage/onetouch.c
index 2c9402d..89401a5 100644
--- a/drivers/usb/storage/onetouch.c
+++ b/drivers/usb/storage/onetouch.c
@@ -5,7 +5,7 @@
  *	Copyright (c) 2005 Nick Sillik <n.sillik@temple.edu>
  *
  * Initial work by:
- * 	Copyright (c) 2003 Erik Thyren <erth7411@student.uu.se>
+ *	Copyright (c) 2003 Erik Thyren <erth7411@student.uu.se>
  *
  * Based on usbmouse.c (Vojtech Pavlik) and xpad.c (Marko Friedemann)
  *
@@ -46,7 +46,7 @@
 struct usb_onetouch {
 	char name[128];
 	char phys[64];
-	struct input_dev dev;	/* input device interface */
+	struct input_dev *dev;	/* input device interface */
 	struct usb_device *udev;	/* usb device */
 
 	struct urb *irq;	/* urb for interrupt in report */
@@ -58,7 +58,7 @@
 {
 	struct usb_onetouch *onetouch = urb->context;
 	signed char *data = onetouch->data;
-	struct input_dev *dev = &onetouch->dev;
+	struct input_dev *dev = onetouch->dev;
 	int status;
 
 	switch (urb->status) {
@@ -74,11 +74,9 @@
 	}
 
 	input_regs(dev, regs);
-
-	input_report_key(&onetouch->dev, ONETOUCH_BUTTON,
-			 data[0] & 0x02);
-
+	input_report_key(dev, ONETOUCH_BUTTON, data[0] & 0x02);
 	input_sync(dev);
+
 resubmit:
 	status = usb_submit_urb (urb, SLAB_ATOMIC);
 	if (status)
@@ -113,8 +111,8 @@
 	struct usb_host_interface *interface;
 	struct usb_endpoint_descriptor *endpoint;
 	struct usb_onetouch *onetouch;
+	struct input_dev *input_dev;
 	int pipe, maxp;
-	char path[64];
 
 	interface = ss->pusb_intf->cur_altsetting;
 
@@ -122,62 +120,62 @@
 		return -ENODEV;
 
 	endpoint = &interface->endpoint[2].desc;
-	if(!(endpoint->bEndpointAddress & USB_DIR_IN))
+	if (!(endpoint->bEndpointAddress & USB_DIR_IN))
 		return -ENODEV;
-	if((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK)
+	if ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK)
 			!= USB_ENDPOINT_XFER_INT)
 		return -ENODEV;
 
 	pipe = usb_rcvintpipe(udev, endpoint->bEndpointAddress);
 	maxp = usb_maxpacket(udev, pipe, usb_pipeout(pipe));
 
-	if (!(onetouch = kcalloc(1, sizeof(struct usb_onetouch), GFP_KERNEL)))
-		return -ENOMEM;
+	onetouch = kzalloc(sizeof(struct usb_onetouch), GFP_KERNEL);
+	input_dev = input_allocate_device();
+	if (!onetouch || !input_dev)
+		goto fail1;
 
 	onetouch->data = usb_buffer_alloc(udev, ONETOUCH_PKT_LEN,
 					  SLAB_ATOMIC, &onetouch->data_dma);
-	if (!onetouch->data){
-		kfree(onetouch);
-		return -ENOMEM;
-	}
+	if (!onetouch->data)
+		goto fail1;
 
 	onetouch->irq = usb_alloc_urb(0, GFP_KERNEL);
-	if (!onetouch->irq){
-		kfree(onetouch);
-		usb_buffer_free(udev, ONETOUCH_PKT_LEN,
-				onetouch->data, onetouch->data_dma);
-		return -ENODEV;
-	}
-
+	if (!onetouch->irq)
+		goto fail2;
 
 	onetouch->udev = udev;
-
-	set_bit(EV_KEY, onetouch->dev.evbit);
-	set_bit(ONETOUCH_BUTTON, onetouch->dev.keybit);
-	clear_bit(0, onetouch->dev.keybit);
-
-	onetouch->dev.private = onetouch;
-	onetouch->dev.open = usb_onetouch_open;
-	onetouch->dev.close = usb_onetouch_close;
-
-	usb_make_path(udev, path, sizeof(path));
-	sprintf(onetouch->phys, "%s/input0", path);
-
-	onetouch->dev.name = onetouch->name;
-	onetouch->dev.phys = onetouch->phys;
-
-	usb_to_input_id(udev, &onetouch->dev.id);
-
-	onetouch->dev.dev = &udev->dev;
+	onetouch->dev = input_dev;
 
 	if (udev->manufacturer)
-		strcat(onetouch->name, udev->manufacturer);
-	if (udev->product)
-		sprintf(onetouch->name, "%s %s", onetouch->name,
-			udev->product);
+		strlcpy(onetouch->name, udev->manufacturer,
+			sizeof(onetouch->name));
+	if (udev->product) {
+		if (udev->manufacturer)
+			strlcat(onetouch->name, " ", sizeof(onetouch->name));
+		strlcat(onetouch->name, udev->product, sizeof(onetouch->name));
+	}
+
 	if (!strlen(onetouch->name))
-		sprintf(onetouch->name, "Maxtor Onetouch %04x:%04x",
-			onetouch->dev.id.vendor, onetouch->dev.id.product);
+		snprintf(onetouch->name, sizeof(onetouch->name),
+			 "Maxtor Onetouch %04x:%04x",
+			 le16_to_cpu(udev->descriptor.idVendor),
+			 le16_to_cpu(udev->descriptor.idProduct));
+
+	usb_make_path(udev, onetouch->phys, sizeof(onetouch->phys));
+	strlcat(onetouch->phys, "/input0", sizeof(onetouch->phys));
+
+	input_dev->name = onetouch->name;
+	input_dev->phys = onetouch->phys;
+	usb_to_input_id(udev, &input_dev->id);
+	input_dev->cdev.dev = &udev->dev;
+
+	set_bit(EV_KEY, input_dev->evbit);
+	set_bit(ONETOUCH_BUTTON, input_dev->keybit);
+	clear_bit(0, input_dev->keybit);
+
+	input_dev->private = onetouch;
+	input_dev->open = usb_onetouch_open;
+	input_dev->close = usb_onetouch_close;
 
 	usb_fill_int_urb(onetouch->irq, udev, pipe, onetouch->data,
 			 (maxp > 8 ? 8 : maxp),
@@ -188,10 +186,15 @@
 	ss->extra_destructor = onetouch_release_input;
 	ss->extra = onetouch;
 
-	input_register_device(&onetouch->dev);
-	printk(KERN_INFO "usb-input: %s on %s\n", onetouch->dev.name, path);
+	input_register_device(onetouch->dev);
 
 	return 0;
+
+ fail2:	usb_buffer_free(udev, ONETOUCH_PKT_LEN,
+			onetouch->data, onetouch->data_dma);
+ fail1:	kfree(onetouch);
+	input_free_device(input_dev);
+	return -ENOMEM;
 }
 
 void onetouch_release_input(void *onetouch_)
@@ -200,11 +203,9 @@
 
 	if (onetouch) {
 		usb_kill_urb(onetouch->irq);
-		input_unregister_device(&onetouch->dev);
+		input_unregister_device(onetouch->dev);
 		usb_free_urb(onetouch->irq);
 		usb_buffer_free(onetouch->udev, ONETOUCH_PKT_LEN,
 				onetouch->data, onetouch->data_dma);
-		printk(KERN_INFO "usb-input: deregistering %s\n",
-				onetouch->dev.name);
 	}
 }
diff --git a/drivers/video/backlight/corgi_bl.c b/drivers/video/backlight/corgi_bl.c
index 3c72c62..1991fdb 100644
--- a/drivers/video/backlight/corgi_bl.c
+++ b/drivers/video/backlight/corgi_bl.c
@@ -73,17 +73,15 @@
 }
 
 #ifdef CONFIG_PM
-static int corgibl_suspend(struct device *dev, pm_message_t state, u32 level)
+static int corgibl_suspend(struct device *dev, pm_message_t state)
 {
-	if (level == SUSPEND_POWER_DOWN)
-		corgibl_blank(FB_BLANK_POWERDOWN);
+	corgibl_blank(FB_BLANK_POWERDOWN);
 	return 0;
 }
 
-static int corgibl_resume(struct device *dev, u32 level)
+static int corgibl_resume(struct device *dev)
 {
-	if (level == RESUME_POWER_ON)
-		corgibl_blank(FB_BLANK_UNBLANK);
+	corgibl_blank(FB_BLANK_UNBLANK);
 	return 0;
 }
 #else
diff --git a/drivers/video/fbmem.c b/drivers/video/fbmem.c
index 70be700..9073be4 100644
--- a/drivers/video/fbmem.c
+++ b/drivers/video/fbmem.c
@@ -1031,7 +1031,7 @@
 			break;
 	fb_info->node = i;
 
-	fb_info->class_device = class_device_create(fb_class, MKDEV(FB_MAJOR, i),
+	fb_info->class_device = class_device_create(fb_class, NULL, MKDEV(FB_MAJOR, i),
 				    fb_info->device, "fb%d", i);
 	if (IS_ERR(fb_info->class_device)) {
 		/* Not fatal */
diff --git a/drivers/video/imxfb.c b/drivers/video/imxfb.c
index 1d54d3d..0b9301f 100644
--- a/drivers/video/imxfb.c
+++ b/drivers/video/imxfb.c
@@ -424,23 +424,21 @@
  * Power management hooks.  Note that we won't be called from IRQ context,
  * unlike the blank functions above, so we may sleep.
  */
-static int imxfb_suspend(struct device *dev, pm_message_t state, u32 level)
+static int imxfb_suspend(struct device *dev, pm_message_t state)
 {
 	struct imxfb_info *fbi = dev_get_drvdata(dev);
 	pr_debug("%s\n",__FUNCTION__);
 
-	if (level == SUSPEND_DISABLE || level == SUSPEND_POWER_DOWN)
-		imxfb_disable_controller(fbi);
+	imxfb_disable_controller(fbi);
 	return 0;
 }
 
-static int imxfb_resume(struct device *dev, u32 level)
+static int imxfb_resume(struct device *dev)
 {
 	struct imxfb_info *fbi = dev_get_drvdata(dev);
 	pr_debug("%s\n",__FUNCTION__);
 
-	if (level == RESUME_ENABLE)
-		imxfb_enable_controller(fbi);
+	imxfb_enable_controller(fbi);
 	return 0;
 }
 #else
diff --git a/drivers/video/pxafb.c b/drivers/video/pxafb.c
index 194eed0..6206da9 100644
--- a/drivers/video/pxafb.c
+++ b/drivers/video/pxafb.c
@@ -981,21 +981,19 @@
  * Power management hooks.  Note that we won't be called from IRQ context,
  * unlike the blank functions above, so we may sleep.
  */
-static int pxafb_suspend(struct device *dev, pm_message_t state, u32 level)
+static int pxafb_suspend(struct device *dev, pm_message_t state)
 {
 	struct pxafb_info *fbi = dev_get_drvdata(dev);
 
-	if (level == SUSPEND_DISABLE || level == SUSPEND_POWER_DOWN)
-		set_ctrlr_state(fbi, C_DISABLE_PM);
+	set_ctrlr_state(fbi, C_DISABLE_PM);
 	return 0;
 }
 
-static int pxafb_resume(struct device *dev, u32 level)
+static int pxafb_resume(struct device *dev)
 {
 	struct pxafb_info *fbi = dev_get_drvdata(dev);
 
-	if (level == RESUME_ENABLE)
-		set_ctrlr_state(fbi, C_ENABLE_PM);
+	set_ctrlr_state(fbi, C_ENABLE_PM);
 	return 0;
 }
 #else
diff --git a/drivers/video/s1d13xxxfb.c b/drivers/video/s1d13xxxfb.c
index fa98d91..cb2f7a1 100644
--- a/drivers/video/s1d13xxxfb.c
+++ b/drivers/video/s1d13xxxfb.c
@@ -655,7 +655,7 @@
 }
 
 #ifdef CONFIG_PM
-static int s1d13xxxfb_suspend(struct device *dev, pm_message_t state, u32 level)
+static int s1d13xxxfb_suspend(struct device *dev, pm_message_t state)
 {
 	struct fb_info *info = dev_get_drvdata(dev);
 	struct s1d13xxxfb_par *s1dfb = info->par;
@@ -702,15 +702,12 @@
 		return 0;
 }
 
-static int s1d13xxxfb_resume(struct device *dev, u32 level)
+static int s1d13xxxfb_resume(struct device *dev)
 {
 	struct fb_info *info = dev_get_drvdata(dev);
 	struct s1d13xxxfb_par *s1dfb = info->par;
 	struct s1d13xxxfb_pdata *pdata = NULL;
 
-	if (level != RESUME_ENABLE)
-		return 0;
-
 	/* awaken the chip */
 	s1d13xxxfb_writereg(s1dfb, S1DREG_PS_CNF, 0x10);
 
diff --git a/drivers/video/s3c2410fb.c b/drivers/video/s3c2410fb.c
index 5ab79af..3862d3c 100644
--- a/drivers/video/s3c2410fb.c
+++ b/drivers/video/s3c2410fb.c
@@ -847,37 +847,32 @@
 
 /* suspend and resume support for the lcd controller */
 
-static int s3c2410fb_suspend(struct device *dev, pm_message_t state, u32 level)
+static int s3c2410fb_suspend(struct device *dev, pm_message_t state)
 {
 	struct fb_info	   *fbinfo = dev_get_drvdata(dev);
 	struct s3c2410fb_info *info = fbinfo->par;
 
-	if (level == SUSPEND_DISABLE || level == SUSPEND_POWER_DOWN) {
-		s3c2410fb_stop_lcd();
+	s3c2410fb_stop_lcd();
 
-		/* sleep before disabling the clock, we need to ensure
-		 * the LCD DMA engine is not going to get back on the bus
-		 * before the clock goes off again (bjd) */
+	/* sleep before disabling the clock, we need to ensure
+	 * the LCD DMA engine is not going to get back on the bus
+	 * before the clock goes off again (bjd) */
 
-		msleep(1);
-		clk_disable(info->clk);
-	}
+	msleep(1);
+	clk_disable(info->clk);
 
 	return 0;
 }
 
-static int s3c2410fb_resume(struct device *dev, u32 level)
+static int s3c2410fb_resume(struct device *dev)
 {
 	struct fb_info	   *fbinfo = dev_get_drvdata(dev);
 	struct s3c2410fb_info *info = fbinfo->par;
 
-	if (level == RESUME_ENABLE) {
-		clk_enable(info->clk);
-		msleep(1);
+	clk_enable(info->clk);
+	msleep(1);
 
-		s3c2410fb_init_registers(info);
-
-	}
+	s3c2410fb_init_registers(info);
 
 	return 0;
 }
diff --git a/drivers/video/sa1100fb.c b/drivers/video/sa1100fb.c
index 8000890..78e5f19 100644
--- a/drivers/video/sa1100fb.c
+++ b/drivers/video/sa1100fb.c
@@ -1309,21 +1309,19 @@
  * Power management hooks.  Note that we won't be called from IRQ context,
  * unlike the blank functions above, so we may sleep.
  */
-static int sa1100fb_suspend(struct device *dev, pm_message_t state, u32 level)
+static int sa1100fb_suspend(struct device *dev, pm_message_t state)
 {
 	struct sa1100fb_info *fbi = dev_get_drvdata(dev);
 
-	if (level == SUSPEND_DISABLE || level == SUSPEND_POWER_DOWN)
-		set_ctrlr_state(fbi, C_DISABLE_PM);
+	set_ctrlr_state(fbi, C_DISABLE_PM);
 	return 0;
 }
 
-static int sa1100fb_resume(struct device *dev, u32 level)
+static int sa1100fb_resume(struct device *dev)
 {
 	struct sa1100fb_info *fbi = dev_get_drvdata(dev);
 
-	if (level == RESUME_ENABLE)
-		set_ctrlr_state(fbi, C_ENABLE_PM);
+	set_ctrlr_state(fbi, C_ENABLE_PM);
 	return 0;
 }
 #else
diff --git a/drivers/video/w100fb.c b/drivers/video/w100fb.c
index 0030c07..752bf88 100644
--- a/drivers/video/w100fb.c
+++ b/drivers/video/w100fb.c
@@ -438,36 +438,34 @@
 	}
 }
 
-static int w100fb_suspend(struct device *dev, pm_message_t state, uint32_t level)
+static int w100fb_suspend(struct device *dev, pm_message_t state)
 {
-	if (level == SUSPEND_POWER_DOWN) {
-		struct fb_info *info = dev_get_drvdata(dev);
-		struct w100fb_par *par=info->par;
-		struct w100_tg_info *tg = par->mach->tg;
+	struct fb_info *info = dev_get_drvdata(dev);
+	struct w100fb_par *par=info->par;
+	struct w100_tg_info *tg = par->mach->tg;
 
-		w100fb_save_vidmem(par);
-		if(tg && tg->suspend)
-			tg->suspend(par);
-		w100_suspend(W100_SUSPEND_ALL);
-		par->blanked = 1;
-	}
+	w100fb_save_vidmem(par);
+	if(tg && tg->suspend)
+		tg->suspend(par);
+	w100_suspend(W100_SUSPEND_ALL);
+	par->blanked = 1;
+
 	return 0;
 }
 
-static int w100fb_resume(struct device *dev, uint32_t level)
+static int w100fb_resume(struct device *dev)
 {
-	if (level == RESUME_POWER_ON) {
-		struct fb_info *info = dev_get_drvdata(dev);
-		struct w100fb_par *par=info->par;
-		struct w100_tg_info *tg = par->mach->tg;
+	struct fb_info *info = dev_get_drvdata(dev);
+	struct w100fb_par *par=info->par;
+	struct w100_tg_info *tg = par->mach->tg;
 
-		w100_hw_init(par);
-		w100fb_activate_var(par);
-		w100fb_restore_vidmem(par);
-		if(tg && tg->resume)
-			tg->resume(par);
-		par->blanked = 0;
-	}
+	w100_hw_init(par);
+	w100fb_activate_var(par);
+	w100fb_restore_vidmem(par);
+	if(tg && tg->resume)
+		tg->resume(par);
+	par->blanked = 0;
+
 	return 0;
 }
 #else
diff --git a/fs/coda/psdev.c b/fs/coda/psdev.c
index 3d1cce3..6a3df88 100644
--- a/fs/coda/psdev.c
+++ b/fs/coda/psdev.c
@@ -370,8 +370,8 @@
 	}		
 	devfs_mk_dir ("coda");
 	for (i = 0; i < MAX_CODADEVS; i++) {
-		class_device_create(coda_psdev_class, MKDEV(CODA_PSDEV_MAJOR,i),
-				NULL, "cfs%d", i);
+		class_device_create(coda_psdev_class, NULL,
+				MKDEV(CODA_PSDEV_MAJOR,i), NULL, "cfs%d", i);
 		err = devfs_mk_cdev(MKDEV(CODA_PSDEV_MAJOR, i),
 				S_IFCHR|S_IRUSR|S_IWUSR, "coda/%d", i);
 		if (err)
diff --git a/fs/partitions/check.c b/fs/partitions/check.c
index 1e84864..9c06c54 100644
--- a/fs/partitions/check.c
+++ b/fs/partitions/check.c
@@ -192,6 +192,7 @@
 struct part_attribute {
 	struct attribute attr;
 	ssize_t (*show)(struct hd_struct *,char *);
+	ssize_t (*store)(struct hd_struct *,const char *, size_t);
 };
 
 static ssize_t 
@@ -201,14 +202,33 @@
 	struct part_attribute * part_attr = container_of(attr,struct part_attribute,attr);
 	ssize_t ret = 0;
 	if (part_attr->show)
-		ret = part_attr->show(p,page);
+		ret = part_attr->show(p, page);
+	return ret;
+}
+static ssize_t
+part_attr_store(struct kobject * kobj, struct attribute * attr,
+		const char *page, size_t count)
+{
+	struct hd_struct * p = container_of(kobj,struct hd_struct,kobj);
+	struct part_attribute * part_attr = container_of(attr,struct part_attribute,attr);
+	ssize_t ret = 0;
+
+	if (part_attr->store)
+		ret = part_attr->store(p, page, count);
 	return ret;
 }
 
 static struct sysfs_ops part_sysfs_ops = {
 	.show	=	part_attr_show,
+	.store	=	part_attr_store,
 };
 
+static ssize_t part_uevent_store(struct hd_struct * p,
+				 const char *page, size_t count)
+{
+	kobject_hotplug(&p->kobj, KOBJ_ADD);
+	return count;
+}
 static ssize_t part_dev_read(struct hd_struct * p, char *page)
 {
 	struct gendisk *disk = container_of(p->kobj.parent,struct gendisk,kobj);
@@ -229,6 +249,10 @@
 		       p->reads, (unsigned long long)p->read_sectors,
 		       p->writes, (unsigned long long)p->write_sectors);
 }
+static struct part_attribute part_attr_uevent = {
+	.attr = {.name = "uevent", .mode = S_IWUSR },
+	.store	= part_uevent_store
+};
 static struct part_attribute part_attr_dev = {
 	.attr = {.name = "dev", .mode = S_IRUGO },
 	.show	= part_dev_read
@@ -247,6 +271,7 @@
 };
 
 static struct attribute * default_attrs[] = {
+	&part_attr_uevent.attr,
 	&part_attr_dev.attr,
 	&part_attr_start.attr,
 	&part_attr_size.attr,
diff --git a/include/linux/device.h b/include/linux/device.h
index 95d607a..a9e72ac 100644
--- a/include/linux/device.h
+++ b/include/linux/device.h
@@ -28,19 +28,6 @@
 #define BUS_ID_SIZE		KOBJ_NAME_LEN
 
 
-enum {
-	SUSPEND_NOTIFY,
-	SUSPEND_SAVE_STATE,
-	SUSPEND_DISABLE,
-	SUSPEND_POWER_DOWN,
-};
-
-enum {
-	RESUME_POWER_ON,
-	RESUME_RESTORE_STATE,
-	RESUME_ENABLE,
-};
-
 struct device;
 struct device_driver;
 struct class;
@@ -115,8 +102,8 @@
 	int	(*probe)	(struct device * dev);
 	int	(*remove)	(struct device * dev);
 	void	(*shutdown)	(struct device * dev);
-	int	(*suspend)	(struct device * dev, pm_message_t state, u32 level);
-	int	(*resume)	(struct device * dev, u32 level);
+	int	(*suspend)	(struct device * dev, pm_message_t state);
+	int	(*resume)	(struct device * dev);
 };
 
 
@@ -190,7 +177,43 @@
 extern int class_create_file(struct class *, const struct class_attribute *);
 extern void class_remove_file(struct class *, const struct class_attribute *);
 
+struct class_device_attribute {
+	struct attribute	attr;
+	ssize_t (*show)(struct class_device *, char * buf);
+	ssize_t (*store)(struct class_device *, const char * buf, size_t count);
+};
 
+#define CLASS_DEVICE_ATTR(_name,_mode,_show,_store)		\
+struct class_device_attribute class_device_attr_##_name = 	\
+	__ATTR(_name,_mode,_show,_store)
+
+extern int class_device_create_file(struct class_device *,
+				    const struct class_device_attribute *);
+
+/**
+ * struct class_device - class devices
+ * @class: pointer to the parent class for this class device.  This is required.
+ * @devt: for internal use by the driver core only.
+ * @node: for internal use by the driver core only.
+ * @kobj: for internal use by the driver core only.
+ * @devt_attr: for internal use by the driver core only.
+ * @dev: if set, a symlink to the struct device is created in the sysfs
+ * directory for this struct class device.
+ * @class_data: pointer to whatever you want to store here for this struct
+ * class_device.  Use class_get_devdata() and class_set_devdata() to get and
+ * set this pointer.
+ * @parent: pointer to a struct class_device that is the parent of this struct
+ * class_device.  If NULL, this class_device will show up at the root of the
+ * struct class in sysfs (which is probably what you want to have happen.)
+ * @release: pointer to a release function for this struct class_device.  If
+ * set, this will be called instead of the class specific release function.
+ * Only use this if you want to override the default release function, like
+ * when you are nesting class_device structures.
+ * @hotplug: pointer to a hotplug function for this struct class_device.  If
+ * set, this will be called instead of the class specific hotplug function.
+ * Only use this if you want to override the default hotplug function, like
+ * when you are nesting class_device structures.
+ */
 struct class_device {
 	struct list_head	node;
 
@@ -198,9 +221,14 @@
 	struct class		* class;	/* required */
 	dev_t			devt;		/* dev_t, creates the sysfs "dev" */
 	struct class_device_attribute *devt_attr;
+	struct class_device_attribute uevent_attr;
 	struct device		* dev;		/* not necessary, but nice to have */
 	void			* class_data;	/* class-specific data */
+	struct class_device	*parent;	/* parent of this child device, if there is one */
 
+	void	(*release)(struct class_device *dev);
+	int	(*hotplug)(struct class_device *dev, char **envp,
+			   int num_envp, char *buffer, int buffer_size);
 	char	class_id[BUS_ID_SIZE];	/* unique to this class */
 };
 
@@ -228,18 +256,6 @@
 extern struct class_device * class_device_get(struct class_device *);
 extern void class_device_put(struct class_device *);
 
-struct class_device_attribute {
-	struct attribute	attr;
-	ssize_t (*show)(struct class_device *, char * buf);
-	ssize_t (*store)(struct class_device *, const char * buf, size_t count);
-};
-
-#define CLASS_DEVICE_ATTR(_name,_mode,_show,_store)		\
-struct class_device_attribute class_device_attr_##_name = 	\
-	__ATTR(_name,_mode,_show,_store)
-
-extern int class_device_create_file(struct class_device *, 
-				    const struct class_device_attribute *);
 extern void class_device_remove_file(struct class_device *, 
 				     const struct class_device_attribute *);
 extern int class_device_create_bin_file(struct class_device *,
@@ -251,8 +267,8 @@
 	struct list_head	node;
 	struct class		*class;
 
-	int (*add)	(struct class_device *);
-	void (*remove)	(struct class_device *);
+	int (*add)	(struct class_device *, struct class_interface *);
+	void (*remove)	(struct class_device *, struct class_interface *);
 };
 
 extern int class_interface_register(struct class_interface *);
@@ -260,12 +276,29 @@
 
 extern struct class *class_create(struct module *owner, char *name);
 extern void class_destroy(struct class *cls);
-extern struct class_device *class_device_create(struct class *cls, dev_t devt,
-						struct device *device, char *fmt, ...)
-					__attribute__((format(printf,4,5)));
+extern struct class_device *class_device_create(struct class *cls,
+						struct class_device *parent,
+						dev_t devt,
+						struct device *device,
+						char *fmt, ...)
+					__attribute__((format(printf,5,6)));
 extern void class_device_destroy(struct class *cls, dev_t devt);
 
 
+/* interface for exporting device attributes */
+struct device_attribute {
+	struct attribute	attr;
+	ssize_t (*show)(struct device *dev, struct device_attribute *attr,
+			char *buf);
+	ssize_t (*store)(struct device *dev, struct device_attribute *attr,
+			 const char *buf, size_t count);
+};
+
+#define DEVICE_ATTR(_name,_mode,_show,_store) \
+struct device_attribute dev_attr_##_name = __ATTR(_name,_mode,_show,_store)
+
+extern int device_create_file(struct device *device, struct device_attribute * entry);
+extern void device_remove_file(struct device * dev, struct device_attribute * attr);
 struct device {
 	struct klist		klist_children;
 	struct klist_node	knode_parent;		/* node in sibling list */
@@ -275,6 +308,7 @@
 
 	struct kobject kobj;
 	char	bus_id[BUS_ID_SIZE];	/* position on parent bus */
+	struct device_attribute uevent_attr;
 
 	struct semaphore	sem;	/* semaphore to synchronize calls to
 					 * its driver.
@@ -343,23 +377,6 @@
 extern void driver_attach(struct device_driver * drv);
 
 
-/* driverfs interface for exporting device attributes */
-
-struct device_attribute {
-	struct attribute	attr;
-	ssize_t (*show)(struct device *dev, struct device_attribute *attr,
-			char *buf);
-	ssize_t (*store)(struct device *dev, struct device_attribute *attr,
-			 const char *buf, size_t count);
-};
-
-#define DEVICE_ATTR(_name,_mode,_show,_store) \
-struct device_attribute dev_attr_##_name = __ATTR(_name,_mode,_show,_store)
-
-
-extern int device_create_file(struct device *device, struct device_attribute * entry);
-extern void device_remove_file(struct device * dev, struct device_attribute * attr);
-
 /*
  * Platform "fixup" functions - allow the platform to have their say
  * about devices and actions that the general device layer doesn't
diff --git a/include/linux/genhd.h b/include/linux/genhd.h
index 142e1c1..eabdb5c 100644
--- a/include/linux/genhd.h
+++ b/include/linux/genhd.h
@@ -132,6 +132,7 @@
 struct disk_attribute {
 	struct attribute attr;
 	ssize_t (*show)(struct gendisk *, char *);
+	ssize_t (*store)(struct gendisk *, const char *, size_t);
 };
 
 /* 
diff --git a/include/linux/i2o.h b/include/linux/i2o.h
index b4af45a..9230032 100644
--- a/include/linux/i2o.h
+++ b/include/linux/i2o.h
@@ -66,8 +66,6 @@
 	struct device device;
 
 	struct semaphore lock;	/* device lock */
-
-	struct class_device classdev;	/* i2o device class */
 };
 
 /*
@@ -194,7 +192,7 @@
 	struct resource mem_resource;	/* Mem resource allocated to the IOP */
 
 	struct device device;
-	struct class_device classdev;	/* I2O controller class */
+	struct class_device *classdev;	/* I2O controller class device */
 	struct i2o_device *exec;	/* Executive */
 #if BITS_PER_LONG == 64
 	spinlock_t context_list_lock;	/* lock for context_list */
diff --git a/include/linux/input.h b/include/linux/input.h
index d783631..f623c74 100644
--- a/include/linux/input.h
+++ b/include/linux/input.h
@@ -12,6 +12,7 @@
 #ifdef __KERNEL__
 #include <linux/time.h>
 #include <linux/list.h>
+#include <linux/device.h>
 #else
 #include <sys/time.h>
 #include <sys/ioctl.h>
@@ -890,11 +891,15 @@
 	struct semaphore sem;	/* serializes open and close operations */
 	unsigned int users;
 
-	struct device *dev;
+	struct class_device cdev;
+	struct device *dev;	/* will be removed soon */
+
+	int dynalloc;	/* temporarily */
 
 	struct list_head	h_list;
 	struct list_head	node;
 };
+#define to_input_dev(d) container_of(d, struct input_dev, cdev)
 
 /*
  * Structure for hotplug & device<->driver matching.
@@ -985,6 +990,23 @@
 	INIT_LIST_HEAD(&dev->node);
 }
 
+struct input_dev *input_allocate_device(void);
+
+static inline void input_free_device(struct input_dev *dev)
+{
+	kfree(dev);
+}
+
+static inline struct input_dev *input_get_device(struct input_dev *dev)
+{
+	return to_input_dev(class_device_get(&dev->cdev));
+}
+
+static inline void input_put_device(struct input_dev *dev)
+{
+	class_device_put(&dev->cdev);
+}
+
 void input_register_device(struct input_dev *);
 void input_unregister_device(struct input_dev *);
 
@@ -1053,7 +1075,7 @@
 	dev->absbit[LONG(axis)] |= BIT(axis);
 }
 
-extern struct class *input_class;
+extern struct class input_class;
 
 #endif
 #endif
diff --git a/include/linux/pm.h b/include/linux/pm.h
index 5cfb076..7897cf5 100644
--- a/include/linux/pm.h
+++ b/include/linux/pm.h
@@ -219,7 +219,9 @@
 
 struct dev_pm_info {
 	pm_message_t		power_state;
+	unsigned		can_wakeup:1;
 #ifdef	CONFIG_PM
+	unsigned		should_wakeup:1;
 	pm_message_t		prev_state;
 	void			* saved_state;
 	atomic_t		pm_users;
@@ -236,13 +238,35 @@
 
 #ifdef CONFIG_PM
 extern int device_suspend(pm_message_t state);
-#else
+
+#define device_set_wakeup_enable(dev,val) \
+	((dev)->power.should_wakeup = !!(val))
+#define device_may_wakeup(dev) \
+	(device_can_wakeup(dev) && (dev)->power.should_wakeup)
+
+#else /* !CONFIG_PM */
+
 static inline int device_suspend(pm_message_t state)
 {
 	return 0;
 }
+
+#define device_set_wakeup_enable(dev,val)	do{}while(0)
+#define device_may_wakeup(dev)			(0)
+
 #endif
 
+/* changes to device_may_wakeup take effect on the next pm state change.
+ * by default, devices should wakeup if they can.
+ */
+#define device_can_wakeup(dev) \
+	((dev)->power.can_wakeup)
+#define device_init_wakeup(dev,val) \
+	do { \
+		device_can_wakeup(dev) = !!(val); \
+		device_set_wakeup_enable(dev,val); \
+	} while(0)
+
 #endif /* __KERNEL__ */
 
 #endif /* _LINUX_PM_H */
diff --git a/lib/kobject_uevent.c b/lib/kobject_uevent.c
index 7ef6f6a..3ab3754 100644
--- a/lib/kobject_uevent.c
+++ b/lib/kobject_uevent.c
@@ -54,7 +54,7 @@
 static struct sock *uevent_sock;
 
 /**
- * send_uevent - notify userspace by sending event trough netlink socket
+ * send_uevent - notify userspace by sending event through netlink socket
  *
  * @signal: signal name
  * @obj: object path (kobject)
diff --git a/net/bluetooth/hidp/core.c b/net/bluetooth/hidp/core.c
index de8af5f..860444a 100644
--- a/net/bluetooth/hidp/core.c
+++ b/net/bluetooth/hidp/core.c
@@ -520,7 +520,7 @@
 
 	if (session->input) {
 		input_unregister_device(session->input);
-		kfree(session->input);
+		session->input = NULL;
 	}
 
 	up_write(&hidp_session_sem);
@@ -536,6 +536,8 @@
 
 	input->private = session;
 
+	input->name = "Bluetooth HID Boot Protocol Device";
+
 	input->id.bustype = BUS_BLUETOOTH;
 	input->id.vendor  = req->vendor;
 	input->id.product = req->product;
@@ -582,16 +584,15 @@
 		return -ENOTUNIQ;
 
 	session = kmalloc(sizeof(struct hidp_session), GFP_KERNEL);
-	if (!session) 
+	if (!session)
 		return -ENOMEM;
 	memset(session, 0, sizeof(struct hidp_session));
 
-	session->input = kmalloc(sizeof(struct input_dev), GFP_KERNEL);
+	session->input = input_allocate_device();
 	if (!session->input) {
 		kfree(session);
 		return -ENOMEM;
 	}
-	memset(session->input, 0, sizeof(struct input_dev));
 
 	down_write(&hidp_session_sem);
 
@@ -651,8 +652,10 @@
 
 	__hidp_unlink_session(session);
 
-	if (session->input)
+	if (session->input) {
 		input_unregister_device(session->input);
+		session->input = NULL; /* don't try to free it here */
+	}
 
 failed:
 	up_write(&hidp_session_sem);
diff --git a/sound/arm/pxa2xx-ac97.c b/sound/arm/pxa2xx-ac97.c
index 38b20ef..877bb00 100644
--- a/sound/arm/pxa2xx-ac97.c
+++ b/sound/arm/pxa2xx-ac97.c
@@ -275,23 +275,23 @@
 	return 0;
 }
 
-static int pxa2xx_ac97_suspend(struct device *_dev, pm_message_t state, u32 level)
+static int pxa2xx_ac97_suspend(struct device *_dev, pm_message_t state)
 {
 	snd_card_t *card = dev_get_drvdata(_dev);
 	int ret = 0;
 
-	if (card && level == SUSPEND_DISABLE)
+	if (card)
 		ret = pxa2xx_ac97_do_suspend(card, PMSG_SUSPEND);
 
 	return ret;
 }
 
-static int pxa2xx_ac97_resume(struct device *_dev, u32 level)
+static int pxa2xx_ac97_resume(struct device *_dev)
 {
 	snd_card_t *card = dev_get_drvdata(_dev);
 	int ret = 0;
 
-	if (card && level == RESUME_ENABLE)
+	if (card)
 		ret = pxa2xx_ac97_do_resume(card);
 
 	return ret;
diff --git a/sound/core/init.c b/sound/core/init.c
index c72a791..59202de 100644
--- a/sound/core/init.c
+++ b/sound/core/init.c
@@ -676,8 +676,8 @@
 #define SND_GENERIC_NAME	"snd_generic"
 
 #ifdef CONFIG_PM
-static int snd_generic_suspend(struct device *dev, pm_message_t state, u32 level);
-static int snd_generic_resume(struct device *dev, u32 level);
+static int snd_generic_suspend(struct device *dev, pm_message_t state);
+static int snd_generic_resume(struct device *dev);
 #endif
 
 /* initialized in sound.c */
@@ -818,13 +818,10 @@
 
 #ifdef CONFIG_SND_GENERIC_DRIVER
 /* suspend/resume callbacks for snd_generic platform device */
-static int snd_generic_suspend(struct device *dev, pm_message_t state, u32 level)
+static int snd_generic_suspend(struct device *dev, pm_message_t state)
 {
 	snd_card_t *card;
 
-	if (level != SUSPEND_DISABLE)
-		return 0;
-
 	card = get_snd_generic_card(dev);
 	if (card->power_state == SNDRV_CTL_POWER_D3hot)
 		return 0;
@@ -834,13 +831,10 @@
 	return 0;
 }
 
-static int snd_generic_resume(struct device *dev, u32 level)
+static int snd_generic_resume(struct device *dev)
 {
 	snd_card_t *card;
 
-	if (level != RESUME_ENABLE)
-		return 0;
-
 	card = get_snd_generic_card(dev);
 	if (card->power_state == SNDRV_CTL_POWER_D0)
 		return 0;
diff --git a/sound/core/sound.c b/sound/core/sound.c
index 9e76bdd..b57519a 100644
--- a/sound/core/sound.c
+++ b/sound/core/sound.c
@@ -231,7 +231,7 @@
 		devfs_mk_cdev(MKDEV(major, minor), S_IFCHR | device_mode, "snd/%s", name);
 	if (card)
 		device = card->dev;
-	class_device_create(sound_class, MKDEV(major, minor), device, "%s", name);
+	class_device_create(sound_class, NULL, MKDEV(major, minor), device, "%s", name);
 
 	up(&sound_mutex);
 	return 0;
diff --git a/sound/oss/soundcard.c b/sound/oss/soundcard.c
index 95fa81e..d33bb46 100644
--- a/sound/oss/soundcard.c
+++ b/sound/oss/soundcard.c
@@ -567,7 +567,7 @@
 		devfs_mk_cdev(MKDEV(SOUND_MAJOR, dev_list[i].minor),
 				S_IFCHR | dev_list[i].mode,
 				"sound/%s", dev_list[i].name);
-		class_device_create(sound_class,
+		class_device_create(sound_class, NULL,
 				    MKDEV(SOUND_MAJOR, dev_list[i].minor),
 				    NULL, "%s", dev_list[i].name);
 
@@ -579,7 +579,7 @@
 						dev_list[i].minor + (j*0x10)),
 					S_IFCHR | dev_list[i].mode,
 					"sound/%s%d", dev_list[i].name, j);
-			class_device_create(sound_class,
+			class_device_create(sound_class, NULL,
 					    MKDEV(SOUND_MAJOR, dev_list[i].minor + (j*0x10)),
 					    NULL, "%s%d", dev_list[i].name, j);
 		}
diff --git a/sound/pci/ac97/ac97_bus.c b/sound/pci/ac97/ac97_bus.c
index becbc42..ec70fad 100644
--- a/sound/pci/ac97/ac97_bus.c
+++ b/sound/pci/ac97/ac97_bus.c
@@ -31,7 +31,8 @@
 	int ret = 0;
 
 	if (dev->driver && dev->driver->suspend)
-		ret = dev->driver->suspend(dev, state, SUSPEND_POWER_DOWN);
+		ret = dev->driver->suspend(dev, state);
+
 	return ret;
 }
 
@@ -40,7 +41,8 @@
 	int ret = 0;
 
 	if (dev->driver && dev->driver->resume)
-		ret = dev->driver->resume(dev, RESUME_POWER_ON);
+		ret = dev->driver->resume(dev);
+
 	return ret;
 }
 
diff --git a/sound/ppc/beep.c b/sound/ppc/beep.c
index 31ea7a4..1681ee1 100644
--- a/sound/ppc/beep.c
+++ b/sound/ppc/beep.c
@@ -31,14 +31,14 @@
 #include "pmac.h"
 
 struct snd_pmac_beep {
-	int running;	/* boolean */
-	int volume;	/* mixer volume: 0-100 */
+	int running;		/* boolean */
+	int volume;		/* mixer volume: 0-100 */
 	int volume_play;	/* currently playing volume */
 	int hz;
 	int nsamples;
 	short *buf;		/* allocated wave buffer */
 	dma_addr_t addr;	/* physical address of buffer */
-	struct input_dev dev;
+	struct input_dev *dev;
 };
 
 /*
@@ -212,47 +212,55 @@
 int __init snd_pmac_attach_beep(pmac_t *chip)
 {
 	pmac_beep_t *beep;
-	int err;
+	struct input_dev *input_dev;
+	void *dmabuf;
+	int err = -ENOMEM;
 
-	beep = kmalloc(sizeof(*beep), GFP_KERNEL);
-	if (! beep)
-		return -ENOMEM;
-
-	memset(beep, 0, sizeof(*beep));
-	beep->buf = dma_alloc_coherent(&chip->pdev->dev, BEEP_BUFLEN * 4,
-					&beep->addr, GFP_KERNEL);
-
-	beep->dev.evbit[0] = BIT(EV_SND);
-	beep->dev.sndbit[0] = BIT(SND_BELL) | BIT(SND_TONE);
-	beep->dev.event = snd_pmac_beep_event;
-	beep->dev.private = chip;
+	beep = kzalloc(sizeof(*beep), GFP_KERNEL);
+	dmabuf = dma_alloc_coherent(&chip->pdev->dev, BEEP_BUFLEN * 4,
+				    &beep->addr, GFP_KERNEL);
+	input_dev = input_allocate_device();
+	if (!beep || !dmabuf || !input_dev)
+		goto fail;
 
 	/* FIXME: set more better values */
-	beep->dev.name = "PowerMac Beep";
-	beep->dev.phys = "powermac/beep";
-	beep->dev.id.bustype = BUS_ADB;
-	beep->dev.id.vendor = 0x001f;
-	beep->dev.id.product = 0x0001;
-	beep->dev.id.version = 0x0100;
+	input_dev->name = "PowerMac Beep";
+	input_dev->phys = "powermac/beep";
+	input_dev->id.bustype = BUS_ADB;
+	input_dev->id.vendor = 0x001f;
+	input_dev->id.product = 0x0001;
+	input_dev->id.version = 0x0100;
 
+	input_dev->evbit[0] = BIT(EV_SND);
+	input_dev->sndbit[0] = BIT(SND_BELL) | BIT(SND_TONE);
+	input_dev->event = snd_pmac_beep_event;
+	input_dev->private = chip;
+	input_dev->cdev.dev = &chip->pdev->dev;
+
+	beep->dev = input_dev;
+	beep->buf = dmabuf;
 	beep->volume = BEEP_VOLUME;
 	beep->running = 0;
-	if ((err = snd_ctl_add(chip->card, snd_ctl_new1(&snd_pmac_beep_mixer, chip))) < 0) {
-		kfree(beep->buf);
-		kfree(beep);
-		return err;
-	}
+
+	err = snd_ctl_add(chip->card, snd_ctl_new1(&snd_pmac_beep_mixer, chip));
+	if (err < 0)
+		goto fail;
 
 	chip->beep = beep;
-	input_register_device(&beep->dev);
+	input_register_device(beep->dev);
 
 	return 0;
+
+ fail:	input_free_device(input_dev);
+	kfree(dmabuf);
+	kfree(beep);
+	return err;
 }
 
 void snd_pmac_detach_beep(pmac_t *chip)
 {
 	if (chip->beep) {
-		input_unregister_device(&chip->beep->dev);
+		input_unregister_device(chip->beep->dev);
 		dma_free_coherent(&chip->pdev->dev, BEEP_BUFLEN * 4,
 				  chip->beep->buf, chip->beep->addr);
 		kfree(chip->beep);
diff --git a/sound/sound_core.c b/sound/sound_core.c
index 954f994..394b53e 100644
--- a/sound/sound_core.c
+++ b/sound/sound_core.c
@@ -174,7 +174,7 @@
 
 	devfs_mk_cdev(MKDEV(SOUND_MAJOR, s->unit_minor),
 			S_IFCHR | mode, s->name);
-	class_device_create(sound_class, MKDEV(SOUND_MAJOR, s->unit_minor),
+	class_device_create(sound_class, NULL, MKDEV(SOUND_MAJOR, s->unit_minor),
 			    dev, s->name+6);
 	return r;