Merge master.kernel.org:/pub/scm/linux/kernel/git/gregkh/driver-2.6
authorLinus Torvalds <torvalds@g5.osdl.org>
Fri, 28 Oct 2005 20:09:47 +0000 (13:09 -0700)
committerLinus Torvalds <torvalds@g5.osdl.org>
Fri, 28 Oct 2005 20:09:47 +0000 (13:09 -0700)
244 files changed:
Documentation/Changes
Documentation/DocBook/writing_usb_driver.tmpl
Documentation/driver-model/driver.txt
Documentation/driver-model/porting.txt
arch/arm/common/locomo.c
arch/arm/common/sa1111.c
arch/arm/common/scoop.c
arch/arm/mach-pxa/corgi_ssp.c
arch/arm/mach-sa1100/neponset.c
arch/i386/kernel/cpuid.c
arch/i386/kernel/msr.c
drivers/base/attribute_container.c
drivers/base/base.h
drivers/base/class.c
drivers/base/core.c
drivers/base/cpu.c
drivers/base/driver.c
drivers/base/firmware.c
drivers/base/init.c
drivers/base/platform.c
drivers/base/power/sysfs.c
drivers/block/aoe/aoe.h
drivers/block/aoe/aoechr.c
drivers/block/aoe/aoecmd.c
drivers/block/genhd.c
drivers/block/paride/pg.c
drivers/block/paride/pt.c
drivers/char/dsp56k.c
drivers/char/ftape/zftape/zftape-init.c
drivers/char/ip2main.c
drivers/char/ipmi/ipmi_devintf.c
drivers/char/istallion.c
drivers/char/lp.c
drivers/char/mem.c
drivers/char/misc.c
drivers/char/ppdev.c
drivers/char/raw.c
drivers/char/s3c2410-rtc.c
drivers/char/snsc.c
drivers/char/sonypi.c
drivers/char/stallion.c
drivers/char/tipar.c
drivers/char/tty_io.c
drivers/char/vc_screen.c
drivers/char/viotape.c
drivers/char/watchdog/s3c2410_wdt.c
drivers/hwmon/hdaps.c
drivers/hwmon/hwmon.c
drivers/i2c/busses/i2c-s3c2410.c
drivers/i2c/i2c-core.c
drivers/ide/ide-tape.c
drivers/ieee1394/dv1394.c
drivers/ieee1394/nodemgr.c
drivers/ieee1394/raw1394.c
drivers/ieee1394/video1394.c
drivers/infiniband/core/ucm.c
drivers/input/evdev.c
drivers/input/input.c
drivers/input/joydev.c
drivers/input/joystick/adi.c
drivers/input/joystick/amijoy.c
drivers/input/joystick/analog.c
drivers/input/joystick/cobra.c
drivers/input/joystick/db9.c
drivers/input/joystick/gamecon.c
drivers/input/joystick/gf2k.c
drivers/input/joystick/grip.c
drivers/input/joystick/grip_mp.c
drivers/input/joystick/guillemot.c
drivers/input/joystick/iforce/iforce-main.c
drivers/input/joystick/iforce/iforce-packets.c
drivers/input/joystick/iforce/iforce-serio.c
drivers/input/joystick/iforce/iforce-usb.c
drivers/input/joystick/iforce/iforce.h
drivers/input/joystick/interact.c
drivers/input/joystick/magellan.c
drivers/input/joystick/sidewinder.c
drivers/input/joystick/spaceball.c
drivers/input/joystick/spaceorb.c
drivers/input/joystick/stinger.c
drivers/input/joystick/tmdc.c
drivers/input/joystick/turbografx.c
drivers/input/joystick/twidjoy.c
drivers/input/joystick/warrior.c
drivers/input/keyboard/amikbd.c
drivers/input/keyboard/atkbd.c
drivers/input/keyboard/corgikbd.c
drivers/input/keyboard/lkkbd.c
drivers/input/keyboard/maple_keyb.c
drivers/input/keyboard/newtonkbd.c
drivers/input/keyboard/spitzkbd.c
drivers/input/keyboard/sunkbd.c
drivers/input/keyboard/xtkbd.c
drivers/input/misc/m68kspkr.c
drivers/input/misc/pcspkr.c
drivers/input/misc/sparcspkr.c
drivers/input/mouse/alps.c
drivers/input/mouse/alps.h
drivers/input/mouse/amimouse.c
drivers/input/mouse/inport.c
drivers/input/mouse/lifebook.c
drivers/input/mouse/logibm.c
drivers/input/mouse/logips2pp.c
drivers/input/mouse/maplemouse.c
drivers/input/mouse/pc110pad.c
drivers/input/mouse/psmouse-base.c
drivers/input/mouse/psmouse.h
drivers/input/mouse/rpcmouse.c
drivers/input/mouse/sermouse.c
drivers/input/mouse/synaptics.c
drivers/input/mouse/vsxxxaa.c
drivers/input/mousedev.c
drivers/input/serio/i8042.c
drivers/input/touchscreen/corgi_ts.c
drivers/input/touchscreen/elo.c
drivers/input/touchscreen/gunze.c
drivers/input/touchscreen/h3600_ts_input.c
drivers/input/touchscreen/hp680_ts_input.c
drivers/input/touchscreen/mk712.c
drivers/input/touchscreen/mtouch.c
drivers/input/tsdev.c
drivers/isdn/capi/capi.c
drivers/macintosh/adb.c
drivers/macintosh/adbhid.c
drivers/macintosh/mac_hid.c
drivers/media/common/ir-common.c
drivers/media/dvb/cinergyT2/cinergyT2.c
drivers/media/dvb/dvb-core/dvbdev.c
drivers/media/dvb/dvb-usb/dvb-usb-remote.c
drivers/media/dvb/dvb-usb/dvb-usb.h
drivers/media/dvb/ttpci/av7110_ir.c
drivers/media/dvb/ttpci/budget-ci.c
drivers/media/dvb/ttusb-dec/ttusb_dec.c
drivers/media/video/bttvp.h
drivers/media/video/cx88/cx88-input.c
drivers/media/video/ir-kbd-gpio.c
drivers/media/video/ir-kbd-i2c.c
drivers/media/video/msp3400.c
drivers/media/video/saa7134/saa7134-input.c
drivers/media/video/saa7134/saa7134.h
drivers/media/video/tda9887.c
drivers/media/video/tuner-core.c
drivers/message/i2o/core.h
drivers/message/i2o/device.c
drivers/message/i2o/driver.c
drivers/message/i2o/iop.c
drivers/mfd/mcp-sa11x0.c
drivers/mfd/ucb1x00-ts.c
drivers/mmc/pxamci.c
drivers/mmc/wbsd.c
drivers/mtd/maps/sa1100-flash.c
drivers/mtd/mtdchar.c
drivers/net/dm9000.c
drivers/net/irda/sa1100_ir.c
drivers/net/irda/smsc-ircc2.c
drivers/net/phy/mdio_bus.c
drivers/net/ppp_generic.c
drivers/net/smc91x.c
drivers/net/wan/cosa.c
drivers/pci/pcie/portdrv_core.c
drivers/pcmcia/au1000_generic.c
drivers/pcmcia/ds.c
drivers/pcmcia/hd64465_ss.c
drivers/pcmcia/i82365.c
drivers/pcmcia/m32r_cfc.c
drivers/pcmcia/m32r_pcc.c
drivers/pcmcia/omap_cf.c
drivers/pcmcia/pxa2xx_base.c
drivers/pcmcia/rsrc_nonstatic.c
drivers/pcmcia/sa1100_generic.c
drivers/pcmcia/socket_sysfs.c
drivers/pcmcia/tcic.c
drivers/pcmcia/vrc4171_card.c
drivers/s390/char/tape_class.c
drivers/s390/char/vmlogrdr.c
drivers/scsi/ch.c
drivers/scsi/osst.c
drivers/scsi/sg.c
drivers/scsi/st.c
drivers/serial/8250.c
drivers/serial/imx.c
drivers/serial/mpc52xx_uart.c
drivers/serial/pxa.c
drivers/serial/s3c2410.c
drivers/serial/sa1100.c
drivers/serial/vr41xx_siu.c
drivers/usb/core/devio.c
drivers/usb/core/file.c
drivers/usb/core/hcd.c
drivers/usb/core/hub.c
drivers/usb/gadget/dummy_hcd.c
drivers/usb/gadget/omap_udc.c
drivers/usb/gadget/pxa2xx_udc.c
drivers/usb/host/isp116x-hcd.c
drivers/usb/host/ohci-omap.c
drivers/usb/host/ohci-pxa27x.c
drivers/usb/host/sl811-hcd.c
drivers/usb/input/acecad.c
drivers/usb/input/aiptek.c
drivers/usb/input/appletouch.c
drivers/usb/input/ati_remote.c
drivers/usb/input/hid-core.c
drivers/usb/input/hid-input.c
drivers/usb/input/hid-lgff.c
drivers/usb/input/hid-tmff.c
drivers/usb/input/hid.h
drivers/usb/input/itmtouch.c
drivers/usb/input/kbtab.c
drivers/usb/input/keyspan_remote.c
drivers/usb/input/mtouchusb.c
drivers/usb/input/pid.c
drivers/usb/input/powermate.c
drivers/usb/input/touchkitusb.c
drivers/usb/input/usbkbd.c
drivers/usb/input/usbmouse.c
drivers/usb/input/wacom.c
drivers/usb/input/xpad.c
drivers/usb/input/yealink.c
drivers/usb/media/konicawc.c
drivers/usb/storage/onetouch.c
drivers/video/backlight/corgi_bl.c
drivers/video/fbmem.c
drivers/video/imxfb.c
drivers/video/pxafb.c
drivers/video/s1d13xxxfb.c
drivers/video/s3c2410fb.c
drivers/video/sa1100fb.c
drivers/video/w100fb.c
fs/coda/psdev.c
fs/partitions/check.c
include/linux/device.h
include/linux/genhd.h
include/linux/i2o.h
include/linux/input.h
include/linux/pm.h
lib/kobject_uevent.c
net/bluetooth/hidp/core.c
sound/arm/pxa2xx-ac97.c
sound/core/init.c
sound/core/sound.c
sound/oss/soundcard.c
sound/pci/ac97/ac97_bus.c
sound/ppc/beep.c
sound/sound_core.c

index 27232be..783ddc3 100644 (file)
@@ -65,7 +65,7 @@ o  isdn4k-utils           3.1pre1                 # isdnctrl 2>&1|grep version
 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
 ==================
index 51f3bfb..008a341 100644 (file)
@@ -345,8 +345,7 @@ if (!retval) {
   <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,
index fabaca1..59806c9 100644 (file)
@@ -14,8 +14,8 @@ struct device_driver {
         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 @@ device; i.e. anything in the device's driver_data field.
 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
index ff2fef2..98b233c 100644 (file)
@@ -350,7 +350,7 @@ When a driver is registered, the bus's list of devices is iterated
 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:
index e8053d1..5cdb412 100644 (file)
@@ -550,15 +550,12 @@ struct locomo_save_data {
        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 @@ static int locomo_suspend(struct device *dev, pm_message_t state, u32 level)
        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;
index 1a47fbf..21e2a51 100644 (file)
@@ -801,7 +801,7 @@ struct sa1111_save_data {
 
 #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 @@ static int sa1111_suspend(struct device *dev, pm_message_t state, u32 level)
        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 @@ static int sa1111_suspend(struct device *dev, pm_message_t state, u32 level)
 /*
  *     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;
index 9e5245c..e8356b7 100644 (file)
@@ -102,26 +102,24 @@ static void check_scoop_reg(struct scoop_dev *sdev)
 }
 
 #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
index 0ef4282..136c269 100644 (file)
@@ -222,24 +222,22 @@ static int corgi_ssp_remove(struct device *dev)
        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;
 }
 
index 0c5eff3..052e4ca 100644 (file)
@@ -178,33 +178,27 @@ static int neponset_probe(struct device *dev)
 /*
  * 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;
-
-               *(unsigned int *)dev->power.saved_state = NCR_0;
-       }
+       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;
 
        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;
index 4647db4..13bae79 100644 (file)
@@ -163,7 +163,7 @@ static int cpuid_class_device_create(int i)
        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;
index 03100d6..44470fe 100644 (file)
@@ -246,7 +246,7 @@ static int msr_class_device_create(int i)
        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;
index 6b2eb6f..2a7d7ae 100644 (file)
@@ -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 {
index 783752b..e3b548d 100644 (file)
@@ -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);
 
index ce23dc8..c3e5697 100644 (file)
@@ -99,7 +99,8 @@ struct class * class_get(struct class * cls)
 
 void class_put(struct class * cls)
 {
-       subsys_put(&cls->subsys);
+       if (cls)
+               subsys_put(&cls->subsys);
 }
 
 
@@ -165,14 +166,25 @@ void class_unregister(struct class * cls)
 
 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 @@ static void class_dev_release(struct kobject * kobj)
        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 @@ static int class_hotplug(struct kset *kset, struct kobject *kobj, char **envp,
        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 @@ static ssize_t show_dev(struct class_device *class_dev, char *buf)
        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 @@ static char *make_class_name(struct class_device *class_dev)
 
 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 @@ int class_device_add(struct class_device *class_dev)
                        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 @@ int class_device_add(struct class_device *class_dev)
                                  class_name);
        }
 
+       kobject_hotplug(&class_dev->kobj, KOBJ_ADD);
+
        /* 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 (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);
-               up(&parent->sem);
+                               class_intf->add(class_dev, class_intf);
+               up(&parent_class->sem);
        }
-       kobject_hotplug(&class_dev->kobj, KOBJ_ADD);
 
  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 @@ int class_device_register(struct class_device *class_dev)
 /**
  * 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 @@ struct class_device *class_device_create(struct class *cls, dev_t devt,
        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 @@ error:
 
 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 @@ void class_device_del(struct class_device *class_dev)
                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 @@ void class_device_del(struct class_device *class_dev)
        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 @@ struct class_device * class_device_get(struct class_device *class_dev)
 
 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 @@ int class_interface_register(struct class_interface *class_intf)
        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 @@ void class_interface_unregister(struct class_interface *class_intf)
        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);
 
index 6ab73f5..8615b42 100644 (file)
@@ -154,6 +154,13 @@ static struct kset_hotplug_ops device_hotplug_ops = {
        .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 @@ void device_initialize(struct device *dev)
                   klist_children_put);
        INIT_LIST_HEAD(&dev->dma_pools);
        init_MUTEX(&dev->sem);
+       device_init_wakeup(dev, 0);
 }
 
 /**
@@ -258,6 +266,14 @@ int device_add(struct device *dev)
 
        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 @@ void device_del(struct device * dev)
 
        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 @@ static struct device * next_device(struct klist_iter * i)
 
 /**
  *     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
index b79badd..081c927 100644 (file)
@@ -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"),
index ef3fe51..161f3a3 100644 (file)
@@ -28,6 +28,7 @@ static struct device * next_device(struct klist_iter * i)
 /**
  *     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 @@ EXPORT_SYMBOL_GPL(driver_for_each_device);
 
 /**
  * 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
index 88ab044..cb1b98a 100644 (file)
@@ -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);
 
index a76ae5a..84e604e 100644 (file)
 #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.
  *
index 361e204..75ce871 100644 (file)
@@ -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 @@ static int platform_suspend(struct device * dev, pm_message_t state)
 {
        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 @@ static int platform_resume(struct device * dev)
 {
        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;
 }
 
index 8d04fb4..89c5787 100644 (file)
@@ -48,8 +48,81 @@ static ssize_t state_store(struct device * dev, struct device_attribute *attr, c
 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 = {
index 0e9e586..881c48d 100644 (file)
@@ -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"
 
index 45a2430..41ae0ed 100644 (file)
@@ -224,7 +224,7 @@ aoechr_init(void)
                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);
 
index b5be4b7..5c9c7c1 100644 (file)
@@ -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 @@ ataid_complete(struct aoedev *d, unsigned char *id)
        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 @@ ataid_complete(struct aoedev *d, unsigned char *id)
                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;
index d42840c..486ce1f 100644 (file)
@@ -337,10 +337,30 @@ static ssize_t disk_attr_show(struct kobject *kobj, struct attribute *attr,
        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 @@ static ssize_t disk_stats_read(struct gendisk * disk, char *page)
                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 disk_attribute disk_attr_stat = {
 };
 
 static struct attribute * default_attrs[] = {
+       &disk_attr_uevent.attr,
        &disk_attr_dev.attr,
        &disk_attr_range.attr,
        &disk_attr_removable.attr,
index b398239..82f2d6d 100644 (file)
@@ -674,7 +674,7 @@ static int __init pg_init(void)
        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",
index d8d3523..686c955 100644 (file)
@@ -971,7 +971,7 @@ static int __init pt_init(void)
        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 @@ static int __init pt_init(void)
                                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,
index 26271e3..8693835 100644 (file)
@@ -515,7 +515,7 @@ static int __init dsp56k_init_driver(void)
                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");
index 5745b74..821357c 100644 (file)
@@ -331,27 +331,27 @@ KERN_INFO
 
        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);
index 9e4e26a..d815d19 100644 (file)
@@ -721,8 +721,9 @@ ip2_loadmain(int *iop, int *irqp, unsigned char *firmware, int firmsize)
                        }
 
                        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 @@ ip2_loadmain(int *iop, int *irqp, unsigned char *firmware, int firmsize)
                                        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);
index a09ff10..7c0684d 100644 (file)
@@ -798,7 +798,7 @@ static void ipmi_new_smi(int if_num)
        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)
index 9c19e54..e3ddbdb 100644 (file)
@@ -5246,7 +5246,8 @@ int __init stli_init(void)
                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);
        }
 
index 2afb903..e572605 100644 (file)
@@ -805,7 +805,7 @@ static int lp_register(int nr, struct parport *port)
        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);
index f182752..38be4b0 100644 (file)
@@ -920,7 +920,8 @@ static int __init chr_dev_init(void)
 
        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);
index 0c83751..3e4c041 100644 (file)
@@ -234,7 +234,7 @@ int misc_register(struct miscdevice * misc)
        }
        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);
index 0e22880..306ee0f 100644 (file)
@@ -752,7 +752,7 @@ static struct file_operations pp_fops = {
 
 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);
 }
 
index f13e5de..30e4cbe 100644 (file)
@@ -128,7 +128,7 @@ raw_ioctl(struct inode *inode, struct file *filp,
 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 @@ static int __init raw_init(void)
                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,
index e1a90d9..887b8b2 100644 (file)
@@ -519,30 +519,28 @@ static struct timespec s3c2410_rtc_delta;
 
 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;
index 261a41b..1758a83 100644 (file)
@@ -437,7 +437,7 @@ scdrv_init(void)
                                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,
index 36ae9ad..f86c155 100644 (file)
@@ -424,10 +424,6 @@ static struct sonypi_eventtypes {
 
 #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 @@ static struct sonypi_device {
        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 input_keyrelease(void *data)
 
 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 @@ static int sonypi_disable(void)
 #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 @@ static struct device_driver sonypi_driver = {
        .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 @@ static int __devinit sonypi_probe(void)
        }
 
        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 @@ static int __devinit sonypi_probe(void)
 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 @@ static void __devexit sonypi_remove(void)
        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);
        }
 
index 951545a..1c68641 100644 (file)
@@ -3095,7 +3095,9 @@ static int __init stl_init(void)
                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;
index ec78d2f..41a94bc 100644 (file)
@@ -436,7 +436,7 @@ tipar_register(int nr, struct parport *port)
                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),
index e5953f3..f5649a3 100644 (file)
@@ -2728,7 +2728,7 @@ void tty_register_device(struct tty_driver *driver, unsigned index,
                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 @@ static int __init tty_init(void)
            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 @@ static int __init tty_init(void)
            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 @@ static int __init tty_init(void)
            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
index 79c2928..f66c7ad 100644 (file)
@@ -484,8 +484,10 @@ void vcs_make_devfs(struct tty_struct *tty)
        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 @@ int __init vcs_init(void)
 
        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;
 }
index 0aff45f..a5e104f 100644 (file)
@@ -956,9 +956,9 @@ static int viotape_probe(struct vio_dev *vdev, const struct vio_device_id *id)
        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);
index 3625b26..b732020 100644 (file)
@@ -464,32 +464,28 @@ static void s3c2410wdt_shutdown(struct device *dev)
 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;
 }
index 7f01076..0015da5 100644 (file)
@@ -296,11 +296,9 @@ static int hdaps_probe(struct device *dev)
        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 = {
index 9b41c9b..6f48579 100644 (file)
@@ -45,7 +45,7 @@ struct class_device *hwmon_device_register(struct device *dev)
                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))
index 73a092f..69fa282 100644 (file)
@@ -879,14 +879,12 @@ static int s3c24xx_i2c_remove(struct device *dev)
 }
 
 #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;
 }
index dda472e..45aa0e5 100644 (file)
@@ -48,7 +48,7 @@ static int i2c_bus_suspend(struct device * dev, pm_message_t state)
        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 @@ static int i2c_bus_resume(struct device * dev)
        int rc = 0;
        
        if (dev->driver && dev->driver->resume)
-               rc = dev->driver->resume(dev,0);
+               rc = dev->driver->resume(dev);
        return rc;
 }
 
index ee38e6b..47f2b83 100644 (file)
@@ -1013,6 +1013,8 @@ typedef struct ide_tape_obj {
 
 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 @@ static void ide_tape_release(struct kref *kref)
 
        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 @@ static int ide_tape_probe(struct device *dev)
 
        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 @@ MODULE_LICENSE("GPL");
 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 void __exit idetape_exit (void)
  */
 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);
index e34730c..cbbbe14 100644 (file)
@@ -2361,7 +2361,7 @@ static void dv1394_add_host (struct hpsb_host *host)
 
        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);
index 347ece6..7fff5a1 100644 (file)
@@ -1292,7 +1292,7 @@ static void nodemgr_suspend_ne(struct node_entry *ne)
 
                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 @@ static void nodemgr_resume_ne(struct node_entry *ne)
                        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);
 
index 0470f77..24411e6 100644 (file)
@@ -2912,7 +2912,7 @@ static int __init init_raw1394(void)
 
        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;
index 11be9c9..23911da 100644 (file)
@@ -1370,7 +1370,7 @@ static void video1394_add_host (struct hpsb_host *host)
        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),
