Merge branches 'for-4.4/upstream-fixes', 'for-4.5/async-suspend', 'for-4.5/container...
authorJiri Kosina <jkosina@suse.cz>
Thu, 14 Jan 2016 15:11:06 +0000 (16:11 +0100)
committerJiri Kosina <jkosina@suse.cz>
Thu, 14 Jan 2016 15:11:06 +0000 (16:11 +0100)
1  2  3  4  5  6  7  8  9  10 
MAINTAINERS
drivers/hid/hid-core.c
drivers/hid/hid-ids.h
drivers/hid/hid-input.c
drivers/hid/hid-multitouch.c
drivers/hid/hid-sony.c
drivers/hid/i2c-hid/i2c-hid.c
drivers/hid/wacom_sys.c
drivers/hid/wacom_wac.c

diff --combined MAINTAINERS
@@@@@@@@@@@ -789,6 -789,11 -789,11 -789,11 -789,6 -789,11 -789,11 -789,6 -789,11 -789,6 +789,11 @@@@@@@@@@@ S:  Maintaine
          F:    drivers/net/appletalk/
          F:    net/appletalk/
          
+   +  + +APPLIED MICRO (APM) X-GENE DEVICE TREE SUPPORT
+   +  + +M:    Duc Dang <dhdang@apm.com>
+   +  + +S:    Supported
+   +  + +F:    arch/arm64/boot/dts/apm/
+   +  + +
          APPLIED MICRO (APM) X-GENE SOC ETHERNET DRIVER
          M:    Iyappan Subramanian <isubramanian@apm.com>
          M:    Keyur Chudgar <kchudgar@apm.com>
@@@@@@@@@@@ -920,7 -925,7 -925,7 -925,7 -920,7 -925,7 -925,7 -920,7 -925,7 -920,7 +925,7 @@@@@@@@@@@ M: Tsahee Zidenberg <tsahee@annapurnala
          S:    Maintained
          F:    arch/arm/mach-alpine/
          
-   -  - -ARM/ATMEL AT91RM9200 AND AT91SAM ARM ARCHITECTURES
+   +  + +ARM/ATMEL AT91RM9200, AT91SAM9 AND SAMA5 SOC SUPPORT
          M:    Nicolas Ferre <nicolas.ferre@atmel.com>
          M:    Alexandre Belloni <alexandre.belloni@free-electrons.com>
          M:    Jean-Christophe Plagniol-Villard <plagnioj@jcrosoft.com>
@@@@@@@@@@@ -1233,6 -1238,13 -1238,13 -1238,13 -1233,6 -1238,13 -1238,13 -1233,6 -1238,13 -1233,6 +1238,13 @@@@@@@@@@@ ARM/LPC18XX ARCHITECTUR
          M:    Joachim Eastwood <manabian@gmail.com>
          L:    linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
          S:    Maintained
+   +  + +F:    arch/arm/boot/dts/lpc43*
+   +  + +F:    drivers/clk/nxp/clk-lpc18xx*
+   +  + +F:    drivers/clocksource/time-lpc32xx.c
+   +  + +F:    drivers/i2c/busses/i2c-lpc2k.c
+   +  + +F:    drivers/memory/pl172.c
+   +  + +F:    drivers/mtd/spi-nor/nxp-spifi.c
+   +  + +F:    drivers/rtc/rtc-lpc24xx.c
          N:    lpc18xx
          
          ARM/MAGICIAN MACHINE SUPPORT
@@@@@@@@@@@ -1455,6 -1467,10 -1467,10 -1467,10 -1455,6 -1467,10 -1467,10 -1455,6 -1467,10 -1455,6 +1467,10 @@@@@@@@@@@ F:       drivers/*/*s3c2410
          F:    drivers/*/*/*s3c2410*
          F:    drivers/spi/spi-s3c*
          F:    sound/soc/samsung/*
+   +  + +F:    Documentation/arm/Samsung/
+   +  + +F:    Documentation/devicetree/bindings/arm/samsung/
+   +  + +F:    Documentation/devicetree/bindings/sram/samsung-sram.txt
+   +  + +F:    Documentation/devicetree/bindings/power/pd-samsung.txt
          N:    exynos
          
          ARM/SAMSUNG MOBILE MACHINE SUPPORT
@@@@@@@@@@@ -1509,8 -1525,6 -1525,6 -1525,6 -1509,8 -1525,6 -1525,6 -1509,8 -1525,6 -1509,8 +1525,6 @@@@@@@@@@@ F:      arch/arm/boot/dts/emev2
          F:    arch/arm/boot/dts/r7s*
          F:    arch/arm/boot/dts/r8a*
          F:    arch/arm/boot/dts/sh*
-   -  - -F:    arch/arm/configs/bockw_defconfig
-   -  - -F:    arch/arm/configs/marzen_defconfig
          F:    arch/arm/configs/shmobile_defconfig
          F:    arch/arm/include/debug/renesas-scif.S
          F:    arch/arm/mach-shmobile/
@@@@@@@@@@@ -1625,7 -1639,10 -1639,10 -1639,10 -1625,7 -1639,10 -1639,10 -1625,7 -1639,10 -1625,7 +1639,10 @@@@@@@@@@@ M:       Masahiro Yamada <yamada.masahiro@soc
          L:    linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
          S:    Maintained
          F:    arch/arm/boot/dts/uniphier*
+   +  + +F:    arch/arm/include/asm/hardware/cache-uniphier.h
          F:    arch/arm/mach-uniphier/
+   +  + +F:    arch/arm/mm/cache-uniphier.c
+   +  + +F:    drivers/i2c/busses/i2c-uniphier*
          F:    drivers/pinctrl/uniphier/
          F:    drivers/tty/serial/8250/8250_uniphier.c
          N:    uniphier
@@@@@@@@@@@ -1914,7 -1931,7 -1931,7 -1931,7 -1914,7 -1931,7 -1931,7 -1914,7 -1931,7 -1914,7 +1931,7 @@@@@@@@@@@ S:      Supporte
          F:    drivers/i2c/busses/i2c-at91.c
          
          ATMEL ISI DRIVER
- ------ -M:    Josh Wu <josh.wu@atmel.com>
+ ++++++ +M:    Ludovic Desroches <ludovic.desroches@atmel.com>
          L:    linux-media@vger.kernel.org
          S:    Supported
          F:    drivers/media/platform/soc_camera/atmel-isi.c
@@@@@@@@@@@ -1933,7 -1950,8 -1950,7 -1950,7 -1933,7 -1950,7 -1950,7 -1933,7 -1950,8 -1933,7 +1950,8 @@@@@@@@@@@ S:      Supporte
          F:    drivers/net/ethernet/cadence/
          
          ATMEL NAND DRIVER
- ------ -M:    Josh Wu <josh.wu@atmel.com>
+ ++++++ +M:    Wenyou Yang <wenyou.yang@atmel.com>
+ ++++++ +M:    Josh Wu <rainyfeeling@outlook.com>
          L:    linux-mtd@lists.infradead.org
          S:    Supported
          F:    drivers/mtd/nand/atmel_nand*
@@@@@@@@@@@ -2193,6 -2211,7 -2210,7 -2210,7 -2193,6 -2210,7 -2210,7 -2193,6 -2211,7 -2193,6 +2211,7 @@@@@@@@@@@ F:      drivers/leds/leds-blinkm.
          
          BLOCK LAYER
          M:    Jens Axboe <axboe@kernel.dk>
+   +  + +L:    linux-block@vger.kernel.org
          T:    git git://git.kernel.org/pub/scm/linux/kernel/git/axboe/linux-block.git
          S:    Maintained
          F:    block/
@@@@@@@@@@@ -2387,19 -2406,27 -2405,27 -2405,27 -2387,19 -2405,27 -2405,27 -2387,19 -2406,27 -2387,19 +2406,27 @@@@@@@@@@@ L:   linux-scsi@vger.kernel.or
          S:    Supported
          F:    drivers/scsi/bnx2i/
          
-   -  - -BROADCOM CYGNUS/IPROC ARM ARCHITECTURE
+   +  + +BROADCOM IPROC ARM ARCHITECTURE
          M:    Ray Jui <rjui@broadcom.com>
          M:    Scott Branden <sbranden@broadcom.com>
+   +  + +M:    Jon Mason <jonmason@broadcom.com>
          L:    linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
          L:    bcm-kernel-feedback-list@broadcom.com
          T:    git git://github.com/broadcom/cygnus-linux.git
          S:    Maintained
          N:    iproc
          N:    cygnus
+   +  + +N:    nsp
          N:    bcm9113*
          N:    bcm9583*
-   -  - -N:    bcm583*
+   +  + +N:    bcm9585*
+   +  + +N:    bcm9586*
+   +  + +N:    bcm988312
          N:    bcm113*
+   +  + +N:    bcm583*
+   +  + +N:    bcm585*
+   +  + +N:    bcm586*
+   +  + +N:    bcm88312
          
          BROADCOM BRCMSTB GPIO DRIVER
          M:    Gregory Fong <gregory.0xf0@gmail.com>
@@@@@@@@@@@ -2423,7 -2450,9 -2449,7 -2449,7 -2423,7 -2449,7 -2449,7 -2423,7 -2450,9 -2423,7 +2450,9 @@@@@@@@@@@ F:      drivers/firmware/broadcom/
          
          BROADCOM STB NAND FLASH DRIVER
          M:    Brian Norris <computersforpeace@gmail.com>
+ ++++++ +M:    Kamal Dasu <kdasu.kdev@gmail.com>
          L:    linux-mtd@lists.infradead.org
+ ++++++ +L:    bcm-kernel-feedback-list@broadcom.com
          S:    Maintained
          F:    drivers/mtd/nand/brcmnand/
          
@@@@@@@@@@@ -2520,7 -2549,7 -2546,7 -2546,7 -2520,7 -2546,7 -2546,7 -2520,7 -2549,7 -2520,7 +2549,7 @@@@@@@@@@@ F:      arch/c6x
          
          CACHEFILES: FS-CACHE BACKEND FOR CACHING ON MOUNTED FILESYSTEMS
          M:    David Howells <dhowells@redhat.com>
-   -  - -L:    linux-cachefs@redhat.com
+   +  + +L:    linux-cachefs@redhat.com (moderated for non-subscribers)
          S:    Supported
          F:    Documentation/filesystems/caching/cachefiles.txt
          F:    fs/cachefiles/
@@@@@@@@@@@ -2757,9 -2786,10 -2783,10 -2783,10 -2757,9 -2783,10 -2783,10 -2757,9 -2786,10 -2757,9 +2786,10 @@@@@@@@@@@ S:       Supporte
          F:    drivers/net/ethernet/cisco/enic/
          
          CISCO VIC LOW LATENCY NIC DRIVER
-   -  - -M:    Upinder Malhi <umalhi@cisco.com>
+   +  + +M:    Christian Benvenuti <benve@cisco.com>
+   +  + +M:    Dave Goodell <dgoodell@cisco.com>
          S:    Supported
-   -  - -F:    drivers/infiniband/hw/usnic
+   +  + +F:    drivers/infiniband/hw/usnic/
          
          CIRRUS LOGIC EP93XX ETHERNET DRIVER
          M:    Hartley Sweeten <hsweeten@visionengravers.com>
@@@@@@@@@@@ -2902,10 -2932,9 -2929,10 -2929,10 -2902,10 -2929,10 -2929,10 -2902,10 -2932,9 -2902,10 +2932,9 @@@@@@@@@@@ S:      Maintaine
          F:    drivers/platform/x86/compal-laptop.c
          
          CONEXANT ACCESSRUNNER USB DRIVER
- ------ -M:    Simon Arlott <cxacru@fire.lp0.eu>
          L:    accessrunner-general@lists.sourceforge.net
          W:    http://accessrunner.sourceforge.net/
- ------ -S:    Maintained
+ ++++++ +S:    Orphan
          F:    drivers/usb/atm/cxacru.c
          
          CONFIGFS
@@@@@@@@@@@ -3623,6 -3652,7 -3650,7 -3650,7 -3623,6 -3650,7 -3650,7 -3623,6 -3652,7 -3623,6 +3652,7 @@@@@@@@@@@ M:      Daniel Vetter <daniel.vetter@intel.c
          M:    Jani Nikula <jani.nikula@linux.intel.com>
          L:    intel-gfx@lists.freedesktop.org
          L:    dri-devel@lists.freedesktop.org
+   +  + +W:    https://01.org/linuxgraphics/
          Q:    http://patchwork.freedesktop.org/project/intel-gfx/
          T:    git git://anongit.freedesktop.org/drm-intel
          S:    Supported
@@@@@@@@@@@ -3663,6 -3693,7 -3691,7 -3691,7 -3663,6 -3691,7 -3691,7 -3663,6 -3693,7 -3663,6 +3693,7 @@@@@@@@@@@ M:      Philipp Zabel <p.zabel@pengutronix.d
          L:    dri-devel@lists.freedesktop.org
          S:    Maintained
          F:    drivers/gpu/drm/imx/
+   +  + +F:    drivers/gpu/ipu-v3/
          F:    Documentation/devicetree/bindings/display/imx/
          
          DRM DRIVERS FOR GMA500 (Poulsbo, Moorestown and derivative chipsets)
@@@@@@@@@@@ -4208,7 -4239,10 -4237,10 -4237,10 -4208,7 -4237,10 -4237,10 -4208,7 -4239,10 -4208,7 +4239,10 @@@@@@@@@@@ L:       linux-kernel@vger.kernel.or
          T:    git git://git.kernel.org/pub/scm/linux/kernel/git/chanwoo/extcon.git
          S:    Maintained
          F:    drivers/extcon/
+   +  + +F:    include/linux/extcon/
+   +  + +F:    include/linux/extcon.h
          F:    Documentation/extcon/
+   +  + +F:    Documentation/devicetree/bindings/extcon/
          
          EXYNOS DP DRIVER
          M:    Jingoo Han <jingoohan1@gmail.com>
@@@@@@@@@@@ -4377,6 -4411,7 -4409,6 -4409,6 -4377,6 -4409,6 -4409,6 -4377,6 -4411,7 -4377,6 +4411,7 @@@@@@@@@@@ K:      fmc_d.*registe
          
          FPGA MANAGER FRAMEWORK
          M:    Alan Tull <atull@opensource.altera.com>
+ ++++++ +R:    Moritz Fischer <moritz.fischer@ettus.com>
          S:    Maintained
          F:    drivers/fpga/
          F:    include/linux/fpga/fpga-mgr.h
@@@@@@@@@@@ -4527,7 -4562,7 -4559,7 -4559,7 -4527,7 -4559,7 -4559,7 -4527,7 -4562,7 -4527,7 +4562,7 @@@@@@@@@@@ F:      include/linux/frontswap.
          
          FS-CACHE: LOCAL CACHING FOR NETWORK FILESYSTEMS
          M:    David Howells <dhowells@redhat.com>
-   -  - -L:    linux-cachefs@redhat.com
+   +  + +L:    linux-cachefs@redhat.com (moderated for non-subscribers)
          S:    Supported
          F:    Documentation/filesystems/caching/
          F:    fs/fscache/
@@@@@@@@@@@ -4949,6 -4984,6 -4981,6 -4981,7 -4949,6 -4981,6 -4981,6 -4949,6 -4984,6 -4949,6 +4984,7 @@@@@@@@@@@ F:      arch/*/include/asm/suspend*.
          
          HID CORE LAYER
          M:    Jiri Kosina <jikos@kernel.org>
