Fedora kernel-2.6.17-1.2142_FC4 patched with stable patch-2.6.17.4-vs2.0.2-rc26.diff
[linux-2.6.git] / drivers / input / keyboard / hil_kbd.c
index ef78bff..2e4abdc 100644 (file)
@@ -66,7 +66,7 @@ static unsigned int hil_kbd_set3[HIL_KEYCODES_SET3_TBLSIZE] =
 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. */
@@ -86,7 +86,7 @@ struct hil_kbd {
 /* 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;
@@ -204,7 +204,7 @@ static irqreturn_t hil_kbd_interrupt(struct serio *serio,
        hil_packet packet;
        int idx;
 
-       kbd = (struct hil_kbd *)serio->private;
+       kbd = serio_get_drvdata(serio);
        if (kbd == NULL) {
                BUG();
                return IRQ_HANDLED;
@@ -234,33 +234,38 @@ static void hil_kbd_disconnect(struct serio *serio)
 {
        struct hil_kbd *kbd;
 
-       kbd = (struct hil_kbd *)serio->private;
+       kbd = serio_get_drvdata(serio);
        if (kbd == NULL) {
                BUG();
                return;
        }
 
-       input_unregister_device(&kbd->dev);
        serio_close(serio);
+       input_unregister_device(kbd->dev);
        kfree(kbd);
 }
 
-static void hil_kbd_connect(struct serio *serio, struct serio_driver *drv)
+static int hil_kbd_connect(struct serio *serio, struct serio_driver *drv)
 {
        struct hil_kbd  *kbd;
        uint8_t         did, *idd;
        int             i;
-       
-       if (serio->type != (SERIO_HIL_MLC | SERIO_HIL)) return;
 
-       if (!(kbd = kmalloc(sizeof(struct hil_kbd), GFP_KERNEL))) return;
-       memset(kbd, 0, sizeof(struct hil_kbd));
+       kbd = kzalloc(sizeof(*kbd), GFP_KERNEL);
+       if (!kbd)
+               return -ENOMEM;
 
-       if (serio_open(serio, drv)) goto bail0;
+       kbd->dev = input_allocate_device();
+       if (!kbd->dev)
+               goto bail0;
 
-       serio->private = kbd;
+       kbd->dev->private = kbd;
+
+       if (serio_open(serio, drv))
+               goto bail1;
+
+       serio_set_drvdata(serio, kbd);
        kbd->serio = serio;
-       kbd->dev.private = kbd;
 
        init_MUTEX_LOCKED(&(kbd->sem));
 
@@ -302,38 +307,38 @@ static void hil_kbd_connect(struct serio *serio, struct serio_driver *drv)
                        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);
@@ -342,19 +347,33 @@ static void hil_kbd_connect(struct serio *serio, struct serio_driver *drv)
        down(&(kbd->sem));
        up(&(kbd->sem));
 
-       return;
- bail1:
+       return 0;
+ bail2:
        serio_close(serio);
+       serio_set_drvdata(serio, NULL);
+ bail1:
+       input_free_device(kbd->dev);
  bail0:
        kfree(kbd);
+       return -EIO;
 }
 
+static struct serio_device_id hil_kbd_ids[] = {
+       {
+               .type = SERIO_HIL_MLC,
+               .proto = SERIO_HIL,
+               .id = SERIO_ANY,
+               .extra = SERIO_ANY,
+       },
+       { 0 }
+};
 
 struct serio_driver hil_kbd_serio_drv = {
        .driver         = {
                .name   = "hil_kbd",
        },
        .description    = "HP HIL keyboard driver",
+       .id_table       = hil_kbd_ids,
        .connect        = hil_kbd_connect,
        .disconnect     = hil_kbd_disconnect,
        .interrupt      = hil_kbd_interrupt