index d0f0b0a..021b8f1 100644 (file)
@@ -1300,7 +1300,7 @@ static int __init ib_ucm_init(void)
                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);
index 3738d17..a4696cd 100644 (file)
@@ -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 file_operations evdev_fops = {
 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 @@ static struct input_handle *evdev_connect(struct input_handler *handler, struct
 
        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 @@ static void evdev_disconnect(struct input_handle *handle)
        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) {
index 14ae558..3b1685f 100644 (file)
 #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_close_device);
 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 @@ static struct input_device_id *input_match_device(struct input_device_id *id, st
        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;
-
-       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;
-       }
-
-       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);
+       int i;
+       int len = 0;
 
-       kfree(buf);
-       kfree(envp);
+       for (i = NBITS(max) - 1; i > 0; i--)
+               if (bitmap[i])
+                       break;
 
-#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 @@ static unsigned int input_devices_poll(struct file *file, poll_table *wait)
        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 @@ static int input_devices_read(char *buf, char **start, off_t pos, int count, int
 
                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 @@ static int input_devices_read(char *buf, char **start, off_t pos, int count, int
                        if (cnt >= count)
                                break;
                }
+
+               kfree(path);
        }
 
        if (&dev->node == &input_dev_list)
@@ -606,6 +507,240 @@ static inline int input_proc_init(void) { return 0; }
 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 @@ void input_register_device(struct input_dev *dev)
        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 @@ void input_unregister_device(struct input_dev *dev)
                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 @@ static struct file_operations input_fops = {
        .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 @@ static int __init input_init(void)
                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);
index e0938d1..20e2972 100644 (file)
@@ -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 file_operations joydev_fops = {
 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 @@ static struct input_handle *joydev_connect(struct input_handler *handler, struct
 
        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 @@ static void joydev_disconnect(struct input_handle *handle)
        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) {
index cf35ae6..9d95459 100644 (file)
@@ -54,7 +54,7 @@ MODULE_LICENSE("GPL");
 #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 @@ static struct {
  */
 
 struct adi {
-       struct input_dev dev;
+       struct input_dev *dev;
        int length;
        int ret;
        int idx;
@@ -215,7 +215,7 @@ static inline int adi_get_bits(struct adi *adi, int count)
 
 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 @@ static void adi_init_digital(struct gameport *gameport)
 
        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_id_decode(struct adi *adi, struct adi_port *port)
        }
 }
 
-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 @@ static void adi_init_center(struct adi *adi)
        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 @@ static int adi_connect(struct gameport *gameport, struct gameport_driver *drv)
        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 @@ static int adi_connect(struct gameport *gameport, struct gameport_driver *drv)
        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 @@ static int adi_connect(struct gameport *gameport, struct gameport_driver *drv)
 
        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 @@ static int adi_connect(struct gameport *gameport, struct gameport_driver *drv)
        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 @@ static void adi_disconnect(struct gameport *gameport)
 
        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);
index e996183..8558a99 100644 (file)
@@ -53,11 +53,9 @@ __obsolete_setup("amijoy=");
 
 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 @@ static irqreturn_t amijoy_interrupt(int irq, void *dummy, struct pt_regs *fp)
                                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 void amijoy_close(struct input_dev *dev)
 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] = input_allocate_device();
+               if (!amijoy_dev[i]) {
+                       err = -ENOMEM;
+                       goto fail;
+               }
 
-                       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;
+               if (!request_mem_region(CUSTOM_PHYSADDR + 10 + i * 2, 2, "amijoy [Denise]")) {
+                       input_free_device(amijoy_dev[i]);
+                       err = -EBUSY;
+                       goto fail;
+               }
 
-                       input_register_device(amijoy_dev + i);
-                       printk(KERN_INFO "input: %s at joy%ddat\n", amijoy_name, i);
+               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 @@ static void __exit amijoy_exit(void)
 
        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);
                }
 }
 
index 64b1313..c75ac6e 100644 (file)
@@ -111,7 +111,7 @@ static short analog_joy_btn[] = { BTN_TRIGGER, BTN_THUMB, BTN_TOP, BTN_TOP2, BTN
 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 unsigned long analog_faketime = 0;
 
 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 @@ static void analog_name(struct analog *analog)
  * 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 @@ static void analog_init_device(struct analog_port *port, struct analog *analog,
                        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 @@ static void analog_init_device(struct analog_port *port, struct analog *analog,
                                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 @@ static void analog_init_device(struct analog_port *port, struct analog *analog,
                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 @@ static int analog_connect(struct gameport *gameport, struct gameport_driver *drv
                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",
index 0b2e9fa..9a3dfc7 100644 (file)
@@ -44,13 +44,11 @@ MODULE_LICENSE("GPL");
 #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 @@ static void cobra_poll(struct gameport *gameport)
        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 void cobra_close(struct input_dev *dev)
 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 @@ static int cobra_connect(struct gameport *gameport, struct gameport_driver *drv)
        gameport_set_poll_handler(gameport, cobra_poll);
        gameport_set_poll_interval(gameport, 20);
 
-       for (i = 0; i < 2; i++)
-               if ((cobra->exists >> i) & 1) {
-
-                       sprintf(cobra->phys[i], "%s/input%d", gameport->phys, i);
+       for (i = 0; i < 2; i++) {
+               if (~(cobra->exists >> i) & 1)
+                       continue;
 
-                       cobra->dev[i].private = cobra;
-                       cobra->dev[i].open = cobra_open;
-                       cobra->dev[i].close = cobra_close;
+               cobra->dev[i] = input_dev = input_allocate_device();
+               if (!input_dev) {
+                       err = -ENOMEM;
+                       goto fail3;
+               }
 
-                       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;
+               sprintf(cobra->phys[i], "%s/input%d", gameport->phys, i);
 
-                       cobra->dev[i].evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
+               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_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);
+               input_dev->open = cobra_open;
+               input_dev->close = cobra_close;
 
-                       for (j = 0; cobra_btn[j]; j++)
-                               set_bit(cobra_btn[j], cobra->dev[i].keybit);
+               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]);
-                       printk(KERN_INFO "input: %s on %s\n", cobra_name, gameport->phys);
-               }
+               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 @@ static void cobra_disconnect(struct gameport *gameport)
 
        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);
index 2a3e4bb..499344c 100644 (file)
@@ -43,25 +43,28 @@ MODULE_AUTHOR("Vojtech Pavlik <vojtech@ucw.cz>");
 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);
-MODULE_PARM_DESC(dev, "Describes first attached device (<parport#>,<type>)");
+struct db9_config {
+       int args[2];
+       int nargs;
+};
 
-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_PARM_DESC(dev2, "Describes second attached device (<parport#>,<type>)");
+#define DB9_MAX_PORTS          3
+static struct db9_config db9[DB9_MAX_PORTS] __initdata;
 
-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(dev, db9[0].args, int, &db9[0].nargs, 0);
+MODULE_PARM_DESC(dev, "Describes first attached device (<parport#>,<type>)");
+module_param_array_named(dev2, db9[1].args, int, &db9[0].nargs, 0);
+MODULE_PARM_DESC(dev2, "Describes second attached device (<parport#>,<type>)");
+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 @@ __obsolete_setup("db9_3=");
 #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 @@ static int db9_saturn(int mode, struct parport *port, struct input_dev *dev)
        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 @@ static void db9_timer(unsigned long private)
 {
        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 @@ static void db9_timer(unsigned long private)
                        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 @@ static void db9_timer(unsigned long private)
                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 @@ static void db9_timer(unsigned long private)
                        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 @@ static void db9_timer(unsigned long private)
 
                        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 @@ static void db9_timer(unsigned long private)
 
                        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 @@ static void db9_timer(unsigned long private)
 
                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 @@ static void db9_timer(unsigned long private)
                                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 @@ static int db9_open(struct input_dev *dev)
        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 @@ static void db9_close(struct input_dev *dev)
        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;
+       }
+
+       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;
        }
 
-       if (!(db9 = kzalloc(sizeof(struct db9), GFP_KERNEL))) {
-               parport_put_port(pp);
-               return NULL;
+       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);
-
-       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_mode->n_pads, DB9_MAX_DEVICES)); i++) {
 
-       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;
-
-               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;
-
-               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->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;
+
+               input_dev->open = db9_open;
+               input_dev->close = db9_close;
+
+               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;
+
+       for (i = 0; i < DB9_MAX_PORTS; i++) {
+               if (db9[i].nargs == 0 || db9[i].args[DB9_ARG_PARPORT] < 0)
+                       continue;
+
+               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 (db9_base[0] || db9_base[1] || db9_base[2])
-               return 0;
+       if (err) {
+               while (--i >= 0)
+                       db9_remove(db9_base[i]);
+               return err;
+       }
 
-       return -ENODEV;
+       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);
index 5427bf9..7df2d82 100644 (file)
@@ -41,20 +41,22 @@ MODULE_AUTHOR("Vojtech Pavlik <vojtech@ucw.cz>");
 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 struct gc_config gc[GC_MAX_PORTS] __initdata;
 
-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");
+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 @@ __obsolete_setup("gc_3=");
 
 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_psx_read_packet(struct gc *gc, unsigned char data[5][GC_PSX_BYTES
 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 @@ static void gc_timer(unsigned long private)
                                        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 @@ static void gc_timer(unsigned long private)
                        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 @@ static void gc_timer(unsigned long private)
                        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 @@ static void gc_timer(unsigned long private)
 
                                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 @@ static void gc_timer(unsigned long private)
                                        }
 
                                        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 @@ static void gc_close(struct input_dev *dev)
        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 gc *gc;
-       struct parport *pp;
-       int i, j;
+       struct input_dev *input_dev;
+       int i;
 
-       if (config[0] < 0)
-               return NULL;
+       if (!pad_type)
+               return 0;
 
-       if (nargs < 2) {
-               printk(KERN_ERR "gamecon.c: at least one device must be specified\n");
-               return NULL;
+       if (pad_type < 1 || pad_type > GC_MAX) {
+               printk(KERN_WARNING "gamecon.c: Pad type %d unknown\n", pad_type);
+               return -EINVAL;
        }
 
-       pp = parport_find_number(config[0]);
-
-       if (!pp) {
-               printk(KERN_ERR "gamecon.c: no such parport\n");
-               return NULL;
+       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;
        }
 
-       if (!(gc = kzalloc(sizeof(struct gc), GFP_KERNEL))) {
-               parport_put_port(pp);
-               return NULL;
+       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;
        }
 
-       init_MUTEX(&gc->sem);
+       return 0;
+}
 
-       gc->pd = parport_register_device(pp, "gamecon", NULL, NULL, NULL, PARPORT_DEV_EXCL, NULL);
+static struct gc __init *gc_probe(int parport, int *pads, int n_pads)
+{
+       struct gc *gc;
+       struct parport *pp;
+       struct pardevice *pd;
+       int i;
+       int err;
 
-       parport_put_port(pp);
+       pp = parport_find_number(parport);
+       if (!pp) {
+               printk(KERN_ERR "gamecon.c: no such parport\n");
+               err = -EINVAL;
+               goto err_out;
+       }
 
-       if (!gc->pd) {
+       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");
-               kfree(gc);
-               return NULL;
+               err = -EBUSY;
+               goto err_put_pp;
        }
 
-       parport_claim(gc->pd);
+       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 = 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;
+               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].evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
+               input_register_device(gc->dev[i]);
+       }
 
-               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;
-               }
+       if (!gc->pads[0]) {
+               printk(KERN_ERR "gamecon.c: No valid devices specified\n");
+               err = -EINVAL;
+               goto err_free_gc;
+       }
 
-               gc->pads[0] |= gc_status_bit[i];
-               gc->pads[config[i + 1]] |= gc_status_bit[i];
+       parport_put_port(pp);
+       return gc;
 
-               switch(config[i + 1]) {
+ 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);
+}
 
-                       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;
-                               }
+static void __exit gc_remove(struct gc *gc)
+{
+       int i;
 
-                               break;
+       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);
+}
 
-                       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;
-                                       }
-                               }
+static int __init gc_init(void)
+{
+       int i;
+       int have_dev = 0;
+       int err = 0;
 
-                               for (j = 0; j < 12; j++)
-                                       set_bit(gc_psx_btn[j], gc->dev[i].keybit);
+       for (i = 0; i < GC_MAX_PORTS; i++) {
+               if (gc[i].nargs == 0 || gc[i].args[0] < 0)
+                       continue;
 
-                               break;
+               if (gc[i].nargs < 2) {
+                       printk(KERN_ERR "gamecon.c: at least one device must be specified\n");
+                       err = -EINVAL;
+                       break;
                }
 
-               sprintf(gc->phys[i], "%s/input%d", gc->pd->port->name, i);
+               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;
+               }
 
-                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;
+               have_dev = 1;
        }
 
-       parport_release(gc->pd);
-
-       if (!gc->pads[0]) {
-               parport_unregister_device(gc->pd);
-               kfree(gc);
-               return NULL;
+       if (err) {
+               while (--i >= 0)
+                       gc_remove(gc_base[i]);
+               return err;
        }
 
-       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);
-               }
-
-       return 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);
-
-       if (gc_base[0] || gc_base[1] || gc_base[2])
-               return 0;
-
-       return -ENODEV;
+       return have_dev ? 0 : -ENODEV;
 }
 
 static void __exit gc_exit(void)
 {
-       int i, j;
-
-       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);
-               }
+       int i;
+
+       for (i = 0; i < GC_MAX_PORTS; i++)
+               if (gc_base[i])
+                       gc_remove(gc_base[i]);
 }
 
 module_init(gc_init);
index 8e4f92b..e151f8c 100644 (file)
@@ -81,7 +81,7 @@ static short gf2k_seq_digital[] = { 590, 320, 860, 0 };
 
 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 int gf2k_get_bits(unsigned char *buf, int pos, int num, int shift)
 
 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 void gf2k_close(struct input_dev *dev)
 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 @@ static int gf2k_connect(struct gameport *gameport, struct gameport_driver *drv)
 
        gf2k->length = gf2k_lens[gf2k->id];
 
-       init_input_dev(&gf2k->dev);
-
-       gf2k->dev.private = gf2k;
-       gf2k->dev.open = gf2k_open;
-       gf2k->dev.close = gf2k_close;
-       gf2k->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
+       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.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 @@ static void gf2k_disconnect(struct gameport *gameport)
 {
        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);