+++ ++++++R:    Benjamin Tissoires <benjamin.tissoires@redhat.com>
          L:    linux-input@vger.kernel.org
          T:    git git://git.kernel.org/pub/scm/linux/kernel/git/jikos/hid.git
          S:    Maintained
@@@@@@@@@@@ -5157,6 -5192,7 -5189,7 -5190,7 -5157,6 -5189,7 -5189,7 -5157,6 -5192,7 -5157,6 +5193,7 @@@@@@@@@@@ S:      Maintaine
          F:    Documentation/devicetree/bindings/i2c/
          F:    Documentation/i2c/
          F:    drivers/i2c/
+   +  + +F:    drivers/i2c/*/
          F:    include/linux/i2c.h
          F:    include/linux/i2c-*.h
          F:    include/uapi/linux/i2c.h
@@@@@@@@@@@ -5473,7 -5509,8 -5506,8 -5507,8 -5473,7 -5506,8 -5506,8 -5473,7 -5509,8 -5473,7 +5510,8 @@@@@@@@@@@ S:      Supporte
          F:    drivers/idle/intel_idle.c
          
          INTEL PSTATE DRIVER
-   -  - -M:    Kristen Carlson Accardi <kristen@linux.intel.com>
+   +  + +M:    Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>
+   +  + +M:    Len Brown <lenb@kernel.org>
          L:    linux-pm@vger.kernel.org
          S:    Supported
          F:    drivers/cpufreq/intel_pstate.c
@@@@@@@@@@@ -5677,13 -5714,6 -5711,6 -5712,6 -5677,13 -5711,6 -5711,6 -5677,13 -5714,6 -5677,13 +5715,6 @@@@@@@@@@@ M:  Juanjo Ciarlante <jjciarla@raiz.uncu
          S:    Maintained
          F:    net/ipv4/netfilter/ipt_MASQUERADE.c
          
-   -  - -IP1000A 10/100/1000 GIGABIT ETHERNET DRIVER
-   -  - -M:    Francois Romieu <romieu@fr.zoreil.com>
-   -  - -M:    Sorbica Shieh <sorbica@icplus.com.tw>
-   -  - -L:    netdev@vger.kernel.org
-   -  - -S:    Maintained
-   -  - -F:    drivers/net/ethernet/icplus/ipg.*
-   -  - -
          IPATH DRIVER
          M:    Mike Marciniszyn <infinipath@intel.com>
          L:    linux-rdma@vger.kernel.org
@@@@@@@@@@@ -6337,6 -6367,7 -6364,6 -6365,6 -6337,6 -6364,6 -6364,6 -6337,6 -6367,7 -6337,6 +6368,7 @@@@@@@@@@@ F:      arch/*/include/asm/pmem.
          LIGHTNVM PLATFORM SUPPORT
          M:    Matias Bjorling <mb@lightnvm.io>
          W:    http://github/OpenChannelSSD
+ ++++++ +L:    linux-block@vger.kernel.org
          S:    Maintained
          F:    drivers/lightnvm/
          F:    include/linux/lightnvm.h
@@@@@@@@@@@ -6889,13 -6920,21 -6916,21 -6917,21 -6889,13 -6916,21 -6916,21 -6889,13 -6920,21 -6889,13 +6921,21 @@@@@@@@@@@ F:   drivers/scsi/megaraid.
          F:    drivers/scsi/megaraid/
          
          MELLANOX ETHERNET DRIVER (mlx4_en)
-   -  - -M:    Amir Vadai <amirv@mellanox.com>
+   +  + +M:    Eugenia Emantayev <eugenia@mellanox.com>
          L:    netdev@vger.kernel.org
          S:    Supported
          W:    http://www.mellanox.com
          Q:    http://patchwork.ozlabs.org/project/netdev/list/
          F:    drivers/net/ethernet/mellanox/mlx4/en_*
          
+   +  + +MELLANOX ETHERNET DRIVER (mlx5e)
+   +  + +M:    Saeed Mahameed <saeedm@mellanox.com>
+   +  + +L:    netdev@vger.kernel.org
+   +  + +S:    Supported
+   +  + +W:    http://www.mellanox.com
+   +  + +Q:    http://patchwork.ozlabs.org/project/netdev/list/
+   +  + +F:    drivers/net/ethernet/mellanox/mlx5/core/en_*
+   +  + +
          MELLANOX ETHERNET SWITCH DRIVERS
          M:    Jiri Pirko <jiri@mellanox.com>
          M:    Ido Schimmel <idosch@mellanox.com>
@@@@@@@@@@@ -6962,7 -7001,7 -6997,7 -6998,7 -6962,7 -6997,7 -6997,7 -6962,7 -7001,7 -6962,7 +7002,7 @@@@@@@@@@@ F:      Documentation/hwmon/menf21bm
          METAG ARCHITECTURE
          M:    James Hogan <james.hogan@imgtec.com>
          L:    linux-metag@vger.kernel.org
-   -  - -S:    Supported
+   +  + +S:    Odd Fixes
          F:    arch/metag/
          F:    Documentation/metag/
          F:    Documentation/devicetree/bindings/metag/
@@@@@@@@@@@ -7489,6 -7528,7 -7524,7 -7525,7 -7489,6 -7524,7 -7524,7 -7489,6 -7528,7 -7489,6 +7529,7 @@@@@@@@@@@ S:      Supporte
          F:    Documentation/filesystems/nilfs2.txt
          F:    fs/nilfs2/
          F:    include/linux/nilfs2_fs.h
+   +  + +F:    include/trace/events/nilfs2.h
          
          NINJA SCSI-3 / NINJA SCSI-32Bi (16bit/CardBus) PCMCIA SCSI HOST ADAPTER DRIVER
          M:    YOKOTA Hiroshi <yokota@netlab.is.tsukuba.ac.jp>
          F:    net/openvswitch/
          F:    include/uapi/linux/openvswitch.h
          
+ ++++++ +OPERATING PERFORMANCE POINTS (OPP)
+ ++++++ +M:    Viresh Kumar <vireshk@kernel.org>
+ ++++++ +M:    Nishanth Menon <nm@ti.com>
+ ++++++ +M:    Stephen Boyd <sboyd@codeaurora.org>
+ ++++++ +L:    linux-pm@vger.kernel.org
+ ++++++ +S:    Maintained
+ ++++++ +T:    git git://git.kernel.org/pub/scm/linux/kernel/git/vireshk/pm.git
+ ++++++ +F:    drivers/base/power/opp/
+ ++++++ +F:    include/linux/pm_opp.h
+ ++++++ +F:    Documentation/power/opp.txt
+ ++++++ +F:    Documentation/devicetree/bindings/opp/
+ ++++++ +
          OPL4 DRIVER
          M:    Clemens Ladisch <clemens@ladisch.de>
          L:    alsa-devel@alsa-project.org (moderated for non-subscribers)
@@@@@@@@@@@ -8411,12 -8463,6 -8447,6 -8448,6 -8411,12 -8447,6 -8447,6 -8411,12 -8463,6 -8411,12 +8464,6 @@@@@@@@@@@ M:  "Rafael J. Wysocki" <rafael.j.wysock
          S:    Maintained
          F:    drivers/pnp/
          
-   -  - -PNXxxxx I2C DRIVER
-   -  - -M:    Vitaly Wool <vitalywool@gmail.com>
-   -  - -L:    linux-i2c@vger.kernel.org
-   -  - -S:    Maintained
-   -  - -F:    drivers/i2c/busses/i2c-pnx.c
-   -  - -
          PPP PROTOCOL DRIVERS AND COMPRESSORS
          M:    Paul Mackerras <paulus@samba.org>
          L:    linux-ppp@vger.kernel.org
@@@@@@@@@@@ -9285,7 -9331,6 -9315,6 -9316,6 -9285,7 -9315,6 -9315,6 -9285,7 -9331,6 -9285,7 +9332,6 @@@@@@@@@@@ F:      drivers/i2c/busses/i2c-designware-
          F:    include/linux/platform_data/i2c-designware.h
          
          SYNOPSYS DESIGNWARE MMC/SD/SDIO DRIVER
-   -  - -M:    Seungwon Jeon <tgih.jun@samsung.com>
          M:    Jaehoon Chung <jh80.chung@samsung.com>
          L:    linux-mmc@vger.kernel.org
          S:    Maintained
@@@@@@@@@@@ -9344,6 -9389,16 -9373,16 -9374,16 -9344,6 -9373,16 -9373,16 -9344,6 -9389,16 -9344,6 +9390,16 @@@@@@@@@@@ W:       http://www.sunplus.co
          S:    Supported
          F:    arch/score/
          
+   +  + +SYSTEM CONTROL & POWER INTERFACE (SCPI) Message Protocol drivers
+   +  + +M:    Sudeep Holla <sudeep.holla@arm.com>
+   +  + +L:    linux-arm-kernel@lists.infradead.org
+   +  + +S:    Maintained
+   +  + +F:    Documentation/devicetree/bindings/arm/arm,scpi.txt
+   +  + +F:    drivers/clk/clk-scpi.c
+   +  + +F:    drivers/cpufreq/scpi-cpufreq.c
+   +  + +F:    drivers/firmware/arm_scpi.c
+   +  + +F:    include/linux/scpi_protocol.h
+   +  + +
          SCSI CDROM DRIVER
          M:    Jens Axboe <axboe@kernel.dk>
          L:    linux-scsi@vger.kernel.org
@@@@@@@@@@@ -10261,7 -10316,7 -10300,7 -10301,7 -10261,7 -10300,7 -10300,7 -10261,7 -10316,7 -10261,7 +10317,7 @@@@@@@@@@@ F:   include/net/switchdev.
          
          SYNOPSYS ARC ARCHITECTURE
          M:    Vineet Gupta <vgupta@synopsys.com>
