Convert HIL drivers to use input_allocate_device() - avoids crashes.
Signed-off-by: Helge Deller <deller@parisc-linux.org>
Signed-off-by: Kyle McMartin <kyle@parisc-linux.org>
 static char hil_language[][16] = { HIL_LOCALE_MAP };
 
 struct hil_kbd {
-       struct input_dev dev;
+       struct input_dev *dev;
        struct serio *serio;
 
        /* Input buffer and index for packets from HIL bus. */
 /* Process a complete packet after transfer from the HIL */
 static void hil_kbd_process_record(struct hil_kbd *kbd)
 {
-       struct input_dev *dev = &kbd->dev;
+       struct input_dev *dev = kbd->dev;
        hil_packet *data = kbd->data;
        hil_packet p;
        int idx, i, cnt;
                return;
        }
 
-       input_unregister_device(&kbd->dev);
+       input_unregister_device(kbd->dev);
        serio_close(serio);
+       input_free_device(kbd->dev);
        kfree(kbd);
 }
 
        uint8_t         did, *idd;
        int             i;
        
-       kbd = kmalloc(sizeof(*kbd), GFP_KERNEL);
+       kbd = kzalloc(sizeof(*kbd), GFP_KERNEL);
        if (!kbd)
                return -ENOMEM;
-       memset(kbd, 0, sizeof(struct hil_kbd));
+
+       kbd->dev = input_allocate_device();
+       if (!kbd->dev) goto bail1;
+       kbd->dev->private = kbd;
 
        if (serio_open(serio, drv)) goto bail0;
 
        serio_set_drvdata(serio, kbd);
        kbd->serio = serio;
-       kbd->dev.private = kbd;
 
        init_MUTEX_LOCKED(&(kbd->sem));
 
                        did, hil_language[did & HIL_IDD_DID_TYPE_KB_LANG_MASK]);
                break;
        default:
-               goto bail1;
+               goto bail2;
        }
 
        if(HIL_IDD_NUM_BUTTONS(idd) || HIL_IDD_NUM_AXES_PER_SET(*idd)) {
                printk(KERN_INFO PREFIX "keyboards only, no combo devices supported.\n");
-               goto bail1;
+               goto bail2;
        }
 
 
-       kbd->dev.evbit[0]       = BIT(EV_KEY) | BIT(EV_REP);
-       kbd->dev.ledbit[0]      = BIT(LED_NUML) | BIT(LED_CAPSL) | BIT(LED_SCROLLL);
-       kbd->dev.keycodemax     = HIL_KEYCODES_SET1_TBLSIZE;
-       kbd->dev.keycodesize    = sizeof(hil_kbd_set1[0]);
-       kbd->dev.keycode        = hil_kbd_set1;
-       kbd->dev.name           = strlen(kbd->rnm) ? kbd->rnm : HIL_GENERIC_NAME;
-       kbd->dev.phys           = "hpkbd/input0";       /* XXX */
+       kbd->dev->evbit[0]      = BIT(EV_KEY) | BIT(EV_REP);
+       kbd->dev->ledbit[0]     = BIT(LED_NUML) | BIT(LED_CAPSL) | BIT(LED_SCROLLL);
+       kbd->dev->keycodemax    = HIL_KEYCODES_SET1_TBLSIZE;
+       kbd->dev->keycodesize   = sizeof(hil_kbd_set1[0]);
+       kbd->dev->keycode       = hil_kbd_set1;
+       kbd->dev->name          = strlen(kbd->rnm) ? kbd->rnm : HIL_GENERIC_NAME;
+       kbd->dev->phys          = "hpkbd/input0";       /* XXX */
 
-       kbd->dev.id.bustype     = BUS_HIL;
-       kbd->dev.id.vendor      = PCI_VENDOR_ID_HP;
-       kbd->dev.id.product     = 0x0001; /* TODO: get from kbd->rsc */
-       kbd->dev.id.version     = 0x0100; /* TODO: get from kbd->rsc */
-       kbd->dev.dev            = &serio->dev;
+       kbd->dev->id.bustype    = BUS_HIL;
+       kbd->dev->id.vendor     = PCI_VENDOR_ID_HP;
+       kbd->dev->id.product    = 0x0001; /* TODO: get from kbd->rsc */
+       kbd->dev->id.version    = 0x0100; /* TODO: get from kbd->rsc */
+       kbd->dev->dev           = &serio->dev;
 
        for (i = 0; i < 128; i++) {
-               set_bit(hil_kbd_set1[i], kbd->dev.keybit);
-               set_bit(hil_kbd_set3[i], kbd->dev.keybit);
+               set_bit(hil_kbd_set1[i], kbd->dev->keybit);
+               set_bit(hil_kbd_set3[i], kbd->dev->keybit);
        }