index 9d3f910..e206bb5 100644 (file)
@@ -55,7 +55,7 @@ MODULE_LICENSE("GPL");
 
 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 @@ static void grip_poll(struct gameport *gameport)
 
        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 void grip_close(struct input_dev *dev)
 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 @@ static int grip_connect(struct gameport *gameport, struct gameport_driver *drv)
        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] = input_dev = input_allocate_device();
+               if (!input_dev) {
+                       err = -ENOMEM;
+                       goto fail3;
+               }
 
-                       grip->dev[i].private = grip;
+               sprintf(grip->phys[i], "%s/input%d", gameport->phys, i);
 
-                       grip->dev[i].open = grip_open;
-                       grip->dev[i].close = grip_close;
+               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;
 
-                       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;
+               input_dev->open = grip_open;
+               input_dev->close = grip_close;
 
-                       grip->dev[i].evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
+               input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
 
-                       for (j = 0; (t = grip_abs[grip->mode[i]][j]) >= 0; j++) {
+               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);
-                       }
+                       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, grip->dev[i].keybit);
+               for (j = 0; (t = grip_btn[grip->mode[i]][j]) >= 0; j++)
+                       if (t > 0)
+                               set_bit(t, input_dev->keybit);
 
-                       printk(KERN_INFO "input: %s on %s\n",
-                               grip_name[grip->mode[i]], gameport->phys);
-                       input_register_device(grip->dev + i);
-               }
+               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 @@ static void grip_disconnect(struct gameport *gameport)
        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);
index da17eee..a0ba93c 100644 (file)
@@ -32,23 +32,37 @@ MODULE_LICENSE("GPL");
 #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 @@ struct grip_mp {
 #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 @@ static const int init_seq[] = {
 
 /* 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 dig_mode_start(struct gameport *gameport, u32 *packet)
 
 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 @@ static int get_and_decode_packet(struct grip_mp *grip, int flags)
        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 @@ static int get_and_decode_packet(struct grip_mp *grip, int flags)
        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 @@ static int get_and_decode_packet(struct grip_mp *grip, int flags)
        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 @@ static int slots_valid(struct grip_mp *grip)
                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 @@ static int multiport_init(struct grip_mp *grip)
 
        /* 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 int multiport_init(struct grip_mp *grip)
 
 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 @@ static void grip_poll(struct gameport *gameport)
        }
 
        for (i = 0; i < 4; i++)
-               if (grip->dirty[i])
+               if (grip->port[i]->dirty)
                        report_slot(grip, i);
 }
 
@@ -571,35 +588,43 @@ static void grip_close(struct input_dev *dev)
  * 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;
+
+       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;
+
+       input_dev->open = grip_open;
+       input_dev->close = grip_close;
 
-       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->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
 
-       for (j = 0; (t = grip_btn[grip->mode[slot]][j]) >= 0; j++)
+       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 @@ static int grip_connect(struct gameport *gameport, struct gameport_driver *drv)
                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 @@ static void grip_disconnect(struct gameport *gameport)
        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);
index 6a70ec4..c528473 100644 (file)
@@ -67,7 +67,7 @@ struct guillemot_type {
 
 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 int guillemot_read_packet(struct gameport *gameport, u8 *data)
 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 void guillemot_close(struct input_dev *dev)
 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 @@ static int guillemot_connect(struct gameport *gameport, struct gameport_driver *
        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 @@ static void guillemot_disconnect(struct gameport *gameport)
        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);
 }
index e31b7b9..64b9c31 100644 (file)
@@ -144,7 +144,7 @@ static int iforce_upload_effect(struct input_dev *dev, struct ff_effect *effect)
        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 @@ static int iforce_upload_effect(struct input_dev *dev, struct ff_effect *effect)
  */
        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 @@ void iforce_delete_device(struct iforce *iforce)
 
 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 @@ int iforce_init_device(struct iforce *iforce)
        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 @@ int iforce_init_device(struct iforce *iforce)
 
        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 @@ int iforce_init_device(struct iforce *iforce)
  */
 
        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 @@ int iforce_init_device(struct iforce *iforce)
                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 @@ int iforce_init_device(struct iforce *iforce)
  */
 
        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 @@ int iforce_init_device(struct iforce *iforce)
                        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);
-
-       printk(KERN_DEBUG "iforce->dev.open = %p\n", iforce->dev.open);
+       input_register_device(iforce->dev);
 
-       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;
 }
index e5a31e5..4a26292 100644 (file)
@@ -139,7 +139,8 @@ printk(KERN_DEBUG "iforce-packets.c: control_playback %d %d\n", id, value);
 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 @@ static int mark_core_as_ready(struct iforce *iforce, unsigned short addr)
 
 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;
 
index 11f5190..64a78c5 100644 (file)
@@ -131,11 +131,10 @@ static int iforce_serio_connect(struct serio *serio, struct serio_driver *drv)
        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 @@ static int iforce_serio_connect(struct serio *serio, struct serio_driver *drv)
                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 @@ static void iforce_serio_disconnect(struct serio *serio)
 {
        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);
index 58600f9..64b4a30 100644 (file)
@@ -135,28 +135,24 @@ static int iforce_usb_probe(struct usb_interface *intf,
        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 @@ static int iforce_usb_probe(struct usb_interface *intf,
        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 @@ fail:
                kfree(iforce);
        }
 
-       return -ENODEV;
+       return err;
 }
 
 /* Called by iforce_delete() */
@@ -211,7 +209,7 @@ static void iforce_usb_disconnect(struct usb_interface *intf)
        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);