-   -  - -L:    linux-snps-arc@lists.infraded.org
+   +  + +L:    linux-snps-arc@lists.infradead.org
          S:    Supported
          F:    arch/arc/
          F:    Documentation/devicetree/bindings/arc/*
@@@@@@@@@@@ -11042,6 -11097,6 -11081,6 -11082,7 -11042,6 -11081,6 -11081,6 -11042,6 -11097,6 -11042,6 +11098,7 @@@@@@@@@@@ F:   include/linux/usb/gadget
          
          USB HID/HIDBP DRIVERS (USB KEYBOARDS, MICE, REMOTE CONTROLS, ...)
          M:    Jiri Kosina <jikos@kernel.org>
+++ ++++++R:    Benjamin Tissoires <benjamin.tissoires@redhat.com>
          L:    linux-usb@vger.kernel.org
          T:    git git://git.kernel.org/pub/scm/linux/kernel/git/jikos/hid.git
          S:    Maintained
diff --combined drivers/hid/hid-core.c
@@@@@@@@@@@ -625,7 -625,7 -625,7 -625,7 -625,7 -625,7 -625,7 -625,7 -625,7 -625,7 +625,7 @@@@@@@@@@@ static void hid_close_report(struct hid
          
          static void hid_device_release(struct device *dev)
          {
-- -------      struct hid_device *hid = container_of(dev, struct hid_device, dev);
++ +++++++      struct hid_device *hid = to_hid_device(dev);
          
                hid_close_report(hid);
                kfree(hid->dev_rdesc);
@@@@@@@@@@@ -1571,8 -1571,8 -1571,8 -1571,8 -1571,8 -1571,8 -1571,8 -1571,8 -1571,8 -1571,8 +1571,8 @@@@@@@@@@@ read_report_descriptor(struct file *fil
                        struct bin_attribute *attr,
                        char *buf, loff_t off, size_t count)
          {
-- -------      struct device *dev = container_of(kobj, struct device, kobj);
-- -------      struct hid_device *hdev = container_of(dev, struct hid_device, dev);
++ +++++++      struct device *dev = kobj_to_dev(kobj);
++ +++++++      struct hid_device *hdev = to_hid_device(dev);
          
                if (off >= hdev->rsize)
                        return 0;
          show_country(struct device *dev, struct device_attribute *attr,
                        char *buf)
          {
-- -------      struct hid_device *hdev = container_of(dev, struct hid_device, dev);
++ +++++++      struct hid_device *hdev = to_hid_device(dev);
          
                return sprintf(buf, "%02x\n", hdev->country & 0xff);
          }
@@@@@@@@@@@ -1691,11 -1691,11 -1691,11 -1691,6 -1691,11 -1691,11 -1691,11 -1691,11 -1691,11 -1691,11 +1691,6 @@@@@@@@@@@ int hid_connect(struct hid_device *hdev
                        hid_warn(hdev,
                                 "can't create sysfs country code attribute err: %d\n", ret);
          
--- ------      ret = device_create_bin_file(&hdev->dev, &dev_bin_attr_report_desc);
--- ------      if (ret)
--- ------              hid_warn(hdev,
--- ------                       "can't create sysfs report descriptor attribute err: %d\n", ret);
--- ------
                hid_info(hdev, "%s: %s HID v%x.%02x %s [%s] on %s\n",
                         buf, bus, hdev->version >> 8, hdev->version & 0xff,
                         type, hdev->name, hdev->phys);
@@@@@@@@@@@ -1707,7 -1707,7 -1707,7 -1702,6 -1707,7 -1707,7 -1707,7 -1707,7 -1707,7 -1707,7 +1702,6 @@@@@@@@@@@ EXPORT_SYMBOL_GPL(hid_connect)
          void hid_disconnect(struct hid_device *hdev)
          {
                device_remove_file(&hdev->dev, &dev_attr_country);
--- ------      device_remove_bin_file(&hdev->dev, &dev_bin_attr_report_desc);
                if (hdev->claimed & HID_CLAIMED_INPUT)
                        hidinput_disconnect(hdev);
                if (hdev->claimed & HID_CLAIMED_HIDDEV)
@@@@@@@@@@@ -1902,6 -1902,6 -1902,7 -1896,6 -1902,6 -1902,7 -1902,6 -1902,6 -1902,6 -1902,6 +1896,7 @@@@@@@@@@@ static const struct hid_device_id hid_h
                { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_RUMBLEPAD) },
                { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_RUMBLEPAD2_2) },
                { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_G29_WHEEL) },
++ ++ ++++      { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_G920_WHEEL) },
                { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_WINGMAN_F3D) },
                { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_WINGMAN_FFG ) },
                { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_FORCE3D_PRO) },
@@@@@@@@@@@ -2076,7 -2076,7 -2077,7 -2070,7 -2076,7 -2077,7 -2076,7 -2076,7 -2076,7 -2076,7 +2071,7 @@@@@@@@@@@ struct hid_dynid 
          static ssize_t store_new_id(struct device_driver *drv, const char *buf,
                        size_t count)
          {
-- -------      struct hid_driver *hdrv = container_of(drv, struct hid_driver, driver);
++ +++++++      struct hid_driver *hdrv = to_hid_driver(drv);
                struct hid_dynid *dynid;
                __u32 bus, vendor, product;
                unsigned long driver_data = 0;
@@@@@@@@@@@ -2138,17 -2138,17 -2139,16 -2132,17 -2138,17 -2139,17 -2138,17 -2138,17 -2138,17 -2138,17 +2133,16 @@@@@@@@@@@ static const struct hid_device_id *hid_
          
          static int hid_bus_match(struct device *dev, struct device_driver *drv)
          {
-- -------      struct hid_driver *hdrv = container_of(drv, struct hid_driver, driver);
-- -------      struct hid_device *hdev = container_of(dev, struct hid_device, dev);
++ +++++++      struct hid_driver *hdrv = to_hid_driver(drv);
++ +++++++      struct hid_device *hdev = to_hid_device(dev);
          
                return hid_match_device(hdev, hdrv) != NULL;
          }
          
          static int hid_device_probe(struct device *dev)
          {
-- -------      struct hid_driver *hdrv = container_of(dev->driver,
-- -------                      struct hid_driver, driver);
-- -------      struct hid_device *hdev = container_of(dev, struct hid_device, dev);
++ +++++++      struct hid_driver *hdrv = to_hid_driver(dev->driver);
++ +++++++      struct hid_device *hdev = to_hid_device(dev);
                const struct hid_device_id *id;
                int ret = 0;
          
@@@@@@@@@@@ -2190,7 -2190,7 -2190,7 -2184,7 -2190,7 -2191,7 -2190,7 -2190,7 -2190,7 -2190,7 +2184,7 @@@@@@@@@@@ unlock_driver_lock
          
          static int hid_device_remove(struct device *dev)
          {
-- -------      struct hid_device *hdev = container_of(dev, struct hid_device, dev);
++ +++++++      struct hid_device *hdev = to_hid_device(dev);
                struct hid_driver *hdrv;
                int ret = 0;
          
@@@@@@@@@@@ -2223,12 -2223,12 -2223,12 -2217,9 -2223,12 -2224,12 -2223,12 -2223,12 -2223,12 -2223,12 +2217,9 @@@@@@@@@@@ static ssize_t modalias_show(struct dev
                                     char *buf)
          {
                struct hid_device *hdev = container_of(dev, struct hid_device, dev);
--- ------      int len;
--  ------
--  ------      len = snprintf(buf, PAGE_SIZE, "hid:b%04Xg%04Xv%08Xp%08X\n",
--  ------                     hdev->bus, hdev->group, hdev->vendor, hdev->product);
          
  -             len = snprintf(buf, PAGE_SIZE, "hid:b%04Xg%04Xv%08Xp%08X\n",
  -                            hdev->bus, hdev->group, hdev->vendor, hdev->product);
  -       
--- ------      return (len >= PAGE_SIZE) ? (PAGE_SIZE - 1) : len;
+++ ++++++      return scnprintf(buf, PAGE_SIZE, "hid:b%04Xg%04Xv%08Xp%08X\n",
+++ ++++++                       hdev->bus, hdev->group, hdev->vendor, hdev->product);
          }
          static DEVICE_ATTR_RO(modalias);
          
@@@@@@@@@@@ -2236,11 -2236,11 -2236,11 -2227,19 -2236,11 -2237,11 -2236,11 -2236,11 -2236,11 -2236,11 +2227,19 @@@@@@@@@@@ static struct attribute *hid_dev_attrs[
                &dev_attr_modalias.attr,
                NULL,
          };
--- ------ATTRIBUTE_GROUPS(hid_dev);
+++ ++++++static struct bin_attribute *hid_dev_bin_attrs[] = {
+++ ++++++      &dev_bin_attr_report_desc,
+++ ++++++      NULL
+++ ++++++};
+++ ++++++static const struct attribute_group hid_dev_group = {
+++ ++++++      .attrs = hid_dev_attrs,
+++ ++++++      .bin_attrs = hid_dev_bin_attrs,
+++ ++++++};
+++ ++++++__ATTRIBUTE_GROUPS(hid_dev);
          
          static int hid_uevent(struct device *dev, struct kobj_uevent_env *env)
          {
-- -------      struct hid_device *hdev = container_of(dev, struct hid_device, dev);
++ +++++++      struct hid_device *hdev = to_hid_device(dev);   
          
                if (add_uevent_var(env, "HID_ID=%04X:%08X:%08X",
                                hdev->bus, hdev->vendor, hdev->product))
@@@@@@@@@@@ -2408,7 -2408,6 -2408,6 -2407,6 -2408,6 -2409,6 -2408,6 -2408,6 -2408,6 -2408,6 +2407,7 @@@@@@@@@@@ static const struct hid_device_id hid_i
                { HID_USB_DEVICE(USB_VENDOR_ID_MICROCHIP, USB_DEVICE_ID_PICKIT1) },
                { HID_USB_DEVICE(USB_VENDOR_ID_MICROCHIP, USB_DEVICE_ID_PICKIT2) },
                { HID_USB_DEVICE(USB_VENDOR_ID_MICROCHIP, USB_DEVICE_ID_PICK16F1454) },
 +++++++++      { HID_USB_DEVICE(USB_VENDOR_ID_MICROCHIP, USB_DEVICE_ID_PICK16F1454_V2) },
                { HID_USB_DEVICE(USB_VENDOR_ID_NATIONAL_SEMICONDUCTOR, USB_DEVICE_ID_N_S_HARMONY) },
                { HID_USB_DEVICE(USB_VENDOR_ID_ONTRAK, USB_DEVICE_ID_ONTRAK_ADU100) },
                { HID_USB_DEVICE(USB_VENDOR_ID_ONTRAK, USB_DEVICE_ID_ONTRAK_ADU100 + 20) },
@@@@@@@@@@@ -2661,6 -2660,7 -2660,6 -2659,6 -2660,6 -2661,6 -2660,6 -2660,6 -2660,6 -2660,6 +2660,7 @@@@@@@@@@@ struct hid_device *hid_allocate_device(
                device_initialize(&hdev->dev);
                hdev->dev.release = hid_device_release;
                hdev->dev.bus = &hid_bus_type;
+ ++++++++      device_enable_async_suspend(&hdev->dev);
          
                hid_close_report(hdev);
          
diff --combined drivers/hid/hid-ids.h
          #define USB_VENDOR_ID_ITE               0x048d
          #define USB_DEVICE_ID_ITE_LENOVO_YOGA   0x8386
          #define USB_DEVICE_ID_ITE_LENOVO_YOGA2  0x8350
 +++++++++#define USB_DEVICE_ID_ITE_LENOVO_YOGA900      0x8396
          
          #define USB_VENDOR_ID_JABRA           0x0b0e
          #define USB_DEVICE_ID_JABRA_SPEAK_410 0x0412
          #define USB_DEVICE_ID_LOGITECH_HARMONY_FIRST  0xc110
          #define USB_DEVICE_ID_LOGITECH_HARMONY_LAST 0xc14f
          #define USB_DEVICE_ID_LOGITECH_HARMONY_PS3 0x0306
  ++++++ +#define USB_DEVICE_ID_LOGITECH_KEYBOARD_G710_PLUS 0xc24d
          #define USB_DEVICE_ID_LOGITECH_MOUSE_C01A     0xc01a
          #define USB_DEVICE_ID_LOGITECH_MOUSE_C05A     0xc05a
          #define USB_DEVICE_ID_LOGITECH_MOUSE_C06A     0xc06a
          #define USB_DEVICE_ID_LOGITECH_RUMBLEPAD2     0xc218
          #define USB_DEVICE_ID_LOGITECH_RUMBLEPAD2_2   0xc219
          #define USB_DEVICE_ID_LOGITECH_G29_WHEEL      0xc24f
++ ++ ++++#define USB_DEVICE_ID_LOGITECH_G920_WHEEL     0xc262
          #define USB_DEVICE_ID_LOGITECH_WINGMAN_F3D    0xc283
          #define USB_DEVICE_ID_LOGITECH_FORCE3D_PRO    0xc286
          #define USB_DEVICE_ID_LOGITECH_FLIGHT_SYSTEM_G940     0xc287
          #define USB_DEVICE_ID_PICOLCD         0xc002
          #define USB_DEVICE_ID_PICOLCD_BOOTLOADER      0xf002
          #define USB_DEVICE_ID_PICK16F1454     0x0042
 +++++++++#define USB_DEVICE_ID_PICK16F1454_V2  0xf2f7
          
          #define USB_VENDOR_ID_MICROSOFT               0x045e
          #define USB_DEVICE_ID_SIDEWINDER_GV   0x003b
diff --combined drivers/hid/hid-input.c
@@@@@@@@@@@ -303,6 -303,6 -303,6 -303,7 -303,6 -303,6 -303,6 -303,6 -303,6 -303,6 +303,7 @@@@@@@@@@@ static enum power_supply_property hidin
          
          #define HID_BATTERY_QUIRK_PERCENT     (1 << 0) /* always reports percent */
          #define HID_BATTERY_QUIRK_FEATURE     (1 << 1) /* ask for feature report */
+++ ++++++#define HID_BATTERY_QUIRK_IGNORE      (1 << 2) /* completely ignore the battery */
          
          static const struct hid_device_id hid_battery_quirks[] = {
                { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE,
                { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE,
                        USB_DEVICE_ID_APPLE_ALU_WIRELESS_ANSI),
                  HID_BATTERY_QUIRK_PERCENT | HID_BATTERY_QUIRK_FEATURE },
+++ ++++++      { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_ELECOM,
+++ ++++++              USB_DEVICE_ID_ELECOM_BM084),
+++ ++++++        HID_BATTERY_QUIRK_IGNORE },
                {}
          };
          
