]> Pileus Git - ~andy/linux/commitdiff
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input
authorLinus Torvalds <torvalds@linux-foundation.org>
Wed, 1 May 2013 20:20:04 +0000 (13:20 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Wed, 1 May 2013 20:20:04 +0000 (13:20 -0700)
Pull input updates from Dmitry Torokhov:
 "Assorted fixes and cleanups to the existing drivers plus a new driver
  for IMS Passenger Control Unit device they use for ther in-flight
  entertainment system."

* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input: (44 commits)
  Input: trackpoint - Optimize trackpoint init to use power-on reset
  Input: apbps2 - convert to devm_ioremap_resource()
  Input: ALPS - use %ph to print buffers
  ARM - shmobile: Armadillo800EVA: Move st1232 reset pin handling
  Input: st1232 - add reset pin handling
  Input: st1232 - convert to devm_* infrastructure
  Input: MT - handle semi-mt devices in core
  Input: adxl34x - use spi_get_drvdata()
  Input: ad7877 - use spi_get_drvdata() and spi_set_drvdata()
  Input: ads7846 - use spi_get_drvdata() and spi_set_drvdata()
  Input: ims-pcu - fix a memory leak on error
  Input: sysrq - supplement reset sequence with timeout functionality
  Input: tegra-kbc - support for defining row/columns based on SoC
  Input: imx_keypad - switch to using managed resources
  Input: arc_ps2 - add support for device tree
  Input: mma8450 - fix signed 12bits to 32bits conversion
  Input: eeti_ts - remove redundant null check
  Input: edt-ft5x06 - remove redundant null check before kfree
  Input: ad714x - add CONFIG_PM_SLEEP to suspend/resume functions
  Input: adxl34x - add CONFIG_PM_SLEEP to suspend/resume functions
  ...

1  2 
arch/arm/mach-shmobile/board-armadillo800eva.c
drivers/tty/sysrq.c
drivers/usb/class/cdc-acm.c
include/linux/device.h

index ff8b7ba9b93c9d34337f7c838c65358e2a24a3da,5dc09358fedd4b64dc859878ddfdc5683c42b381..881e5c0e41ddcbffbcbd89eb488f219c12d0f9c0
@@@ -24,6 -24,7 +24,7 @@@
  #include <linux/err.h>
  #include <linux/kernel.h>
  #include <linux/input.h>
+ #include <linux/platform_data/st1232_pdata.h>
  #include <linux/irq.h>
  #include <linux/platform_device.h>
  #include <linux/gpio.h>
@@@ -169,7 -170,7 +170,7 @@@ static int usbhsf_get_id(struct platfor
        return USBHS_GADGET;
  }
  
 -static void usbhsf_power_ctrl(struct platform_device *pdev,
 +static int usbhsf_power_ctrl(struct platform_device *pdev,
                              void __iomem *base, int enable)
  {
        struct usbhsf_private *priv = usbhsf_get_priv(pdev);
                clk_disable(priv->pci);         /* usb work around */
                clk_disable(priv->usb24);       /* usb work around */
        }
 +
 +      return 0;
  }
  
  static int usbhsf_get_vbus(struct platform_device *pdev)
@@@ -241,7 -240,7 +242,7 @@@ static irqreturn_t usbhsf_interrupt(in
        return IRQ_HANDLED;
  }
  
 -static void usbhsf_hardware_exit(struct platform_device *pdev)
 +static int usbhsf_hardware_exit(struct platform_device *pdev)
  {
        struct usbhsf_private *priv = usbhsf_get_priv(pdev);
  
        priv->usbh_base = NULL;
  
        free_irq(IRQ7, pdev);
 +
 +      return 0;
  }
  
  static int usbhsf_hardware_init(struct platform_device *pdev)
@@@ -882,10 -879,15 +883,15 @@@ static struct platform_device i2c_gpio_
  };
  
  /* I2C */