index bce247b..146f406 100644 (file)
@@ -117,7 +117,7 @@ struct iforce_device {
 };
 
 struct iforce {
-       struct input_dev dev;           /* Input device interface */
+       struct input_dev *dev;          /* Input device interface */
        struct iforce_device *type;
        int bus;
 
index d7b3472..8511ee7 100644 (file)
@@ -54,7 +54,7 @@ MODULE_LICENSE("GPL");
 
 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 int interact_read_packet(struct gameport *gameport, int length, u32 *data
 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 void interact_close(struct input_dev *dev)
 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 @@ static int interact_connect(struct gameport *gameport, struct gameport_driver *d
        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 @@ static void interact_disconnect(struct gameport *gameport)
 {
        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);
index 1ba5036..ca3cc23 100644 (file)
@@ -49,14 +49,13 @@ MODULE_LICENSE("GPL");
 
 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 int magellan_crunch_nibbles(unsigned char *data, int count)
 
 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 @@ static void magellan_disconnect(struct serio *serio)
 {
        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 void magellan_disconnect(struct serio *serio)
 static int magellan_connect(struct serio *serio, struct serio_driver *drv)
 {
        struct magellan *magellan;
-       int i, t;
-       int err;
-
-       if (!(magellan = kmalloc(sizeof(struct magellan), GFP_KERNEL)))
-               return -ENOMEM;
+       struct input_dev *input_dev;
+       int err = -ENOMEM;
+       int i;
 
-       memset(magellan, 0, sizeof(struct magellan));
+       magellan = kzalloc(sizeof(struct magellan), GFP_KERNEL);
+       input_dev = input_allocate_device();
+       if (!magellan || !input_dev)
+               goto fail;
 
-       magellan->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
+       magellan->dev = input_dev;
+       sprintf(magellan->phys, "%s/input0", serio->phys);
 
-       for (i = 0; i < 9; i++)
-               set_bit(magellan_buttons[i], magellan->dev.keybit);
+       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;
 
-       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;
-       }
+       input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
 
-       sprintf(magellan->phys, "%s/input0", serio->phys);
+       for (i = 0; i < 9; i++)
+               set_bit(magellan_buttons[i], input_dev->keybit);
 
-       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;
+       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;
-       }
-
-       input_register_device(&magellan->dev);
-
-       printk(KERN_INFO "input: %s on %s\n", magellan_name, serio->phys);
+       if (err)
+               goto fail;
 
+       input_register_device(magellan->dev);
        return 0;
+
+ fail: serio_set_drvdata(serio, NULL);
+       input_free_device(input_dev);
+       kfree(magellan);
+       return err;
 }
 
 /*
index 9e03537..eaaad45 100644 (file)
@@ -113,7 +113,7 @@ static struct {
 
 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_check(__u64 t)
 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 @@ static int sw_parse(unsigned char *buf, struct sw *sw)
                        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 @@ static int sw_parse(unsigned char *buf, struct sw *sw)
                                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 @@ static int sw_parse(unsigned char *buf, struct sw *sw)
                        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 @@ static int sw_parse(unsigned char *buf, struct sw *sw)
                        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 @@ static int sw_parse(unsigned char *buf, struct sw *sw)
                        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_guess_mode(unsigned char *buf, int len)
 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 @@ static int sw_connect(struct gameport *gameport, struct gameport_driver *drv)
                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);
+
+               dbg("%s%s [%d-bit id %d data %d]\n", sw->name, comment, m, l, k);
 
-               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);
+               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 @@ static void sw_disconnect(struct gameport *gameport)
        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);
index a436f22..d6f8db8 100644 (file)
@@ -70,8 +70,7 @@ static char *spaceball_names[] = {
  */
 
 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 @@ struct spaceball {
 
 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 @@ static void spaceball_disconnect(struct serio *serio)
 {
        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 void spaceball_disconnect(struct serio *serio)
 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);
+
+       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;
 
-       spaceball->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
+       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;
-       }
-
-       input_register_device(&spaceball->dev);
-
-       printk(KERN_INFO "input: %s on serio%s\n",
-               spaceball_names[id], serio->phys);
+       if (err)
+               goto fail;
 
+       input_register_device(spaceball->dev);
        return 0;
+
+ fail: serio_set_drvdata(serio, NULL);
+       input_free_device(input_dev);
+       kfree(spaceball);
+       return err;
 }
 
 /*
index 01fd2e4..7c123a0 100644 (file)
@@ -52,15 +52,13 @@ MODULE_LICENSE("GPL");
 
 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 unsigned char *spaceorb_errors[] = { "EEPROM storing 0 failed", "Receive
 
 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 @@ static void spaceorb_process_packet(struct spaceorb *spaceorb, struct pt_regs *r
                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 @@ static void spaceorb_process_packet(struct spaceorb *spaceorb, struct pt_regs *r
 
                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 @@ static void spaceorb_disconnect(struct serio *serio)
 {
        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 void spaceorb_disconnect(struct serio *serio)
 static int spaceorb_connect(struct serio *serio, struct serio_driver *drv)
 {
        struct spaceorb *spaceorb;
-       int i, t;
-       int err;
-
-       if (!(spaceorb = kmalloc(sizeof(struct spaceorb), GFP_KERNEL)))
-               return -ENOMEM;
-
-       memset(spaceorb, 0, sizeof(struct spaceorb));
+       struct input_dev *input_dev;
+       int err = -ENOMEM;
+       int i;
 
-       spaceorb->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
+       spaceorb = kzalloc(sizeof(struct spaceorb), GFP_KERNEL);
+       input_dev = input_allocate_device();
+       if (!spaceorb || !input_dev)
+               goto fail;
 
-       for (i = 0; i < 6; i++)
-               set_bit(spaceorb_buttons[i], spaceorb->dev.keybit);
+       spaceorb->dev = input_dev;
+       sprintf(spaceorb->phys, "%s/input0", serio->phys);
 
-       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;
-       }
+       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;
 
-       spaceorb->serio = serio;
-       spaceorb->dev.private = spaceorb;
+       input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
 
-       sprintf(spaceorb->phys, "%s/input0", serio->phys);
+       for (i = 0; i < 6; i++)
+               set_bit(spaceorb_buttons[i], input_dev->keybit);
 
-       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;
+       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;
-       }
-
-       input_register_device(&spaceorb->dev);
+       if (err)
+               goto fail;
 
+       input_register_device(spaceorb->dev);
        return 0;
+
+ fail: serio_set_drvdata(serio, NULL);
+       input_free_device(input_dev);
+       kfree(spaceorb);
+       return err;
 }
 
 /*
index 6f6e675..0a9ed1d 100644 (file)
@@ -48,14 +48,12 @@ MODULE_LICENSE("GPL");
 
 #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 @@ struct stinger {
 
 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 @@ static void stinger_disconnect(struct serio *serio)
 {
        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 void stinger_disconnect(struct serio *serio)
 static int stinger_connect(struct serio *serio, struct serio_driver *drv)
 {
        struct stinger *stinger;
-       int i;
-       int err;
-
-       if (!(stinger = kmalloc(sizeof(struct stinger), GFP_KERNEL)))
-               return -ENOMEM;
-
-       memset(stinger, 0, sizeof(struct stinger));
+       struct input_dev *input_dev;
+       int err = -ENOMEM;
 
-       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 = kmalloc(sizeof(struct stinger), GFP_KERNEL);
+       input_dev = input_allocate_device();
+       if (!stinger || !input_dev)
+               goto fail;
 
+       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;
-
-       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->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;
+
+       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;
-       }
-
-       input_register_device(&stinger->dev);
-
-       printk(KERN_INFO "input: %s on %s\n",  stinger_name, serio->phys);
+       if (err)
+               goto fail;
 
+       input_register_device(stinger->dev);
        return 0;
+
+ fail: serio_set_drvdata(serio, NULL);
+       input_free_device(input_dev);
+       kfree(stinger);
+       return err;
 }
 
 /*
index 7431efc..3a7d1bb 100644 (file)
@@ -63,37 +63,70 @@ MODULE_LICENSE("GPL");
 #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 @@ struct tmdc {
        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 @@ static int tmdc_read_packet(struct gameport *gameport, unsigned char data[2][TMD
        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 @@ static void tmdc_poll(struct gameport *gameport)
 {
        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
-
-       for (j = 0; j < 2; j++)
-               if (r & (1 << j) & tmdc->exists) {
-
-                       if (data[j][TMDC_BYTE_ID] != tmdc->mode[j]) {
-                               bad = 1;
-                               continue;
-                       }
-
-                       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]) {
+       else {
+               for (i = 0; i < 2; i++) {
+                       if (r & (1 << i) & tmdc->exists) {
 
-                               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];
+                               if (tmdc_parse_packet(tmdc->port[i], data[i]))
+                                       bad = 1;
                        }
-
-                       input_sync(dev);
+               }
        }
 
        tmdc->bads += bad;
@@ -235,31 +277,89 @@ static void tmdc_close(struct input_dev *dev)
        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 @@ static int tmdc_connect(struct gameport *gameport, struct gameport_driver *drv)
        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 @@ static void tmdc_disconnect(struct gameport *gameport)
        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);
index 0c5b9c8..7e97649 100644 (file)
@@ -42,19 +42,21 @@ MODULE_AUTHOR("Vojtech Pavlik <vojtech@ucw.cz>");
 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);
-MODULE_PARM_DESC(map, "Describes first set of devices (<parport#>,<js1>,<js2>,..<js7>");
+#define TGFX_MAX_PORTS         3
+#define TGFX_MAX_DEVICES       7
 
-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_PARM_DESC(map2, "Describes second set of devices");
+struct tgfx_config {
+       int args[TGFX_MAX_DEVICES + 1];
+       int nargs;
+};
+
+static struct tgfx_config tgfx[TGFX_MAX_PORTS] __initdata;
 
-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(map, tgfx[0].args, int, &tgfx[0].nargs, 0);
+MODULE_PARM_DESC(map, "Describes first set of devices (<parport#>,<js1>,<js2>,..<js7>");
+module_param_array_named(map2, tgfx[1].args, int, &tgfx[1].nargs, 0);
+MODULE_PARM_DESC(map2, "Describes second set of devices");
+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 @@ __obsolete_setup("tgfx_3=");
 #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 @@ static void tgfx_timer(unsigned long private)
        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 @@ static void tgfx_close(struct input_dev *dev)
        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;
        }
 
-       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 = 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 = 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);
+               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].private = tgfx;
-                       tgfx->dev[i].open = tgfx_open;
-                       tgfx->dev[i].close = tgfx_close;
+               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;
+               }
 
-                       sprintf(tgfx->phys[i], "%s/input0", tgfx->pd->port->name);
+               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);
 
-                       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;
+               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;
 
-                       tgfx->dev[i].evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
-                       tgfx->dev[i].absbit[0] = BIT(ABS_X) | BIT(ABS_Y);
+               input_dev->private = tgfx;
+               input_dev->open = tgfx_open;
+               input_dev->close = tgfx_close;
 
-                       for (j = 0; j < config[i+1]; j++)
-                               set_bit(tgfx_buttons[j], tgfx->dev[i].keybit);
+               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);
 
-                       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;
+               for (j = 0; j < n_buttons[i]; j++)
+                       set_bit(tgfx_buttons[j], input_dev->keybit);
 
-                       input_register_device(tgfx->dev + i);
-                       printk(KERN_INFO "input: %d-button Multisystem joystick on %s\n",
-                               config[i+1], tgfx->pd->port->name);
-               }
+               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;
+
+       for (i = 0; i < TGFX_MAX_PORTS; i++) {
+               if (tgfx[i].nargs == 0 || tgfx[i].args[0] < 0)
+                       continue;
+
+               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 (tgfx_base[0] || tgfx_base[1] || tgfx_base[2])
-               return 0;
+       if (err) {
+               while (--i >= 0)
+                       tgfx_remove(tgfx_base[i]);
+               return err;
+       }
 
-       return -ENODEV;
+       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);
index 0379bc1..cd3a1e7 100644 (file)
@@ -69,8 +69,6 @@ MODULE_LICENSE("GPL");
 
 #define TWIDJOY_MAX_LENGTH 5
 
-static char *twidjoy_name = "Handykey Twiddler";
-
 static struct twidjoy_button_spec {
        int bitshift;
        int bitmask;
@@ -95,7 +93,7 @@ twidjoy_buttons[] = {
  */
 
 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 @@ struct twidjoy {
 
 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;
-
-               button_bits = ((data[1] & 0x7f) << 7) | (data[0] & 0x7f);
+       struct input_dev *dev = twidjoy->dev;
+       unsigned char *data = twidjoy->data;
+       struct twidjoy_button_spec *bp;
+       int button_bits, abs_x, abs_y;
 
-               input_regs(dev, regs);
+       button_bits = ((data[1] & 0x7f) << 7) | (data[0] & 0x7f);
 
-               for (bp = twidjoy_buttons; bp->bitmask; bp++) {
-                       int value = (button_bits & (bp->bitmask << bp->bitshift)) >> bp->bitshift;
-                       int i;
+       input_regs(dev, regs);
 
-                       for (i = 0; i < bp->bitmask; i++)
-                               input_report_key(dev, bp->buttons[i], i+1 == value);
-               }
+       for (bp = twidjoy_buttons; bp->bitmask; bp++) {
+               int value = (button_bits & (bp->bitmask << bp->bitshift)) >> bp->bitshift;
+               int i;
 
-               abs_x = ((data[4] & 0x07) << 5) | ((data[3] & 0x7C) >> 2);
-               if (data[4] & 0x08) abs_x -= 256;
+               for (i = 0; i < bp->bitmask; i++)
+                       input_report_key(dev, bp->buttons[i], i+1 == value);
+       }
 
-               abs_y = ((data[3] & 0x01) << 7) | ((data[2] & 0x7F) >> 0);
-               if (data[3] & 0x02) abs_y -= 256;
+       abs_x = ((data[4] & 0x07) << 5) | ((data[3] & 0x7C) >> 2);
+       if (data[4] & 0x08) abs_x -= 256;
 
-               input_report_abs(dev, ABS_X, -abs_x);
-               input_report_abs(dev, ABS_Y, +abs_y);
+       abs_y = ((data[3] & 0x01) << 7) | ((data[2] & 0x7F) >> 0);
+       if (data[3] & 0x02) abs_y -= 256;
 
-               input_sync(dev);
-       }
+       input_report_abs(dev, ABS_X, -abs_x);
+       input_report_abs(dev, ABS_Y, +abs_y);
 
-       return;
+       input_sync(dev);
 }
 
 /*
@@ -179,9 +173,9 @@ static void twidjoy_disconnect(struct serio *serio)
 {
        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 @@ static int twidjoy_connect(struct serio *serio, struct serio_driver *drv)
 {
        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;
 
-       memset(twidjoy, 0, sizeof(struct twidjoy));
+       twidjoy = kzalloc(sizeof(struct twidjoy), GFP_KERNEL);
+       input_dev = input_allocate_device();
+       if (!twidjoy || !input_dev)
+               goto fail;
 
+       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;
-
-       twidjoy->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
-
-       for (bp = twidjoy_buttons; bp->bitmask; bp++) {
+       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;
+
+       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 (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;
-       }
-
-       input_register_device(&twidjoy->dev);
-
-       printk(KERN_INFO "input: %s on %s\n", twidjoy_name, serio->phys);
+       if (err)
+               goto fail;
 
+       input_register_device(twidjoy->dev);
        return 0;
+
+ fail: serio_set_drvdata(serio, NULL);
+       input_free_device(input_dev);
+       kfree(twidjoy);
+       return err;
 }
 
 /*
index 6976a21..99a642d 100644 (file)
@@ -47,14 +47,13 @@ MODULE_LICENSE("GPL");
 
 #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 @@ struct warrior {
 
 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 @@ static void warrior_disconnect(struct serio *serio)
 {
        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 void warrior_disconnect(struct serio *serio)
 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;
-
-       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 = kzalloc(sizeof(struct warrior), GFP_KERNEL);
+       input_dev = input_allocate_device();
+       if (!warrior || !input_dev)
+               goto fail;
 
+       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;
-
-       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->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;
+
+       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;
-       }
-
-       input_register_device(&warrior->dev);
-
-       printk(KERN_INFO "input: Logitech WingMan Warrior on %s\n", serio->phys);
+       if (err)
+               goto fail;
 
+       input_register_device(warrior->dev);
        return 0;
+
+ fail: serio_set_drvdata(serio, NULL);
+       input_free_device(input_dev);
+       kfree(warrior);
+       return err;
 }
 
 /*
index 4e8e8ea..3d63bc1 100644 (file)
@@ -155,10 +155,7 @@ static const char *amikbd_messages[8] = {
        [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 @@ static irqreturn_t amikbd_interrupt(int irq, void *dummy, struct pt_regs *fp)
 
                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 @@ static int __init amikbd_init(void)
        if (!request_mem_region(CIAA_PHYSADDR-1+0xb00, 0x100, "amikeyb"))
                return -EBUSY;
 
-       init_input_dev(&amikbd_dev);
-
-       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 = 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->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);
index 1ad8c2e..820c7fd 100644 (file)
@@ -185,12 +185,12 @@ static struct {
 
 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 @@ static irqreturn_t atkbd_interrupt(struct serio *serio, unsigned char data,
        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 @@ static irqreturn_t atkbd_interrupt(struct serio *serio, unsigned char data,
                        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 @@ static irqreturn_t atkbd_interrupt(struct serio *serio, unsigned char data,
        }
 
        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 @@ static irqreturn_t atkbd_interrupt(struct serio *serio, unsigned char data,
                                       "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 @@ static irqreturn_t atkbd_interrupt(struct serio *serio, unsigned char data,
                        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 @@ static irqreturn_t atkbd_interrupt(struct serio *serio, unsigned char data,
                                        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 @@ static irqreturn_t atkbd_interrupt(struct serio *serio, unsigned char data,
                                        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 @@ static int atkbd_event(struct input_dev *dev, unsigned int type, unsigned int co
 
                        return 0;
 
-
                case EV_REP:
 
                        if (atkbd->softrepeat) return 0;
@@ -693,7 +692,7 @@ static void atkbd_disconnect(struct serio *serio)
        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 @@ static void atkbd_disconnect(struct serio *serio)
 
 
 /*
- * 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_keycode_table(struct atkbd *atkbd)
 
 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 void atkbd_set_device_attrs(struct atkbd *atkbd)
 static int atkbd_connect(struct serio *serio, struct serio_driver *drv)
 {
        struct atkbd *atkbd;
-       int err;
-
-       if (!(atkbd = kmalloc(sizeof(struct atkbd), GFP_KERNEL)))
-               return - ENOMEM;
+       struct input_dev *dev;
+       int err = -ENOMEM;
 
-       memset(atkbd, 0, sizeof(struct atkbd));
+       atkbd = kzalloc(sizeof(struct atkbd), GFP_KERNEL);
+       dev = input_allocate_device();
+       if (!atkbd || !dev)
+               goto fail;
 
+       atkbd->dev = dev;
        ps2_init(&atkbd->ps2dev, serio);
 
        switch (serio->id.type) {
@@ -828,19 +834,15 @@ static int atkbd_connect(struct serio *serio, struct serio_driver *drv)
        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 @@ static int atkbd_connect(struct serio *serio, struct serio_driver *drv)
                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 @@ static int atkbd_connect(struct serio *serio, struct serio_driver *drv)
 
        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 @@ static int atkbd_reconnect(struct serio *serio)
        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_show_extra(struct atkbd *atkbd, char *buf)
 
 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 @@ static ssize_t atkbd_set_extra(struct atkbd *atkbd, const char *buf, size_t coun
                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_show_scroll(struct atkbd *atkbd, char *buf)
 
 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 @@ static ssize_t atkbd_set_scroll(struct atkbd *atkbd, const char *buf, size_t cou
                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_show_set(struct atkbd *atkbd, char *buf)
 
 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 @@ static ssize_t atkbd_set_set(struct atkbd *atkbd, const char *buf, size_t count)
                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_show_softrepeat(struct atkbd *atkbd, char *buf)
 
 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 @@ static ssize_t atkbd_set_softrepeat(struct atkbd *atkbd, const char *buf, size_t
                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_show_softraw(struct atkbd *atkbd, char *buf)
 
 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 @@ static ssize_t atkbd_set_softraw(struct atkbd *atkbd, const char *buf, size_t co
                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;
 }
index cd4b6e7..3210d29 100644 (file)
@@ -70,8 +70,7 @@ static unsigned char corgikbd_keycode[NR_SCANCODES] = {
 
 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 @@ static void corgikbd_scankeyboard(struct corgikbd *corgikbd_data, struct pt_regs
        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 @@ static void corgikbd_scankeyboard(struct corgikbd *corgikbd_data, struct pt_regs
                        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 @@ static void corgikbd_scankeyboard(struct corgikbd *corgikbd_data, struct pt_regs
 
        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 @@ static void corgikbd_hinge_timer(unsigned long data)
                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 @@ static void corgikbd_hinge_timer(unsigned long data)
 }
 
 #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 corgikbd_resume(struct device *dev, uint32_t level)
 
 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 @@ static int __init corgikbd_probe(struct device *dev)
 
        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));
+
+       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], corgikbd->input.keybit);
-       clear_bit(0, corgikbd->input.keybit);
-       set_bit(SW_0, corgikbd->input.swbit);
-       set_bit(SW_1, corgikbd->input.swbit);
+               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);
 
-       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 @@ static int __init corgikbd_probe(struct device *dev)
        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 @@ static int corgikbd_remove(struct device *dev)
        del_timer_sync(&corgikbd->htimer);
        del_timer_sync(&corgikbd->timer);
 
-       input_unregister_device(&corgikbd->input);
+       input_unregister_device(corgikbd->input);
 
        kfree(corgikbd);
 
index 098963c..7f06780 100644 (file)
@@ -102,7 +102,7 @@ static int ctrlclick_volume = 100; /* % */
 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 @@ static lk_keycode_t lkkbd_keycode[LK_NUM_KEYCODES] = {
 };
 
 #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 @@ struct lkkbd {
        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 @@ lkkbd_interrupt (struct serio *serio, unsigned char data, unsigned int flags,
        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 @@ lkkbd_interrupt (struct serio *serio, unsigned char data, unsigned int flags,
 
        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 @@ lkkbd_interrupt (struct serio *serio, unsigned char data, unsigned int flags,
 
                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 @@ lkkbd_reinit (void *data)
        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 @@ lkkbd_reinit (void *data)
        }
 
        /* 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 @@ static int
 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;
-
-       lk->dev.event = lkkbd_event;
-       lk->dev.private = lk;
+       strlcpy (lk->name, "DEC LK keyboard", sizeof(lk->name));
+       snprintf (lk->phys, sizeof(lk->phys), "%s/input0", serio->phys);
+
+       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 @@ lkkbd_disconnect (struct serio *serio)
 {
        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);
 }
 
index eecbde2..cc6aaf9 100644 (file)
@@ -37,7 +37,7 @@ static unsigned char dc_kbd_keycode[256] = {
 
 
 struct dc_kbd {
-       struct input_dev dev;
+       struct input_dev *dev;
        unsigned char new[8];
        unsigned char old[8];
 };
@@ -46,30 +46,24 @@ struct dc_kbd {
 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 @@ static void dc_kbd_callback(struct mapleq *mq)
        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;
-
-       kbd->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_REP);
-
-       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);
+       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;
+       }
 
-       kbd->dev.private = kbd;
+       kbd->dev = input_dev;
 
-       kbd->dev.name = dev->product_name;
-       kbd->dev.id.bustype = BUS_MAPLE;
+       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);
 
-       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 @@ static void dc_kbd_disconnect(struct maple_device *dev)
 {
        struct dc_kbd *kbd = dev->private_data;
 
-       input_unregister_device(&kbd->dev);
+       input_unregister_device(kbd->dev);
        kfree(kbd);
 }
 
index 2e8ce16..d10983c 100644 (file)
@@ -57,11 +57,9 @@ static unsigned char nkbd_keycode[128] = {
        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 @@ static irqreturn_t nkbd_interrupt(struct serio *serio,
 
        /* 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 irqreturn_t nkbd_interrupt(struct serio *serio,
 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;
-       }
-
-       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);
+       if (err)
+               goto fail;
 
+       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);
 }
 
index 344f460..cee9c73 100644 (file)
@@ -85,7 +85,7 @@ static int spitz_senses[] = {
 
 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 @@ static void spitzkbd_scankeyboard(struct spitzkbd *spitzkbd_data, struct pt_regs
 
        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 @@ static void spitzkbd_scankeyboard(struct spitzkbd *spitzkbd_data, struct pt_regs
                        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 @@ static void spitzkbd_scankeyboard(struct spitzkbd *spitzkbd_data, struct pt_regs
 
        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 irqreturn_t spitzkbd_interrupt(int irq, void *dev_id, struct pt_regs *reg
 static void spitzkbd_timer_callback(unsigned long data)
 {
        struct spitzkbd *spitzkbd_data = (struct spitzkbd *) data;
+
        spitzkbd_scankeyboard(spitzkbd_data, NULL);
 }
 
@@ -298,9 +298,9 @@ static void spitzkbd_hinge_timer(unsigned long data)
        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 @@ static void spitzkbd_hinge_timer(unsigned long data)
 }
 
 #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;
-
-               /* 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);
-       }
+       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);
+
        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 spitzkbd_resume(struct device *dev, uint32_t level)
 
 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 @@ static int __init spitzkbd_probe(struct device *dev)
        spitzkbd->htimer.function = spitzkbd_hinge_timer;
        spitzkbd->htimer.data = (unsigned long) spitzkbd;
 
-       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->suspend_jiffies = jiffies;
+
+       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(input_dev);
 
-       input_register_device(&spitzkbd->input);
        mod_timer(&spitzkbd->htimer, jiffies + msecs_to_jiffies(HINGE_SCAN_INTERVAL));
 
        /* Setup sense interrupts - RisingEdge Detect, sense lines as inputs */
@@ -444,7 +453,7 @@ static int spitzkbd_remove(struct device *dev)
        del_timer_sync(&spitzkbd->htimer);
        del_timer_sync(&spitzkbd->timer);
 
-       input_unregister_device(&spitzkbd->input);
+       input_unregister_device(spitzkbd->input);
 
        kfree(spitzkbd);
 
index 4bae5d8..b15b6d8 100644 (file)
@@ -76,13 +76,14 @@ static unsigned char sunkbd_keycode[128] = {
 
 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 @@ static irqreturn_t sunkbd_interrupt(struct serio *serio,
                        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 @@ static int sunkbd_initialize(struct sunkbd *sunkbd)
        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 @@ static void sunkbd_reinit(void *data)
 
        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 void sunkbd_reinit(void *data)
 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));
-       for (i = 0; i < 128; i++)
-               set_bit(sunkbd->keycode[i], sunkbd->dev.keybit);
-       clear_bit(0, sunkbd->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);
+       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], input_dev->keybit);
+       clear_bit(0, input_dev->keybit);
 
+       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 int sunkbd_connect(struct serio *serio, struct serio_driver *drv)
 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);
index 19eaec7..4135e3e 100644 (file)
@@ -56,11 +56,9 @@ static unsigned char xtkbd_keycode[256] = {
        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 @@ static irqreturn_t xtkbd_interrupt(struct serio *serio,
                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 irqreturn_t xtkbd_interrupt(struct serio *serio,
 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;
-
-       serio_set_drvdata(serio, 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;
 
-       err = serio_open(serio, drv);
-       if (err) {
-               serio_set_drvdata(serio, NULL);
-               kfree(xtkbd);
-               return err;
-       }
+       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);
 
-       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;
+               set_bit(xtkbd->keycode[i], input_dev->keybit);
+       clear_bit(0, input_dev->keybit);
 
-       input_register_device(&xtkbd->dev);
+       serio_set_drvdata(serio, xtkbd);
 
-       printk(KERN_INFO "input: %s on %s\n", xtkbd_name, serio->phys);
+       err = serio_open(serio, drv);
+       if (err)
+               goto fail;
 
+       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);
 }
 
index 64abdd9..04489ad 100644 (file)
@@ -24,9 +24,7 @@ MODULE_AUTHOR("Richard Zidlicky <rz@linux-m68k.org>");
 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 m68kspkr_event(struct input_dev *dev, unsigned int type, unsigned int
 
 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);
index 3013194..e34633c 100644 (file)
@@ -23,9 +23,7 @@ MODULE_AUTHOR("Vojtech Pavlik <vojtech@ucw.cz>");
 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 pcspkr_event(struct input_dev *dev, unsigned int type, unsigned int c
 
 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);
 }
index cdc3fb3..5778220 100644 (file)
 #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.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->evbit[0] = BIT(EV_SND);
+       sparcspkr_dev->sndbit[0] = BIT(SND_BELL) | BIT(SND_TONE);
+
+       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 @@ static int __init init_ebus_beep(struct linux_ebus_device *edev)
 {
        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 @@ static int __init init_isa_beep(struct sparc_isa_device *isa_dev)
 {
        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 int __init sparcspkr_init(void)
 
 static void __exit sparcspkr_exit(void)
 {
-       input_unregister_device(&sparcspkr_dev);
+       input_unregister_device(sparcspkr_dev);
 }
 
 module_init(sparcspkr_init);
index b20783f..4acc7fd 100644 (file)
@@ -79,8 +79,8 @@ static void alps_process_packet(struct psmouse *psmouse, struct pt_regs *regs)
 {
        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 int alps_reconnect(struct psmouse *psmouse)
 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 @@ int alps_init(struct psmouse *psmouse)
        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;
-
-       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->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;
 
-       input_register_device(&priv->dev2);
+       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);
 
-       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 @@ int alps_init(struct psmouse *psmouse)
        return 0;
 
 init_fail:
+       input_free_device(dev2);
        kfree(priv);
        return -1;
 }
index aba103d..e428f8d 100644 (file)
@@ -22,7 +22,7 @@ struct alps_model_info {
 };
 
 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 */
index e994849..d13d4c8 100644 (file)
@@ -34,10 +34,7 @@ MODULE_DESCRIPTION("Amiga mouse driver");
 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 @@ static irqreturn_t amimouse_interrupt(int irq, void *dummy, struct pt_regs *fp)
 
        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 @@ static int __init amimouse_init(void)
        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 = "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;
 
-       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->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;
 
-       input_register_device(&amimouse_dev);
+       input_register_device(amimouse_dev);
 
-        printk(KERN_INFO "input: %s at joy0dat\n", amimouse_name);
        return 0;
 }
 
 static void __exit amimouse_exit(void)
 {
-        input_unregister_device(&amimouse_dev);
+        input_unregister_device(amimouse_dev);
 }
 
 module_init(amimouse_init);
index 1f62c01..afc66f5 100644 (file)
@@ -87,40 +87,7 @@ MODULE_PARM_DESC(irq, "IRQ number (5=default)");
 
 __obsolete_setup("inport_irq=");
 
