Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input
authorLinus Torvalds <torvalds@linux-foundation.org>
Wed, 3 Oct 2012 00:16:10 +0000 (17:16 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Wed, 3 Oct 2012 00:16:10 +0000 (17:16 -0700)
Pull input updates from Dmitry Torokhov:
 "A few drivers were updated with device tree bindings and others got a
  few small cleanups and fixes."

Fix trivial conflict in drivers/input/keyboard/omap-keypad.c due to
changes clashing with a whitespace cleanup.

* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input: (28 commits)
  Input: wacom - mark Intuos5 pad as in-prox when touching buttons
  Input: synaptics - adjust threshold for treating position values as negative
  Input: hgpk - use %*ph to dump small buffer
  Input: gpio_keys_polled - fix dt pdata->nbuttons
  Input: Add KD[GS]KBDIACRUC ioctls to the compatible list
  Input: omap-keypad - fixed formatting
  Input: tegra - move platform data header
  Input: wacom - add support for EMR on Cintiq 24HD touch
  Input: s3c2410_ts - make s3c_ts_pmops const
  Input: samsung-keypad - use of_get_child_count() helper
  Input: samsung-keypad - use of_match_ptr()
  Input: uinput - fix formatting
  Input: uinput - specify exact bit sizes on userspace APIs
  Input: uinput - mark failed submission requests as free
  Input: uinput - fix race that can block nonblocking read
  Input: uinput - return -EINVAL when read buffer size is too small
  Input: uinput - take event lock when fetching events from buffer
  Input: get rid of MATCH_BIT() macro
  Input: rotary-encoder - add DT bindings
  Input: rotary-encoder - constify platform data pointers
  ...

1  2 
drivers/input/input.c
drivers/input/keyboard/omap-keypad.c
drivers/input/misc/uinput.c
drivers/input/mouse/synaptics.c
drivers/input/tablet/wacom_wac.c
drivers/input/touchscreen/s3c2410_ts.c
fs/compat_ioctl.c

diff --combined drivers/input/input.c
@@@ -47,8 -47,6 +47,8 @@@ static DEFINE_MUTEX(input_mutex)
  
  static struct input_handler *input_table[8];
  
 +static const struct input_value input_value_sync = { EV_SYN, SYN_REPORT, 1 };
 +
  static inline int is_event_supported(unsigned int code,
                                     unsigned long *bm, unsigned int max)
  {
@@@ -71,102 -69,42 +71,102 @@@ static int input_defuzz_abs_event(int v
        return value;
  }
  
 +static void input_start_autorepeat(struct input_dev *dev, int code)
 +{
 +      if (test_bit(EV_REP, dev->evbit) &&
 +          dev->rep[REP_PERIOD] && dev->rep[REP_DELAY] &&
 +          dev->timer.data) {
 +              dev->repeat_key = code;
 +              mod_timer(&dev->timer,
 +                        jiffies + msecs_to_jiffies(dev->rep[REP_DELAY]));
 +      }
 +}
 +
 +static void input_stop_autorepeat(struct input_dev *dev)
 +{
 +      del_timer(&dev->timer);
 +}
 +
  /*
   * Pass event first through all filters and then, if event has not been
   * filtered out, through all open handles. This function is called with
   * dev->event_lock held and interrupts disabled.
   */
 -static void input_pass_event(struct input_dev *dev,
 -                           unsigned int type, unsigned int code, int value)
 +static unsigned int input_to_handler(struct input_handle *handle,
 +                      struct input_value *vals, unsigned int count)
 +{
 +      struct input_handler *handler = handle->handler;
 +      struct input_value *end = vals;
 +      struct input_value *v;
 +
 +      for (v = vals; v != vals + count; v++) {
 +              if (handler->filter &&
 +                  handler->filter(handle, v->type, v->code, v->value))
 +                      continue;
 +              if (end != v)
 +                      *end = *v;
 +              end++;
 +      }
 +
 +      count = end - vals;
 +      if (!count)
 +              return 0;
 +
 +      if (handler->events)
 +              handler->events(handle, vals, count);
 +      else if (handler->event)
 +              for (v = vals; v != end; v++)
 +                      handler->event(handle, v->type, v->code, v->value);
 +
 +      return count;
 +}
 +
 +/*
 + * Pass values first through all filters and then, if event has not been
 + * filtered out, through all open handles. This function is called with
 + * dev->event_lock held and interrupts disabled.
 + */
 +static void input_pass_values(struct input_dev *dev,
 +                            struct input_value *vals, unsigned int count)
  {
 -      struct input_handler *handler;
        struct input_handle *handle;
 +      struct input_value *v;
 +
 +      if (!count)
 +              return;
  
        rcu_read_lock();
  
        handle = rcu_dereference(dev->grab);
 -      if (handle)
 -              handle->handler->event(handle, type, code, value);
 -      else {
 -              bool filtered = false;
 -
 -              list_for_each_entry_rcu(handle, &dev->h_list, d_node) {
 -                      if (!handle->open)
 -                              continue;
 +      if (handle) {
 +              count = input_to_handler(handle, vals, count);
 +      } else {
 +              list_for_each_entry_rcu(handle, &dev->h_list, d_node)
 +                      if (handle->open)
 +                              count = input_to_handler(handle, vals, count);
 +      }
  
 -                      handler = handle->handler;
 -                      if (!handler->filter) {
 -                              if (filtered)
 -                                      break;
 +      rcu_read_unlock();
  
 -                              handler->event(handle, type, code, value);
 +      add_input_randomness(vals->type, vals->code, vals->value);
  
 -                      } else if (handler->filter(handle, type, code, value))
 -                              filtered = true;
 +      /* trigger auto repeat for key events */
 +      for (v = vals; v != vals + count; v++) {
 +              if (v->type == EV_KEY && v->value != 2) {
 +                      if (v->value)
 +                              input_start_autorepeat(dev, v->code);
 +                      else
 +                              input_stop_autorepeat(dev);
                }
        }
 +}
  
 -      rcu_read_unlock();
 +static void input_pass_event(struct input_dev *dev,
 +                           unsigned int type, unsigned int code, int value)
 +{
 +      struct input_value vals[] = { { type, code, value } };
 +
 +      input_pass_values(dev, vals, ARRAY_SIZE(vals));
  }
  
  /*
@@@ -183,12 -121,18 +183,12 @@@ static void input_repeat_key(unsigned l
  
        if (test_bit(dev->repeat_key, dev->key) &&
            is_event_supported(dev->repeat_key, dev->keybit, KEY_MAX)) {
 +              struct input_value vals[] =  {
 +                      { EV_KEY, dev->repeat_key, 2 },
 +                      input_value_sync
 +              };
  
 -              input_pass_event(dev, EV_KEY, dev->repeat_key, 2);
 -
 -              if (dev->sync) {
 -                      /*
 -                       * Only send SYN_REPORT if we are not in a middle
 -                       * of driver parsing a new hardware packet.
 -                       * Otherwise assume that the driver will send
 -                       * SYN_REPORT once it's done.
 -                       */
 -                      input_pass_event(dev, EV_SYN, SYN_REPORT, 1);
 -              }
 +              input_pass_values(dev, vals, ARRAY_SIZE(vals));
  
                if (dev->rep[REP_PERIOD])
                        mod_timer(&dev->timer, jiffies +
        spin_unlock_irqrestore(&dev->event_lock, flags);
  }
  
 -static void input_start_autorepeat(struct input_dev *dev, int code)
 -{
 -      if (test_bit(EV_REP, dev->evbit) &&
 -          dev->rep[REP_PERIOD] && dev->rep[REP_DELAY] &&
 -          dev->timer.data) {
 -              dev->repeat_key = code;
 -              mod_timer(&dev->timer,
 -                        jiffies + msecs_to_jiffies(dev->rep[REP_DELAY]));
 -      }
 -}
 -
 -static void input_stop_autorepeat(struct input_dev *dev)
 -{
 -      del_timer(&dev->timer);
 -}
 -
  #define INPUT_IGNORE_EVENT    0
  #define INPUT_PASS_TO_HANDLERS        1
  #define INPUT_PASS_TO_DEVICE  2
 +#define INPUT_SLOT            4
 +#define INPUT_FLUSH           8
  #define INPUT_PASS_TO_ALL     (INPUT_PASS_TO_HANDLERS | INPUT_PASS_TO_DEVICE)
  
  static int input_handle_abs_event(struct input_dev *dev,
                                  unsigned int code, int *pval)
  {
 +      struct input_mt *mt = dev->mt;
        bool is_mt_event;
        int *pold;
  
                 * "Stage" the event; we'll flush it later, when we
                 * get actual touch data.
                 */
 -              if (*pval >= 0 && *pval < dev->mtsize)
 -                      dev->slot = *pval;
 +              if (mt && *pval >= 0 && *pval < mt->num_slots)
 +                      mt->slot = *pval;
  
                return INPUT_IGNORE_EVENT;
        }
  
        if (!is_mt_event) {
                pold = &dev->absinfo[code].value;
 -      } else if (dev->mt) {
 -              struct input_mt_slot *mtslot = &dev->mt[dev->slot];
 -              pold = &mtslot->abs[code - ABS_MT_FIRST];
 +      } else if (mt) {
 +              pold = &mt->slots[mt->slot].abs[code - ABS_MT_FIRST];
        } else {
                /*
                 * Bypass filtering for multi-touch events when
        }
  
        /* Flush pending "slot" event */
 -      if (is_mt_event && dev->slot != input_abs_get_val(dev, ABS_MT_SLOT)) {
 -              input_abs_set_val(dev, ABS_MT_SLOT, dev->slot);
 -              input_pass_event(dev, EV_ABS, ABS_MT_SLOT, dev->slot);
 +      if (is_mt_event && mt && mt->slot != input_abs_get_val(dev, ABS_MT_SLOT)) {
 +              input_abs_set_val(dev, ABS_MT_SLOT, mt->slot);
 +              return INPUT_PASS_TO_HANDLERS | INPUT_SLOT;
        }
  
        return INPUT_PASS_TO_HANDLERS;
  }
  
 -static void input_handle_event(struct input_dev *dev,
 -                             unsigned int type, unsigned int code, int value)
 +static int input_get_disposition(struct input_dev *dev,
 +                        unsigned int type, unsigned int code, int value)
  {
        int disposition = INPUT_IGNORE_EVENT;
  
                        break;
  
                case SYN_REPORT:
 -                      if (!dev->sync) {
 -                              dev->sync = true;
 -                              disposition = INPUT_PASS_TO_HANDLERS;
 -                      }
 +                      disposition = INPUT_PASS_TO_HANDLERS | INPUT_FLUSH;
                        break;
                case SYN_MT_REPORT:
 -                      dev->sync = false;
                        disposition = INPUT_PASS_TO_HANDLERS;
                        break;
                }
                break;
  
        case EV_KEY:
 -              if (is_event_supported(code, dev->keybit, KEY_MAX) &&
 -                  !!test_bit(code, dev->key) != value) {
 +              if (is_event_supported(code, dev->keybit, KEY_MAX)) {
  
 -                      if (value != 2) {
 -                              __change_bit(code, dev->key);
 -                              if (value)
 -                                      input_start_autorepeat(dev, code);
 -                              else
 -                                      input_stop_autorepeat(dev);
 +                      /* auto-repeat bypasses state updates */
 +                      if (value == 2) {
 +                              disposition = INPUT_PASS_TO_HANDLERS;
 +                              break;
                        }
  
 -                      disposition = INPUT_PASS_TO_HANDLERS;
 +                      if (!!test_bit(code, dev->key) != !!value) {
 +
 +                              __change_bit(code, dev->key);
 +                              disposition = INPUT_PASS_TO_HANDLERS;
 +                      }
                }
                break;
  
        case EV_SW:
                if (is_event_supported(code, dev->swbit, SW_MAX) &&
 -                  !!test_bit(code, dev->sw) != value) {
 +                  !!test_bit(code, dev->sw) != !!value) {
  
                        __change_bit(code, dev->sw);
                        disposition = INPUT_PASS_TO_HANDLERS;
  
        case EV_LED:
                if (is_event_supported(code, dev->ledbit, LED_MAX) &&
 -                  !!test_bit(code, dev->led) != value) {
 +                  !!test_bit(code, dev->led) != !!value) {
  
                        __change_bit(code, dev->led);
                        disposition = INPUT_PASS_TO_ALL;
                break;
        }
  
 -      if (disposition != INPUT_IGNORE_EVENT && type != EV_SYN)
 -              dev->sync = false;
 +      return disposition;
 +}
 +
 +static void input_handle_event(struct input_dev *dev,
 +                             unsigned int type, unsigned int code, int value)
 +{
 +      int disposition;
 +
 +      disposition = input_get_disposition(dev, type, code, value);
  
        if ((disposition & INPUT_PASS_TO_DEVICE) && dev->event)
                dev->event(dev, type, code, value);
  
 -      if (disposition & INPUT_PASS_TO_HANDLERS)
 -              input_pass_event(dev, type, code, value);
 +      if (!dev->vals)
 +              return;
 +
 +      if (disposition & INPUT_PASS_TO_HANDLERS) {
 +              struct input_value *v;
 +
 +              if (disposition & INPUT_SLOT) {
 +                      v = &dev->vals[dev->num_vals++];
 +                      v->type = EV_ABS;
 +                      v->code = ABS_MT_SLOT;
 +                      v->value = dev->mt->slot;
 +              }
 +
 +              v = &dev->vals[dev->num_vals++];
 +              v->type = type;
 +              v->code = code;
 +              v->value = value;
 +      }
 +
 +      if (disposition & INPUT_FLUSH) {
 +              if (dev->num_vals >= 2)
 +                      input_pass_values(dev, dev->vals, dev->num_vals);
 +              dev->num_vals = 0;
 +      } else if (dev->num_vals >= dev->max_vals - 2) {
 +              dev->vals[dev->num_vals++] = input_value_sync;
 +              input_pass_values(dev, dev->vals, dev->num_vals);
 +              dev->num_vals = 0;
 +      }
 +
  }
  
  /**
@@@ -425,6 -352,7 +425,6 @@@ void input_event(struct input_dev *dev
        if (is_event_supported(type, dev->evbit, EV_MAX)) {
  
                spin_lock_irqsave(&dev->event_lock, flags);
 -              add_input_randomness(type, code, value);
                input_handle_event(dev, type, code, value);
                spin_unlock_irqrestore(&dev->event_lock, flags);
        }
@@@ -903,12 -831,10 +903,12 @@@ int input_set_keycode(struct input_dev 
        if (test_bit(EV_KEY, dev->evbit) &&
            !is_event_supported(old_keycode, dev->keybit, KEY_MAX) &&
            __test_and_clear_bit(old_keycode, dev->key)) {
 +              struct input_value vals[] =  {
 +                      { EV_KEY, old_keycode, 0 },
 +                      input_value_sync
 +              };
  
 -              input_pass_event(dev, EV_KEY, old_keycode, 0);
 -              if (dev->sync)
 -                      input_pass_event(dev, EV_SYN, SYN_REPORT, 1);
 +              input_pass_values(dev, vals, ARRAY_SIZE(vals));
        }
  
   out:
  }
  EXPORT_SYMBOL(input_set_keycode);
  
- #define MATCH_BIT(bit, max) \
-               for (i = 0; i < BITS_TO_LONGS(max); i++) \
-                       if ((id->bit[i] & dev->bit[i]) != id->bit[i]) \
-                               break; \
-               if (i != BITS_TO_LONGS(max)) \
-                       continue;
  static const struct input_device_id *input_match_device(struct input_handler *handler,
                                                        struct input_dev *dev)
  {
        const struct input_device_id *id;
-       int i;
  
        for (id = handler->id_table; id->flags || id->driver_info; id++) {
  
                        if (id->version != dev->id.version)
                                continue;
  
-               MATCH_BIT(evbit,  EV_MAX);
-               MATCH_BIT(keybit, KEY_MAX);
-               MATCH_BIT(relbit, REL_MAX);
-               MATCH_BIT(absbit, ABS_MAX);
-               MATCH_BIT(mscbit, MSC_MAX);
-               MATCH_BIT(ledbit, LED_MAX);
-               MATCH_BIT(sndbit, SND_MAX);
-               MATCH_BIT(ffbit,  FF_MAX);
-               MATCH_BIT(swbit,  SW_MAX);
+               if (!bitmap_subset(id->evbit, dev->evbit, EV_MAX))
+                       continue;
+               if (!bitmap_subset(id->keybit, dev->keybit, KEY_MAX))
+                       continue;
+               if (!bitmap_subset(id->relbit, dev->relbit, REL_MAX))
+                       continue;
+               if (!bitmap_subset(id->absbit, dev->absbit, ABS_MAX))
+                       continue;
+               if (!bitmap_subset(id->mscbit, dev->mscbit, MSC_MAX))
+                       continue;
+               if (!bitmap_subset(id->ledbit, dev->ledbit, LED_MAX))
+                       continue;
+               if (!bitmap_subset(id->sndbit, dev->sndbit, SND_MAX))
+                       continue;
+               if (!bitmap_subset(id->ffbit, dev->ffbit, FF_MAX))
+                       continue;
+               if (!bitmap_subset(id->swbit, dev->swbit, SW_MAX))
+                       continue;
  
                if (!handler->match || handler->match(handler, dev))
                        return id;
@@@ -1490,7 -1425,6 +1499,7 @@@ static void input_dev_release(struct de
        input_ff_destroy(dev);
        input_mt_destroy_slots(dev);
        kfree(dev->absinfo);
 +      kfree(dev->vals);
        kfree(dev);
  
        module_put(THIS_MODULE);
@@@ -1826,8 -1760,8 +1835,8 @@@ static unsigned int input_estimate_even
        int i;
        unsigned int events;
  
 -      if (dev->mtsize) {
 -              mt_slots = dev->mtsize;
 +      if (dev->mt) {
 +              mt_slots = dev->mt->num_slots;
        } else if (test_bit(ABS_MT_TRACKING_ID, dev->absbit)) {
                mt_slots = dev->absinfo[ABS_MT_TRACKING_ID].maximum -
                           dev->absinfo[ABS_MT_TRACKING_ID].minimum + 1,
                if (test_bit(i, dev->relbit))
                        events++;
  
 +      /* Make room for KEY and MSC events */
 +      events += 7;
 +
        return events;
  }
  
@@@ -1894,7 -1825,6 +1903,7 @@@ int input_register_device(struct input_
  {
        static atomic_t input_no = ATOMIC_INIT(0);
        struct input_handler *handler;
 +      unsigned int packet_size;
        const char *path;
        int error;
  
        /* Make sure that bitmasks not mentioned in dev->evbit are clean. */
        input_cleanse_bitmasks(dev);
  
 -      if (!dev->hint_events_per_packet)
 -              dev->hint_events_per_packet =
 -                              input_estimate_events_per_packet(dev);
 +      packet_size = input_estimate_events_per_packet(dev);
 +      if (dev->hint_events_per_packet < packet_size)
 +              dev->hint_events_per_packet = packet_size;
 +
 +      dev->max_vals = max(dev->hint_events_per_packet, packet_size) + 2;
 +      dev->vals = kcalloc(dev->max_vals, sizeof(*dev->vals), GFP_KERNEL);
 +      if (!dev->vals)
 +              return -ENOMEM;
  
        /*
         * If delay and period are pre-set by the driver, then autorepeating
  #include <linux/mutex.h>
  #include <linux/errno.h>
  #include <linux/slab.h>
 -#include <asm/gpio.h>
 -#include <plat/keypad.h>
 -#include <plat/menelaus.h>
 -#include <asm/irq.h>
 -#include <mach/hardware.h>
 -#include <asm/io.h>
 -#include <plat/mux.h>
 +#include <linux/gpio.h>
 +#include <linux/platform_data/gpio-omap.h>
 +#include <linux/platform_data/keypad-omap.h>
  
  #undef NEW_BOARD_LEARNING_MODE
  
@@@ -92,8 -96,28 +92,8 @@@ static u8 get_row_gpio_val(struct omap_
  
  static irqreturn_t omap_kp_interrupt(int irq, void *dev_id)
  {
 -      struct omap_kp *omap_kp = dev_id;
 -
        /* disable keyboard interrupt and schedule for handling */
 -      if (cpu_is_omap24xx()) {
 -              int i;
 -
 -              for (i = 0; i < omap_kp->rows; i++) {
 -                      int gpio_irq = gpio_to_irq(row_gpios[i]);
 -                      /*
 -                       * The interrupt which we're currently handling should
 -                       * be disabled _nosync() to avoid deadlocks waiting
 -                       * for this handler to complete.  All others should
 -                       * be disabled the regular way for SMP safety.
 -                       */
 -                      if (gpio_irq == irq)
 -                              disable_irq_nosync(gpio_irq);
 -                      else
 -                              disable_irq(gpio_irq);
 -              }
 -      } else
 -              /* disable keyboard interrupt and schedule for handling */
 -              omap_writew(1, OMAP1_MPUIO_BASE + OMAP_MPUIO_KBD_MASKIT);
 +      omap_writew(1, OMAP1_MPUIO_BASE + OMAP_MPUIO_KBD_MASKIT);
  
        tasklet_schedule(&kp_tasklet);
  
@@@ -109,22 -133,33 +109,22 @@@ static void omap_kp_scan_keypad(struct 
  {
        int col = 0;
  
 -      /* read the keypad status */
 -      if (cpu_is_omap24xx()) {
 -              /* read the keypad status */
 -              for (col = 0; col < omap_kp->cols; col++) {
 -                      set_col_gpio_val(omap_kp, ~(1 << col));
 -                      state[col] = ~(get_row_gpio_val(omap_kp)) & 0xff;
 -              }
 -              set_col_gpio_val(omap_kp, 0);
 -
 -      } else {
 -              /* disable keyboard interrupt and schedule for handling */
 -              omap_writew(1, OMAP1_MPUIO_BASE + OMAP_MPUIO_KBD_MASKIT);
 +      /* disable keyboard interrupt and schedule for handling */
 +      omap_writew(1, OMAP1_MPUIO_BASE + OMAP_MPUIO_KBD_MASKIT);
  
 -              /* read the keypad status */
 -              omap_writew(0xff, OMAP1_MPUIO_BASE + OMAP_MPUIO_KBC);
 -              for (col = 0; col < omap_kp->cols; col++) {
 -                      omap_writew(~(1 << col) & 0xff,
 -                                  OMAP1_MPUIO_BASE + OMAP_MPUIO_KBC);
 +      /* read the keypad status */
 +      omap_writew(0xff, OMAP1_MPUIO_BASE + OMAP_MPUIO_KBC);
 +      for (col = 0; col < omap_kp->cols; col++) {
 +              omap_writew(~(1 << col) & 0xff,
 +                          OMAP1_MPUIO_BASE + OMAP_MPUIO_KBC);
  
 -                      udelay(omap_kp->delay);
 +              udelay(omap_kp->delay);
  
 -                      state[col] = ~omap_readw(OMAP1_MPUIO_BASE +
 -                                               OMAP_MPUIO_KBR_LATCH) & 0xff;
 -              }
 -              omap_writew(0x00, OMAP1_MPUIO_BASE + OMAP_MPUIO_KBC);
 -              udelay(2);
 +              state[col] = ~omap_readw(OMAP1_MPUIO_BASE +
 +                                       OMAP_MPUIO_KBR_LATCH) & 0xff;
        }
 +      omap_writew(0x00, OMAP1_MPUIO_BASE + OMAP_MPUIO_KBC);
 +      udelay(2);
  }
  
  static void omap_kp_tasklet(unsigned long data)
        memcpy(keypad_state, new_state, sizeof(keypad_state));
  
        if (key_down) {
-                 int delay = HZ / 20;
+               int delay = HZ / 20;
                /* some key is pressed - keep irq disabled and use timer
                 * to poll the keypad */
                if (spurious)
                mod_timer(&omap_kp_data->timer, jiffies + delay);
        } else {
                /* enable interrupts */
 -              if (cpu_is_omap24xx()) {
 -                      int i;
 -                      for (i = 0; i < omap_kp_data->rows; i++)
 -                              enable_irq(gpio_to_irq(row_gpios[i]));
 -              } else {
 -                      omap_writew(0, OMAP1_MPUIO_BASE + OMAP_MPUIO_KBD_MASKIT);
 -                      kp_cur_group = -1;
 -              }
 +              omap_writew(0, OMAP1_MPUIO_BASE + OMAP_MPUIO_KBD_MASKIT);
 +              kp_cur_group = -1;
        }
  }
  
@@@ -201,7 -242,6 +201,7 @@@ static ssize_t omap_kp_enable_show(stru
  static ssize_t omap_kp_enable_store(struct device *dev, struct device_attribute *attr,
                                    const char *buf, size_t count)
  {
 +      struct omap_kp *omap_kp = dev_get_drvdata(dev);
        int state;
  
        if (sscanf(buf, "%u", &state) != 1)
        mutex_lock(&kp_enable_mutex);
        if (state != kp_enable) {
                if (state)
 -                      enable_irq(INT_KEYBOARD);
 +                      enable_irq(omap_kp->irq);
                else
 -                      disable_irq(INT_KEYBOARD);
 +                      disable_irq(omap_kp->irq);
                kp_enable = state;
        }
        mutex_unlock(&kp_enable_mutex);
@@@ -249,7 -289,7 +249,7 @@@ static int __devinit omap_kp_probe(stru
        struct omap_kp *omap_kp;
        struct input_dev *input_dev;
        struct omap_kp_platform_data *pdata =  pdev->dev.platform_data;
 -      int i, col_idx, row_idx, irq_idx, ret;
 +      int i, col_idx, row_idx, ret;
        unsigned int row_shift, keycodemax;
  
        if (!pdata->rows || !pdata->cols || !pdata->keymap_data) {
        omap_kp->input = input_dev;
  
        /* Disable the interrupt for the MPUIO keyboard */
 -      if (!cpu_is_omap24xx())
 -              omap_writew(1, OMAP1_MPUIO_BASE + OMAP_MPUIO_KBD_MASKIT);
 +      omap_writew(1, OMAP1_MPUIO_BASE + OMAP_MPUIO_KBD_MASKIT);
  
        if (pdata->delay)
                omap_kp->delay = pdata->delay;
        omap_kp->rows = pdata->rows;
        omap_kp->cols = pdata->cols;
  
 -      if (cpu_is_omap24xx()) {
 -              /* Cols: outputs */
 -              for (col_idx = 0; col_idx < omap_kp->cols; col_idx++) {
 -                      if (gpio_request(col_gpios[col_idx], "omap_kp_col") < 0) {
 -                              printk(KERN_ERR "Failed to request"
 -                                     "GPIO%d for keypad\n",
 -                                     col_gpios[col_idx]);
 -                              goto err1;
 -                      }
 -                      gpio_direction_output(col_gpios[col_idx], 0);
 -              }
 -              /* Rows: inputs */
 -              for (row_idx = 0; row_idx < omap_kp->rows; row_idx++) {
 -                      if (gpio_request(row_gpios[row_idx], "omap_kp_row") < 0) {
 -                              printk(KERN_ERR "Failed to request"
 -                                     "GPIO%d for keypad\n",
 -                                     row_gpios[row_idx]);
 -                              goto err2;
 -                      }
 -                      gpio_direction_input(row_gpios[row_idx]);
 -              }
 -      } else {
 -              col_idx = 0;
 -              row_idx = 0;
 -      }
 +      col_idx = 0;
 +      row_idx = 0;
  
        setup_timer(&omap_kp->timer, omap_kp_timer, (unsigned long)omap_kp);
  
  
        /* scan current status and enable interrupt */
        omap_kp_scan_keypad(omap_kp, keypad_state);
 -      if (!cpu_is_omap24xx()) {
 -              omap_kp->irq = platform_get_irq(pdev, 0);
 -              if (omap_kp->irq >= 0) {
 -                      if (request_irq(omap_kp->irq, omap_kp_interrupt, 0,
 -                                      "omap-keypad", omap_kp) < 0)
 -                              goto err4;
 -              }
 -              omap_writew(0, OMAP1_MPUIO_BASE + OMAP_MPUIO_KBD_MASKIT);
 -      } else {
 -              for (irq_idx = 0; irq_idx < omap_kp->rows; irq_idx++) {
 -                      if (request_irq(gpio_to_irq(row_gpios[irq_idx]),
 -                                      omap_kp_interrupt,
 -                                      IRQF_TRIGGER_FALLING,
 -                                      "omap-keypad", omap_kp) < 0)
 -                              goto err5;
 -              }
 +      omap_kp->irq = platform_get_irq(pdev, 0);
 +      if (omap_kp->irq >= 0) {
 +              if (request_irq(omap_kp->irq, omap_kp_interrupt, 0,
 +                              "omap-keypad", omap_kp) < 0)
 +                      goto err4;
        }
 +      omap_writew(0, OMAP1_MPUIO_BASE + OMAP_MPUIO_KBD_MASKIT);
 +
        return 0;
 -err5:
 -      for (i = irq_idx - 1; i >= 0; i--)
 -              free_irq(row_gpios[i], omap_kp);
 +
  err4:
        input_unregister_device(omap_kp->input);
        input_dev = NULL;
  err3:
        device_remove_file(&pdev->dev, &dev_attr_enable);
  err2:
-       for (i = row_idx - 1; i >=0; i--)
+       for (i = row_idx - 1; i >= 0; i--)
                gpio_free(row_gpios[i]);
-       for (i = col_idx - 1; i >=0; i--)
 -err1:
+       for (i = col_idx - 1; i >= 0; i--)
                gpio_free(col_gpios[i]);
  
        kfree(omap_kp);
@@@ -363,8 -439,18 +363,8 @@@ static int __devexit omap_kp_remove(str
  
        /* disable keypad interrupt handling */
        tasklet_disable(&kp_tasklet);
 -      if (cpu_is_omap24xx()) {
 -              int i;
 -              for (i = 0; i < omap_kp->cols; i++)
 -                      gpio_free(col_gpios[i]);
 -              for (i = 0; i < omap_kp->rows; i++) {
 -                      gpio_free(row_gpios[i]);
 -                      free_irq(gpio_to_irq(row_gpios[i]), omap_kp);
 -              }
 -      } else {
 -              omap_writew(1, OMAP1_MPUIO_BASE + OMAP_MPUIO_KBD_MASKIT);
 -              free_irq(omap_kp->irq, omap_kp);
 -      }
 +      omap_writew(1, OMAP1_MPUIO_BASE + OMAP_MPUIO_KBD_MASKIT);
 +      free_irq(omap_kp->irq, omap_kp);
  
        del_timer_sync(&omap_kp->timer);
        tasklet_kill(&kp_tasklet);
@@@ -40,7 -40,8 +40,8 @@@
  #include <linux/input/mt.h>
  #include "../input-compat.h"
  
- static int uinput_dev_event(struct input_dev *dev, unsigned int type, unsigned int code, int value)
+ static int uinput_dev_event(struct input_dev *dev,
+                           unsigned int type, unsigned int code, int value)
  {
        struct uinput_device    *udev = input_get_drvdata(dev);
  
  }
  
  /* Atomically allocate an ID for the given request. Returns 0 on success. */
- static int uinput_request_alloc_id(struct uinput_device *udev, struct uinput_request *request)
+ static bool uinput_request_alloc_id(struct uinput_device *udev,
+                                   struct uinput_request *request)
  {
-       int id;
-       int err = -1;
+       unsigned int id;
+       bool reserved = false;
  
        spin_lock(&udev->requests_lock);
  
                if (!udev->requests[id]) {
                        request->id = id;
                        udev->requests[id] = request;
-                       err = 0;
+                       reserved = true;
                        break;
                }
        }
  
        spin_unlock(&udev->requests_lock);
-       return err;
+       return reserved;
  }
  
- static struct uinput_request *uinput_request_find(struct uinput_device *udev, int id)
+ static struct uinput_request *uinput_request_find(struct uinput_device *udev,
+                                                 unsigned int id)
  {
        /* Find an input request, by ID. Returns NULL if the ID isn't valid. */
-       if (id >= UINPUT_NUM_REQUESTS || id < 0)
+       if (id >= UINPUT_NUM_REQUESTS)
                return NULL;
  
        return udev->requests[id];
  }
  
- static inline int uinput_request_reserve_slot(struct uinput_device *udev, struct uinput_request *request)
+ static int uinput_request_reserve_slot(struct uinput_device *udev,
+                                      struct uinput_request *request)
  {
        /* Allocate slot. If none are available right away, wait. */
        return wait_event_interruptible(udev->requests_waitq,
-                                       !uinput_request_alloc_id(udev, request));
+                                       uinput_request_alloc_id(udev, request));
  }
  
- static void uinput_request_done(struct uinput_device *udev, struct uinput_request *request)
+ static void uinput_request_done(struct uinput_device *udev,
+                               struct uinput_request *request)
  {
        /* Mark slot as available */
        udev->requests[request->id] = NULL;
        complete(&request->done);
  }
  
- static int uinput_request_submit(struct uinput_device *udev, struct uinput_request *request)
+ static int uinput_request_send(struct uinput_device *udev,
+                              struct uinput_request *request)
  {
        int retval;
  
-       retval = uinput_request_reserve_slot(udev, request);
-       if (retval)
-               return retval;
        retval = mutex_lock_interruptible(&udev->mutex);
        if (retval)
                return retval;
                goto out;
        }
  
-       /* Tell our userspace app about this new request by queueing an input event */
+       init_completion(&request->done);
+       /*
+        * Tell our userspace application about this new request
+        * by queueing an input event.
+        */
        uinput_dev_event(udev->dev, EV_UINPUT, request->code, request->id);
  
   out:
        return retval;
  }
  
+ static int uinput_request_submit(struct uinput_device *udev,
+                                struct uinput_request *request)
+ {
+       int error;
+       error = uinput_request_reserve_slot(udev, request);
+       if (error)
+               return error;
+       error = uinput_request_send(udev, request);
+       if (error) {
+               uinput_request_done(udev, request);
+               return error;
+       }
+       wait_for_completion(&request->done);
+       return request->retval;
+ }
  /*
-  * Fail all ouitstanding requests so handlers don't wait for the userspace
+  * Fail all outstanding requests so handlers don't wait for the userspace
   * to finish processing them.
   */
  static void uinput_flush_requests(struct uinput_device *udev)
@@@ -163,11 -189,12 +189,12 @@@ static int uinput_dev_playback(struct i
        return uinput_dev_event(dev, EV_FF, effect_id, value);
  }
  
- static int uinput_dev_upload_effect(struct input_dev *dev, struct ff_effect *effect, struct ff_effect *old)
+ static int uinput_dev_upload_effect(struct input_dev *dev,
+                                   struct ff_effect *effect,
+                                   struct ff_effect *old)
  {
        struct uinput_device *udev = input_get_drvdata(dev);
        struct uinput_request request;
-       int retval;
  
        /*
         * uinput driver does not currently support periodic effects with
                        effect->u.periodic.waveform == FF_CUSTOM)
                return -EINVAL;
  
-       request.id = -1;
-       init_completion(&request.done);
        request.code = UI_FF_UPLOAD;
        request.u.upload.effect = effect;
        request.u.upload.old = old;
  
-       retval = uinput_request_submit(udev, &request);
-       if (!retval) {
-               wait_for_completion(&request.done);
-               retval = request.retval;
-       }
-       return retval;
+       return uinput_request_submit(udev, &request);
  }
  
  static int uinput_dev_erase_effect(struct input_dev *dev, int effect_id)
  {
        struct uinput_device *udev = input_get_drvdata(dev);
        struct uinput_request request;
-       int retval;
  
        if (!test_bit(EV_FF, dev->evbit))
                return -ENOSYS;
  
-       request.id = -1;
-       init_completion(&request.done);
        request.code = UI_FF_ERASE;
        request.u.effect_id = effect_id;
  
-       retval = uinput_request_submit(udev, &request);
-       if (!retval) {
-               wait_for_completion(&request.done);
-               retval = request.retval;
-       }
-       return retval;
+       return uinput_request_submit(udev, &request);
  }
  
  static void uinput_destroy_device(struct uinput_device *udev)
@@@ -347,7 -357,8 +357,8 @@@ static int uinput_allocate_device(struc
        return 0;
  }
  
- static int uinput_setup_device(struct uinput_device *udev, const char __user *buffer, size_t count)
+ static int uinput_setup_device(struct uinput_device *udev,
+                              const char __user *buffer, size_t count)
  {
        struct uinput_user_dev  *user_dev;
        struct input_dev        *dev;
                        goto exit;
                if (test_bit(ABS_MT_SLOT, dev->absbit)) {
                        int nslot = input_abs_get_max(dev, ABS_MT_SLOT) + 1;
 -                      input_mt_init_slots(dev, nslot);
 +                      input_mt_init_slots(dev, nslot, 0);
                } else if (test_bit(ABS_MT_POSITION_X, dev->absbit)) {
                        input_set_events_per_packet(dev, 60);
                }
        return retval;
  }
  
- static inline ssize_t uinput_inject_event(struct uinput_device *udev, const char __user *buffer, size_t count)
+ static ssize_t uinput_inject_event(struct uinput_device *udev,
+                                  const char __user *buffer, size_t count)
  {
        struct input_event ev;
  
        return input_event_size();
  }
  
- static ssize_t uinput_write(struct file *file, const char __user *buffer, size_t count, loff_t *ppos)
+ static ssize_t uinput_write(struct file *file, const char __user *buffer,
+                           size_t count, loff_t *ppos)
  {
        struct uinput_device *udev = file->private_data;
        int retval;
  
+       if (count == 0)
+               return 0;
        retval = mutex_lock_interruptible(&udev->mutex);
        if (retval)
                return retval;
        return retval;
  }
  
- static ssize_t uinput_read(struct file *file, char __user *buffer, size_t count, loff_t *ppos)
+ static bool uinput_fetch_next_event(struct uinput_device *udev,
+                                   struct input_event *event)
  {
-       struct uinput_device *udev = file->private_data;
-       int retval = 0;
+       bool have_event;
  
-       if (udev->state != UIST_CREATED)
-               return -ENODEV;
+       spin_lock_irq(&udev->dev->event_lock);
  
-       if (udev->head == udev->tail && (file->f_flags & O_NONBLOCK))
-               return -EAGAIN;
+       have_event = udev->head != udev->tail;
+       if (have_event) {
+               *event = udev->buff[udev->tail];
+               udev->tail = (udev->tail + 1) % UINPUT_BUFFER_SIZE;
+       }
  
-       retval = wait_event_interruptible(udev->waitq,
-                       udev->head != udev->tail || udev->state != UIST_CREATED);
-       if (retval)
-               return retval;
+       spin_unlock_irq(&udev->dev->event_lock);
  
-       retval = mutex_lock_interruptible(&udev->mutex);
-       if (retval)
-               return retval;
+       return have_event;
+ }
  
-       if (udev->state != UIST_CREATED) {
-               retval = -ENODEV;
-               goto out;
-       }
+ static ssize_t uinput_events_to_user(struct uinput_device *udev,
+                                    char __user *buffer, size_t count)
+ {
+       struct input_event event;
+       size_t read = 0;
  
-       while (udev->head != udev->tail && retval + input_event_size() <= count) {
-               if (input_event_to_user(buffer + retval, &udev->buff[udev->tail])) {
-                       retval = -EFAULT;
-                       goto out;
-               }
-               udev->tail = (udev->tail + 1) % UINPUT_BUFFER_SIZE;
-               retval += input_event_size();
+       while (read + input_event_size() <= count &&
+              uinput_fetch_next_event(udev, &event)) {
+               if (input_event_to_user(buffer + read, &event))
+                       return -EFAULT;
+               read += input_event_size();
        }
  
-  out:
-       mutex_unlock(&udev->mutex);
+       return read;
+ }
+ static ssize_t uinput_read(struct file *file, char __user *buffer,
+                          size_t count, loff_t *ppos)
+ {
+       struct uinput_device *udev = file->private_data;
+       ssize_t retval;
+       if (count != 0 && count < input_event_size())
+               return -EINVAL;
+       do {
+               retval = mutex_lock_interruptible(&udev->mutex);
+               if (retval)
+                       return retval;
+               if (udev->state != UIST_CREATED)
+                       retval = -ENODEV;
+               else if (udev->head == udev->tail &&
+                        (file->f_flags & O_NONBLOCK))
+                       retval = -EAGAIN;
+               else
+                       retval = uinput_events_to_user(udev, buffer, count);
+               mutex_unlock(&udev->mutex);
+               if (retval || count == 0)
+                       break;
+               if (!(file->f_flags & O_NONBLOCK))
+                       retval = wait_event_interruptible(udev->waitq,
+                                                 udev->head != udev->tail ||
+                                                 udev->state != UIST_CREATED);
+       } while (retval == 0);
  
        return retval;
  }
@@@ -516,8 -564,8 +564,8 @@@ static int uinput_release(struct inode 
  
  #ifdef CONFIG_COMPAT
  struct uinput_ff_upload_compat {
-       int                     request_id;
-       int                     retval;
+       __u32                   request_id;
+       __s32                   retval;
        struct ff_effect_compat effect;
        struct ff_effect_compat old;
  };
@@@ -703,7 -751,8 +751,8 @@@ static long uinput_ioctl_handler(struc
                                break;
  
                        req = uinput_request_find(udev, ff_up.request_id);
-                       if (!req || req->code != UI_FF_UPLOAD || !req->u.upload.effect) {
+                       if (!req || req->code != UI_FF_UPLOAD ||
+                           !req->u.upload.effect) {
                                retval = -EINVAL;
                                break;
                        }
@@@ -786,7 -835,8 +835,8 @@@ static long uinput_ioctl(struct file *f
  }
  
  #ifdef CONFIG_COMPAT
- static long uinput_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
+ static long uinput_compat_ioctl(struct file *file,
+                               unsigned int cmd, unsigned long arg)
  {
        return uinput_ioctl_handler(file, cmd, arg, compat_ptr(arg));
  }
@@@ -831,4 -881,3 +881,3 @@@ MODULE_VERSION("0.3")
  
  module_init(uinput_init);
  module_exit(uinput_exit);
  #define ABS_POS_BITS 13
  
  /*
-  * Any position values from the hardware above the following limits are
-  * treated as "wrapped around negative" values that have been truncated to
-  * the 13-bit reporting range of the hardware. These are just reasonable
-  * guesses and can be adjusted if hardware is found that operates outside
-  * of these parameters.
+  * These values should represent the absolute maximum value that will
+  * be reported for a positive position value. Some Synaptics firmware
+  * uses this value to indicate a finger near the edge of the touchpad
+  * whose precise position cannot be determined.
+  *
+  * At least one touchpad is known to report positions in excess of this
+  * value which are actually negative values truncated to the 13-bit
+  * reporting range. These values have never been observed to be lower
+  * than 8184 (i.e. -8), so we treat all values greater than 8176 as
+  * negative and any other value as positive.
   */
- #define X_MAX_POSITIVE (((1 << ABS_POS_BITS) + XMAX) / 2)
- #define Y_MAX_POSITIVE (((1 << ABS_POS_BITS) + YMAX) / 2)
+ #define X_MAX_POSITIVE 8176
+ #define Y_MAX_POSITIVE 8176
  
  /*****************************************************************************
   *    Stuff we need even when we do not want native Synaptics support
@@@ -604,11 -609,21 +609,21 @@@ static int synaptics_parse_hw_state(con
                hw->right = (buf[0] & 0x02) ? 1 : 0;
        }
  
-       /* Convert wrap-around values to negative */
+       /*
+        * Convert wrap-around values to negative. (X|Y)_MAX_POSITIVE
+        * is used by some firmware to indicate a finger at the edge of
+        * the touchpad whose precise position cannot be determined, so
+        * convert these values to the maximum axis value.
+        */
        if (hw->x > X_MAX_POSITIVE)
                hw->x -= 1 << ABS_POS_BITS;
+       else if (hw->x == X_MAX_POSITIVE)
+               hw->x = XMAX;
        if (hw->y > Y_MAX_POSITIVE)
                hw->y -= 1 << ABS_POS_BITS;
+       else if (hw->y == Y_MAX_POSITIVE)
+               hw->y = YMAX;
  
        return 0;
  }
@@@ -1232,7 -1247,7 +1247,7 @@@ static void set_input_params(struct inp
        input_set_abs_params(dev, ABS_PRESSURE, 0, 255, 0, 0);
  
        if (SYN_CAP_IMAGE_SENSOR(priv->ext_cap_0c)) {
 -              input_mt_init_slots(dev, 2);
 +              input_mt_init_slots(dev, 2, 0);
                set_abs_position_params(dev, priv, ABS_MT_POSITION_X,
                                        ABS_MT_POSITION_Y);
                /* Image sensors can report per-contact pressure */
        } else if (SYN_CAP_ADV_GESTURE(priv->ext_cap_0c)) {
                /* Non-image sensors with AGM use semi-mt */
                __set_bit(INPUT_PROP_SEMI_MT, dev->propbit);
 -              input_mt_init_slots(dev, 2);
 +              input_mt_init_slots(dev, 2, 0);
                set_abs_position_params(dev, priv, ABS_MT_POSITION_X,
                                        ABS_MT_POSITION_Y);
        }
@@@ -606,7 -606,7 +606,7 @@@ static int wacom_intuos_irq(struct waco
                                input_report_abs(input, ABS_WHEEL, 0);
                        }
  
-                       if (data[2] | (data[3] & 0x01) | data[4]) {
+                       if (data[2] | (data[3] & 0x01) | data[4] | data[5]) {
                                input_report_key(input, wacom->tool[1], 1);
                                input_report_abs(input, ABS_MISC, PAD_DEVICE_ID);
                        } else {
@@@ -1530,7 -1530,7 +1530,7 @@@ int wacom_setup_input_capabilities(stru
                        __set_bit(BTN_TOOL_TRIPLETAP, input_dev->keybit);
                        __set_bit(BTN_TOOL_QUADTAP, input_dev->keybit);
  
 -                      input_mt_init_slots(input_dev, features->touch_max);
 +                      input_mt_init_slots(input_dev, features->touch_max, 0);
  
                        input_set_abs_params(input_dev, ABS_MT_TOUCH_MAJOR,
                                             0, 255, 0, 0);
  
        case TABLETPC2FG:
                if (features->device_type == BTN_TOOL_FINGER) {
 -                      input_mt_init_slots(input_dev, features->touch_max);
 +                      input_mt_init_slots(input_dev, features->touch_max, 0);
                        input_set_abs_params(input_dev, ABS_MT_TOOL_TYPE,
                                        0, MT_TOOL_MAX, 0, 0);
                        input_set_abs_params(input_dev, ABS_MT_POSITION_X,
  
                        __set_bit(BTN_TOOL_FINGER, input_dev->keybit);
                        __set_bit(BTN_TOOL_DOUBLETAP, input_dev->keybit);
 -                      input_mt_init_slots(input_dev, features->touch_max);
 +                      input_mt_init_slots(input_dev, features->touch_max, 0);
  
                        if (features->pktlen == WACOM_PKGLEN_BBTOUCH3) {
                                __set_bit(BTN_TOOL_TRIPLETAP,
@@@ -37,7 -37,7 +37,7 @@@
  
  #include <plat/adc.h>
  #include <plat/regs-adc.h>
 -#include <plat/ts.h>
 +#include <linux/platform_data/touchscreen-s3c2410.h>
  
  #define TSC_SLEEP  (S3C2410_ADCTSC_PULL_UP_DISABLE | S3C2410_ADCTSC_XY_PST(0))
  
@@@ -406,7 -406,7 +406,7 @@@ static int s3c2410ts_resume(struct devi
        return 0;
  }
  
- static struct dev_pm_ops s3c_ts_pmops = {
+ static const struct dev_pm_ops s3c_ts_pmops = {
        .suspend        = s3c2410ts_suspend,
        .resume         = s3c2410ts_resume,
  };
diff --combined fs/compat_ioctl.c
@@@ -866,12 -866,6 +866,12 @@@ COMPATIBLE_IOCTL(TIOCGPTN
  COMPATIBLE_IOCTL(TIOCSPTLCK)
  COMPATIBLE_IOCTL(TIOCSERGETLSR)
  COMPATIBLE_IOCTL(TIOCSIG)
 +#ifdef TIOCSRS485
 +COMPATIBLE_IOCTL(TIOCSRS485)
 +#endif
 +#ifdef TIOCGRS485
 +COMPATIBLE_IOCTL(TIOCGRS485)
 +#endif
  #ifdef TCGETS2
  COMPATIBLE_IOCTL(TCGETS2)
  COMPATIBLE_IOCTL(TCSETS2)
@@@ -903,6 -897,8 +903,8 @@@ COMPATIBLE_IOCTL(KDGKBSENT
  COMPATIBLE_IOCTL(KDSKBSENT)
  COMPATIBLE_IOCTL(KDGKBDIACR)
  COMPATIBLE_IOCTL(KDSKBDIACR)
+ COMPATIBLE_IOCTL(KDGKBDIACRUC)
+ COMPATIBLE_IOCTL(KDSKBDIACRUC)
  COMPATIBLE_IOCTL(KDKBDREP)
  COMPATIBLE_IOCTL(KDGKBLED)
  COMPATIBLE_IOCTL(KDGETLED)