Linux Input/HID development
 help / color / mirror / Atom feed
* Re: [PATCH] hid: intel-ish-hid: use put_device() instead of kfree()
From: Jiri Kosina @ 2018-04-26 12:37 UTC (permalink / raw)
  To: Arvind Yadav
  Cc: srinivas.pandruvada, benjamin.tissoires, linux-kernel,
	linux-input
In-Reply-To: <66bd5f1ab1322081927f657090a04b44da326140.1522408033.git.arvind.yadav.cs@gmail.com>

On Fri, 30 Mar 2018, Arvind Yadav wrote:

> Never directly free @dev after calling device_register(), even
> if it returned an error. Always use put_device() to give up the
> reference initialized.
> 
> Signed-off-by: Arvind Yadav <arvind.yadav.cs@gmail.com>

Applied, thank you.

-- 
Jiri Kosina
SUSE Labs

^ permalink raw reply

* Re: [PATCH 0/4] HID: alps: Fix some bugs and improve code around 't4_read_write_register()'
From: Jiri Kosina @ 2018-04-26 12:34 UTC (permalink / raw)
  To: Christophe JAILLET
  Cc: masaki.ota, benjamin.tissoires, linux-input, linux-kernel,
	kernel-janitors
In-Reply-To: <cover.1521492069.git.christophe.jaillet@wanadoo.fr>

On Mon, 19 Mar 2018, Christophe JAILLET wrote:

> All is said in the subject and below.
> 
> These patches are untested. Especially, patch 1 slightly changes the behavior
> of 't4_read_write_register()'.
> This looks logical to me, but please, review it carefully.
> 
> Christophe JAILLET (4):
>   HID: alps: Report an error if we receive invalid data in
>     't4_read_write_register()'
>   HID: alps: Save a memory allocation in 't4_read_write_register()' when
>     writing data
>   HID: alps: Check errors returned by 't4_read_write_register()'
>   HID: alps: Fix some style in 't4_read_write_register()'
> 
>  drivers/hid/hid-alps.c | 27 ++++++++++++++++++++++-----
>  1 file changed, 22 insertions(+), 5 deletions(-)

Queued for 4.18, thanks.

-- 
Jiri Kosina
SUSE Labs

^ permalink raw reply

* Re: [PATCH v2 0/6] HID: input cleanups and mt additions
From: Jiri Kosina @ 2018-04-26 12:21 UTC (permalink / raw)
  To: Benjamin Tissoires
  Cc: Dmitry Torokhov, Peter Hutterer, Mario.Limonciello, linux-input,
	linux-kernel
In-Reply-To: <20180424080437.21367-1-benjamin.tissoires@redhat.com>

On Tue, 24 Apr 2018, Benjamin Tissoires wrote:

> following the thread about the 'not incrementing ABS_MISC', here is the
> actual submission of the series.

Thanks Benjamin, this looks nice. I've queued it for 4.18.

-- 
Jiri Kosina
SUSE Labs

^ permalink raw reply

* [PATCH v3 2/2] input: misc: Add Spreadtrum vibrator driver
From: Baolin Wang @ 2018-04-26  9:12 UTC (permalink / raw)
  To: dmitry.torokhov, robh+dt, mark.rutland, orsonzhai, zhang.lyra
  Cc: linux-input, devicetree, linux-kernel, baolin.wang, xiaotong.lu
In-Reply-To: <e2f85ec0b1fb66baa41dd85bb31e8113e23c704b.1524733425.git.baolin.wang@linaro.org>

From: Xiaotong Lu <xiaotong.lu@spreadtrum.com>

This patch adds the Spreadtrum vibrator driver, which embedded in the
Spreadtrum SC27xx series PMICs.

Signed-off-by: Xiaotong Lu <xiaotong.lu@spreadtrum.com>
Signed-off-by: Baolin Wang <baolin.wang@linaro.org>
---
Changes since v2:
 - Fix the condition when disabling the vibrator.
 - Change of_property_read_u32() to device_property_read_u32().
 - Correct the device parent relationship.
 - Call sc27xx_vibra_hw_init() before calling input_register_device().
 - Remove platform_set_drvdata().

Changes since v1:
 - Remove input_ff_destroy() and input_unregister_device()
---
 drivers/input/misc/Kconfig        |   10 +++
 drivers/input/misc/Makefile       |    1 +
 drivers/input/misc/sc27xx-vibra.c |  154 +++++++++++++++++++++++++++++++++++++
 3 files changed, 165 insertions(+)
 create mode 100644 drivers/input/misc/sc27xx-vibra.c

diff --git a/drivers/input/misc/Kconfig b/drivers/input/misc/Kconfig
index 572b15f..c761c0c 100644
--- a/drivers/input/misc/Kconfig
+++ b/drivers/input/misc/Kconfig
@@ -841,4 +841,14 @@ config INPUT_RAVE_SP_PWRBUTTON
 	  To compile this driver as a module, choose M here: the
 	  module will be called rave-sp-pwrbutton.
 
+config INPUT_SC27XX_VIBRA
+	tristate "Spreadtrum sc27xx vibrator support"
+	depends on MFD_SC27XX_PMIC || COMPILE_TEST
+	select INPUT_FF_MEMLESS
+	help
+	  This option enables support for Spreadtrum sc27xx vibrator driver.
+
+	  To compile this driver as a module, choose M here. The module will
+	  be called sc27xx_vibra.
+
 endif
diff --git a/drivers/input/misc/Makefile b/drivers/input/misc/Makefile
index 72cde28..9d0f9d1 100644
--- a/drivers/input/misc/Makefile
+++ b/drivers/input/misc/Makefile
@@ -66,6 +66,7 @@ obj-$(CONFIG_INPUT_RETU_PWRBUTTON)	+= retu-pwrbutton.o
 obj-$(CONFIG_INPUT_AXP20X_PEK)		+= axp20x-pek.o
 obj-$(CONFIG_INPUT_GPIO_ROTARY_ENCODER)	+= rotary_encoder.o
 obj-$(CONFIG_INPUT_RK805_PWRKEY)	+= rk805-pwrkey.o
+obj-$(CONFIG_INPUT_SC27XX_VIBRA)	+= sc27xx-vibra.o
 obj-$(CONFIG_INPUT_SGI_BTNS)		+= sgi_btns.o
 obj-$(CONFIG_INPUT_SIRFSOC_ONKEY)	+= sirfsoc-onkey.o
 obj-$(CONFIG_INPUT_SOC_BUTTON_ARRAY)	+= soc_button_array.o
diff --git a/drivers/input/misc/sc27xx-vibra.c b/drivers/input/misc/sc27xx-vibra.c
new file mode 100644
index 0000000..1167c48
--- /dev/null
+++ b/drivers/input/misc/sc27xx-vibra.c
@@ -0,0 +1,154 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2018 Spreadtrum Communications Inc.
+ */
+
+#include <linux/module.h>
+#include <linux/of_address.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+#include <linux/input.h>
+#include <linux/workqueue.h>
+
+#define CUR_DRV_CAL_SEL		GENMASK(13, 12)
+#define SLP_LDOVIBR_PD_EN	BIT(9)
+#define LDO_VIBR_PD		BIT(8)
+
+struct vibra_info {
+	struct input_dev	*input_dev;
+	struct work_struct	play_work;
+	struct regmap		*regmap;
+	u32			base;
+	u32			strength;
+	bool			enabled;
+};
+
+static void sc27xx_vibra_set(struct vibra_info *info, bool on)
+{
+	if (on) {
+		regmap_update_bits(info->regmap, info->base, LDO_VIBR_PD, 0);
+		regmap_update_bits(info->regmap, info->base,
+				   SLP_LDOVIBR_PD_EN, 0);
+		info->enabled = true;
+	} else {
+		regmap_update_bits(info->regmap, info->base, LDO_VIBR_PD,
+				   LDO_VIBR_PD);
+		regmap_update_bits(info->regmap, info->base,
+				   SLP_LDOVIBR_PD_EN, SLP_LDOVIBR_PD_EN);
+		info->enabled = false;
+	}
+}
+
+static int sc27xx_vibra_hw_init(struct vibra_info *info)
+{
+	return regmap_update_bits(info->regmap, info->base, CUR_DRV_CAL_SEL, 0);
+}
+
+static void sc27xx_vibra_play_work(struct work_struct *work)
+{
+	struct vibra_info *info = container_of(work, struct vibra_info,
+					       play_work);
+
+	if (info->strength && !info->enabled)
+		sc27xx_vibra_set(info, true);
+	else if (info->strength == 0 && info->enabled)
+		sc27xx_vibra_set(info, false);
+}
+
+static int sc27xx_vibra_play(struct input_dev *input, void *data,
+			     struct ff_effect *effect)
+{
+	struct vibra_info *info = input_get_drvdata(input);
+
+	info->strength = effect->u.rumble.weak_magnitude;
+	schedule_work(&info->play_work);
+
+	return 0;
+}
+
+static void sc27xx_vibra_close(struct input_dev *input)
+{
+	struct vibra_info *info = input_get_drvdata(input);
+
+	cancel_work_sync(&info->play_work);
+	if (info->enabled)
+		sc27xx_vibra_set(info, false);
+}
+
+static int sc27xx_vibra_probe(struct platform_device *pdev)
+{
+	struct vibra_info *info;
+	int error;
+
+	info = devm_kzalloc(&pdev->dev, sizeof(*info), GFP_KERNEL);
+	if (!info)
+		return -ENOMEM;
+
+	info->regmap = dev_get_regmap(pdev->dev.parent, NULL);
+	if (!info->regmap) {
+		dev_err(&pdev->dev, "failed to get vibrator regmap.\n");
+		return -ENODEV;
+	}
+
+	error = device_property_read_u32(&pdev->dev, "reg", &info->base);
+	if (error) {
+		dev_err(&pdev->dev, "failed to get vibrator base address.\n");
+		return error;
+	}
+
+	info->input_dev = devm_input_allocate_device(&pdev->dev);
+	if (!info->input_dev) {
+		dev_err(&pdev->dev, "failed to allocate input device.\n");
+		return -ENOMEM;
+	}
+
+	info->input_dev->name = "sc27xx:vibrator";
+	info->input_dev->id.version = 0;
+	info->input_dev->close = sc27xx_vibra_close;
+
+	input_set_drvdata(info->input_dev, info);
+	input_set_capability(info->input_dev, EV_FF, FF_RUMBLE);
+	INIT_WORK(&info->play_work, sc27xx_vibra_play_work);
+	info->enabled = false;
+
+	error = sc27xx_vibra_hw_init(info);
+	if (error) {
+		dev_err(&pdev->dev, "failed to initialize the vibrator.\n");
+		return error;
+	}
+
+	error = input_ff_create_memless(info->input_dev, NULL,
+					sc27xx_vibra_play);
+	if (error) {
+		dev_err(&pdev->dev, "failed to register vibrator to FF.\n");
+		return error;
+	}
+
+	error = input_register_device(info->input_dev);
+	if (error) {
+		dev_err(&pdev->dev, "failed to register input device.\n");
+		return error;
+	}
+
+	return 0;
+}
+
+static const struct of_device_id sc27xx_vibra_of_match[] = {
+	{ .compatible = "sprd,sc27xx-vibrator", },
+	{}
+};
+MODULE_DEVICE_TABLE(of, sc27xx_vibra_of_match);
+
+static struct platform_driver sc27xx_vibra_driver = {
+	.driver = {
+		.name = "sc27xx-vibrator",
+		.of_match_table = sc27xx_vibra_of_match,
+	},
+	.probe = sc27xx_vibra_probe,
+};
+
+module_platform_driver(sc27xx_vibra_driver);
+
+MODULE_DESCRIPTION("Spreadtrum SC27xx Vibrator Driver");
+MODULE_LICENSE("GPL v2");
+MODULE_AUTHOR("Xiaotong Lu <xiaotong.lu@spreadtrum.com>");
-- 
1.7.9.5

^ permalink raw reply related

* [PATCH v3 1/2] dt-bindings: input: Add Add Spreadtrum SC27xx vibrator documentation
From: Baolin Wang @ 2018-04-26  9:12 UTC (permalink / raw)
  To: dmitry.torokhov, robh+dt, mark.rutland, orsonzhai, zhang.lyra
  Cc: linux-input, devicetree, linux-kernel, baolin.wang, xiaotong.lu

From: Xiaotong Lu <xiaotong.lu@spreadtrum.com>

This patch adds the binding documentation for Spreadtrum SC27xx series
vibrator device.

Signed-off-by: Xiaotong Lu <xiaotong.lu@spreadtrum.com>
Signed-off-by: Baolin Wang <baolin.wang@linaro.org>
---
Changes since v2:
 - No updates.

Changes since v1:
 - No updates.
---
 .../bindings/input/sprd,sc27xx-vibra.txt           |   12 ++++++++++++
 1 file changed, 12 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/input/sprd,sc27xx-vibra.txt

diff --git a/Documentation/devicetree/bindings/input/sprd,sc27xx-vibra.txt b/Documentation/devicetree/bindings/input/sprd,sc27xx-vibra.txt
new file mode 100644
index 0000000..92ead29
--- /dev/null
+++ b/Documentation/devicetree/bindings/input/sprd,sc27xx-vibra.txt
@@ -0,0 +1,12 @@
+Spreadtrum SC27xx PMIC Vibrator
+
+Required properties:
+- compatible: should be "sprd,sc27xx-vibrator".
+- reg: address of vibrator control register.
+
+Example :
+
+vibrator@eb4 {
+	compatible = "sprd,sc27xx-vibrator";
+	reg = <0xeb4>;
+};
-- 
1.7.9.5

^ permalink raw reply related

* Re: [GIT PULL] Immutable branch between MFD, Input and RTC due for the v4.18 merge window
From: Chen Zhong @ 2018-04-26  6:53 UTC (permalink / raw)
  To: Lee Jones
  Cc: Dmitry Torokhov, Rob Herring, Alexandre Belloni, Mark Rutland,
	Matthias Brugger, Eddie Huang, Alessandro Zummo, Linus Walleij,
	Beomho Seo, Javier Martinez Canillas, Jaechul Lee,
	Krzysztof Kozlowski, linux-input, devicetree, linux-kernel,
	linux-arm-kernel, linux-mediatek, linux-rtc
In-Reply-To: <20180416141809.34l2ofmeljqvyicm@dell>