+ static struct st1232_pdata st1232_i2c0_pdata = {
+       .reset_gpio = 166,
+ };
  static struct i2c_board_info i2c0_devices[] = {
        {
                I2C_BOARD_INFO("st1232-ts", 0x55),
                .irq = evt2irq(0x0340),
+               .platform_data = &st1232_i2c0_pdata,
        },
        {
                I2C_BOARD_INFO("wm8978", 0x1a),
@@@ -1009,7 -1011,6 +1015,6 @@@ static void __init eva_init(void
  
        /* Touchscreen */
        gpio_request(GPIO_FN_IRQ10,     NULL); /* TP_INT */
-       gpio_request_one(GPIO_PORT166, GPIOF_OUT_INIT_HIGH, NULL); /* TP_RST_B */
  
        /* GETHER */
        gpio_request(GPIO_FN_ET_CRS,            NULL);
diff --combined drivers/tty/sysrq.c
index 0a0de333c765992615326a66a5862116a3b00cb7,b6b267d939a07bdba1c776bb7f5984fc76f77ed0..b51c15408ff317980205880dae4961e1db793eb4
@@@ -43,6 -43,7 +43,7 @@@
  #include <linux/input.h>
  #include <linux/uaccess.h>
  #include <linux/moduleparam.h>
+ #include <linux/jiffies.h>
  
  #include <asm/ptrace.h>
  #include <asm/irq_regs.h>
@@@ -51,6 -52,9 +52,9 @@@
  static int __read_mostly sysrq_enabled = SYSRQ_DEFAULT_ENABLE;
  static bool __read_mostly sysrq_always_enabled;
  
+ unsigned short platform_sysrq_reset_seq[] __weak = { KEY_RESERVED };
+ int sysrq_reset_downtime_ms __weak;
  static bool sysrq_on(void)
  {
        return sysrq_enabled || sysrq_always_enabled;
@@@ -101,7 -105,7 +105,7 @@@ static void sysrq_handle_SAK(int key
  }
  static struct sysrq_key_op sysrq_SAK_op = {
        .handler        = sysrq_handle_SAK,
 -      .help_msg       = "saK",
 +      .help_msg       = "sak(k)",
        .action_msg     = "SAK",
        .enable_mask    = SYSRQ_ENABLE_KEYBOARD,
  };
@@@ -117,7 -121,7 +121,7 @@@ static void sysrq_handle_unraw(int key
  
  static struct sysrq_key_op sysrq_unraw_op = {
        .handler        = sysrq_handle_unraw,
 -      .help_msg       = "unRaw",
 +      .help_msg       = "unraw(r)",
        .action_msg     = "Keyboard mode set to system default",
        .enable_mask    = SYSRQ_ENABLE_KEYBOARD,
  };
@@@ -135,7 -139,7 +139,7 @@@ static void sysrq_handle_crash(int key
  }
  static struct sysrq_key_op sysrq_crash_op = {
        .handler        = sysrq_handle_crash,
 -      .help_msg       = "Crash",
 +      .help_msg       = "crash(c)",
        .action_msg     = "Trigger a crash",
        .enable_mask    = SYSRQ_ENABLE_DUMP,
  };
@@@ -148,7 -152,7 +152,7 @@@ static void sysrq_handle_reboot(int key
  }
  static struct sysrq_key_op sysrq_reboot_op = {
        .handler        = sysrq_handle_reboot,
 -      .help_msg       = "reBoot",
 +      .help_msg       = "reboot(b)",
        .action_msg     = "Resetting",
        .enable_mask    = SYSRQ_ENABLE_BOOT,
  };
@@@ -159,7 -163,7 +163,7 @@@ static void sysrq_handle_sync(int key
  }
  static struct sysrq_key_op sysrq_sync_op = {
        .handler        = sysrq_handle_sync,
 -      .help_msg       = "Sync",
 +      .help_msg       = "sync(s)",
        .action_msg     = "Emergency Sync",
        .enable_mask    = SYSRQ_ENABLE_SYNC,
  };
@@@ -171,7 -175,7 +175,7 @@@ static void sysrq_handle_show_timers(in
  
  static struct sysrq_key_op sysrq_show_timers_op = {
        .handler        = sysrq_handle_show_timers,
 -      .help_msg       = "show-all-timers(Q)",
 +      .help_msg       = "show-all-timers(q)",
        .action_msg     = "Show clockevent devices & pending hrtimers (no others)",
  };
  
@@@ -181,7 -185,7 +185,7 @@@ static void sysrq_handle_mountro(int ke
  }
  static struct sysrq_key_op sysrq_mountro_op = {
        .handler        = sysrq_handle_mountro,
 -      .help_msg       = "Unmount",
 +      .help_msg       = "unmount(u)",
        .action_msg     = "Emergency Remount R/O",
        .enable_mask    = SYSRQ_ENABLE_REMOUNT,
  };
@@@ -194,7 -198,7 +198,7 @@@ static void sysrq_handle_showlocks(int 
  
  static struct sysrq_key_op sysrq_showlocks_op = {
        .handler        = sysrq_handle_showlocks,
 -      .help_msg       = "show-all-locks(D)",
 +      .help_msg       = "show-all-locks(d)",
        .action_msg     = "Show Locks Held",
  };
  #else
@@@ -245,7 -249,7 +249,7 @@@ static void sysrq_handle_showallcpus(in
  
  static struct sysrq_key_op sysrq_showallcpus_op = {
        .handler        = sysrq_handle_showallcpus,
 -      .help_msg       = "show-backtrace-all-active-cpus(L)",
 +      .help_msg       = "show-backtrace-all-active-cpus(l)",
        .action_msg     = "Show backtrace of all active CPUs",
        .enable_mask    = SYSRQ_ENABLE_DUMP,
  };
@@@ -260,7 -264,7 +264,7 @@@ static void sysrq_handle_showregs(int k
  }
  static struct sysrq_key_op sysrq_showregs_op = {
        .handler        = sysrq_handle_showregs,
 -      .help_msg       = "show-registers(P)",
 +      .help_msg       = "show-registers(p)",
        .action_msg     = "Show Regs",
        .enable_mask    = SYSRQ_ENABLE_DUMP,
  };
@@@ -271,7 -275,7 +275,7 @@@ static void sysrq_handle_showstate(int 
  }
  static struct sysrq_key_op sysrq_showstate_op = {
        .handler        = sysrq_handle_showstate,
 -      .help_msg       = "show-task-states(T)",
 +      .help_msg       = "show-task-states(t)",
        .action_msg     = "Show State",
        .enable_mask    = SYSRQ_ENABLE_DUMP,
  };
@@@ -282,7 -286,7 +286,7 @@@ static void sysrq_handle_showstate_bloc
  }
  static struct sysrq_key_op sysrq_showstate_blocked_op = {
        .handler        = sysrq_handle_showstate_blocked,
 -      .help_msg       = "show-blocked-tasks(W)",
 +      .help_msg       = "show-blocked-tasks(w)",
        .action_msg     = "Show Blocked State",
        .enable_mask    = SYSRQ_ENABLE_DUMP,
  };
@@@ -296,7 -300,7 +300,7 @@@ static void sysrq_ftrace_dump(int key
  }
  static struct sysrq_key_op sysrq_ftrace_dump_op = {
        .handler        = sysrq_ftrace_dump,
 -      .help_msg       = "dump-ftrace-buffer(Z)",
 +      .help_msg       = "dump-ftrace-buffer(z)",
        .action_msg     = "Dump ftrace buffer",
        .enable_mask    = SYSRQ_ENABLE_DUMP,
  };
@@@ -310,7 -314,7 +314,7 @@@ static void sysrq_handle_showmem(int ke
  }
  static struct sysrq_key_op sysrq_showmem_op = {
        .handler        = sysrq_handle_showmem,
 -      .help_msg       = "show-memory-usage(M)",
 +      .help_msg       = "show-memory-usage(m)",
        .action_msg     = "Show Memory",
        .enable_mask    = SYSRQ_ENABLE_DUMP,
  };
@@@ -341,7 -345,7 +345,7 @@@ static void sysrq_handle_term(int key
  }
  static struct sysrq_key_op sysrq_term_op = {
        .handler        = sysrq_handle_term,
 -      .help_msg       = "terminate-all-tasks(E)",
 +      .help_msg       = "terminate-all-tasks(e)",
        .action_msg     = "Terminate All Tasks",
        .enable_mask    = SYSRQ_ENABLE_SIGNAL,
  };
@@@ -360,7 -364,7 +364,7 @@@ static void sysrq_handle_moom(int key
  }
  static struct sysrq_key_op sysrq_moom_op = {
        .handler        = sysrq_handle_moom,
 -      .help_msg       = "memory-full-oom-kill(F)",
 +      .help_msg       = "memory-full-oom-kill(f)",
        .action_msg     = "Manual OOM execution",
        .enable_mask    = SYSRQ_ENABLE_SIGNAL,
  };
@@@ -372,7 -376,7 +376,7 @@@ static void sysrq_handle_thaw(int key
  }
  static struct sysrq_key_op sysrq_thaw_op = {
        .handler        = sysrq_handle_thaw,
 -      .help_msg       = "thaw-filesystems(J)",
 +      .help_msg       = "thaw-filesystems(j)",
        .action_msg     = "Emergency Thaw of all frozen filesystems",
        .enable_mask    = SYSRQ_ENABLE_SIGNAL,
  };
@@@ -385,7 -389,7 +389,7 @@@ static void sysrq_handle_kill(int key
  }
  static struct sysrq_key_op sysrq_kill_op = {
        .handler        = sysrq_handle_kill,
 -      .help_msg       = "kill-all-tasks(I)",
 +      .help_msg       = "kill-all-tasks(i)",
        .action_msg     = "Kill All Tasks",
        .enable_mask    = SYSRQ_ENABLE_SIGNAL,
  };
@@@ -396,7 -400,7 +400,7 @@@ static void sysrq_handle_unrt(int key
  }
  static struct sysrq_key_op sysrq_unrt_op = {
        .handler        = sysrq_handle_unrt,
 -      .help_msg       = "nice-all-RT-tasks(N)",
 +      .help_msg       = "nice-all-RT-tasks(n)",
        .action_msg     = "Nice All RT Tasks",
        .enable_mask    = SYSRQ_ENABLE_RTNICE,
  };
@@@ -586,6 -590,7 +590,7 @@@ struct sysrq_state 
        int reset_seq_len;
        int reset_seq_cnt;
        int reset_seq_version;
+       struct timer_list keyreset_timer;
  };
  
  #define SYSRQ_KEY_RESET_MAX   20 /* Should be plenty */
@@@ -619,29 -624,51 +624,51 @@@ static void sysrq_parse_reset_sequence(
        state->reset_seq_version = sysrq_reset_seq_version;
  }
  
- static bool sysrq_detect_reset_sequence(struct sysrq_state *state,
+ static void sysrq_do_reset(unsigned long dummy)
+ {
+       __handle_sysrq(sysrq_xlate[KEY_B], false);
+ }
+ static void sysrq_handle_reset_request(struct sysrq_state *state)
+ {
+       if (sysrq_reset_downtime_ms)
+               mod_timer(&state->keyreset_timer,
+                       jiffies + msecs_to_jiffies(sysrq_reset_downtime_ms));
+       else
+               sysrq_do_reset(0);
+ }
+ static void sysrq_detect_reset_sequence(struct sysrq_state *state,
                                        unsigned int code, int value)
  {
        if (!test_bit(code, state->reset_keybit)) {
                /*
                 * Pressing any key _not_ in reset sequence cancels
-                * the reset sequence.
+                * the reset sequence.  Also cancelling the timer in
+                * case additional keys were pressed after a reset
+                * has been requested.
                 */
-               if (value && state->reset_seq_cnt)
+               if (value && state->reset_seq_cnt) {
                        state->reset_canceled = true;
+                       del_timer(&state->keyreset_timer);
+               }
        } else if (value == 0) {
-               /* key release */
+               /*
+                * Key release - all keys in the reset sequence need
+                * to be pressed and held for the reset timeout
+                * to hold.
+                */
+               del_timer(&state->keyreset_timer);
                if (--state->reset_seq_cnt == 0)
                        state->reset_canceled = false;
        } else if (value == 1) {
                /* key press, not autorepeat */
                if (++state->reset_seq_cnt == state->reset_seq_len &&
                    !state->reset_canceled) {
-                       return true;
+                       sysrq_handle_reset_request(state);
                }
        }
-       return false;
  }
  
  static void sysrq_reinject_alt_sysrq(struct work_struct *work)
@@@ -748,10 -775,8 +775,8 @@@ static bool sysrq_handle_keypress(struc
                if (was_active)
                        schedule_work(&sysrq->reinject_work);
  
-               if (sysrq_detect_reset_sequence(sysrq, code, value)) {
-                       /* Force emergency reboot */
-                       __handle_sysrq(sysrq_xlate[KEY_B], false);
-               }
+               /* Check for reset sequence */
+               sysrq_detect_reset_sequence(sysrq, code, value);
  
        } else if (value == 0 && test_and_clear_bit(code, sysrq->key_down)) {
                /*
@@@ -812,6 -837,7 +837,7 @@@ static int sysrq_connect(struct input_h
        sysrq->handle.handler = handler;
        sysrq->handle.name = "sysrq";
        sysrq->handle.private = sysrq;
+       setup_timer(&sysrq->keyreset_timer, sysrq_do_reset, 0);
  
        error = input_register_handle(&sysrq->handle);
        if (error) {
@@@ -841,6 -867,7 +867,7 @@@ static void sysrq_disconnect(struct inp
  
        input_close_device(handle);
        cancel_work_sync(&sysrq->reinject_work);
+       del_timer_sync(&sysrq->keyreset_timer);
        input_unregister_handle(handle);
        kfree(sysrq);
  }
@@@ -870,8 -897,6 +897,6 @@@ static struct input_handler sysrq_handl
  
  static bool sysrq_handler_registered;
  
- unsigned short platform_sysrq_reset_seq[] __weak = { KEY_RESERVED };
  static inline void sysrq_register_handler(void)
  {
        unsigned short key;
@@@ -931,6 -956,8 +956,8 @@@ static struct kernel_param_ops param_op
  module_param_array_named(reset_seq, sysrq_reset_seq, sysrq_reset_seq,
                         &sysrq_reset_seq_len, 0644);
  
+ module_param_named(sysrq_downtime_ms, sysrq_reset_downtime_ms, int, 0644);
  #else
  
  static inline void sysrq_register_handler(void)
index 171d7a9df3aedd31fe660b4a7fec2cb5f9e1e6d8,cb8ef3ef5c94012de4bb1ebb0b5cb595df97e99d..9b1cbcf8fb7fcfbd0f3b576d207a90dd4421c62f
@@@ -292,6 -292,7 +292,6 @@@ static void acm_ctrl_irq(struct urb *ur
  {
        struct acm *acm = urb->context;
        struct usb_cdc_notification *dr = urb->transfer_buffer;
 -      struct tty_struct *tty;
        unsigned char *data;
        int newctrl;
        int retval;
                break;
  
        case USB_CDC_NOTIFY_SERIAL_STATE:
 -              tty = tty_port_tty_get(&acm->port);
                newctrl = get_unaligned_le16(data);
  
 -              if (tty) {
 -                      if (!acm->clocal &&
 -                              (acm->ctrlin & ~newctrl & ACM_CTRL_DCD)) {
 -                              dev_dbg(&acm->control->dev,
 -                                      "%s - calling hangup\n", __func__);
 -                              tty_hangup(tty);
 -                      }
 -                      tty_kref_put(tty);
 +              if (!acm->clocal && (acm->ctrlin & ~newctrl & ACM_CTRL_DCD)) {
 +                      dev_dbg(&acm->control->dev, "%s - calling hangup\n",
 +                                      __func__);
 +                      tty_port_tty_hangup(&acm->port, false);
                }
  
                acm->ctrlin = newctrl;
@@@ -469,10 -475,15 +469,10 @@@ static void acm_write_bulk(struct urb *
  static void acm_softint(struct work_struct *work)
  {
        struct acm *acm = container_of(work, struct acm, work);
 -      struct tty_struct *tty;
  
        dev_vdbg(&acm->data->dev, "%s\n", __func__);
  
 -      tty = tty_port_tty_get(&acm->port);
 -      if (!tty)
 -              return;
 -      tty_wakeup(tty);
 -      tty_kref_put(tty);
 +      tty_port_tty_wakeup(&acm->port);
  }
  
  /*
@@@ -582,6 -593,7 +582,6 @@@ static void acm_port_destruct(struct tt
  
        dev_dbg(&acm->control->dev, "%s\n", __func__);
  
 -      tty_unregister_device(acm_tty_driver, acm->minor);
        acm_release_minor(acm);
        usb_put_intf(acm->control);
        kfree(acm->country_codes);
@@@ -828,6 -840,14 +828,6 @@@ static int acm_tty_ioctl(struct tty_str
        return rv;
  }
  
 -static const __u32 acm_tty_speed[] = {
 -      0, 50, 75, 110, 134, 150, 200, 300, 600,
 -      1200, 1800, 2400, 4800, 9600, 19200, 38400,
 -      57600, 115200, 230400, 460800, 500000, 576000,
 -      921600, 1000000, 1152000, 1500000, 2000000,
 -      2500000, 3000000, 3500000, 4000000
 -};
 -
  static void acm_tty_set_termios(struct tty_struct *tty,
                                                struct ktermios *termios_old)
  {
@@@ -957,11 -977,13 +957,15 @@@ static int acm_probe(struct usb_interfa
        int num_rx_buf;
        int i;
        int combined_interfaces = 0;
 +      struct device *tty_dev;
 +      int rv = -ENOMEM;
  
        /* normal quirks */
        quirks = (unsigned long)id->driver_info;
+       if (quirks == IGNORE_DEVICE)
+               return -ENODEV;
        num_rx_buf = (quirks == SINGLE_RX_URB) ? 1 : ACM_NR;
  
        /* handle quirks deadly to normal probing*/
@@@ -1321,24 -1343,11 +1325,24 @@@ skip_countries
        usb_set_intfdata(data_interface, acm);
  
        usb_get_intf(control_interface);
 -      tty_port_register_device(&acm->port, acm_tty_driver, minor,
 +      tty_dev = tty_port_register_device(&acm->port, acm_tty_driver, minor,
                        &control_interface->dev);
 +      if (IS_ERR(tty_dev)) {
 +              rv = PTR_ERR(tty_dev);
 +              goto alloc_fail8;
 +      }
  
        return 0;
 +alloc_fail8:
 +      if (acm->country_codes) {
 +              device_remove_file(&acm->control->dev,
 +                              &dev_attr_wCountryCodes);
 +              device_remove_file(&acm->control->dev,
 +                              &dev_attr_iCountryCodeRelDate);
 +      }
 +      device_remove_file(&acm->control->dev, &dev_attr_bmCapabilities);
  alloc_fail7:
 +      usb_set_intfdata(intf, NULL);
        for (i = 0; i < ACM_NW; i++)
                usb_free_urb(acm->wb[i].urb);
  alloc_fail6:
@@@ -1354,7 -1363,7 +1358,7 @@@ alloc_fail2
        acm_release_minor(acm);
        kfree(acm);
  alloc_fail:
 -      return -ENOMEM;
 +      return rv;
  }
  
  static void stop_data_traffic(struct acm *acm)
@@@ -1406,8 -1415,6 +1410,8 @@@ static void acm_disconnect(struct usb_i
  
        stop_data_traffic(acm);
  
 +      tty_unregister_device(acm_tty_driver, acm->minor);
 +
        usb_free_urb(acm->ctrlurb);
        for (i = 0; i < ACM_NW; i++)
                usb_free_urb(acm->wb[i].urb);
@@@ -1500,9 -1507,15 +1504,9 @@@ err_out
  static int acm_reset_resume(struct usb_interface *intf)
  {
        struct acm *acm = usb_get_intfdata(intf);
 -      struct tty_struct *tty;
  
 -      if (test_bit(ASYNCB_INITIALIZED, &acm->port.flags)) {
 -              tty = tty_port_tty_get(&acm->port);
 -              if (tty) {
 -                      tty_hangup(tty);
 -                      tty_kref_put(tty);
 -              }
 -      }
 +      if (test_bit(ASYNCB_INITIALIZED, &acm->port.flags))
 +              tty_port_tty_hangup(&acm->port, false);
  
        return acm_resume(intf);
  }
@@@ -1675,6 -1688,15 +1679,15 @@@ static const struct usb_device_id acm_i
        .driver_info = NO_DATA_INTERFACE,
        },
  
+ #if IS_ENABLED(CONFIG_INPUT_IMS_PCU)
+       { USB_DEVICE(0x04d8, 0x0082),   /* Application mode */
+       .driver_info = IGNORE_DEVICE,
+       },
+       { USB_DEVICE(0x04d8, 0x0083),   /* Bootloader mode */
+       .driver_info = IGNORE_DEVICE,
+       },
+ #endif
        /* control interfaces without any protocol set */
        { USB_INTERFACE_INFO(USB_CLASS_COMM, USB_CDC_SUBCLASS_ACM,
                USB_CDC_PROTO_NONE) },
diff --combined include/linux/device.h
index 711793b145ff60f19962aa8400a9a05b5ec4a464,4fd899bd2c0d31cc14124998e7ffa406d3744cb0..c0a12612532512bab2f792fba4b40580c48b13dd
@@@ -25,7 -25,6 +25,7 @@@
  #include <linux/pm.h>
  #include <linux/atomic.h>
  #include <linux/ratelimit.h>
 +#include <linux/uidgid.h>
  #include <asm/device.h>
  
  struct device;
@@@ -112,11 -111,17 +112,11 @@@ struct bus_type 
        struct iommu_ops *iommu_ops;
  
        struct subsys_private *p;
 +      struct lock_class_key lock_key;
  };
  
 -/* This is a #define to keep the compiler from merging different
 - * instances of the __key variable */
 -#define bus_register(subsys)                  \
 -({                                            \
 -      static struct lock_class_key __key;     \
 -      __bus_register(subsys, &__key); \
 -})
 -extern int __must_check __bus_register(struct bus_type *bus,
 -                                     struct lock_class_key *key);
 +extern int __must_check bus_register(struct bus_type *bus);
 +
  extern void bus_unregister(struct bus_type *bus);
  
  extern int __must_check bus_rescan_devices(struct bus_type *bus);
@@@ -297,8 -302,6 +297,8 @@@ void subsys_interface_unregister(struc
  
  int subsys_system_register(struct bus_type *subsys,
                           const struct attribute_group **groups);
 +int subsys_virtual_register(struct bus_type *subsys,
 +                          const struct attribute_group **groups);
  
  /**
   * struct class - device classes
@@@ -468,8 -471,7 +468,8 @@@ struct device_type 
        const char *name;
        const struct attribute_group **groups;
        int (*uevent)(struct device *dev, struct kobj_uevent_env *env);
 -      char *(*devnode)(struct device *dev, umode_t *mode);
 +      char *(*devnode)(struct device *dev, umode_t *mode,
 +                       kuid_t *uid, kgid_t *gid);
        void (*release)(struct device *dev);
  
        const struct dev_pm_ops *pm;
@@@ -576,6 -578,10 +576,10 @@@ void __iomem *devm_ioremap_resource(str
  void __iomem *devm_request_and_ioremap(struct device *dev,
                        struct resource *res);
  
+ /* allows to add/remove a custom action to devres stack */
+ int devm_add_action(struct device *dev, void (*action)(void *), void *data);
+ void devm_remove_action(struct device *dev, void (*action)(void *), void *data);
  struct device_dma_parameters {
        /*
         * a low level driver may set these to teach IOMMU code about
@@@ -847,8 -853,7 +851,8 @@@ extern int device_rename(struct device 
  extern int device_move(struct device *dev, struct device *new_parent,
                       enum dpm_order dpm_order);
  extern const char *device_get_devnode(struct device *dev,
 -                                    umode_t *mode, const char **tmp);
 +                                    umode_t *mode, kuid_t *uid, kgid_t *gid,
 +                                    const char **tmp);
  extern void *dev_get_drvdata(const struct device *dev);
  extern int dev_set_drvdata(struct device *dev, void *data);