-       clear_bit(0, kbd->dev.keybit);
+       clear_bit(0, kbd->dev->keybit);
 
-       input_register_device(&kbd->dev);
+       input_register_device(kbd->dev);
        printk(KERN_INFO "input: %s, ID: %d\n",
-               kbd->dev.name, did);
+               kbd->dev->name, did);
 
        serio->write(serio, 0);
        serio->write(serio, 0);
        up(&(kbd->sem));
 
        return 0;
- bail1:
+ bail2:
        serio_close(serio);
+ bail1:
+       input_free_device(kbd->dev);
  bail0:
        kfree(kbd);
        serio_set_drvdata(serio, NULL);
 
  *
  *  Copyright (C) 1998 Philip Blundell <philb@gnu.org>
  *  Copyright (C) 1999 Matthew Wilcox <willy@bofh.ai>
- *  Copyright (C) 1999-2003 Helge Deller <deller@gmx.de>
+ *  Copyright (C) 1999-2006 Helge Deller <deller@gmx.de>
  *
  *  Very basic HP Human Interface Loop (HIL) driver.
  *  This driver handles the keyboard on HP300 (m68k) and on some 
 
 /* HIL structure */
 static struct {
-       struct input_dev dev;
+       struct input_dev *dev;
 
        unsigned int curdev;
        
                down = (hil_dev.data[1] & 1) == 0;
                scode = hil_dev.data[1] >> 1;
                key = hphilkeyb_keycode[scode];
-               input_report_key(&hil_dev.dev, key, down);
+               input_report_key(hil_dev.dev, key, down);
                break;
        }
        hil_dev.curdev = 0;
        unsigned int i, kbid;
        wait_queue_head_t hil_wait;
 
-       if (hil_dev.dev.id.bustype) {
+       if (hil_dev.dev) {
                return -ENODEV; /* already initialized */
        }
+
+       hil_dev.dev = input_allocate_device();
+       if (!hil_dev.dev)
+               return -ENOMEM;
+       hil_dev.dev->private = &hil_dev;
        
 #if defined(CONFIG_HP300)
        if (!hwreg_present((void *)(HILBASE + HIL_DATA)))
        c = 0;
        hil_do(HIL_WRITEKBDSADR, &c, 1);
        
-       init_input_dev(&hil_dev.dev);
-
        for (i = 0; i < HIL_KEYCODES_SET1_TBLSIZE; i++)
                if (hphilkeyb_keycode[i] != KEY_RESERVED)
-                       set_bit(hphilkeyb_keycode[i], hil_dev.dev.keybit);
-
-       hil_dev.dev.evbit[0]    = BIT(EV_KEY) | BIT(EV_REP);
-       hil_dev.dev.ledbit[0]   = BIT(LED_NUML) | BIT(LED_CAPSL) | BIT(LED_SCROLLL);
-       hil_dev.dev.keycodemax  = HIL_KEYCODES_SET1_TBLSIZE;
-        hil_dev.dev.keycodesize = sizeof(hphilkeyb_keycode[0]);
-       hil_dev.dev.keycode     = hphilkeyb_keycode;
-       hil_dev.dev.name        = "HIL keyboard";
-       hil_dev.dev.phys        = "hpkbd/input0";
-
-       hil_dev.dev.id.bustype  = BUS_HIL;
-       hil_dev.dev.id.vendor   = PCI_VENDOR_ID_HP;
-       hil_dev.dev.id.product  = 0x0001;
-       hil_dev.dev.id.version  = 0x0010;
-
-       input_register_device(&hil_dev.dev);
+                       set_bit(hphilkeyb_keycode[i], hil_dev.dev->keybit);
+
+       hil_dev.dev->evbit[0]    = BIT(EV_KEY) | BIT(EV_REP);
+       hil_dev.dev->ledbit[0]   = BIT(LED_NUML) | BIT(LED_CAPSL) | BIT(LED_SCROLLL);
+       hil_dev.dev->keycodemax  = HIL_KEYCODES_SET1_TBLSIZE;
+       hil_dev.dev->keycodesize = sizeof(hphilkeyb_keycode[0]);
+       hil_dev.dev->keycode     = hphilkeyb_keycode;
+       hil_dev.dev->name       = "HIL keyboard";
+       hil_dev.dev->phys       = "hpkbd/input0";
+
+       hil_dev.dev->id.bustype = BUS_HIL;
+       hil_dev.dev->id.vendor  = PCI_VENDOR_ID_HP;
+       hil_dev.dev->id.product = 0x0001;
+       hil_dev.dev->id.version = 0x0010;
+
+       input_register_device(hil_dev.dev);
        printk(KERN_INFO "input: %s, ID %d at 0x%08lx (irq %d) found and attached\n",
-               hil_dev.dev.name, kbid, HILBASE, HIL_IRQ);
+               hil_dev.dev->name, kbid, HILBASE, HIL_IRQ);
 
        return 0;
 }
        /* Turn off interrupts */
        hil_do(HIL_INTOFF, NULL, 0);
 
