]> Git Repo - linux.git/commitdiff
Merge branch 'next' into for-linus
authorDmitry Torokhov <[email protected]>
Mon, 25 Nov 2024 01:05:27 +0000 (17:05 -0800)
committerDmitry Torokhov <[email protected]>
Mon, 25 Nov 2024 01:05:27 +0000 (17:05 -0800)
Prepare input updates for 6.13 merge window.

1  2 
drivers/input/input.c
drivers/input/joystick/xpad.c
drivers/input/keyboard/adp5589-keys.c
drivers/input/serio/i8042-acpipnpio.h
drivers/input/touchscreen/edt-ft5x06.c
include/linux/input.h

diff --combined drivers/input/input.c
index 3d2cc13e1f32c89d293380b17f0adef2856d2a45,3b1e88ead97e1557f0365d0b69e1ee5699c7dd49..fd9d40286b7590ba1a1f43f1e7f2a3ba0bc536ea
@@@ -119,12 -119,12 +119,12 @@@ static void input_pass_values(struct in
  
        handle = rcu_dereference(dev->grab);
        if (handle) {
 -              count = handle->handler->events(handle, vals, count);
 +              count = handle->handle_events(handle, vals, count);
        } else {
                list_for_each_entry_rcu(handle, &dev->h_list, d_node)
                        if (handle->open) {
 -                              count = handle->handler->events(handle, vals,
 -                                                              count);
 +                              count = handle->handle_events(handle, vals,
 +                                                            count);
                                if (!count)
                                        break;
                        }
@@@ -605,6 -605,9 +605,9 @@@ int input_open_device(struct input_hand
  
        handle->open++;
  
+       if (handle->handler->passive_observer)
+               goto out;
        if (dev->users++ || dev->inhibited) {
                /*
                 * Device is already opened and/or inhibited,
@@@ -668,11 -671,13 +671,13 @@@ void input_close_device(struct input_ha
  
        __input_release_device(handle);
  
-       if (!--dev->users && !dev->inhibited) {
-               if (dev->poller)
-                       input_dev_poller_stop(dev->poller);
-               if (dev->close)
-                       dev->close(dev);
+       if (!handle->handler->passive_observer) {
+               if (!--dev->users && !dev->inhibited) {
+                       if (dev->poller)
+                               input_dev_poller_stop(dev->poller);
+                       if (dev->close)
+                               dev->close(dev);
+               }
        }
  
        if (!--handle->open) {
@@@ -2537,6 -2542,57 +2542,6 @@@ static int input_handler_check_methods(
        return 0;
  }
  
 -/*
 - * An implementation of input_handler's events() method that simply
 - * invokes handler->event() method for each event one by one.
 - */
 -static unsigned int input_handler_events_default(struct input_handle *handle,
 -                                               struct input_value *vals,
 -                                               unsigned int count)
 -{
 -      struct input_handler *handler = handle->handler;
 -      struct input_value *v;
 -
 -      for (v = vals; v != vals + count; v++)
 -              handler->event(handle, v->type, v->code, v->value);
 -
 -      return count;
 -}
 -
 -/*
 - * An implementation of input_handler's events() method that invokes
 - * handler->filter() method for each event one by one and removes events
 - * that were filtered out from the "vals" array.
 - */
 -static unsigned int input_handler_events_filter(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(handle, v->type, v->code, v->value))
 -                      continue;
 -              if (end != v)
 -                      *end = *v;
 -              end++;
 -      }
 -
 -      return end - vals;
 -}
 -
 -/*
 - * An implementation of input_handler's events() method that does nothing.
 - */
 -static unsigned int input_handler_events_null(struct input_handle *handle,
 -                                            struct input_value *vals,
 -                                            unsigned int count)
 -{
 -      return count;
 -}
 -
  /**
   * input_register_handler - register a new input handler
   * @handler: handler to be registered
@@@ -2556,6 -2612,13 +2561,6 @@@ int input_register_handler(struct input
  
        INIT_LIST_HEAD(&handler->h_list);
  
 -      if (handler->filter)
 -              handler->events = input_handler_events_filter;
 -      else if (handler->event)
 -              handler->events = input_handler_events_default;
 -      else if (!handler->events)
 -              handler->events = input_handler_events_null;
 -
        error = mutex_lock_interruptible(&input_mutex);
        if (error)
                return error;
@@@ -2629,75 -2692,6 +2634,75 @@@ int input_handler_for_each_handle(struc
  }
  EXPORT_SYMBOL(input_handler_for_each_handle);
  
 +/*
 + * An implementation of input_handle's handle_events() method that simply
 + * invokes handler->event() method for each event one by one.
 + */
 +static unsigned int input_handle_events_default(struct input_handle *handle,
 +                                              struct input_value *vals,
 +                                              unsigned int count)
 +{
 +      struct input_handler *handler = handle->handler;
 +      struct input_value *v;
 +
 +      for (v = vals; v != vals + count; v++)
 +              handler->event(handle, v->type, v->code, v->value);
 +
 +      return count;
 +}
 +
 +/*
 + * An implementation of input_handle's handle_events() method that invokes
 + * handler->filter() method for each event one by one and removes events
 + * that were filtered out from the "vals" array.
 + */
 +static unsigned int input_handle_events_filter(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(handle, v->type, v->code, v->value))
 +                      continue;
 +              if (end != v)
 +                      *end = *v;
 +              end++;
 +      }
 +
 +      return end - vals;
 +}
 +
 +/*
 + * An implementation of input_handle's handle_events() method that does nothing.
 + */
 +static unsigned int input_handle_events_null(struct input_handle *handle,
 +                                           struct input_value *vals,
 +                                           unsigned int count)
 +{
 +      return count;
 +}
 +
 +/*
 + * Sets up appropriate handle->event_handler based on the input_handler
 + * associated with the handle.
 + */
 +static void input_handle_setup_event_handler(struct input_handle *handle)
 +{
 +      struct input_handler *handler = handle->handler;
 +
 +      if (handler->filter)
 +              handle->handle_events = input_handle_events_filter;
 +      else if (handler->event)
 +              handle->handle_events = input_handle_events_default;
 +      else if (handler->events)
 +              handle->handle_events = handler->events;
 +      else
 +              handle->handle_events = input_handle_events_null;
 +}
 +
  /**
   * input_register_handle - register a new input handle
   * @handle: handle to register
@@@ -2715,7 -2709,6 +2720,7 @@@ int input_register_handle(struct input_
        struct input_dev *dev = handle->dev;
        int error;
  
 +      input_handle_setup_event_handler(handle);
        /*
         * We take dev->mutex here to prevent race with
         * input_release_device().
index 22ea58bf76cb5ca82eaa55f179f2c5501f5a84d6,3e61df92727796f8deb650924157dd2eab4acdce..ff9bc87f2f709211d1cc46793e79ef09c4a75033
@@@ -218,7 -218,6 +218,7 @@@ static const struct xpad_device 
        { 0x0c12, 0x8810, "Zeroplus Xbox Controller", 0, XTYPE_XBOX },
        { 0x0c12, 0x9902, "HAMA VibraX - *FAULTY HARDWARE*", 0, XTYPE_XBOX },
        { 0x0d2f, 0x0002, "Andamiro Pump It Up pad", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX },
 +      { 0x0db0, 0x1901, "Micro Star International Xbox360 Controller for Windows", 0, XTYPE_XBOX360 },
        { 0x0e4c, 0x1097, "Radica Gamester Controller", 0, XTYPE_XBOX },
        { 0x0e4c, 0x1103, "Radica Gamester Reflex", MAP_TRIGGERS_TO_BUTTONS, XTYPE_XBOX },
        { 0x0e4c, 0x2390, "Radica Games Jtech Controller", 0, XTYPE_XBOX },
        { 0x294b, 0x3404, "Snakebyte GAMEPAD RGB X", 0, XTYPE_XBOXONE },
        { 0x2dc8, 0x2000, "8BitDo Pro 2 Wired Controller fox Xbox", 0, XTYPE_XBOXONE },
        { 0x2dc8, 0x3106, "8BitDo Pro 2 Wired Controller", 0, XTYPE_XBOX360 },
 +      { 0x2dc8, 0x310a, "8BitDo Ultimate 2C Wireless Controller", 0, XTYPE_XBOX360 },
        { 0x2e24, 0x0652, "Hyperkin Duke X-Box One pad", 0, XTYPE_XBOXONE },
        { 0x31e3, 0x1100, "Wooting One", 0, XTYPE_XBOX360 },
        { 0x31e3, 0x1200, "Wooting Two", 0, XTYPE_XBOX360 },
@@@ -494,7 -492,6 +494,7 @@@ static const struct usb_device_id xpad_
        XPAD_XBOX360_VENDOR(0x07ff),            /* Mad Catz Gamepad */
        XPAD_XBOXONE_VENDOR(0x0b05),            /* ASUS controllers */
        XPAD_XBOX360_VENDOR(0x0c12),            /* Zeroplus X-Box 360 controllers */
 +      XPAD_XBOX360_VENDOR(0x0db0),            /* Micro Star International X-Box 360 controllers */
        XPAD_XBOX360_VENDOR(0x0e6f),            /* 0x0e6f Xbox 360 controllers */
        XPAD_XBOXONE_VENDOR(0x0e6f),            /* 0x0e6f Xbox One controllers */
        XPAD_XBOX360_VENDOR(0x0f0d),            /* Hori controllers */