-static irqreturn_t inport_interrupt(int irq, void *dev_id, struct pt_regs *regs);
-
-static int inport_open(struct input_dev *dev)
-{
-       if (request_irq(inport_irq, inport_interrupt, 0, "inport", NULL))
-               return -EBUSY;
-       outb(INPORT_REG_MODE, INPORT_CONTROL_PORT);
-       outb(INPORT_MODE_IRQ | INPORT_MODE_BASE, INPORT_DATA_PORT);
-
-       return 0;
-}
-
-static void inport_close(struct input_dev *dev)
-{
-       outb(INPORT_REG_MODE, INPORT_CONTROL_PORT);
-       outb(INPORT_MODE_BASE, INPORT_DATA_PORT);
-       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 struct input_dev *inport_dev;
 
 static irqreturn_t inport_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 {
@@ -129,31 +96,48 @@ static irqreturn_t inport_interrupt(int irq, void *dev_id, struct pt_regs *regs)
        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);
+       input_regs(inport_dev, regs);
 
        outb(INPORT_REG_X, INPORT_CONTROL_PORT);
-       input_report_rel(&inport_dev, REL_X, inb(INPORT_DATA_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));
+       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);
+       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);
+       input_sync(inport_dev);
        return IRQ_HANDLED;
 }
 
+static int inport_open(struct input_dev *dev)
+{
+       if (request_irq(inport_irq, inport_interrupt, 0, "inport", NULL))
+               return -EBUSY;
+       outb(INPORT_REG_MODE, INPORT_CONTROL_PORT);
+       outb(INPORT_MODE_IRQ | INPORT_MODE_BASE, INPORT_DATA_PORT);
+
+       return 0;
+}
+
+static void inport_close(struct input_dev *dev)
+{
+       outb(INPORT_REG_MODE, INPORT_CONTROL_PORT);
+       outb(INPORT_MODE_BASE, INPORT_DATA_PORT);
+       free_irq(inport_irq, NULL);
+}
+
 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 @@ static int __init inport_init(void)
        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);
 }
 
index bd9df9b..5599142 100644 (file)
@@ -34,7 +34,7 @@ static struct dmi_system_id lifebook_dmi_table[] = {
 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_detect(struct psmouse *psmouse, int set_properties)
 
 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;
index 8b52431..9c7ce38 100644 (file)
@@ -77,39 +77,7 @@ MODULE_PARM_DESC(irq, "IRQ number (5=default)");
 
 __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 @@ static irqreturn_t logibm_interrupt(int irq, void *dev_id, struct pt_regs *regs)
        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 @@ static int __init logibm_init(void)
        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;
+       }
+
+       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;
 
-       printk(KERN_INFO "input: Logitech bus mouse at %#x irq %d\n", LOGIBM_BASE, logibm_irq);
+       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);
 }
 
index 7df9652..0f69ff4 100644 (file)
@@ -40,7 +40,7 @@ struct ps2pp_info {
 
 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 struct ps2pp_info *get_model_info(unsigned char model)
 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 @@ int ps2pp_init(struct psmouse *psmouse, int set_properties)
                }
 
                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);
index e90c60c..b5b34fe 100644 (file)
@@ -41,13 +41,12 @@ static int dc_mouse_connect(struct maple_device *dev)
        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 @@ static int dc_mouse_connect(struct maple_device *dev)
 
        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 @@ static void dc_mouse_disconnect(struct maple_device *dev)
        struct input_dev *input_dev = dev->private_data;
 
        input_unregister_device(input_dev);
-       kfree(input_dev);
 }
 
 
index 93393d5..d284ea7 100644 (file)
@@ -53,13 +53,10 @@ MODULE_LICENSE("GPL");
 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 @@ static irqreturn_t pc110pad_interrupt(int irq, void *ptr, struct pt_regs *regs)
        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 void pc110pad_close(struct input_dev *dev)
 
 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 @@ static int __init pc110pad_init(void)
 
        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);
 }
 
index af24313..6ee9999 100644 (file)
@@ -114,7 +114,7 @@ struct psmouse_protocol {
 
 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 @@ static int genius_detect(struct psmouse *psmouse, int set_properties)
                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 @@ static int intellimouse_detect(struct psmouse *psmouse, int set_properties)
                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 @@ static int im_explorer_detect(struct psmouse *psmouse, int set_properties)
                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 @@ static int thinking_detect(struct psmouse *psmouse, int set_properties)
                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 @@ static void psmouse_disconnect(struct serio *serio)
 
        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 void psmouse_disconnect(struct serio *serio)
 
 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 @@ static int psmouse_switch_protocol(struct psmouse *psmouse, struct psmouse_proto
        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_switch_protocol(struct psmouse *psmouse, struct psmouse_proto
 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 @@ static int psmouse_connect(struct serio *serio, struct serio_driver *drv)
                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 @@ static int psmouse_connect(struct serio *serio, struct serio_driver *drv)
        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 @@ static int psmouse_connect(struct serio *serio, struct serio_driver *drv)
 
        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 @@ static int psmouse_connect(struct serio *serio, struct serio_driver *drv)
        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 @@ static ssize_t psmouse_attr_set_protocol(struct psmouse *psmouse, void *data, co
 {
        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 @@ static ssize_t psmouse_attr_set_protocol(struct psmouse *psmouse, void *data, co
        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 @@ static ssize_t psmouse_attr_set_protocol(struct psmouse *psmouse, void *data, co
                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 @@ static ssize_t psmouse_attr_set_protocol(struct psmouse *psmouse, void *data, co
                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 @@ static ssize_t psmouse_attr_set_protocol(struct psmouse *psmouse, void *data, co
        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);
index 45d2bd7..7c4192b 100644 (file)
@@ -36,7 +36,7 @@ typedef enum {
 
 struct psmouse {
        void *private;
-       struct input_dev dev;
+       struct input_dev *dev;
        struct ps2dev ps2dev;
        char *vendor;
        char *name;
index 8fe1212..09b6ffd 100644 (file)
@@ -34,20 +34,7 @@ MODULE_DESCRIPTION("Acorn RiscPC mouse driver");
 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 @@ static irqreturn_t rpcmouse_irq(int irq, void *dev_id, struct pt_regs *regs)
        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);
index d12b93a..4bf5843 100644 (file)
@@ -48,7 +48,7 @@ static char *sermouse_protocols[] = { "None", "Mouse Systems Mouse", "Sun Mouse"
                                        "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 @@ struct sermouse {
 
 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_msc(struct sermouse *sermouse, signed char data, st
 
 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 @@ static void sermouse_disconnect(struct serio *serio)
 {
        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 void sermouse_disconnect(struct serio *serio)
 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;
-
-       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 = kzalloc(sizeof(struct sermouse), GFP_KERNEL);
+       input_dev = input_allocate_device();
+       if (!sermouse || !input_dev)
+               goto fail;
 
+       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;
-       }
-
-       input_register_device(&sermouse->dev);
+       if (err)
+               goto fail;
 
-       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[] = {
index 0293094..97cdfd6 100644 (file)
@@ -342,7 +342,7 @@ static void synaptics_parse_hw_state(unsigned char buf[], struct synaptics_data
  */
 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 unsigned char synaptics_detect_pkt_type(struct psmouse *psmouse)
 
 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 @@ int synaptics_init(struct psmouse *psmouse)
                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;
index f024be9..36e9442 100644 (file)
@@ -112,7 +112,7 @@ MODULE_LICENSE ("GPL");
 
 
 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 @@ vsxxxaa_smells_like_packet (struct vsxxxaa *mouse, unsigned char type, size_t le
 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 @@ vsxxxaa_handle_REL_packet (struct vsxxxaa *mouse, struct pt_regs *regs)
 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 @@ vsxxxaa_handle_ABS_packet (struct vsxxxaa *mouse, struct pt_regs *regs)
 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 @@ vsxxxaa_disconnect (struct serio *serio)
 {
        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 @@ static int
 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;
-
-       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 = kzalloc (sizeof (struct vsxxxaa), GFP_KERNEL);
+       input_dev = input_allocate_device ();
+       if (!mouse || !input_dev)
+               goto fail;
 
+       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 */
-
-       input_register_device (&mouse->dev);
+       serio->write (serio, 'T'); /* Test */
 
-       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[] = {
index c6194a9..2d0af44 100644 (file)
@@ -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 file_operations mousedev_fops = {
 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 @@ static struct input_handle *mousedev_connect(struct input_handler *handler, stru
 
        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 @@ static void mousedev_disconnect(struct input_handle *handle)
        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 @@ static int __init mousedev_init(void)
        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 @@ static void __exit mousedev_exit(void)
        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);
 }
index 40d451c..4bc40f1 100644 (file)
@@ -911,12 +911,10 @@ static long i8042_panic_blink(long count)
  * 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 @@ static int i8042_suspend(struct device *dev, pm_message_t state, u32 level)
  * 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;
 
index 4c7fbe5..0ba3e65 100644 (file)
@@ -41,8 +41,7 @@ struct ts_event {
 };
 
 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 @@ static void new_data(struct corgi_ts *corgi_ts, struct pt_regs *regs)
        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 @@ static irqreturn_t ts_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 }
 
 #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);
-
-               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;
+       struct corgi_ts *corgi_ts = dev_get_drvdata(dev);
 
-               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 @@ static int __init corgits_probe(struct device *dev)
 {
        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 @@ static int __init corgits_probe(struct device *dev)
        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 @@ static int corgits_remove(struct device *dev)
        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;
 }
index 3cdc9ca..c86a2eb 100644 (file)
@@ -36,14 +36,12 @@ MODULE_LICENSE("GPL");
 
 #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 @@ struct elo {
 
 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 @@ static void elo_process_data_10(struct elo* elo, unsigned char data, struct pt_r
                                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_10(struct elo* elo, unsigned char data, struct pt_r
 
 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 @@ static void elo_process_data_6(struct elo* elo, unsigned char data, struct pt_re
                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_6(struct elo* elo, unsigned char data, struct pt_re
 
 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 @@ static void elo_disconnect(struct serio *serio)
 {
        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 void elo_disconnect(struct serio *serio)
 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));
+       elo->serio = serio;
+       elo->id = serio->id.id;
+       elo->dev = input_dev;
+       snprintf(elo->phys, sizeof(elo->phys), "%s/input0", serio->phys);
 
-       init_input_dev(&elo->dev);
-       elo->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
-       elo->dev.keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH);
+       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;
 
-       elo->id = serio->id.id;
+       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;
-       }
-
-       input_register_device(&elo->dev);
-
-       printk(KERN_INFO "input: %s on %s\n", elo_name, serio->phys);
+       if (err)
+               goto fail;
 
+       input_register_device(elo->dev);
        return 0;
+
+ fail: serio_set_drvdata(serio, NULL);
+       input_free_device(input_dev);
+       kfree(elo);
+       return err;
 }
 
 /*
index 53a27e4..466da19 100644 (file)
@@ -48,14 +48,12 @@ MODULE_LICENSE("GPL");
 
 #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 @@ struct gunze {
 
 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 irqreturn_t gunze_interrupt(struct serio *serio,
 
 static void gunze_disconnect(struct serio *serio)
 {
-       struct gunzegunze = 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 void gunze_disconnect(struct serio *serio)
 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;
-       }
-
-       input_register_device(&gunze->dev);
-
-       printk(KERN_INFO "input: %s on %s\n", gunze_name, serio->phys);
+       if (err)
+               goto fail;
 
+       input_register_device(gunze->dev);
        return 0;
+
+ fail: serio_set_drvdata(serio, NULL);
+       input_free_device(input_dev);
+       kfree(gunze);
+       return err;
 }
 
 /*
index bcfa1e3..a18d56b 100644 (file)
@@ -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 @@ MODULE_LICENSE("GPL");
 #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 @@ unsigned int h3600_flite_power(struct input_dev *dev, enum flite_pwr pwr)
        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 int h3600ts_pm_callback(struct pm_dev *pm_dev, pm_request_t req,
  */
 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 void h3600ts_process_packet(struct h3600_dev *ts, struct pt_regs *regs)
 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 @@ static int h3600ts_event(struct input_dev *dev, unsigned int type,
                }
        }
        return -1;
+#endif
+       return 0;
 }
 
 /*
@@ -380,14 +351,48 @@ static irqreturn_t h3600ts_interrupt(struct serio *serio, unsigned char data,
 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 @@ static int h3600ts_connect(struct serio *serio, struct serio_driver *drv)
                        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 @@ static void h3600ts_disconnect(struct serio *serio)
 
        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);
 }
 
index 7e14044..957dd5a 100644 (file)
 
 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 @@ static void do_softint(void *data)
        }
 
        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 @@ static int __init hp680_ts_init(void)
        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 @@ static void __exit hp680_ts_exit(void)
        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);
index afaaebe..4844d25 100644 (file)
@@ -77,7 +77,7 @@ MODULE_PARM_DESC(irq, "IRQ of MK712 touchscreen controller");
 #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 irqreturn_t mk712_interrupt(int irq, void *dev_id, struct pt_regs *regs)
        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 @@ static irqreturn_t mk712_interrupt(int irq, void *dev_id, struct pt_regs *regs)
        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 @@ static irqreturn_t mk712_interrupt(int irq, void *dev_id, struct pt_regs *regs)
                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 @@ static void mk712_close(struct input_dev *dev)
        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 @@ int __init mk712_init(void)
            (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))
-       {
-               printk(KERN_WARNING "mk712: unable to get IRQ\n");
-               release_region(mk712_io, 8);
-               return -EBUSY;
+       if (!(mk712_dev = input_allocate_device())) {
+               printk(KERN_ERR "mk712: not enough memory\n");
+               err = -ENOMEM;
+               goto fail;
        }
 
-       input_register_device(&mk712_dev);
+       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;
 
-       printk(KERN_INFO "input: ICS MicroClock MK712 TouchScreen at %#x irq %d\n", mk712_io, mk712_irq);
+       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");
+               err = -EBUSY;
+               goto fail;
+       }
+
+       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);
 }
 
index aa8ee78..1d0d37e 100644 (file)
@@ -51,14 +51,12 @@ MODULE_LICENSE("GPL");
 #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 @@ struct mtouch {
 
 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 @@ static void mtouch_disconnect(struct serio *serio)
 {
        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 void mtouch_disconnect(struct serio *serio)
 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;
-       }
-
-       input_register_device(&mtouch->dev);
+       if (err)
+               goto fail;
 
-       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;
 }
 
 /*
index 50c63a1..ca15479 100644 (file)
@@ -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 @@ static struct input_handle *tsdev_connect(struct input_handler *handler,
                                          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 @@ static struct input_handle *tsdev_connect(struct input_handler *handler,
 
        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 @@ static void tsdev_disconnect(struct input_handle *handle)
        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) {
index 04fb606..11ae0fd 100644 (file)
@@ -1505,7 +1505,7 @@ static int __init capi_init(void)
                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");
 
index c0dc1e3..d2ead17 100644 (file)
@@ -905,5 +905,5 @@ adbdev_init(void)
        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");
 }
index db654e8..cdb6d02 100644 (file)
@@ -206,7 +206,7 @@ u8 adb_to_linux_keycodes[128] = {
 };
 
 struct adbhid {
-       struct input_dev input;
+       struct input_dev *input;
        int id;
        int default_id;
        int original_handler_id;
@@ -291,10 +291,10 @@ adbhid_input_keycode(int id, int keycode, int repeat, struct pt_regs *regs)
 
        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 @@ adbhid_input_keycode(int id, int keycode, int repeat, struct pt_regs *regs)
        }
 
        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 @@ adbhid_mouse_input(unsigned char *data, int nb, struct pt_regs *regs, int autopo
                 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 @@ adbhid_buttons_input(unsigned char *data, int nb, struct pt_regs *regs, int auto
                return;
        }
 
-       input_regs(&adbhid[id]->input, regs);
+       input_regs(adbhid[id]->input, regs);
 
        switch (adbhid[id]->original_handler_id) {
        default:
@@ -477,19 +477,19 @@ adbhid_buttons_input(unsigned char *data, int nb, struct pt_regs *regs, int auto
 
                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 @@ adbhid_buttons_input(unsigned char *data, int nb, struct pt_regs *regs, int auto
 
                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 @@ adbhid_buttons_input(unsigned char *data, int nb, struct pt_regs *regs, int auto
                                }
                        }
 #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 @@ adbhid_buttons_input(unsigned char *data, int nb, struct pt_regs *regs, int auto
                                }
                        }
 #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 @@ adbhid_buttons_input(unsigned char *data, int nb, struct pt_regs *regs, int auto
                        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 @@ adbhid_buttons_input(unsigned char *data, int nb, struct pt_regs *regs, int auto
          break;
        }
 
-       input_sync(&adbhid[id]->input);
+       input_sync(adbhid[id]->input);
 }
 
 static struct adb_request led_request;
@@ -683,7 +683,7 @@ adb_message_handler(struct notifier_block *this, unsigned long code, void *x)
                        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 @@ adb_message_handler(struct notifier_block *this, unsigned long code, void *x)
        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;
-
-       memset(adbhid[id], 0, sizeof(struct adbhid));
-       sprintf(adbhid[id]->phys, "adb%d:%d.%02x/input", id, default_id, original_handler_id);
+       adbhid[id] = hid = kzalloc(sizeof(struct adbhid), GFP_KERNEL);
+       input_dev = input_allocate_device();
+       if (!hid || !input_dev) {
+               err = -ENOMEM;
+               goto fail;
 
-       init_input_dev(&adbhid[id]->input);
+       }
 
-       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;
+       sprintf(hid->phys, "adb%d:%d.%02x/input", id, default_id, original_handler_id);
+
+       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);
-
-               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;
+                       if (hid->keycode[i])
+                               set_bit(hid->keycode[i], input_dev->keybit);
+
+               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_register_device(&adbhid[id]->input);
+       input_dev->keycode = hid->keycode;
 
-       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 @@ adbhid_input_reregister(int id, int default_id, int org_handler_id,
                        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,
index 5ad3a5a..a666361 100644 (file)
@@ -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 @@ int mac_hid_mouse_emulate_buttons(int caller, unsigned int keycode, int down)
                    && (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 @@ int mac_hid_mouse_emulate_buttons(int caller, unsigned int keycode, int down)
 
 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);
index a0e700d..06f4d46 100644 (file)
@@ -252,7 +252,6 @@ void ir_input_init(struct input_dev *dev, struct ir_input_state *ir,
        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;
index 6db0929..a1607e7 100644 (file)
@@ -137,7 +137,8 @@ struct cinergyt2 {
        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 @@ static struct dvb_device cinergyt2_fe_template = {
 };
 
 #ifdef ENABLE_RC
+
 static void cinergyt2_query_rc (void *data)
 {
        struct cinergyt2 *cinergyt2 = data;
@@ -703,7 +705,7 @@ static void cinergyt2_query_rc (void *data)
                        /* 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 @@ static void cinergyt2_query_rc (void *data)
                        /* 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 @@ static void cinergyt2_query_rc (void *data)
                            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 @@ out:
 
        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 @@ static int cinergyt2_probe (struct usb_interface *intf,
 {
        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 @@ static int cinergyt2_probe (struct usb_interface *intf,
                            &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";
-
-       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;
+       err = cinergyt2_register_rc(cinergyt2);
+       if (err)
+               goto bailout;
 
-       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 @@ static void cinergyt2_disconnect (struct usb_interface *intf)
        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 @@ static int cinergyt2_suspend (struct usb_interface *intf, pm_message_t state)
 
        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 @@ static int cinergyt2_resume (struct usb_interface *intf)
                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;
 }
index 4b7adca..477b4fa 100644 (file)
@@ -235,7 +235,7 @@ int dvb_register_device(struct dvb_adapter *adap, struct dvb_device **pdvbdev,
                        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",
index fc7800f..e5c6d98 100644 (file)
@@ -39,9 +39,9 @@ static void dvb_usb_read_remote_control(void *data)
                        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 @@ static void dvb_usb_read_remote_control(void *data)
                        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 @@ static void dvb_usb_read_remote_control(void *data)
                        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 @@ static void dvb_usb_read_remote_control(void *data)
                        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 @@ schedule:
 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 = 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->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 @@ int dvb_usb_remote_init(struct dvb_usb_device *d)
                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 @@ int dvb_usb_remote_exit(struct dvb_usb_device *d)
        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;
index 0e4f103..b4a1a98 100644 (file)
@@ -300,7 +300,8 @@ struct dvb_usb_device {
        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;
index 357a372..f5e59fc 100644 (file)
@@ -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 u16 key_map [256] = {
 
 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 @@ static void av7110_emit_key(unsigned long parm)
        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 @@ static void input_register_keys(void)
 {
        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 @@ int __init av7110_ir_init(struct av7110 *av7110)
                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 @@ void __exit av7110_ir_exit(struct av7110 *av7110)
        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--;
index 2980db3..51c30ba 100644 (file)
@@ -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_debounce(unsigned long data)
 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 void msp430_ir_interrupt(unsigned long data)
 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 int msp430_ir_init(struct budget_ci *budget_ci)
 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);
index 3d08fc8..832d179 100644 (file)
@@ -152,7 +152,8 @@ struct ttusb_dec {
        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 @@ static void ttusb_dec_handle_irq( struct urb *urb, struct pt_regs *regs)
                 * 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 @@ static void ttusb_dec_init_tasklet(struct ttusb_dec *dec)
                     (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;
+
+       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;
 
-        for (i = 0; i < sizeof(rc_keys)/sizeof(rc_keys[0]); i++)
-                set_bit(rc_keys[i], dec->rc_input_dev.keybit);
+       for (i = 0; i < ARRAY_SIZE(rc_keys); i++)
+                set_bit(rc_keys[i], input_dev->keybit);
 
-       input_register_device(&dec->rc_input_dev);
+       input_register_device(input_dev);
 
-       if(usb_submit_urb(dec->irq_urb,GFP_KERNEL)) {
+       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 @@ static void ttusb_dec_exit_rc(struct ttusb_dec *dec)
          * 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 @@ static void ttusb_dec_exit_rc(struct ttusb_dec *dec)
        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 @@ static int ttusb_dec_probe(struct usb_interface *intf,
 
        ttusb_dec_set_interface(dec, TTUSB_DEC_INTERFACE_IN);
 
-       if(enable_rc)
+       if (enable_rc)
                ttusb_init_rc(dec);
 
        return 0;
index 7a312f7..e0e7c7a 100644 (file)
@@ -240,7 +240,7 @@ struct bttv_pll_info {
 
 /* 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];
index d81b21d..c27fe4c 100644 (file)
@@ -260,7 +260,7 @@ static IR_KEYTAB_TYPE ir_codes_cinergy_1400[IR_KEYTAB_SIZE] = {
 
 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 @@ static void cx88_ir_handle_key(struct cx88_IR *ir)
        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 @@ static void cx88_ir_work(void *data)
 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 @@ int cx88_ir_init(struct cx88_core *core, struct pci_dev *pci)
 
        if (NULL == ir_codes) {
                kfree(ir);
+               input_free_device(input_dev);
                return -ENODEV;
        }
 
@@ -433,19 +440,19 @@ int cx88_ir_init(struct cx88_core *core, struct pci_dev *pci)
                 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 @@ int cx88_ir_init(struct cx88_core *core, struct pci_dev *pci)
        }
 
        /* 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 @@ int cx88_ir_fini(struct cx88_core *core)
                flush_scheduled_work();
        }
 
-       input_unregister_device(&ir->input);
+       input_unregister_device(ir->input);
        kfree(ir);
 
        /* done */
@@ -515,7 +521,7 @@ void cx88_ir_irq(struct cx88_core *core)
        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 @@ void cx88_ir_irq(struct cx88_core *core)
 
                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 @@ void cx88_ir_irq(struct cx88_core *core)
                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;
        }
index cf292da..234151e 100644 (file)
@@ -158,7 +158,7 @@ static IR_KEYTAB_TYPE ir_codes_apac_viewcomp[IR_KEYTAB_SIZE] = {
 
 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 @@ static void ir_handle_key(struct IR *ir)
        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 @@ static int ir_probe(struct device *dev)
 {
        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 @@ static int ir_probe(struct device *dev)
        }
        if (NULL == ir_codes) {
                kfree(ir);
+               input_free_device(input_dev);
                return -ENODEV;
        }
 
@@ -341,19 +346,19 @@ static int ir_probe(struct device *dev)
        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 @@ static int ir_probe(struct device *dev)
        }
 
        /* 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 @@ static int ir_remove(struct device *dev)
                flush_scheduled_work();
        }
 
-       input_unregister_device(&ir->input);
+       input_unregister_device(ir->input);
        kfree(ir);
        return 0;
 }
index 67105b9..9703d3d 100644 (file)
@@ -121,10 +121,9 @@ static IR_KEYTAB_TYPE ir_codes_purpletv[IR_KEYTAB_SIZE] = {
 
 };
 
-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 @@ static void ir_key_poll(struct IR *ir)
        }
 
        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 @@ static int ir_attach(struct i2c_adapter *adap, int addr,
        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 @@ static int ir_attach(struct i2c_adapter *adap, int addr,
                 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 @@ static int ir_detach(struct i2c_client *client)
        flush_scheduled_work();
 
        /* unregister devices */
-       input_unregister_device(&ir->input);
+       input_unregister_device(ir->input);
        i2c_detach_client(&ir->c);
 
        /* free memory */
index f0d43fc..262890c 100644 (file)
@@ -1420,8 +1420,8 @@ static int msp_detach(struct i2c_client *client);
 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 @@ static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg)
        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 @@ static int msp_suspend(struct device * dev, pm_message_t state, u32 level)
        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);
 
index 1f456c4..242cb23 100644 (file)
@@ -425,9 +425,9 @@ static int build_key(struct saa7134_dev *dev)
 
        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 @@ static void saa7134_input_timer(unsigned long data)
 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 @@ int saa7134_input_init1(struct saa7134_dev *dev)
                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 @@ int saa7134_input_init1(struct saa7134_dev *dev)
        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 @@ int saa7134_input_init1(struct saa7134_dev *dev)
                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 @@ void saa7134_input_fini(struct saa7134_dev *dev)
        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;
 }
index 3ea0914..860b895 100644 (file)
@@ -351,7 +351,7 @@ struct saa7134_oss {
 
 /* IR input */
 struct saa7134_ir {
-       struct input_dev           dev;
+       struct input_dev           *dev;
        struct ir_input_state      ir;
        char                       name[32];
        char                       phys[32];
index 0456dda..94053f1 100644 (file)
@@ -784,13 +784,13 @@ tda9887_command(struct i2c_client *client, unsigned int cmd, void *arg)
        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);
index 0557202..ad85bef 100644 (file)
@@ -697,7 +697,7 @@ static int tuner_command(struct i2c_client *client, unsigned int cmd, void *arg)
        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 @@ static int tuner_suspend(struct device *dev, pm_message_t state, u32 level)
        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);
index c5bcfd7..9eefedb 100644 (file)
@@ -36,9 +36,6 @@ extern void __exit i2o_pci_exit(void);
 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 *);
index 21f16ba..d987996 100644 (file)
@@ -45,10 +45,10 @@ static inline int i2o_device_issue_claim(struct i2o_device *dev, u32 cmd,
        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 @@ int i2o_device_claim(struct i2o_device *dev)
        up(&dev->lock);
 
        return rc;
-};
+}
 
 /**
  *     i2o_device_claim_release - release a device that the OSM is using
@@ -119,7 +119,8 @@ int i2o_device_claim_release(struct i2o_device *dev)
        up(&dev->lock);
 
        return rc;
-};
+}
+
 
 /**
  *     i2o_device_release - release the memory for a I2O device
@@ -135,39 +136,47 @@ static void i2o_device_release(struct device *dev)
        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 @@ static struct i2o_device *i2o_device_alloc(void)
 
        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 @@ static struct i2o_device *i2o_device_add(struct i2o_controller *c,
        }
 
        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 @@ static struct i2o_device *i2o_device_add(struct i2o_controller *c,
 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 @@ int i2o_device_parse_lct(struct i2o_controller *c)
        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 @@ int i2o_parm_field_get(struct i2o_device *i2o_dev, int group, int field,
 }
 
 /*
- *     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 @@ int i2o_parm_table_get(struct i2o_device *dev, int oper, int group,
        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);
index 739bfde..0079a4b 100644 (file)
@@ -58,9 +58,12 @@ static int i2o_bus_match(struct device *dev, struct device_driver *drv)
 };
 
 /* 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,
 };
 
 /**
index 42f8b81..361da8d 100644 (file)
@@ -833,6 +833,7 @@ void i2o_iop_remove(struct i2o_controller *c)
        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 @@ static void i2o_iop_release(struct device *dev)
 };
 
 /* 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 @@ struct i2o_controller *i2o_iop_alloc(void)
        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 @@ int i2o_iop_add(struct i2o_controller *c)
                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 @@ int i2o_iop_add(struct i2o_controller *c)
        return 0;
 
       class_del:
-       class_device_del(&c->classdev);
+       class_device_unregister(c->classdev);
 
       device_del:
        device_del(&c->device);
@@ -1246,13 +1243,10 @@ static int __init i2o_iop_init(void)
 
        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 @@ static int __init i2o_iop_init(void)
        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 @@ static void __exit i2o_iop_exit(void)
        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);
index e9806fb..720e7a3 100644 (file)
@@ -219,26 +219,24 @@ static int mcp_sa11x0_remove(struct device *dev)
        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;
 }
 
index a260f83..585cded 100644 (file)
@@ -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 int adcsync;
 
 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 @@ static int ucb1x00_ts_add(struct ucb1x00_dev *dev)
 {
        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 int ucb1x00_ts_add(struct ucb1x00_dev *dev)
 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);
 }
 
index b53af57..8eba373 100644 (file)
@@ -571,23 +571,23 @@ static int pxamci_remove(struct device *dev)
 }
 
 #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;
index 3cbca7c..25f7ce7 100644 (file)
@@ -1955,14 +1955,14 @@ static void __devexit wbsd_pnp_remove(struct pnp_dev * dev)
  */
 
 #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");
 
index 9133351..6a8e0ca 100644 (file)
@@ -403,21 +403,21 @@ static int __exit sa1100_mtd_remove(struct device *dev)
 }
 
 #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;
 }
index 1ed602a..c534fd5 100644 (file)
@@ -24,10 +24,10 @@ static void mtd_notify_add(struct mtd_info* mtd)
        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);
 }
index e54fc10..abce1f7 100644 (file)
@@ -1140,11 +1140,11 @@ dm9000_phy_write(struct net_device *dev, int phyaddr_unused, int reg, int value)
 }
 
 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 @@ dm9000_drv_suspend(struct device *dev, pm_message_t state, u32 level)
 }
 
 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);