-       input_unregister_device(&hil_dev.dev);
+       input_unregister_device(hil_dev.dev);
+
+       input_free_device(hil_dev.dev);
+       hil_dev.dev = NULL;
 
 #if defined(CONFIG_PARISC)
        unregister_parisc_driver(&hil_driver);
 
 #define HIL_PTR_MAX_LENGTH 16
 
 struct hil_ptr {
-       struct input_dev dev;
+       struct input_dev *dev;
        struct serio *serio;
 
        /* Input buffer and index for packets from HIL bus. */
 /* Process a complete packet after transfer from the HIL */
 static void hil_ptr_process_record(struct hil_ptr *ptr)
 {
-       struct input_dev *dev = &ptr->dev;
+       struct input_dev *dev = ptr->dev;
        hil_packet *data = ptr->data;
        hil_packet p;
        int idx, i, cnt, laxis;
                if (absdev) {
                        val = lo + (hi<<8);
 #ifdef TABLET_AUTOADJUST
-                       if (val < ptr->dev.absmin[ABS_X + i])
-                               ptr->dev.absmin[ABS_X + i] = val;
-                       if (val > ptr->dev.absmax[ABS_X + i])
-                               ptr->dev.absmax[ABS_X + i] = val;
+                       if (val < dev->absmin[ABS_X + i])
+                               dev->absmin[ABS_X + i] = val;
+                       if (val > dev->absmax[ABS_X + i])
+                               dev->absmax[ABS_X + i] = val;
 #endif
-                       if (i%3) val = ptr->dev.absmax[ABS_X + i] - val;
+                       if (i%3) val = dev->absmax[ABS_X + i] - val;
                        input_report_abs(dev, ABS_X + i, val);
                } else {
                        val = (int) (((int8_t)lo) | ((int8_t)hi<<8));
                return;
        }
 
-       input_unregister_device(&ptr->dev);
+       input_unregister_device(ptr->dev);
        serio_close(serio);
+       input_free_device(ptr->dev);
        kfree(ptr);
 }
 
 static int hil_ptr_connect(struct serio *serio, struct serio_driver *driver)
 {
-       struct hil_ptr  *ptr;
-       char            *txt;
-       unsigned int    i, naxsets, btntype;
-       uint8_t         did, *idd;
+       struct hil_ptr   *ptr;
+       char             *txt;
+       unsigned int     i, naxsets, btntype;
+       uint8_t          did, *idd;
 
-       if (!(ptr = kmalloc(sizeof(struct hil_ptr), GFP_KERNEL))) return -ENOMEM;
-       memset(ptr, 0, sizeof(struct hil_ptr));
+       if (!(ptr = kzalloc(sizeof(struct hil_ptr), GFP_KERNEL)))
+               return -ENOMEM;
 
-       if (serio_open(serio, driver)) goto bail0;
+       ptr->dev = input_allocate_device();
+       if (!ptr->dev) goto bail0;
+       ptr->dev->private = ptr;
+
+       if (serio_open(serio, driver)) goto bail1;
 
        serio_set_drvdata(serio, ptr);
        ptr->serio = serio;
-       ptr->dev.private = ptr;
 
        init_MUTEX_LOCKED(&(ptr->sem));
 
 
        up(&(ptr->sem));
 
-       init_input_dev(&ptr->dev);
        did = ptr->idd[0];
        idd = ptr->idd + 1;
        txt = "unknown";
        if ((did & HIL_IDD_DID_TYPE_MASK) == HIL_IDD_DID_TYPE_REL) {
-               ptr->dev.evbit[0] = BIT(EV_REL);
+               ptr->dev->evbit[0] = BIT(EV_REL);
                txt = "relative";
        }
 
        if ((did & HIL_IDD_DID_TYPE_MASK) == HIL_IDD_DID_TYPE_ABS) {
-               ptr->dev.evbit[0] = BIT(EV_ABS);
+               ptr->dev->evbit[0] = BIT(EV_ABS);
                txt = "absolute";
        }
-       if (!ptr->dev.evbit[0]) {
-               goto bail1;
+       if (!ptr->dev->evbit[0]) {
+               goto bail2;
        }
 
        ptr->nbtn = HIL_IDD_NUM_BUTTONS(idd);
-       if (ptr->nbtn) ptr->dev.evbit[0] |= BIT(EV_KEY);
+       if (ptr->nbtn) ptr->dev->evbit[0] |= BIT(EV_KEY);
 
        naxsets = HIL_IDD_NUM_AXSETS(*idd);
        ptr->naxes = HIL_IDD_NUM_AXES_PER_SET(*idd);
                btntype = BTN_MOUSE;
 
        for (i = 0; i < ptr->nbtn; i++) {
-               set_bit(btntype | i, ptr->dev.keybit);
+               set_bit(btntype | i, ptr->dev->keybit);
                ptr->btnmap[i] = btntype | i;
        }
 
 
        if ((did & HIL_IDD_DID_TYPE_MASK) == HIL_IDD_DID_TYPE_REL) {
                for (i = 0; i < ptr->naxes; i++) {
-                       set_bit(REL_X + i, ptr->dev.relbit);
+                       set_bit(REL_X + i, ptr->dev->relbit);
                }
                for (i = 3; (i < ptr->naxes + 3) && (naxsets > 1); i++) {
-                       set_bit(REL_X + i, ptr->dev.relbit);
+                       set_bit(REL_X + i, ptr->dev->relbit);
                }
        } else {
                for (i = 0; i < ptr->naxes; i++) {
-                       set_bit(ABS_X + i, ptr->dev.absbit);
-                       ptr->dev.absmin[ABS_X + i] = 0;
-                       ptr->dev.absmax[ABS_X + i] = 
+                       set_bit(ABS_X + i, ptr->dev->absbit);
+                       ptr->dev->absmin[ABS_X + i] = 0;
+                       ptr->dev->absmax[ABS_X + i] =
                                HIL_IDD_AXIS_MAX((ptr->idd + 1), i);
                }
                for (i = 3; (i < ptr->naxes + 3) && (naxsets > 1); i++) {
-                       set_bit(ABS_X + i, ptr->dev.absbit);
-                       ptr->dev.absmin[ABS_X + i] = 0;
-                       ptr->dev.absmax[ABS_X + i] = 
+                       set_bit(ABS_X + i, ptr->dev->absbit);
+                       ptr->dev->absmin[ABS_X + i] = 0;
+                       ptr->dev->absmax[ABS_X + i] =
                                HIL_IDD_AXIS_MAX((ptr->idd + 1), (i - 3));
                }
 #ifdef TABLET_AUTOADJUST
                for (i = 0; i < ABS_MAX; i++) {
-                       int diff = ptr->dev.absmax[ABS_X + i] / 10;
-                       ptr->dev.absmin[ABS_X + i] += diff;
-                       ptr->dev.absmax[ABS_X + i] -= diff;
+                       int diff = ptr->dev->absmax[ABS_X + i] / 10;
+                       ptr->dev->absmin[ABS_X + i] += diff;
+                       ptr->dev->absmax[ABS_X + i] -= diff;
                }
 #endif
        }
 
-       ptr->dev.name = strlen(ptr->rnm) ? ptr->rnm : HIL_GENERIC_NAME;
+       ptr->dev->name = strlen(ptr->rnm) ? ptr->rnm : HIL_GENERIC_NAME;
 
-       ptr->dev.id.bustype     = BUS_HIL;
-       ptr->dev.id.vendor      = PCI_VENDOR_ID_HP;
-       ptr->dev.id.product     = 0x0001; /* TODO: get from ptr->rsc */
-       ptr->dev.id.version     = 0x0100; /* TODO: get from ptr->rsc */
-       ptr->dev.dev            = &serio->dev;
+       ptr->dev->id.bustype    = BUS_HIL;
+       ptr->dev->id.vendor     = PCI_VENDOR_ID_HP;
+       ptr->dev->id.product    = 0x0001; /* TODO: get from ptr->rsc */
+       ptr->dev->id.version    = 0x0100; /* TODO: get from ptr->rsc */
+       ptr->dev->dev           = &serio->dev;
 
-       input_register_device(&ptr->dev);
+       input_register_device(ptr->dev);
        printk(KERN_INFO "input: %s (%s), ID: %d\n",
-                ptr->dev.name, 
+               ptr->dev->name,
                (btntype == BTN_MOUSE) ? "HIL mouse":"HIL tablet or touchpad",
                did);
 
        return 0;
- bail1:
+ bail2:
        serio_close(serio);
+ bail1:
+       input_free_device(ptr->dev);
  bail0:
        kfree(ptr);
        serio_set_drvdata(serio, NULL);