@@@@@@@@@@@ -408,6 -408,6 -408,6 -412,14 -408,6 -408,6 -408,6 -408,6 -408,6 -408,6 +412,14 @@@@@@@@@@@ static bool hidinput_setup_battery(stru
                if (dev->battery != NULL)
                        goto out;       /* already initialized? */
          
+++ ++++++      quirks = find_battery_quirk(dev);
+++ ++++++
+++ ++++++      hid_dbg(dev, "device %x:%x:%x %d quirks %d\n",
+++ ++++++              dev->bus, dev->vendor, dev->product, dev->version, quirks);
+++ ++++++
+++ ++++++      if (quirks & HID_BATTERY_QUIRK_IGNORE)
+++ ++++++              goto out;
+++ ++++++
                psy_desc = kzalloc(sizeof(*psy_desc), GFP_KERNEL);
                if (psy_desc == NULL)
                        goto out;
                psy_desc->use_for_apm = 0;
                psy_desc->get_property = hidinput_get_battery_property;
          
--- ------      quirks = find_battery_quirk(dev);
--- ------
--- ------      hid_dbg(dev, "device %x:%x:%x %d quirks %d\n",
--- ------              dev->bus, dev->vendor, dev->product, dev->version, quirks);
--- ------
                min = field->logical_minimum;
                max = field->logical_maximum;
          
@@@@@@@@@@@ -960,6 -960,6 -960,10 -967,6 -960,6 -960,10 -960,6 -960,6 -960,6 -960,6 +967,10 @@@@@@@@@@@ static void hidinput_configure_usage(st
                        goto ignore;
          
                case HID_UP_LOGIVENDOR:
++ ++ ++++              /* intentional fallback */
++ ++ ++++      case HID_UP_LOGIVENDOR2:
++ ++ ++++              /* intentional fallback */
++ ++ ++++      case HID_UP_LOGIVENDOR3:
                        goto ignore;
          
                case HID_UP_PID:
@@@@@@@@@@@ -272,7 -272,7 -272,7 -272,7 -272,7 -272,7 -272,7 -272,7 -272,7 -272,7 +272,7 @@@@@@@@@@@ static ssize_t mt_show_quirks(struct de
                                   struct device_attribute *attr,
                                   char *buf)
          {
-- -------      struct hid_device *hdev = container_of(dev, struct hid_device, dev);
++ +++++++      struct hid_device *hdev = to_hid_device(dev);
                struct mt_device *td = hid_get_drvdata(hdev);
          
                return sprintf(buf, "%u\n", td->mtclass.quirks);
@@@@@@@@@@@ -282,7 -282,7 -282,7 -282,7 -282,7 -282,7 -282,7 -282,7 -282,7 -282,7 +282,7 @@@@@@@@@@@ static ssize_t mt_set_quirks(struct dev
                                  struct device_attribute *attr,
                                  const char *buf, size_t count)
          {
-- -------      struct hid_device *hdev = container_of(dev, struct hid_device, dev);
++ +++++++      struct hid_device *hdev = to_hid_device(dev);
                struct mt_device *td = hid_get_drvdata(hdev);
          
                unsigned long val;
@@@@@@@@@@@ -357,8 -357,8 -357,8 -357,8 -357,8 -357,8 -357,19 -357,8 -357,8 -357,8 +357,19 @@@@@@@@@@@ static void mt_feature_mapping(struct h
                                break;
                        }
          
------ ---              td->inputmode = field->report->id;
------ ---              td->inputmode_index = usage->usage_index;
++++++ +++              if (td->inputmode < 0) {
++++++ +++                      td->inputmode = field->report->id;
++++++ +++                      td->inputmode_index = usage->usage_index;
++++++ +++              } else {
++++++ +++                      /*
++++++ +++                       * Some elan panels wrongly declare 2 input mode
++++++ +++                       * features, and silently ignore when we set the
++++++ +++                       * value in the second field. Skip the second feature
++++++ +++                       * and hope for the best.
++++++ +++                       */
++++++ +++                      dev_info(&hdev->dev,
++++++ +++                               "Ignoring the extra HID_DG_INPUTMODE\n");
++++++ +++              }
          
                        break;
                case HID_DG_CONTACTMAX:
@@@@@@@@@@@ -486,6 -486,6 -486,6 -486,6 -486,6 -486,6 -497,11 -486,6 -486,6 -486,6 +497,11 @@@@@@@@@@@ static int mt_touch_input_mapping(struc
                                mt_store_field(usage, td, hi);
                                return 1;
                        case HID_DG_CONFIDENCE:
++++++ +++                      if (cls->name == MT_CLS_WIN_8 &&
++++++ +++                              field->application == HID_DG_TOUCHPAD) {
++++++ +++                              cls->quirks &= ~MT_QUIRK_ALWAYS_VALID;
++++++ +++                              cls->quirks |= MT_QUIRK_VALID_IS_CONFIDENCE;
++++++ +++                      }
                                mt_store_field(usage, td, hi);
                                return 1;
                        case HID_DG_TIPSWITCH:
diff --combined drivers/hid/hid-sony.c
@@@@@@@@@@@ -1028,6 -1028,6 -1028,6 -1028,6 -1028,6 -1028,6 -1028,6 -1028,7 -1028,6 -1028,6 +1028,7 @@@@@@@@@@@ struct sony_sc 
                struct led_classdev *leds[MAX_LEDS];
                unsigned long quirks;
                struct work_struct state_worker;
+++++++ ++      void(*send_output_report)(struct sony_sc*);
                struct power_supply *battery;
                struct power_supply_desc battery_desc;
                int device_id;
                __u8 battery_charging;
                __u8 battery_capacity;
                __u8 led_state[MAX_LEDS];
+++++++ ++      __u8 resume_led_state[MAX_LEDS];
                __u8 led_delay_on[MAX_LEDS];
                __u8 led_delay_off[MAX_LEDS];
                __u8 led_count;
@@@@@@@@@@@ -1137,11 -1137,11 -1137,11 -1137,11 -1137,11 -1137,11 -1137,11 -1139,11 -1137,11 -1137,11 +1139,11 @@@@@@@@@@@ static __u8 *sony_report_fixup(struct h
                 * the gyroscope values to corresponding axes so we need a
                 * modified one.
                 */
------- --      if ((sc->quirks & DUALSHOCK4_CONTROLLER_USB) && *rsize == 467) {
+++++++ ++      if (sc->quirks & DUALSHOCK4_CONTROLLER_USB) {
                        hid_info(hdev, "Using modified Dualshock 4 report descriptor with gyroscope axes\n");
                        rdesc = dualshock4_usb_rdesc;
                        *rsize = sizeof(dualshock4_usb_rdesc);
------- --      } else if ((sc->quirks & DUALSHOCK4_CONTROLLER_BT) && *rsize == 357) {
+++++++ ++      } else if (sc->quirks & DUALSHOCK4_CONTROLLER_BT) {
                        hid_info(hdev, "Using modified Dualshock 4 Bluetooth report descriptor\n");
                        rdesc = dualshock4_bt_rdesc;
                        *rsize = sizeof(dualshock4_bt_rdesc);
@@@@@@@@@@@ -1549,7 -1549,7 -1549,7 -1549,7 -1549,7 -1549,7 -1549,7 -1551,7 -1549,7 -1549,7 +1551,7 @@@@@@@@@@@ static void sony_led_set_brightness(str
                                            enum led_brightness value)
          {
                struct device *dev = led->dev->parent;
-- -------      struct hid_device *hdev = container_of(dev, struct hid_device, dev);
++ +++++++      struct hid_device *hdev = to_hid_device(dev);
                struct sony_sc *drv_data;
          
                int n;
          static enum led_brightness sony_led_get_brightness(struct led_classdev *led)
          {
                struct device *dev = led->dev->parent;
-- -------      struct hid_device *hdev = container_of(dev, struct hid_device, dev);
++ +++++++      struct hid_device *hdev = to_hid_device(dev);
                struct sony_sc *drv_data;
          
                int n;
@@@@@@@@@@@ -1614,7 -1614,7 -1614,7 -1614,7 -1614,7 -1614,7 -1614,7 -1616,7 -1614,7 -1614,7 +1616,7 @@@@@@@@@@@ static int sony_led_blink_set(struct le
                                        unsigned long *delay_off)
          {
                struct device *dev = led->dev->parent;
-- -------      struct hid_device *hdev = container_of(dev, struct hid_device, dev);
++ +++++++      struct hid_device *hdev = to_hid_device(dev);
                struct sony_sc *drv_data = hid_get_drvdata(hdev);
                int n;
                __u8 new_on, new_off;
                return ret;
          }
          
------- --static void sixaxis_state_worker(struct work_struct *work)
+++++++ ++static void sixaxis_send_output_report(struct sony_sc *sc)
          {
                static const union sixaxis_output_report_01 default_report = {
                        .buf = {
                                0x00, 0x00, 0x00, 0x00, 0x00
                        }
                };
------- --      struct sony_sc *sc = container_of(work, struct sony_sc, state_worker);
                struct sixaxis_output_report *report =
                        (struct sixaxis_output_report *)sc->output_report_dmabuf;
                int n;
                                HID_OUTPUT_REPORT, HID_REQ_SET_REPORT);
          }
          
------- --static void dualshock4_state_worker(struct work_struct *work)
+++++++ ++static void dualshock4_send_output_report(struct sony_sc *sc)
          {
------- --      struct sony_sc *sc = container_of(work, struct sony_sc, state_worker);
                struct hid_device *hdev = sc->hdev;
                __u8 *buf = sc->output_report_dmabuf;
                int offset;
                                        HID_OUTPUT_REPORT, HID_REQ_SET_REPORT);
          }
          
------- --static void motion_state_worker(struct work_struct *work)
+++++++ ++static void motion_send_output_report(struct sony_sc *sc)
          {
------- --      struct sony_sc *sc = container_of(work, struct sony_sc, state_worker);
                struct hid_device *hdev = sc->hdev;
                struct motion_output_report_02 *report =
                        (struct motion_output_report_02 *)sc->output_report_dmabuf;
                hid_hw_output_report(hdev, (__u8 *)report, MOTION_REPORT_0x02_SIZE);
          }
          
+++++++ ++static inline void sony_send_output_report(struct sony_sc *sc)
+++++++ ++{
+++++++ ++      if (sc->send_output_report)
+++++++ ++              sc->send_output_report(sc);
+++++++ ++}
+++++++ ++
+++++++ ++static void sony_state_worker(struct work_struct *work)
+++++++ ++{
+++++++ ++      struct sony_sc *sc = container_of(work, struct sony_sc, state_worker);
+++++++ ++      sc->send_output_report(sc);
+++++++ ++}
+++++++ ++
          static int sony_allocate_output_report(struct sony_sc *sc)
          {
                if ((sc->quirks & SIXAXIS_CONTROLLER) ||
@@@@@@@@@@@ -2241,11 -2241,11 -2241,11 -2241,11 -2241,11 -2241,11 -2241,11 -2252,13 -2241,11 -2241,11 +2252,13 @@@@@@@@@@@ static void sony_release_device_id(stru
                }
          }
          
------- --static inline void sony_init_work(struct sony_sc *sc,
------- --                                      void (*worker)(struct work_struct *))
+++++++ ++static inline void sony_init_output_report(struct sony_sc *sc,
+++++++ ++                              void(*send_output_report)(struct sony_sc*))
          {
+++++++ ++      sc->send_output_report = send_output_report;
+++++++ ++
                if (!sc->worker_initialized)
------- --              INIT_WORK(&sc->state_worker, worker);
+++++++ ++              INIT_WORK(&sc->state_worker, sony_state_worker);
          
                sc->worker_initialized = 1;
          }
@@@@@@@@@@@ -2319,7 -2319,7 -2319,7 -2319,7 -2319,7 -2319,7 -2319,7 -2332,7 -2319,7 -2319,7 +2332,7 @@@@@@@@@@@ static int sony_probe(struct hid_devic
                        hdev->quirks |= HID_QUIRK_NO_OUTPUT_REPORTS_ON_INTR_EP;
                        hdev->quirks |= HID_QUIRK_SKIP_OUTPUT_REPORT_ID;
                        ret = sixaxis_set_operational_usb(hdev);
------- --              sony_init_work(sc, sixaxis_state_worker);
+++++++ ++              sony_init_output_report(sc, sixaxis_send_output_report);
                } else if ((sc->quirks & SIXAXIS_CONTROLLER_BT) ||
                                (sc->quirks & NAVIGATION_CONTROLLER_BT)) {
                        /*
                         */
                        hdev->quirks |= HID_QUIRK_NO_OUTPUT_REPORTS_ON_INTR_EP;
                        ret = sixaxis_set_operational_bt(hdev);
------- --              sony_init_work(sc, sixaxis_state_worker);
+++++++ ++              sony_init_output_report(sc, sixaxis_send_output_report);
                } else if (sc->quirks & DUALSHOCK4_CONTROLLER) {
                        if (sc->quirks & DUALSHOCK4_CONTROLLER_BT) {
                                /*
                                }
                        }
          
------- --              sony_init_work(sc, dualshock4_state_worker);
+++++++ ++              sony_init_output_report(sc, dualshock4_send_output_report);
                } else if (sc->quirks & MOTION_CONTROLLER) {
------- --              sony_init_work(sc, motion_state_worker);
+++++++ ++              sony_init_output_report(sc, motion_send_output_report);
                } else {
                        ret = 0;
                }
@@@@@@@@@@@ -2421,6 -2421,6 -2421,6 -2421,6 -2421,6 -2421,6 -2421,6 -2434,56 -2421,6 -2421,6 +2434,56 @@@@@@@@@@@ static void sony_remove(struct hid_devi
                hid_hw_stop(hdev);
          }
          
+++++++ ++#ifdef CONFIG_PM
+++++++ ++
+++++++ ++static int sony_suspend(struct hid_device *hdev, pm_message_t message)
+++++++ ++{
+++++++ ++      /*
+++++++ ++       * On suspend save the current LED state,
+++++++ ++       * stop running force-feedback and blank the LEDS.
+++++++ ++         */
+++++++ ++      if (SONY_LED_SUPPORT || SONY_FF_SUPPORT) {
+++++++ ++              struct sony_sc *sc = hid_get_drvdata(hdev);
+++++++ ++
+++++++ ++#ifdef CONFIG_SONY_FF
+++++++ ++              sc->left = sc->right = 0;
+++++++ ++#endif
+++++++ ++
+++++++ ++              memcpy(sc->resume_led_state, sc->led_state,
+++++++ ++                      sizeof(sc->resume_led_state));
+++++++ ++              memset(sc->led_state, 0, sizeof(sc->led_state));
+++++++ ++
+++++++ ++              sony_send_output_report(sc);
+++++++ ++      }
+++++++ ++
+++++++ ++      return 0;
+++++++ ++}
+++++++ ++
+++++++ ++static int sony_resume(struct hid_device *hdev)
+++++++ ++{
+++++++ ++      /* Restore the state of controller LEDs on resume */
+++++++ ++      if (SONY_LED_SUPPORT) {
+++++++ ++              struct sony_sc *sc = hid_get_drvdata(hdev);
+++++++ ++
+++++++ ++              memcpy(sc->led_state, sc->resume_led_state,
+++++++ ++                      sizeof(sc->led_state));
+++++++ ++
+++++++ ++              /*
+++++++ ++               * The Sixaxis and navigation controllers on USB need to be
+++++++ ++               * reinitialized on resume or they won't behave properly.
+++++++ ++               */
+++++++ ++              if ((sc->quirks & SIXAXIS_CONTROLLER_USB) ||
+++++++ ++                      (sc->quirks & NAVIGATION_CONTROLLER_USB))
+++++++ ++                      sixaxis_set_operational_usb(sc->hdev);
+++++++ ++
+++++++ ++              sony_set_leds(sc);
+++++++ ++      }
+++++++ ++
+++++++ ++      return 0;
+++++++ ++}
+++++++ ++
+++++++ ++#endif
+++++++ ++
          static const struct hid_device_id sony_devices[] = {
                { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS3_CONTROLLER),
                        .driver_data = SIXAXIS_CONTROLLER_USB },
@@@@@@@@@@@ -2470,7 -2470,7 -2470,7 -2470,7 -2470,7 -2470,7 -2470,7 -2533,13 -2470,7 -2470,7 +2533,13 @@@@@@@@@@@ static struct hid_driver sony_driver = 
                .probe            = sony_probe,
                .remove           = sony_remove,
                .report_fixup     = sony_report_fixup,
------- --      .raw_event        = sony_raw_event
+++++++ ++      .raw_event        = sony_raw_event,
+++++++ ++
+++++++ ++#ifdef CONFIG_PM
+++++++ ++      .suspend          = sony_suspend,
+++++++ ++      .resume           = sony_resume,
+++++++ ++      .reset_resume     = sony_resume,
+++++++ ++#endif
          };
          
          static int __init sony_init(void)
@@@@@@@@@@@ -151,7 -151,6 -151,6 -151,6 -151,6 -151,6 -151,6 -151,6 -151,6 -151,6 +151,7 @@@@@@@@@@@ struct i2c_hid 
                struct i2c_hid_platform_data pdata;
          
                bool                    irq_wake_enabled;
 +++++++++      struct mutex            reset_lock;
          };
          
          static int __i2c_hid_command(struct i2c_client *client,
@@@@@@@@@@@ -357,16 -356,9 -356,9 -356,9 -356,9 -356,9 -356,9 -356,9 -356,9 -356,9 +357,16 @@@@@@@@@@@ static int i2c_hid_hwreset(struct i2c_c
          
                i2c_hid_dbg(ihid, "%s\n", __func__);
          
 +++++++++      /*
 +++++++++       * This prevents sending feature reports while the device is
 +++++++++       * being reset. Otherwise we may lose the reset complete
 +++++++++       * interrupt.
 +++++++++       */
 +++++++++      mutex_lock(&ihid->reset_lock);
 +++++++++
                ret = i2c_hid_set_power(client, I2C_HID_PWR_ON);
                if (ret)
 ---------              return ret;
 +++++++++              goto out_unlock;
          
                i2c_hid_dbg(ihid, "resetting...\n");
          
                if (ret) {
                        dev_err(&client->dev, "failed to reset device.\n");
                        i2c_hid_set_power(client, I2C_HID_PWR_SLEEP);
 ---------              return ret;
                }
          
 ---------      return 0;
 +++++++++out_unlock:
 +++++++++      mutex_unlock(&ihid->reset_lock);
 +++++++++      return ret;
          }
          
          static void i2c_hid_get_input(struct i2c_hid *ihid)
@@@@@@@@@@@ -596,15 -587,12 -587,12 -587,12 -587,12 -587,12 -587,12 -587,12 -587,12 -587,12 +596,15 @@@@@@@@@@@ static int i2c_hid_output_raw_report(st
                        size_t count, unsigned char report_type, bool use_data)
          {
                struct i2c_client *client = hid->driver_data;
 +++++++++      struct i2c_hid *ihid = i2c_get_clientdata(client);
                int report_id = buf[0];
                int ret;
          
                if (report_type == HID_INPUT_REPORT)
                        return -EINVAL;
          
 +++++++++      mutex_lock(&ihid->reset_lock);
 +++++++++
                if (report_id) {
                        buf++;
                        count--;
                if (report_id && ret >= 0)
                        ret++; /* add report_id to the number of transfered bytes */
          
 +++++++++      mutex_unlock(&ihid->reset_lock);
 +++++++++
                return ret;
          }
          
@@@@@@@@@@@ -1004,7 -990,6 -990,6 -990,6 -990,6 -990,6 -990,6 -990,6 -990,6 -990,6 +1004,7 @@@@@@@@@@@ static int i2c_hid_probe(struct i2c_cli
                ihid->wHIDDescRegister = cpu_to_le16(hidRegister);
          
                init_waitqueue_head(&ihid->wait);
 +++++++++      mutex_init(&ihid->reset_lock);
          
                /* we need to allocate the command buffer without knowing the maximum
                 * size of the reports. Let's use HID_MIN_BUFFER_SIZE, then we do the
@@@@@@@@@@@ -1199,7 -1184,7 -1184,7 -1184,7 -1184,6 -1184,7 -1184,7 -1184,7 -1184,7 -1184,7 +1199,6 @@@@@@@@@@@ MODULE_DEVICE_TABLE(i2c, i2c_hid_id_tab
          static struct i2c_driver i2c_hid_driver = {
                .driver = {
                        .name   = "i2c_hid",
---- -----              .owner  = THIS_MODULE,
                        .pm     = &i2c_hid_pm,
                        .acpi_match_table = ACPI_PTR(i2c_hid_acpi_match),
                        .of_match_table = of_match_ptr(i2c_hid_of_match),
diff --combined drivers/hid/wacom_sys.c
          static ssize_t wacom_led_select_store(struct device *dev, int set_id,
                                              const char *buf, size_t count)
          {
-- -------      struct hid_device *hdev = container_of(dev, struct hid_device, dev);
++ +++++++      struct hid_device *hdev = to_hid_device(dev);
                struct wacom *wacom = hid_get_drvdata(hdev);
                unsigned int id;
                int err;
@@@@@@@@@@@ -714,7 -714,7 -714,7 -714,7 -714,7 -714,7 -714,7 -714,7 -714,7 -714,7 +714,7 @@@@@@@@@@@ static ssize_t wacom_led##SET_ID##_sele
          static ssize_t wacom_led##SET_ID##_select_show(struct device *dev,    \
                struct device_attribute *attr, char *buf)                       \
          {                                                                     \
-- -------      struct hid_device *hdev = container_of(dev, struct hid_device, dev);\
++ +++++++      struct hid_device *hdev = to_hid_device(dev);\
                struct wacom *wacom = hid_get_drvdata(hdev);                    \
                return scnprintf(buf, PAGE_SIZE, "%d\n",                        \
                                 wacom->led.select[SET_ID]);                    \
@@@@@@@@@@@ -750,7 -750,7 -750,7 -750,7 -750,7 -750,7 -750,7 -750,7 -750,7 -750,7 +750,7 @@@@@@@@@@@ static ssize_t wacom_luminance_store(st
          static ssize_t wacom_##name##_luminance_store(struct device *dev,     \
                struct device_attribute *attr, const char *buf, size_t count)   \
          {                                                                     \
-- -------      struct hid_device *hdev = container_of(dev, struct hid_device, dev);\
++ +++++++      struct hid_device *hdev = to_hid_device(dev);\
                struct wacom *wacom = hid_get_drvdata(hdev);                    \
                                                                                \
                return wacom_luminance_store(wacom, &wacom->led.field,          \
@@@@@@@@@@@ -773,7 -773,7 -773,7 -773,7 -773,7 -773,7 -773,7 -773,7 -773,7 -773,7 +773,7 @@@@@@@@@@@ DEVICE_LUMINANCE_ATTR(buttons, img_lum)
          static ssize_t wacom_button_image_store(struct device *dev, int button_id,
                                                const char *buf, size_t count)
          {
-- -------      struct hid_device *hdev = container_of(dev, struct hid_device, dev);
++ +++++++      struct hid_device *hdev = to_hid_device(dev);
                struct wacom *wacom = hid_get_drvdata(hdev);
                int err;
                unsigned len;
@@@@@@@@@@@ -1097,7 -1097,7 -1097,7 -1097,7 -1097,7 -1097,7 -1097,7 -1097,7 -1097,7 -1097,7 +1097,7 @@@@@@@@@@@ static ssize_t wacom_show_speed(struct 
                                        struct device_attribute
                                        *attr, char *buf)
          {
-- -------      struct hid_device *hdev = container_of(dev, struct hid_device, dev);
++ +++++++      struct hid_device *hdev = to_hid_device(dev);
                struct wacom *wacom = hid_get_drvdata(hdev);
          
                return snprintf(buf, PAGE_SIZE, "%i\n", wacom->wacom_wac.bt_high_speed);
@@@@@@@@@@@ -1107,7 -1107,7 -1107,7 -1107,7 -1107,7 -1107,7 -1107,7 -1107,7 -1107,7 -1107,7 +1107,7 @@@@@@@@@@@ static ssize_t wacom_store_speed(struc
                                        struct device_attribute *attr,
                                        const char *buf, size_t count)
          {
-- -------      struct hid_device *hdev = container_of(dev, struct hid_device, dev);
++ +++++++      struct hid_device *hdev = to_hid_device(dev);
                struct wacom *wacom = hid_get_drvdata(hdev);
                u8 new_speed;
          
@@@@@@@@@@@ -1130,8 -1130,8 -1130,8 -1130,8 -1130,8 -1130,8 -1130,8 -1130,8 -1130,8 -1130,8 +1130,8 @@@@@@@@@@@ static ssize_t wacom_show_remote_mode(s
                                              struct kobj_attribute *kattr,
                                              char *buf, int index)
          {
-- -------      struct device *dev = container_of(kobj->parent, struct device, kobj);
-- -------      struct hid_device *hdev = container_of(dev, struct hid_device, dev);
++ +++++++      struct device *dev = kobj_to_dev(kobj->parent);
++ +++++++      struct hid_device *hdev = to_hid_device(dev);
                struct wacom *wacom = hid_get_drvdata(hdev);
                u8 mode;
          
@@@@@@@@@@@ -1241,8 -1241,8 -1241,8 -1241,8 -1241,8 -1241,8 -1241,8 -1241,8 -1241,8 -1241,8 +1241,8 @@@@@@@@@@@ static ssize_t wacom_store_unpair_remot
                                                 const char *buf, size_t count)
          {
                unsigned char selector = 0;
-- -------      struct device *dev = container_of(kobj->parent, struct device, kobj);
-- -------      struct hid_device *hdev = container_of(dev, struct hid_device, dev);
++ +++++++      struct device *dev = kobj_to_dev(kobj->parent);
++ +++++++      struct hid_device *hdev = to_hid_device(dev);
                struct wacom *wacom = hid_get_drvdata(hdev);
                int err;
          
@@@@@@@@@@@ -1353,8 -1353,8 -1353,8 -1353,8 -1353,8 -1353,8 -1353,8 -1353,8 -1353,8 -1353,7 +1353,7 @@@@@@@@@@@ static void wacom_clean_inputs(struct w
                        else
                                input_free_device(wacom->wacom_wac.pad_input);
                }
---------       if (wacom->remote_dir)
---------               kobject_put(wacom->remote_dir);
+++++++++       kobject_put(wacom->remote_dir);
                wacom->wacom_wac.pen_input = NULL;
                wacom->wacom_wac.touch_input = NULL;
                wacom->wacom_wac.pad_input = NULL;
diff --combined drivers/hid/wacom_wac.c
           */
          #define WACOM_CONTACT_AREA_SCALE 2607
          
+++++++++ static void wacom_report_numbered_buttons(struct input_dev *input_dev,
+++++++++                               int button_count, int mask);
+++++++++ 
          /*
           * Percent of battery capacity for Graphire.
           * 8th value means AC online and show 100% capacity.
          static void wacom_intuos_schedule_prox_event(struct wacom_wac *wacom_wac)
          {
                struct wacom *wacom = container_of(wacom_wac, struct wacom, wacom_wac);
+++++++++       struct wacom_features *features = &wacom_wac->features;
                struct hid_report *r;
                struct hid_report_enum *re;
          
                re = &(wacom->hdev->report_enum[HID_FEATURE_REPORT]);
---------       r = re->report_id_hash[WACOM_REPORT_INTUOSREAD];
+++++++++       if (features->type == INTUOSHT2)
+++++++++               r = re->report_id_hash[WACOM_REPORT_INTUOSHT2_ID];
+++++++++       else
+++++++++               r = re->report_id_hash[WACOM_REPORT_INTUOS_ID1];
                if (r) {
                        hid_hw_request(wacom->hdev, r, HID_REQ_GET_REPORT);
                }
          }
          
+++++++++ static int wacom_intuos_pad(struct wacom_wac *wacom)
+++++++++ {
+++++++++       struct wacom_features *features = &wacom->features;
+++++++++       unsigned char *data = wacom->data;
+++++++++       struct input_dev *input = wacom->pad_input;
+++++++++       int i;
+++++++++       int buttons = 0, nbuttons = features->numbered_buttons;
+++++++++       int keys = 0, nkeys = 0;
+++++++++       int ring1 = 0, ring2 = 0;
+++++++++       int strip1 = 0, strip2 = 0;
+++++++++       bool prox = false;
+++++++++ 
+++++++++       /* pad packets. Works as a second tool and is always in prox */
+++++++++       if (!(data[0] == WACOM_REPORT_INTUOSPAD || data[0] == WACOM_REPORT_INTUOS5PAD ||
+++++++++             data[0] == WACOM_REPORT_CINTIQPAD))
+++++++++               return 0;
+++++++++ 
+++++++++       if (features->type >= INTUOS4S && features->type <= INTUOS4L) {
+++++++++               buttons = (data[3] << 1) | (data[2] & 0x01);
+++++++++               ring1 = data[1];
+++++++++       } else if (features->type == DTK) {
+++++++++               buttons = data[6];
+++++++++       } else if (features->type == WACOM_13HD) {
+++++++++               buttons = (data[4] << 1) | (data[3] & 0x01);
+++++++++       } else if (features->type == WACOM_24HD) {
+++++++++               buttons = (data[8] << 8) | data[6];
+++++++++               ring1 = data[1];
+++++++++               ring2 = data[2];
+++++++++ 
+++++++++               /*
+++++++++                * Three "buttons" are available on the 24HD which are
+++++++++                * physically implemented as a touchstrip. Each button
+++++++++                * is approximately 3 bits wide with a 2 bit spacing.
+++++++++                * The raw touchstrip bits are stored at:
+++++++++                *    ((data[3] & 0x1f) << 8) | data[4])
+++++++++                */
+++++++++               nkeys = 3;
+++++++++               keys = ((data[3] & 0x1C) ? 1<<2 : 0) |
+++++++++                      ((data[4] & 0xE0) ? 1<<1 : 0) |
+++++++++                      ((data[4] & 0x07) ? 1<<0 : 0);
+++++++++       } else if (features->type == WACOM_27QHD) {
+++++++++               nkeys = 3;
+++++++++               keys = data[2] & 0x07;
+++++++++ 
+++++++++               input_report_abs(input, ABS_X, be16_to_cpup((__be16 *)&data[4]));
+++++++++               input_report_abs(input, ABS_Y, be16_to_cpup((__be16 *)&data[6]));
+++++++++               input_report_abs(input, ABS_Z, be16_to_cpup((__be16 *)&data[8]));
+++++++++       } else if (features->type == CINTIQ_HYBRID) {
+++++++++               /*
+++++++++                * Do not send hardware buttons under Android. They
+++++++++                * are already sent to the system through GPIO (and
+++++++++                * have different meaning).
+++++++++                *
+++++++++                * d-pad right  -> data[4] & 0x10
+++++++++                * d-pad up     -> data[4] & 0x20
+++++++++                * d-pad left   -> data[4] & 0x40
+++++++++                * d-pad down   -> data[4] & 0x80
+++++++++                * d-pad center -> data[3] & 0x01
+++++++++                */
+++++++++               buttons = (data[4] << 1) | (data[3] & 0x01);
+++++++++       } else if (features->type == CINTIQ_COMPANION_2) {
+++++++++               /* d-pad right  -> data[4] & 0x10
+++++++++                * d-pad up     -> data[4] & 0x20
+++++++++                * d-pad left   -> data[4] & 0x40
+++++++++                * d-pad down   -> data[4] & 0x80
+++++++++                * d-pad center -> data[3] & 0x01
+++++++++                */
+++++++++               buttons = ((data[2] >> 4) << 7) |
+++++++++                         ((data[1] & 0x04) << 6) |
+++++++++                         ((data[2] & 0x0F) << 2) |
+++++++++                         (data[1] & 0x03);
+++++++++       } else if (features->type >= INTUOS5S && features->type <= INTUOSPL) {
+++++++++               /*
+++++++++                * ExpressKeys on Intuos5/Intuos Pro have a capacitive sensor in
+++++++++                * addition to the mechanical switch. Switch data is
+++++++++                * stored in data[4], capacitive data in data[5].
+++++++++                *
+++++++++                * Touch ring mode switch (data[3]) has no capacitive sensor
+++++++++                */
+++++++++               buttons = (data[4] << 1) | (data[3] & 0x01);
+++++++++               ring1 = data[2];
+++++++++       } else {
+++++++++               if (features->type == WACOM_21UX2 || features->type == WACOM_22HD) {
+++++++++                       buttons = (data[8] << 10) | ((data[7] & 0x01) << 9) |
+++++++++                                 (data[6] << 1) | (data[5] & 0x01);
+++++++++ 
+++++++++                       if (features->type == WACOM_22HD) {
+++++++++                               nkeys = 3;
+++++++++                               keys = data[9] & 0x07;
+++++++++                       }
+++++++++               } else {
+++++++++                       buttons = ((data[6] & 0x10) << 10) |
+++++++++                                 ((data[5] & 0x10) << 9)  |
+++++++++                                 ((data[6] & 0x0F) << 4)  |
+++++++++                                 (data[5] & 0x0F);
+++++++++               }
+++++++++               strip1 = ((data[1] & 0x1f) << 8) | data[2];
+++++++++               strip2 = ((data[3] & 0x1f) << 8) | data[4];
+++++++++       }
+++++++++ 
+++++++++       prox = (buttons & ~(~0 << nbuttons)) | (keys & ~(~0 << nkeys)) |
+++++++++              (ring1 & 0x80) | (ring2 & 0x80) | strip1 | strip2;
+++++++++ 
+++++++++       wacom_report_numbered_buttons(input, nbuttons, buttons);
+++++++++ 
+++++++++       for (i = 0; i < nkeys; i++)
+++++++++               input_report_key(input, KEY_PROG1 + i, keys & (1 << i));
+++++++++ 
+++++++++       input_report_abs(input, ABS_RX, strip1);
+++++++++       input_report_abs(input, ABS_RY, strip2);
+++++++++ 
+++++++++       input_report_abs(input, ABS_WHEEL,    (ring1 & 0x80) ? (ring1 & 0x7f) : 0);
+++++++++       input_report_abs(input, ABS_THROTTLE, (ring2 & 0x80) ? (ring2 & 0x7f) : 0);
+++++++++ 
+++++++++       input_report_key(input, wacom->tool[1], prox ? 1 : 0);
+++++++++       input_report_abs(input, ABS_MISC, prox ? PAD_DEVICE_ID : 0);
+++++++++ 
+++++++++       input_event(input, EV_MSC, MSC_SERIAL, 0xffffffff);
+++++++++ 
+++++++++       return 1;
+++++++++ }
+++++++++ 
          static int wacom_intuos_inout(struct wacom_wac *wacom)
          {
                struct wacom_features *features = &wacom->features;
@@@@@@@@@@@ -755,19 -755,19 -755,19 -755,19 -755,19 -755,19 -755,19 -755,19 -755,19 -884,40 +884,40 @@@@@@@@@@@ static int wacom_remote_status_irq(stru
                return 0;
          }
          
--------- static void wacom_intuos_general(struct wacom_wac *wacom)
+++++++++ static int wacom_intuos_general(struct wacom_wac *wacom)
          {
                struct wacom_features *features = &wacom->features;
                unsigned char *data = wacom->data;
                struct input_dev *input = wacom->pen_input;
---------       unsigned int t;
+++++++++       int idx = (features->type == INTUOS) ? (data[1] & 0x01) : 0;
+++++++++       unsigned char type = (data[1] >> 1) & 0x0F;
+++++++++       unsigned int x, y, distance, t;
          
---------       /* general pen packet */
---------       if ((data[1] & 0xb8) == 0xa0) {
---------               t = (data[6] << 2) | ((data[7] >> 6) & 3);
---------               if (features->pressure_max == 2047) {
---------                       t = (t << 1) | (data[1] & 1);
---------               }
+++++++++       if (data[0] != WACOM_REPORT_PENABLED && data[0] != WACOM_REPORT_CINTIQ &&
+++++++++               data[0] != WACOM_REPORT_INTUOS_PEN)
+++++++++               return 0;
+++++++++ 
+++++++++       x = (be16_to_cpup((__be16 *)&data[2]) << 1) | ((data[9] >> 1) & 1);
+++++++++       y = (be16_to_cpup((__be16 *)&data[4]) << 1) | (data[9] & 1);
+++++++++       distance = data[9] >> 2;
+++++++++       if (features->type < INTUOS3S) {
+++++++++               x >>= 1;
+++++++++               y >>= 1;
+++++++++               distance >>= 1;
+++++++++       }
+++++++++       input_report_abs(input, ABS_X, x);
+++++++++       input_report_abs(input, ABS_Y, y);
+++++++++       input_report_abs(input, ABS_DISTANCE, distance);
+++++++++ 
+++++++++       switch (type) {
+++++++++       case 0x00:
+++++++++       case 0x01:
+++++++++       case 0x02:
+++++++++       case 0x03:
+++++++++               /* general pen packet */
+++++++++               t = (data[6] << 3) | ((data[7] & 0xC0) >> 5) | (data[1] & 1);
+++++++++               if (features->pressure_max < 2047)
+++++++++                       t >>= 1;
                        input_report_abs(input, ABS_PRESSURE, t);
                        if (features->type != INTUOSHT2) {
                            input_report_abs(input, ABS_TILT_X,
                        input_report_key(input, BTN_STYLUS, data[1] & 2);
                        input_report_key(input, BTN_STYLUS2, data[1] & 4);
                        input_report_key(input, BTN_TOUCH, t > 10);
---------       }
+++++++++               break;
          
---------       /* airbrush second packet */
---------       if ((data[1] & 0xbc) == 0xb4) {
+++++++++       case 0x0a:
+++++++++               /* airbrush second packet */
                        input_report_abs(input, ABS_WHEEL,
                                        (data[6] << 2) | ((data[7] >> 6) & 3));
                        input_report_abs(input, ABS_TILT_X,
                                         (((data[7] << 1) & 0x7e) | (data[8] >> 7)) - 64);
                        input_report_abs(input, ABS_TILT_Y, (data[8] & 0x7f) - 64);
+++++++++               break;
+++++++++ 
+++++++++       case 0x05:
+++++++++               /* Rotation packet */
+++++++++               if (features->type >= INTUOS3S) {
+++++++++                       /* I3 marker pen rotation */
+++++++++                       t = (data[6] << 3) | ((data[7] >> 5) & 7);
+++++++++                       t = (data[7] & 0x20) ? ((t > 900) ? ((t-1) / 2 - 1350) :
+++++++++                               ((t-1) / 2 + 450)) : (450 - t / 2) ;
+++++++++                       input_report_abs(input, ABS_Z, t);
+++++++++               } else {
+++++++++                       /* 4D mouse 2nd packet */
+++++++++                       t = (data[6] << 3) | ((data[7] >> 5) & 7);
+++++++++                       input_report_abs(input, ABS_RZ, (data[7] & 0x20) ?
+++++++++                               ((t - 1) / 2) : -t / 2);
+++++++++               }
+++++++++               break;
+++++++++ 
+++++++++       case 0x04:
+++++++++               /* 4D mouse 1st packet */
+++++++++               input_report_key(input, BTN_LEFT,   data[8] & 0x01);
+++++++++               input_report_key(input, BTN_MIDDLE, data[8] & 0x02);
+++++++++               input_report_key(input, BTN_RIGHT,  data[8] & 0x04);
+++++++++ 
+++++++++               input_report_key(input, BTN_SIDE,   data[8] & 0x20);
+++++++++               input_report_key(input, BTN_EXTRA,  data[8] & 0x10);
+++++++++               t = (data[6] << 2) | ((data[7] >> 6) & 3);
+++++++++               input_report_abs(input, ABS_THROTTLE, (data[8] & 0x08) ? -t : t);
+++++++++               break;
+++++++++ 
+++++++++       case 0x06:
+++++++++               /* I4 mouse */
+++++++++               input_report_key(input, BTN_LEFT,   data[6] & 0x01);
+++++++++               input_report_key(input, BTN_MIDDLE, data[6] & 0x02);
+++++++++               input_report_key(input, BTN_RIGHT,  data[6] & 0x04);
+++++++++               input_report_rel(input, REL_WHEEL, ((data[7] & 0x80) >> 7)
+++++++++                                - ((data[7] & 0x40) >> 6));
+++++++++               input_report_key(input, BTN_SIDE,   data[6] & 0x08);
+++++++++               input_report_key(input, BTN_EXTRA,  data[6] & 0x10);
+++++++++ 
+++++++++               input_report_abs(input, ABS_TILT_X,
+++++++++                       (((data[7] << 1) & 0x7e) | (data[8] >> 7)) - 64);
+++++++++               input_report_abs(input, ABS_TILT_Y, (data[8] & 0x7f) - 64);
+++++++++               break;
+++++++++ 
+++++++++       case 0x08:
+++++++++               if (wacom->tool[idx] == BTN_TOOL_MOUSE) {
+++++++++                       /* 2D mouse packet */
+++++++++                       input_report_key(input, BTN_LEFT,   data[8] & 0x04);
+++++++++                       input_report_key(input, BTN_MIDDLE, data[8] & 0x08);
+++++++++                       input_report_key(input, BTN_RIGHT,  data[8] & 0x10);
+++++++++                       input_report_rel(input, REL_WHEEL, (data[8] & 0x01)
+++++++++                                        - ((data[8] & 0x02) >> 1));
+++++++++ 
+++++++++                       /* I3 2D mouse side buttons */
+++++++++                       if (features->type >= INTUOS3S && features->type <= INTUOS3L) {
+++++++++                               input_report_key(input, BTN_SIDE,   data[8] & 0x40);
+++++++++                               input_report_key(input, BTN_EXTRA,  data[8] & 0x20);
+++++++++                       }
+++++++++               }
+++++++++               else if (wacom->tool[idx] == BTN_TOOL_LENS) {
+++++++++                       /* Lens cursor packets */
+++++++++                       input_report_key(input, BTN_LEFT,   data[8] & 0x01);
+++++++++                       input_report_key(input, BTN_MIDDLE, data[8] & 0x02);
+++++++++                       input_report_key(input, BTN_RIGHT,  data[8] & 0x04);
+++++++++                       input_report_key(input, BTN_SIDE,   data[8] & 0x10);
+++++++++                       input_report_key(input, BTN_EXTRA,  data[8] & 0x08);
+++++++++               }
+++++++++               break;
+++++++++ 
+++++++++       case 0x07:
+++++++++       case 0x09:
+++++++++       case 0x0b:
+++++++++       case 0x0c:
+++++++++       case 0x0d:
+++++++++       case 0x0e:
+++++++++       case 0x0f:
+++++++++               /* unhandled */
+++++++++               break;
                }
+++++++++ 
+++++++++       input_report_abs(input, ABS_MISC, wacom->id[idx]); /* report tool id */
+++++++++       input_report_key(input, wacom->tool[idx], 1);
+++++++++       input_event(input, EV_MSC, MSC_SERIAL, wacom->serial[idx]);
+++++++++       wacom->reporting_data = true;
+++++++++       return 2;
          }
          
          static int wacom_intuos_irq(struct wacom_wac *wacom)
          {
---------       struct wacom_features *features = &wacom->features;
                unsigned char *data = wacom->data;
                struct input_dev *input = wacom->pen_input;
---------       unsigned int t;
---------       int idx = 0, result;
+++++++++       int result;
          
                if (data[0] != WACOM_REPORT_PENABLED &&
---------           data[0] != WACOM_REPORT_INTUOSREAD &&
---------           data[0] != WACOM_REPORT_INTUOSWRITE &&
+++++++++           data[0] != WACOM_REPORT_INTUOS_ID1 &&
+++++++++           data[0] != WACOM_REPORT_INTUOS_ID2 &&
                    data[0] != WACOM_REPORT_INTUOSPAD &&
                    data[0] != WACOM_REPORT_INTUOS_PEN &&
                    data[0] != WACOM_REPORT_CINTIQ &&
                          return 0;
                }
          
---------       /* tool number */
---------       if (features->type == INTUOS)
---------               idx = data[1] & 0x01;
--------- 
---------       /* pad packets. Works as a second tool and is always in prox */
---------       if (data[0] == WACOM_REPORT_INTUOSPAD || data[0] == WACOM_REPORT_INTUOS5PAD ||
---------           data[0] == WACOM_REPORT_CINTIQPAD) {
---------               input = wacom->pad_input;
---------               if (features->type >= INTUOS4S && features->type <= INTUOS4L) {
---------                       input_report_key(input, BTN_0, (data[2] & 0x01));
---------                       input_report_key(input, BTN_1, (data[3] & 0x01));
---------                       input_report_key(input, BTN_2, (data[3] & 0x02));
---------                       input_report_key(input, BTN_3, (data[3] & 0x04));
---------                       input_report_key(input, BTN_4, (data[3] & 0x08));
---------                       input_report_key(input, BTN_5, (data[3] & 0x10));
---------                       input_report_key(input, BTN_6, (data[3] & 0x20));
---------                       if (data[1] & 0x80) {
---------                               input_report_abs(input, ABS_WHEEL, (data[1] & 0x7f));
---------                       } else {
---------                               /* Out of proximity, clear wheel value. */
---------                               input_report_abs(input, ABS_WHEEL, 0);
---------                       }
---------                       if (features->type != INTUOS4S) {
---------                               input_report_key(input, BTN_7, (data[3] & 0x40));
---------                               input_report_key(input, BTN_8, (data[3] & 0x80));
---------                       }
---------                       if (data[1] | (data[2] & 0x01) | data[3]) {
---------                               input_report_abs(input, ABS_MISC, PAD_DEVICE_ID);
---------                       } else {
---------                               input_report_abs(input, ABS_MISC, 0);
---------                       }
---------               } else if (features->type == DTK) {
---------                       input_report_key(input, BTN_0, (data[6] & 0x01));
---------                       input_report_key(input, BTN_1, (data[6] & 0x02));
---------                       input_report_key(input, BTN_2, (data[6] & 0x04));
---------                       input_report_key(input, BTN_3, (data[6] & 0x08));
---------                       input_report_key(input, BTN_4, (data[6] & 0x10));
---------                       input_report_key(input, BTN_5, (data[6] & 0x20));
---------                       if (data[6] & 0x3f) {
---------                               input_report_abs(input, ABS_MISC, PAD_DEVICE_ID);
---------                       } else {
---------                               input_report_abs(input, ABS_MISC, 0);
---------                       }
---------               } else if (features->type == WACOM_13HD) {
---------                       input_report_key(input, BTN_0, (data[3] & 0x01));
---------                       input_report_key(input, BTN_1, (data[4] & 0x01));
---------                       input_report_key(input, BTN_2, (data[4] & 0x02));
---------                       input_report_key(input, BTN_3, (data[4] & 0x04));
---------                       input_report_key(input, BTN_4, (data[4] & 0x08));
---------                       input_report_key(input, BTN_5, (data[4] & 0x10));
---------                       input_report_key(input, BTN_6, (data[4] & 0x20));
---------                       input_report_key(input, BTN_7, (data[4] & 0x40));
---------                       input_report_key(input, BTN_8, (data[4] & 0x80));
---------                       if ((data[3] & 0x01) | data[4]) {
---------                               input_report_abs(input, ABS_MISC, PAD_DEVICE_ID);
---------                       } else {
---------                               input_report_abs(input, ABS_MISC, 0);
---------                       }
---------               } else if (features->type == WACOM_24HD) {
---------                       input_report_key(input, BTN_0, (data[6] & 0x01));
---------                       input_report_key(input, BTN_1, (data[6] & 0x02));
---------                       input_report_key(input, BTN_2, (data[6] & 0x04));
---------                       input_report_key(input, BTN_3, (data[6] & 0x08));
---------                       input_report_key(input, BTN_4, (data[6] & 0x10));
---------                       input_report_key(input, BTN_5, (data[6] & 0x20));
---------                       input_report_key(input, BTN_6, (data[6] & 0x40));
---------                       input_report_key(input, BTN_7, (data[6] & 0x80));
---------                       input_report_key(input, BTN_8, (data[8] & 0x01));
---------                       input_report_key(input, BTN_9, (data[8] & 0x02));
---------                       input_report_key(input, BTN_A, (data[8] & 0x04));
---------                       input_report_key(input, BTN_B, (data[8] & 0x08));
---------                       input_report_key(input, BTN_C, (data[8] & 0x10));
---------                       input_report_key(input, BTN_X, (data[8] & 0x20));
---------                       input_report_key(input, BTN_Y, (data[8] & 0x40));
---------                       input_report_key(input, BTN_Z, (data[8] & 0x80));
--------- 
---------                       /*
---------                        * Three "buttons" are available on the 24HD which are
---------                        * physically implemented as a touchstrip. Each button
---------                        * is approximately 3 bits wide with a 2 bit spacing.
---------                        * The raw touchstrip bits are stored at:
---------                        *    ((data[3] & 0x1f) << 8) | data[4])
---------                        */
---------                       input_report_key(input, KEY_PROG1, data[4] & 0x07);
---------                       input_report_key(input, KEY_PROG2, data[4] & 0xE0);
---------                       input_report_key(input, KEY_PROG3, data[3] & 0x1C);
--------- 
---------                       if (data[1] & 0x80) {
---------                               input_report_abs(input, ABS_WHEEL, (data[1] & 0x7f));
---------                       } else {
---------                               /* Out of proximity, clear wheel value. */
---------                               input_report_abs(input, ABS_WHEEL, 0);
---------                       }
--------- 
---------                       if (data[2] & 0x80) {
---------                               input_report_abs(input, ABS_THROTTLE, (data[2] & 0x7f));
---------                       } else {
---------                               /* Out of proximity, clear second wheel value. */
---------                               input_report_abs(input, ABS_THROTTLE, 0);
---------                       }
--------- 
---------                       if (data[1] | data[2] | (data[3] & 0x1f) | data[4] | data[6] | data[8]) {
---------                               input_report_abs(input, ABS_MISC, PAD_DEVICE_ID);
---------                       } else {
---------                               input_report_abs(input, ABS_MISC, 0);
---------                       }
---------               } else if (features->type == WACOM_27QHD) {
---------                       input_report_key(input, KEY_PROG1, data[2] & 0x01);
---------                       input_report_key(input, KEY_PROG2, data[2] & 0x02);
---------                       input_report_key(input, KEY_PROG3, data[2] & 0x04);
--------- 
---------                       input_report_abs(input, ABS_X, be16_to_cpup((__be16 *)&data[4]));
---------                       input_report_abs(input, ABS_Y, be16_to_cpup((__be16 *)&data[6]));
---------                       input_report_abs(input, ABS_Z, be16_to_cpup((__be16 *)&data[8]));
---------                       if ((data[2] & 0x07) | data[4] | data[5] | data[6] | data[7] | data[8] | data[9]) {
---------                               input_report_abs(input, ABS_MISC, PAD_DEVICE_ID);
---------                       } else {
---------                               input_report_abs(input, ABS_MISC, 0);
---------                       }
---------               } else if (features->type == CINTIQ_HYBRID) {
---------                       /*
---------                        * Do not send hardware buttons under Android. They
---------                        * are already sent to the system through GPIO (and
---------                        * have different meaning).
---------                        */
---------                       input_report_key(input, BTN_1, (data[4] & 0x01));
---------                       input_report_key(input, BTN_2, (data[4] & 0x02));
---------                       input_report_key(input, BTN_3, (data[4] & 0x04));
---------                       input_report_key(input, BTN_4, (data[4] & 0x08));
--------- 
---------                       input_report_key(input, BTN_5, (data[4] & 0x10));  /* Right  */
---------                       input_report_key(input, BTN_6, (data[4] & 0x20));  /* Up     */
---------                       input_report_key(input, BTN_7, (data[4] & 0x40));  /* Left   */
---------                       input_report_key(input, BTN_8, (data[4] & 0x80));  /* Down   */
---------                       input_report_key(input, BTN_0, (data[3] & 0x01));  /* Center */
--------- 
---------                       if (data[4] | (data[3] & 0x01)) {
---------                               input_report_abs(input, ABS_MISC, PAD_DEVICE_ID);
---------                       } else {
---------                               input_report_abs(input, ABS_MISC, 0);
---------                       }
--------- 
---------               } else if (features->type == CINTIQ_COMPANION_2) {
---------                       input_report_key(input, BTN_1, (data[1] & 0x02));
---------                       input_report_key(input, BTN_2, (data[2] & 0x01));
---------                       input_report_key(input, BTN_3, (data[2] & 0x02));
---------                       input_report_key(input, BTN_4, (data[2] & 0x04));
---------                       input_report_key(input, BTN_5, (data[2] & 0x08));
---------                       input_report_key(input, BTN_6, (data[1] & 0x04));
--------- 
---------                       input_report_key(input, BTN_7, (data[2] & 0x10));  /* Right  */
---------                       input_report_key(input, BTN_8, (data[2] & 0x20));  /* Up         */
---------                       input_report_key(input, BTN_9, (data[2] & 0x40));  /* Left   */
---------                       input_report_key(input, BTN_A, (data[2] & 0x80));  /* Down   */
---------                       input_report_key(input, BTN_0, (data[1] & 0x01));  /* Center */
--------- 
---------                       if (data[2] | (data[1] & 0x07)) {
---------                               input_report_abs(input, ABS_MISC, PAD_DEVICE_ID);
---------                       } else {
---------                               input_report_abs(input, ABS_MISC, 0);
---------                       }
--------- 
---------               } else if (features->type >= INTUOS5S && features->type <= INTUOSPL) {
---------                       int i;
--------- 
---------                       /* Touch ring mode switch has no capacitive sensor */
---------                       input_report_key(input, BTN_0, (data[3] & 0x01));
--------- 
---------                       /*
---------                        * ExpressKeys on Intuos5/Intuos Pro have a capacitive sensor in
---------                        * addition to the mechanical switch. Switch data is
---------                        * stored in data[4], capacitive data in data[5].
---------                        */
---------                       for (i = 0; i < 8; i++)
---------                               input_report_key(input, BTN_1 + i, data[4] & (1 << i));
--------- 
---------                       if (data[2] & 0x80) {
---------                               input_report_abs(input, ABS_WHEEL, (data[2] & 0x7f));
---------                       } else {
---------                               /* Out of proximity, clear wheel value. */
---------                               input_report_abs(input, ABS_WHEEL, 0);
---------                       }
--------- 
---------                       if (data[2] | (data[3] & 0x01) | data[4] | data[5]) {
---------                               input_report_abs(input, ABS_MISC, PAD_DEVICE_ID);
---------                       } else {
---------                               input_report_abs(input, ABS_MISC, 0);
---------                       }
---------               } else {
---------                       if (features->type == WACOM_21UX2 || features->type == WACOM_22HD) {
---------                               input_report_key(input, BTN_0, (data[5] & 0x01));
---------                               input_report_key(input, BTN_1, (data[6] & 0x01));
---------                               input_report_key(input, BTN_2, (data[6] & 0x02));
---------                               input_report_key(input, BTN_3, (data[6] & 0x04));
---------                               input_report_key(input, BTN_4, (data[6] & 0x08));
---------                               input_report_key(input, BTN_5, (data[6] & 0x10));
---------                               input_report_key(input, BTN_6, (data[6] & 0x20));
---------                               input_report_key(input, BTN_7, (data[6] & 0x40));
---------                               input_report_key(input, BTN_8, (data[6] & 0x80));
---------                               input_report_key(input, BTN_9, (data[7] & 0x01));
---------                               input_report_key(input, BTN_A, (data[8] & 0x01));
---------                               input_report_key(input, BTN_B, (data[8] & 0x02));
---------                               input_report_key(input, BTN_C, (data[8] & 0x04));
---------                               input_report_key(input, BTN_X, (data[8] & 0x08));
---------                               input_report_key(input, BTN_Y, (data[8] & 0x10));
---------                               input_report_key(input, BTN_Z, (data[8] & 0x20));
---------                               input_report_key(input, BTN_BASE, (data[8] & 0x40));
---------                               input_report_key(input, BTN_BASE2, (data[8] & 0x80));
--------- 
---------                               if (features->type == WACOM_22HD) {
---------                                       input_report_key(input, KEY_PROG1, data[9] & 0x01);
---------                                       input_report_key(input, KEY_PROG2, data[9] & 0x02);
---------                                       input_report_key(input, KEY_PROG3, data[9] & 0x04);
---------                               }
---------                       } else {
---------                               input_report_key(input, BTN_0, (data[5] & 0x01));
---------                               input_report_key(input, BTN_1, (data[5] & 0x02));
---------                               input_report_key(input, BTN_2, (data[5] & 0x04));
---------                               input_report_key(input, BTN_3, (data[5] & 0x08));
---------                               input_report_key(input, BTN_4, (data[6] & 0x01));
---------                               input_report_key(input, BTN_5, (data[6] & 0x02));
---------                               input_report_key(input, BTN_6, (data[6] & 0x04));
---------                               input_report_key(input, BTN_7, (data[6] & 0x08));
---------                               input_report_key(input, BTN_8, (data[5] & 0x10));
---------                               input_report_key(input, BTN_9, (data[6] & 0x10));
---------                       }
---------                       input_report_abs(input, ABS_RX, ((data[1] & 0x1f) << 8) | data[2]);
---------                       input_report_abs(input, ABS_RY, ((data[3] & 0x1f) << 8) | data[4]);
--------- 
---------                       if ((data[5] & 0x1f) | data[6] | (data[1] & 0x1f) |
---------                               data[2] | (data[3] & 0x1f) | data[4] | data[8] |
---------                               (data[7] & 0x01)) {
---------                               input_report_abs(input, ABS_MISC, PAD_DEVICE_ID);
---------                       } else {
---------                               input_report_abs(input, ABS_MISC, 0);
---------                       }
---------               }
---------                 return 1;
---------       }
+++++++++       /* process pad events */
+++++++++       result = wacom_intuos_pad(wacom);
+++++++++       if (result)
+++++++++               return result;
          
                /* process in/out prox events */
                result = wacom_intuos_inout(wacom);
                if (result)
---------                 return result - 1;
--------- 
---------       if (features->type >= INTUOS3S) {
---------               input_report_abs(input, ABS_X, (data[2] << 9) | (data[3] << 1) | ((data[9] >> 1) & 1));
---------               input_report_abs(input, ABS_Y, (data[4] << 9) | (data[5] << 1) | (data[9] & 1));
---------               input_report_abs(input, ABS_DISTANCE, ((data[9] >> 2) & 0x3f));
---------       } else {
---------               input_report_abs(input, ABS_X, be16_to_cpup((__be16 *)&data[2]));
---------               input_report_abs(input, ABS_Y, be16_to_cpup((__be16 *)&data[4]));
---------               input_report_abs(input, ABS_DISTANCE, ((data[9] >> 3) & 0x1f));
---------       }
+++++++++               return result - 1;
          
                /* process general packets */
---------       wacom_intuos_general(wacom);
--------- 
---------       /* 4D mouse, 2D mouse, marker pen rotation, tilt mouse, or Lens cursor packets */
---------       if ((data[1] & 0xbc) == 0xa8 || (data[1] & 0xbe) == 0xb0 || (data[1] & 0xbc) == 0xac) {
--------- 
---------               if (data[1] & 0x02) {
---------                       /* Rotation packet */
---------                       if (features->type >= INTUOS3S) {
---------                               /* I3 marker pen rotation */
---------                               t = (data[6] << 3) | ((data[7] >> 5) & 7);
---------                               t = (data[7] & 0x20) ? ((t > 900) ? ((t-1) / 2 - 1350) :
---------                                       ((t-1) / 2 + 450)) : (450 - t / 2) ;
---------                               input_report_abs(input, ABS_Z, t);
---------                       } else {
---------                               /* 4D mouse rotation packet */
---------                               t = (data[6] << 3) | ((data[7] >> 5) & 7);
---------                               input_report_abs(input, ABS_RZ, (data[7] & 0x20) ?
---------                                       ((t - 1) / 2) : -t / 2);
---------                       }
--------- 
---------               } else if (!(data[1] & 0x10) && features->type < INTUOS3S) {
---------                       /* 4D mouse packet */
---------                       input_report_key(input, BTN_LEFT,   data[8] & 0x01);
---------                       input_report_key(input, BTN_MIDDLE, data[8] & 0x02);
---------                       input_report_key(input, BTN_RIGHT,  data[8] & 0x04);
--------- 
---------                       input_report_key(input, BTN_SIDE,   data[8] & 0x20);
---------                       input_report_key(input, BTN_EXTRA,  data[8] & 0x10);
---------                       t = (data[6] << 2) | ((data[7] >> 6) & 3);
---------                       input_report_abs(input, ABS_THROTTLE, (data[8] & 0x08) ? -t : t);
--------- 
---------               } else if (wacom->tool[idx] == BTN_TOOL_MOUSE) {
---------                       /* I4 mouse */
---------                       if (features->type >= INTUOS4S && features->type <= INTUOSPL) {
---------                               input_report_key(input, BTN_LEFT,   data[6] & 0x01);
---------                               input_report_key(input, BTN_MIDDLE, data[6] & 0x02);
---------                               input_report_key(input, BTN_RIGHT,  data[6] & 0x04);
---------                               input_report_rel(input, REL_WHEEL, ((data[7] & 0x80) >> 7)
---------                                                - ((data[7] & 0x40) >> 6));
---------                               input_report_key(input, BTN_SIDE,   data[6] & 0x08);
---------                               input_report_key(input, BTN_EXTRA,  data[6] & 0x10);
--------- 
---------                               input_report_abs(input, ABS_TILT_X,
---------                                       (((data[7] << 1) & 0x7e) | (data[8] >> 7)) - 64);
---------                               input_report_abs(input, ABS_TILT_Y, (data[8] & 0x7f) - 64);
---------                       } else {
---------                               /* 2D mouse packet */
---------                               input_report_key(input, BTN_LEFT,   data[8] & 0x04);
---------                               input_report_key(input, BTN_MIDDLE, data[8] & 0x08);
---------                               input_report_key(input, BTN_RIGHT,  data[8] & 0x10);
---------                               input_report_rel(input, REL_WHEEL, (data[8] & 0x01)
---------                                                - ((data[8] & 0x02) >> 1));
--------- 
---------                               /* I3 2D mouse side buttons */
---------                               if (features->type >= INTUOS3S && features->type <= INTUOS3L) {
---------                                       input_report_key(input, BTN_SIDE,   data[8] & 0x40);
---------                                       input_report_key(input, BTN_EXTRA,  data[8] & 0x20);
---------                               }
---------                       }
---------               } else if ((features->type < INTUOS3S || features->type == INTUOS3L ||
---------                               features->type == INTUOS4L || features->type == INTUOS5L ||
---------                               features->type == INTUOSPL) &&
---------                          wacom->tool[idx] == BTN_TOOL_LENS) {
---------                       /* Lens cursor packets */
---------                       input_report_key(input, BTN_LEFT,   data[8] & 0x01);
---------                       input_report_key(input, BTN_MIDDLE, data[8] & 0x02);
---------                       input_report_key(input, BTN_RIGHT,  data[8] & 0x04);
---------                       input_report_key(input, BTN_SIDE,   data[8] & 0x10);
---------                       input_report_key(input, BTN_EXTRA,  data[8] & 0x08);
---------               }
---------       }
+++++++++       result = wacom_intuos_general(wacom);
+++++++++       if (result)
+++++++++               return result - 1;
          
---------       input_report_abs(input, ABS_MISC, wacom->id[idx]); /* report tool id */
---------       input_report_key(input, wacom->tool[idx], 1);
---------       input_event(input, EV_MSC, MSC_SERIAL, wacom->serial[idx]);
---------       wacom->reporting_data = true;
---------       return 1;
+++++++++       return 0;
          }
          
          static int int_dist(int x1, int y1, int x2, int y2)
@@@@@@@@@@@ -2481,7 -2481,7 -2481,7 -2481,7 -2481,7 -2481,7 -2481,7 -2481,7 -2481,7 -2397,7 +2397,7 @@@@@@@@@@@ void wacom_setup_device_quirks(struct w
                        if (features->pktlen == WACOM_PKGLEN_BBTOUCH3) {
                                if (features->touch_max)
                                        features->device_type |= WACOM_DEVICETYPE_TOUCH;
    -  - -                      if (features->type >= INTUOSHT || features->type <= BAMBOO_PT)
    +  + +                      if (features->type >= INTUOSHT && features->type <= BAMBOO_PT)
                                        features->device_type |= WACOM_DEVICETYPE_PAD;
          
                                features->x_max = 4096;
                        features->quirks |= WACOM_QUIRK_BATTERY;
          
                /* quirk for bamboo touch with 2 low res touches */
---------       if (features->type == BAMBOO_PT &&
+++++++++       if ((features->type == BAMBOO_PT || features->type == BAMBOO_TOUCH) &&
                    features->pktlen == WACOM_PKGLEN_BBTOUCH) {
                        features->x_max <<= 5;
                        features->y_max <<= 5;
@@@@@@@@@@@ -2806,6 -2806,6 -2806,6 -2806,6 -2806,6 -2806,6 -2806,6 -2806,6 -2806,6 -2722,19 +2722,19 @@@@@@@@@@@ static void wacom_setup_numbered_button
                        __set_bit(BTN_BASE + (i-16), input_dev->keybit);
          }
          
+++++++++ static void wacom_report_numbered_buttons(struct input_dev *input_dev,
+++++++++                               int button_count, int mask)
+++++++++ {
+++++++++       int i;
+++++++++ 
+++++++++       for (i = 0; i < button_count && i < 10; i++)
+++++++++               input_report_key(input_dev, BTN_0 + i, mask & (1 << i));
+++++++++       for (i = 10; i < button_count && i < 16; i++)
+++++++++               input_report_key(input_dev, BTN_A + (i-10), mask & (1 << i));
+++++++++       for (i = 16; i < button_count && i < 18; i++)
+++++++++               input_report_key(input_dev, BTN_BASE + (i-16), mask & (1 << i));
+++++++++ }
+++++++++ 
          int wacom_setup_pad_input_capabilities(struct input_dev *input_dev,
                                           struct wacom_wac *wacom_wac)
          {
@@@@@@@@@@@ -3213,8 -3213,8 -3213,8 -3213,8 -3213,7 -3213,8 -3213,8 -3213,7 -3213,8 -3142,7 +3142,8 @@@@@@@@@@@ static const struct wacom_features waco
                  WACOM_DTU_OFFSET, WACOM_DTU_OFFSET };
          static const struct wacom_features wacom_features_0x336 =
                { "Wacom DTU1141", 23472, 13203, 1023, 0,
    -  - -        DTUS, WACOM_INTUOS_RES, WACOM_INTUOS_RES, 4 };
    +  + +        DTUS, WACOM_INTUOS_RES, WACOM_INTUOS_RES, 4,
    +  + +        WACOM_DTU_OFFSET, WACOM_DTU_OFFSET };
          static const struct wacom_features wacom_features_0x57 =
                { "Wacom DTK2241", 95640, 54060, 2047, 63,
                  DTK, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, 6,