index 8d34ac6..0688330 100644 (file)
@@ -291,12 +291,12 @@ static void sa1100_irda_shutdown(struct sa1100_irda *si)
 /*
  * 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 @@ static int sa1100_irda_suspend(struct device *_dev, pm_message_t state, u32 leve
 /*
  * 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;
index dd89bda..bbac720 100644 (file)
@@ -213,8 +213,8 @@ static int  smsc_ircc_probe_transceiver_smsc_ircc_atc(int fir_base);
 
 /* 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 @@ static int smsc_ircc_net_close(struct net_device *dev)
        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 @@ static int smsc_ircc_suspend(struct device *dev, pm_message_t state, u32 level)
        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;
index 9063067..ad93b0d 100644 (file)
@@ -133,13 +133,9 @@ static int mdio_bus_suspend(struct device * dev, pm_message_t state)
        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 @@ static int mdio_bus_resume(struct device * dev)
        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;
 }
 
index 0df7e92..d3c9958 100644 (file)
@@ -863,7 +863,7 @@ static int __init ppp_init(void)
                        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)
index 1438fdd..0ddaa61 100644 (file)
@@ -2291,11 +2291,11 @@ static int smc_drv_remove(struct device *dev)
        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 @@ static int smc_drv_suspend(struct device *dev, pm_message_t state, u32 level)
        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)) {
index ae9e897..e392ee8 100644 (file)
@@ -400,7 +400,7 @@ static int __init cosa_init(void)
                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,
index 393e0ce..14f05d2 100644 (file)
@@ -61,7 +61,7 @@ static int pcie_port_remove_service(struct device *dev)
 
 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 @@ static int pcie_port_suspend_service(struct device *dev, pm_message_t state, u32
        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;
index 470ef75..d90a634 100644 (file)
@@ -519,30 +519,13 @@ static int au1x00_drv_pcmcia_probe(struct device *dev)
 }
 
 
-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 = {
index 080608c..39d096b 100644 (file)
@@ -1157,7 +1157,8 @@ static struct pcmcia_callback pcmcia_bus_callback = {
        .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 @@ static int __devinit pcmcia_bus_add_socket(struct class_device *class_dev)
        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);
 
index 316f8bc..b57a0b9 100644 (file)
@@ -844,27 +844,11 @@ static void hs_exit_socket(hs_socket_t *sp)
        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 = {
index a713015..4a41f67 100644 (file)
@@ -1332,27 +1332,11 @@ static struct pccard_operations pcic_operations = {
 
 /*====================================================================*/
 