On Mon, 2018-04-16 at 15:18 +0100, Lee Jones wrote:
> Enjoy!
> 
> The following changes since commit 60cc43fc888428bb2f18f08997432d426a243338:
> 
>   Linux 4.17-rc1 (2018-04-15 18:24:20 -0700)
> 
> are available in the git repository at:
> 
>   git://git.kernel.org/pub/scm/linux/kernel/git/lee/mfd.git ib-mfd-input-rtc-v4.18
> 
> for you to fetch changes up to 55d1d1547ab5e52269988af5e7c553796ff68e97:
> 
>   mfd: mt6397: Add PMIC keys support to MT6397 driver (2018-04-16 15:16:11 +0100)
> 
> ----------------------------------------------------------------
> Immutable branch between MFD, Input and RTC due for the v4.18 merge window
> 
> ----------------------------------------------------------------
> Chen Zhong (5):
>       mfd: mt6397: Create irq mappings in mfd core driver
>       dt-bindings: input: Add document bindings for mtk-pmic-keys
>       dt-bindings: mfd: Add bindings for the keys as subnode of PMIC
>       input: Add MediaTek PMIC keys support
>       mfd: mt6397: Add PMIC keys support to MT6397 driver
> 
>  .../devicetree/bindings/input/mtk-pmic-keys.txt    |  43 +++
>  Documentation/devicetree/bindings/mfd/mt6397.txt   |   6 +
>  drivers/input/keyboard/Kconfig                     |   9 +
>  drivers/input/keyboard/Makefile                    |   1 +
>  drivers/input/keyboard/mtk-pmic-keys.c             | 339 +++++++++++++++++++++
>  drivers/mfd/mt6397-core.c                          |  26 +-
>  drivers/rtc/rtc-mt6397.c                           |   7 +-
>  7 files changed, 424 insertions(+), 7 deletions(-)
>  create mode 100644 Documentation/devicetree/bindings/input/mtk-pmic-keys.txt
>  create mode 100644 drivers/input/keyboard/mtk-pmic-keys.c
> 

Hi Lee,

I’m sorry that I found this patch
https://patchwork.kernel.org/patch/10026705/

is missing in the git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/lee/mfd.git
ib-mfd-input-rtc-v4.18

Could you please take this patch up?

Thanks.

Best regards,
Chen Zhong

^ permalink raw reply

* AW: [PATCH v2] Input: add bu21029 touch driver
From: Jonas Mark (BT-FIR/ENG1) @ 2018-04-26  6:40 UTC (permalink / raw)
  To: Dmitry Torokhov, Rob Herring, Mark Rutland
  Cc: linux-input@vger.kernel.org, devicetree@vger.kernel.org,
	linux-kernel@vger.kernel.org, hs@denx.de,
	ZHU Yi (BT-FIR/ENG1-Zhu), Jonas Mark (BT-FIR/ENG1)
In-Reply-To: <1523897378-23207-1-git-send-email-mark.jonas@de.bosch.com>

Hello,

> Betreff: [PATCH v2] Input: add bu21029 touch driver
> 
> From: Zhu Yi <yi.zhu5@cn.bosch.com>
> 
> Add Rohm BU21029 resistive touch panel controller support with I2C
> interface.
> 
> Signed-off-by: Zhu Yi <yi.zhu5@cn.bosch.com>
> Signed-off-by: Mark Jonas <mark.jonas@de.bosch.com>
> Reviewed-by: Heiko Schocher <hs@denx.de>
> ---
> Changes in v2:
>  - make ABS_PRESSURE proportionally rising with finger pressure
>  - fix race between interrupt and timer during shutdown
>  - use infrastructure from include/linux/input/touchscreen.h
>  - add SPDX tag for the driver
>  - improve binding documentation
>  - fix multi-line comments

In the mean time I received a Reviewed-by from Rob Herring.

How shall I proceed? I am convinced that we did all the requested
changes and published them 2018-04-16 in the cited patch above. 

Greetings,
Mark Jonas

Building Technologies, Panel Software Fire (BT-FIR/ENG1) 
Bosch Sicherheitssysteme GmbH | Postfach 11 11 | 85626 Grasbrunn | GERMANY | www.boschsecurity.com

Sitz: Stuttgart, Registergericht: Amtsgericht Stuttgart HRB 23118 
Aufsichtsratsvorsitzender: Stefan Hartung; Geschäftsführung: Gert van Iperen, Andreas Bartz, Thomas Quante, Bernhard Schuster

^ permalink raw reply

* Re: [PATCH v2] input/touchscreen: atmel_mxt_ts: Add correct touchpad button mapping for the Caroline Chromebook.
From: Vittorio Gambaletta (VittGam) @ 2018-04-26  5:37 UTC (permalink / raw)
  To: Dmitry Torokhov
  Cc: linux-kernel, linux-input, stable, nick, bleung,
	Salvatore Bellizzi, groeck
In-Reply-To: <20180425225734.GD200812@dtor-ws>

Hello,

On 26/04/2018 00:57:34 CEST, Dmitry Torokhov wrote:
> On Wed, Apr 25, 2018 at 03:26:50PM -0700, Dmitry Torokhov wrote:
>> On Wed, Apr 25, 2018 at 02:32:58PM +0200, Vittorio Gambaletta (VittGam) wrote:
>> > This patch adds the correct platform data information for the Caroline
>> > Chromebook, so that the mouse button does not get stuck in pressed state
>> > after the first click.
>> >
>> > The Samus button keymap and platform data definition are the correct
>> > ones for Caroline, so they have been reused here.
>> >
>> > v2: updated patch offset after 20180409 changes.
>> >
>> > Cc: stable@vger.kernel.org
>> > Signed-off-by: Vittorio Gambaletta <linuxbugs@vittgam.net>
>> > Signed-off-by: Salvatore Bellizzi <lkml@seppia.net>
>> >
>>
>> Applied, thank you.
>>
>> > ---
>> >
>> > --- a/drivers/input/touchscreen/atmel_mxt_ts.c
>> > +++ b/drivers/input/touchscreen/atmel_mxt_ts.c
>> > @@ -3035,6 +3035,15 @@
>> >  		.driver_data = samus_platform_data,
>> >  	},
>> >  	{
>> > +		/* Samsung Chromebook Pro */
>> > +		.ident = "Samsung Chromebook Pro",
>> > +		.matches = {
>> > +			DMI_MATCH(DMI_SYS_VENDOR, "GOOGLE"),
> 
> I've been alerted that shipping BIOS has vendor not capitalized; where
> did you get the firmware that has vendor all capitals?

Upstream coreboot and mrchromebox's coreboot, which do support loading Linux
natively or with UEFI, both use capitalized GOOGLE as DMI System Vendor
as far as I know.

By the way, the shipping BIOS (coreboot customized by Google) does not support
mainline Linux natively (eg. without seabios and nasty tricks), but only
Chromium OS, which for Caroline is an old 3.something fork of Linux, so this
patch does not really apply to Chromium OS or to Linux running on shipping BIOS.

Anyway if I recall correctly, the DMI System Vendor should be GOOGLE in
Google's coreboot for Caroline too, but I'm not 100% sure and cannot check
right now.

By the way please note that this is the DMI System Vendor and not the DMI
BIOS version string, which indeed starts with "Google_" in the shipping BIOS
(but not in coreboot, see f56db262e46d3368ee4e5c9e19797853cab382cd).

> Thanks.

Cheers,
Vittorio G

>> > +			DMI_MATCH(DMI_PRODUCT_NAME, "Caroline"),
>> > +		},
>> > +		.driver_data = samus_platform_data,
>> > +	},
>> > +	{
>> >  		/* Other Google Chromebooks */
>> >  		.ident = "Chromebook",
>> >  		.matches = {
>>
>> --
>> Dmitry

^ permalink raw reply

* Re: [PATCH v3 1/3] resource: Use list_head to link sibling resource
From: kbuild test robot @ 2018-04-26  3:23 UTC (permalink / raw)
  Cc: nicolas.pitre-QSEj5FYQhm4dnm+yROfE0A, Brijesh Singh, Tom Lendacky,
	David Airlie, linux-pci-u79uwXL29TY76Z2rM5mHXA, Wei Yang,
	Keith Busch, Yaowei Bai, Frank Rowand, Thomas Gleixner,
	Lorenzo Pieralisi, Stephen Hemminger, Baoquan He,
	linux-nvdimm-hn68Rpc1hR1g9hUCZPvPmw, Patrik Jakobsson,
	linux-input-u79uwXL29TY76Z2rM5mHXA, Borislav Petkov,
	devicetree-u79uwXL29TY76Z2rM5mHXA, Haiyang Zhang,
	josh-iaAMLnmF4UmaiuxdJuQwMA, Jérôme Glisse,
	robh+dt-DgEjT+Ai2ygdnm+yROfE0A, Bjorn Helgaas, Jonathan Derrick
In-Reply-To: <20180419001848.3041-2-bhe-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>

Hi Baoquan,

I love your patch! Yet something to improve:

[auto build test ERROR on linus/master]
[also build test ERROR on v4.17-rc2 next-20180424]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]

url:    https://github.com/0day-ci/linux/commits/Baoquan-He/resource-Use-list_head-to-link-sibling-resource/20180419-223752
config: xtensa-common_defconfig (attached as .config)
compiler: xtensa-linux-gcc (GCC) 7.2.0
reproduce:
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # save the attached .config to linux build tree
        make.cross ARCH=xtensa 

All errors (new ones prefixed by >>):

   In file included from arch/xtensa/lib/pci-auto.c:22:0:
   arch/xtensa/include/asm/pci-bridge.h: In function 'pcibios_init_resource':
>> arch/xtensa/include/asm/pci-bridge.h:74:15: error: incompatible types when assigning to type 'struct list_head' from type 'void *'
     res->sibling = NULL;
                  ^
   arch/xtensa/include/asm/pci-bridge.h:75:13: error: incompatible types when assigning to type 'struct list_head' from type 'void *'
     res->child = NULL;
                ^

vim +74 arch/xtensa/include/asm/pci-bridge.h

9a8fd558 include/asm-xtensa/pci-bridge.h Chris Zankel 2005-06-23  65  
9a8fd558 include/asm-xtensa/pci-bridge.h Chris Zankel 2005-06-23  66  static inline void pcibios_init_resource(struct resource *res,
9a8fd558 include/asm-xtensa/pci-bridge.h Chris Zankel 2005-06-23  67  		unsigned long start, unsigned long end, int flags, char *name)
9a8fd558 include/asm-xtensa/pci-bridge.h Chris Zankel 2005-06-23  68  {
9a8fd558 include/asm-xtensa/pci-bridge.h Chris Zankel 2005-06-23  69  	res->start = start;
9a8fd558 include/asm-xtensa/pci-bridge.h Chris Zankel 2005-06-23  70  	res->end = end;
9a8fd558 include/asm-xtensa/pci-bridge.h Chris Zankel 2005-06-23  71  	res->flags = flags;
9a8fd558 include/asm-xtensa/pci-bridge.h Chris Zankel 2005-06-23  72  	res->name = name;
9a8fd558 include/asm-xtensa/pci-bridge.h Chris Zankel 2005-06-23  73  	res->parent = NULL;
9a8fd558 include/asm-xtensa/pci-bridge.h Chris Zankel 2005-06-23 @74  	res->sibling = NULL;
9a8fd558 include/asm-xtensa/pci-bridge.h Chris Zankel 2005-06-23  75  	res->child = NULL;
9a8fd558 include/asm-xtensa/pci-bridge.h Chris Zankel 2005-06-23  76  }
9a8fd558 include/asm-xtensa/pci-bridge.h Chris Zankel 2005-06-23  77  

:::::: The code at line 74 was first introduced by commit
:::::: 9a8fd5589902153a134111ed7a40f9cca1f83254 [PATCH] xtensa: Architecture support for Tensilica Xtensa Part 6

:::::: TO: Chris Zankel <czankel-66fqrpuXKgGB+jHODAdFcQ@public.gmane.org>
:::::: CC: Linus Torvalds <torvalds-gWtpgVMusWVb5UGfqNBoRg@public.gmane.org>

---
0-DAY kernel test infrastructure                Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all                   Intel Corporation

^ permalink raw reply

* Re: [PATCH v3 1/3] resource: Use list_head to link sibling resource
From: kbuild test robot @ 2018-04-26  3:01 UTC (permalink / raw)
  Cc: nicolas.pitre-QSEj5FYQhm4dnm+yROfE0A, Brijesh Singh, Tom Lendacky,
	David Airlie, linux-pci-u79uwXL29TY76Z2rM5mHXA, Wei Yang,
	Keith Busch, Yaowei Bai, Frank Rowand, Thomas Gleixner,
	Lorenzo Pieralisi, Stephen Hemminger, Baoquan He,
	linux-nvdimm-hn68Rpc1hR1g9hUCZPvPmw, Patrik Jakobsson,
	linux-input-u79uwXL29TY76Z2rM5mHXA, Borislav Petkov,
	devicetree-u79uwXL29TY76Z2rM5mHXA, Haiyang Zhang,
	josh-iaAMLnmF4UmaiuxdJuQwMA, Jérôme Glisse,
	robh+dt-DgEjT+Ai2ygdnm+yROfE0A, Bjorn Helgaas, Jonathan Derrick
In-Reply-To: <20180419001848.3041-2-bhe-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>

Hi Baoquan,

I love your patch! Yet something to improve:

[auto build test ERROR on linus/master]
[also build test ERROR on v4.17-rc2 next-20180424]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]

url:    https://github.com/0day-ci/linux/commits/Baoquan-He/resource-Use-list_head-to-link-sibling-resource/20180419-223752
config: microblaze-mmu_defconfig (attached as .config)
compiler: microblaze-linux-gcc (GCC) 7.2.0
reproduce:
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # save the attached .config to linux build tree
        make.cross ARCH=microblaze 

All errors (new ones prefixed by >>):

   arch/microblaze/pci/pci-common.c: In function 'pci_process_bridge_OF_ranges':
>> arch/microblaze/pci/pci-common.c:536:44: error: incompatible types when assigning to type 'struct list_head' from type 'void *'
       res->parent = res->child = res->sibling = NULL;
                                               ^
   arch/microblaze/pci/pci-common.c: In function 'reparent_resources':