@@@ -1292,9 -1289,8 +1292,8 @@@ static void xpad_irq_out(struct urb *ur
        struct device *dev = &xpad->intf->dev;
        int status = urb->status;
        int error;
-       unsigned long flags;
  
-       spin_lock_irqsave(&xpad->odata_lock, flags);
+       guard(spinlock_irqsave)(&xpad->odata_lock);
  
        switch (status) {
        case 0:
                        xpad->irq_out_active = false;
                }
        }
-       spin_unlock_irqrestore(&xpad->odata_lock, flags);
  }
  
  static int xpad_init_output(struct usb_interface *intf, struct usb_xpad *xpad,
@@@ -1394,10 -1388,8 +1391,8 @@@ static int xpad_inquiry_pad_presence(st
  {
        struct xpad_output_packet *packet =
                        &xpad->out_packets[XPAD_OUT_CMD_IDX];
-       unsigned long flags;
-       int retval;
  
-       spin_lock_irqsave(&xpad->odata_lock, flags);
+       guard(spinlock_irqsave)(&xpad->odata_lock);
  
        packet->data[0] = 0x08;
        packet->data[1] = 0x00;
  
        /* Reset the sequence so we send out presence first */
        xpad->last_out_packet = -1;
-       retval = xpad_try_sending_next_out_packet(xpad);
-       spin_unlock_irqrestore(&xpad->odata_lock, flags);
-       return retval;
+       return xpad_try_sending_next_out_packet(xpad);
  }
  
  static int xpad_start_xbox_one(struct usb_xpad *xpad)
  {
-       unsigned long flags;
-       int retval;
+       int error;
  
        if (usb_ifnum_to_if(xpad->udev, GIP_WIRED_INTF_AUDIO)) {
                /*
                 * Controller for Series X|S (0x20d6:0x200e) to report the
                 * guide button.
                 */
-               retval = usb_set_interface(xpad->udev,
-                                          GIP_WIRED_INTF_AUDIO, 0);
-               if (retval)
+               error = usb_set_interface(xpad->udev,
+                                         GIP_WIRED_INTF_AUDIO, 0);
+               if (error)
                        dev_warn(&xpad->dev->dev,
                                 "unable to disable audio interface: %d\n",
-                                retval);
+                                error);
        }
  
-       spin_lock_irqsave(&xpad->odata_lock, flags);
+       guard(spinlock_irqsave)(&xpad->odata_lock);
  
        /*
         * Begin the init sequence by attempting to send a packet.
         * sending any packets from the output ring.
         */
        xpad->init_seq = 0;
-       retval = xpad_try_sending_next_out_packet(xpad);
-       spin_unlock_irqrestore(&xpad->odata_lock, flags);
-       return retval;
+       return xpad_try_sending_next_out_packet(xpad);
  }
  
  static void xpadone_ack_mode_report(struct usb_xpad *xpad, u8 seq_num)
  {
-       unsigned long flags;
        struct xpad_output_packet *packet =
                        &xpad->out_packets[XPAD_OUT_CMD_IDX];
        static const u8 mode_report_ack[] = {
                0x00, GIP_CMD_VIRTUAL_KEY, GIP_OPT_INTERNAL, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00
        };
  
-       spin_lock_irqsave(&xpad->odata_lock, flags);
+       guard(spinlock_irqsave)(&xpad->odata_lock);
  
        packet->len = sizeof(mode_report_ack);
        memcpy(packet->data, mode_report_ack, packet->len);
        /* Reset the sequence so we send out the ack now */
        xpad->last_out_packet = -1;
        xpad_try_sending_next_out_packet(xpad);
-       spin_unlock_irqrestore(&xpad->odata_lock, flags);
  }
  
  #ifdef CONFIG_JOYSTICK_XPAD_FF
@@@ -1489,8 -1469,6 +1472,6 @@@ static int xpad_play_effect(struct inpu
        struct xpad_output_packet *packet = &xpad->out_packets[XPAD_OUT_FF_IDX];
        __u16 strong;
        __u16 weak;
-       int retval;
-       unsigned long flags;
  
        if (effect->type != FF_RUMBLE)
                return 0;
        strong = effect->u.rumble.strong_magnitude;
        weak = effect->u.rumble.weak_magnitude;
  
-       spin_lock_irqsave(&xpad->odata_lock, flags);
+       guard(spinlock_irqsave)(&xpad->odata_lock);
  
        switch (xpad->xtype) {
        case XTYPE_XBOX:
                dev_dbg(&xpad->dev->dev,
                        "%s - rumble command sent to unsupported xpad type: %d\n",
                        __func__, xpad->xtype);
-               retval = -EINVAL;
-               goto out;
+               return -EINVAL;
        }
  
-       retval = xpad_try_sending_next_out_packet(xpad);
- out:
-       spin_unlock_irqrestore(&xpad->odata_lock, flags);
-       return retval;
+       return xpad_try_sending_next_out_packet(xpad);
  }
  
  static int xpad_init_ff(struct usb_xpad *xpad)
@@@ -1625,11 -1598,10 +1601,10 @@@ static void xpad_send_led_command(struc
  {
        struct xpad_output_packet *packet =
                        &xpad->out_packets[XPAD_OUT_LED_IDX];
-       unsigned long flags;
  
        command %= 16;
  
-       spin_lock_irqsave(&xpad->odata_lock, flags);
+       guard(spinlock_irqsave)(&xpad->odata_lock);
  
        switch (xpad->xtype) {
        case XTYPE_XBOX360:
        }
  
        xpad_try_sending_next_out_packet(xpad);
-       spin_unlock_irqrestore(&xpad->odata_lock, flags);
  }
  
  /*
@@@ -1785,11 -1755,10 +1758,10 @@@ static void xpad_stop_input(struct usb_
  
  static void xpad360w_poweroff_controller(struct usb_xpad *xpad)
  {
-       unsigned long flags;
        struct xpad_output_packet *packet =
                        &xpad->out_packets[XPAD_OUT_CMD_IDX];
  
-       spin_lock_irqsave(&xpad->odata_lock, flags);
+       guard(spinlock_irqsave)(&xpad->odata_lock);
  
        packet->data[0] = 0x00;
        packet->data[1] = 0x00;
        /* Reset the sequence so we send out poweroff now */
        xpad->last_out_packet = -1;
        xpad_try_sending_next_out_packet(xpad);
-       spin_unlock_irqrestore(&xpad->odata_lock, flags);
  }
  
  static int xpad360w_start_input(struct usb_xpad *xpad)
@@@ -2234,10 -2201,10 +2204,10 @@@ static int xpad_suspend(struct usb_inte
                if (auto_poweroff && xpad->pad_present)
                        xpad360w_poweroff_controller(xpad);
        } else {
-               mutex_lock(&input->mutex);
+               guard(mutex)(&input->mutex);
                if (input_device_enabled(input))
                        xpad_stop_input(xpad);
-               mutex_unlock(&input->mutex);
        }
  
        xpad_stop_output(xpad);
@@@ -2249,26 -2216,25 +2219,25 @@@ static int xpad_resume(struct usb_inter
  {
        struct usb_xpad *xpad = usb_get_intfdata(intf);
        struct input_dev *input = xpad->dev;
-       int retval = 0;
  
-       if (xpad->xtype == XTYPE_XBOX360W) {
-               retval = xpad360w_start_input(xpad);
-       } else {
-               mutex_lock(&input->mutex);
-               if (input_device_enabled(input)) {
-                       retval = xpad_start_input(xpad);
-               } else if (xpad->xtype == XTYPE_XBOXONE) {
-                       /*
-                        * Even if there are no users, we'll send Xbox One pads
-                        * the startup sequence so they don't sit there and
-                        * blink until somebody opens the input device again.
-                        */
-                       retval = xpad_start_xbox_one(xpad);
-               }
-               mutex_unlock(&input->mutex);
+       if (xpad->xtype == XTYPE_XBOX360W)
+               return xpad360w_start_input(xpad);
+       guard(mutex)(&input->mutex);
+       if (input_device_enabled(input))
+               return xpad_start_input(xpad);
+       if (xpad->xtype == XTYPE_XBOXONE) {
+               /*
+                * Even if there are no users, we'll send Xbox One pads
+                * the startup sequence so they don't sit there and
+                * blink until somebody opens the input device again.
+                */
+               return xpad_start_xbox_one(xpad);
        }
  
-       return retval;
+       return 0;
  }
  
  static struct usb_driver xpad_driver = {
index 922d3ab998f3a5dfbaf277f10eb19e5cd1b35415,735d96b056d40b7050ce76409785a7f61a20351c..81d0876ee358ef4b521f3f936dc2ab108bb4cda3
@@@ -391,17 -391,10 +391,17 @@@ static int adp5589_gpio_get_value(struc
        struct adp5589_kpad *kpad = gpiochip_get_data(chip);
        unsigned int bank = kpad->var->bank(kpad->gpiomap[off]);
        unsigned int bit = kpad->var->bit(kpad->gpiomap[off]);
 +      int val;
  
 -      return !!(adp5589_read(kpad->client,
 -                             kpad->var->reg(ADP5589_GPI_STATUS_A) + bank) &
 -                             bit);
 +      mutex_lock(&kpad->gpio_lock);
 +      if (kpad->dir[bank] & bit)
 +              val = kpad->dat_out[bank];
 +      else
 +              val = adp5589_read(kpad->client,
 +                                 kpad->var->reg(ADP5589_GPI_STATUS_A) + bank);
 +      mutex_unlock(&kpad->gpio_lock);
 +
 +      return !!(val & bit);
  }
  
  static void adp5589_gpio_set_value(struct gpio_chip *chip,
        unsigned int bank = kpad->var->bank(kpad->gpiomap[off]);
        unsigned int bit = kpad->var->bit(kpad->gpiomap[off]);
  
-       mutex_lock(&kpad->gpio_lock);
+       guard(mutex)(&kpad->gpio_lock);
  
        if (val)
                kpad->dat_out[bank] |= bit;
  
        adp5589_write(kpad->client, kpad->var->reg(ADP5589_GPO_DATA_OUT_A) +
                      bank, kpad->dat_out[bank]);
-       mutex_unlock(&kpad->gpio_lock);
  }
  
  static int adp5589_gpio_direction_input(struct gpio_chip *chip, unsigned off)
        struct adp5589_kpad *kpad = gpiochip_get_data(chip);
        unsigned int bank = kpad->var->bank(kpad->gpiomap[off]);
        unsigned int bit = kpad->var->bit(kpad->gpiomap[off]);
-       int ret;
  
-       mutex_lock(&kpad->gpio_lock);
+       guard(mutex)(&kpad->gpio_lock);
  
        kpad->dir[bank] &= ~bit;
-       ret = adp5589_write(kpad->client,
-                           kpad->var->reg(ADP5589_GPIO_DIRECTION_A) + bank,
-                           kpad->dir[bank]);
-       mutex_unlock(&kpad->gpio_lock);
-       return ret;
+       return adp5589_write(kpad->client,
+                            kpad->var->reg(ADP5589_GPIO_DIRECTION_A) + bank,
+                            kpad->dir[bank]);
  }
  
  static int adp5589_gpio_direction_output(struct gpio_chip *chip,
        struct adp5589_kpad *kpad = gpiochip_get_data(chip);
        unsigned int bank = kpad->var->bank(kpad->gpiomap[off]);
        unsigned int bit = kpad->var->bit(kpad->gpiomap[off]);
-       int ret;
+       int error;
  
-       mutex_lock(&kpad->gpio_lock);
+       guard(mutex)(&kpad->gpio_lock);
  
        kpad->dir[bank] |= bit;
  
        else
                kpad->dat_out[bank] &= ~bit;
  
-       ret = adp5589_write(kpad->client, kpad->var->reg(ADP5589_GPO_DATA_OUT_A)
-                           + bank, kpad->dat_out[bank]);
-       ret |= adp5589_write(kpad->client,
-                            kpad->var->reg(ADP5589_GPIO_DIRECTION_A) + bank,
-                            kpad->dir[bank]);
+       error = adp5589_write(kpad->client,
+                             kpad->var->reg(ADP5589_GPO_DATA_OUT_A) + bank,
+                             kpad->dat_out[bank]);
+       if (error)
+               return error;
  
-       mutex_unlock(&kpad->gpio_lock);
+       error = adp5589_write(kpad->client,
+                             kpad->var->reg(ADP5589_GPIO_DIRECTION_A) + bank,
+                             kpad->dir[bank]);
+       if (error)
+               return error;
  
-       return ret;
+       return 0;
  }
  
  static int adp5589_build_gpiomap(struct adp5589_kpad *kpad,
@@@ -943,9 -933,10 +940,9 @@@ static int adp5589_keypad_add(struct ad
  
  static void adp5589_clear_config(void *data)
  {
 -      struct i2c_client *client = data;
 -      struct adp5589_kpad *kpad = i2c_get_clientdata(client);
 +      struct adp5589_kpad *kpad = data;
  
 -      adp5589_write(client, kpad->var->reg(ADP5589_GENERAL_CFG), 0);
 +      adp5589_write(kpad->client, kpad->var->reg(ADP5589_GENERAL_CFG), 0);
  }
  
  static int adp5589_probe(struct i2c_client *client)
        }
  
        error = devm_add_action_or_reset(&client->dev, adp5589_clear_config,
 -                                       client);
 +                                       kpad);
        if (error)
                return error;
  
        if (error)
                return error;
  
 -      i2c_set_clientdata(client, kpad);
 -
        dev_info(&client->dev, "Rev.%d keypad, irq %d\n", revid, client->irq);
        return 0;
  }
index 34d1f07ea4c30470b9bdfb8c9a0615cf5a3d5675,d236469032b171f139a6ea38ad76a4ca0173662e..127cfdc8668a0912b2964d6c7c7e428b5e4aba24
@@@ -90,7 -90,7 +90,7 @@@ static inline void i8042_write_command(
   * ORDERING IS IMPORTANT! The first match will be apllied and the rest ignored.
   * This allows entries to overwrite vendor wide quirks on a per device basis.
   * Where this is irrelevant, entries are sorted case sensitive by DMI_SYS_VENDOR
-  * and/or DMI_BOARD_VENDOR to make it easier to avoid dublicate entries.
+  * and/or DMI_BOARD_VENDOR to make it easier to avoid duplicate entries.
   */
  static const struct dmi_system_id i8042_dmi_quirk_table[] __initconst = {
        {
                },
                .driver_data = (void *)(SERIO_QUIRK_NOLOOP)
        },
 +      /*
 +       * Some TongFang barebones have touchpad and/or keyboard issues after
 +       * suspend fixable with nomux + reset + noloop + nopnp. Luckily, none of
 +       * them have an external PS/2 port so this can safely be set for all of
 +       * them.
 +       * TongFang barebones come with board_vendor and/or system_vendor set to
 +       * a different value for each individual reseller. The only somewhat
 +       * universal way to identify them is by board_name.
 +       */
 +      {
 +              .matches = {
 +                      DMI_MATCH(DMI_BOARD_NAME, "GM6XGxX"),
 +              },
 +              .driver_data = (void *)(SERIO_QUIRK_NOMUX | SERIO_QUIRK_RESET_ALWAYS |
 +                                      SERIO_QUIRK_NOLOOP | SERIO_QUIRK_NOPNP)
 +      },
 +      {
 +              .matches = {
 +                      DMI_MATCH(DMI_BOARD_NAME, "GMxXGxx"),
 +              },
 +              .driver_data = (void *)(SERIO_QUIRK_NOMUX | SERIO_QUIRK_RESET_ALWAYS |
 +                                      SERIO_QUIRK_NOLOOP | SERIO_QUIRK_NOPNP)
 +      },
 +      {
 +              .matches = {
 +                      DMI_MATCH(DMI_BOARD_NAME, "GMxXGxX"),
 +              },
 +              .driver_data = (void *)(SERIO_QUIRK_NOMUX | SERIO_QUIRK_RESET_ALWAYS |
 +                                      SERIO_QUIRK_NOLOOP | SERIO_QUIRK_NOPNP)
 +      },
 +      {
 +              .matches = {
 +                      DMI_MATCH(DMI_BOARD_NAME, "GMxHGxx"),
 +              },
 +              .driver_data = (void *)(SERIO_QUIRK_NOMUX | SERIO_QUIRK_RESET_ALWAYS |
 +                                      SERIO_QUIRK_NOLOOP | SERIO_QUIRK_NOPNP)
 +      },
        /*
         * A lot of modern Clevo barebones have touchpad and/or keyboard issues
         * after suspend fixable with nomux + reset + noloop + nopnp. Luckily,
index 126b0ed85aa50c2cc21fae2a9d9bec2665e5284c,8c77e9f347c52f2ef9b16da254e4f2ca4816bbcd..b6a66bd370d03c949bc6c47419875fe2387a1b04
@@@ -1121,14 -1121,6 +1121,14 @@@ static void edt_ft5x06_ts_set_regs(stru
        }
  }
  
 +static void edt_ft5x06_exit_regmap(void *arg)
 +{
 +      struct edt_ft5x06_ts_data *data = arg;
 +
 +      if (!IS_ERR_OR_NULL(data->regmap))
 +              regmap_exit(data->regmap);
 +}
 +
  static void edt_ft5x06_disable_regulators(void *arg)
  {
        struct edt_ft5x06_ts_data *data = arg;
@@@ -1162,16 -1154,6 +1162,16 @@@ static int edt_ft5x06_ts_probe(struct i
                return PTR_ERR(tsdata->regmap);
        }
  
 +      /*
 +       * We are not using devm_regmap_init_i2c() and instead install a
 +       * custom action because we may replace regmap with M06-specific one
 +       * and we need to make sure that it will not be released too early.
 +       */
 +      error = devm_add_action_or_reset(&client->dev, edt_ft5x06_exit_regmap,
 +                                       tsdata);
 +      if (error)
 +              return error;
 +
        chip_data = device_get_match_data(&client->dev);
        if (!chip_data)
                chip_data = (const struct edt_i2c_chip_data *)id->driver_data;
        }
  
        /*
-        * Check which sleep modes we can support. Power-off requieres the
+        * Check which sleep modes we can support. Power-off requires the
         * reset-pin to ensure correct power-down/power-up behaviour. Start with
         * the EDT_PMODE_POWEROFF test since this is the deepest possible sleep
         * mode.
@@@ -1365,6 -1347,7 +1365,6 @@@ static void edt_ft5x06_ts_remove(struc
        struct edt_ft5x06_ts_data *tsdata = i2c_get_clientdata(client);
  
        edt_ft5x06_ts_teardown_debugfs(tsdata);
 -      regmap_exit(tsdata->regmap);
  }
  
  static int edt_ft5x06_ts_suspend(struct device *dev)
diff --combined include/linux/input.h
index cd866b020a01d67081788e1baa2d372ce1c79767,6437c35f07968378d2670fee1bfa193f4a158f8b..7d7cb0593a63e93c4906c49cde430188db2d1ab5
@@@ -286,6 -286,10 +286,10 @@@ struct input_handle
   * @start: starts handler for given handle. This function is called by
   *    input core right after connect() method and also when a process
   *    that "grabbed" a device releases it
+  * @passive_observer: set to %true by drivers only interested in observing
+  *    data stream from devices if there are other users present. Such
+  *    drivers will not result in starting underlying hardware device
+  *    when input_open_device() is called for their handles
   * @legacy_minors: set to %true by drivers using legacy minor ranges
   * @minor: beginning of range of 32 legacy minors for devices this driver
   *    can provide
@@@ -321,6 -325,7 +325,7 @@@ struct input_handler 
        void (*disconnect)(struct input_handle *handle);
        void (*start)(struct input_handle *handle);
  
+       bool passive_observer;
        bool legacy_minors;
        int minor;
        const char *name;
   * @name: name given to the handle by handler that created it
   * @dev: input device the handle is attached to
   * @handler: handler that works with the device through this handle
 + * @handle_events: event sequence handler. It is set up by the input core
 + *    according to event handling method specified in the @handler. See
 + *    input_handle_setup_event_handler().
 + *    This method is being called by the input core with interrupts disabled
 + *    and dev->event_lock spinlock held and so it may not sleep.
   * @d_node: used to put the handle on device's list of attached handles
   * @h_node: used to put the handle on handler's list of handles from which
   *    it gets events
   */
  struct input_handle {
 -
        void *private;
  
        int open;
        struct input_dev *dev;
        struct input_handler *handler;
  
 +      unsigned int (*handle_events)(struct input_handle *handle,
 +                                    struct input_value *vals,
 +                                    unsigned int count);
 +
        struct list_head        d_node;
        struct list_head        h_node;
  };
This page took 0.11885 seconds and 4 git commands to generate.