]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/commitdiff
Merge rsync://rsync.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6
authorDmitry Torokhov <dtor@insightbb.com>
Fri, 8 Dec 2006 06:07:56 +0000 (01:07 -0500)
committerDmitry Torokhov <dtor@insightbb.com>
Fri, 8 Dec 2006 06:07:56 +0000 (01:07 -0500)
Conflicts:

drivers/usb/input/hid.h

13 files changed:
1  2 
Documentation/DocBook/kernel-api.tmpl
drivers/input/gameport/gameport.c
drivers/input/keyboard/atkbd.c
drivers/input/keyboard/lkkbd.c
drivers/input/keyboard/sunkbd.c
drivers/input/mouse/psmouse-base.c
drivers/input/serio/serio.c
drivers/input/serio/serio_raw.c
drivers/input/touchscreen/ads7846.c
drivers/macintosh/Kconfig
drivers/usb/input/hid-core.c
drivers/usb/input/hid-input.c
drivers/usb/input/hid.h

index a1af278f9901d9d2f6607bff72f3e3986207e85b,ca094913c5555fc99caeadf5b964d0d6e0195de0..3fa0c4b4541e065760a3c119e88d314ba3b6ee91
@@@ -418,9 -418,35 +418,35 @@@ X!Edrivers/pnp/system.
  !Idrivers/parport/daisy.c
    </chapter>
  
-   <chapter id="viddev">
-      <title>Video4Linux</title>
- !Edrivers/media/video/videodev.c
+   <chapter id="message_devices">
+       <title>Message-based devices</title>
+      <sect1><title>Fusion message devices</title>
+ !Edrivers/message/fusion/mptbase.c
+ !Idrivers/message/fusion/mptbase.c
+ !Edrivers/message/fusion/mptscsih.c
+ !Idrivers/message/fusion/mptscsih.c
+ !Idrivers/message/fusion/mptctl.c
+ !Idrivers/message/fusion/mptspi.c
+ !Idrivers/message/fusion/mptfc.c
+ !Idrivers/message/fusion/mptlan.c
+      </sect1>
+      <sect1><title>I2O message devices</title>
+ !Iinclude/linux/i2o.h
+ !Idrivers/message/i2o/core.h
+ !Edrivers/message/i2o/iop.c
+ !Idrivers/message/i2o/iop.c
+ !Idrivers/message/i2o/config-osm.c
+ !Edrivers/message/i2o/exec-osm.c
+ !Idrivers/message/i2o/exec-osm.c
+ !Idrivers/message/i2o/bus-osm.c
+ !Edrivers/message/i2o/device.c
+ !Idrivers/message/i2o/device.c
+ !Idrivers/message/i2o/driver.c
+ !Idrivers/message/i2o/pci.c
+ !Idrivers/message/i2o/i2o_block.c
+ !Idrivers/message/i2o/i2o_scsi.c
+ !Idrivers/message/i2o/i2o_proc.c
+      </sect1>
    </chapter>
  
    <chapter id="snddev">
@@@ -533,12 -559,4 +559,12 @@@ X!Idrivers/video/console/fonts.
  -->
       </sect1>
    </chapter>
 +
 +  <chapter id="input_subsystem">
 +     <title>Input Subsystem</title>
 +!Iinclude/linux/input.h
 +!Edrivers/input/input.c
 +!Edrivers/input/ff-core.c
 +!Edrivers/input/ff-memless.c
 +  </chapter>
  </book>
index bba5894fcecd515945b62e078a33af9dc6ebf93f,79dfb4b25c97126ef1817bafb28195073f0727d7..a00fe470a8292847f3607df00973440a98d43d45
@@@ -23,6 -23,7 +23,7 @@@
  #include <linux/kthread.h>
  #include <linux/sched.h>      /* HZ */
  #include <linux/mutex.h>
+ #include <linux/freezer.h>
  
  /*#include <asm/io.h>*/
  