-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 = {
index 65f3ee3..c6ed70e 100644 (file)
@@ -731,28 +731,11 @@ static struct pccard_operations pcc_operations = {
 
 /*====================================================================*/
 
-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 = {
index 7b14d7e..3397ff2 100644 (file)
@@ -695,28 +695,11 @@ static struct pccard_operations pcc_operations = {
 
 /*====================================================================*/
 
-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 = {
index 94be9e5..2558c3c 100644 (file)
@@ -329,27 +329,13 @@ static int __devexit omap_cf_remove(struct device *dev)
        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)
index 325c992..c2a12d5 100644 (file)
@@ -205,32 +205,20 @@ int pxa2xx_drv_pcmcia_probe(struct device *dev)
 }
 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);
-               ret = pcmcia_socket_dev_resume(dev);
-       }
-       return ret;
+       MECR = nr > 1 ? MECR_CIT | MECR_NOS : (nr > 0 ? MECR_CIT : 0);
+
+       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,
index f9a5c70..fc87e7e 100644 (file)
@@ -994,7 +994,8 @@ static struct class_device_attribute *pccard_rsrc_attributes[] = {
        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 @@ static int __devinit pccard_sysfs_add_rsrc(struct class_device *class_dev)
        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;
index d4ed508..b768fa8 100644 (file)
@@ -74,29 +74,13 @@ static int sa11x0_drv_pcmcia_probe(struct device *dev)
        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()
index 1040a6c..4a3150a 100644 (file)
@@ -341,7 +341,8 @@ static struct bin_attribute pccard_cis_attr = {
        .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 @@ static int __devinit pccard_sysfs_add_socket(struct class_device *class_dev)
        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;
 
index d5a61ea..f158b67 100644 (file)
@@ -372,27 +372,11 @@ static int __init get_tcic_id(void)
 
 /*====================================================================*/
 
-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 = {
index 17bb2da..3d2dca6 100644 (file)
@@ -774,31 +774,11 @@ static int __devinit vrc4171_card_setup(char *options)
 
 __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)
index ed0cb1f..fcaee44 100644 (file)
@@ -72,6 +72,7 @@ struct tape_class_device *register_tape_dev(
 
        tcd->class_device = class_device_create(
                                tape_class,
+                               NULL,
                                tcd->char_device->dev,
                                device,
                                "%s", tcd->device_name
index 491f00c..a107fec 100644 (file)
@@ -787,6 +787,7 @@ vmlogrdr_register_device(struct vmlogrdr_priv_t *priv) {
                return ret;
        }
        priv->class_device = class_device_create(
+                               NULL,
                                vmlogrdr_class,
                                MKDEV(vmlogrdr_major, priv->minor_num),
                                dev,
index da6e51c..540147c 100644 (file)
@@ -936,7 +936,7 @@ static int ch_probe(struct device *dev)
        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);
 
index af11331..172839f 100644 (file)
@@ -5629,7 +5629,7 @@ static void osst_sysfs_add(dev_t dev, struct device *device, struct osst_tape *
 
        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;
index fd56b7e..861e513 100644 (file)
@@ -104,8 +104,8 @@ static int sg_allow_dio = SG_ALLOW_DIO_DEF;
 
 #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_alloc(struct gendisk *disk, struct scsi_device *scsidp)
 }
 
 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 @@ sg_add(struct class_device *cl_dev)
        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 @@ out:
 }
 
 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;
index 927d700..5eb54d8 100644 (file)
@@ -4377,7 +4377,7 @@ static void do_create_class_files(struct scsi_tape *STp, int dev_num, int mode)
                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);
index 4d75cdf..afb7ddf 100644 (file)
@@ -2358,13 +2358,10 @@ static int __devexit serial8250_remove(struct device *dev)
        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 @@ static int serial8250_suspend(struct device *dev, pm_message_t state, u32 level)
        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];
 
index bdb4e45..5b3933b 100644 (file)
@@ -921,21 +921,21 @@ static struct uart_driver imx_reg = {
        .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;
index 0585ab2..8a79968 100644 (file)
@@ -781,22 +781,22 @@ mpc52xx_uart_remove(struct device *dev)
 
 #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;
index 005f027..8cc4ced 100644 (file)
@@ -805,21 +805,21 @@ static struct uart_driver serial_pxa_reg = {
        .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;
index 52692aa..06a17df 100644 (file)
@@ -1134,23 +1134,22 @@ static int s3c24xx_serial_remove(struct device *_dev)
 
 #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);
index dd8aed2..c4a789e 100644 (file)
@@ -834,21 +834,21 @@ static struct uart_driver sa1100_reg = {
        .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;
index 0c5d65a..2b623ab 100644 (file)
@@ -976,14 +976,11 @@ static int siu_remove(struct device *dev)
        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 @@ static int siu_suspend(struct device *dev, pm_message_t state, u32 level)
        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 ||
index 487ff67..befe0c7 100644 (file)
@@ -1509,7 +1509,7 @@ void usbdev_add(struct usb_device *dev)
 {
        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);
 
index 65ca131..78cb4be 100644 (file)
@@ -172,7 +172,9 @@ int usb_register_dev(struct usb_interface *intf,
                ++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;
index ff19d64..14c47a1 100644 (file)
@@ -782,7 +782,8 @@ static int usb_register_bus(struct usb_bus *bus)
                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);
index a12cab5..c3e2024 100644 (file)
@@ -1020,9 +1020,15 @@ void usb_set_device_state(struct usb_device *udev,
        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 @@ static int hub_port_suspend(struct usb_hub *hub, int port1,
         * 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,
index 8d9d8ee..5032017 100644 (file)
@@ -935,14 +935,10 @@ static int dummy_udc_remove (struct device *dev)
        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 @@ static int dummy_udc_suspend (struct device *dev, pm_message_t state,
        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 @@ static int dummy_hcd_remove (struct device *dev)
        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 @@ static int dummy_hcd_suspend (struct device *dev, pm_message_t state,
        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;
index 287c590..b7885dc 100644 (file)
@@ -2909,12 +2909,10 @@ static int __exit omap_udc_remove(struct device *dev)
  * 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 @@ static int omap_udc_suspend(struct device *dev, pm_message_t message, u32 level)
        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);
 
index 3d4d89c..6470285 100644 (file)
@@ -2602,24 +2602,23 @@ static int __exit pxa2xx_udc_remove(struct device *_dev)
  * 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;
 }
 
index 2548d94..642f350 100644 (file)
@@ -1774,15 +1774,12 @@ static int __init isp116x_probe(struct device *dev)
 /*
   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 @@ static int isp116x_suspend(struct device *dev, pm_message_t state, u32 phase)
 /*
   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) {
index d8f3ba7..a574216 100644 (file)
@@ -455,14 +455,11 @@ static int ohci_hcd_omap_drv_remove(struct device *dev)
 
 #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 @@ static int ohci_omap_suspend(struct device *dev, pm_message_t message, u32 level
        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;
index 2fdb262..f042261 100644 (file)
@@ -309,7 +309,7 @@ static int ohci_hcd_pxa27x_drv_remove(struct device *dev)
        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 @@ static int ohci_hcd_pxa27x_drv_suspend(struct device *dev, pm_message_t state, u
        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);
index cad8585..b5e7a47 100644 (file)
@@ -1784,15 +1784,12 @@ sl811h_probe(struct device *dev)
  */
 
 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 @@ sl811h_suspend(struct device *dev, pm_message_t state, u32 phase)
 }
 
 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.
         */
index 74f8760..a32558b 100644 (file)
@@ -53,7 +53,7 @@ struct usb_acecad {
        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 @@ static void usb_acecad_irq(struct urb *urb, struct pt_regs *regs)
 {
        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 @@ static int usb_acecad_probe(struct usb_interface *intf, const struct usb_device_
        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 @@ static int usb_acecad_probe(struct usb_interface *intf, const struct usb_device_
        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 @@ static int usb_acecad_probe(struct usb_interface *intf, const struct usb_device_
        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 @@ static int usb_acecad_probe(struct usb_interface *intf, const struct usb_device_
                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 @@ static int usb_acecad_probe(struct usb_interface *intf, const struct usb_device_
        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 @@ static void usb_acecad_disconnect(struct usb_interface *intf)
        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);
index cd0cbfe..1c52053 100644 (file)
@@ -317,7 +317,7 @@ struct aiptek_settings {
 };
 
 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 @@ static void aiptek_irq(struct urb *urb, struct pt_regs *regs)
 {
        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 @@ static int aiptek_program_tablet(struct aiptek *aiptek)
        /* 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 @@ static ssize_t show_tabletSize(struct device *dev, struct device_attribute *attr
                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 @@ static ssize_t show_tabletProductId(struct device *dev, struct device_attribute
                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 @@ static ssize_t show_tabletVendorId(struct device *dev, struct device_attribute *
        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 @@ aiptek_probe(struct usb_interface *intf, const struct usb_device_id *id)
        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 @@ aiptek_probe(struct usb_interface *intf, const struct usb_device_id *id)
         */
        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 @@ aiptek_probe(struct usb_interface *intf, const struct usb_device_id *id)
 
        /* 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 @@ aiptek_probe(struct usb_interface *intf, const struct usb_device_id *id)
             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 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);
+               set_bit(macroKeyEvents[i], inputdev->keybit);
 
-       /* 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_probe(struct usb_interface *intf, const struct usb_device_id *id)
        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 @@ aiptek_probe(struct usb_interface *intf, const struct usb_device_id *id)
        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 @@ aiptek_probe(struct usb_interface *intf, const struct usb_device_id *id)
                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 @@ static void aiptek_disconnect(struct usb_interface *intf)
                /* 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),
index e03c1c5..15840db 100644 (file)
@@ -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 @@ MODULE_DEVICE_TABLE (usb, atp_table);
  * 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 @@ MODULE_DEVICE_TABLE (usb, atp_table);
 
 /* 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 @@ struct atp {
                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 @@ static void atp_complete(struct urb* urb, struct pt_regs* regs)
                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 @@ static void atp_complete(struct urb* urb, struct pt_regs* regs)
                                       "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 @@ static void atp_complete(struct urb* urb, struct pt_regs* regs)
        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 void atp_close(struct input_dev *input)
 
 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 @@ static int atp_probe(struct usb_interface *iface, const struct usb_device_id *id
                }
        }
        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));
+
+       input_dev->name = "appletouch";
+       input_dev->phys = dev->phys;
+       usb_to_input_id(dev->udev, &input_dev->id);
+       input_dev->cdev.dev = &iface->dev;
 
-       usb_to_input_id(dev->udev, &dev->input.id);
+       input_dev->private = dev;
+       input_dev->open = atp_open;
+       input_dev->close = atp_close;
 
-       set_bit(EV_ABS, dev->input.evbit);
+       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 @@ static void atp_disconnect(struct usb_interface *iface)
        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);
index fd99681..9a2a47d 100644 (file)
 
 #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 char accel[] = { 1, 2, 4, 6, 9, 13, 20 };
 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 @@ struct ati_remote {
 #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 @@ static struct
 
 /* 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 @@ static void ati_remote_input_report(struct urb *urb, struct pt_regs *regs)
 {
        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,38 +583,55 @@ static void ati_remote_irq_in(struct urb *urb, struct pt_regs *regs)
 }
 
 /*
- *     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)
 {
-       if (ati_remote->irq_urb)
-               usb_kill_urb(ati_remote->irq_urb);
+       ati_remote->inbuf = usb_buffer_alloc(udev, DATA_BUFSIZE, SLAB_ATOMIC,
+                                            &ati_remote->inbuf_dma);
+       if (!ati_remote->inbuf)
+               return -1;
 
-       if (ati_remote->out_urb)
-               usb_kill_urb(ati_remote->out_urb);
+       ati_remote->outbuf = usb_buffer_alloc(udev, DATA_BUFSIZE, SLAB_ATOMIC,
+                                             &ati_remote->outbuf_dma);
+       if (!ati_remote->outbuf)
+               return -1;
 
-       input_unregister_device(&ati_remote->idev);
+       ati_remote->irq_urb = usb_alloc_urb(0, GFP_KERNEL);
+       if (!ati_remote->irq_urb)
+               return -1;
 
-       if (ati_remote->inbuf)
-               usb_buffer_free(ati_remote->udev, DATA_BUFSIZE,
-                               ati_remote->inbuf, ati_remote->inbuf_dma);
+       ati_remote->out_urb = usb_alloc_urb(0, GFP_KERNEL);
+       if (!ati_remote->out_urb)
+               return -1;
 
-       if (ati_remote->outbuf)
-               usb_buffer_free(ati_remote->udev, DATA_BUFSIZE,
-                               ati_remote->outbuf, ati_remote->outbuf_dma);
+       return 0;
+}
 
+/*
+ *     ati_remote_free_buffers
+ */
+static void ati_remote_free_buffers(struct ati_remote *ati_remote)
+{
        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);
+       if (ati_remote->inbuf)
+               usb_buffer_free(ati_remote->udev, DATA_BUFSIZE,
+                               ati_remote->inbuf, ati_remote->inbuf_dma);
+
+       if (ati_remote->outbuf)
+               usb_buffer_free(ati_remote->udev, DATA_BUFSIZE,
+                               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 @@ static void ati_remote_input_init(struct ati_remote *ati_remote)
        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 @@ static int ati_remote_initialize(struct ati_remote *ati_remote)
            (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_initialize(struct ati_remote *ati_remote)
 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];
-
-       /* 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));
+       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;
 
-       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;
        }
 
-       /* 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;
+       ati_remote = kzalloc(sizeof (struct ati_remote), GFP_KERNEL);
+       input_dev = input_allocate_device();
+       if (!ati_remote || !input_dev)
+               goto fail1;
 
-       ati_remote->outbuf = usb_buffer_alloc(udev, DATA_BUFSIZE, SLAB_ATOMIC,
-                                             &ati_remote->outbuf_dma);
-       if (!ati_remote->outbuf)
-               goto error;
+       /* Allocate URB buffers, URBs */
+       if (ati_remote_alloc_buffers(udev, ati_remote))
+               goto fail2;
 
-       ati_remote->irq_urb = usb_alloc_urb(0, GFP_KERNEL);
-       if (!ati_remote->irq_urb)
-               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->out_urb = usb_alloc_urb(0, GFP_KERNEL);
-       if (!ati_remote->out_urb)
-               goto error;
+       usb_make_path(udev, ati_remote->phys, sizeof(ati_remote->phys));
+       strlcpy(ati_remote->phys, "/input0", sizeof(ati_remote->phys));
 
-       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 @@ static void ati_remote_disconnect(struct usb_interface *interface)
                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);
 }
 
 /*
index 41f92b9..411a064 100644 (file)
@@ -1619,8 +1619,8 @@ static struct hid_device *usb_hid_configure(struct usb_interface *intf)
        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 @@ static struct hid_device *usb_hid_configure(struct usb_interface *intf)
        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 @@ static struct hid_device *usb_hid_configure(struct usb_interface *intf)
 
        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->product) {
+               if (dev->manufacturer)
+                       strlcat(hid->name, " ", sizeof(hid->name));
+               strlcat(hid->name, dev->product, sizeof(hid->name));
+       }
+
+       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));
 
-       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));
-
-       usb_make_path(dev, buf, 64);
-       snprintf(hid->phys, 64, "%s/input%d", buf,
-                       intf->altsetting[0].desc.bInterfaceNumber);
+       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;
index 0b64522..9ff25eb 100644 (file)
@@ -76,8 +76,8 @@ static struct {
 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 @@ void hidinput_hid_event(struct hid_device *hid, struct hid_field *field, struct
 
        if (!field->hidinput)
                return;
-       input = &field->hidinput->input;
+
+       input = field->hidinput->input;
 
        input_regs(input, regs);
 
@@ -533,13 +534,10 @@ void hidinput_hid_event(struct hid_device *hid, struct hid_field *field, struct
 
 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 @@ int hidinput_connect(struct hid_device *hid)
        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 @@ int hidinput_connect(struct hid_device *hid)
                                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));
 
-                               list_add_tail(&hidinput->list, &hid->inputs);
+                               input_dev->private = hid;
+                               input_dev->event = hidinput_input_event;
+                               input_dev->open = hidinput_open;
+                               input_dev->close = hidinput_close;
 
-                               hidinput->input.private = hid;
-                               hidinput->input.event = hidinput_input_event;
-                               hidinput->input.open = hidinput_open;
-                               hidinput->input.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.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;
+                               hidinput->input = input_dev;
+                               list_add_tail(&hidinput->list, &hid->inputs);
                        }
 
                        for (i = 0; i < report->maxfield; i++)
@@ -657,7 +659,7 @@ int hidinput_connect(struct hid_device *hid)
                                 * 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 @@ int hidinput_connect(struct hid_device *hid)
         * 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 @@ int hidinput_connect(struct hid_device *hid)
 
 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);
        }
 }
index 0c4c77a..f82c9c9 100644 (file)
@@ -255,22 +255,19 @@ static void hid_lgff_input_init(struct hid_device* hid)
        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;
-       }
-
-       hidinput->input.upload_effect = hid_lgff_upload_effect;
-       hidinput->input.flush = hid_lgff_flush;
+       input_dev->upload_effect = hid_lgff_upload_effect;
+       input_dev->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)
index 8f6a0a6..023fd5a 100644 (file)
@@ -111,6 +111,7 @@ int hid_tmff_init(struct hid_device *hid)
        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 @@ int hid_tmff_init(struct hid_device *hid)
                                        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 @@ int hid_tmff_init(struct hid_device *hid)
                        }
 
                        /* 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;
                }
        }
 
index ec2412c..ee48a22 100644 (file)
@@ -371,7 +371,7 @@ struct hid_control_fifo {
 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 */
index becb87e..3b58185 100644 (file)
@@ -73,7 +73,7 @@ MODULE_LICENSE( DRIVER_LICENSE );
 
 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 struct usb_device_id itmtouch_ids [] = {
 
 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 void itmtouch_close(struct input_dev *input)
 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 @@ static int itmtouch_probe(struct usb_interface *intf, const struct usb_device_id
                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 @@ static void itmtouch_disconnect(struct usb_interface *intf)
        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);
index b6f6ac8..a248664 100644 (file)
@@ -34,7 +34,7 @@ MODULE_PARM_DESC(kb_pressure_click, "pressure threshold for clicks");
 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 @@ static void kbtab_irq(struct urb *urb, struct pt_regs *regs)
 {
        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 @@ static int kbtab_probe(struct usb_interface *intf, const struct usb_device_id *i
        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;
-       }
-
-       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);
+       if (!kbtab->irq)
+               goto fail2;
 
-       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->usbdev = dev;
+       kbtab->dev = input_dev;
 
-       kbtab->dev.absfuzz[ABS_X] = 4;
-       kbtab->dev.absfuzz[ABS_Y] = 4;
+       usb_make_path(dev, kbtab->phys, sizeof(kbtab->phys));
+       strlcat(kbtab->phys, "/input0", sizeof(kbtab->phys));
 
-       kbtab->dev.private = kbtab;
-       kbtab->dev.open = kbtab_open;
-       kbtab->dev.close = kbtab_close;
+       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;
 
-       usb_make_path(dev, path, 64);
-       sprintf(kbtab->phys, "%s/input0", path);
+       input_dev->open = kbtab_open;
+       input_dev->close = kbtab_close;
 
-       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;
+       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 @@ static int kbtab_probe(struct usb_interface *intf, const struct usb_device_id *i
        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);
index 99de1b3..5b8d65f 100644 (file)
@@ -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 @@ struct usb_keyspan {
        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 struct usb_driver keyspan_driver;
  */
 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 void keyspan_print(struct usb_keyspan* dev) /*unsigned char* data)*/
 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 @@ static int keyspan_load_tester(struct usb_keyspan* dev, int bits_needed)
        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 @@ static int keyspan_load_tester(struct usb_keyspan* dev, int bits_needed)
                dev->data.bits_left += 8;
        }
 
-       return(0);
+       return 0;
 }
 
 /*
@@ -311,10 +311,10 @@ static void keyspan_check_data(struct usb_keyspan *remote, struct pt_regs *regs)
                        __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 @@ static int keyspan_open(struct input_dev *dev)
 {
        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 @@ static void keyspan_close(struct input_dev *dev)
 {
        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 void keyspan_close(struct input_dev *dev)
  */
 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;
-       }
-
-       /*
-        * 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);
-               }
+               goto fail3;
        }
 
-       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);
+       if (udev->manufacturer)
+               strlcpy(remote->name, udev->manufacturer, sizeof(remote->name));
 
-       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 (udev->product) {
+               if (udev->manufacturer)
+                       strlcat(remote->name, " ", sizeof(remote->name));
+               strlcat(remote->name, udev->product, sizeof(remote->name));
        }
 
-       if (remote->udev->descriptor.iManufacturer &&
-           usb_string(remote->udev, remote->udev->descriptor.iManufacturer, buf, 63) > 0)
-               strcat(remote->name, buf);
+       if (!strlen(remote->name))
+               snprintf(remote->name, sizeof(remote->name),
+                        "USB Keyspan Remote %04x:%04x",
+                        le16_to_cpu(udev->descriptor.idVendor),
+                        le16_to_cpu(udev->descriptor.idProduct));
 
-       if (remote->udev->descriptor.iProduct &&
-           usb_string(remote->udev, remote->udev->descriptor.iProduct, buf, 63) > 0)
-               sprintf(remote->name, "%s %s", remote->name, buf);
+       usb_make_path(udev, remote->phys, sizeof(remote->phys));
+       strlcat(remote->phys, "/input0", sizeof(remote->phys));
 
-       if (!strlen(remote->name))
-               sprintf(remote->name, "USB Keyspan Remote %04x:%04x",
-                       remote->input.id.vendor, remote->input.id.product);
+       input_dev->name = remote->name;
+       input_dev->phys = remote->phys;
+       usb_to_input_id(udev, &input_dev->id);
+       input_dev->cdev.dev = &interface->dev;
 
-       kfree(buf);
+       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 @@ static int keyspan_probe(struct usb_interface *interface, const struct usb_devic
        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 @@ static void keyspan_disconnect(struct usb_interface *interface)
 {
        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");
 }
 
 /*
index ff92750..7fce526 100644 (file)
@@ -98,7 +98,7 @@ struct mtouch_usb {
        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 @@ static void mtouchusb_irq(struct urb *urb, struct pt_regs *regs)
                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 void mtouchusb_free_buffers(struct usb_device *udev, struct mtouch_usb *m
 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 @@ static int mtouchusb_probe(struct usb_interface *intf, const struct usb_device_i
        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 @@ static int mtouchusb_probe(struct usb_interface *intf, const struct usb_device_i
        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 @@ static int mtouchusb_probe(struct usb_interface *intf, const struct usb_device_i
                         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 @@ static int mtouchusb_probe(struct usb_interface *intf, const struct usb_device_i
        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 @@ static void mtouchusb_disconnect(struct usb_interface *intf)
        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);
index acc71ec..a00672c 100644 (file)
@@ -262,6 +262,7 @@ int hid_pid_init(struct hid_device *hid)
 {
        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 @@ int hid_pid_init(struct hid_device *hid)
        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);
 
index ad4afe7..b747623 100644 (file)
@@ -68,7 +68,7 @@ struct powermate_device {
        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 @@ static void powermate_irq(struct urb *urb, struct pt_regs *regs)
        }
 
        /* 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 @@ static void powermate_sync_state(struct powermate_device *pm)
 
                   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 @@ static void powermate_sync_state(struct powermate_device *pm)
                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 @@ static void powermate_pulse_led(struct powermate_device *pm, int static_brightne
        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 @@ static int powermate_alloc_buffers(struct usb_device *udev, struct powermate_dev
                                    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 @@ static int powermate_probe(struct usb_interface *intf, const struct usb_device_i
        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 @@ static int powermate_probe(struct usb_interface *intf, const struct usb_device_i
                0, interface->desc.bInterfaceNumber, NULL, 0,
                USB_CTRL_SET_TIMEOUT);
 
-       if (!(pm = kmalloc(sizeof(struct powermate_device), GFP_KERNEL)))
-               return -ENOMEM;
-
-       memset(pm, 0, sizeof(struct powermate_device));
-       pm->udev = udev;
+       pm = kzalloc(sizeof(struct powermate_device), GFP_KERNEL);
+       input_dev = input_allocate_device();
+       if (!pm || !input_dev)
+               goto fail1;
 
-       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 @@ static int powermate_probe(struct usb_interface *intf, const struct usb_device_i
 
        /* 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 @@ static int powermate_probe(struct usb_interface *intf, const struct usb_device_i
 
        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 @@ static void powermate_disconnect(struct usb_interface *intf)
        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);
index 4276c24..3766ccc 100644 (file)
@@ -68,7 +68,7 @@ struct touchkit_usb {
        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 @@ static void touchkit_irq(struct urb *urb, struct pt_regs *regs)
                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 void touchkit_free_buffers(struct usb_device *udev,
 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 @@ static void touchkit_disconnect(struct usb_interface *intf)
 
        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);
index 28987f1..226b6f9 100644 (file)
@@ -66,7 +66,7 @@ static unsigned char usb_kbd_keycode[256] = {
 };
 
 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 @@ static void usb_kbd_irq(struct urb *urb, struct pt_regs *regs)
                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 void usb_kbd_free_mem(struct usb_device *dev, struct usb_kbd *kbd)
 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 @@ static int usb_kbd_probe(struct usb_interface *iface,
                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;
+
+       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));
 
-       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);
+       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 @@ static int usb_kbd_probe(struct usb_interface *iface,
        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 @@ static void usb_kbd_disconnect(struct usb_interface *intf)
        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);
        }
index 4104dec..230f6b1 100644 (file)
@@ -50,7 +50,7 @@ struct usb_mouse {
        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 @@ static void usb_mouse_irq(struct urb *urb, struct pt_regs *regs)
 {
        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 @@ static void usb_mouse_close(struct input_dev *dev)
        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 @@ static int usb_mouse_probe(struct usb_interface * intf, const struct usb_device_
                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 = input_dev;
+
+       if (dev->manufacturer)
+               strlcpy(mouse->name, dev->manufacturer, sizeof(mouse->name));
 
-       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);
+       if (dev->product) {
+               if (dev->manufacturer)
+                       strlcat(mouse->name, " ", sizeof(mouse->name));
+               strlcat(mouse->name, dev->product, sizeof(mouse->name));
+       }
 
-       mouse->dev.private = mouse;
-       mouse->dev.open = usb_mouse_open;
-       mouse->dev.close = usb_mouse_close;
+       if (!strlen(mouse->name))
+               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, path, 64);
-       sprintf(mouse->phys, "%s/input0", path);
+       usb_make_path(dev, mouse->phys, sizeof(mouse->phys));
+       strlcat(mouse->phys, "/input0", sizeof(mouse->phys));
 
-       mouse->dev.name = mouse->name;
-       mouse->dev.phys = mouse->phys;
-       usb_to_input_id(dev, &mouse->dev.id);
-       mouse->dev.dev = &intf->dev;
+       input_dev->name = mouse->name;
+       input_dev->phys = mouse->phys;
+       usb_to_input_id(dev, &input_dev->id);
+       input_dev->cdev.dev = &intf->dev;
 
-       if (dev->manufacturer)
-               strcat(mouse->name, dev->manufacturer);
-       if (dev->product)
-               sprintf(mouse->name, "%s %s", mouse->name, dev->product);
+       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);
 
-       if (!strlen(mouse->name))
-               sprintf(mouse->name, "USB HIDBP Mouse %04x:%04x",
-                       mouse->dev.id.vendor, mouse->dev.id.product);
+       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 @@ static int usb_mouse_probe(struct usb_interface * intf, const struct usb_device_
        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 @@ static void usb_mouse_disconnect(struct usb_interface *intf)
        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);
index 3b266af..ea0f757 100644 (file)
@@ -111,7 +111,7 @@ struct wacom_features {
 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 @@ static void wacom_pl_irq(struct urb *urb, struct pt_regs *regs)
 {
        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 @@ static void wacom_ptu_irq(struct urb *urb, struct pt_regs *regs)
 {
        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 @@ static void wacom_penpartner_irq(struct urb *urb, struct pt_regs *regs)
 {
        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 @@ static void wacom_graphire_irq(struct urb *urb, struct pt_regs *regs)
 {
        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 @@ static int wacom_intuos_inout(struct urb *urb)
 {
        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 @@ static void wacom_intuos_general(struct urb *urb)
 {
        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 @@ static void wacom_intuos_irq(struct urb *urb, struct pt_regs *regs)
 {
        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 @@ static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *i
 {
        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();
+
+       input_dev->name = wacom->features->name;
+       usb_to_input_id(dev, &input_dev->id);
 
-       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->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 @@ static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *i
        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 @@ static void wacom_disconnect(struct usb_interface *intf)
        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);
index 18125e0..43112f0 100644 (file)
@@ -103,7 +103,7 @@ static struct usb_device_id xpad_table [] = {
 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 @@ struct usb_xpad {
 
 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 void xpad_close (struct input_dev *dev)
 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,89 +225,80 @@ static int xpad_probe(struct usb_interface *intf, const struct usb_device_id *id
                        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;
-        }
-
-       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,
-                        xpad, ep_irq_in->bInterval);
-       xpad->irq_in->transfer_dma = xpad->idata_dma;
-       xpad->irq_in->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
+       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));
 
-       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);
+       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;
 
-       xpad->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
+       input_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);
+               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, xpad->dev.absbit);
+               set_bit(t, input_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;
+                               input_set_abs_params(input_dev, t, -32768, 32767, 16, 128);
                                break;
                        case ABS_Z:
                        case ABS_RZ:    /* the triggers */
-                               xpad->dev.absmax[t] = 255;
-                               xpad->dev.absmin[t] = 0;
+                               input_set_abs_params(input_dev, t, 0, 255, 0, 0);
                                break;
                        case ABS_HAT0X:
                        case ABS_HAT0Y: /* the d-pad */
-                               xpad->dev.absmax[t] =  1;
-                               xpad->dev.absmin[t] = -1;
+                               input_set_abs_params(input_dev, t, -1, 1, 0, 0);
                                break;
                }
        }
 
-       input_register_device(&xpad->dev);
+       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,
+                        xpad, ep_irq_in->bInterval);
+       xpad->irq_in->transfer_dma = xpad->idata_dma;
+       xpad->irq_in->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
 
-       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 @@ static void xpad_disconnect(struct usb_interface *intf)
        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);
index 58a176e..f526aeb 100644 (file)
@@ -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 @@ static const struct lcd_segment_map {
 };
 
 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 int map_p1k_to_key(int scancode)
  */
 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 @@ static int usb_cleanup(struct yealink_dev *yld, int err)
        }
         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 @@ static int usb_probe(struct usb_interface *intf, const struct usb_device_id *id)
        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 @@ static int usb_probe(struct usb_interface *intf, const struct usb_device_id *id)
 
        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 @@ static int usb_probe(struct usb_interface *intf, const struct usb_device_id *id)
        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 */
index 20ac9e1..9fe2c27 100644 (file)
@@ -119,7 +119,7 @@ struct konicawc {
        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 @@ static void konicawc_adjust_picture(struct uvd *uvd)
        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 @@ static int konicawc_compress_iso(struct uvd *uvd, struct urb *dataurb, struct ur
                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 @@ static int konicawc_set_video_mode(struct uvd *uvd, struct video_window *vw)
        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 @@ static void konicawc_configure_video(struct uvd *uvd)
        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 @@ static int konicawc_probe(struct usb_interface *intf, const struct usb_device_id
                        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 @@ static void konicawc_free_uvd(struct uvd *uvd)
        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;
        }
index 2c9402d..89401a5 100644 (file)
@@ -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 @@ void onetouch_release_input(void *onetouch_);
 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 @@ static void usb_onetouch_irq(struct urb *urb, struct pt_regs *regs)
 {
        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 @@ static void usb_onetouch_irq(struct urb *urb, struct pt_regs *regs)
        }
 
        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 @@ int onetouch_connect_input(struct us_data *ss)
        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 @@ int onetouch_connect_input(struct us_data *ss)
                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;
+       onetouch->dev = input_dev;
 
-       set_bit(EV_KEY, onetouch->dev.evbit);
-       set_bit(ONETOUCH_BUTTON, onetouch->dev.keybit);
-       clear_bit(0, onetouch->dev.keybit);
+       if (udev->manufacturer)
+               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));
+       }
 
-       onetouch->dev.private = onetouch;
-       onetouch->dev.open = usb_onetouch_open;
-       onetouch->dev.close = usb_onetouch_close;
+       if (!strlen(onetouch->name))
+               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, path, sizeof(path));
-       sprintf(onetouch->phys, "%s/input0", path);
+       usb_make_path(udev, onetouch->phys, sizeof(onetouch->phys));
+       strlcat(onetouch->phys, "/input0", sizeof(onetouch->phys));
 
-       onetouch->dev.name = onetouch->name;
-       onetouch->dev.phys = 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;
 
-       usb_to_input_id(udev, &onetouch->dev.id);
+       set_bit(EV_KEY, input_dev->evbit);
+       set_bit(ONETOUCH_BUTTON, input_dev->keybit);
+       clear_bit(0, input_dev->keybit);
 
-       onetouch->dev.dev = &udev->dev;
-
-       if (udev->manufacturer)
-               strcat(onetouch->name, udev->manufacturer);
-       if (udev->product)
-               sprintf(onetouch->name, "%s %s", onetouch->name,
-                       udev->product);
-       if (!strlen(onetouch->name))
-               sprintf(onetouch->name, "Maxtor Onetouch %04x:%04x",
-                       onetouch->dev.id.vendor, onetouch->dev.id.product);
+       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 @@ int onetouch_connect_input(struct us_data *ss)
        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 @@ void onetouch_release_input(void *onetouch_)
 
        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);
        }
 }
index 3c72c62..1991fdb 100644 (file)
@@ -73,17 +73,15 @@ static void corgibl_blank(int blank)
 }
 
 #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