>> arch/microblaze/pci/pci-common.c:631:10: error: assignment from incompatible pointer type [-Werror=incompatible-pointer-types]
     for (pp = &parent->child; (p = *pp) != NULL; pp = &p->sibling) {
             ^
   arch/microblaze/pci/pci-common.c:631:50: error: assignment from incompatible pointer type [-Werror=incompatible-pointer-types]
     for (pp = &parent->child; (p = *pp) != NULL; pp = &p->sibling) {
                                                     ^
>> arch/microblaze/pci/pci-common.c:644:13: error: incompatible types when assigning to type 'struct list_head' from type 'struct resource *'
     res->child = *firstpp;
                ^
   arch/microblaze/pci/pci-common.c:645:15: error: incompatible types when assigning to type 'struct list_head' from type 'struct resource *'
     res->sibling = *pp;
                  ^
>> arch/microblaze/pci/pci-common.c:648:9: error: incompatible types when assigning to type 'struct resource *' from type 'struct list_head'
     for (p = res->child; p != NULL; p = p->sibling) {
            ^
   arch/microblaze/pci/pci-common.c:648:36: error: incompatible types when assigning to type 'struct resource *' from type 'struct list_head'
     for (p = res->child; p != NULL; p = p->sibling) {
                                       ^
   cc1: some warnings being treated as errors

vim +536 arch/microblaze/pci/pci-common.c

d3afa58c Michal Simek        2010-01-18  387  
d3afa58c Michal Simek        2010-01-18  388  /**
d3afa58c Michal Simek        2010-01-18  389   * pci_process_bridge_OF_ranges - Parse PCI bridge resources from device tree
d3afa58c Michal Simek        2010-01-18  390   * @hose: newly allocated pci_controller to be setup
d3afa58c Michal Simek        2010-01-18  391   * @dev: device node of the host bridge
d3afa58c Michal Simek        2010-01-18  392   * @primary: set if primary bus (32 bits only, soon to be deprecated)
d3afa58c Michal Simek        2010-01-18  393   *
d3afa58c Michal Simek        2010-01-18  394   * This function will parse the "ranges" property of a PCI host bridge device
d3afa58c Michal Simek        2010-01-18  395   * node and setup the resource mapping of a pci controller based on its
d3afa58c Michal Simek        2010-01-18  396   * content.
d3afa58c Michal Simek        2010-01-18  397   *
d3afa58c Michal Simek        2010-01-18  398   * Life would be boring if it wasn't for a few issues that we have to deal
d3afa58c Michal Simek        2010-01-18  399   * with here:
d3afa58c Michal Simek        2010-01-18  400   *
d3afa58c Michal Simek        2010-01-18  401   *   - We can only cope with one IO space range and up to 3 Memory space
d3afa58c Michal Simek        2010-01-18  402   *     ranges. However, some machines (thanks Apple !) tend to split their
d3afa58c Michal Simek        2010-01-18  403   *     space into lots of small contiguous ranges. So we have to coalesce.
d3afa58c Michal Simek        2010-01-18  404   *
d3afa58c Michal Simek        2010-01-18  405   *   - We can only cope with all memory ranges having the same offset
d3afa58c Michal Simek        2010-01-18  406   *     between CPU addresses and PCI addresses. Unfortunately, some bridges
d3afa58c Michal Simek        2010-01-18  407   *     are setup for a large 1:1 mapping along with a small "window" which
d3afa58c Michal Simek        2010-01-18  408   *     maps PCI address 0 to some arbitrary high address of the CPU space in
d3afa58c Michal Simek        2010-01-18  409   *     order to give access to the ISA memory hole.
d3afa58c Michal Simek        2010-01-18  410   *     The way out of here that I've chosen for now is to always set the
d3afa58c Michal Simek        2010-01-18  411   *     offset based on the first resource found, then override it if we
d3afa58c Michal Simek        2010-01-18  412   *     have a different offset and the previous was set by an ISA hole.
d3afa58c Michal Simek        2010-01-18  413   *
d3afa58c Michal Simek        2010-01-18  414   *   - Some busses have IO space not starting at 0, which causes trouble with
d3afa58c Michal Simek        2010-01-18  415   *     the way we do our IO resource renumbering. The code somewhat deals with
d3afa58c Michal Simek        2010-01-18  416   *     it for 64 bits but I would expect problems on 32 bits.
d3afa58c Michal Simek        2010-01-18  417   *
d3afa58c Michal Simek        2010-01-18  418   *   - Some 32 bits platforms such as 4xx can have physical space larger than
d3afa58c Michal Simek        2010-01-18  419   *     32 bits so we need to use 64 bits values for the parsing
d3afa58c Michal Simek        2010-01-18  420   */
b881bc46 Greg Kroah-Hartman  2012-12-21  421  void pci_process_bridge_OF_ranges(struct pci_controller *hose,
b881bc46 Greg Kroah-Hartman  2012-12-21  422  				  struct device_node *dev, int primary)
d3afa58c Michal Simek        2010-01-18  423  {
d3afa58c Michal Simek        2010-01-18  424  	int memno = 0, isa_hole = -1;
d3afa58c Michal Simek        2010-01-18  425  	unsigned long long isa_mb = 0;
d3afa58c Michal Simek        2010-01-18  426  	struct resource *res;
4f7b6de4 Andrew Murray       2013-07-27  427  	struct of_pci_range range;
4f7b6de4 Andrew Murray       2013-07-27  428  	struct of_pci_range_parser parser;
d3afa58c Michal Simek        2010-01-18  429  
f2b8ae0e Rob Herring         2017-06-06  430  	pr_info("PCI host bridge %pOF %s ranges:\n",
f2b8ae0e Rob Herring         2017-06-06  431  	       dev, primary ? "(primary)" : "");
d3afa58c Michal Simek        2010-01-18  432  
4f7b6de4 Andrew Murray       2013-07-27  433  	/* Check for ranges property */
4f7b6de4 Andrew Murray       2013-07-27  434  	if (of_pci_range_parser_init(&parser, dev))
d3afa58c Michal Simek        2010-01-18  435  		return;
d3afa58c Michal Simek        2010-01-18  436  
d3afa58c Michal Simek        2010-01-18  437  	pr_debug("Parsing ranges property...\n");
4f7b6de4 Andrew Murray       2013-07-27  438  	for_each_of_pci_range(&parser, &range) {
d3afa58c Michal Simek        2010-01-18  439  		/* Read next ranges element */
6bd55f0b Michal Simek        2012-12-27  440  		pr_debug("pci_space: 0x%08x pci_addr:0x%016llx ",
4f7b6de4 Andrew Murray       2013-07-27  441  				range.pci_space, range.pci_addr);
6bd55f0b Michal Simek        2012-12-27  442  		pr_debug("cpu_addr:0x%016llx size:0x%016llx\n",
4f7b6de4 Andrew Murray       2013-07-27  443  					range.cpu_addr, range.size);
d3afa58c Michal Simek        2010-01-18  444  
d3afa58c Michal Simek        2010-01-18  445  		/* If we failed translation or got a zero-sized region
d3afa58c Michal Simek        2010-01-18  446  		 * (some FW try to feed us with non sensical zero sized regions
d3afa58c Michal Simek        2010-01-18  447  		 * such as power3 which look like some kind of attempt
d3afa58c Michal Simek        2010-01-18  448  		 * at exposing the VGA memory hole)
d3afa58c Michal Simek        2010-01-18  449  		 */
4f7b6de4 Andrew Murray       2013-07-27  450  		if (range.cpu_addr == OF_BAD_ADDR || range.size == 0)
d3afa58c Michal Simek        2010-01-18  451  			continue;
d3afa58c Michal Simek        2010-01-18  452  
d3afa58c Michal Simek        2010-01-18  453  		/* Act based on address space type */
d3afa58c Michal Simek        2010-01-18  454  		res = NULL;
4f7b6de4 Andrew Murray       2013-07-27  455  		switch (range.flags & IORESOURCE_TYPE_BITS) {
4f7b6de4 Andrew Murray       2013-07-27  456  		case IORESOURCE_IO:
6bd55f0b Michal Simek        2012-12-27  457  			pr_info("  IO 0x%016llx..0x%016llx -> 0x%016llx\n",
4f7b6de4 Andrew Murray       2013-07-27  458  				range.cpu_addr, range.cpu_addr + range.size - 1,
4f7b6de4 Andrew Murray       2013-07-27  459  				range.pci_addr);
d3afa58c Michal Simek        2010-01-18  460  
d3afa58c Michal Simek        2010-01-18  461  			/* We support only one IO range */
d3afa58c Michal Simek        2010-01-18  462  			if (hose->pci_io_size) {
6bd55f0b Michal Simek        2012-12-27  463  				pr_info(" \\--> Skipped (too many) !\n");
d3afa58c Michal Simek        2010-01-18  464  				continue;
d3afa58c Michal Simek        2010-01-18  465  			}
d3afa58c Michal Simek        2010-01-18  466  			/* On 32 bits, limit I/O space to 16MB */
4f7b6de4 Andrew Murray       2013-07-27  467  			if (range.size > 0x01000000)
4f7b6de4 Andrew Murray       2013-07-27  468  				range.size = 0x01000000;
d3afa58c Michal Simek        2010-01-18  469  
d3afa58c Michal Simek        2010-01-18  470  			/* 32 bits needs to map IOs here */
4f7b6de4 Andrew Murray       2013-07-27  471  			hose->io_base_virt = ioremap(range.cpu_addr,
4f7b6de4 Andrew Murray       2013-07-27  472  						range.size);
d3afa58c Michal Simek        2010-01-18  473  
d3afa58c Michal Simek        2010-01-18  474  			/* Expect trouble if pci_addr is not 0 */
d3afa58c Michal Simek        2010-01-18  475  			if (primary)
d3afa58c Michal Simek        2010-01-18  476  				isa_io_base =
d3afa58c Michal Simek        2010-01-18  477  					(unsigned long)hose->io_base_virt;
d3afa58c Michal Simek        2010-01-18  478  			/* pci_io_size and io_base_phys always represent IO
d3afa58c Michal Simek        2010-01-18  479  			 * space starting at 0 so we factor in pci_addr
d3afa58c Michal Simek        2010-01-18  480  			 */
4f7b6de4 Andrew Murray       2013-07-27  481  			hose->pci_io_size = range.pci_addr + range.size;
4f7b6de4 Andrew Murray       2013-07-27  482  			hose->io_base_phys = range.cpu_addr - range.pci_addr;
d3afa58c Michal Simek        2010-01-18  483  
d3afa58c Michal Simek        2010-01-18  484  			/* Build resource */
d3afa58c Michal Simek        2010-01-18  485  			res = &hose->io_resource;
4f7b6de4 Andrew Murray       2013-07-27  486  			range.cpu_addr = range.pci_addr;
4f7b6de4 Andrew Murray       2013-07-27  487  
d3afa58c Michal Simek        2010-01-18  488  			break;
4f7b6de4 Andrew Murray       2013-07-27  489  		case IORESOURCE_MEM:
6bd55f0b Michal Simek        2012-12-27  490  			pr_info(" MEM 0x%016llx..0x%016llx -> 0x%016llx %s\n",
4f7b6de4 Andrew Murray       2013-07-27  491  				range.cpu_addr, range.cpu_addr + range.size - 1,
4f7b6de4 Andrew Murray       2013-07-27  492  				range.pci_addr,
4f7b6de4 Andrew Murray       2013-07-27  493  				(range.pci_space & 0x40000000) ?
4f7b6de4 Andrew Murray       2013-07-27  494  				"Prefetch" : "");
d3afa58c Michal Simek        2010-01-18  495  
d3afa58c Michal Simek        2010-01-18  496  			/* We support only 3 memory ranges */
d3afa58c Michal Simek        2010-01-18  497  			if (memno >= 3) {
6bd55f0b Michal Simek        2012-12-27  498  				pr_info(" \\--> Skipped (too many) !\n");
d3afa58c Michal Simek        2010-01-18  499  				continue;
d3afa58c Michal Simek        2010-01-18  500  			}
d3afa58c Michal Simek        2010-01-18  501  			/* Handles ISA memory hole space here */
4f7b6de4 Andrew Murray       2013-07-27  502  			if (range.pci_addr == 0) {
4f7b6de4 Andrew Murray       2013-07-27  503  				isa_mb = range.cpu_addr;
d3afa58c Michal Simek        2010-01-18  504  				isa_hole = memno;
d3afa58c Michal Simek        2010-01-18  505  				if (primary || isa_mem_base == 0)
4f7b6de4 Andrew Murray       2013-07-27  506  					isa_mem_base = range.cpu_addr;
4f7b6de4 Andrew Murray       2013-07-27  507  				hose->isa_mem_phys = range.cpu_addr;
4f7b6de4 Andrew Murray       2013-07-27  508  				hose->isa_mem_size = range.size;
d3afa58c Michal Simek        2010-01-18  509  			}
d3afa58c Michal Simek        2010-01-18  510  
d3afa58c Michal Simek        2010-01-18  511  			/* We get the PCI/Mem offset from the first range or
d3afa58c Michal Simek        2010-01-18  512  			 * the, current one if the offset came from an ISA
d3afa58c Michal Simek        2010-01-18  513  			 * hole. If they don't match, bugger.
d3afa58c Michal Simek        2010-01-18  514  			 */
d3afa58c Michal Simek        2010-01-18  515  			if (memno == 0 ||
4f7b6de4 Andrew Murray       2013-07-27  516  			    (isa_hole >= 0 && range.pci_addr != 0 &&
d3afa58c Michal Simek        2010-01-18  517  			     hose->pci_mem_offset == isa_mb))
4f7b6de4 Andrew Murray       2013-07-27  518  				hose->pci_mem_offset = range.cpu_addr -
4f7b6de4 Andrew Murray       2013-07-27  519  							range.pci_addr;
4f7b6de4 Andrew Murray       2013-07-27  520  			else if (range.pci_addr != 0 &&
4f7b6de4 Andrew Murray       2013-07-27  521  				 hose->pci_mem_offset != range.cpu_addr -
4f7b6de4 Andrew Murray       2013-07-27  522  							range.pci_addr) {
6bd55f0b Michal Simek        2012-12-27  523  				pr_info(" \\--> Skipped (offset mismatch) !\n");
d3afa58c Michal Simek        2010-01-18  524  				continue;
d3afa58c Michal Simek        2010-01-18  525  			}
d3afa58c Michal Simek        2010-01-18  526  
d3afa58c Michal Simek        2010-01-18  527  			/* Build resource */
d3afa58c Michal Simek        2010-01-18  528  			res = &hose->mem_resources[memno++];
d3afa58c Michal Simek        2010-01-18  529  			break;
d3afa58c Michal Simek        2010-01-18  530  		}
70dcd942 Michal Simek        2014-10-27  531  		if (res != NULL) {
70dcd942 Michal Simek        2014-10-27  532  			res->name = dev->full_name;
70dcd942 Michal Simek        2014-10-27  533  			res->flags = range.flags;
70dcd942 Michal Simek        2014-10-27  534  			res->start = range.cpu_addr;
70dcd942 Michal Simek        2014-10-27  535  			res->end = range.cpu_addr + range.size - 1;
70dcd942 Michal Simek        2014-10-27 @536  			res->parent = res->child = res->sibling = NULL;
70dcd942 Michal Simek        2014-10-27  537  		}
d3afa58c Michal Simek        2010-01-18  538  	}
d3afa58c Michal Simek        2010-01-18  539  
d3afa58c Michal Simek        2010-01-18  540  	/* If there's an ISA hole and the pci_mem_offset is -not- matching
d3afa58c Michal Simek        2010-01-18  541  	 * the ISA hole offset, then we need to remove the ISA hole from
d3afa58c Michal Simek        2010-01-18  542  	 * the resource list for that brige
d3afa58c Michal Simek        2010-01-18  543  	 */
d3afa58c Michal Simek        2010-01-18  544  	if (isa_hole >= 0 && hose->pci_mem_offset != isa_mb) {
d3afa58c Michal Simek        2010-01-18  545  		unsigned int next = isa_hole + 1;
6bd55f0b Michal Simek        2012-12-27  546  		pr_info(" Removing ISA hole at 0x%016llx\n", isa_mb);
d3afa58c Michal Simek        2010-01-18  547  		if (next < memno)
d3afa58c Michal Simek        2010-01-18  548  			memmove(&hose->mem_resources[isa_hole],
d3afa58c Michal Simek        2010-01-18  549  				&hose->mem_resources[next],
d3afa58c Michal Simek        2010-01-18  550  				sizeof(struct resource) * (memno - next));
d3afa58c Michal Simek        2010-01-18  551  		hose->mem_resources[--memno].flags = 0;
d3afa58c Michal Simek        2010-01-18  552  	}
d3afa58c Michal Simek        2010-01-18  553  }
d3afa58c Michal Simek        2010-01-18  554  
9413d968 Bharat Kumar Gogada 2016-09-01  555  /* Display the domain number in /proc */
d3afa58c Michal Simek        2010-01-18  556  int pci_proc_domain(struct pci_bus *bus)
d3afa58c Michal Simek        2010-01-18  557  {
9413d968 Bharat Kumar Gogada 2016-09-01  558  	return pci_domain_nr(bus);
d3afa58c Michal Simek        2010-01-18  559  }
d3afa58c Michal Simek        2010-01-18  560  
d3afa58c Michal Simek        2010-01-18  561  /* This header fixup will do the resource fixup for all devices as they are
d3afa58c Michal Simek        2010-01-18  562   * probed, but not for bridge ranges
d3afa58c Michal Simek        2010-01-18  563   */
b881bc46 Greg Kroah-Hartman  2012-12-21  564  static void pcibios_fixup_resources(struct pci_dev *dev)
d3afa58c Michal Simek        2010-01-18  565  {
d3afa58c Michal Simek        2010-01-18  566  	struct pci_controller *hose = pci_bus_to_host(dev->bus);
d3afa58c Michal Simek        2010-01-18  567  	int i;
d3afa58c Michal Simek        2010-01-18  568  
d3afa58c Michal Simek        2010-01-18  569  	if (!hose) {
6bd55f0b Michal Simek        2012-12-27  570  		pr_err("No host bridge for PCI dev %s !\n",
d3afa58c Michal Simek        2010-01-18  571  		       pci_name(dev));
d3afa58c Michal Simek        2010-01-18  572  		return;
d3afa58c Michal Simek        2010-01-18  573  	}
d3afa58c Michal Simek        2010-01-18  574  	for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) {
d3afa58c Michal Simek        2010-01-18  575  		struct resource *res = dev->resource + i;
d3afa58c Michal Simek        2010-01-18  576  		if (!res->flags)
d3afa58c Michal Simek        2010-01-18  577  			continue;
e5b36841 Bjorn Helgaas       2012-02-23  578  		if (res->start == 0) {
6bd55f0b Michal Simek        2012-12-27  579  			pr_debug("PCI:%s Resource %d %016llx-%016llx [%x]",
d3afa58c Michal Simek        2010-01-18  580  				 pci_name(dev), i,
d3afa58c Michal Simek        2010-01-18  581  				 (unsigned long long)res->start,
d3afa58c Michal Simek        2010-01-18  582  				 (unsigned long long)res->end,
d3afa58c Michal Simek        2010-01-18  583  				 (unsigned int)res->flags);
6bd55f0b Michal Simek        2012-12-27  584  			pr_debug("is unassigned\n");
d3afa58c Michal Simek        2010-01-18  585  			res->end -= res->start;
d3afa58c Michal Simek        2010-01-18  586  			res->start = 0;
d3afa58c Michal Simek        2010-01-18  587  			res->flags |= IORESOURCE_UNSET;
d3afa58c Michal Simek        2010-01-18  588  			continue;
d3afa58c Michal Simek        2010-01-18  589  		}
d3afa58c Michal Simek        2010-01-18  590  
aa23bdc0 Bjorn Helgaas       2012-02-23  591  		pr_debug("PCI:%s Resource %d %016llx-%016llx [%x]\n",
d3afa58c Michal Simek        2010-01-18  592  			 pci_name(dev), i,
6bd55f0b Michal Simek        2012-12-27  593  			 (unsigned long long)res->start,
d3afa58c Michal Simek        2010-01-18  594  			 (unsigned long long)res->end,
d3afa58c Michal Simek        2010-01-18  595  			 (unsigned int)res->flags);
d3afa58c Michal Simek        2010-01-18  596  	}
d3afa58c Michal Simek        2010-01-18  597  }
d3afa58c Michal Simek        2010-01-18  598  DECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID, PCI_ANY_ID, pcibios_fixup_resources);
d3afa58c Michal Simek        2010-01-18  599  
d3afa58c Michal Simek        2010-01-18  600  /*
d3afa58c Michal Simek        2010-01-18  601   * We need to avoid collisions with `mirrored' VGA ports
d3afa58c Michal Simek        2010-01-18  602   * and other strange ISA hardware, so we always want the
d3afa58c Michal Simek        2010-01-18  603   * addresses to be allocated in the 0x000-0x0ff region
d3afa58c Michal Simek        2010-01-18  604   * modulo 0x400.
d3afa58c Michal Simek        2010-01-18  605   *
d3afa58c Michal Simek        2010-01-18  606   * Why? Because some silly external IO cards only decode
d3afa58c Michal Simek        2010-01-18  607   * the low 10 bits of the IO address. The 0x00-0xff region
d3afa58c Michal Simek        2010-01-18  608   * is reserved for motherboard devices that decode all 16
d3afa58c Michal Simek        2010-01-18  609   * bits, so it's ok to allocate at, say, 0x2800-0x28ff,
d3afa58c Michal Simek        2010-01-18  610   * but we want to try to avoid allocating at 0x2900-0x2bff
d3afa58c Michal Simek        2010-01-18  611   * which might have be mirrored at 0x0100-0x03ff..
d3afa58c Michal Simek        2010-01-18  612   */
01cf9d52 Bharat Kumar Gogada 2016-02-11  613  int pcibios_add_device(struct pci_dev *dev)
01cf9d52 Bharat Kumar Gogada 2016-02-11  614  {
01cf9d52 Bharat Kumar Gogada 2016-02-11  615  	dev->irq = of_irq_parse_and_map_pci(dev, 0, 0);
c86fac43 Michal Simek        2010-04-16  616  
01cf9d52 Bharat Kumar Gogada 2016-02-11  617  	return 0;
d3afa58c Michal Simek        2010-01-18  618  }
01cf9d52 Bharat Kumar Gogada 2016-02-11  619  EXPORT_SYMBOL(pcibios_add_device);
d3afa58c Michal Simek        2010-01-18  620  
d3afa58c Michal Simek        2010-01-18  621  /*
d3afa58c Michal Simek        2010-01-18  622   * Reparent resource children of pr that conflict with res
d3afa58c Michal Simek        2010-01-18  623   * under res, and make res replace those children.
d3afa58c Michal Simek        2010-01-18  624   */
d3afa58c Michal Simek        2010-01-18  625  static int __init reparent_resources(struct resource *parent,
d3afa58c Michal Simek        2010-01-18  626  				     struct resource *res)
d3afa58c Michal Simek        2010-01-18  627  {
d3afa58c Michal Simek        2010-01-18  628  	struct resource *p, **pp;
d3afa58c Michal Simek        2010-01-18  629  	struct resource **firstpp = NULL;
d3afa58c Michal Simek        2010-01-18  630  
d3afa58c Michal Simek        2010-01-18 @631  	for (pp = &parent->child; (p = *pp) != NULL; pp = &p->sibling) {
d3afa58c Michal Simek        2010-01-18  632  		if (p->end < res->start)
d3afa58c Michal Simek        2010-01-18  633  			continue;
d3afa58c Michal Simek        2010-01-18  634  		if (res->end < p->start)
d3afa58c Michal Simek        2010-01-18  635  			break;
d3afa58c Michal Simek        2010-01-18  636  		if (p->start < res->start || p->end > res->end)
d3afa58c Michal Simek        2010-01-18  637  			return -1;	/* not completely contained */
d3afa58c Michal Simek        2010-01-18  638  		if (firstpp == NULL)
d3afa58c Michal Simek        2010-01-18  639  			firstpp = pp;
d3afa58c Michal Simek        2010-01-18  640  	}
d3afa58c Michal Simek        2010-01-18  641  	if (firstpp == NULL)
d3afa58c Michal Simek        2010-01-18  642  		return -1;	/* didn't find any conflicting entries? */
d3afa58c Michal Simek        2010-01-18  643  	res->parent = parent;
d3afa58c Michal Simek        2010-01-18 @644  	res->child = *firstpp;
d3afa58c Michal Simek        2010-01-18  645  	res->sibling = *pp;
d3afa58c Michal Simek        2010-01-18  646  	*firstpp = res;
d3afa58c Michal Simek        2010-01-18  647  	*pp = NULL;
d3afa58c Michal Simek        2010-01-18 @648  	for (p = res->child; p != NULL; p = p->sibling) {
d3afa58c Michal Simek        2010-01-18  649  		p->parent = res;
d3afa58c Michal Simek        2010-01-18  650  		pr_debug("PCI: Reparented %s [%llx..%llx] under %s\n",
d3afa58c Michal Simek        2010-01-18  651  			 p->name,
d3afa58c Michal Simek        2010-01-18  652  			 (unsigned long long)p->start,
d3afa58c Michal Simek        2010-01-18  653  			 (unsigned long long)p->end, res->name);
d3afa58c Michal Simek        2010-01-18  654  	}
d3afa58c Michal Simek        2010-01-18  655  	return 0;
d3afa58c Michal Simek        2010-01-18  656  }
d3afa58c Michal Simek        2010-01-18  657  

:::::: The code at line 536 was first introduced by commit
:::::: 70dcd942dc4af3cc6c3dcc2ba499cd841c7f65a7 microblaze: Fix IO space breakage after of_pci_range_to_resource() change

:::::: TO: Michal Simek <michal.simek-gjFFaj9aHVfQT0dZR+AlfA@public.gmane.org>
:::::: CC: Michal Simek <michal.simek-gjFFaj9aHVfQT0dZR+AlfA@public.gmane.org>

---
0-DAY kernel test infrastructure                Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all                   Intel Corporation

^ permalink raw reply

* Re: [PATCH v3 1/3] resource: Use list_head to link sibling resource
From: Wei Yang @ 2018-04-26  1:18 UTC (permalink / raw)
  To: Baoquan He
  Cc: nicolas.pitre-QSEj5FYQhm4dnm+yROfE0A, Brijesh Singh,
	devicetree-u79uwXL29TY76Z2rM5mHXA, David Airlie,
	linux-pci-u79uwXL29TY76Z2rM5mHXA, Wei Yang, Keith Busch,
	Yaowei Bai, K. Y. Srinivasan, Frank Rowand, Lorenzo Pieralisi,
	Stephen Hemminger, linux-nvdimm-hn68Rpc1hR1g9hUCZPvPmw,
	Patrik Jakobsson, linux-input-u79uwXL29TY76Z2rM5mHXA,
	Borislav Petkov, Tom Lendacky, Haiyang Zhang,
	josh-iaAMLnmF4UmaiuxdJuQwMA, Jérôme Glisse,
	robh+dt-DgEjT+Ai2ygdnm+yROfE0A, Bjorn Helgaas, Thomas Gleixner,
	Jonathan Derrick
In-Reply-To: <20180419001848.3041-2-bhe-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>

On Thu, Apr 19, 2018 at 08:18:46AM +0800, Baoquan He wrote:
>The struct resource uses singly linked list to link siblings. It's not
>easy to do reverse iteration on sibling list. So replace it with list_head.
>

Hi, Baoquan

Besides changing the data structure, I have another proposal to do the reverse
iteration. Which means it would not affect other users, if you just want a
reverse iteration.

BTW, I don't think Andrew suggest to use linked-list directly. What he wants
is a better solution to your first proposal in
https://patchwork.kernel.org/patch/10300819/.

Below is my proposal of resource reverse iteration without changing current
design.

>From 5d7145d44fe48b98572a03884fa3a3aa82e3cef9 Mon Sep 17 00:00:00 2001
From: Wei Yang <richard.weiyang-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
Date: Sat, 24 Mar 2018 23:25:46 +0800
Subject: [PATCH] kernel/resource: add walk_system_ram_res_rev()

As discussed on https://patchwork.kernel.org/patch/10300819/, this patch
comes up with a variant implementation of walk_system_ram_res_rev(), which
uses iteration instead of allocating array to store those resources.

Signed-off-by: Wei Yang <richard.weiyang-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
---
 include/linux/ioport.h |   3 ++
 kernel/resource.c      | 113 +++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 116 insertions(+)

diff --git a/include/linux/ioport.h b/include/linux/ioport.h
index da0ebaec25f0..473f1d9cb97e 100644
--- a/include/linux/ioport.h
+++ b/include/linux/ioport.h
@@ -277,6 +277,9 @@ extern int
 walk_system_ram_res(u64 start, u64 end, void *arg,
 		    int (*func)(struct resource *, void *));
 extern int
+walk_system_ram_res_rev(u64 start, u64 end, void *arg,
+		    int (*func)(struct resource *, void *));
+extern int
 walk_iomem_res_desc(unsigned long desc, unsigned long flags, u64 start, u64 end,
 		    void *arg, int (*func)(struct resource *, void *));
 
diff --git a/kernel/resource.c b/kernel/resource.c
index 769109f20fb7..d4ec5fbc6875 100644
--- a/kernel/resource.c
+++ b/kernel/resource.c
@@ -73,6 +73,38 @@ static struct resource *next_resource(struct resource *p, bool sibling_only)
 	return p->sibling;
 }
 
+static struct resource *prev_resource(struct resource *p, bool sibling_only)
+{
+	struct resource *prev;
+	if (NULL == iomem_resource.child)
+		return NULL;
+
+	if (p == NULL) {
+		prev = iomem_resource.child;
+		while (prev->sibling)
+			prev = prev->sibling;
+	} else {
+		if (p->parent->child == p) {
+			return p->parent;
+		}
+
+		for (prev = p->parent->child; prev->sibling != p;
+			prev = prev->sibling) {}
+	}
+
+	/* Caller wants to traverse through siblings only */
+	if (sibling_only)
+		return prev;
+
+	for (;prev->child;) {
+		prev = prev->child;
+
+		while (prev->sibling)
+			prev = prev->sibling;
+	}
+	return prev;
+}
+
 static void *r_next(struct seq_file *m, void *v, loff_t *pos)
 {
 	struct resource *p = v;
@@ -401,6 +433,47 @@ static int find_next_iomem_res(struct resource *res, unsigned long desc,
 	return 0;
 }
 
+/*
+ * Finds the highest iomem resource existing within [res->start.res->end).
+ * The caller must specify res->start, res->end, res->flags, and optionally
+ * desc.  If found, returns 0, res is overwritten, if not found, returns -1.
+ * This function walks the whole tree and not just first level children until
+ * and unless first_level_children_only is true.
+ */
+static int find_prev_iomem_res(struct resource *res, unsigned long desc,
+			       bool first_level_children_only)
+{
+	struct resource *p;
+
+	BUG_ON(!res);
+	BUG_ON(res->start >= res->end);
+
+	read_lock(&resource_lock);
+
+	for (p = prev_resource(NULL, first_level_children_only); p;
+		p = prev_resource(p, first_level_children_only)) {
+		if ((p->flags & res->flags) != res->flags)
+			continue;
+		if ((desc != IORES_DESC_NONE) && (desc != p->desc))
+			continue;
+		if (p->end < res->start || p->child == iomem_resource.child) {
+			p = NULL;
+			break;
+		}
+		if ((p->end >= res->start) && (p->start < res->end))
+			break;
+	}
+
+	read_unlock(&resource_lock);
+	if (!p)
+		return -1;
+	/* copy data */
+	resource_clip(res, p->start, p->end);
+	res->flags = p->flags;
+	res->desc = p->desc;
+	return 0;
+}
+
 static int __walk_iomem_res_desc(struct resource *res, unsigned long desc,
 				 bool first_level_children_only,
 				 void *arg,
@@ -422,6 +495,27 @@ static int __walk_iomem_res_desc(struct resource *res, unsigned long desc,
 	return ret;
 }
 
+static int __walk_iomem_res_rev_desc(struct resource *res, unsigned long desc,
+				 bool first_level_children_only,
+				 void *arg,
+				 int (*func)(struct resource *, void *))
+{
+	u64 orig_start = res->start;
+	int ret = -1;
+
+	while ((res->start < res->end) &&
+	       !find_prev_iomem_res(res, desc, first_level_children_only)) {
+		ret = (*func)(res, arg);
+		if (ret)
+			break;
+
+		res->end = res->start?(res->start - 1):0;
+		res->start = orig_start;
+	}
+
+	return ret;
+}
+
 /*
  * Walks through iomem resources and calls func() with matching resource
  * ranges. This walks through whole tree and not just first level children.
@@ -468,6 +562,25 @@ int walk_system_ram_res(u64 start, u64 end, void *arg,
 				     arg, func);
 }
 
+/*
+ * This function, being a variant of walk_system_ram_res(), calls the @func
+ * callback against all memory ranges of type System RAM which are marked as
+ * IORESOURCE_SYSTEM_RAM and IORESOUCE_BUSY in reversed order, i.e., from
+ * higher to lower.
+ */
+int walk_system_ram_res_rev(u64 start, u64 end, void *arg,
+				int (*func)(struct resource *, void *))
+{
+	struct resource res;
+
+	res.start = start;
+	res.end = end;
+	res.flags = IORESOURCE_SYSTEM_RAM | IORESOURCE_BUSY;
+
+	return __walk_iomem_res_rev_desc(&res, IORES_DESC_NONE, true,
+				     arg, func);
+}
+
 /*
  * This function calls the @func callback against all memory ranges, which
  * are ranges marked as IORESOURCE_MEM and IORESOUCE_BUSY.
-- 
2.15.1


-- 
Wei Yang
Help you, Help me

^ permalink raw reply related

* Re: [PATCH v2] input/touchscreen: atmel_mxt_ts: Add correct touchpad button mapping for the Caroline Chromebook.
From: Dmitry Torokhov @ 2018-04-25 22:57 UTC (permalink / raw)
  To: Vittorio Gambaletta (VittGam)
  Cc: linux-kernel, linux-input, stable, nick, bleung,
	Salvatore Bellizzi, groeck
In-Reply-To: <20180425222650.GC200812@dtor-ws>

On Wed, Apr 25, 2018 at 03:26:50PM -0700, Dmitry Torokhov wrote:
> On Wed, Apr 25, 2018 at 02:32:58PM +0200, Vittorio Gambaletta (VittGam) wrote:
> > This patch adds the correct platform data information for the Caroline
> > Chromebook, so that the mouse button does not get stuck in pressed state
> > after the first click.
> > 
> > The Samus button keymap and platform data definition are the correct
> > ones for Caroline, so they have been reused here.
> > 
> > v2: updated patch offset after 20180409 changes.
> > 
> > Cc: stable@vger.kernel.org
> > Signed-off-by: Vittorio Gambaletta <linuxbugs@vittgam.net>
> > Signed-off-by: Salvatore Bellizzi <lkml@seppia.net>
> > 
> 
> Applied, thank you.
> 
> > ---
> > 
> > --- a/drivers/input/touchscreen/atmel_mxt_ts.c
> > +++ b/drivers/input/touchscreen/atmel_mxt_ts.c
> > @@ -3035,6 +3035,15 @@
> >  		.driver_data = samus_platform_data,
> >  	},
> >  	{
> > +		/* Samsung Chromebook Pro */
> > +		.ident = "Samsung Chromebook Pro",
> > +		.matches = {
> > +			DMI_MATCH(DMI_SYS_VENDOR, "GOOGLE"),

I've been alerted that shipping BIOS has vendor not capitalized; where
did you get the firmware that has vendor all capitals?

Thanks.

> > +			DMI_MATCH(DMI_PRODUCT_NAME, "Caroline"),
> > +		},
> > +		.driver_data = samus_platform_data,
> > +	},
> > +	{
> >  		/* Other Google Chromebooks */
> >  		.ident = "Chromebook",
> >  		.matches = {
> 
> -- 
> Dmitry

-- 
Dmitry

^ permalink raw reply

* Re: [PATCH v2] input/touchscreen: atmel_mxt_ts: Add correct touchpad button mapping for the Caroline Chromebook.
From: Dmitry Torokhov @ 2018-04-25 22:26 UTC (permalink / raw)
  To: Vittorio Gambaletta (VittGam)
  Cc: linux-kernel, linux-input, stable, nick, bleung,
	Salvatore Bellizzi, groeck
In-Reply-To: <201804251232.w3PCWweA028076@mail.vittgam.net>

On Wed, Apr 25, 2018 at 02:32:58PM +0200, Vittorio Gambaletta (VittGam) wrote:
> This patch adds the correct platform data information for the Caroline
> Chromebook, so that the mouse button does not get stuck in pressed state
> after the first click.
> 
> The Samus button keymap and platform data definition are the correct
> ones for Caroline, so they have been reused here.
> 
> v2: updated patch offset after 20180409 changes.
> 
> Cc: stable@vger.kernel.org
> Signed-off-by: Vittorio Gambaletta <linuxbugs@vittgam.net>
> Signed-off-by: Salvatore Bellizzi <lkml@seppia.net>
> 

Applied, thank you.

> ---
> 
> --- a/drivers/input/touchscreen/atmel_mxt_ts.c
> +++ b/drivers/input/touchscreen/atmel_mxt_ts.c
> @@ -3035,6 +3035,15 @@
>  		.driver_data = samus_platform_data,
>  	},
>  	{
> +		/* Samsung Chromebook Pro */
> +		.ident = "Samsung Chromebook Pro",
> +		.matches = {
> +			DMI_MATCH(DMI_SYS_VENDOR, "GOOGLE"),
> +			DMI_MATCH(DMI_PRODUCT_NAME, "Caroline"),
> +		},
> +		.driver_data = samus_platform_data,
> +	},
> +	{
>  		/* Other Google Chromebooks */
>  		.ident = "Chromebook",
>  		.matches = {

-- 
Dmitry

^ permalink raw reply

* [PATCH v2] input/touchscreen: atmel_mxt_ts: Add correct touchpad button mapping for the Caroline Chromebook.
From: Vittorio Gambaletta (VittGam) @ 2018-04-25 12:32 UTC (permalink / raw)
  To: linux-kernel, linux-input, stable, nick, dmitry.torokhov, bleung
  Cc: Salvatore Bellizzi

This patch adds the correct platform data information for the Caroline
Chromebook, so that the mouse button does not get stuck in pressed state
after the first click.

The Samus button keymap and platform data definition are the correct
ones for Caroline, so they have been reused here.

v2: updated patch offset after 20180409 changes.

Cc: stable@vger.kernel.org
Signed-off-by: Vittorio Gambaletta <linuxbugs@vittgam.net>
Signed-off-by: Salvatore Bellizzi <lkml@seppia.net>

---

--- a/drivers/input/touchscreen/atmel_mxt_ts.c
+++ b/drivers/input/touchscreen/atmel_mxt_ts.c
@@ -3035,6 +3035,15 @@
 		.driver_data = samus_platform_data,
 	},
 	{
+		/* Samsung Chromebook Pro */
+		.ident = "Samsung Chromebook Pro",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "GOOGLE"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "Caroline"),
+		},
+		.driver_data = samus_platform_data,
+	},
+	{
 		/* Other Google Chromebooks */
 		.ident = "Chromebook",
 		.matches = {

^ permalink raw reply

* Re: [PATCH] HID: wacom: Release device resource data obtained by devres_alloc()
From: Jiri Kosina @ 2018-04-25  8:51 UTC (permalink / raw)
  To: Arvind Yadav; +Cc: benjamin.tissoires, linux-kernel, linux-input
In-Reply-To: <9b8c9c6134cb27ee8ac37224098e382ab9189d62.1524556744.git.arvind.yadav.cs@gmail.com>

On Tue, 24 Apr 2018, Arvind Yadav wrote:

> Free device resource data, if __wacom_devm_sysfs_create_group
> is not successful.

Applied, thanks.

-- 
Jiri Kosina
SUSE Labs

^ permalink raw reply

* Re: WARNING: HARDIRQ-safe -> HARDIRQ-unsafe lock order detected
From: Theodore Y. Ts'o @ 2018-04-24 12:55 UTC (permalink / raw)
  To: Dmitry Torokhov
  Cc: syzbot, linux-input@vger.kernel.org, lkml, Henrik Rydberg,
	syzkaller-bugs
In-Reply-To: <CAKdAkRRyRPEnghR6YqE++-H=HJbFL0ejK73Z_vMp_TMyNTT4ew@mail.gmail.com>

On Mon, Apr 23, 2018 at 10:49:12AM -0700, Dmitry Torokhov wrote:
> On Sun, Apr 22, 2018 at 7:02 PM, syzbot
> <syzbot+e1670f554caa60fb147b@syzkaller.appspotmail.com> wrote:
> >
> > Hello,
> >
> > syzbot hit the following crash on upstream commit
> > 285848b0f4074f04ab606f1e5dca296482033d54 (Sun Apr 22 04:20:48 2018 +0000)
> > Merge tag 'random_for_linus_stable' of git://git.kernel.org/pub/scm/linux/kernel/git/tytso/random
> > syzbot dashboard link: https://syzkaller.appspot.com/bug?extid=e1670f554caa60fb147b
> 
> Ted,
> 
> input_add_randomness() (that ends up calling crng_reseed() and the new
> numa_crng_init()) is called (and has been called ever since inception)
> from an interrupt context and thus may not sleep. The following commit
> breaks this:

Fixed by: https://www.mail-archive.com/linux-kernel@vger.kernel.org/msg1672186.html

Will be pushed to Linux shortly.

						- Ted

^ permalink raw reply

* Re: [PATCH] Input: alps - Demystify trackstick initialization for v3 and v6 protocols
From: Pali Rohár @ 2018-04-24 11:14 UTC (permalink / raw)
  To: Dmitry Torokhov
  Cc: linux-input@vger.kernel.org, linux-kernel@vger.kernel.org,
	Masaki Ota
In-Reply-To: <20180423234026.GI66646@dtor-ws>

On Monday 23 April 2018 16:40:26 Dmitry Torokhov wrote:
> On Wed, Apr 18, 2018 at 01:40:30PM +0200, Pali Rohár wrote:
> > Dmitry, ping
> 
> Applied, thank you. Can you tell me if I am missing anything else for
> ALPS?

Hi! All remaining ALPS patches should be already processed.

> 
> Thanks!
> 
> > 
> > On Wednesday 21 March 2018 17:41:26 Pali Rohár wrote:
> > > That is pity, but OK.
> > > 
> > > Anyway, as wrote patch which I sent in the first email matches this
> > > documentation.
> > > 
> > > Dmitry, can you review/comment/accept/reject this patch?
> > > 
> > > On Monday 19 March 2018 08:41:19 Masaki Ota wrote:
> > > > Hi, Pali,
> > > > 
> > > > v3/v6 devices are T3 type, and it can use only Method 2.
> > > > P36 (At this time GLIDEPOINT_T3 uses the Method 2 ....)
> > > > T3 has the potential that uses Method2, but I think it needs to change Firmware.
> > > > 
> > > > Best Regards,
> > > > Masaki Ota
> > > > -----Original Message-----
> > > > From: Pali Rohár [mailto:pali.rohar@gmail.com] 
> > > > Sent: Friday, March 16, 2018 7:58 PM
> > > > To: 太田 真喜 Masaki Ota <masaki.ota@jp.alps.com>
> > > > Cc: Dmitry Torokhov <dmitry.torokhov@gmail.com>; linux-input@vger.kernel.org; linux-kernel@vger.kernel.org
> > > > Subject: Re: [PATCH] Input: alps - Demystify trackstick initialization for v3 and v6 protocols
> > > > 
> > > > Great, thank you. Enabling that RAW/extended/SP4 mode is done by sequence E6, E6, E6, F3, C8, F3, 14 (written in page 35) and it matches what function alps_trackstick_enter_extended_mode_v3_v6() in my patch is doing. So is correct.
> > > > 
> > > > On page 36 I see that there is described Method 1 for reporting stick data which prevents cursor jumps. Seems that kernel uses Method 2.
> > > > Method 1 depends on some prioritization.
> > > > 
> > > > Do you have some information how to activate Method 1? Sometimes I observe that problem with "cursor jumps" and from Method 1 could prevent it. So I would like to try experimenting...
> > > > 
> > > > On Wednesday 14 March 2018 23:56:46 Masaki Ota wrote:
> > > > > Hi, Pali,
> > > > > 
> > > > > I have added Appendix.
> > > > > According to this spec documents, SP raw mode is SP 4 byte mode.
> > > > > I think Extended mode meaning is almost all the same as Raw mode.
> > > > > The description of how to set is written in Page 35.
> > > > > 
> > > > > Best Regards,
> > > > > Masaki Ota
> > > > > -----Original Message-----
> > > > > From: Pali Rohár [mailto:pali.rohar@gmail.com]
> > > > > Sent: Thursday, March 15, 2018 7:58 AM
> > > > > To: 太田 真喜 Masaki Ota <masaki.ota@jp.alps.com>
> > > > > Cc: Dmitry Torokhov <dmitry.torokhov@gmail.com>; 
> > > > > linux-input@vger.kernel.org; linux-kernel@vger.kernel.org
> > > > > Subject: Re: [PATCH] Input: alps - Demystify trackstick initialization 
> > > > > for v3 and v6 protocols
> > > > > 
> > > > > Hi! Thank you for information.
> > > > > 
> > > > > Your PS/2 Aux Port Control description seems to really matches. Just there is reverse order of bits. Bit 0 in description is highest, therefore matches BIT(7) macro.
> > > > > 
> > > > > Bit 6 in description (BIT(1) in code) describes SP Extended Mode which alps.c enabled. And in that description is written:
> > > > > 
> > > > > "If 1 SP is extended packet format (driver must set SP raw mode and GP absolute mode)."
> > > > > 
> > > > > Do you have any idea what "SP raw mode" is? How to set it? For me it looks like it could be that extended mode of trackstick itself.
> > > > > 
> > > > > "GP absolute mode" I guess is GlidePoint absolute mode, therefore 
> > > > > enable
> > > > > 6 byte absolute mode for touchpad.
> > > > > 
> > > > > And for Bit 7 (BIT(0)) is written:
> > > > > 
> > > > > This bit is used with the PS/2 Aux port to use the Pass-Thru mode ( see appendix A ). Do you have some information about this appendix A?
> > > > > 
> > > > > On Wednesday 14 March 2018 10:21:43 Masaki Ota wrote:
> > > > > > Hi, Pali,
> > > > > > 
> > > > > > I just picked up the spec which relates with trackstic.
> > > > > > 
> > > > > > Best Regards,
> > > > > > Masaki Ota
> > > > > > -----Original Message-----
> > > > > > From: Pali Rohár [mailto:pali.rohar@gmail.com]
> > > > > > Sent: Tuesday, March 13, 2018 8:14 AM
> > > > > > To: 太田 真喜 Masaki Ota <masaki.ota@jp.alps.com>; Dmitry Torokhov 
> > > > > > <dmitry.torokhov@gmail.com>
> > > > > > Cc: linux-input@vger.kernel.org; linux-kernel@vger.kernel.org
> > > > > > Subject: Re: [PATCH] Input: alps - Demystify trackstick 
> > > > > > initialization for v3 and v6 protocols
> > > > > > 
> > > > > > Masaki, if you have access to the internal ALPS v3 / Rushmore 
> > > > > > documentation, I would like to have a review of this patch or 
> > > > > > confirmation of those information :-)
> > > > > 
> > > > > --
> > > > > Pali Rohár
> > > > > pali.rohar@gmail.com
> > > > 
> > > > --
> > > > Pali Rohár
> > > > pali.rohar@gmail.com
> > > 
> > 
> > -- 
> > Pali Rohár
> > pali.rohar@gmail.com
> 

-- 
Pali Rohár
pali.rohar@gmail.com

^ permalink raw reply

* Re: [PATCH] HID: wacom: Release device resource data obtained by devres_alloc()
From: Benjamin Tissoires @ 2018-04-24  9:04 UTC (permalink / raw)
  To: Arvind Yadav; +Cc: Jiri Kosina, jkosina, lkml, open list:HID CORE LAYER
In-Reply-To: <9b8c9c6134cb27ee8ac37224098e382ab9189d62.1524556744.git.arvind.yadav.cs@gmail.com>

On Tue, Apr 24, 2018 at 10:03 AM, Arvind Yadav
<arvind.yadav.cs@gmail.com> wrote:
> Free device resource data, if __wacom_devm_sysfs_create_group
> is not successful.
>
> Signed-off-by: Arvind Yadav <arvind.yadav.cs@gmail.com>
> ---

Looks good to me:
Reviewed-by: Benjamin Tissoires <benjamin.tissoires@redhat.com>

Cheers,
Benjamin

>  drivers/hid/wacom_sys.c | 4 +++-
>  1 file changed, 3 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/hid/wacom_sys.c b/drivers/hid/wacom_sys.c
> index b54ef1f..ee7a37e 100644
> --- a/drivers/hid/wacom_sys.c
> +++ b/drivers/hid/wacom_sys.c
> @@ -1213,8 +1213,10 @@ static int __wacom_devm_sysfs_create_group(struct wacom *wacom,
>         devres->root = root;
>
>         error = sysfs_create_group(devres->root, group);
> -       if (error)
> +       if (error) {
> +               devres_free(devres);
>                 return error;
> +       }
>
>         devres_add(&wacom->hdev->dev, devres);
>
> --
> 1.9.1
>

^ permalink raw reply

* [PATCH v2 6/6] HID: multitouch: implement precision touchpad latency and switches
From: Benjamin Tissoires @ 2018-04-24  8:04 UTC (permalink / raw)
  To: Jiri Kosina
  Cc: Dmitry Torokhov, Peter Hutterer, Mario.Limonciello, linux-input,
	linux-kernel, Benjamin Tissoires
In-Reply-To: <20180424080437.21367-1-benjamin.tissoires@redhat.com>

The Win 8.1 precision touchpad spec introduce new modes for touchpads
that can come in handy[1].

Implement the settings of these modes, so we are not taken off-guard if
a firmware decides to enforce them.

[1] https://docs.microsoft.com/en-us/windows-hardware/design/component-guidelines/windows-precision-touchpad-required-hid-top-level-collections

Signed-off-by: Benjamin Tissoires <benjamin.tissoires@redhat.com>
---
 drivers/hid/hid-multitouch.c | 34 +++++++++++++++++++++++++++++-----
 include/linux/hid.h          |  3 +++
 2 files changed, 32 insertions(+), 5 deletions(-)

diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c
index 8878de9eedba..82c98bf14d60 100644
--- a/drivers/hid/hid-multitouch.c
+++ b/drivers/hid/hid-multitouch.c
@@ -81,6 +81,11 @@ MODULE_LICENSE("GPL");
 
 #define MT_BUTTONTYPE_CLICKPAD		0
 
+enum latency_mode {
+	HID_LATENCY_NORMAL = 0,
+	HID_LATENCY_HIGH = 1,
+};
+
 #define MT_IO_FLAGS_RUNNING		0
 #define MT_IO_FLAGS_ACTIVE_SLOTS	1
 #define MT_IO_FLAGS_PENDING_SLOTS	2
@@ -1156,7 +1161,10 @@ static void mt_report(struct hid_device *hid, struct hid_report *report)
 
 static bool mt_need_to_apply_feature(struct hid_device *hdev,
 				     struct hid_field *field,
-				     struct hid_usage *usage)
+				     struct hid_usage *usage,
+				     enum latency_mode latency,
+				     bool surface_switch,
+				     bool button_switch)
 {
 	struct mt_device *td = hid_get_drvdata(hdev);
 	struct mt_class *cls = &td->mtclass;
@@ -1195,12 +1203,25 @@ static bool mt_need_to_apply_feature(struct hid_device *hdev,
 			}
 		}
 		break;
+
+	case HID_DG_LATENCYMODE:
+		field->value[index] = latency;
+		return 1;
+
+	case HID_DG_SURFACESWITCH:
+		field->value[index] = surface_switch;
+		return 1;
+
+	case HID_DG_BUTTONSWITCH:
+		field->value[index] = button_switch;
+		return 1;
 	}
 
 	return false; /* no need to update the report */
 }
 
-static void mt_set_modes(struct hid_device *hdev)
+static void mt_set_modes(struct hid_device *hdev, enum latency_mode latency,
+			 bool surface_switch, bool button_switch)
 {
 	struct hid_report_enum *rep_enum;
 	struct hid_report *rep;
@@ -1222,7 +1243,10 @@ static void mt_set_modes(struct hid_device *hdev)
 
 				if (mt_need_to_apply_feature(hdev,
 							     rep->field[i],
-							     usage))
+							     usage,
+							     latency,
+							     surface_switch,
+							     button_switch))
 					update_report = true;
 			}
 		}