@@@ -730,6 -731,12 +731,6 @@@ static int gameport_driver_remove(struc
        return 0;
  }
  
 -static struct bus_type gameport_bus = {
 -      .name   = "gameport",
 -      .probe  = gameport_driver_probe,
 -      .remove = gameport_driver_remove,
 -};
 -
  static void gameport_add_driver(struct gameport_driver *drv)
  {
        int error;
@@@ -775,15 -782,6 +776,15 @@@ static int gameport_bus_match(struct de
        return !gameport_drv->ignore;
  }
  
 +static struct bus_type gameport_bus = {
 +      .name           = "gameport",
 +      .dev_attrs      = gameport_device_attrs,
 +      .drv_attrs      = gameport_driver_attrs,
 +      .match          = gameport_bus_match,
 +      .probe          = gameport_driver_probe,
 +      .remove         = gameport_driver_remove,
 +};
 +
  static void gameport_set_drv(struct gameport *gameport, struct gameport_driver *drv)
  {
        mutex_lock(&gameport->drv_mutex);
  
  int gameport_open(struct gameport *gameport, struct gameport_driver *drv, int mode)
  {
 -
        if (gameport->open) {
                if (gameport->open(gameport, mode)) {
                        return -1;
@@@ -820,6 -819,9 +821,6 @@@ static int __init gameport_init(void
  {
        int error;
  
 -      gameport_bus.dev_attrs = gameport_device_attrs;
 -      gameport_bus.drv_attrs = gameport_driver_attrs;
 -      gameport_bus.match = gameport_bus_match;
        error = bus_register(&gameport_bus);
        if (error) {
                printk(KERN_ERR "gameport: failed to register gameport bus, error: %d\n", error);
index 498e64a00e3cf51044515a10f37d8481403f4ebc,8451b29a3db534ff1b1d746b35e88d334b7b07dc..c621a9177a565353c424b610d2901a4c4ff87834
@@@ -567,9 -567,9 +567,9 @@@ static int atkbd_set_leds(struct atkbd 
   * interrupt context.
   */
  
- static void atkbd_event_work(void *data)
+ static void atkbd_event_work(struct work_struct *work)
  {
-       struct atkbd *atkbd = data;
+       struct atkbd *atkbd = container_of(work, struct atkbd, event_work);
  
        mutex_lock(&atkbd->event_mutex);
  
@@@ -939,11 -939,11 +939,11 @@@ static int atkbd_connect(struct serio *
        atkbd = kzalloc(sizeof(struct atkbd), GFP_KERNEL);
        dev = input_allocate_device();
        if (!atkbd || !dev)
 -              goto fail;
 +              goto fail1;
  
        atkbd->dev = dev;
        ps2_init(&atkbd->ps2dev, serio);
-       INIT_WORK(&atkbd->event_work, atkbd_event_work, atkbd);
+       INIT_WORK(&atkbd->event_work, atkbd_event_work);
        mutex_init(&atkbd->event_mutex);
  
        switch (serio->id.type) {
  
        err = serio_open(serio, drv);
        if (err)
 -              goto fail;
 +              goto fail2;
  
        if (atkbd->write) {
  
                if (atkbd_probe(atkbd)) {
 -                      serio_close(serio);
                        err = -ENODEV;
 -                      goto fail;
 +                      goto fail3;
                }
  
                atkbd->set = atkbd_select_set(atkbd, atkbd_set, atkbd_extra);
        atkbd_set_keycode_table(atkbd);
        atkbd_set_device_attrs(atkbd);
  
 -      sysfs_create_group(&serio->dev.kobj, &atkbd_attribute_group);
 +      err = sysfs_create_group(&serio->dev.kobj, &atkbd_attribute_group);
 +      if (err)
 +              goto fail3;
  
        atkbd_enable(atkbd);
  
 -      input_register_device(atkbd->dev);
 +      err = input_register_device(atkbd->dev);
 +      if (err)
 +              goto fail4;
  
        return 0;
  
 - fail:        serio_set_drvdata(serio, NULL);
 -      input_free_device(dev);
 + fail4: sysfs_remove_group(&serio->dev.kobj, &atkbd_attribute_group);
 + fail3:       serio_close(serio);
 + fail2:       serio_set_drvdata(serio, NULL);
 + fail1:       input_free_device(dev);
        kfree(atkbd);
        return err;
  }
@@@ -1138,11 -1133,9 +1138,11 @@@ static ssize_t atkbd_show_extra(struct 
  
  static ssize_t atkbd_set_extra(struct atkbd *atkbd, const char *buf, size_t count)
  {
 -      struct input_dev *new_dev;
 +      struct input_dev *old_dev, *new_dev;
        unsigned long value;
        char *rest;
 +      int err;
 +      unsigned char old_extra, old_set;
  
        if (!atkbd->write)
                return -EIO;
        if (atkbd->extra != value) {
                /*
                 * Since device's properties will change we need to
 -               * unregister old device. But allocate new one first
 -               * to make sure we have it.
 +               * unregister old device. But allocate and register
 +               * new one first to make sure we have it.
                 */
 -              if (!(new_dev = input_allocate_device()))
 +              old_dev = atkbd->dev;
 +              old_extra = atkbd->extra;
 +              old_set = atkbd->set;
 +
 +              new_dev = input_allocate_device();
 +              if (!new_dev)
                        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_keycode_table(atkbd);
                atkbd_set_device_attrs(atkbd);
 -              input_register_device(atkbd->dev);
 +
 +              err = input_register_device(atkbd->dev);
 +              if (err) {
 +                      input_free_device(new_dev);
 +
 +                      atkbd->dev = old_dev;
 +                      atkbd->set = atkbd_select_set(atkbd, old_set, old_extra);
 +                      atkbd_set_keycode_table(atkbd);
 +                      atkbd_set_device_attrs(atkbd);
 +
 +                      return err;
 +              }
 +              input_unregister_device(old_dev);
 +
        }
        return count;
  }
@@@ -1195,41 -1169,23 +1195,41 @@@ static ssize_t atkbd_show_scroll(struc
  
  static ssize_t atkbd_set_scroll(struct atkbd *atkbd, const char *buf, size_t count)
  {
 -      struct input_dev *new_dev;
 +      struct input_dev *old_dev, *new_dev;
        unsigned long value;
        char *rest;
 +      int err;
 +      unsigned char old_scroll;
  
        value = simple_strtoul(buf, &rest, 10);
        if (*rest || value > 1)
                return -EINVAL;
  
        if (atkbd->scroll != value) {
 -              if (!(new_dev = input_allocate_device()))
 +              old_dev = atkbd->dev;
 +              old_scroll = atkbd->scroll;
 +
 +              new_dev = input_allocate_device();
 +              if (!new_dev)
                        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);
 +
 +              err = input_register_device(atkbd->dev);
 +              if (err) {
 +                      input_free_device(new_dev);
 +
 +                      atkbd->scroll = old_scroll;
 +                      atkbd->dev = old_dev;
 +                      atkbd_set_keycode_table(atkbd);
 +                      atkbd_set_device_attrs(atkbd);
 +
 +                      return err;
 +              }
 +              input_unregister_device(old_dev);
        }
        return count;
  }
@@@ -1241,11 -1197,9 +1241,11 @@@ static ssize_t atkbd_show_set(struct at
  
  static ssize_t atkbd_set_set(struct atkbd *atkbd, const char *buf, size_t count)
  {
 -      struct input_dev *new_dev;
 +      struct input_dev *old_dev, *new_dev;
        unsigned long value;
        char *rest;
 +      int err;
 +      unsigned char old_set, old_extra;
  
        if (!atkbd->write)
                return -EIO;
                return -EINVAL;
  
        if (atkbd->set != value) {
 -              if (!(new_dev = input_allocate_device()))
 +              old_dev = atkbd->dev;
 +              old_extra = atkbd->extra;
 +              old_set = atkbd->set;
 +
 +              new_dev = input_allocate_device();
 +              if (!new_dev)
                        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);
 +
 +              err = input_register_device(atkbd->dev);
 +              if (err) {
 +                      input_free_device(new_dev);
 +
 +                      atkbd->dev = old_dev;
 +                      atkbd->set = atkbd_select_set(atkbd, old_set, old_extra);
 +                      atkbd_set_keycode_table(atkbd);
 +                      atkbd_set_device_attrs(atkbd);
 +
 +                      return err;
 +              }
 +              input_unregister_device(old_dev);
        }
        return count;
  }
@@@ -1292,11 -1229,9 +1292,11 @@@ static ssize_t atkbd_show_softrepeat(st
  
  static ssize_t atkbd_set_softrepeat(struct atkbd *atkbd, const char *buf, size_t count)
  {
 -      struct input_dev *new_dev;
 +      struct input_dev *old_dev, *new_dev;
        unsigned long value;
        char *rest;
 +      int err;
 +      unsigned char old_softrepeat, old_softraw;
  
        if (!atkbd->write)
                return -EIO;
                return -EINVAL;
  
        if (atkbd->softrepeat != value) {
 -              if (!(new_dev = input_allocate_device()))
 +              old_dev = atkbd->dev;
 +              old_softrepeat = atkbd->softrepeat;
 +              old_softraw = atkbd->softraw;
 +
 +              new_dev = input_allocate_device();
 +              if (!new_dev)
                        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);
 +
 +              err = input_register_device(atkbd->dev);
 +              if (err) {
 +                      input_free_device(new_dev);
 +
 +                      atkbd->dev = old_dev;
 +                      atkbd->softrepeat = old_softrepeat;
 +                      atkbd->softraw = old_softraw;
 +                      atkbd_set_device_attrs(atkbd);
 +
 +                      return err;
 +              }
 +              input_unregister_device(old_dev);
        }
        return count;
  }
@@@ -1344,39 -1262,22 +1344,39 @@@ static ssize_t atkbd_show_softraw(struc
  
  static ssize_t atkbd_set_softraw(struct atkbd *atkbd, const char *buf, size_t count)
  {
 -      struct input_dev *new_dev;
 +      struct input_dev *old_dev, *new_dev;
        unsigned long value;
        char *rest;
 +      int err;
 +      unsigned char old_softraw;
  
        value = simple_strtoul(buf, &rest, 10);
        if (*rest || value > 1)
                return -EINVAL;
  
        if (atkbd->softraw != value) {
 -              if (!(new_dev = input_allocate_device()))
 +              old_dev = atkbd->dev;
 +              old_softraw = atkbd->softraw;
 +
 +              new_dev = input_allocate_device();
 +              if (!new_dev)
                        return -ENOMEM;
 -              input_unregister_device(atkbd->dev);
 +
                atkbd->dev = new_dev;
                atkbd->softraw = value;
                atkbd_set_device_attrs(atkbd);
 -              input_register_device(atkbd->dev);
 +
 +              err = input_register_device(atkbd->dev);
 +              if (err) {
 +                      input_free_device(new_dev);
 +
 +                      atkbd->dev = old_dev;
 +                      atkbd->softraw = old_softraw;
 +                      atkbd_set_device_attrs(atkbd);
 +
 +                      return err;
 +              }
 +              input_unregister_device(old_dev);
        }
        return count;
  }
@@@ -1389,7 -1290,8 +1389,7 @@@ static ssize_t atkbd_show_err_count(str
  
  static int __init atkbd_init(void)
  {
 -      serio_register_driver(&atkbd_drv);
 -      return 0;
 +      return serio_register_driver(&atkbd_drv);
  }
  
  static void __exit atkbd_exit(void)
index 1789785813ee5c350434845b9611cd5d4d02a62d,b7f049b45b6bffc7fb0230a86afe23b2cf8953dc..3d4d0a0ede28333bb3bc7b12ae24bcd7bd116e2e
   * You should have received a copy of the GNU General Public License
   * along with this program; if not, write to the Free Software
   * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-  *
-  * Should you need to contact me, the author, you can do so either by
-  * email or by paper mail:
-  * Jan-Benedict Glaw, Lilienstraße 16, 33790 Hörste (near Halle/Westf.),
-  * Germany.
   */
  
  #include <linux/delay.h>
@@@ -577,9 -572,9 +572,9 @@@ lkkbd_event (struct input_dev *dev, uns
   * were in.
   */
  static void
- lkkbd_reinit (void *data)
+ lkkbd_reinit (struct work_struct *work)
  {
-       struct lkkbd *lk = data;
+       struct lkkbd *lk = container_of(work, struct lkkbd, tq);
        int division;
        unsigned char leds_on = 0;
        unsigned char leds_off = 0;
@@@ -651,12 -646,12 +646,12 @@@ lkkbd_connect (struct serio *serio, str
        input_dev = input_allocate_device ();
        if (!lk || !input_dev) {
                err = -ENOMEM;
 -              goto fail;
 +              goto fail1;
        }
  
        lk->serio = serio;
        lk->dev = input_dev;
-       INIT_WORK (&lk->tq, lkkbd_reinit, lk);
+       INIT_WORK (&lk->tq, lkkbd_reinit);
        lk->bell_volume = bell_volume;
        lk->keyclick_volume = keyclick_volume;
        lk->ctrlclick_volume = ctrlclick_volume;
  
        err = serio_open (serio, drv);
        if (err)
 -              goto fail;
 +              goto fail2;
 +
 +      err = input_register_device (lk->dev);
 +      if (err)
 +              goto fail3;
  
 -      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);
 + fail3:       serio_close (serio);
 + fail2:       serio_set_drvdata (serio, NULL);
 + fail1:       input_free_device (input_dev);
        kfree (lk);
        return err;
  }
@@@ -758,7 -749,8 +753,7 @@@ static struct serio_driver lkkbd_drv = 
  static int __init
  lkkbd_init (void)
  {
 -      serio_register_driver(&lkkbd_drv);
 -      return 0;
 +      return serio_register_driver(&lkkbd_drv);
  }
  
  static void __exit
index d6ab6d4b1fa87576e9bbce4fec844cd801904595,6cd887c5eb0a1082560d61172e1dc9bef1b7f0e9..3826db9403e633950c941fda8517bfc6b4c009e9
@@@ -208,9 -208,9 +208,9 @@@ static int sunkbd_initialize(struct sun
   * were in.
   */
  
- static void sunkbd_reinit(void *data)
+ static void sunkbd_reinit(struct work_struct *work)
  {
-       struct sunkbd *sunkbd = data;
+       struct sunkbd *sunkbd = container_of(work, struct sunkbd, tq);
  
        wait_event_interruptible_timeout(sunkbd->wait, sunkbd->reset >= 0, HZ);
  
@@@ -243,23 -243,23 +243,23 @@@ static int sunkbd_connect(struct serio 
        sunkbd = kzalloc(sizeof(struct sunkbd), GFP_KERNEL);
        input_dev = input_allocate_device();
        if (!sunkbd || !input_dev)
 -              goto fail;
 +              goto fail1;
  
        sunkbd->serio = serio;
        sunkbd->dev = input_dev;
        init_waitqueue_head(&sunkbd->wait);
-       INIT_WORK(&sunkbd->tq, sunkbd_reinit, sunkbd);
+       INIT_WORK(&sunkbd->tq, sunkbd_reinit);
        snprintf(sunkbd->phys, sizeof(sunkbd->phys), "%s/input0", serio->phys);
  
        serio_set_drvdata(serio, sunkbd);
  
        err = serio_open(serio, drv);
        if (err)
 -              goto fail;
 +              goto fail2;
  
        if (sunkbd_initialize(sunkbd) < 0) {
 -              serio_close(serio);
 -              goto fail;
 +              err = -ENODEV;
 +              goto fail3;
        }
  
        snprintf(sunkbd->name, sizeof(sunkbd->name), "Sun Type %d keyboard", sunkbd->type);
        clear_bit(0, input_dev->keybit);
  
        sunkbd_enable(sunkbd, 1);
 -      input_register_device(sunkbd->dev);
 +
 +      err = input_register_device(sunkbd->dev);
 +      if (err)
 +              goto fail4;
 +
        return 0;
  
 - fail:        serio_set_drvdata(serio, NULL);
 -      input_free_device(input_dev);
 + fail4:       sunkbd_enable(sunkbd, 0);
 + fail3:       serio_close(serio);
 + fail2:       serio_set_drvdata(serio, NULL);
 + fail1:       input_free_device(input_dev);
        kfree(sunkbd);
        return err;
  }
@@@ -352,7 -346,8 +352,7 @@@ static struct serio_driver sunkbd_drv 
  
  static int __init sunkbd_init(void)
  {
 -      serio_register_driver(&sunkbd_drv);
 -      return 0;
 +      return serio_register_driver(&sunkbd_drv);
  }
  
  static void __exit sunkbd_exit(void)
index e626b1e737fa46a076402453c4ad4817d812f961,52bb2226ce2fb9ac816018da35a0a232d050a692..a0e4a033e2db553346e646044a8bf25c298735fb
@@@ -888,9 -888,10 +888,10 @@@ static int psmouse_poll(struct psmouse 
   * psmouse_resync() attempts to re-validate current protocol.
   */
  
- static void psmouse_resync(void *p)
+ static void psmouse_resync(struct work_struct *work)
  {
-       struct psmouse *psmouse = p, *parent = NULL;
+       struct psmouse *parent = NULL, *psmouse =
+               container_of(work, struct psmouse, resync_work);
        struct serio *serio = psmouse->ps2dev.serio;
        psmouse_ret_t rc = PSMOUSE_GOOD_DATA;
        int failed = 0, enabled = 0;
@@@ -1102,7 -1103,7 +1103,7 @@@ static int psmouse_connect(struct seri
  {
        struct psmouse *psmouse, *parent = NULL;
        struct input_dev *input_dev;
 -      int retval = -ENOMEM;
 +      int retval = 0, error = -ENOMEM;
  
        mutex_lock(&psmouse_mutex);
  
        psmouse = kzalloc(sizeof(struct psmouse), GFP_KERNEL);
        input_dev = input_allocate_device();
        if (!psmouse || !input_dev)
 -              goto out;
 +              goto err_free;
  
        ps2_init(&psmouse->ps2dev, serio);
-       INIT_WORK(&psmouse->resync_work, psmouse_resync, psmouse);
+       INIT_WORK(&psmouse->resync_work, psmouse_resync);
        psmouse->dev = input_dev;
        snprintf(psmouse->phys, sizeof(psmouse->phys), "%s/input0", serio->phys);
  
  
        serio_set_drvdata(serio, psmouse);
  
 -      retval = serio_open(serio, drv);
 -      if (retval)
 -              goto out;
 +      error = serio_open(serio, drv);
 +      if (error)
 +              goto err_clear_drvdata;
  
        if (psmouse_probe(psmouse) < 0) {
 -              serio_close(serio);
 -              retval = -ENODEV;
 -              goto out;
 +              error = -ENODEV;
 +              goto err_close_serio;
        }
  
        psmouse->rate = psmouse_rate;
        psmouse_set_state(psmouse, PSMOUSE_CMD_MODE);
        psmouse_initialize(psmouse);
  
 -      input_register_device(psmouse->dev);
 +      error = input_register_device(psmouse->dev);
 +      if (error)
 +              goto err_protocol_disconnect;
  
        if (parent && parent->pt_activate)
                parent->pt_activate(parent);
  
 -      sysfs_create_group(&serio->dev.kobj, &psmouse_attribute_group);
 +      error = sysfs_create_group(&serio->dev.kobj, &psmouse_attribute_group);
 +      if (error)
 +              goto err_pt_deactivate;
  
        psmouse_activate(psmouse);
  
 -      retval = 0;
 -
 -out:
 -      if (retval) {
 -              serio_set_drvdata(serio, NULL);
 -              input_free_device(input_dev);
 -              kfree(psmouse);
 -      }
 -
 + out:
        /* If this is a pass-through port the parent needs to be re-activated */
        if (parent)
                psmouse_activate(parent);
  
        mutex_unlock(&psmouse_mutex);
        return retval;
 +
 + err_pt_deactivate:
 +      if (parent && parent->pt_deactivate)
 +              parent->pt_deactivate(parent);
 + err_protocol_disconnect:
 +      if (psmouse->disconnect)
 +              psmouse->disconnect(psmouse);
 +      psmouse_set_state(psmouse, PSMOUSE_IGNORE);
 + err_close_serio:
 +      serio_close(serio);
 + err_clear_drvdata:
 +      serio_set_drvdata(serio, NULL);
 + err_free:
 +      input_free_device(input_dev);
 +      kfree(psmouse);
 +
 +      retval = error;
 +      goto out;
  }
  
  
@@@ -1349,14 -1337,14 +1350,14 @@@ ssize_t psmouse_attr_set_helper(struct 
  
  static ssize_t psmouse_show_int_attr(struct psmouse *psmouse, void *offset, char *buf)
  {
 -      unsigned long *field = (unsigned long *)((char *)psmouse + (size_t)offset);
 +      unsigned int *field = (unsigned int *)((char *)psmouse + (size_t)offset);
  
 -      return sprintf(buf, "%lu\n", *field);
 +      return sprintf(buf, "%u\n", *field);
  }
  
  static ssize_t psmouse_set_int_attr(struct psmouse *psmouse, void *offset, const char *buf, size_t count)
  {
 -      unsigned long *field = (unsigned long *)((char *)psmouse + (size_t)offset);
 +      unsigned int *field = (unsigned int *)((char *)psmouse + (size_t)offset);
        unsigned long value;
        char *rest;
  
        if (*rest)
                return -EINVAL;
  
 +      if ((unsigned int)value != value)
 +              return -EINVAL;
 +
        *field = value;
  
        return count;
@@@ -1381,20 -1366,17 +1382,20 @@@ static ssize_t psmouse_attr_set_protoco
  {
        struct serio *serio = psmouse->ps2dev.serio;
        struct psmouse *parent = NULL;
 -      struct input_dev *new_dev;
 -      const struct psmouse_protocol *proto;
 +      struct input_dev *old_dev, *new_dev;
 +      const struct psmouse_protocol *proto, *old_proto;
 +      int error;
        int retry = 0;
  
 -      if (!(proto = psmouse_protocol_by_name(buf, count)))
 +      proto = psmouse_protocol_by_name(buf, count);
 +      if (!proto)
                return -EINVAL;
  
        if (psmouse->type == proto->type)
                return count;
  
 -      if (!(new_dev = input_allocate_device()))
 +      new_dev = input_allocate_device();
 +      if (!new_dev)
                return -ENOMEM;
  
        while (serio->child) {
                        parent->pt_deactivate(parent);
        }
  
 +      old_dev = psmouse->dev;
 +      old_proto = psmouse_protocol_by_type(psmouse->type);
 +
        if (psmouse->disconnect)
                psmouse->disconnect(psmouse);
  
        psmouse_set_state(psmouse, PSMOUSE_IGNORE);
 -      input_unregister_device(psmouse->dev);
  
        psmouse->dev = new_dev;
        psmouse_set_state(psmouse, PSMOUSE_INITIALIZING);
        psmouse_initialize(psmouse);
        psmouse_set_state(psmouse, PSMOUSE_CMD_MODE);
  
 -      input_register_device(psmouse->dev);
 +      error = input_register_device(psmouse->dev);
 +      if (error) {
 +              if (psmouse->disconnect)
 +                      psmouse->disconnect(psmouse);
 +
 +              psmouse_set_state(psmouse, PSMOUSE_IGNORE);
 +              input_free_device(new_dev);
 +              psmouse->dev = old_dev;
 +              psmouse_set_state(psmouse, PSMOUSE_INITIALIZING);
 +              psmouse_switch_protocol(psmouse, old_proto);
 +              psmouse_initialize(psmouse);
 +              psmouse_set_state(psmouse, PSMOUSE_CMD_MODE);
 +
 +              return error;
 +      }
 +
 +      input_unregister_device(old_dev);
  
        if (parent && parent->pt_activate)
                parent->pt_activate(parent);
@@@ -1524,19 -1488,15 +1525,19 @@@ static int psmouse_get_maxproto(char *b
  
  static int __init psmouse_init(void)
  {
 +      int err;
 +
        kpsmoused_wq = create_singlethread_workqueue("kpsmoused");
        if (!kpsmoused_wq) {
                printk(KERN_ERR "psmouse: failed to create kpsmoused workqueue\n");
                return -ENOMEM;
        }
  
 -      serio_register_driver(&psmouse_drv);
 +      err = serio_register_driver(&psmouse_drv);
 +      if (err)
 +              destroy_workqueue(kpsmoused_wq);
  
 -      return 0;
 +      return err;
  }
  
  static void __exit psmouse_exit(void)
index 8c717042f6113bce589ab5f9f5fb47cf181f05a9,5f1d4032fd57fbddc4faf65635b416c9a8daf74f..f0ce822c1028741efabecf0cef37e1e356754eb5
@@@ -35,6 -35,7 +35,7 @@@
  #include <linux/slab.h>
  #include <linux/kthread.h>
  #include <linux/mutex.h>
+ #include <linux/freezer.h>
  
  MODULE_AUTHOR("Vojtech Pavlik <vojtech@ucw.cz>");
  MODULE_DESCRIPTION("Serio abstraction core");
@@@ -44,7 -45,8 +45,7 @@@ EXPORT_SYMBOL(serio_interrupt)
  EXPORT_SYMBOL(__serio_register_port);
  EXPORT_SYMBOL(serio_unregister_port);
  EXPORT_SYMBOL(serio_unregister_child_port);
 -EXPORT_SYMBOL(__serio_unregister_port_delayed);
 -EXPORT_SYMBOL(__serio_register_driver);
 +EXPORT_SYMBOL(serio_register_driver);
  EXPORT_SYMBOL(serio_unregister_driver);
  EXPORT_SYMBOL(serio_open);
  EXPORT_SYMBOL(serio_close);
@@@ -61,10 -63,11 +62,10 @@@ static LIST_HEAD(serio_list)
  
  static struct bus_type serio_bus;
  
 -static void serio_add_driver(struct serio_driver *drv);
  static void serio_add_port(struct serio *serio);
 -static void serio_destroy_port(struct serio *serio);
  static void serio_reconnect_port(struct serio *serio);
  static void serio_disconnect_port(struct serio *serio);
 +static void serio_attach_driver(struct serio_driver *drv);
  
  static int serio_connect_driver(struct serio *serio, struct serio_driver *drv)
  {
@@@ -168,10 -171,11 +169,10 @@@ static void serio_find_driver(struct se
   */
  
  enum serio_event_type {
 -      SERIO_RESCAN,
 -      SERIO_RECONNECT,
 +      SERIO_RESCAN_PORT,
 +      SERIO_RECONNECT_PORT,
        SERIO_REGISTER_PORT,
 -      SERIO_UNREGISTER_PORT,
 -      SERIO_REGISTER_DRIVER,
 +      SERIO_ATTACH_DRIVER,
  };
  
  struct serio_event {
@@@ -186,12 -190,11 +187,12 @@@ static LIST_HEAD(serio_event_list)
  static DECLARE_WAIT_QUEUE_HEAD(serio_wait);
  static struct task_struct *serio_task;
  
 -static void serio_queue_event(void *object, struct module *owner,
 -                            enum serio_event_type event_type)
 +static int serio_queue_event(void *object, struct module *owner,
 +                           enum serio_event_type event_type)
  {
        unsigned long flags;
        struct serio_event *event;
 +      int retval = 0;
  
        spin_lock_irqsave(&serio_event_lock, flags);
  
                }
        }
  
 -      if ((event = kmalloc(sizeof(struct serio_event), GFP_ATOMIC))) {
 -              if (!try_module_get(owner)) {
 -                      printk(KERN_WARNING "serio: Can't get module reference, dropping event %d\n", event_type);
 -                      kfree(event);
 -                      goto out;
 -              }
 -
 -              event->type = event_type;
 -              event->object = object;
 -              event->owner = owner;
 +      event = kmalloc(sizeof(struct serio_event), GFP_ATOMIC);
 +      if (!event) {
 +              printk(KERN_ERR
 +                      "serio: Not enough memory to queue event %d\n",
 +                      event_type);
 +              retval = -ENOMEM;
 +              goto out;
 +      }
  
 -              list_add_tail(&event->node, &serio_event_list);
 -              wake_up(&serio_wait);
 -      } else {
 -              printk(KERN_ERR "serio: Not enough memory to queue event %d\n", event_type);
 +      if (!try_module_get(owner)) {
 +              printk(KERN_WARNING
 +                      "serio: Can't get module reference, dropping event %d\n",
 +                      event_type);
 +              kfree(event);
 +              retval = -EINVAL;
 +              goto out;
        }
 +
 +      event->type = event_type;
 +      event->object = object;
 +      event->owner = owner;
 +
 +      list_add_tail(&event->node, &serio_event_list);
 +      wake_up(&serio_wait);
 +
  out:
        spin_unlock_irqrestore(&serio_event_lock, flags);
 +      return retval;
  }
  
  static void serio_free_event(struct serio_event *event)
@@@ -315,17 -308,22 +316,17 @@@ static void serio_handle_event(void
                                serio_add_port(event->object);
                                break;
  
 -                      case SERIO_UNREGISTER_PORT:
 -                              serio_disconnect_port(event->object);
 -                              serio_destroy_port(event->object);
 -                              break;
 -
 -                      case SERIO_RECONNECT:
 +                      case SERIO_RECONNECT_PORT:
                                serio_reconnect_port(event->object);
                                break;
  
 -                      case SERIO_RESCAN:
 +                      case SERIO_RESCAN_PORT:
                                serio_disconnect_port(event->object);
                                serio_find_driver(event->object);
                                break;
  
 -                      case SERIO_REGISTER_DRIVER:
 -                              serio_add_driver(event->object);
 +                      case SERIO_ATTACH_DRIVER:
 +                              serio_attach_driver(event->object);
                                break;
  
                        default:
@@@ -677,12 -675,12 +678,12 @@@ static void serio_disconnect_port(struc
  
  void serio_rescan(struct serio *serio)
  {
 -      serio_queue_event(serio, NULL, SERIO_RESCAN);
 +      serio_queue_event(serio, NULL, SERIO_RESCAN_PORT);
  }
  
  void serio_reconnect(struct serio *serio)
  {
 -      serio_queue_event(serio, NULL, SERIO_RECONNECT);
 +      serio_queue_event(serio, NULL, SERIO_RECONNECT_PORT);
  }
  
  /*
@@@ -719,6 -717,16 +720,6 @@@ void serio_unregister_child_port(struc
        mutex_unlock(&serio_mutex);
  }
  
 -/*
 - * Submits register request to kseriod for subsequent execution.
 - * Can be used when it is not obvious whether the serio_mutex is
 - * taken or not and when delayed execution is feasible.
 - */
 -void __serio_unregister_port_delayed(struct serio *serio, struct module *owner)
 -{
 -      serio_queue_event(serio, owner, SERIO_UNREGISTER_PORT);
 -}
 -
  
  /*
   * Serio driver operations
@@@ -777,52 -785,28 +778,52 @@@ static int serio_driver_remove(struct d
        return 0;
  }
  
 -static struct bus_type serio_bus = {
 -      .name = "serio",
 -      .probe = serio_driver_probe,
 -      .remove = serio_driver_remove,
 -};
 -
 -static void serio_add_driver(struct serio_driver *drv)
 +static void serio_attach_driver(struct serio_driver *drv)
  {
        int error;
  
 -      error = driver_register(&drv->driver);
 +      error = driver_attach(&drv->driver);
        if (error)
 -              printk(KERN_ERR
 -                      "serio: driver_register() failed for %s, error: %d\n",
 +              printk(KERN_WARNING
 +                      "serio: driver_attach() failed for %s with error %d\n",
                        drv->driver.name, error);
  }
  
 -void __serio_register_driver(struct serio_driver *drv, struct module *owner)
 +int serio_register_driver(struct serio_driver *drv)
  {
 +      int manual_bind = drv->manual_bind;
 +      int error;
 +
        drv->driver.bus = &serio_bus;
  
 -      serio_queue_event(drv, owner, SERIO_REGISTER_DRIVER);
 +      /*
 +       * Temporarily disable automatic binding because probing
 +       * takes long time and we are better off doing it in kseriod
 +       */
 +      drv->manual_bind = 1;
 +
 +      error = driver_register(&drv->driver);
 +      if (error) {
 +              printk(KERN_ERR
 +                      "serio: driver_register() failed for %s, error: %d\n",
 +                      drv->driver.name, error);
 +              return error;
 +      }
 +
 +      /*
 +       * Restore original bind mode and let kseriod bind the
 +       * driver to free ports
 +       */
 +      if (!manual_bind) {
 +              drv->manual_bind = 0;
 +              error = serio_queue_event(drv, NULL, SERIO_ATTACH_DRIVER);
 +              if (error) {
 +                      driver_unregister(&drv->driver);
 +                      return error;
 +              }
 +      }
 +
 +      return 0;
  }
  
  void serio_unregister_driver(struct serio_driver *drv)
@@@ -963,21 -947,15 +964,21 @@@ irqreturn_t serio_interrupt(struct seri
        return ret;
  }
  
 +static struct bus_type serio_bus = {
 +      .name           = "serio",
 +      .dev_attrs      = serio_device_attrs,
 +      .drv_attrs      = serio_driver_attrs,
 +      .match          = serio_bus_match,
 +      .uevent         = serio_uevent,
 +      .probe          = serio_driver_probe,
 +      .remove         = serio_driver_remove,
 +      .resume         = serio_resume,
 +};
 +
  static int __init serio_init(void)
  {
        int error;
  
 -      serio_bus.dev_attrs = serio_device_attrs;
 -      serio_bus.drv_attrs = serio_driver_attrs;
 -      serio_bus.match = serio_bus_match;
 -      serio_bus.uevent = serio_uevent;
 -      serio_bus.resume = serio_resume;
        error = bus_register(&serio_bus);
        if (error) {
                printk(KERN_ERR "serio: failed to register serio bus, error: %d\n", error);
index 0e343a6cacc9b82a9d4ebbca8f1bdbbfb28b279b,7c8d0399ae820ae6996f888f07910126bc3607f6..088ebc348ba31da45ddefa6b10a51aabf168185f
@@@ -297,7 -297,7 +297,7 @@@ static int serio_raw_connect(struct ser
  
        serio_raw->dev.minor = PSMOUSE_MINOR;
        serio_raw->dev.name = serio_raw->name;
-       serio_raw->dev.dev = &serio->dev;
+       serio_raw->dev.parent = &serio->dev;
        serio_raw->dev.fops = &serio_raw_fops;
  
        err = misc_register(&serio_raw->dev);
@@@ -389,7 -389,8 +389,7 @@@ static struct serio_driver serio_raw_dr
  
  static int __init serio_raw_init(void)
  {
 -      serio_register_driver(&serio_raw_drv);
 -      return 0;
 +      return serio_register_driver(&serio_raw_drv);
  }
  
  static void __exit serio_raw_exit(void)
index 8f56af8cd7a093643ab8c594656f2edbf7561ee4,0517c7387d67511593f07a40b67146eb51801760..c6164b6f476a3ecb5fde27af07ddd05c38557d01
@@@ -76,7 -76,6 +76,7 @@@ struct ads7846 
        char                    phys[32];
  
        struct spi_device       *spi;
 +      struct attribute_group  *attr_group;
        u16                     model;
        u16                     vref_delay_usecs;
        u16                     x_plate_ohms;
@@@ -190,7 -189,7 +190,7 @@@ static int ads7846_read12_ser(struct de
  {
        struct spi_device       *spi = to_spi_device(dev);
        struct ads7846          *ts = dev_get_drvdata(dev);
-       struct ser_req          *req = kzalloc(sizeof *req, SLAB_KERNEL);
+       struct ser_req          *req = kzalloc(sizeof *req, GFP_KERNEL);
        int                     status;
        int                     sample;
        int                     i;
@@@ -318,48 -317,6 +318,48 @@@ static ssize_t ads7846_disable_store(st
  
  static DEVICE_ATTR(disable, 0664, ads7846_disable_show, ads7846_disable_store);
  
 +static struct attribute *ads7846_attributes[] = {
 +      &dev_attr_temp0.attr,
 +      &dev_attr_temp1.attr,
 +      &dev_attr_vbatt.attr,
 +      &dev_attr_vaux.attr,
 +      &dev_attr_pen_down.attr,
 +      &dev_attr_disable.attr,
 +      NULL,
 +};
 +
 +static struct attribute_group ads7846_attr_group = {
 +      .attrs = ads7846_attributes,
 +};
 +
 +/*
 + * ads7843/7845 don't have temperature sensors, and
 + * use the other sensors a bit differently too
 + */
 +
 +static struct attribute *ads7843_attributes[] = {
 +      &dev_attr_vbatt.attr,
 +      &dev_attr_vaux.attr,
 +      &dev_attr_pen_down.attr,
 +      &dev_attr_disable.attr,
 +      NULL,
 +};
 +
 +static struct attribute_group ads7843_attr_group = {
 +      .attrs = ads7843_attributes,
 +};
 +
 +static struct attribute *ads7845_attributes[] = {
 +      &dev_attr_vaux.attr,
 +      &dev_attr_pen_down.attr,
 +      &dev_attr_disable.attr,
 +      NULL,
 +};
 +
 +static struct attribute_group ads7845_attr_group = {
 +      .attrs = ads7845_attributes,
 +};
 +
  /*--------------------------------------------------------------------------*/
  
  /*
@@@ -831,30 -788,38 +831,30 @@@ static int __devinit ads7846_probe(stru
        (void) ads7846_read12_ser(&spi->dev,
                          READ_12BIT_SER(vaux) | ADS_PD10_ALL_ON);
  
 -      /* ads7843/7845 don't have temperature sensors, and
 -       * use the other sensors a bit differently too
 -       */
 -      if (ts->model == 7846) {
 -              device_create_file(&spi->dev, &dev_attr_temp0);
 -              device_create_file(&spi->dev, &dev_attr_temp1);
 +      switch (ts->model) {
 +      case 7846:
 +              ts->attr_group = &ads7846_attr_group;
 +              break;
 +      case 7845:
 +              ts->attr_group = &ads7845_attr_group;
 +              break;
 +      default:
 +              ts->attr_group = &ads7843_attr_group;
 +              break;
        }
 -      if (ts->model != 7845)
 -              device_create_file(&spi->dev, &dev_attr_vbatt);
 -      device_create_file(&spi->dev, &dev_attr_vaux);
 -
 -      device_create_file(&spi->dev, &dev_attr_pen_down);
 -
 -      device_create_file(&spi->dev, &dev_attr_disable);
 +      err = sysfs_create_group(&spi->dev.kobj, ts->attr_group);
 +      if (err)
 +              goto err_free_irq;
  
        err = input_register_device(input_dev);
        if (err)
 -              goto err_remove_attr;
 +              goto err_remove_attr_group;
  
        return 0;
  
 - err_remove_attr:
 -      device_remove_file(&spi->dev, &dev_attr_disable);
 -      device_remove_file(&spi->dev, &dev_attr_pen_down);
 -      if (ts->model == 7846) {
 -              device_remove_file(&spi->dev, &dev_attr_temp1);
 -              device_remove_file(&spi->dev, &dev_attr_temp0);
 -      }
 -      if (ts->model != 7845)
 -              device_remove_file(&spi->dev, &dev_attr_vbatt);
 -      device_remove_file(&spi->dev, &dev_attr_vaux);
 -
 + err_remove_attr_group:
 +      sysfs_remove_group(&spi->dev.kobj, ts->attr_group);
 + err_free_irq:
        free_irq(spi->irq, ts);
   err_free_mem:
        input_free_device(input_dev);
@@@ -870,7 -835,15 +870,7 @@@ static int __devexit ads7846_remove(str
  
        ads7846_suspend(spi, PMSG_SUSPEND);
  
 -      device_remove_file(&spi->dev, &dev_attr_disable);
 -      device_remove_file(&spi->dev, &dev_attr_pen_down);
 -      if (ts->model == 7846) {
 -              device_remove_file(&spi->dev, &dev_attr_temp1);
 -              device_remove_file(&spi->dev, &dev_attr_temp0);
 -      }
 -      if (ts->model != 7845)
 -              device_remove_file(&spi->dev, &dev_attr_vbatt);
 -      device_remove_file(&spi->dev, &dev_attr_vaux);
 +      sysfs_remove_group(&spi->dev.kobj, ts->attr_group);
  
        free_irq(ts->spi->irq, ts);
        /* suspend left the IRQ disabled */
index 31015d55d3536510c0ae2f75c3584caccf037968,92ccee85e2a20fe30ab9fbe20ed64c8217ddccf9..a9e747c3979131179d6304755c693c815a2661f0
@@@ -162,6 -162,7 +162,6 @@@ config INPUT_ADBHI
  
  config MAC_EMUMOUSEBTN
        bool "Support for mouse button 2+3 emulation"
 -      depends on INPUT_ADBHID
        help
          This provides generic support for emulating the 2nd and 3rd mouse
          button with keypresses.  If you say Y here, the emulation is still
@@@ -227,4 -228,11 +227,11 @@@ config ANSLC
        tristate "Support for ANS LCD display"
        depends on ADB_CUDA && PPC_PMAC
  
+ config PMAC_RACKMETER
+       tristate "Support for Apple XServe front panel LEDs"
+       depends on PPC_PMAC
+       help
+         This driver procides some support to control the front panel
+           blue LEDs "vu-meter" of the XServer macs.
  endmenu
index 6095d9cedb7ee770dd88815b74158a6e59e25afe,f1d0e1d69828d4db297f22086001a1ee86662445..0811c39bd14f785900defc5787119f8f47e5bef5
@@@ -968,20 -968,30 +968,30 @@@ static void hid_retry_timeout(unsigned 
                hid_io_error(hid);
  }
  
- /* Workqueue routine to reset the device */
- static void hid_reset(void *_hid)
+ /* Workqueue routine to reset the device or clear a halt */
+ static void hid_reset(struct work_struct *work)
  {
-       struct hid_device *hid = (struct hid_device *) _hid;
-       int rc_lock, rc;
-       dev_dbg(&hid->intf->dev, "resetting device\n");
-       rc = rc_lock = usb_lock_device_for_reset(hid->dev, hid->intf);
-       if (rc_lock >= 0) {
-               rc = usb_reset_composite_device(hid->dev, hid->intf);
-               if (rc_lock)
-                       usb_unlock_device(hid->dev);
+       struct hid_device *hid =
+               container_of(work, struct hid_device, reset_work);
+       int rc_lock, rc = 0;
+       if (test_bit(HID_CLEAR_HALT, &hid->iofl)) {
+               dev_dbg(&hid->intf->dev, "clear halt\n");
+               rc = usb_clear_halt(hid->dev, hid->urbin->pipe);
+               clear_bit(HID_CLEAR_HALT, &hid->iofl);
+               hid_start_in(hid);
+       }
+       else if (test_bit(HID_RESET_PENDING, &hid->iofl)) {
+               dev_dbg(&hid->intf->dev, "resetting device\n");
+               rc = rc_lock = usb_lock_device_for_reset(hid->dev, hid->intf);
+               if (rc_lock >= 0) {
+                       rc = usb_reset_composite_device(hid->dev, hid->intf);
+                       if (rc_lock)
+                               usb_unlock_device(hid->dev);
+               }
+               clear_bit(HID_RESET_PENDING, &hid->iofl);
        }
-       clear_bit(HID_RESET_PENDING, &hid->iofl);
  
        switch (rc) {
        case 0:
@@@ -1023,9 -1033,8 +1033,8 @@@ static void hid_io_error(struct hid_dev
  
                /* Retries failed, so do a port reset */
                if (!test_and_set_bit(HID_RESET_PENDING, &hid->iofl)) {
-                       if (schedule_work(&hid->reset_work))
-                               goto done;
-                       clear_bit(HID_RESET_PENDING, &hid->iofl);
+                       schedule_work(&hid->reset_work);
+                       goto done;
                }
        }
  
@@@ -1049,6 -1058,11 +1058,11 @@@ static void hid_irq_in(struct urb *urb
                        hid->retry_delay = 0;
                        hid_input_report(HID_INPUT_REPORT, urb, 1);
                        break;
+               case -EPIPE:            /* stall */
+                       clear_bit(HID_IN_RUNNING, &hid->iofl);
+                       set_bit(HID_CLEAR_HALT, &hid->iofl);
+                       schedule_work(&hid->reset_work);
+                       return;
                case -ECONNRESET:       /* unlink */
                case -ENOENT:
                case -ESHUTDOWN:        /* unplug */
                        warn("input irq status %d received", urb->status);
        }
  
-       status = usb_submit_urb(urb, SLAB_ATOMIC);
+       status = usb_submit_urb(urb, GFP_ATOMIC);
        if (status) {
                clear_bit(HID_IN_RUNNING, &hid->iofl);
                if (status != -EPERM) {
@@@ -1627,6 -1641,19 +1641,19 @@@ void hid_init_reports(struct hid_devic
  
  #define USB_VENDOR_ID_APPLE           0x05ac
  #define USB_DEVICE_ID_APPLE_MIGHTYMOUSE       0x0304
+ #define USB_DEVICE_ID_APPLE_FOUNTAIN_ANSI     0x020e
+ #define USB_DEVICE_ID_APPLE_FOUNTAIN_ISO      0x020f
+ #define USB_DEVICE_ID_APPLE_GEYSER_ANSI       0x0214
+ #define USB_DEVICE_ID_APPLE_GEYSER_ISO        0x0215
+ #define USB_DEVICE_ID_APPLE_GEYSER_JIS        0x0216
+ #define USB_DEVICE_ID_APPLE_GEYSER3_ANSI      0x0217
+ #define USB_DEVICE_ID_APPLE_GEYSER3_ISO       0x0218
+ #define USB_DEVICE_ID_APPLE_GEYSER3_JIS       0x0219
+ #define USB_DEVICE_ID_APPLE_GEYSER4_ANSI      0x021a
+ #define USB_DEVICE_ID_APPLE_GEYSER4_ISO       0x021b
+ #define USB_DEVICE_ID_APPLE_GEYSER4_JIS       0x021c
+ #define USB_DEVICE_ID_APPLE_FOUNTAIN_TP_ONLY  0x030a
+ #define USB_DEVICE_ID_APPLE_GEYSER1_TP_ONLY   0x030b
  
  #define USB_VENDOR_ID_CHERRY          0x046a
  #define USB_DEVICE_ID_CHERRY_CYMOTION 0x0023
  #define USB_VENDOR_ID_AIRCABLE                0x16CA
  #define USB_DEVICE_ID_AIRCABLE1               0x1502
  
 +#define USB_VENDOR_ID_LOGITECH                0x046d
 +#define USB_DEVICE_ID_LOGITECH_USB_RECEIVER   0xc101
 +
  /*
   * Alphabetically sorted blacklist by quirk type.
   */
@@@ -1797,16 -1821,19 +1824,19 @@@ static const struct hid_blacklist 
  
        { USB_VENDOR_ID_CHERRY, USB_DEVICE_ID_CHERRY_CYMOTION, HID_QUIRK_CYMOTION },
  
-       { USB_VENDOR_ID_APPLE, 0x020E, HID_QUIRK_POWERBOOK_HAS_FN },
-       { USB_VENDOR_ID_APPLE, 0x020F, HID_QUIRK_POWERBOOK_HAS_FN },
-       { USB_VENDOR_ID_APPLE, 0x0214, HID_QUIRK_POWERBOOK_HAS_FN },
-       { USB_VENDOR_ID_APPLE, 0x0215, HID_QUIRK_POWERBOOK_HAS_FN },
-       { USB_VENDOR_ID_APPLE, 0x0216, HID_QUIRK_POWERBOOK_HAS_FN },
-       { USB_VENDOR_ID_APPLE, 0x0217, HID_QUIRK_POWERBOOK_HAS_FN },
-       { USB_VENDOR_ID_APPLE, 0x0218, HID_QUIRK_POWERBOOK_HAS_FN },
-       { USB_VENDOR_ID_APPLE, 0x0219, HID_QUIRK_POWERBOOK_HAS_FN },
-       { USB_VENDOR_ID_APPLE, 0x030A, HID_QUIRK_POWERBOOK_HAS_FN },
-       { USB_VENDOR_ID_APPLE, 0x030B, HID_QUIRK_POWERBOOK_HAS_FN },
+       { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_ANSI, HID_QUIRK_POWERBOOK_HAS_FN },
+       { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_ISO, HID_QUIRK_POWERBOOK_HAS_FN },
+       { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER_ANSI, HID_QUIRK_POWERBOOK_HAS_FN },
+       { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER_ISO, HID_QUIRK_POWERBOOK_HAS_FN | HID_QUIRK_POWERBOOK_ISO_KEYBOARD},
+       { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER_JIS, HID_QUIRK_POWERBOOK_HAS_FN },
+       { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER3_ANSI, HID_QUIRK_POWERBOOK_HAS_FN },
+       { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER3_ISO, HID_QUIRK_POWERBOOK_HAS_FN | HID_QUIRK_POWERBOOK_ISO_KEYBOARD},
+       { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER3_JIS, HID_QUIRK_POWERBOOK_HAS_FN },
+       { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_ANSI, HID_QUIRK_POWERBOOK_HAS_FN },
+       { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_ISO, HID_QUIRK_POWERBOOK_HAS_FN },
+       { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_JIS, HID_QUIRK_POWERBOOK_HAS_FN },
+       { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_TP_ONLY, HID_QUIRK_POWERBOOK_HAS_FN },
+       { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER1_TP_ONLY, HID_QUIRK_POWERBOOK_HAS_FN },
  
        { USB_VENDOR_ID_PANJIT, 0x0001, HID_QUIRK_IGNORE },
        { USB_VENDOR_ID_PANJIT, 0x0002, HID_QUIRK_IGNORE },
        { USB_VENDOR_ID_PANJIT, 0x0004, HID_QUIRK_IGNORE },
  
        { USB_VENDOR_ID_TURBOX, USB_DEVICE_ID_TURBOX_KEYBOARD, HID_QUIRK_NOGET },
 -      
 +
 +      { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_USB_RECEIVER, HID_QUIRK_BAD_RELATIVE_KEYS },
 +
        { 0, 0 }
  };
  
@@@ -1839,13 -1864,13 +1869,13 @@@ static void hid_find_max_report(struct 
  
  static int hid_alloc_buffers(struct usb_device *dev, struct hid_device *hid)
  {
-       if (!(hid->inbuf = usb_buffer_alloc(dev, hid->bufsize, SLAB_ATOMIC, &hid->inbuf_dma)))
+       if (!(hid->inbuf = usb_buffer_alloc(dev, hid->bufsize, GFP_ATOMIC, &hid->inbuf_dma)))
                return -1;
-       if (!(hid->outbuf = usb_buffer_alloc(dev, hid->bufsize, SLAB_ATOMIC, &hid->outbuf_dma)))
+       if (!(hid->outbuf = usb_buffer_alloc(dev, hid->bufsize, GFP_ATOMIC, &hid->outbuf_dma)))
                return -1;
-       if (!(hid->cr = usb_buffer_alloc(dev, sizeof(*(hid->cr)), SLAB_ATOMIC, &hid->cr_dma)))
+       if (!(hid->cr = usb_buffer_alloc(dev, sizeof(*(hid->cr)), GFP_ATOMIC, &hid->cr_dma)))
                return -1;
-       if (!(hid->ctrlbuf = usb_buffer_alloc(dev, hid->bufsize, SLAB_ATOMIC, &hid->ctrlbuf_dma)))
+       if (!(hid->ctrlbuf = usb_buffer_alloc(dev, hid->bufsize, GFP_ATOMIC, &hid->ctrlbuf_dma)))
                return -1;
  
        return 0;
@@@ -1989,7 -2014,7 +2019,7 @@@ static struct hid_device *usb_hid_confi
                if (hid->collection->usage == HID_GD_MOUSE && hid_mousepoll_interval > 0)
                        interval = hid_mousepoll_interval;
  
-               if (endpoint->bEndpointAddress & USB_DIR_IN) {
+               if (usb_endpoint_dir_in(endpoint)) {
                        if (hid->urbin)
                                continue;
                        if (!(hid->urbin = usb_alloc_urb(0, GFP_KERNEL)))
  
        init_waitqueue_head(&hid->wait);
  
-       INIT_WORK(&hid->reset_work, hid_reset, hid);
+       INIT_WORK(&hid->reset_work, hid_reset);
        setup_timer(&hid->io_retry, hid_retry_timeout, (unsigned long) hid);
  
        spin_lock_init(&hid->inlock);
        return hid;
  
  fail:
-       if (hid->urbin)
-               usb_free_urb(hid->urbin);
-       if (hid->urbout)
-               usb_free_urb(hid->urbout);
-       if (hid->urbctrl)
-               usb_free_urb(hid->urbctrl);
+       usb_free_urb(hid->urbin);
+       usb_free_urb(hid->urbout);
+       usb_free_urb(hid->urbctrl);
        hid_free_buffers(dev, hid);
        hid_free_device(hid);
  
@@@ -2108,8 -2129,7 +2134,7 @@@ static void hid_disconnect(struct usb_i
  
        usb_free_urb(hid->urbin);
        usb_free_urb(hid->urbctrl);
-       if (hid->urbout)
-               usb_free_urb(hid->urbout);
+       usb_free_urb(hid->urbout);
  
        hid_free_buffers(hid->dev, hid);
        hid_free_device(hid);
index c8ce65c70a42b876959c6df2284c1c9efaaf14a1,68e7ebb978a9721c0eb13ce6d0d4710c00d78c42..3a7e5fbff025f20a6cbad8a1594476bebb24d7c4
@@@ -121,6 -121,12 +121,12 @@@ static struct hidinput_key_translation 
        { }
  };
  
+ static struct hidinput_key_translation powerbook_iso_keyboard[] = {
+       { KEY_GRAVE,    KEY_102ND },
+       { KEY_102ND,    KEY_GRAVE },
+       { }
+ };
  static int usbhid_pb_fnmode = 1;
  module_param_named(pb_fnmode, usbhid_pb_fnmode, int, 0644);
  MODULE_PARM_DESC(pb_fnmode,
@@@ -195,6 -201,14 +201,14 @@@ static int hidinput_pb_event(struct hid
                }
        }
  
+       if (hid->quirks & HID_QUIRK_POWERBOOK_ISO_KEYBOARD) {
+               trans = find_translation(powerbook_iso_keyboard, usage->code);
+               if (trans) {
+                       input_event(input, usage->type, trans->to, value);
+                       return 1;
+               }
+       }
        return 0;
  }
  
@@@ -210,6 -224,9 +224,9 @@@ static void hidinput_pb_setup(struct in
  
        for (trans = powerbook_numlock_keys; trans->from; trans++)
                set_bit(trans->to, input->keybit);
+       for (trans = powerbook_iso_keyboard; trans->from; trans++)
+               set_bit(trans->to, input->keybit);
  }
  #else
  static inline int hidinput_pb_event(struct hid_device *hid, struct input_dev *input,
@@@ -564,10 -581,6 +581,10 @@@ static void hidinput_configure_usage(st
                || ((device->quirks & HID_QUIRK_2WHEEL_MOUSE_HACK_7) && (usage->hid == 0x00090007)))
                goto ignore;
  
 +      if ((device->quirks & HID_QUIRK_BAD_RELATIVE_KEYS) &&
 +          usage->type == EV_KEY && (field->flags & HID_MAIN_ITEM_RELATIVE))
 +              field->flags &= ~HID_MAIN_ITEM_RELATIVE;
 +
        set_bit(usage->type, input->evbit);
  
        while (usage->code <= max && test_and_set_bit(usage->code, bit))
diff --combined drivers/usb/input/hid.h
index 8aa9ec08e8ab6ffa7315c00ea1d3a4e2ea0a6c9a,2a9bf07944c03b94adfc62ed5aa989c197fb04fe..76ad68d9edfd04d645788f3eeaa3476a1093a240
@@@ -260,7 -260,7 +260,8 @@@ struct hid_item 
  #define HID_QUIRK_POWERBOOK_HAS_FN            0x00001000
  #define HID_QUIRK_POWERBOOK_FN_ON             0x00002000
  #define HID_QUIRK_INVERT_HWHEEL                       0x00004000
- #define HID_QUIRK_BAD_RELATIVE_KEYS           0x00008000
+ #define HID_QUIRK_POWERBOOK_ISO_KEYBOARD      0x00008000
++#define HID_QUIRK_BAD_RELATIVE_KEYS           0x00010000
  
  /*
   * This is the global environment of the parser. This information is
@@@ -385,6 -385,7 +386,7 @@@ struct hid_control_fifo 
  #define HID_IN_RUNNING                3
  #define HID_RESET_PENDING     4
  #define HID_SUSPENDED         5
+ #define HID_CLEAR_HALT                6
  
  struct hid_input {
        struct list_head list;