index 70be700..9073be4 100644 (file)
@@ -1031,7 +1031,7 @@ register_framebuffer(struct fb_info *fb_info)
                        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 */
index 1d54d3d..0b9301f 100644 (file)
@@ -424,23 +424,21 @@ static void imxfb_setup_gpio(struct imxfb_info *fbi)
  * 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
index 194eed0..6206da9 100644 (file)
@@ -981,21 +981,19 @@ pxafb_freq_policy(struct notifier_block *nb, unsigned long val, void *data)
  * 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
index fa98d91..cb2f7a1 100644 (file)
@@ -655,7 +655,7 @@ bail:
 }
 
 #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 @@ static int s1d13xxxfb_suspend(struct device *dev, pm_message_t state, u32 level)
                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);
 
index 5ab79af..3862d3c 100644 (file)
@@ -847,37 +847,32 @@ static int s3c2410fb_remove(struct device *dev)
 
 /* 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);
-
-               s3c2410fb_init_registers(info);
+       clk_enable(info->clk);
+       msleep(1);
 
-       }
+       s3c2410fb_init_registers(info);
 
        return 0;
 }
index 8000890..78e5f19 100644 (file)
@@ -1309,21 +1309,19 @@ sa1100fb_freq_policy(struct notifier_block *nb, unsigned long val,
  * 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
index 0030c07..752bf88 100644 (file)
@@ -438,36 +438,34 @@ static void w100fb_restore_vidmem(struct w100fb_par *par)
        }
 }
 
-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;
-
-               w100fb_save_vidmem(par);
-               if(tg && tg->suspend)
-                       tg->suspend(par);
-               w100_suspend(W100_SUSPEND_ALL);
-               par->blanked = 1;
-       }
+       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;
+
        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
index 3d1cce3..6a3df88 100644 (file)
@@ -370,8 +370,8 @@ static int init_coda_psdev(void)
        }               
        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)
index 1e84864..9c06c54 100644 (file)
@@ -192,6 +192,7 @@ check_partition(struct gendisk *hd, struct block_device *bdev)
 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 @@ part_attr_show(struct kobject * kobj, struct attribute * attr, char * page)
        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 @@ static ssize_t part_stat_read(struct hd_struct * p, char *page)
                       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 part_attribute part_attr_stat = {
 };
 
 static struct attribute * default_attrs[] = {
+       &part_attr_uevent.attr,
        &part_attr_dev.attr,
        &part_attr_start.attr,
        &part_attr_size.attr,
index 95d607a..a9e72ac 100644 (file)
 #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 @@ struct device_driver {
        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 @@ struct class_attribute class_attr_##_name = __ATTR(_name,_mode,_show,_store)
 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_device {
        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 int class_device_rename(struct class_device *, char *);
 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 class_interface {
        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 void class_interface_unregister(struct class_interface *);
 
 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 device {
 
        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 int  device_attach(struct device * dev);
 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
index 142e1c1..eabdb5c 100644 (file)
@@ -132,6 +132,7 @@ struct gendisk {
 struct disk_attribute {
        struct attribute attr;
        ssize_t (*show)(struct gendisk *, char *);
+       ssize_t (*store)(struct gendisk *, const char *, size_t);
 };
 
 /* 
index b4af45a..9230032 100644 (file)
@@ -66,8 +66,6 @@ struct i2o_device {
        struct device device;
 
        struct semaphore lock;  /* device lock */
-
-       struct class_device classdev;   /* i2o device class */
 };
 
 /*
@@ -194,7 +192,7 @@ struct i2o_controller {
        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 */
index d783631..f623c74 100644 (file)
@@ -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 input_dev {
        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 @@ static inline void init_input_dev(struct input_dev *dev)
        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 @@ static inline void input_set_abs_params(struct input_dev *dev, int axis, int min
        dev->absbit[LONG(axis)] |= BIT(axis);
 }
 
-extern struct class *input_class;
+extern struct class input_class;
 
 #endif
 #endif
index 5cfb076..7897cf5 100644 (file)
@@ -219,7 +219,9 @@ typedef struct pm_message {
 
 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 @@ extern void device_resume(void);
 
 #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 */
index 7ef6f6a..3ab3754 100644 (file)
@@ -54,7 +54,7 @@ static char *action_to_string(enum kobject_action action)
 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)
index de8af5f..860444a 100644 (file)
@@ -520,7 +520,7 @@ static int hidp_session(void *arg)
 
        if (session->input) {
                input_unregister_device(session->input);
-               kfree(session->input);
+               session->input = NULL;
        }
 
        up_write(&hidp_session_sem);
@@ -536,6 +536,8 @@ static inline void hidp_setup_input(struct hidp_session *session, struct hidp_co
 
        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 @@ int hidp_add_connection(struct hidp_connadd_req *req, struct socket *ctrl_sock,
                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 @@ unlink:
 
        __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);
index 38b20ef..877bb00 100644 (file)
@@ -275,23 +275,23 @@ static int pxa2xx_ac97_do_resume(snd_card_t *card)
        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;
index c72a791..59202de 100644 (file)
@@ -676,8 +676,8 @@ struct snd_generic_device {
 #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 @@ int snd_card_set_pm_callback(snd_card_t *card,
 
 #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 @@ static int snd_generic_suspend(struct device *dev, pm_message_t state, u32 level
        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;
index 9e76bdd..b57519a 100644 (file)
@@ -231,7 +231,7 @@ int snd_register_device(int type, snd_card_t * card, int dev, snd_minor_t * reg,
                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;
index 95fa81e..d33bb46 100644 (file)
@@ -567,7 +567,7 @@ static int __init oss_init(void)
                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 @@ static int __init oss_init(void)
                                                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);
                }
index becbc42..ec70fad 100644 (file)
@@ -31,7 +31,8 @@ static int ac97_bus_suspend(struct device *dev, pm_message_t state)
        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 @@ static int ac97_bus_resume(struct device *dev)
        int ret = 0;
 
        if (dev->driver && dev->driver->resume)
-               ret = dev->driver->resume(dev, RESUME_POWER_ON);
+               ret = dev->driver->resume(dev);
+
        return ret;
 }
 
index 31ea7a4..1681ee1 100644 (file)
 #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 @@ static snd_kcontrol_new_t snd_pmac_beep_mixer = {
 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);
index 954f994..394b53e 100644 (file)
@@ -174,7 +174,7 @@ static int sound_insert_unit(struct sound_unit **list, struct file_operations *f
 
        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;