From: Greg Kroah-Hartman Date: Mon, 10 Apr 2017 15:17:54 +0000 (+0200) Subject: 4.9-stable patches X-Git-Tag: v4.4.61~21 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=38037cc961c0519ee824e0d9fbec985b9214b604;p=thirdparty%2Fkernel%2Fstable-queue.git 4.9-stable patches added patches: clk-lpc32xx-add-a-quirk-for-pwm-and-ms-clock-dividers.patch drm-sun4i-add-compatible-string-for-a31-a31s-tcon-timing-controller.patch drm-sun4i-add-compatible-strings-for-a31-a31s-display-pipelines.patch drm-sun4i-tcon-move-soc-specific-quirks-to-a-dt-matched-data-structure.patch hid-i2c-hid-add-a-simple-quirk-to-fix-device-defects.patch hid-usbhid-add-quirks-for-mayflash-dragonrise-gamecube-and-ps3-adapters.patch --- diff --git a/queue-4.9/clk-lpc32xx-add-a-quirk-for-pwm-and-ms-clock-dividers.patch b/queue-4.9/clk-lpc32xx-add-a-quirk-for-pwm-and-ms-clock-dividers.patch new file mode 100644 index 00000000000..3928bb24f30 --- /dev/null +++ b/queue-4.9/clk-lpc32xx-add-a-quirk-for-pwm-and-ms-clock-dividers.patch @@ -0,0 +1,102 @@ +From foo@baz Mon Apr 10 17:14:09 CEST 2017 +From: alexander.levin@verizon.com +Date: Tue, 4 Apr 2017 19:32:03 +0000 +Subject: clk: lpc32xx: add a quirk for PWM and MS clock dividers +To: "gregkh@linuxfoundation.org" +Cc: "stable@vger.kernel.org" +Message-ID: <20170404193158.19041-3-alexander.levin@verizon.com> + +From: Vladimir Zapolskiy + +[ Upstream commit f84d42a9cffc4ecd96f1ce3a038f841782142eb2 ] + +In common clock framework CLK_DIVIDER_ONE_BASED or'ed with +CLK_DIVIDER_ALLOW_ZERO flags indicates that +1) a divider clock may be set to zero value, +2) divider's zero value is interpreted as a non-divided clock. + +On the LPC32xx platform clock dividers of PWM and memory card clocks +comply with the first condition, but zero value means a gated clock, +thus it may happen that the divider value is not updated when +the clock is enabled and the clock remains gated. + +The change adds one-shot quirks, which check for zero value of divider +on initialization and set it to a non-zero value, therefore in runtime +a gate clock will work as expected. + +Signed-off-by: Vladimir Zapolskiy +Reviewed-by: Sylvain Lemieux +Signed-off-by: Stephen Boyd +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + drivers/clk/nxp/clk-lpc32xx.c | 32 ++++++++++++++++++++++++++++---- + 1 file changed, 28 insertions(+), 4 deletions(-) + +--- a/drivers/clk/nxp/clk-lpc32xx.c ++++ b/drivers/clk/nxp/clk-lpc32xx.c +@@ -1282,13 +1282,13 @@ static struct clk_hw_proto clk_hw_proto[ + + LPC32XX_DEFINE_MUX(PWM1_MUX, PWMCLK_CTRL, 1, 0x1, NULL, 0), + LPC32XX_DEFINE_DIV(PWM1_DIV, PWMCLK_CTRL, 4, 4, NULL, +- CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO), ++ CLK_DIVIDER_ONE_BASED), + LPC32XX_DEFINE_GATE(PWM1_GATE, PWMCLK_CTRL, 0, 0), + LPC32XX_DEFINE_COMPOSITE(PWM1, PWM1_MUX, PWM1_DIV, PWM1_GATE), + + LPC32XX_DEFINE_MUX(PWM2_MUX, PWMCLK_CTRL, 3, 0x1, NULL, 0), + LPC32XX_DEFINE_DIV(PWM2_DIV, PWMCLK_CTRL, 8, 4, NULL, +- CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO), ++ CLK_DIVIDER_ONE_BASED), + LPC32XX_DEFINE_GATE(PWM2_GATE, PWMCLK_CTRL, 2, 0), + LPC32XX_DEFINE_COMPOSITE(PWM2, PWM2_MUX, PWM2_DIV, PWM2_GATE), + +@@ -1335,8 +1335,7 @@ static struct clk_hw_proto clk_hw_proto[ + LPC32XX_DEFINE_GATE(USB_DIV_GATE, USB_CTRL, 17, 0), + LPC32XX_DEFINE_COMPOSITE(USB_DIV, _NULL, USB_DIV_DIV, USB_DIV_GATE), + +- LPC32XX_DEFINE_DIV(SD_DIV, MS_CTRL, 0, 4, NULL, +- CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO), ++ LPC32XX_DEFINE_DIV(SD_DIV, MS_CTRL, 0, 4, NULL, CLK_DIVIDER_ONE_BASED), + LPC32XX_DEFINE_CLK(SD_GATE, MS_CTRL, BIT(5) | BIT(9), BIT(5) | BIT(9), + 0x0, BIT(5) | BIT(9), 0x0, 0x0, clk_mask_ops), + LPC32XX_DEFINE_COMPOSITE(SD, _NULL, SD_DIV, SD_GATE), +@@ -1478,6 +1477,20 @@ static struct clk * __init lpc32xx_clk_r + return clk; + } + ++static void __init lpc32xx_clk_div_quirk(u32 reg, u32 div_mask, u32 gate) ++{ ++ u32 val; ++ ++ regmap_read(clk_regmap, reg, &val); ++ ++ if (!(val & div_mask)) { ++ val &= ~gate; ++ val |= BIT(__ffs(div_mask)); ++ } ++ ++ regmap_update_bits(clk_regmap, reg, gate | div_mask, val); ++} ++ + static void __init lpc32xx_clk_init(struct device_node *np) + { + unsigned int i; +@@ -1517,6 +1530,17 @@ static void __init lpc32xx_clk_init(stru + return; + } + ++ /* ++ * Divider part of PWM and MS clocks requires a quirk to avoid ++ * a misinterpretation of formally valid zero value in register ++ * bitfield, which indicates another clock gate. Instead of ++ * adding complexity to a gate clock ensure that zero value in ++ * divider clock is never met in runtime. ++ */ ++ lpc32xx_clk_div_quirk(LPC32XX_CLKPWR_PWMCLK_CTRL, 0xf0, BIT(0)); ++ lpc32xx_clk_div_quirk(LPC32XX_CLKPWR_PWMCLK_CTRL, 0xf00, BIT(2)); ++ lpc32xx_clk_div_quirk(LPC32XX_CLKPWR_MS_CTRL, 0xf, BIT(5) | BIT(9)); ++ + for (i = 1; i < LPC32XX_CLK_MAX; i++) { + clk[i] = lpc32xx_clk_register(i); + if (IS_ERR(clk[i])) { diff --git a/queue-4.9/drm-sun4i-add-compatible-string-for-a31-a31s-tcon-timing-controller.patch b/queue-4.9/drm-sun4i-add-compatible-string-for-a31-a31s-tcon-timing-controller.patch new file mode 100644 index 00000000000..95dd170c314 --- /dev/null +++ b/queue-4.9/drm-sun4i-add-compatible-string-for-a31-a31s-tcon-timing-controller.patch @@ -0,0 +1,84 @@ +From 93a5ec14da24a8abbac5bcb953b45cc7a5d0198a Mon Sep 17 00:00:00 2001 +From: Chen-Yu Tsai +Date: Thu, 20 Oct 2016 11:43:40 +0800 +Subject: drm/sun4i: Add compatible string for A31/A31s TCON (timing controller) + +From: Chen-Yu Tsai + +commit 93a5ec14da24a8abbac5bcb953b45cc7a5d0198a upstream. + +The A31 TCON has mux controls for how TCON outputs are routed to the +HDMI and MIPI DSI blocks. + +Since the A31s does not have MIPI DSI, it only has a mux for the HDMI +controller input. + +This patch only adds support for the compatible strings. Actual support +for the mux controls should be added with HDMI and MIPI DSI support. + +Signed-off-by: Chen-Yu Tsai +Signed-off-by: Maxime Ripard +Signed-off-by: Greg Kroah-Hartman + +--- + Documentation/devicetree/bindings/display/sunxi/sun4i-drm.txt | 4 +++- + drivers/gpu/drm/sun4i/sun4i_drv.c | 2 ++ + drivers/gpu/drm/sun4i/sun4i_tcon.c | 10 ++++++++++ + 3 files changed, 15 insertions(+), 1 deletion(-) + +--- a/Documentation/devicetree/bindings/display/sunxi/sun4i-drm.txt ++++ b/Documentation/devicetree/bindings/display/sunxi/sun4i-drm.txt +@@ -28,6 +28,8 @@ The TCON acts as a timing controller for + Required properties: + - compatible: value must be either: + * allwinner,sun5i-a13-tcon ++ * allwinner,sun6i-a31-tcon ++ * allwinner,sun6i-a31s-tcon + * allwinner,sun8i-a33-tcon + - reg: base address and size of memory-mapped region + - interrupts: interrupt associated to this IP +@@ -50,7 +52,7 @@ Required properties: + second the block connected to the TCON channel 1 (usually the TV + encoder) + +-On the A13, there is one more clock required: ++On SoCs other than the A33, there is one more clock required: + - 'tcon-ch1': The clock driving the TCON channel 1 + + DRC +--- a/drivers/gpu/drm/sun4i/sun4i_drv.c ++++ b/drivers/gpu/drm/sun4i/sun4i_drv.c +@@ -208,6 +208,8 @@ static bool sun4i_drv_node_is_frontend(s + static bool sun4i_drv_node_is_tcon(struct device_node *node) + { + return of_device_is_compatible(node, "allwinner,sun5i-a13-tcon") || ++ of_device_is_compatible(node, "allwinner,sun6i-a31-tcon") || ++ of_device_is_compatible(node, "allwinner,sun6i-a31s-tcon") || + of_device_is_compatible(node, "allwinner,sun8i-a33-tcon"); + } + +--- a/drivers/gpu/drm/sun4i/sun4i_tcon.c ++++ b/drivers/gpu/drm/sun4i/sun4i_tcon.c +@@ -587,12 +587,22 @@ static const struct sun4i_tcon_quirks su + .has_channel_1 = true, + }; + ++static const struct sun4i_tcon_quirks sun6i_a31_quirks = { ++ .has_channel_1 = true, ++}; ++ ++static const struct sun4i_tcon_quirks sun6i_a31s_quirks = { ++ .has_channel_1 = true, ++}; ++ + static const struct sun4i_tcon_quirks sun8i_a33_quirks = { + /* nothing is supported */ + }; + + static const struct of_device_id sun4i_tcon_of_table[] = { + { .compatible = "allwinner,sun5i-a13-tcon", .data = &sun5i_a13_quirks }, ++ { .compatible = "allwinner,sun6i-a31-tcon", .data = &sun6i_a31_quirks }, ++ { .compatible = "allwinner,sun6i-a31s-tcon", .data = &sun6i_a31s_quirks }, + { .compatible = "allwinner,sun8i-a33-tcon", .data = &sun8i_a33_quirks }, + { } + }; diff --git a/queue-4.9/drm-sun4i-add-compatible-strings-for-a31-a31s-display-pipelines.patch b/queue-4.9/drm-sun4i-add-compatible-strings-for-a31-a31s-display-pipelines.patch new file mode 100644 index 00000000000..8732c0be0e4 --- /dev/null +++ b/queue-4.9/drm-sun4i-add-compatible-strings-for-a31-a31s-display-pipelines.patch @@ -0,0 +1,87 @@ +From 49c440e87cd6f547f93d0dc53571ae0e11d9ec8f Mon Sep 17 00:00:00 2001 +From: Chen-Yu Tsai +Date: Thu, 20 Oct 2016 11:43:41 +0800 +Subject: drm/sun4i: Add compatible strings for A31/A31s display pipelines + +From: Chen-Yu Tsai + +commit 49c440e87cd6f547f93d0dc53571ae0e11d9ec8f upstream. + +The A31's display pipeline has 2 frontends, 2 backends, and 2 TCONs. It +also has new display enhancement blocks, such as the DRC (Dynamic Range +Controller), the DEU (Display Enhancement Unit), and the CMU (Color +Management Unit). It supports HDMI, MIPI DSI, and 2 LCD/LVDS channels. + +The A31s display pipeline is almost the same, just without MIPI DSI. +Only the TCON seems to be different, due to the missing mux for MIPI +DSI. + +Add compatible strings for both of them. + +Signed-off-by: Chen-Yu Tsai +Acked-by: Rob Herring +Signed-off-by: Maxime Ripard +Signed-off-by: Greg Kroah-Hartman + +--- + Documentation/devicetree/bindings/display/sunxi/sun4i-drm.txt | 4 ++++ + drivers/gpu/drm/sun4i/sun4i_backend.c | 1 + + drivers/gpu/drm/sun4i/sun4i_drv.c | 3 +++ + 3 files changed, 8 insertions(+) + +--- a/Documentation/devicetree/bindings/display/sunxi/sun4i-drm.txt ++++ b/Documentation/devicetree/bindings/display/sunxi/sun4i-drm.txt +@@ -87,6 +87,7 @@ system. + Required properties: + - compatible: value must be one of: + * allwinner,sun5i-a13-display-backend ++ * allwinner,sun6i-a31-display-backend + * allwinner,sun8i-a33-display-backend + - reg: base address and size of the memory-mapped region. + - clocks: phandles to the clocks feeding the frontend and backend +@@ -117,6 +118,7 @@ deinterlacing and color space conversion + Required properties: + - compatible: value must be one of: + * allwinner,sun5i-a13-display-frontend ++ * allwinner,sun6i-a31-display-frontend + * allwinner,sun8i-a33-display-frontend + - reg: base address and size of the memory-mapped region. + - interrupts: interrupt associated to this IP +@@ -142,6 +144,8 @@ extra node. + Required properties: + - compatible: value must be one of: + * allwinner,sun5i-a13-display-engine ++ * allwinner,sun6i-a31-display-engine ++ * allwinner,sun6i-a31s-display-engine + * allwinner,sun8i-a33-display-engine + + - allwinner,pipelines: list of phandle to the display engine +--- a/drivers/gpu/drm/sun4i/sun4i_backend.c ++++ b/drivers/gpu/drm/sun4i/sun4i_backend.c +@@ -408,6 +408,7 @@ static int sun4i_backend_remove(struct p + + static const struct of_device_id sun4i_backend_of_table[] = { + { .compatible = "allwinner,sun5i-a13-display-backend" }, ++ { .compatible = "allwinner,sun6i-a31-display-backend" }, + { .compatible = "allwinner,sun8i-a33-display-backend" }, + { } + }; +--- a/drivers/gpu/drm/sun4i/sun4i_drv.c ++++ b/drivers/gpu/drm/sun4i/sun4i_drv.c +@@ -201,6 +201,7 @@ static const struct component_master_ops + static bool sun4i_drv_node_is_frontend(struct device_node *node) + { + return of_device_is_compatible(node, "allwinner,sun5i-a13-display-frontend") || ++ of_device_is_compatible(node, "allwinner,sun6i-a31-display-frontend") || + of_device_is_compatible(node, "allwinner,sun8i-a33-display-frontend"); + } + +@@ -322,6 +323,8 @@ static int sun4i_drv_remove(struct platf + + static const struct of_device_id sun4i_drv_of_table[] = { + { .compatible = "allwinner,sun5i-a13-display-engine" }, ++ { .compatible = "allwinner,sun6i-a31-display-engine" }, ++ { .compatible = "allwinner,sun6i-a31s-display-engine" }, + { .compatible = "allwinner,sun8i-a33-display-engine" }, + { } + }; diff --git a/queue-4.9/drm-sun4i-tcon-move-soc-specific-quirks-to-a-dt-matched-data-structure.patch b/queue-4.9/drm-sun4i-tcon-move-soc-specific-quirks-to-a-dt-matched-data-structure.patch new file mode 100644 index 00000000000..2cbe4fc3caa --- /dev/null +++ b/queue-4.9/drm-sun4i-tcon-move-soc-specific-quirks-to-a-dt-matched-data-structure.patch @@ -0,0 +1,145 @@ +From 91ea2f29cba6a7fe035ea232e4f981211a9fce5d Mon Sep 17 00:00:00 2001 +From: Chen-Yu Tsai +Date: Thu, 20 Oct 2016 11:43:39 +0800 +Subject: drm/sun4i: tcon: Move SoC specific quirks to a DT matched data structure + +From: Chen-Yu Tsai + +commit 91ea2f29cba6a7fe035ea232e4f981211a9fce5d upstream. + +We already have some differences between the 2 supported SoCs. +More will be added as we support other SoCs. To avoid bloating +the probe function with even more conditionals, move the quirks +to a separate data structure that's tied to the compatible string. + +Signed-off-by: Chen-Yu Tsai +Signed-off-by: Maxime Ripard +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/gpu/drm/sun4i/sun4i_tcon.c | 33 ++++++++++++++++++--------------- + drivers/gpu/drm/sun4i/sun4i_tcon.h | 11 +++++++---- + 2 files changed, 25 insertions(+), 19 deletions(-) + +--- a/drivers/gpu/drm/sun4i/sun4i_tcon.c ++++ b/drivers/gpu/drm/sun4i/sun4i_tcon.c +@@ -20,6 +20,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -62,7 +63,7 @@ void sun4i_tcon_channel_disable(struct s + return; + } + +- WARN_ON(!tcon->has_channel_1); ++ WARN_ON(!tcon->quirks->has_channel_1); + regmap_update_bits(tcon->regs, SUN4I_TCON1_CTL_REG, + SUN4I_TCON1_CTL_TCON_ENABLE, 0); + clk_disable_unprepare(tcon->sclk1); +@@ -80,7 +81,7 @@ void sun4i_tcon_channel_enable(struct su + return; + } + +- WARN_ON(!tcon->has_channel_1); ++ WARN_ON(!tcon->quirks->has_channel_1); + regmap_update_bits(tcon->regs, SUN4I_TCON1_CTL_REG, + SUN4I_TCON1_CTL_TCON_ENABLE, + SUN4I_TCON1_CTL_TCON_ENABLE); +@@ -202,7 +203,7 @@ void sun4i_tcon1_mode_set(struct sun4i_t + u8 clk_delay; + u32 val; + +- WARN_ON(!tcon->has_channel_1); ++ WARN_ON(!tcon->quirks->has_channel_1); + + /* Adjust clock delay */ + clk_delay = sun4i_tcon_get_clk_delay(mode, 1); +@@ -266,7 +267,7 @@ void sun4i_tcon1_mode_set(struct sun4i_t + /* + * FIXME: Undocumented bits + */ +- if (tcon->has_mux) ++ if (tcon->quirks->has_unknown_mux) + regmap_write(tcon->regs, SUN4I_TCON_MUX_CTRL_REG, 1); + } + EXPORT_SYMBOL(sun4i_tcon1_mode_set); +@@ -327,7 +328,7 @@ static int sun4i_tcon_init_clocks(struct + return PTR_ERR(tcon->sclk0); + } + +- if (tcon->has_channel_1) { ++ if (tcon->quirks->has_channel_1) { + tcon->sclk1 = devm_clk_get(dev, "tcon-ch1"); + if (IS_ERR(tcon->sclk1)) { + dev_err(dev, "Couldn't get the TCON channel 1 clock\n"); +@@ -487,14 +488,7 @@ static int sun4i_tcon_bind(struct device + drv->tcon = tcon; + tcon->drm = drm; + tcon->dev = dev; +- +- if (of_device_is_compatible(dev->of_node, "allwinner,sun5i-a13-tcon")) { +- tcon->has_mux = true; +- tcon->has_channel_1 = true; +- } else { +- tcon->has_mux = false; +- tcon->has_channel_1 = false; +- } ++ tcon->quirks = of_device_get_match_data(dev); + + tcon->lcd_rst = devm_reset_control_get(dev, "lcd"); + if (IS_ERR(tcon->lcd_rst)) { +@@ -588,9 +582,18 @@ static int sun4i_tcon_remove(struct plat + return 0; + } + ++static const struct sun4i_tcon_quirks sun5i_a13_quirks = { ++ .has_unknown_mux = true, ++ .has_channel_1 = true, ++}; ++ ++static const struct sun4i_tcon_quirks sun8i_a33_quirks = { ++ /* nothing is supported */ ++}; ++ + static const struct of_device_id sun4i_tcon_of_table[] = { +- { .compatible = "allwinner,sun5i-a13-tcon" }, +- { .compatible = "allwinner,sun8i-a33-tcon" }, ++ { .compatible = "allwinner,sun5i-a13-tcon", .data = &sun5i_a13_quirks }, ++ { .compatible = "allwinner,sun8i-a33-tcon", .data = &sun8i_a33_quirks }, + { } + }; + MODULE_DEVICE_TABLE(of, sun4i_tcon_of_table); +--- a/drivers/gpu/drm/sun4i/sun4i_tcon.h ++++ b/drivers/gpu/drm/sun4i/sun4i_tcon.h +@@ -142,6 +142,11 @@ + + #define SUN4I_TCON_MAX_CHANNELS 2 + ++struct sun4i_tcon_quirks { ++ bool has_unknown_mux; /* sun5i has undocumented mux */ ++ bool has_channel_1; /* a33 does not have channel 1 */ ++}; ++ + struct sun4i_tcon { + struct device *dev; + struct drm_device *drm; +@@ -160,12 +165,10 @@ struct sun4i_tcon { + /* Reset control */ + struct reset_control *lcd_rst; + +- /* Platform adjustments */ +- bool has_mux; +- + struct drm_panel *panel; + +- bool has_channel_1; ++ /* Platform adjustments */ ++ const struct sun4i_tcon_quirks *quirks; + }; + + struct drm_bridge *sun4i_tcon_find_bridge(struct device_node *node); diff --git a/queue-4.9/hid-i2c-hid-add-a-simple-quirk-to-fix-device-defects.patch b/queue-4.9/hid-i2c-hid-add-a-simple-quirk-to-fix-device-defects.patch new file mode 100644 index 00000000000..a06bca031ad --- /dev/null +++ b/queue-4.9/hid-i2c-hid-add-a-simple-quirk-to-fix-device-defects.patch @@ -0,0 +1,141 @@ +From foo@baz Mon Apr 10 17:14:09 CEST 2017 +From: alexander.levin@verizon.com +Date: Tue, 4 Apr 2017 19:32:03 +0000 +Subject: HID: i2c-hid: add a simple quirk to fix device defects +To: "gregkh@linuxfoundation.org" +Cc: "stable@vger.kernel.org" +Message-ID: <20170404193158.19041-5-alexander.levin@verizon.com> + +From: HungNien Chen + +[ Upstream commit 71af01a8c85ad89449209594133bdfdfaa9f1e2a ] + +Certain devices produced by Weida Tech need to have a wakeup command sent to +them before powering on. The call itself will come back with error, but the +device can be powered on afterwards. + +[jkosina@suse.cz: rewrite changelog] +[jkosina@suse.cz: remove unused device ID addition] +Signed-off-by: HungNien Chen +Reviewed-by: Benjamin Tissoires +Signed-off-by: Jiri Kosina + +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + drivers/hid/hid-ids.h | 4 ++ + drivers/hid/i2c-hid/i2c-hid.c | 57 ++++++++++++++++++++++++++++++++++++++++++ + 2 files changed, 61 insertions(+) + +--- a/drivers/hid/hid-ids.h ++++ b/drivers/hid/hid-ids.h +@@ -1039,6 +1039,10 @@ + #define USB_DEVICE_ID_WALTOP_MEDIA_TABLET_14_1_INCH 0x0500 + #define USB_DEVICE_ID_WALTOP_SIRIUS_BATTERY_FREE_TABLET 0x0502 + ++#define USB_VENDOR_ID_WEIDA 0x2575 ++#define USB_DEVICE_ID_WEIDA_8752 0xC300 ++#define USB_DEVICE_ID_WEIDA_8755 0xC301 ++ + #define USB_VENDOR_ID_WISEGROUP 0x0925 + #define USB_DEVICE_ID_SMARTJOY_PLUS 0x0005 + #define USB_DEVICE_ID_SUPER_JOY_BOX_3 0x8888 +--- a/drivers/hid/i2c-hid/i2c-hid.c ++++ b/drivers/hid/i2c-hid/i2c-hid.c +@@ -41,6 +41,11 @@ + + #include + ++#include "../hid-ids.h" ++ ++/* quirks to control the device */ ++#define I2C_HID_QUIRK_SET_PWR_WAKEUP_DEV BIT(0) ++ + /* flags */ + #define I2C_HID_STARTED 0 + #define I2C_HID_RESET_PENDING 1 +@@ -143,6 +148,7 @@ struct i2c_hid { + char *argsbuf; /* Command arguments buffer */ + + unsigned long flags; /* device flags */ ++ unsigned long quirks; /* Various quirks */ + + wait_queue_head_t wait; /* For waiting the interrupt */ + struct gpio_desc *desc; +@@ -154,6 +160,39 @@ struct i2c_hid { + struct mutex reset_lock; + }; + ++static const struct i2c_hid_quirks { ++ __u16 idVendor; ++ __u16 idProduct; ++ __u32 quirks; ++} i2c_hid_quirks[] = { ++ { USB_VENDOR_ID_WEIDA, USB_DEVICE_ID_WEIDA_8752, ++ I2C_HID_QUIRK_SET_PWR_WAKEUP_DEV }, ++ { USB_VENDOR_ID_WEIDA, USB_DEVICE_ID_WEIDA_8755, ++ I2C_HID_QUIRK_SET_PWR_WAKEUP_DEV }, ++ { 0, 0 } ++}; ++ ++/* ++ * i2c_hid_lookup_quirk: return any quirks associated with a I2C HID device ++ * @idVendor: the 16-bit vendor ID ++ * @idProduct: the 16-bit product ID ++ * ++ * Returns: a u32 quirks value. ++ */ ++static u32 i2c_hid_lookup_quirk(const u16 idVendor, const u16 idProduct) ++{ ++ u32 quirks = 0; ++ int n; ++ ++ for (n = 0; i2c_hid_quirks[n].idVendor; n++) ++ if (i2c_hid_quirks[n].idVendor == idVendor && ++ (i2c_hid_quirks[n].idProduct == (__u16)HID_ANY_ID || ++ i2c_hid_quirks[n].idProduct == idProduct)) ++ quirks = i2c_hid_quirks[n].quirks; ++ ++ return quirks; ++} ++ + static int __i2c_hid_command(struct i2c_client *client, + const struct i2c_hid_cmd *command, u8 reportID, + u8 reportType, u8 *args, int args_len, +@@ -346,11 +385,27 @@ static int i2c_hid_set_power(struct i2c_ + + i2c_hid_dbg(ihid, "%s\n", __func__); + ++ /* ++ * Some devices require to send a command to wakeup before power on. ++ * The call will get a return value (EREMOTEIO) but device will be ++ * triggered and activated. After that, it goes like a normal device. ++ */ ++ if (power_state == I2C_HID_PWR_ON && ++ ihid->quirks & I2C_HID_QUIRK_SET_PWR_WAKEUP_DEV) { ++ ret = i2c_hid_command(client, &hid_set_power_cmd, NULL, 0); ++ ++ /* Device was already activated */ ++ if (!ret) ++ goto set_pwr_exit; ++ } ++ + ret = __i2c_hid_command(client, &hid_set_power_cmd, power_state, + 0, NULL, 0, NULL, 0); ++ + if (ret) + dev_err(&client->dev, "failed to change power setting.\n"); + ++set_pwr_exit: + return ret; + } + +@@ -1050,6 +1105,8 @@ static int i2c_hid_probe(struct i2c_clie + client->name, hid->vendor, hid->product); + strlcpy(hid->phys, dev_name(&client->dev), sizeof(hid->phys)); + ++ ihid->quirks = i2c_hid_lookup_quirk(hid->vendor, hid->product); ++ + ret = hid_add_device(hid); + if (ret) { + if (ret != -ENODEV) diff --git a/queue-4.9/hid-usbhid-add-quirks-for-mayflash-dragonrise-gamecube-and-ps3-adapters.patch b/queue-4.9/hid-usbhid-add-quirks-for-mayflash-dragonrise-gamecube-and-ps3-adapters.patch new file mode 100644 index 00000000000..696e713acdd --- /dev/null +++ b/queue-4.9/hid-usbhid-add-quirks-for-mayflash-dragonrise-gamecube-and-ps3-adapters.patch @@ -0,0 +1,53 @@ +From foo@baz Mon Apr 10 17:14:09 CEST 2017 +From: alexander.levin@verizon.com +Date: Tue, 4 Apr 2017 19:32:03 +0000 +Subject: HID: usbhid: Add quirks for Mayflash/Dragonrise GameCube and PS3 adapters +To: "gregkh@linuxfoundation.org" +Cc: "stable@vger.kernel.org" +Message-ID: <20170404193158.19041-4-alexander.levin@verizon.com> + +From: Marcel Hasler + +[ Upstream commit b2554000f5b5d2a3a368d09c6debf7da64901fcf ] + +All known gamepad adapters by Mayflash (identified as Dragonrise) need +HID_QUIRK_MULTI_INPUT to split them up into four input devices. Without this +quirk those adapters are falsely recognized as tablets. Fixes bug 115841 +(https://bugzilla.kernel.org/show_bug.cgi?id=115841). + +Signed-off-by: Marcel Hasler +Reviewed-by: Benjamin Tissoires +Signed-off-by: Jiri Kosina +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + drivers/hid/hid-ids.h | 6 ++++-- + drivers/hid/usbhid/hid-quirks.c | 2 ++ + 2 files changed, 6 insertions(+), 2 deletions(-) + +--- a/drivers/hid/hid-ids.h ++++ b/drivers/hid/hid-ids.h +@@ -318,8 +318,10 @@ + #define USB_VENDOR_ID_DMI 0x0c0b + #define USB_DEVICE_ID_DMI_ENC 0x5fab + +-#define USB_VENDOR_ID_DRAGONRISE 0x0079 +-#define USB_DEVICE_ID_DRAGONRISE_WIIU 0x1800 ++#define USB_VENDOR_ID_DRAGONRISE 0x0079 ++#define USB_DEVICE_ID_DRAGONRISE_WIIU 0x1800 ++#define USB_DEVICE_ID_DRAGONRISE_PS3 0x1801 ++#define USB_DEVICE_ID_DRAGONRISE_GAMECUBE 0x1843 + + #define USB_VENDOR_ID_DWAV 0x0eef + #define USB_DEVICE_ID_EGALAX_TOUCHCONTROLLER 0x0001 +--- a/drivers/hid/usbhid/hid-quirks.c ++++ b/drivers/hid/usbhid/hid-quirks.c +@@ -83,6 +83,8 @@ static const struct hid_blacklist { + { USB_VENDOR_ID_CREATIVELABS, USB_DEVICE_ID_CREATIVE_SB_OMNI_SURROUND_51, HID_QUIRK_NOGET }, + { USB_VENDOR_ID_DMI, USB_DEVICE_ID_DMI_ENC, HID_QUIRK_NOGET }, + { USB_VENDOR_ID_DRAGONRISE, USB_DEVICE_ID_DRAGONRISE_WIIU, HID_QUIRK_MULTI_INPUT }, ++ { USB_VENDOR_ID_DRAGONRISE, USB_DEVICE_ID_DRAGONRISE_PS3, HID_QUIRK_MULTI_INPUT }, ++ { USB_VENDOR_ID_DRAGONRISE, USB_DEVICE_ID_DRAGONRISE_GAMECUBE, HID_QUIRK_MULTI_INPUT }, + { USB_VENDOR_ID_ELAN, HID_ANY_ID, HID_QUIRK_ALWAYS_POLL }, + { USB_VENDOR_ID_ELO, USB_DEVICE_ID_ELO_TS2700, HID_QUIRK_NOGET }, + { USB_VENDOR_ID_FORMOSA, USB_DEVICE_ID_FORMOSA_IR_RECEIVER, HID_QUIRK_NO_INIT_REPORTS }, diff --git a/queue-4.9/series b/queue-4.9/series index 89fa02bd244..85eaa4d3c89 100644 --- a/queue-4.9/series +++ b/queue-4.9/series @@ -54,3 +54,9 @@ mips-c-r4k-fix-loongson-3-s-vcache-scache-waysize-calculation.patch documentation-stable-kernel-rules-fix-stable-tag-format.patch mm-mempolicy.c-fix-error-handling-in-set_mempolicy-and-mbind.patch random-use-chacha20-for-get_random_int-long.patch +drm-sun4i-tcon-move-soc-specific-quirks-to-a-dt-matched-data-structure.patch +drm-sun4i-add-compatible-strings-for-a31-a31s-display-pipelines.patch +drm-sun4i-add-compatible-string-for-a31-a31s-tcon-timing-controller.patch +clk-lpc32xx-add-a-quirk-for-pwm-and-ms-clock-dividers.patch +hid-usbhid-add-quirks-for-mayflash-dragonrise-gamecube-and-ps3-adapters.patch +hid-i2c-hid-add-a-simple-quirk-to-fix-device-defects.patch