@@ -1467,7 +1491,7 @@ static int mt_probe(struct hid_device *hdev, const struct hid_device_id *id)
 		dev_warn(&hdev->dev, "Cannot allocate sysfs group for %s\n",
 				hdev->name);
 
-	mt_set_modes(hdev);
+	mt_set_modes(hdev, HID_LATENCY_NORMAL, true, true);
 
 	/* release .fields memory as it is not used anymore */
 	devm_kfree(&hdev->dev, td->fields);
@@ -1480,7 +1504,7 @@ static int mt_probe(struct hid_device *hdev, const struct hid_device_id *id)
 static int mt_reset_resume(struct hid_device *hdev)
 {
 	mt_release_contacts(hdev);
-	mt_set_modes(hdev);
+	mt_set_modes(hdev, HID_LATENCY_NORMAL, true, true);
 	return 0;
 }
 
diff --git a/include/linux/hid.h b/include/linux/hid.h
index d3bd83d9127f..d65ce4ab82d6 100644
--- a/include/linux/hid.h
+++ b/include/linux/hid.h
@@ -292,9 +292,12 @@ struct hid_item {
 #define HID_DG_CONTACTCOUNT	0x000d0054
 #define HID_DG_CONTACTMAX	0x000d0055
 #define HID_DG_SCANTIME		0x000d0056
+#define HID_DG_SURFACESWITCH	0x000d0057
+#define HID_DG_BUTTONSWITCH	0x000d0058
 #define HID_DG_BUTTONTYPE	0x000d0059
 #define HID_DG_BARRELSWITCH2	0x000d005a
 #define HID_DG_TOOLSERIALNUMBER	0x000d005b
+#define HID_DG_LATENCYMODE	0x000d0060
 
 #define HID_VD_ASUS_CUSTOM_MEDIA_KEYS	0xff310076
 /*
-- 
2.14.3

^ permalink raw reply related

* [PATCH v2 5/6] HID: multitouch: simplify the settings of the various features
From: Benjamin Tissoires @ 2018-04-24  8:04 UTC (permalink / raw)
  To: Jiri Kosina
  Cc: Dmitry Torokhov, Peter Hutterer, Mario.Limonciello, linux-input,
	linux-kernel, Benjamin Tissoires
In-Reply-To: <20180424080437.21367-1-benjamin.tissoires@redhat.com>

The Win8 spec also declare other features we want to support:
latency and surface and button switches.

Though it doesn't seem we need to activate those by default, we have been
proved in the past that manufacturers rely on the Windows driver behavior
so we better mimic it to prevent further issues.

The current way of setting the features is cumbersome. It avoids iterating
over the list of features, but the way we store/retrieve the data just
doesn't scale with more than two values.

So iterate over the features when we decide to switch on the device and
make it simpler to extend.

Signed-off-by: Benjamin Tissoires <benjamin.tissoires@redhat.com>
---
 drivers/hid/hid-multitouch.c | 131 ++++++++++++++++++++-----------------------
 1 file changed, 60 insertions(+), 71 deletions(-)

diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c
index 43784d31a1a3..8878de9eedba 100644
--- a/drivers/hid/hid-multitouch.c
+++ b/drivers/hid/hid-multitouch.c
@@ -127,11 +127,7 @@ struct mt_device {
 	int left_button_state;	/* left button state */
 	unsigned last_slot_field;	/* the last field of a slot */
 	unsigned mt_report_id;	/* the report ID of the multitouch device */
-	__s16 inputmode;	/* InputMode HID feature, -1 if non-existent */
-	__s16 inputmode_index;	/* InputMode HID feature index in the report */
-	__s16 maxcontact_report_id;	/* Maximum Contact Number HID feature,
-				   -1 if non-existent */
-	__u8 inputmode_value;  /* InputMode HID feature value */
+	__u8 inputmode_value;	/* InputMode HID feature value */
 	__u8 num_received;	/* how many contacts we received */
 	__u8 num_expected;	/* expected last contact index */
 	__u8 maxcontacts;
@@ -415,32 +411,9 @@ static void mt_feature_mapping(struct hid_device *hdev,
 	struct mt_device *td = hid_get_drvdata(hdev);
 
 	switch (usage->hid) {
-	case HID_DG_INPUTMODE:
-		/* Ignore if value index is out of bounds. */
-		if (usage->usage_index >= field->report_count) {
-			dev_err(&hdev->dev, "HID_DG_INPUTMODE out of range\n");
-			break;
-		}
-
-		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:
 		mt_get_feature(hdev, field->report);
 
-		td->maxcontact_report_id = field->report->id;
 		td->maxcontacts = field->value[0];
 		if (!td->maxcontacts &&
 		    field->logical_maximum <= MT_MAX_MAXCONTACT)
@@ -1181,61 +1154,81 @@ static void mt_report(struct hid_device *hid, struct hid_report *report)
 		input_sync(field->hidinput->input);
 }
 
-static void mt_set_input_mode(struct hid_device *hdev)
+static bool mt_need_to_apply_feature(struct hid_device *hdev,
+				     struct hid_field *field,
+				     struct hid_usage *usage)
 {
 	struct mt_device *td = hid_get_drvdata(hdev);
-	struct hid_report *r;
-	struct hid_report_enum *re;
 	struct mt_class *cls = &td->mtclass;
+	struct hid_report *report = field->report;
+	unsigned int index = usage->usage_index;
 	char *buf;
 	u32 report_len;
+	int max;
 
-	if (td->inputmode < 0)
-		return;
-
-	re = &(hdev->report_enum[HID_FEATURE_REPORT]);
-	r = re->report_id_hash[td->inputmode];
-	if (r) {
+	switch (usage->hid) {
+	case HID_DG_INPUTMODE:
 		if (cls->quirks & MT_QUIRK_FORCE_GET_FEATURE) {
-			report_len = hid_report_len(r);
-			buf = hid_alloc_report_buf(r, GFP_KERNEL);
+			report_len = hid_report_len(report);
+			buf = hid_alloc_report_buf(report, GFP_KERNEL);
 			if (!buf) {
-				hid_err(hdev, "failed to allocate buffer for report\n");
-				return;
+				hid_err(hdev,
+					"failed to allocate buffer for report\n");
+				return false;
 			}
-			hid_hw_raw_request(hdev, r->id, buf, report_len,
+			hid_hw_raw_request(hdev, report->id, buf, report_len,
 					   HID_FEATURE_REPORT,
 					   HID_REQ_GET_REPORT);
 			kfree(buf);
 		}
-		r->field[0]->value[td->inputmode_index] = td->inputmode_value;
-		hid_hw_request(hdev, r, HID_REQ_SET_REPORT);
-	}
-}
 
-static void mt_set_maxcontacts(struct hid_device *hdev)
-{
-	struct mt_device *td = hid_get_drvdata(hdev);
-	struct hid_report *r;
-	struct hid_report_enum *re;
-	int fieldmax, max;
+		field->value[index] = td->inputmode_value;
+		return true;
 
-	if (td->maxcontact_report_id < 0)
-		return;
+	case HID_DG_CONTACTMAX:
+		if (td->mtclass.maxcontacts) {
+			max = min_t(int, field->logical_maximum,
+				    td->mtclass.maxcontacts);
+			if (field->value[index] != max) {
+				field->value[index] = max;
+				return true;
+			}
+		}
+		break;
+	}
 
-	if (!td->mtclass.maxcontacts)
-		return;
+	return false; /* no need to update the report */
+}
 
-	re = &hdev->report_enum[HID_FEATURE_REPORT];
-	r = re->report_id_hash[td->maxcontact_report_id];
-	if (r) {
-		max = td->mtclass.maxcontacts;
-		fieldmax = r->field[0]->logical_maximum;
-		max = min(fieldmax, max);
-		if (r->field[0]->value[0] != max) {
-			r->field[0]->value[0] = max;
-			hid_hw_request(hdev, r, HID_REQ_SET_REPORT);
+static void mt_set_modes(struct hid_device *hdev)
+{
+	struct hid_report_enum *rep_enum;
+	struct hid_report *rep;
+	struct hid_usage *usage;
+	int i, j;
+	bool update_report;
+
+	rep_enum = &hdev->report_enum[HID_FEATURE_REPORT];
+	list_for_each_entry(rep, &rep_enum->report_list, list) {
+		update_report = false;
+
+		for (i = 0; i < rep->maxfield; i++) {
+			/* Ignore if report count is out of bounds. */
+			if (rep->field[i]->report_count < 1)
+				continue;
+
+			for (j = 0; j < rep->field[i]->maxusage; j++) {
+				usage = &rep->field[i]->usage[j];
+
+				if (mt_need_to_apply_feature(hdev,
+							     rep->field[i],
+							     usage))
+					update_report = true;
+			}
 		}
+
+		if (update_report)
+			hid_hw_request(hdev, rep, HID_REQ_SET_REPORT);
 	}
 }
 
@@ -1428,8 +1421,6 @@ static int mt_probe(struct hid_device *hdev, const struct hid_device_id *id)
 	}
 	td->hdev = hdev;
 	td->mtclass = *mtclass;
-	td->inputmode = -1;
-	td->maxcontact_report_id = -1;
 	td->inputmode_value = MT_INPUTMODE_TOUCHSCREEN;
 	td->cc_index = -1;
 	td->scantime_index = -1;
@@ -1476,8 +1467,7 @@ static int mt_probe(struct hid_device *hdev, const struct hid_device_id *id)
 		dev_warn(&hdev->dev, "Cannot allocate sysfs group for %s\n",
 				hdev->name);
 
-	mt_set_maxcontacts(hdev);
-	mt_set_input_mode(hdev);
+	mt_set_modes(hdev);
 
 	/* release .fields memory as it is not used anymore */
 	devm_kfree(&hdev->dev, td->fields);
@@ -1490,8 +1480,7 @@ static int mt_probe(struct hid_device *hdev, const struct hid_device_id *id)
 static int mt_reset_resume(struct hid_device *hdev)
 {
 	mt_release_contacts(hdev);
-	mt_set_maxcontacts(hdev);
-	mt_set_input_mode(hdev);
+	mt_set_modes(hdev);
 	return 0;
 }
 
-- 
2.14.3

^ permalink raw reply related

* [PATCH v2 4/6] HID: multitouch: make use of HID_QUIRK_INPUT_PER_APP
From: Benjamin Tissoires @ 2018-04-24  8:04 UTC (permalink / raw)
  To: Jiri Kosina
  Cc: Dmitry Torokhov, Peter Hutterer, Mario.Limonciello, linux-input,
	linux-kernel, Benjamin Tissoires
In-Reply-To: <20180424080437.21367-1-benjamin.tissoires@redhat.com>

We now have HID_QUIRK_INPUT_PER_APPLICATION that splits the devices
into several devices. This helps us as we can now rely on hid-input
to set the names for us.

Also, this helps removing some magical numbers '0' when calling
.input_configured().

The only thing to take care of is that the field .report in struct
hid_input is now null. We need to iterate over the full list of
reports attached to a hid_input.

This is required for some Advanced Silicon touchscreen to correctly apply
the HID_QUIRK_INPUT_PER_APPLICATION as they have 2 reports associated
with the hidinput node. One contains the Input data, the other one
contains the Output data.

Signed-off-by: Benjamin Tissoires <benjamin.tissoires@redhat.com>
---
 drivers/hid/hid-multitouch.c | 72 ++++++++++++++++++++------------------------
 1 file changed, 33 insertions(+), 39 deletions(-)

diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c
index dad2fbb0e3f8..43784d31a1a3 100644
--- a/drivers/hid/hid-multitouch.c
+++ b/drivers/hid/hid-multitouch.c
@@ -1274,54 +1274,48 @@ static int mt_input_configured(struct hid_device *hdev, struct hid_input *hi)
 	struct mt_device *td = hid_get_drvdata(hdev);
 	char *name;
 	const char *suffix = NULL;
-	struct hid_field *field = hi->report->field[0];
+	unsigned int application = 0;
+	struct hid_report *report;
 	int ret;
 
-	if (hi->report->id == td->mt_report_id) {
-		ret = mt_touch_input_configured(hdev, hi);
-		if (ret)
-			return ret;
+	list_for_each_entry(report, &hi->reports, hidinput_list) {
+		application = report->application;
+		if (report->id == td->mt_report_id) {
+			ret = mt_touch_input_configured(hdev, hi);
+			if (ret)
+				return ret;
+		}
+
+		/*
+		 * some egalax touchscreens have "application == DG_TOUCHSCREEN"
+		 * for the stylus. Check this first, and then rely on
+		 * the application field.
+		 */
+		if (report->field[0]->physical == HID_DG_STYLUS) {
+			suffix = "Pen";
+			/* force BTN_STYLUS to allow tablet matching in udev */
+			__set_bit(BTN_STYLUS, hi->input->keybit);
+		}
 	}
 
-	/*
-	 * some egalax touchscreens have "application == HID_DG_TOUCHSCREEN"
-	 * for the stylus. Check this first, and then rely on the application
-	 * field.
-	 */
-	if (hi->report->field[0]->physical == HID_DG_STYLUS) {
-		suffix = "Pen";
-		/* force BTN_STYLUS to allow tablet matching in udev */
-		__set_bit(BTN_STYLUS, hi->input->keybit);
-	} else {
-		switch (field->application) {
+	if (!suffix) {
+		switch (application) {
 		case HID_GD_KEYBOARD:
-			suffix = "Keyboard";
-			break;
 		case HID_GD_KEYPAD:
-			suffix = "Keypad";
-			break;
 		case HID_GD_MOUSE:
-			suffix = "Mouse";
-			break;
-		case HID_DG_STYLUS:
-			suffix = "Pen";
-			/* force BTN_STYLUS to allow tablet matching in udev */
-			__set_bit(BTN_STYLUS, hi->input->keybit);
-			break;
-		case HID_DG_TOUCHSCREEN:
-			/* we do not set suffix = "Touchscreen" */
-			break;
 		case HID_DG_TOUCHPAD:
-			suffix = "Touchpad";
-			break;
 		case HID_GD_SYSTEM_CONTROL:
-			suffix = "System Control";
-			break;
 		case HID_CP_CONSUMER_CONTROL:
-			suffix = "Consumer Control";
-			break;
 		case HID_GD_WIRELESS_RADIO_CTLS:
-			suffix = "Wireless Radio Control";
+			/* already handled by hid core */
+			break;
+		case HID_DG_TOUCHSCREEN:
+			/* we do not set suffix = "Touchscreen" */
+			hi->input->name = hdev->name;
+			break;
+		case HID_DG_STYLUS:
+			/* force BTN_STYLUS to allow tablet matching in udev */
+			__set_bit(BTN_STYLUS, hi->input->keybit);
 			break;
 		case HID_VD_ASUS_CUSTOM_MEDIA_KEYS:
 			suffix = "Custom Media Keys";
@@ -1459,10 +1453,10 @@ static int mt_probe(struct hid_device *hdev, const struct hid_device_id *id)
 
 	/*
 	 * This allows the driver to handle different input sensors
-	 * that emits events through different reports on the same HID
+	 * that emits events through different applications on the same HID
 	 * device.
 	 */
-	hdev->quirks |= HID_QUIRK_MULTI_INPUT;
+	hdev->quirks |= HID_QUIRK_INPUT_PER_APP;
 
 	timer_setup(&td->release_timer, mt_expired_timeout, 0);
 
-- 
2.14.3

^ permalink raw reply related

* [PATCH v2 3/6] HID: input: append a suffix matching the application
From: Benjamin Tissoires @ 2018-04-24  8:04 UTC (permalink / raw)
  To: Jiri Kosina
  Cc: Dmitry Torokhov, Peter Hutterer, Mario.Limonciello, linux-input,
	linux-kernel, Benjamin Tissoires
In-Reply-To: <20180424080437.21367-1-benjamin.tissoires@redhat.com>

Given that we create one input node per application, we should name
the input node accordingly to not lose userspace.

Signed-off-by: Benjamin Tissoires <benjamin.tissoires@redhat.com>
---
 drivers/hid/hid-input.c | 67 +++++++++++++++++++++++++++++++++++++++++++------
 include/linux/hid.h     |  1 +
 2 files changed, 60 insertions(+), 8 deletions(-)

diff --git a/drivers/hid/hid-input.c b/drivers/hid/hid-input.c
index 361643683c08..ab93dd5927c3 100644
--- a/drivers/hid/hid-input.c
+++ b/drivers/hid/hid-input.c
@@ -1510,15 +1510,56 @@ static void report_features(struct hid_device *hid)
 		}
 }
 
-static struct hid_input *hidinput_allocate(struct hid_device *hid)
+static struct hid_input *hidinput_allocate(struct hid_device *hid,
+					   unsigned int application)
 {
 	struct hid_input *hidinput = kzalloc(sizeof(*hidinput), GFP_KERNEL);
 	struct input_dev *input_dev = input_allocate_device();
-	if (!hidinput || !input_dev) {
-		kfree(hidinput);
-		input_free_device(input_dev);
-		hid_err(hid, "Out of memory during hid input probe\n");
-		return NULL;
+	const char *suffix = NULL;
+
+	if (!hidinput || !input_dev)
+		goto fail;
+
+	if ((hid->quirks & HID_QUIRK_INPUT_PER_APP) &&
+	    hid->maxapplication > 1) {
+		switch (application) {
+		case HID_GD_KEYBOARD:
+			suffix = "Keyboard";
+			break;
+		case HID_GD_KEYPAD:
+			suffix = "Keypad";
+			break;
+		case HID_GD_MOUSE:
+			suffix = "Mouse";
+			break;
+		case HID_DG_STYLUS:
+			suffix = "Pen";
+			break;
+		case HID_DG_TOUCHSCREEN:
+			suffix = "Touchscreen";
+			break;
+		case HID_DG_TOUCHPAD:
+			suffix = "Touchpad";
+			break;
+		case HID_GD_SYSTEM_CONTROL:
+			suffix = "System Control";
+			break;
+		case HID_CP_CONSUMER_CONTROL:
+			suffix = "Consumer Control";
+			break;
+		case HID_GD_WIRELESS_RADIO_CTLS:
+			suffix = "Wireless Radio Control";
+			break;
+		default:
+			break;
+		}
+	}
+
+	if (suffix) {
+		hidinput->name = kasprintf(GFP_KERNEL, "%s %s",
+					   hid->name, suffix);
+		if (!hidinput->name)
+			goto fail;
 	}
 
 	input_set_drvdata(input_dev, hid);
@@ -1528,7 +1569,7 @@ static struct hid_input *hidinput_allocate(struct hid_device *hid)
 	input_dev->setkeycode = hidinput_setkeycode;
 	input_dev->getkeycode = hidinput_getkeycode;
 
-	input_dev->name = hid->name;
+	input_dev->name = hidinput->name ? hidinput->name : hid->name;
 	input_dev->phys = hid->phys;
 	input_dev->uniq = hid->uniq;
 	input_dev->id.bustype = hid->bus;
@@ -1543,6 +1584,12 @@ static struct hid_input *hidinput_allocate(struct hid_device *hid)
 	INIT_LIST_HEAD(&hidinput->reports);
 
 	return hidinput;
+
+fail:
+	kfree(hidinput);
+	input_free_device(input_dev);
+	hid_err(hid, "Out of memory during hid input probe\n");
+	return NULL;
 }
 
 static bool hidinput_has_been_populated(struct hid_input *hidinput)
@@ -1588,6 +1635,7 @@ static void hidinput_cleanup_hidinput(struct hid_device *hid,
 
 	list_del(&hidinput->list);
 	input_free_device(hidinput->input);
+	kfree(hidinput->name);
 
 	for (k = HID_INPUT_REPORT; k <= HID_OUTPUT_REPORT; k++) {
 		if (k == HID_OUTPUT_REPORT &&
@@ -1656,6 +1704,7 @@ int hidinput_connect(struct hid_device *hid, unsigned int force)
 	struct hid_driver *drv = hid->driver;
 	struct hid_report *report;
 	struct hid_input *next, *hidinput = NULL;
+	unsigned int application;
 	int i, k;
 
 	INIT_LIST_HEAD(&hid->inputs);
@@ -1688,6 +1737,8 @@ int hidinput_connect(struct hid_device *hid, unsigned int force)
 			if (!report->maxfield)
 				continue;
 
+			application = report->application;
+
 			/*
 			 * Find the previous hidinput report attached
 			 * to this report id.
@@ -1699,7 +1750,7 @@ int hidinput_connect(struct hid_device *hid, unsigned int force)
 				hidinput = hidinput_match_application(report);
 
 			if (!hidinput) {
-				hidinput = hidinput_allocate(hid);
+				hidinput = hidinput_allocate(hid, application);
 				if (!hidinput)
 					goto out_unwind;
 			}
diff --git a/include/linux/hid.h b/include/linux/hid.h
index d5ebeacc3b57..d3bd83d9127f 100644
--- a/include/linux/hid.h
+++ b/include/linux/hid.h
@@ -512,6 +512,7 @@ struct hid_input {
 	struct list_head list;
 	struct hid_report *report;
 	struct input_dev *input;
+	const char *name;
 	bool registered;
 	struct list_head reports;	/* the list of reports */
 };
-- 
2.14.3

^ permalink raw reply related

* [PATCH v2 2/6] HID: generic: create one input report per application type
From: Benjamin Tissoires @ 2018-04-24  8:04 UTC (permalink / raw)
  To: Jiri Kosina
  Cc: Dmitry Torokhov, Peter Hutterer, Mario.Limonciello, linux-input,
	linux-kernel, Benjamin Tissoires
In-Reply-To: <20180424080437.21367-1-benjamin.tissoires@redhat.com>

It is not a good idea to try to fit all types of applications in the
same input report. There are a lot of devices that are needing
the quirk HID_MULTI_INPUT but this quirk doesn't match the actual HID
description as it is based on the report ID.

Given that most devices with MULTI_INPUT I can think of split nicely
the devices inputs into application, it is a good thing to split the
devices by default based on this assumption.

Also make hid-multitouch following this rule, to not have to deal
with too many input created.

While we are at it, fix some checkpatch complaints about converting
'unsigned' to 'unsigned int'.

Signed-off-by: Benjamin Tissoires <benjamin.tissoires@redhat.com>
---
 drivers/hid/hid-core.c       | 19 +++++++++++++------
 drivers/hid/hid-generic.c    | 15 +++++++++++++++
 drivers/hid/hid-gfrm.c       |  2 +-
 drivers/hid/hid-input.c      | 17 +++++++++++++++++
 drivers/hid/hid-magicmouse.c |  6 +++---
 include/linux/hid.h          | 10 +++++++---
 6 files changed, 56 insertions(+), 13 deletions(-)

diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c
index 5d7cc6bbbac6..68819106f4fc 100644
--- a/drivers/hid/hid-core.c
+++ b/drivers/hid/hid-core.c
@@ -57,7 +57,9 @@ MODULE_PARM_DESC(ignore_special_drivers, "Ignore any special drivers and handle
  * Register a new report for a device.
  */
 
-struct hid_report *hid_register_report(struct hid_device *device, unsigned type, unsigned id)
+struct hid_report *hid_register_report(struct hid_device *device,
+				       unsigned int type, unsigned int id,
+				       unsigned int application)
 {
 	struct hid_report_enum *report_enum = device->report_enum + type;
 	struct hid_report *report;
@@ -78,6 +80,7 @@ struct hid_report *hid_register_report(struct hid_device *device, unsigned type,
 	report->type = type;
 	report->size = 0;
 	report->device = device;
+	report->application = application;
 	report_enum->report_id_hash[id] = report;
 
 	list_add_tail(&report->list, &report_enum->report_list);
@@ -221,11 +224,15 @@ static int hid_add_field(struct hid_parser *parser, unsigned report_type, unsign
 {
 	struct hid_report *report;
 	struct hid_field *field;
-	unsigned usages;
-	unsigned offset;
-	unsigned i;
+	unsigned int usages;
+	unsigned int offset;
+	unsigned int i;
+	unsigned int application;
+
+	application = hid_lookup_collection(parser, HID_COLLECTION_APPLICATION);
 
-	report = hid_register_report(parser->device, report_type, parser->global.report_id);
+	report = hid_register_report(parser->device, report_type,
+				     parser->global.report_id, application);
 	if (!report) {
 		hid_err(parser->device, "hid_register_report failed\n");
 		return -1;
@@ -259,7 +266,7 @@ static int hid_add_field(struct hid_parser *parser, unsigned report_type, unsign
 
 	field->physical = hid_lookup_collection(parser, HID_COLLECTION_PHYSICAL);
 	field->logical = hid_lookup_collection(parser, HID_COLLECTION_LOGICAL);
-	field->application = hid_lookup_collection(parser, HID_COLLECTION_APPLICATION);
+	field->application = application;
 
 	for (i = 0; i < usages; i++) {
 		unsigned j = i;
diff --git a/drivers/hid/hid-generic.c b/drivers/hid/hid-generic.c
index c25b4718de44..3b6eccbc2519 100644
--- a/drivers/hid/hid-generic.c
+++ b/drivers/hid/hid-generic.c
@@ -56,6 +56,20 @@ static bool hid_generic_match(struct hid_device *hdev,
 	return true;
 }
 
+static int hid_generic_probe(struct hid_device *hdev,
+			     const struct hid_device_id *id)
+{
+	int ret;
+
+	hdev->quirks |= HID_QUIRK_INPUT_PER_APP;
+
+	ret = hid_parse(hdev);
+	if (ret)
+		return ret;
+
+	return hid_hw_start(hdev, HID_CONNECT_DEFAULT);
+}
+
 static const struct hid_device_id hid_table[] = {
 	{ HID_DEVICE(HID_BUS_ANY, HID_GROUP_ANY, HID_ANY_ID, HID_ANY_ID) },
 	{ }
@@ -66,6 +80,7 @@ static struct hid_driver hid_generic = {
 	.name = "hid-generic",
 	.id_table = hid_table,
 	.match = hid_generic_match,
+	.probe = hid_generic_probe,
 };
 module_hid_driver(hid_generic);
 
diff --git a/drivers/hid/hid-gfrm.c b/drivers/hid/hid-gfrm.c
index 075b1c020846..cf477f8c8f4c 100644
--- a/drivers/hid/hid-gfrm.c
+++ b/drivers/hid/hid-gfrm.c
@@ -116,7 +116,7 @@ static int gfrm_probe(struct hid_device *hdev, const struct hid_device_id *id)
 		 * those reports reach gfrm_raw_event() from hid_input_report().
 		 */
 		if (!hid_register_report(hdev, HID_INPUT_REPORT,
-					 GFRM100_SEARCH_KEY_REPORT_ID)) {
+					 GFRM100_SEARCH_KEY_REPORT_ID, 0)) {
 			ret = -ENOMEM;
 			goto done;
 		}
diff --git a/drivers/hid/hid-input.c b/drivers/hid/hid-input.c
index 62e42664955e..361643683c08 100644
--- a/drivers/hid/hid-input.c
+++ b/drivers/hid/hid-input.c
@@ -1620,6 +1620,20 @@ static struct hid_input *hidinput_match(struct hid_report *report)
 	return NULL;
 }
 
+static struct hid_input *hidinput_match_application(struct hid_report *report)
+{
+	struct hid_device *hid = report->device;
+	struct hid_input *hidinput;
+
+	list_for_each_entry(hidinput, &hid->inputs, list) {
+		if (hidinput->report &&
+		    hidinput->report->application == report->application)
+			return hidinput;
+	}
+
+	return NULL;
+}
+
 static inline void hidinput_configure_usages(struct hid_input *hidinput,
 					     struct hid_report *report)
 {
@@ -1680,6 +1694,9 @@ int hidinput_connect(struct hid_device *hid, unsigned int force)
 			 */
 			if (hid->quirks & HID_QUIRK_MULTI_INPUT)
 				hidinput = hidinput_match(report);
+			else if (hid->maxapplication > 1 &&
+				 (hid->quirks & HID_QUIRK_INPUT_PER_APP))
+				hidinput = hidinput_match_application(report);
 
 			if (!hidinput) {
 				hidinput = hidinput_allocate(hid);
diff --git a/drivers/hid/hid-magicmouse.c b/drivers/hid/hid-magicmouse.c
index 42ed887ba0be..b454c4386157 100644
--- a/drivers/hid/hid-magicmouse.c
+++ b/drivers/hid/hid-magicmouse.c
@@ -531,12 +531,12 @@ static int magicmouse_probe(struct hid_device *hdev,
 
 	if (id->product == USB_DEVICE_ID_APPLE_MAGICMOUSE)
 		report = hid_register_report(hdev, HID_INPUT_REPORT,
-			MOUSE_REPORT_ID);
+			MOUSE_REPORT_ID, 0);
 	else { /* USB_DEVICE_ID_APPLE_MAGICTRACKPAD */
 		report = hid_register_report(hdev, HID_INPUT_REPORT,
-			TRACKPAD_REPORT_ID);
+			TRACKPAD_REPORT_ID, 0);
 		report = hid_register_report(hdev, HID_INPUT_REPORT,
-			DOUBLE_REPORT_ID);
+			DOUBLE_REPORT_ID, 0);
 	}
 
 	if (!report) {
diff --git a/include/linux/hid.h b/include/linux/hid.h
index e1ec7f91f926..d5ebeacc3b57 100644
--- a/include/linux/hid.h
+++ b/include/linux/hid.h
@@ -341,6 +341,7 @@ struct hid_item {
 /* BIT(8) reserved for backward compatibility, was HID_QUIRK_NO_EMPTY_INPUT */
 /* BIT(9) reserved for backward compatibility, was NO_INIT_INPUT_REPORTS */
 #define HID_QUIRK_ALWAYS_POLL			BIT(10)
+#define HID_QUIRK_INPUT_PER_APP			BIT(11)
 #define HID_QUIRK_SKIP_OUTPUT_REPORTS		BIT(16)
 #define HID_QUIRK_SKIP_OUTPUT_REPORT_ID		BIT(17)
 #define HID_QUIRK_NO_OUTPUT_REPORTS_ON_INTR_EP	BIT(18)
@@ -465,8 +466,9 @@ struct hid_field {
 struct hid_report {
 	struct list_head list;
 	struct list_head hidinput_list;
-	unsigned id;					/* id of this report */
-	unsigned type;					/* report type */
+	unsigned int id;				/* id of this report */
+	unsigned int type;				/* report type */
+	unsigned int application;			/* application usage for this report */
 	struct hid_field *field[HID_MAX_FIELDS];	/* fields of the report */
 	unsigned maxfield;				/* maximum valid field index */
 	unsigned size;					/* size of the report (bits) */
@@ -868,7 +870,9 @@ void hid_output_report(struct hid_report *report, __u8 *data);
 void __hid_request(struct hid_device *hid, struct hid_report *rep, int reqtype);
 u8 *hid_alloc_report_buf(struct hid_report *report, gfp_t flags);
 struct hid_device *hid_allocate_device(void);
-struct hid_report *hid_register_report(struct hid_device *device, unsigned type, unsigned id);
+struct hid_report *hid_register_report(struct hid_device *device,
+				       unsigned int type, unsigned int id,
+				       unsigned int application);
 int hid_parse_report(struct hid_device *hid, __u8 *start, unsigned size);
 struct hid_report *hid_validate_values(struct hid_device *hid,
 				       unsigned int type, unsigned int id,
-- 
2.14.3

^ permalink raw reply related

* [PATCH v2 1/6] HID: store the full list of reports in the hidinput
From: Benjamin Tissoires @ 2018-04-24  8:04 UTC (permalink / raw)
  To: Jiri Kosina
  Cc: Dmitry Torokhov, Peter Hutterer, Mario.Limonciello, linux-input,
	linux-kernel, Benjamin Tissoires
In-Reply-To: <20180424080437.21367-1-benjamin.tissoires@redhat.com>

We were only storing the report in case of QUIRK_MULTI_INPUT.
It is interesting for the upcoming  HID_QUIRK_INPUT_PER_APP to also
store the full list of reports that are attached to it.

We need the full list because a device (Advanced Silicon has some)
might want to use a different report ID for the Input reports and
the Output reports. Storing the full list allows the drivers to
have all the data.

Signed-off-by: Benjamin Tissoires <benjamin.tissoires@redhat.com>
---
 drivers/hid/hid-input.c | 6 ++++++
 include/linux/hid.h     | 2 ++
 2 files changed, 8 insertions(+)

diff --git a/drivers/hid/hid-input.c b/drivers/hid/hid-input.c
index a8a33e56b43e..62e42664955e 100644
--- a/drivers/hid/hid-input.c
+++ b/drivers/hid/hid-input.c
@@ -1536,9 +1536,12 @@ static struct hid_input *hidinput_allocate(struct hid_device *hid)
 	input_dev->id.product = hid->product;
 	input_dev->id.version = hid->version;
 	input_dev->dev.parent = &hid->dev;
+
 	hidinput->input = input_dev;
 	list_add_tail(&hidinput->list, &hid->inputs);
 
+	INIT_LIST_HEAD(&hidinput->reports);
+
 	return hidinput;
 }
 
@@ -1688,6 +1691,9 @@ int hidinput_connect(struct hid_device *hid, unsigned int force)
 
 			if (hid->quirks & HID_QUIRK_MULTI_INPUT)
 				hidinput->report = report;
+
+			list_add_tail(&report->hidinput_list,
+				      &hidinput->reports);
 		}
 	}
 
diff --git a/include/linux/hid.h b/include/linux/hid.h
index 0a8d5c320b6c..e1ec7f91f926 100644
--- a/include/linux/hid.h
+++ b/include/linux/hid.h
@@ -464,6 +464,7 @@ struct hid_field {
 
 struct hid_report {
 	struct list_head list;
+	struct list_head hidinput_list;
 	unsigned id;					/* id of this report */
 	unsigned type;					/* report type */
 	struct hid_field *field[HID_MAX_FIELDS];	/* fields of the report */
@@ -510,6 +511,7 @@ struct hid_input {
 	struct hid_report *report;
 	struct input_dev *input;
 	bool registered;
+	struct list_head reports;	/* the list of reports */
 };
 
 enum hid_type {
-- 
2.14.3

^ permalink raw reply related

* [PATCH v2 0/6] HID: input cleanups and mt additions
From: Benjamin Tissoires @ 2018-04-24  8:04 UTC (permalink / raw)
  To: Jiri Kosina
  Cc: Dmitry Torokhov, Peter Hutterer, Mario.Limonciello, linux-input,
	linux-kernel, Benjamin Tissoires

Hi Jiri,

following the thread about the 'not incrementing ABS_MISC', here is the
actual submission of the series.

Compared to the 2 patches I sent last week, there are a few more:
- patch 1 needed to be added or some (all?) Advanced Silicon touchscreen
  would fail the tests with HID_QUIRK_INPUT_PER_APPLICATION
- patch 3 is extracted from v1-2/2, as it has grown significantly, still
  because of the same issue with Advanced Silicon panels
- patch 4 is something I had in mind while debugging some other
  not-so-talkative touchpads, because of patch 5
- patch 5 should put us at the same level than the Windows driver now.
  Note that we could unset the features (button/surface reporting, and
  latency during suspend, but not sure it helps that much. We should probably
  test the current consumption with and without)

The series has been tested against regressions thanks to my new hid test suite
https://github.com/bentiss/hid-tools (I rewrote hid-replay in python and hook
up python tests). I also used the loaner from Dell (thanks Mario!), and XPS
9360 that has both touchscreen and touchpad, and on which the touchpad has the
new features I implemented here.

Cheers,
Benjamin


Benjamin Tissoires (6):
  HID: store the full list of reports in the hidinput
  HID: generic: create one input report per application type
  HID: input: append a suffix matching the application
  HID: multitouch: make use of HID_QUIRK_INPUT_PER_APP
  HID: multitouch: simplify the settings of the various features
  HID: multitouch: implement precision touchpad latency and switches

 drivers/hid/hid-core.c       |  19 ++--
 drivers/hid/hid-generic.c    |  15 +++
 drivers/hid/hid-gfrm.c       |   2 +-
 drivers/hid/hid-input.c      |  90 +++++++++++++++--
 drivers/hid/hid-magicmouse.c |   6 +-
 drivers/hid/hid-multitouch.c | 227 ++++++++++++++++++++++---------------------
 include/linux/hid.h          |  16 ++-
 7 files changed, 244 insertions(+), 131 deletions(-)

-- 
2.14.3

^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox