* [PATCH] i2c: Prevent runtime suspend of adapter when Host Notify is required
From: Jarkko Nikula @ 2019-04-30 14:23 UTC (permalink / raw)
To: linux-i2c
Cc: Wolfram Sang, Keijo Vaara, linux-input, Bjorn Helgaas,
Rafael J . Wysocki, Jarkko Nikula, stable
Multiple users have reported their Synaptics touchpad has stopped
working between v4.20.1 and v4.20.2 when using SMBus interface.
The culprit for this appeared to be commit c5eb1190074c ("PCI / PM: Allow
runtime PM without callback functions") that fixed the runtime PM for
i2c-i801 SMBus adapter. Those Synaptics touchpad are using i2c-i801
for SMBus communication and testing showed they are able to get back
working by preventing the runtime suspend of adapter.
Normally when i2c-i801 SMBus adapter transmits with the client it resumes
before operation and autosuspends after.
However, if client requires SMBus Host Notify protocol, what those
Synaptics touchpads do, then the host adapter must not go to runtime
suspend since then it cannot process incoming SMBus Host Notify commands
the client may send.
Fix this by keeping I2C/SMBus adapter active in case client requires
Host Notify.
Reported-by: Keijo Vaara <ferdasyn@rocketmail.com>
Link: https://bugzilla.kernel.org/show_bug.cgi?id=203297
Fixes: c5eb1190074c ("PCI / PM: Allow runtime PM without callback functions")
Cc: stable@vger.kernel.org # v4.20+
Signed-off-by: Jarkko Nikula <jarkko.nikula@linux.intel.com>
---
Keijo: could you test this does it fix the issue you reported? This is
practically the same diff I sent earlier what you probably haven't tested yet.
I wanted to send a commitable fix in case it works since I'll be out of
office in a few coming days.
---
drivers/i2c/i2c-core-base.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/drivers/i2c/i2c-core-base.c b/drivers/i2c/i2c-core-base.c
index 38af18645133..8149c9e32b69 100644
--- a/drivers/i2c/i2c-core-base.c
+++ b/drivers/i2c/i2c-core-base.c
@@ -327,6 +327,8 @@ static int i2c_device_probe(struct device *dev)
if (client->flags & I2C_CLIENT_HOST_NOTIFY) {
dev_dbg(dev, "Using Host Notify IRQ\n");
+ /* Keep adapter active when Host Notify is required */
+ pm_runtime_get_sync(&client->adapter->dev);
irq = i2c_smbus_host_notify_to_irq(client);
} else if (dev->of_node) {
irq = of_irq_get_byname(dev->of_node, "irq");
@@ -431,6 +433,8 @@ static int i2c_device_remove(struct device *dev)
device_init_wakeup(&client->dev, false);
client->irq = client->init_irq;
+ if (client->flags & I2C_CLIENT_HOST_NOTIFY)
+ pm_runtime_put(&client->adapter->dev);
return status;
}
--
2.20.1
^ permalink raw reply related
* Re: [PATCH] i2c: Prevent runtime suspend of adapter when Host Notify is required
From: Rafael J. Wysocki @ 2019-04-30 15:42 UTC (permalink / raw)
To: Jarkko Nikula
Cc: linux-i2c, Wolfram Sang, Keijo Vaara, linux-input, Bjorn Helgaas,
Rafael J . Wysocki, Stable
In-Reply-To: <20190430142322.15013-1-jarkko.nikula@linux.intel.com>
On Tue, Apr 30, 2019 at 4:23 PM Jarkko Nikula
<jarkko.nikula@linux.intel.com> wrote:
>
> Multiple users have reported their Synaptics touchpad has stopped
> working between v4.20.1 and v4.20.2 when using SMBus interface.
>
> The culprit for this appeared to be commit c5eb1190074c ("PCI / PM: Allow
> runtime PM without callback functions") that fixed the runtime PM for
> i2c-i801 SMBus adapter. Those Synaptics touchpad are using i2c-i801
> for SMBus communication and testing showed they are able to get back
> working by preventing the runtime suspend of adapter.
>
> Normally when i2c-i801 SMBus adapter transmits with the client it resumes
> before operation and autosuspends after.
>
> However, if client requires SMBus Host Notify protocol, what those
> Synaptics touchpads do, then the host adapter must not go to runtime
> suspend since then it cannot process incoming SMBus Host Notify commands
> the client may send.
>
> Fix this by keeping I2C/SMBus adapter active in case client requires
> Host Notify.
>
> Reported-by: Keijo Vaara <ferdasyn@rocketmail.com>
> Link: https://bugzilla.kernel.org/show_bug.cgi?id=203297
> Fixes: c5eb1190074c ("PCI / PM: Allow runtime PM without callback functions")
> Cc: stable@vger.kernel.org # v4.20+
> Signed-off-by: Jarkko Nikula <jarkko.nikula@linux.intel.com>
Acked-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Or please let me know if you want me to take this.
> ---
> Keijo: could you test this does it fix the issue you reported? This is
> practically the same diff I sent earlier what you probably haven't tested yet.
> I wanted to send a commitable fix in case it works since I'll be out of
> office in a few coming days.
> ---
> drivers/i2c/i2c-core-base.c | 4 ++++
> 1 file changed, 4 insertions(+)
>
> diff --git a/drivers/i2c/i2c-core-base.c b/drivers/i2c/i2c-core-base.c
> index 38af18645133..8149c9e32b69 100644
> --- a/drivers/i2c/i2c-core-base.c
> +++ b/drivers/i2c/i2c-core-base.c
> @@ -327,6 +327,8 @@ static int i2c_device_probe(struct device *dev)
>
> if (client->flags & I2C_CLIENT_HOST_NOTIFY) {
> dev_dbg(dev, "Using Host Notify IRQ\n");
> + /* Keep adapter active when Host Notify is required */
> + pm_runtime_get_sync(&client->adapter->dev);
> irq = i2c_smbus_host_notify_to_irq(client);
> } else if (dev->of_node) {
> irq = of_irq_get_byname(dev->of_node, "irq");
> @@ -431,6 +433,8 @@ static int i2c_device_remove(struct device *dev)
> device_init_wakeup(&client->dev, false);
>
> client->irq = client->init_irq;
> + if (client->flags & I2C_CLIENT_HOST_NOTIFY)
> + pm_runtime_put(&client->adapter->dev);
>
> return status;
> }
> --
> 2.20.1
>
^ permalink raw reply
* [PATCH 1/2] input: edt-ft5x06 - add polled input support
From: Nicolas Saenz Julienne @ 2019-04-30 18:58 UTC (permalink / raw)
To: linux-kernel; +Cc: Nicolas Saenz Julienne, Dmitry Torokhov, linux-input
Some hardware configurations might pass on providing an interrupt line.
In that case there is always the option to use a polled input approach.
This patch adapts the driver for it.
The polled approach is only triggered if no interrupt is provided by the
firmware or platform data.
Signed-off-by: Nicolas Saenz Julienne <nsaenzjulienne@suse.de>
---
drivers/input/touchscreen/edt-ft5x06.c | 100 ++++++++++++++++++-------
1 file changed, 72 insertions(+), 28 deletions(-)
diff --git a/drivers/input/touchscreen/edt-ft5x06.c b/drivers/input/touchscreen/edt-ft5x06.c
index 702bfda7ee77..e58645c72c2f 100644
--- a/drivers/input/touchscreen/edt-ft5x06.c
+++ b/drivers/input/touchscreen/edt-ft5x06.c
@@ -39,6 +39,7 @@
#include <linux/gpio/consumer.h>
#include <linux/input/mt.h>
#include <linux/input/touchscreen.h>
+#include <linux/input-polldev.h>
#include <linux/of_device.h>
#define WORK_REGISTER_THRESHOLD 0x00
@@ -97,6 +98,7 @@ struct edt_reg_addr {
struct edt_ft5x06_ts_data {
struct i2c_client *client;
struct input_dev *input;
+ struct input_polled_dev *poll_dev;
struct touchscreen_properties prop;
u16 num_x;
u16 num_y;
@@ -181,9 +183,8 @@ static bool edt_ft5x06_ts_check_crc(struct edt_ft5x06_ts_data *tsdata,
return true;
}
-static irqreturn_t edt_ft5x06_ts_isr(int irq, void *dev_id)
+static void edt_ft5x06_process(struct edt_ft5x06_ts_data *tsdata)
{
- struct edt_ft5x06_ts_data *tsdata = dev_id;
struct device *dev = &tsdata->client->dev;
u8 cmd;
u8 rdbuf[63];
@@ -210,7 +211,7 @@ static irqreturn_t edt_ft5x06_ts_isr(int irq, void *dev_id)
break;
default:
- goto out;
+ return;
}
memset(rdbuf, 0, sizeof(rdbuf));
@@ -222,7 +223,7 @@ static irqreturn_t edt_ft5x06_ts_isr(int irq, void *dev_id)
if (error) {
dev_err_ratelimited(dev, "Unable to fetch data, error: %d\n",
error);
- goto out;
+ return;
}
/* M09/M12 does not send header or CRC */
@@ -232,11 +233,11 @@ static irqreturn_t edt_ft5x06_ts_isr(int irq, void *dev_id)
dev_err_ratelimited(dev,
"Unexpected header: %02x%02x%02x!\n",
rdbuf[0], rdbuf[1], rdbuf[2]);
- goto out;
+ return;
}
if (!edt_ft5x06_ts_check_crc(tsdata, rdbuf, datalen))
- goto out;
+ return;
}
for (i = 0; i < tsdata->max_support_points; i++) {
@@ -273,11 +274,23 @@ static irqreturn_t edt_ft5x06_ts_isr(int irq, void *dev_id)
input_mt_report_pointer_emulation(tsdata->input, true);
input_sync(tsdata->input);
+}
-out:
+static irqreturn_t edt_ft5x06_ts_isr(int irq, void *dev_id)
+{
+ struct edt_ft5x06_ts_data *tsdata = dev_id;
+
+ edt_ft5x06_process(tsdata);
return IRQ_HANDLED;
}
+static void edt_ft5x06_poll(struct input_polled_dev *dev)
+{
+ struct edt_ft5x06_ts_data *tsdata = dev->private;
+
+ edt_ft5x06_process(tsdata);
+}
+
static int edt_ft5x06_register_write(struct edt_ft5x06_ts_data *tsdata,
u8 addr, u8 value)
{
@@ -1059,7 +1072,9 @@ static int edt_ft5x06_ts_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
const struct edt_i2c_chip_data *chip_data;
+ struct input_polled_dev *poll_dev = NULL;
struct edt_ft5x06_ts_data *tsdata;
+ bool polled = !(client->irq);
struct input_dev *input;
unsigned long irq_flags;
int error;
@@ -1112,15 +1127,38 @@ static int edt_ft5x06_ts_probe(struct i2c_client *client,
msleep(300);
}
- input = devm_input_allocate_device(&client->dev);
- if (!input) {
- dev_err(&client->dev, "failed to allocate input device.\n");
- return -ENOMEM;
+ if (polled) {
+ poll_dev = devm_input_allocate_polled_device(&client->dev);
+ if (!poll_dev) {
+ dev_err(&client->dev,
+ "failed to allocate polled input device.\n");
+ return -ENOMEM;
+ }
+
+ poll_dev->poll = edt_ft5x06_poll;
+ poll_dev->private = tsdata;
+
+ tsdata->poll_dev = poll_dev;
+ tsdata->input = poll_dev->input;
+
+ input = poll_dev->input;
+
+ device_property_read_u32(&client->dev, "poll-interval",
+ &poll_dev->poll_interval);
+
+ } else {
+ input = devm_input_allocate_device(&client->dev);
+ if (!input) {
+ dev_err(&client->dev,
+ "failed to allocate input device.\n");
+ return -ENOMEM;
+ }
+
+ tsdata->input = input;
}
mutex_init(&tsdata->mutex);
tsdata->client = client;
- tsdata->input = input;
tsdata->factory_mode = false;
error = edt_ft5x06_ts_identify(client, tsdata, fw_version);
@@ -1167,26 +1205,32 @@ static int edt_ft5x06_ts_probe(struct i2c_client *client,
i2c_set_clientdata(client, tsdata);
- irq_flags = irq_get_trigger_type(client->irq);
- if (irq_flags == IRQF_TRIGGER_NONE)
- irq_flags = IRQF_TRIGGER_FALLING;
- irq_flags |= IRQF_ONESHOT;
-
- error = devm_request_threaded_irq(&client->dev, client->irq,
- NULL, edt_ft5x06_ts_isr, irq_flags,
- client->name, tsdata);
- if (error) {
- dev_err(&client->dev, "Unable to request touchscreen IRQ.\n");
- return error;
- }
-
error = devm_device_add_group(&client->dev, &edt_ft5x06_attr_group);
if (error)
return error;
- error = input_register_device(input);
- if (error)
- return error;
+ if (polled) {
+ error = input_register_polled_device(poll_dev);
+ if (error)
+ return error;
+ } else {
+ irq_flags = irq_get_trigger_type(client->irq);
+ if (irq_flags == IRQF_TRIGGER_NONE)
+ irq_flags = IRQF_TRIGGER_FALLING;
+ irq_flags |= IRQF_ONESHOT;
+
+ error = devm_request_threaded_irq(&client->dev, client->irq,
+ NULL, edt_ft5x06_ts_isr, irq_flags,
+ client->name, tsdata);
+ if (error) {
+ dev_err(&client->dev, "Unable to request touchscreen IRQ.\n");
+ return error;
+ }
+
+ error = input_register_device(input);
+ if (error)
+ return error;
+ }
edt_ft5x06_ts_prepare_debugfs(tsdata, dev_driver_string(&client->dev));
device_init_wakeup(&client->dev, 1);
--
2.21.0
^ permalink raw reply related
* [PATCH 2/2] Input: edt-ft5x06 - add support for polled configuration
From: Nicolas Saenz Julienne @ 2019-04-30 18:58 UTC (permalink / raw)
To: linux-kernel
Cc: Nicolas Saenz Julienne, Dmitry Torokhov, Rob Herring,
Mark Rutland, linux-input, devicetree
In-Reply-To: <20190430185859.24015-1-nsaenzjulienne@suse.de>
Some devices might not provide an interrupt line for the touchscreen.
In that case the driver defaults to using a polled interface.
Signed-off-by: Nicolas Saenz Julienne <nsaenzjulienne@suse.de>
---
.../devicetree/bindings/input/touchscreen/edt-ft5x06.txt | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/Documentation/devicetree/bindings/input/touchscreen/edt-ft5x06.txt b/Documentation/devicetree/bindings/input/touchscreen/edt-ft5x06.txt
index 870b8c5cce9b..2605994a1257 100644
--- a/Documentation/devicetree/bindings/input/touchscreen/edt-ft5x06.txt
+++ b/Documentation/devicetree/bindings/input/touchscreen/edt-ft5x06.txt
@@ -24,10 +24,14 @@ Required properties:
or: "focaltech,ft6236"
- reg: I2C slave address of the chip (0x38)
- - interrupts: interrupt specification for the touchdetect
- interrupt
Optional properties:
+- interrupts: interrupt specification for the touchdetect interrupt, if not
+ supplied the driver will deafult to polling.
+
+- poll-interval: Poll interval time in milliseconds, only relevant if no
+ interrupt was provided.
+
- reset-gpios: GPIO specification for the RESET input
- wake-gpios: GPIO specification for the WAKE input
--
2.21.0
^ permalink raw reply related
* Re: [PATCH v2] Input: uinput: Avoid Object-Already-Free with a global lock
From: Mukesh Ojha @ 2019-05-01 7:50 UTC (permalink / raw)
To: Al Viro
Cc: dmitry.torokhov@gmail.com, linux-input, linux-kernel,
Gaurav Kohli, Peter Hutterer, Martin Kepplinger, Paul E. McKenney
In-Reply-To: <20190424225641.GQ2217@ZenIV.linux.org.uk>
Sorry to come late on this
On 4/25/2019 4:26 AM, Al Viro wrote:
> On Wed, Apr 24, 2019 at 07:39:03PM +0530, Mukesh Ojha wrote:
>
>> This was my simple program no multithreading just to understand f_counting
>>
>> int main()
>> {
>> int fd = open("/dev/uinput", O_WRONLY | O_NONBLOCK);
>> ioctl(fd, UI_SET_EVBIT, EV_KEY);
>> close(fd);
>> return 0;
>> }
>>
>> uinput-532 [002] .... 45.312044: SYSC_ioctl: 2 <= f_count
> Er... So how does it manage to hit ioctl(2) before open(2)? Confused...
I was confused too about this earlier, but after printing fd got to know
this is not for the same fd
opening for /dev/uinput, may it is for something while running the
executable.
>
>>> <After fdget()
>> uinput-532 [002] .... 45.312055: SYSC_ioctl: 2
>> <After fdput()
>> uinput-532 [004] .... 45.313766: uinput_open: uinput: 1 /*
>> This is from the uinput driver uinput_open()*/
>>
>> =>>>> /* All the above calls happened for the
>> open() in userspace*/
>>
>> uinput-532 [004] .... 45.313783: SYSC_ioctl: 1 /* This print
>> is for the trace, i put after fdget */
>> uinput-532 [004] .... 45.313788: uinput_ioctl_handler:
>> uinput: uinput_ioctl_handler, 1 /* This print is from the uinput_ioctl
>> driver */
>>
>> uinput-532 [004] .... 45.313835: SYSC_ioctl: 1 /* This print
>> is for the trace, i put after fdput*/
>> uinput-532 [004] .... 45.313843: uinput_release: uinput: 0
>> /* And this is from the close() */
>>
>>
>> Should fdget not suppose to increment the f_count here, as it is coming 1 ?
>> This f_count to one is done at the open, but i have no idea how this below
>> f_count 2 came before open() for
>> this simple program.
> If descriptor table is not shared, fdget() will simply return you the reference
> from there, without bothering to bump the refcount. _And_ having it marked
> "don't drop refcount" in struct fd.
>
> Rationale: since it's not shared, nobody other than our process can modify
> it. So unless we remove (and drop) the reference from it ourselves (which
> we certainly have no business doing in ->ioctl() and do not do anywhere
> in drivers/input), it will remain there until we return from syscall.
>
> Nobody is allowed to modify descriptor table other than their own.
> And if it's not shared, no other owners can appear while the only
> existing one is in the middle of syscall other than clone() (with
> CLONE_FILES in flags, at that).
>
> For shared descriptor table fdget() bumps file refcount, since there
> the reference in descriptor table itself could be removed and dropped
> by another thread.
>
> And fdget() marks whether fput() is needed in fd.flags, so that
> fdput() does the right thing.
Thanks Al, it is quite clear that issue can't happen while a ioctl is in
progress.
Actually the issue seems to be a race while glue_dir input is removed.
114.339374] input: syz1 as /devices/virtual/input/input278
[ 114.345619] input: syz1 as /devices/virtual/input/input279
[ 114.353502] input: syz1 as /devices/virtual/input/input280
[ 114.361907] input: syz1 as /devices/virtual/input/input281
[ 114.367276] input: syz1 as /devices/virtual/input/input282
[ 114.382292] input: syz1 as /devices/virtual/input/input283
in our case it is input which is getting removed while a inputxx is
trying make node inside input.
Similar issue https://lkml.org/lkml/2019/5/1/3
Thanks,
Mukesh
^ permalink raw reply
* [REOPENED] PROBLEM: Elan touchpad regression on Kernel 5.0.10
From: Outvi V @ 2019-05-01 13:57 UTC (permalink / raw)
To: dmitry.torokhov; +Cc: linux-input, linux-kernel
In-Reply-To: <9db8c26a-d9fd-4cc9-a3aa-bd593d8f73ac@www.fastmail.com>
Hello,
Sorry for disturbing. But later I find it is not actually solved. It seems to be a regression that randomly happens. Sometimes the touchpad works after starting without any bad logs, while somethime the touchpad is completely unusable.
I have filed a bug on Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=203467
If any detail is needed, please don't hesitate to contact me.
Regards,
On Tue, Apr 30, 2019, at 14:16, Outvi V wrote:
> Hello,
>
> After a cold restart, this problems seem to be solved automatically
> on kernel 5.0.10.
>
> Regards,
>
> On Tue, Apr 30, 2019, at 12:21, Outvi V wrote:
> > Hello,
> >
> > [1.] One line summary of the problem: Elan touchpad regression on Kernel 5.0.10
> >
> > [2.] Full description of the problem/report:
> > Elan touchpad does not work on 5.0.10 while working on 5.0.9
> >
> > [3.] Keywords: elan_i2c_core elan i2c touchpad 5.0.10
> >
> > [4.] Kernel information
> > [4.1.] Kernel version:
> > Linux version 5.0.10-arch1-1-ARCH (builduser@heftig-2592) (gcc
> > version 8.3.0 (GCC)) #1 SMP PREEMPT Sat Apr 27 20:06:45 UTC 2019
> > [4.2.] Kernel .config file:
> > I'm not sure, but I think it may be referring to
> >
> > https://git.archlinux.org/svntogit/packages.git/tree/trunk/config?h=packages/linux
> > [5.] Most recent kernel version which did not have the bug: 5.0.9
> >
> > [6.] Output of Oops.. message (if applicable) with symbolic information
> > resolved (Not appliable)
> > [7.] A small shell script or example program which triggers the
> > problem: (Not appliable)
> >
> > [8.] Environment
> > [8.1.] Software (add the output of the ver_linux script here)
> >
> > Linux sheltty 5.0.10-arch1-1-ARCH #1 SMP PREEMPT Sat Apr 27 20:06:45
> > UTC 2019 x86_64 GNU/Linux
> >
> > GNU C 8.3.0
> > GNU Make 4.2.1
> > Binutils 2.32
> > Util-linux 2.33.2
> > Mount 2.33.2
> > Module-init-tools 26
> > E2fsprogs 1.45.0
> > Jfsutils 1.1.15
> > Reiserfsprogs 3.6.27
> > Xfsprogs 4.20.0
> > PPP 2.4.7
> > Linux C Library 2.29
> > Dynamic linker (ldd) 2.29
> > Linux C++ Library 6.0.25
> > Procps 3.3.15
> > Kbd 2.0.4
> > Console-tools 2.0.4
> > Sh-utils 8.31
> > Udev 242
> > Modules Loaded 8021q 8250_dw ac ac97_bus acpi_thermal_rel
> > aesni_intel aes_x86_64 agpgart ahci arc4 atkbd battery bbswitch
> > bluetooth btbcm btintel btrtl btusb cfg80211 coretemp crc16
> > crc32c_generic crc32c_intel crc32_pclmul crct10dif_pclmul cryptd
> > crypto_simd crypto_user drm drm_kms_helper ecdh_generic elan_i2c evdev
> > ext4 fat fb_sys_fops fscrypto garp ghash_clmulni_intel glue_helper hid
> > hid_generic i2c_algo_bit i2c_hid i2c_i801 i8042 i915 idma64 input_leds
> > int3400_thermal int3403_thermal int340x_thermal_zone intel_cstate
> > intel_gtt intel_lpss intel_lpss_pci intel_pch_thermal intel_powerclamp
> > intel_rapl intel_rapl_perf intel_soc_dts_iosf intel_uncore
> > intel_wmi_thunderbolt ip_tables irqbypass iTCO_vendor_support iTCO_wdt
> > jbd2 joydev kvm kvmgt kvm_intel ledtrig_audio libahci libata libphy
> > libps2 llc mac80211 mac_hid mbcache mdev media mei mei_me mousedev mrp
> > nls_cp437 nls_iso8859_1 pcc_cpufreq processor_thermal_device r8169
> > r8822be realtek rfkill rng_core scsi_mod serio serio_raw snd
> > snd_compress snd_hda_codec snd_hda_codec_generic snd_hda_codec_hdmi
> > snd_hda_codec_realtek snd_hda_core snd_hda_ext_core snd_hda_intel
> > snd_hwdep snd_pcm snd_pcm_dmaengine snd_soc_acpi
> > snd_soc_acpi_intel_match snd_soc_core snd_soc_hdac_hda snd_soc_skl
> > snd_soc_skl_ipc snd_soc_sst_dsp snd_soc_sst_ipc snd_timer soundcore stp
> > syscopyarea sysfillrect sysimgblt tpm tpm_crb tpm_tis tpm_tis_core
> > typec typec_ucsi ucsi_acpi usbhid uvcvideo vfat vfio vfio_iommu_type1
> > vfio_mdev videobuf2_common videobuf2_memops videobuf2_v4l2
> > videobuf2_vmalloc videodev wmi wmi_bmof x86_pkg_temp_thermal xhci_hcd
> > xhci_pci x_tables
> >
> > [8.2.] Processor information (from /proc/cpuinfo): (Maybe not appliable)
> > [8.3.] Module information (from /proc/modules):
> >
> > (Parts related to i2c and elan:)
> >
> > i2c_algo_bit 16384 1 i915, Live 0x0000000000000000
> > i2c_hid 32768 0 - Live 0x0000000000000000
> > hid 147456 3 hid_generic,usbhid,i2c_hid, Live 0x0000000000000000
> > elan_i2c 49152 0 - Live 0x0000000000000000
> > i2c_i801 36864 0 - Live 0x0000000000000000
> >
> > [8.4.] Loaded driver and hardware information (/proc/ioports, /proc/iomem)
> >
> > /proc/ioports:
> > 0000-0000 : PCI Bus 0000:00
> > 0000-0000 : dma1
> > 0000-0000 : pic1
> > 0000-0000 : iTCO_wdt
> > 0000-0000 : timer0
> > 0000-0000 : timer1
> > 0000-0000 : keyboard
> > 0000-0000 : PNP0C09:00
> > 0000-0000 : EC data
> > 0000-0000 : keyboard
> > 0000-0000 : PNP0C09:00
> > 0000-0000 : EC cmd
> > 0000-0000 : rtc0
> > 0000-0000 : dma page reg
> > 0000-0000 : pic2
> > 0000-0000 : dma2
> > 0000-0000 : fpu
> > 0000-0000 : PNP0C04:00
> > 0000-0000 : iTCO_wdt
> > 0000-0000 : pnp 00:02
> > 0000-0000 : PCI conf1
> > 0000-0000 : PCI Bus 0000:00
> > 0000-0000 : pnp 00:02
> > 0000-0000 : pnp 00:00
> > 0000-0000 : ACPI PM1a_EVT_BLK
> > 0000-0000 : ACPI PM1a_CNT_BLK
> > 0000-0000 : ACPI PM_TMR
> > 0000-0000 : ACPI CPU throttle
> > 0000-0000 : ACPI PM2_CNT_BLK
> > 0000-0000 : pnp 00:04
> > 0000-0000 : ACPI GPE0_BLK
> > 0000-0000 : pnp 00:01
> > 0000-0000 : PCI Bus 0000:08
> > 0000-0000 : 0000:08:00.0
> > 0000-0000 : PCI Bus 0000:07
> > 0000-0000 : 0000:07:00.0
> > 0000-0000 : r8822be
> > 0000-0000 : PCI Bus 0000:01
> > 0000-0000 : 0000:01:00.0
> > 0000-0000 : 0000:00:02.0
> > 0000-0000 : 0000:00:1f.4
> > 0000-0000 : i801_smbus
> > 0000-0000 : 0000:00:17.0
> > 0000-0000 : ahci
> > 0000-0000 : 0000:00:17.0
> > 0000-0000 : ahci
> > 0000-0000 : 0000:00:17.0
> > 0000-0000 : ahci
> >
> >
> > [8.5.] PCI information
> > It seems to be long (over 700 lines) and unrelated to this
> > regression. Omitted to avoid flooding. I've kept an archive so feel
> > free to ask me to post it if needed.
> >
> > [8.6.] SCSI information (from /proc/scsi/scsi): (Empty)
> > [8.7.] Other information that might be relevant to the problem:
> >
> > dmesg is constantly showing "elan_i2c i2c-ELAN061B:00: invalid report
> > id data (d)".
> > I checked the git log and it is likely to be related to commit
> > "95df599f95f398b0a34d081dadfdee3126e58163".
> > I'm using Arch Linux, its kernel repository link: [1]
> > I checked the related file "elan_i2c_core.c" in Arch Linux's kernel
> > repository [2], and it is the same as in 5.0.10 on kernel.org.
> > My laptop is a Lenovo Legion Y7000.
> >
> > Links:
> > [1]. https://git.archlinux.org/linux.git
> > [2].
> > https://git.archlinux.org/linux.git/tree/drivers/input/mouse/elan_i2c_core.c?h=v5.0.10-arch1
> >
> > Please don't hesitate if more information or operation is needed.
^ permalink raw reply
* Re: [RFC PATCH 1/4] dt-bindings: input: Add support for the MPR121 without interrupt line
From: Rob Herring @ 2019-05-02 0:48 UTC (permalink / raw)
To: Michal Vokáč
Cc: Dmitry Torokhov, Mark Rutland, Shawn Guo, Sascha Hauer,
Fabio Estevam, linux-input, devicetree, linux-kernel,
Pengutronix Kernel Team
In-Reply-To: <1556267420-93219-2-git-send-email-michal.vokac@ysoft.com>
On Fri, Apr 26, 2019 at 10:30:17AM +0200, Michal Vokáč wrote:
> Normally, the MPR121 controller uses separate interrupt line to notify
> the I2C host that a key was touched/released. To support platforms that
> can not use the interrupt line, polling of the MPR121 registers can be
> used.
Other than making the 'interrupts' property optional, that's a driver
change, not a DT change. IOW, we shouldn't need a whole new binding.
>
> Signed-off-by: Michal Vokáč <michal.vokac@ysoft.com>
> ---
> .../bindings/input/mpr121-touchkey-polled.txt | 26 ++++++++++++++++++++++
> 1 file changed, 26 insertions(+)
> create mode 100644 Documentation/devicetree/bindings/input/mpr121-touchkey-polled.txt
>
> diff --git a/Documentation/devicetree/bindings/input/mpr121-touchkey-polled.txt b/Documentation/devicetree/bindings/input/mpr121-touchkey-polled.txt
> new file mode 100644
> index 000000000000..6bb1d312614c
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/input/mpr121-touchkey-polled.txt
> @@ -0,0 +1,26 @@
> +* Freescale MPR121 Controller without interrupt line
> +
> +Required Properties:
> +- compatible: Should be "fsl,mpr121-touchkey-polled"
> +- reg: The I2C slave address of the device.
> +- vdd-supply: Phandle to the Vdd power supply.
> +- linux,keycodes: Specifies an array of numeric keycode values to
> + be used for reporting button presses. The array can
> + contain up to 12 entries.
> +
> +Optional Properties:
> +- autorepeat: Enable autorepeat feature.
> +
> +Example:
> +
> +#include "dt-bindings/input/input.h"
> +
> + touchkeys: keys@5a {
> + compatible = "fsl,mpr121-touchkey-polled";
> + reg = <0x5a>;
> + autorepeat;
> + vdd-supply = <&ldo4_reg>;
> + linux,keycodes = <KEY_0>, <KEY_1>, <KEY_2>, <KEY_3>,
> + <KEY_4> <KEY_5>, <KEY_6>, <KEY_7>,
> + <KEY_8>, <KEY_9>, <KEY_A>, <KEY_B>;
> + };
> --
> 2.1.4
>
^ permalink raw reply
* Re: [PATCH] i2c: Prevent runtime suspend of adapter when Host Notify is required
From: Keijo Vaara @ 2019-05-02 8:07 UTC (permalink / raw)
To: linux-i2c, Jarkko Nikula
Cc: Wolfram Sang, linux-input, Bjorn Helgaas, Rafael J . Wysocki,
stable
In-Reply-To: <20190430142322.15013-1-jarkko.nikula@linux.intel.com>
On Tue, Apr 30, 2019 at 4:23 PM Jarkko Nikula
<jarkko.nikula@linux.intel.com> wrote:
>
> ---
> Keijo: could you test this does it fix the issue you reported? This is
> practically the same diff I sent earlier what you probably haven't tested yet.
> I wanted to send a commitable fix in case it works since I'll be out of
> office in a few coming days.
> ---
> drivers/i2c/i2c-core-base.c | 4 ++++
> 1 file changed, 4 insertions(+)
>
> diff --git a/drivers/i2c/i2c-core-base.c b/drivers/i2c/i2c-core-base.c
> index 38af18645133..8149c9e32b69 100644
> --- a/drivers/i2c/i2c-core-base.c
> +++ b/drivers/i2c/i2c-core-base.c
> @@ -327,6 +327,8 @@ static int i2c_device_probe(struct device *dev)
>
> if (client->flags & I2C_CLIENT_HOST_NOTIFY) {
> dev_dbg(dev, "Using Host Notify IRQ\n");
> + /* Keep adapter active when Host Notify is required */
> + pm_runtime_get_sync(&client->adapter->dev);
> irq = i2c_smbus_host_notify_to_irq(client);
> } else if (dev->of_node) {
> irq = of_irq_get_byname(dev->of_node, "irq");
> @@ -431,6 +433,8 @@ static int i2c_device_remove(struct device *dev)
> device_init_wakeup(&client->dev, false);
>
> client->irq = client->init_irq;
> + if (client->flags & I2C_CLIENT_HOST_NOTIFY)
> + pm_runtime_put(&client->adapter->dev);
>
> return status;
> }
> --
> 2.20.1
>
Thanks guys, I've tested the patch and can confirm it fixes the issue.
^ permalink raw reply
* Re: [PATCH] i2c: Prevent runtime suspend of adapter when Host Notify is required
From: Wolfram Sang @ 2019-05-02 16:43 UTC (permalink / raw)
To: Jarkko Nikula
Cc: linux-i2c, Keijo Vaara, linux-input, Bjorn Helgaas,
Rafael J . Wysocki, stable
In-Reply-To: <20190430142322.15013-1-jarkko.nikula@linux.intel.com>
[-- Attachment #1: Type: text/plain, Size: 1362 bytes --]
On Tue, Apr 30, 2019 at 05:23:22PM +0300, Jarkko Nikula wrote:
> Multiple users have reported their Synaptics touchpad has stopped
> working between v4.20.1 and v4.20.2 when using SMBus interface.
>
> The culprit for this appeared to be commit c5eb1190074c ("PCI / PM: Allow
> runtime PM without callback functions") that fixed the runtime PM for
> i2c-i801 SMBus adapter. Those Synaptics touchpad are using i2c-i801
> for SMBus communication and testing showed they are able to get back
> working by preventing the runtime suspend of adapter.
>
> Normally when i2c-i801 SMBus adapter transmits with the client it resumes
> before operation and autosuspends after.
>
> However, if client requires SMBus Host Notify protocol, what those
> Synaptics touchpads do, then the host adapter must not go to runtime
> suspend since then it cannot process incoming SMBus Host Notify commands
> the client may send.
>
> Fix this by keeping I2C/SMBus adapter active in case client requires
> Host Notify.
>
> Reported-by: Keijo Vaara <ferdasyn@rocketmail.com>
> Link: https://bugzilla.kernel.org/show_bug.cgi?id=203297
> Fixes: c5eb1190074c ("PCI / PM: Allow runtime PM without callback functions")
> Cc: stable@vger.kernel.org # v4.20+
> Signed-off-by: Jarkko Nikula <jarkko.nikula@linux.intel.com>
Applied to for-current-fixed, thanks!
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]
^ permalink raw reply
* Re: [PATCH 2/2] Input: edt-ft5x06 - add support for polled configuration
From: Rob Herring @ 2019-05-02 21:32 UTC (permalink / raw)
Cc: linux-kernel, Nicolas Saenz Julienne, Dmitry Torokhov,
Mark Rutland, linux-input, devicetree
In-Reply-To: <20190430185859.24015-2-nsaenzjulienne@suse.de>
On Tue, 30 Apr 2019 20:58:59 +0200, Nicolas Saenz Julienne wrote:
> Some devices might not provide an interrupt line for the touchscreen.
> In that case the driver defaults to using a polled interface.
>
> Signed-off-by: Nicolas Saenz Julienne <nsaenzjulienne@suse.de>
> ---
> .../devicetree/bindings/input/touchscreen/edt-ft5x06.txt | 8 ++++++--
> 1 file changed, 6 insertions(+), 2 deletions(-)
>
Reviewed-by: Rob Herring <robh@kernel.org>
^ permalink raw reply
* [PATCH] HID: fix A4Tech horizontal scrolling
From: Błażej Szczygieł @ 2019-05-02 21:36 UTC (permalink / raw)
Cc: igorkuo, Błażej Szczygieł, Jiri Kosina,
Benjamin Tissoires, linux-input, linux-kernel
Since recent high resolution scrolling changes the A4Tech driver must
check for the "REL_WHEEL_HI_RES" usage code.
Fixes: 2dc702c991e3774af9d7ce410eef410ca9e2357e (HID: input: use the
Resolution Multiplier for high-resolution scrolling)
Signed-off-by: Błażej Szczygieł <spaz16@wp.pl>
---
drivers/hid/hid-a4tech.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/drivers/hid/hid-a4tech.c b/drivers/hid/hid-a4tech.c
index 9428ea7cdf8a..fafb9fa558e7 100644
--- a/drivers/hid/hid-a4tech.c
+++ b/drivers/hid/hid-a4tech.c
@@ -38,7 +38,7 @@ static int a4_input_mapped(struct hid_device *hdev, struct hid_input *hi,
{
struct a4tech_sc *a4 = hid_get_drvdata(hdev);
- if (usage->type == EV_REL && usage->code == REL_WHEEL)
+ if (usage->type == EV_REL && usage->code == REL_WHEEL_HI_RES)
set_bit(REL_HWHEEL, *bit);
if ((a4->quirks & A4_2WHEEL_MOUSE_HACK_7) && usage->hid == 0x00090007)
@@ -60,7 +60,7 @@ static int a4_event(struct hid_device *hdev, struct hid_field *field,
input = field->hidinput->input;
if (a4->quirks & A4_2WHEEL_MOUSE_HACK_B8) {
- if (usage->type == EV_REL && usage->code == REL_WHEEL) {
+ if (usage->type == EV_REL && usage->code == REL_WHEEL_HI_RES) {
a4->delayed_value = value;
return 1;
}
@@ -77,7 +77,7 @@ static int a4_event(struct hid_device *hdev, struct hid_field *field,
return 1;
}
- if (usage->code == REL_WHEEL && a4->hw_wheel) {
+ if (usage->code == REL_WHEEL_HI_RES && a4->hw_wheel) {
input_event(input, usage->type, REL_HWHEEL, value);
return 1;
}
--
2.21.0
^ permalink raw reply related
* Re: [PATCH] HID: fix A4Tech horizontal scrolling
From: Benjamin Tissoires @ 2019-05-03 7:36 UTC (permalink / raw)
To: Błażej Szczygieł
Cc: igorkuo, Jiri Kosina, open list:HID CORE LAYER, lkml
In-Reply-To: <20190502213639.7632-1-spaz16@wp.pl>
Hi,
On Thu, May 2, 2019 at 11:37 PM Błażej Szczygieł <spaz16@wp.pl> wrote:
>
> Since recent high resolution scrolling changes the A4Tech driver must
> check for the "REL_WHEEL_HI_RES" usage code.
>
> Fixes: 2dc702c991e3774af9d7ce410eef410ca9e2357e (HID: input: use the
> Resolution Multiplier for high-resolution scrolling)
>
> Signed-off-by: Błażej Szczygieł <spaz16@wp.pl>
Thanks for the patch. I do not doubt this fixes the issues, but I
still wonder if we should not export REL_HWHEEL_HI_RES instead of
REL_HWHEEL events.
Also, I can not figure out how the events are processed by the kernel.
Could you attach a hid-recorder dump of the mouse wheels with
hid-recorder from https://gitlab.freedesktop.org/libevdev/hid-tools ?
This should give me a better view of the mouse, and I could also add
it to the regression tests I am running for each commit.
Cheers,
Benjamin
> ---
> drivers/hid/hid-a4tech.c | 6 +++---
> 1 file changed, 3 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/hid/hid-a4tech.c b/drivers/hid/hid-a4tech.c
> index 9428ea7cdf8a..fafb9fa558e7 100644
> --- a/drivers/hid/hid-a4tech.c
> +++ b/drivers/hid/hid-a4tech.c
> @@ -38,7 +38,7 @@ static int a4_input_mapped(struct hid_device *hdev, struct hid_input *hi,
> {
> struct a4tech_sc *a4 = hid_get_drvdata(hdev);
>
> - if (usage->type == EV_REL && usage->code == REL_WHEEL)
> + if (usage->type == EV_REL && usage->code == REL_WHEEL_HI_RES)
> set_bit(REL_HWHEEL, *bit);
>
> if ((a4->quirks & A4_2WHEEL_MOUSE_HACK_7) && usage->hid == 0x00090007)
> @@ -60,7 +60,7 @@ static int a4_event(struct hid_device *hdev, struct hid_field *field,
> input = field->hidinput->input;
>
> if (a4->quirks & A4_2WHEEL_MOUSE_HACK_B8) {
> - if (usage->type == EV_REL && usage->code == REL_WHEEL) {
> + if (usage->type == EV_REL && usage->code == REL_WHEEL_HI_RES) {
> a4->delayed_value = value;
> return 1;
> }
> @@ -77,7 +77,7 @@ static int a4_event(struct hid_device *hdev, struct hid_field *field,
> return 1;
> }
>
> - if (usage->code == REL_WHEEL && a4->hw_wheel) {
> + if (usage->code == REL_WHEEL_HI_RES && a4->hw_wheel) {
> input_event(input, usage->type, REL_HWHEEL, value);
> return 1;
> }
> --
> 2.21.0
>
^ permalink raw reply
* Re: [PATCH] HID: fix A4Tech horizontal scrolling
From: Błażej Szczygieł @ 2019-05-03 9:22 UTC (permalink / raw)
To: Benjamin Tissoires; +Cc: igorkuo, Jiri Kosina, open list:HID CORE LAYER, lkml
In-Reply-To: <CAO-hwJLbFv3S9M5N+BKBuafj8H-vToy=2VQd=cvohmaTHLMC3A@mail.gmail.com>
Hi,
I used the hid-record tool and my results are here:
https://gitlab.com/snippets/1853568
Cheers,
Błażej
> Hi,
>
> On Thu, May 2, 2019 at 11:37 PM Błażej Szczygieł <spaz16@wp.pl> wrote:
>>
>> Since recent high resolution scrolling changes the A4Tech driver must
>> check for the "REL_WHEEL_HI_RES" usage code.
>>
>> Fixes: 2dc702c991e3774af9d7ce410eef410ca9e2357e (HID: input: use the
>> Resolution Multiplier for high-resolution scrolling)
>>
>> Signed-off-by: Błażej Szczygieł <spaz16@wp.pl>
>
> Thanks for the patch. I do not doubt this fixes the issues, but I
> still wonder if we should not export REL_HWHEEL_HI_RES instead of
> REL_HWHEEL events.
>
> Also, I can not figure out how the events are processed by the kernel.
> Could you attach a hid-recorder dump of the mouse wheels with
> hid-recorder from https://gitlab.freedesktop.org/libevdev/hid-tools ?
>
> This should give me a better view of the mouse, and I could also add
> it to the regression tests I am running for each commit.
>
> Cheers,
> Benjamin
>
>> ---
>> drivers/hid/hid-a4tech.c | 6 +++---
>> 1 file changed, 3 insertions(+), 3 deletions(-)
>>
>> diff --git a/drivers/hid/hid-a4tech.c b/drivers/hid/hid-a4tech.c
>> index 9428ea7cdf8a..fafb9fa558e7 100644
>> --- a/drivers/hid/hid-a4tech.c
>> +++ b/drivers/hid/hid-a4tech.c
>> @@ -38,7 +38,7 @@ static int a4_input_mapped(struct hid_device *hdev, struct hid_input *hi,
>> {
>> struct a4tech_sc *a4 = hid_get_drvdata(hdev);
>>
>> - if (usage->type == EV_REL && usage->code == REL_WHEEL)
>> + if (usage->type == EV_REL && usage->code == REL_WHEEL_HI_RES)
>> set_bit(REL_HWHEEL, *bit);
>>
>> if ((a4->quirks & A4_2WHEEL_MOUSE_HACK_7) && usage->hid == 0x00090007)
>> @@ -60,7 +60,7 @@ static int a4_event(struct hid_device *hdev, struct hid_field *field,
>> input = field->hidinput->input;
>>
>> if (a4->quirks & A4_2WHEEL_MOUSE_HACK_B8) {
>> - if (usage->type == EV_REL && usage->code == REL_WHEEL) {
>> + if (usage->type == EV_REL && usage->code == REL_WHEEL_HI_RES) {
>> a4->delayed_value = value;
>> return 1;
>> }
>> @@ -77,7 +77,7 @@ static int a4_event(struct hid_device *hdev, struct hid_field *field,
>> return 1;
>> }
>>
>> - if (usage->code == REL_WHEEL && a4->hw_wheel) {
>> + if (usage->code == REL_WHEEL_HI_RES && a4->hw_wheel) {
>> input_event(input, usage->type, REL_HWHEEL, value);
>> return 1;
>> }
>> --
>> 2.21.0
>>
^ permalink raw reply
* Re: [PATCH] HID: fix A4Tech horizontal scrolling
From: Igor Kushnir @ 2019-05-03 9:36 UTC (permalink / raw)
To: Benjamin Tissoires, Błażej Szczygieł
Cc: Jiri Kosina, open list:HID CORE LAYER, lkml
In-Reply-To: <CAO-hwJLbFv3S9M5N+BKBuafj8H-vToy=2VQd=cvohmaTHLMC3A@mail.gmail.com>
Hi Benjamin,
On 5/3/19 10:36 AM, Benjamin Tissoires wrote:
> Hi,
>
> On Thu, May 2, 2019 at 11:37 PM Błażej Szczygieł <spaz16@wp.pl> wrote:
>>
>> Since recent high resolution scrolling changes the A4Tech driver must
>> check for the "REL_WHEEL_HI_RES" usage code.
>>
>> Fixes: 2dc702c991e3774af9d7ce410eef410ca9e2357e (HID: input: use the
>> Resolution Multiplier for high-resolution scrolling)
>>
>> Signed-off-by: Błażej Szczygieł <spaz16@wp.pl>
>
> Thanks for the patch. I do not doubt this fixes the issues, but I
> still wonder if we should not export REL_HWHEEL_HI_RES instead of
> REL_HWHEEL events.
If you mean exporting REL_HWHEEL_HI_RES instead of REL_HWHEEL from
hid-a4tech.c, then it makes sense to me, though I do not know the code
well enough to be certain.
Błażej and I have discussed the bug and the patch here:
https://bugzilla.kernel.org/show_bug.cgi?id=203369
In summary: the patch fixes the bug for both our mice;
the documentation in input/event-codes.rst states that
REL_WHEEL, REL_HWHEEL "are legacy codes and REL_WHEEL_HI_RES and
REL_HWHEEL_HI_RES should be preferred where available."
> Also, I can not figure out how the events are processed by the kernel.
> Could you attach a hid-recorder dump of the mouse wheels with
> hid-recorder from https://gitlab.freedesktop.org/libevdev/hid-tools ?
>
> This should give me a better view of the mouse, and I could also add
> it to the regression tests I am running for each commit.
>
> Cheers,
> Benjamin
After launching hid-recorder for my A4Tech WOP-49Z mouse under kernel
5.0.10 patched with Błażej's patch I:
* scrolled the vertical wheel down ("Wheel: -1");
* scrolled the vertical wheel up ("Wheel: 1");
* scrolled the horizontal wheel "left" ("Wheel: -1");
* scrolled the horizontal wheel "right" ("Wheel: 1").
Note that the horizontal wheel is physically scrolled just like the
vertical one in this mouse (forward/back), so "left" and "right" are the
effects these scrollings make in applications when the kernel supports
the mouse properly.
$ sudo ./hid-recorder /dev/hidraw1
# A4Tech PS/2+USB Mouse
# 0x05, 0x01, // Usage Page (Generic Desktop) 0
# 0x09, 0x02, // Usage (Mouse) 2
# 0xa1, 0x01, // Collection (Application) 4
# 0x09, 0x01, // Usage (Pointer) 6
# 0xa1, 0x00, // Collection (Physical) 8
# 0x05, 0x09, // Usage Page (Button) 10
# 0x19, 0x01, // Usage Minimum (1) 12
# 0x29, 0x07, // Usage Maximum (7) 14
# 0x15, 0x00, // Logical Minimum (0) 16
# 0x25, 0x01, // Logical Maximum (1) 18
# 0x75, 0x01, // Report Size (1) 20
# 0x95, 0x07, // Report Count (7) 22
# 0x81, 0x02, // Input (Data,Var,Abs) 24
# 0x75, 0x01, // Report Size (1) 26
# 0x95, 0x01, // Report Count (1) 28
# 0x81, 0x01, // Input (Cnst,Arr,Abs) 30
# 0x05, 0x01, // Usage Page (Generic Desktop) 32
# 0x09, 0x30, // Usage (X) 34
# 0x09, 0x31, // Usage (Y) 36
# 0x09, 0x38, // Usage (Wheel) 38
# 0x15, 0x81, // Logical Minimum (-127) 40
# 0x25, 0x7f, // Logical Maximum (127) 42
# 0x75, 0x08, // Report Size (8) 44
# 0x95, 0x03, // Report Count (3) 46
# 0x81, 0x06, // Input (Data,Var,Rel) 48
# 0xc0, // End Collection 50
# 0xc0, // End Collection 51
#
R: 52 05 01 09 02 a1 01 09 01 a1 00 05 09 19 01 29 07 15 00 25 01 75 01
95 07 81 02 75 01 95 01 81 01 05 01 09 30 09 31 09 38 15 81 25 7f 75 08
95 03 81 06 c0 c0
N: A4Tech PS/2+USB Mouse
I: 3 09da 0006
# Button: 0 0 0 0 0 0 0 | # | X: 0 | Y: 0 | Wheel: -1
E: 000000.000000 4 00 00 00 ff
# Button: 0 0 0 0 0 0 0 | # | X: 0 | Y: 0 | Wheel: -1
E: 000000.071952 4 00 00 00 ff
# Button: 0 0 0 0 0 0 0 | # | X: 0 | Y: 0 | Wheel: -1
E: 000000.159957 4 00 00 00 ff
# Button: 0 0 0 0 0 0 0 | # | X: 0 | Y: 0 | Wheel: 1
E: 000002.912232 4 00 00 00 01
# Button: 0 0 0 0 0 0 0 | # | X: 0 | Y: 0 | Wheel: 1
E: 000002.952190 4 00 00 00 01
# Button: 0 0 0 0 0 0 0 | # | X: 0 | Y: 0 | Wheel: 1
E: 000004.512359 4 00 00 00 01
# Button: 0 0 0 0 0 0 0 | # | X: 0 | Y: 0 | Wheel: 1
E: 000004.584332 4 00 00 00 01
# Button: 0 0 0 0 0 0 1 | # | X: 0 | Y: 0 | Wheel: -1
E: 000007.528626 4 40 00 00 ff
# Button: 0 0 0 0 0 0 1 | # | X: 0 | Y: 0 | Wheel: -1
E: 000007.568577 4 40 00 00 ff
# Button: 0 0 0 0 0 0 1 | # | X: 0 | Y: 0 | Wheel: -1
E: 000008.256395 4 40 00 00 ff
# Button: 0 0 0 0 0 0 1 | # | X: 0 | Y: 0 | Wheel: -1
E: 000008.336669 4 40 00 00 ff
# Button: 0 0 0 0 0 0 1 | # | X: 0 | Y: 0 | Wheel: -1
E: 000008.400649 4 40 00 00 ff
# Button: 0 0 0 0 0 0 1 | # | X: 0 | Y: 0 | Wheel: 1
E: 000010.936908 4 40 00 00 01
# Button: 0 0 0 0 0 0 1 | # | X: 0 | Y: 0 | Wheel: 1
E: 000010.984864 4 40 00 00 01
# Button: 0 0 0 0 0 0 1 | # | X: 0 | Y: 0 | Wheel: 1
E: 000011.056897 4 40 00 00 01
# Button: 0 0 0 0 0 0 1 | # | X: 0 | Y: 0 | Wheel: 1
E: 000011.528936 4 40 00 00 01
# Button: 0 0 0 0 0 0 1 | # | X: 0 | Y: 0 | Wheel: 1
E: 000011.616923 4 40 00 00 01
Cheers,
Igor
>> ---
>> drivers/hid/hid-a4tech.c | 6 +++---
>> 1 file changed, 3 insertions(+), 3 deletions(-)
>>
>> diff --git a/drivers/hid/hid-a4tech.c b/drivers/hid/hid-a4tech.c
>> index 9428ea7cdf8a..fafb9fa558e7 100644
>> --- a/drivers/hid/hid-a4tech.c
>> +++ b/drivers/hid/hid-a4tech.c
>> @@ -38,7 +38,7 @@ static int a4_input_mapped(struct hid_device *hdev, struct hid_input *hi,
>> {
>> struct a4tech_sc *a4 = hid_get_drvdata(hdev);
>>
>> - if (usage->type == EV_REL && usage->code == REL_WHEEL)
>> + if (usage->type == EV_REL && usage->code == REL_WHEEL_HI_RES)
>> set_bit(REL_HWHEEL, *bit);
>>
>> if ((a4->quirks & A4_2WHEEL_MOUSE_HACK_7) && usage->hid == 0x00090007)
>> @@ -60,7 +60,7 @@ static int a4_event(struct hid_device *hdev, struct hid_field *field,
>> input = field->hidinput->input;
>>
>> if (a4->quirks & A4_2WHEEL_MOUSE_HACK_B8) {
>> - if (usage->type == EV_REL && usage->code == REL_WHEEL) {
>> + if (usage->type == EV_REL && usage->code == REL_WHEEL_HI_RES) {
>> a4->delayed_value = value;
>> return 1;
>> }
>> @@ -77,7 +77,7 @@ static int a4_event(struct hid_device *hdev, struct hid_field *field,
>> return 1;
>> }
>>
>> - if (usage->code == REL_WHEEL && a4->hw_wheel) {
>> + if (usage->code == REL_WHEEL_HI_RES && a4->hw_wheel) {
>> input_event(input, usage->type, REL_HWHEEL, value);
>> return 1;
>> }
>> --
>> 2.21.0
>>
^ permalink raw reply
* Re: [PATCH] HID: fix A4Tech horizontal scrolling
From: Benjamin Tissoires @ 2019-05-03 11:59 UTC (permalink / raw)
To: Igor Kushnir, Peter Hutterer
Cc: Błażej Szczygieł, Jiri Kosina,
open list:HID CORE LAYER, lkml
In-Reply-To: <1a40ea07-368a-93f6-8335-dec7ae50bbf4@gmail.com>
Hi,
On Fri, May 3, 2019 at 11:43 AM Igor Kushnir <igorkuo@gmail.com> wrote:
>
> Hi Benjamin,
>
> On 5/3/19 10:36 AM, Benjamin Tissoires wrote:
> > Hi,
> >
> > On Thu, May 2, 2019 at 11:37 PM Błażej Szczygieł <spaz16@wp.pl> wrote:
> >>
> >> Since recent high resolution scrolling changes the A4Tech driver must
> >> check for the "REL_WHEEL_HI_RES" usage code.
> >>
> >> Fixes: 2dc702c991e3774af9d7ce410eef410ca9e2357e (HID: input: use the
> >> Resolution Multiplier for high-resolution scrolling)
> >>
> >> Signed-off-by: Błażej Szczygieł <spaz16@wp.pl>
> >
> > Thanks for the patch. I do not doubt this fixes the issues, but I
> > still wonder if we should not export REL_HWHEEL_HI_RES instead of
> > REL_HWHEEL events.
>
>
> If you mean exporting REL_HWHEEL_HI_RES instead of REL_HWHEEL from
> hid-a4tech.c, then it makes sense to me, though I do not know the code
> well enough to be certain.
Yep, that's what I meant. I am worried that userspace doesn't know
well how to deal with a device that mixes the new and old REL_WHEEL
events.
>
> Błażej and I have discussed the bug and the patch here:
> https://bugzilla.kernel.org/show_bug.cgi?id=203369
Oh cool.
Then we should add: "Link:
https://bugzilla.kernel.org/show_bug.cgi?id=203369" in the commit
description.
Also, given that the patch will likely see a v2, te format of the
"Fixes" tag is not correct: see
https://www.kernel.org/doc/html/v4.20/process/submitting-patches.html#describe-your-changes
(I have been notified that I tend to not follow the rules here, so I
am trying to do better here :-P )
>
> In summary: the patch fixes the bug for both our mice;
> the documentation in input/event-codes.rst states that
> REL_WHEEL, REL_HWHEEL "are legacy codes and REL_WHEEL_HI_RES and
> REL_HWHEEL_HI_RES should be preferred where available."
>
> > Also, I can not figure out how the events are processed by the kernel.
> > Could you attach a hid-recorder dump of the mouse wheels with
> > hid-recorder from https://gitlab.freedesktop.org/libevdev/hid-tools ?
> >
> > This should give me a better view of the mouse, and I could also add
> > it to the regression tests I am running for each commit.
> >
> > Cheers,
> > Benjamin
>
> After launching hid-recorder for my A4Tech WOP-49Z mouse under kernel
> 5.0.10 patched with Błażej's patch I:
> * scrolled the vertical wheel down ("Wheel: -1");
> * scrolled the vertical wheel up ("Wheel: 1");
> * scrolled the horizontal wheel "left" ("Wheel: -1");
> * scrolled the horizontal wheel "right" ("Wheel: 1").
> Note that the horizontal wheel is physically scrolled just like the
> vertical one in this mouse (forward/back), so "left" and "right" are the
> effects these scrollings make in applications when the kernel supports
> the mouse properly.
>
> $ sudo ./hid-recorder /dev/hidraw1
> # A4Tech PS/2+USB Mouse
> # 0x05, 0x01, // Usage Page (Generic Desktop) 0
> # 0x09, 0x02, // Usage (Mouse) 2
> # 0xa1, 0x01, // Collection (Application) 4
> # 0x09, 0x01, // Usage (Pointer) 6
> # 0xa1, 0x00, // Collection (Physical) 8
> # 0x05, 0x09, // Usage Page (Button) 10
> # 0x19, 0x01, // Usage Minimum (1) 12
> # 0x29, 0x07, // Usage Maximum (7) 14
> # 0x15, 0x00, // Logical Minimum (0) 16
> # 0x25, 0x01, // Logical Maximum (1) 18
> # 0x75, 0x01, // Report Size (1) 20
> # 0x95, 0x07, // Report Count (7) 22
> # 0x81, 0x02, // Input (Data,Var,Abs) 24
> # 0x75, 0x01, // Report Size (1) 26
> # 0x95, 0x01, // Report Count (1) 28
> # 0x81, 0x01, // Input (Cnst,Arr,Abs) 30
> # 0x05, 0x01, // Usage Page (Generic Desktop) 32
> # 0x09, 0x30, // Usage (X) 34
> # 0x09, 0x31, // Usage (Y) 36
> # 0x09, 0x38, // Usage (Wheel) 38
> # 0x15, 0x81, // Logical Minimum (-127) 40
> # 0x25, 0x7f, // Logical Maximum (127) 42
> # 0x75, 0x08, // Report Size (8) 44
> # 0x95, 0x03, // Report Count (3) 46
> # 0x81, 0x06, // Input (Data,Var,Rel) 48
> # 0xc0, // End Collection 50
> # 0xc0, // End Collection 51
> #
> R: 52 05 01 09 02 a1 01 09 01 a1 00 05 09 19 01 29 07 15 00 25 01 75 01
> 95 07 81 02 75 01 95 01 81 01 05 01 09 30 09 31 09 38 15 81 25 7f 75 08
> 95 03 81 06 c0 c0
> N: A4Tech PS/2+USB Mouse
> I: 3 09da 0006
> # Button: 0 0 0 0 0 0 0 | # | X: 0 | Y: 0 | Wheel: -1
> E: 000000.000000 4 00 00 00 ff
> # Button: 0 0 0 0 0 0 0 | # | X: 0 | Y: 0 | Wheel: -1
> E: 000000.071952 4 00 00 00 ff
> # Button: 0 0 0 0 0 0 0 | # | X: 0 | Y: 0 | Wheel: -1
> E: 000000.159957 4 00 00 00 ff
> # Button: 0 0 0 0 0 0 0 | # | X: 0 | Y: 0 | Wheel: 1
> E: 000002.912232 4 00 00 00 01
> # Button: 0 0 0 0 0 0 0 | # | X: 0 | Y: 0 | Wheel: 1
> E: 000002.952190 4 00 00 00 01
> # Button: 0 0 0 0 0 0 0 | # | X: 0 | Y: 0 | Wheel: 1
> E: 000004.512359 4 00 00 00 01
> # Button: 0 0 0 0 0 0 0 | # | X: 0 | Y: 0 | Wheel: 1
> E: 000004.584332 4 00 00 00 01
> # Button: 0 0 0 0 0 0 1 | # | X: 0 | Y: 0 | Wheel: -1
> E: 000007.528626 4 40 00 00 ff
> # Button: 0 0 0 0 0 0 1 | # | X: 0 | Y: 0 | Wheel: -1
> E: 000007.568577 4 40 00 00 ff
> # Button: 0 0 0 0 0 0 1 | # | X: 0 | Y: 0 | Wheel: -1
> E: 000008.256395 4 40 00 00 ff
> # Button: 0 0 0 0 0 0 1 | # | X: 0 | Y: 0 | Wheel: -1
> E: 000008.336669 4 40 00 00 ff
> # Button: 0 0 0 0 0 0 1 | # | X: 0 | Y: 0 | Wheel: -1
> E: 000008.400649 4 40 00 00 ff
> # Button: 0 0 0 0 0 0 1 | # | X: 0 | Y: 0 | Wheel: 1
> E: 000010.936908 4 40 00 00 01
> # Button: 0 0 0 0 0 0 1 | # | X: 0 | Y: 0 | Wheel: 1
> E: 000010.984864 4 40 00 00 01
> # Button: 0 0 0 0 0 0 1 | # | X: 0 | Y: 0 | Wheel: 1
> E: 000011.056897 4 40 00 00 01
> # Button: 0 0 0 0 0 0 1 | # | X: 0 | Y: 0 | Wheel: 1
> E: 000011.528936 4 40 00 00 01
> # Button: 0 0 0 0 0 0 1 | # | X: 0 | Y: 0 | Wheel: 1
> E: 000011.616923 4 40 00 00 01
>
OK, thanks both of you for your logs, this is helpful.
So just in case I need to come back later, the horizontal wheel is
"just" the normal wheel plus a modifier in the report.
Anyway, ideally, can we have a v2 of the patch with the 2 changes
requested above in the commit message and the introduction of
REL_HWHEEL_HI_RES events in addition to REL_HWHEEL?
REL_HWHEEL_HI_RES should report `120*value` and we should also keep
the reporting of REL_WHEEL as it is currently.
Peter, I grepped in the hid code, and it seems hid-cypress.c is having
the exact same issue. Sigh.
Cheers,
Benjamin
^ permalink raw reply
* Re: [PATCH] HID: rmi: fix devm_add_action_or_reset() parameter
From: Jiri Kosina @ 2019-05-03 12:19 UTC (permalink / raw)
To: Fabien Dessenne; +Cc: Benjamin Tissoires, linux-input, linux-kernel
In-Reply-To: <1555073657-24386-1-git-send-email-fabien.dessenne@st.com>
On Fri, 12 Apr 2019, Fabien Dessenne wrote:
> The second parameter of devm_add_action_or_reset() shall be a function,
> not a function address.
>
> Signed-off-by: Fabien Dessenne <fabien.dessenne@st.com>
> ---
> drivers/hid/hid-rmi.c | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/drivers/hid/hid-rmi.c b/drivers/hid/hid-rmi.c
> index 9e33165..8748d4d 100644
> --- a/drivers/hid/hid-rmi.c
> +++ b/drivers/hid/hid-rmi.c
> @@ -623,7 +623,7 @@ static int rmi_setup_irq_domain(struct hid_device *hdev)
> if (!hdata->domain)
> return -ENOMEM;
>
> - ret = devm_add_action_or_reset(&hdev->dev, &rmi_irq_teardown, hdata);
> + ret = devm_add_action_or_reset(&hdev->dev, rmi_irq_teardown, hdata);
Why do you think this is wrong C?
--
Jiri Kosina
SUSE Labs
^ permalink raw reply
* Re: [PATCH] HID: rmi: fix devm_add_action_or_reset() parameter
From: Fabien DESSENNE @ 2019-05-03 12:38 UTC (permalink / raw)
To: Jiri Kosina
Cc: Benjamin Tissoires, linux-input@vger.kernel.org,
linux-kernel@vger.kernel.org
In-Reply-To: <nycvar.YFH.7.76.1905031418510.10635@cbobk.fhfr.pm>
On 03/05/2019 2:19 PM, Jiri Kosina wrote:
> On Fri, 12 Apr 2019, Fabien Dessenne wrote:
>
>> The second parameter of devm_add_action_or_reset() shall be a function,
>> not a function address.
>>
>> Signed-off-by: Fabien Dessenne <fabien.dessenne@st.com>
>> ---
>> drivers/hid/hid-rmi.c | 2 +-
>> 1 file changed, 1 insertion(+), 1 deletion(-)
>>
>> diff --git a/drivers/hid/hid-rmi.c b/drivers/hid/hid-rmi.c
>> index 9e33165..8748d4d 100644
>> --- a/drivers/hid/hid-rmi.c
>> +++ b/drivers/hid/hid-rmi.c
>> @@ -623,7 +623,7 @@ static int rmi_setup_irq_domain(struct hid_device *hdev)
>> if (!hdata->domain)
>> return -ENOMEM;
>>
>> - ret = devm_add_action_or_reset(&hdev->dev, &rmi_irq_teardown, hdata);
>> + ret = devm_add_action_or_reset(&hdev->dev, rmi_irq_teardown, hdata);
> Why do you think this is wrong C?
Because I was not aware that both func and &func refer to the same
function pointer.
Now I know :)
>
^ permalink raw reply
* Re: [PATCH] HID: rmi: fix devm_add_action_or_reset() parameter
From: Jiri Kosina @ 2019-05-03 12:42 UTC (permalink / raw)
To: Fabien DESSENNE
Cc: Benjamin Tissoires, linux-input@vger.kernel.org,
linux-kernel@vger.kernel.org
In-Reply-To: <9628edde-5270-d5a5-7db6-c9ec3f47c742@st.com>
On Fri, 3 May 2019, Fabien DESSENNE wrote:
> >> - ret = devm_add_action_or_reset(&hdev->dev, &rmi_irq_teardown, hdata);
> >> + ret = devm_add_action_or_reset(&hdev->dev, rmi_irq_teardown, hdata);
> > Why do you think this is wrong C?
>
> Because I was not aware that both func and &func refer to the same
> function pointer.
>
> Now I know :)
Yup, it's defined in 6.3.2.1.4 in C99.
--
Jiri Kosina
SUSE Labs
^ permalink raw reply
* [PATCH v2] HID: fix A4Tech horizontal scrolling
From: Błażej Szczygieł @ 2019-05-03 20:28 UTC (permalink / raw)
Cc: igorkuo, peter.hutterer, Błażej Szczygieł,
Jiri Kosina, Benjamin Tissoires, linux-input, linux-kernel
In-Reply-To: <AO-hwJKNH7WoJV-X+egK5cJNNtxamh0L0e1er5dkiTt6KvrmSQ@mail.gmail.com>
Since recent high resolution scrolling changes the A4Tech driver must
check for the "REL_WHEEL_HI_RES" usage code.
Link: https://bugzilla.kernel.org/show_bug.cgi?id=203369
Fixes: 2dc702c991e3774af9d7ce410eef410ca9e2357e ("HID: input: use the
Resolution Multiplier for high-resolution scrolling")
Signed-off-by: Błażej Szczygieł <spaz16@wp.pl>
---
Changes in v2:
- changed commit message
drivers/hid/hid-a4tech.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/drivers/hid/hid-a4tech.c b/drivers/hid/hid-a4tech.c
index 9428ea7cdf8a..fafb9fa558e7 100644
--- a/drivers/hid/hid-a4tech.c
+++ b/drivers/hid/hid-a4tech.c
@@ -38,7 +38,7 @@ static int a4_input_mapped(struct hid_device *hdev, struct hid_input *hi,
{
struct a4tech_sc *a4 = hid_get_drvdata(hdev);
- if (usage->type == EV_REL && usage->code == REL_WHEEL)
+ if (usage->type == EV_REL && usage->code == REL_WHEEL_HI_RES)
set_bit(REL_HWHEEL, *bit);
if ((a4->quirks & A4_2WHEEL_MOUSE_HACK_7) && usage->hid == 0x00090007)
@@ -60,7 +60,7 @@ static int a4_event(struct hid_device *hdev, struct hid_field *field,
input = field->hidinput->input;
if (a4->quirks & A4_2WHEEL_MOUSE_HACK_B8) {
- if (usage->type == EV_REL && usage->code == REL_WHEEL) {
+ if (usage->type == EV_REL && usage->code == REL_WHEEL_HI_RES) {
a4->delayed_value = value;
return 1;
}
@@ -77,7 +77,7 @@ static int a4_event(struct hid_device *hdev, struct hid_field *field,
return 1;
}
- if (usage->code == REL_WHEEL && a4->hw_wheel) {
+ if (usage->code == REL_WHEEL_HI_RES && a4->hw_wheel) {
input_event(input, usage->type, REL_HWHEEL, value);
return 1;
}
--
2.21.0
^ permalink raw reply related
* [PATCH v5] platform: chrome: Add ChromeOS EC ISHTP driver
From: Rushikesh S Kadam @ 2019-05-04 13:34 UTC (permalink / raw)
To: benjamin.tissoires, jikos, bleung, enric.balletbo, groeck,
srinivas.pandruvada
Cc: linux-kernel, linux-input, ncrews, jettrink, gwendal,
rushikesh.s.kadam
This driver implements a slim layer to enable the ChromeOS
EC kernel stack (cros_ec) to communicate with ChromeOS EC
firmware running on the Intel Integrated Sensor Hub (ISH).
The driver registers a ChromeOS EC MFD device to connect
with cros_ec kernel stack (upper layer), and it registers a
client with the ISH Transport Protocol bus (lower layer) to
talk with the ISH firwmare. See description of the ISHTP
protocol at Documentation/hid/intel-ish-hid.txt
Signed-off-by: Rushikesh S Kadam <rushikesh.s.kadam@intel.com>
Acked-by: Enric Balletbo i Serra <enric.balletbo@collabora.com>
Acked-by: Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>
Reviewed-by: Jett Rink <jettrink@chromium.org>
Tested-by: Jett Rink <jettrink@chromium.org>
---
Submitting the patch to linux-input@ per the discussion here
https://lkml.org/lkml/2019/5/2/339
The patch is baselined to hid git tree, branch for-5.2/ish
https://git.kernel.org/pub/scm/linux/kernel/git/hid/hid.git/log/?h=for-5.2/ish
v5
- Submitting with all Acked-by & Tested-bys. No other changes.
v4
- Coding style related changes. No functional changes. Addresses
review comments on v3.
v3
- Made several changes to improve code readability. Replaced
multiple cl_data_to_dev(client_data) with dev variable. Use
reverse Xmas tree for variable defintion where it made sense.
Dropped few debug prints. Add docstring for function
prepare_cros_ec_rx().
- Fix code in function prepare_cros_ec_rx() under label
end_cros_ec_dev_init_error.
- Recycle buffer in process_recv() on failing to obtain the
semaphore.
- Increase ISHTP TX/RX ring buffer size to 8.
- Alphabetically ordered CROS_EC_ISHTP entries in Makefile and
Kconfig.
- Updated commit message.
v2
- Dropped unused "reset" parameter in function cros_ec_init()
- Change driver name to cros_ec_ishtp to be consistent with other
references in the code.
- Fixed a few typos.
v1
- Initial version
drivers/platform/chrome/Kconfig | 13 +
drivers/platform/chrome/Makefile | 1 +
drivers/platform/chrome/cros_ec_ishtp.c | 763 ++++++++++++++++++++++++++++++++
3 files changed, 777 insertions(+)
create mode 100644 drivers/platform/chrome/cros_ec_ishtp.c
diff --git a/drivers/platform/chrome/Kconfig b/drivers/platform/chrome/Kconfig
index 16b1615..5848179 100644
--- a/drivers/platform/chrome/Kconfig
+++ b/drivers/platform/chrome/Kconfig
@@ -62,6 +62,19 @@ config CROS_EC_I2C
a checksum. Failing accesses will be retried three times to
improve reliability.
+config CROS_EC_ISHTP
+ tristate "ChromeOS Embedded Controller (ISHTP)"
+ depends on MFD_CROS_EC
+ depends on INTEL_ISH_HID
+ help
+ If you say Y here, you get support for talking to the ChromeOS EC
+ firmware running on Intel Integrated Sensor Hub (ISH), using the
+ ISH Transport protocol (ISH-TP). This uses a simple byte-level
+ protocol with a checksum.
+
+ To compile this driver as a module, choose M here: the
+ module will be called cros_ec_ishtp.
+
config CROS_EC_SPI
tristate "ChromeOS Embedded Controller (SPI)"
depends on MFD_CROS_EC && SPI
diff --git a/drivers/platform/chrome/Makefile b/drivers/platform/chrome/Makefile
index cd591bf..4efe102 100644
--- a/drivers/platform/chrome/Makefile
+++ b/drivers/platform/chrome/Makefile
@@ -7,6 +7,7 @@ cros_ec_ctl-objs := cros_ec_sysfs.o cros_ec_lightbar.o \
cros_ec_vbc.o cros_ec_debugfs.o
obj-$(CONFIG_CROS_EC_CTL) += cros_ec_ctl.o
obj-$(CONFIG_CROS_EC_I2C) += cros_ec_i2c.o
+obj-$(CONFIG_CROS_EC_ISHTP) += cros_ec_ishtp.o
obj-$(CONFIG_CROS_EC_SPI) += cros_ec_spi.o
cros_ec_lpcs-objs := cros_ec_lpc.o cros_ec_lpc_reg.o
cros_ec_lpcs-$(CONFIG_CROS_EC_LPC_MEC) += cros_ec_lpc_mec.o
diff --git a/drivers/platform/chrome/cros_ec_ishtp.c b/drivers/platform/chrome/cros_ec_ishtp.c
new file mode 100644
index 0000000..997503d
--- /dev/null
+++ b/drivers/platform/chrome/cros_ec_ishtp.c
@@ -0,0 +1,763 @@
+// SPDX-License-Identifier: GPL-2.0
+// ISHTP interface for ChromeOS Embedded Controller
+//
+// Copyright (c) 2019, Intel Corporation.
+//
+// ISHTP client driver for talking to the Chrome OS EC firmware running
+// on Intel Integrated Sensor Hub (ISH) using the ISH Transport protocol
+// (ISH-TP).
+
+#include <linux/delay.h>
+#include <linux/mfd/core.h>
+#include <linux/mfd/cros_ec.h>
+#include <linux/mfd/cros_ec_commands.h>
+#include <linux/module.h>
+#include <linux/pci.h>
+#include <linux/intel-ish-client-if.h>
+
+/*
+ * ISH TX/RX ring buffer pool size
+ *
+ * The AP->ISH messages and corresponding ISH->AP responses are
+ * serialized. We need 1 TX and 1 RX buffer for these.
+ *
+ * The MKBP ISH->AP events are serialized. We need one additional RX
+ * buffer for them.
+ */
+#define CROS_ISH_CL_TX_RING_SIZE 8
+#define CROS_ISH_CL_RX_RING_SIZE 8
+
+/* ISH CrOS EC Host Commands */
+enum cros_ec_ish_channel {
+ CROS_EC_COMMAND = 1, /* AP->ISH message */
+ CROS_MKBP_EVENT = 2, /* ISH->AP events */
+};
+
+/*
+ * ISH firmware timeout for 1 message send failure is 1Hz, and the
+ * firmware will retry 2 times, so 3Hz is used for timeout.
+ */
+#define ISHTP_SEND_TIMEOUT (3 * HZ)
+
+/* ISH Transport CrOS EC ISH client unique GUID */
+static const guid_t cros_ish_guid =
+ GUID_INIT(0x7b7154d0, 0x56f4, 0x4bdc,
+ 0xb0, 0xd8, 0x9e, 0x7c, 0xda, 0xe0, 0xd6, 0xa0);
+
+struct header {
+ u8 channel;
+ u8 status;
+ u8 reserved[2];
+} __packed;
+
+struct cros_ish_out_msg {
+ struct header hdr;
+ struct ec_host_request ec_request;
+} __packed;
+
+struct cros_ish_in_msg {
+ struct header hdr;
+ struct ec_host_response ec_response;
+} __packed;
+
+#define IN_MSG_EC_RESPONSE_PREAMBLE \
+ offsetof(struct cros_ish_in_msg, ec_response)
+
+#define OUT_MSG_EC_REQUEST_PREAMBLE \
+ offsetof(struct cros_ish_out_msg, ec_request)
+
+#define cl_data_to_dev(client_data) ishtp_device((client_data)->cl_device)
+
+/*
+ * The Read-Write Semaphore is used to prevent message TX or RX while
+ * the ishtp client is being initialized or undergoing reset.
+ *
+ * The readers are the kernel function calls responsible for IA->ISH
+ * and ISH->AP messaging.
+ *
+ * The writers are .reset() and .probe() function.
+ */
+DECLARE_RWSEM(init_lock);
+
+/**
+ * struct response_info - Encapsulate firmware response related
+ * information for passing between function ish_send() and
+ * process_recv() callback.
+ *
+ * @data: Copy the data received from firmware here.
+ * @max_size: Max size allocated for the @data buffer. If the received
+ * data exceeds this value, we log an error.
+ * @size: Actual size of data received from firmware.
+ * @error: 0 for success, negative error code for a failure in process_recv().
+ * @received: Set to true on receiving a valid firmware response to host command
+ * @wait_queue: Wait queue for host to wait for firmware response.
+ */
+struct response_info {
+ void *data;
+ size_t max_size;
+ size_t size;
+ int error;
+ bool received;
+ wait_queue_head_t wait_queue;
+};
+
+/**
+ * struct ishtp_cl_data - Encapsulate per ISH TP Client.
+ *
+ * @cros_ish_cl: ISHTP firmware client instance.
+ * @cl_device: ISHTP client device instance.
+ * @response: Response info passing between ish_send() and process_recv().
+ * @work_ishtp_reset: Work queue reset handling.
+ * @work_ec_evt: Work queue for EC events.
+ * @ec_dev: CrOS EC MFD device.
+ *
+ * This structure is used to store per client data.
+ */
+struct ishtp_cl_data {
+ struct ishtp_cl *cros_ish_cl;
+ struct ishtp_cl_device *cl_device;
+
+ /*
+ * Used for passing firmware response information between
+ * ish_send() and process_recv() callback.
+ */
+ struct response_info response;
+
+ struct work_struct work_ishtp_reset;
+ struct work_struct work_ec_evt;
+ struct cros_ec_device *ec_dev;
+};
+
+/**
+ * ish_evt_handler - ISH to AP event handler
+ * @work: Work struct
+ */
+static void ish_evt_handler(struct work_struct *work)
+{
+ struct ishtp_cl_data *client_data =
+ container_of(work, struct ishtp_cl_data, work_ec_evt);
+ struct cros_ec_device *ec_dev = client_data->ec_dev;
+
+ if (cros_ec_get_next_event(ec_dev, NULL) > 0) {
+ blocking_notifier_call_chain(&ec_dev->event_notifier,
+ 0, ec_dev);
+ }
+}
+
+/**
+ * ish_send() - Send message from host to firmware
+ *
+ * @client_data: Client data instance
+ * @out_msg: Message buffer to be sent to firmware
+ * @out_size: Size of out going message
+ * @in_msg: Message buffer where the incoming data is copied. This buffer
+ * is allocated by calling
+ * @in_size: Max size of incoming message
+ *
+ * Return: Number of bytes copied in the in_msg on success, negative
+ * error code on failure.
+ */
+static int ish_send(struct ishtp_cl_data *client_data,
+ u8 *out_msg, size_t out_size,
+ u8 *in_msg, size_t in_size)
+{
+ int rv;
+ struct header *out_hdr = (struct header *)out_msg;
+ struct ishtp_cl *cros_ish_cl = client_data->cros_ish_cl;
+
+ dev_dbg(cl_data_to_dev(client_data),
+ "%s: channel=%02u status=%02u\n",
+ __func__, out_hdr->channel, out_hdr->status);
+
+ /* Setup for incoming response */
+ client_data->response.data = in_msg;
+ client_data->response.max_size = in_size;
+ client_data->response.error = 0;
+ client_data->response.received = false;
+
+ rv = ishtp_cl_send(cros_ish_cl, out_msg, out_size);
+ if (rv) {
+ dev_err(cl_data_to_dev(client_data),
+ "ishtp_cl_send error %d\n", rv);
+ return rv;
+ }
+
+ wait_event_interruptible_timeout(client_data->response.wait_queue,
+ client_data->response.received,
+ ISHTP_SEND_TIMEOUT);
+ if (!client_data->response.received) {
+ dev_err(cl_data_to_dev(client_data),
+ "Timed out for response to host message\n");
+ return -ETIMEDOUT;
+ }
+
+ if (client_data->response.error < 0)
+ return client_data->response.error;
+
+ return client_data->response.size;
+}
+
+/**
+ * process_recv() - Received and parse incoming packet
+ * @cros_ish_cl: Client instance to get stats
+ * @rb_in_proc: Host interface message buffer
+ *
+ * Parse the incoming packet. If it is a response packet then it will
+ * update per instance flags and wake up the caller waiting to for the
+ * response. If it is an event packet then it will schedule event work.
+ */
+static void process_recv(struct ishtp_cl *cros_ish_cl,
+ struct ishtp_cl_rb *rb_in_proc)
+{
+ size_t data_len = rb_in_proc->buf_idx;
+ struct ishtp_cl_data *client_data =
+ ishtp_get_client_data(cros_ish_cl);
+ struct device *dev = cl_data_to_dev(client_data);
+ struct cros_ish_in_msg *in_msg =
+ (struct cros_ish_in_msg *)rb_in_proc->buffer.data;
+
+ /* Proceed only if reset or init is not in progress */
+ if (!down_read_trylock(&init_lock)) {
+ /* Free the buffer */
+ ishtp_cl_io_rb_recycle(rb_in_proc);
+ dev_warn(dev,
+ "Host is not ready to receive incoming messages\n");
+ return;
+ }
+
+ /*
+ * All firmware messages contain a header. Check the buffer size
+ * before accessing elements inside.
+ */
+ if (!rb_in_proc->buffer.data) {
+ dev_warn(dev, "rb_in_proc->buffer.data returned null");
+ client_data->response.error = -EBADMSG;
+ goto end_error;
+ }
+
+ if (data_len < sizeof(struct header)) {
+ dev_err(dev, "data size %zu is less than header %zu\n",
+ data_len, sizeof(struct header));
+ client_data->response.error = -EMSGSIZE;
+ goto end_error;
+ }
+
+ dev_dbg(dev, "channel=%02u status=%02u\n",
+ in_msg->hdr.channel, in_msg->hdr.status);
+
+ switch (in_msg->hdr.channel) {
+ case CROS_EC_COMMAND:
+ /* Sanity check */
+ if (!client_data->response.data) {
+ dev_err(dev,
+ "Receiving buffer is null. Should be allocated by calling function\n");
+ client_data->response.error = -EINVAL;
+ goto error_wake_up;
+ }
+
+ if (client_data->response.received) {
+ dev_err(dev,
+ "Previous firmware message not yet processed\n");
+ client_data->response.error = -EINVAL;
+ goto error_wake_up;
+ }
+
+ if (data_len > client_data->response.max_size) {
+ dev_err(dev,
+ "Received buffer size %zu is larger than allocated buffer %zu\n",
+ data_len, client_data->response.max_size);
+ client_data->response.error = -EMSGSIZE;
+ goto error_wake_up;
+ }
+
+ if (in_msg->hdr.status) {
+ dev_err(dev, "firmware returned status %d\n",
+ in_msg->hdr.status);
+ client_data->response.error = -EIO;
+ goto error_wake_up;
+ }
+
+ /* Update the actual received buffer size */
+ client_data->response.size = data_len;
+
+ /*
+ * Copy the buffer received in firmware response for the
+ * calling thread.
+ */
+ memcpy(client_data->response.data,
+ rb_in_proc->buffer.data, data_len);
+
+ /* Set flag before waking up the caller */
+ client_data->response.received = true;
+error_wake_up:
+ /* Wake the calling thread */
+ wake_up_interruptible(&client_data->response.wait_queue);
+
+ break;
+
+ case CROS_MKBP_EVENT:
+ /* The event system doesn't send any data in buffer */
+ schedule_work(&client_data->work_ec_evt);
+
+ break;
+
+ default:
+ dev_err(dev, "Invalid channel=%02d\n", in_msg->hdr.channel);
+ }
+
+end_error:
+ /* Free the buffer */
+ ishtp_cl_io_rb_recycle(rb_in_proc);
+
+ up_read(&init_lock);
+}
+
+/**
+ * ish_event_cb() - bus driver callback for incoming message
+ * @cl_device: ISHTP client device for which this message is targeted.
+ *
+ * Remove the packet from the list and process the message by calling
+ * process_recv.
+ */
+static void ish_event_cb(struct ishtp_cl_device *cl_device)
+{
+ struct ishtp_cl_rb *rb_in_proc;
+ struct ishtp_cl *cros_ish_cl = ishtp_get_drvdata(cl_device);
+
+ while ((rb_in_proc = ishtp_cl_rx_get_rb(cros_ish_cl)) != NULL) {
+ /* Decide what to do with received data */
+ process_recv(cros_ish_cl, rb_in_proc);
+ }
+}
+
+/**
+ * cros_ish_init() - Init function for ISHTP client
+ * @cros_ish_cl: ISHTP client instance
+ *
+ * This function complete the initializtion of the client.
+ *
+ * Return: 0 for success, negative error code for failure.
+ */
+static int cros_ish_init(struct ishtp_cl *cros_ish_cl)
+{
+ int rv;
+ struct ishtp_device *dev;
+ struct ishtp_fw_client *fw_client;
+ struct ishtp_cl_data *client_data = ishtp_get_client_data(cros_ish_cl);
+
+ rv = ishtp_cl_link(cros_ish_cl);
+ if (rv) {
+ dev_err(cl_data_to_dev(client_data),
+ "ishtp_cl_link failed\n");
+ return rv;
+ }
+
+ dev = ishtp_get_ishtp_device(cros_ish_cl);
+
+ /* Connect to firmware client */
+ ishtp_set_tx_ring_size(cros_ish_cl, CROS_ISH_CL_TX_RING_SIZE);
+ ishtp_set_rx_ring_size(cros_ish_cl, CROS_ISH_CL_RX_RING_SIZE);
+
+ fw_client = ishtp_fw_cl_get_client(dev, &cros_ish_guid);
+ if (!fw_client) {
+ dev_err(cl_data_to_dev(client_data),
+ "ish client uuid not found\n");
+ rv = -ENOENT;
+ goto err_cl_unlink;
+ }
+
+ ishtp_cl_set_fw_client_id(cros_ish_cl,
+ ishtp_get_fw_client_id(fw_client));
+ ishtp_set_connection_state(cros_ish_cl, ISHTP_CL_CONNECTING);
+
+ rv = ishtp_cl_connect(cros_ish_cl);
+ if (rv) {
+ dev_err(cl_data_to_dev(client_data),
+ "client connect fail\n");
+ goto err_cl_unlink;
+ }
+
+ ishtp_register_event_cb(client_data->cl_device, ish_event_cb);
+ return 0;
+
+err_cl_unlink:
+ ishtp_cl_unlink(cros_ish_cl);
+ return rv;
+}
+
+/**
+ * cros_ish_deinit() - Deinit function for ISHTP client
+ * @cros_ish_cl: ISHTP client instance
+ *
+ * Unlink and free cros_ec client
+ */
+static void cros_ish_deinit(struct ishtp_cl *cros_ish_cl)
+{
+ ishtp_set_connection_state(cros_ish_cl, ISHTP_CL_DISCONNECTING);
+ ishtp_cl_disconnect(cros_ish_cl);
+ ishtp_cl_unlink(cros_ish_cl);
+ ishtp_cl_flush_queues(cros_ish_cl);
+
+ /* Disband and free all Tx and Rx client-level rings */
+ ishtp_cl_free(cros_ish_cl);
+}
+
+/**
+ * prepare_cros_ec_rx() - Check & prepare receive buffer
+ * @ec_dev: CrOS EC MFD device.
+ * @in_msg: Incoming message buffer
+ * @msg: cros_ec command used to send & receive data
+ *
+ * Return: 0 for success, negative error code for failure.
+ *
+ * Check the received buffer. Convert to cros_ec_command format.
+ */
+static int prepare_cros_ec_rx(struct cros_ec_device *ec_dev,
+ const struct cros_ish_in_msg *in_msg,
+ struct cros_ec_command *msg)
+{
+ u8 sum = 0;
+ int i, rv, offset;
+
+ /* Check response error code */
+ msg->result = in_msg->ec_response.result;
+ rv = cros_ec_check_result(ec_dev, msg);
+ if (rv < 0)
+ return rv;
+
+ if (in_msg->ec_response.data_len > msg->insize) {
+ dev_err(ec_dev->dev, "Packet too long (%d bytes, expected %d)",
+ in_msg->ec_response.data_len, msg->insize);
+ return -ENOSPC;
+ }
+
+ /* Copy response packet payload and compute checksum */
+ for (i = 0; i < sizeof(struct ec_host_response); i++)
+ sum += ((u8 *)in_msg)[IN_MSG_EC_RESPONSE_PREAMBLE + i];
+
+ offset = sizeof(struct cros_ish_in_msg);
+ for (i = 0; i < in_msg->ec_response.data_len; i++)
+ sum += msg->data[i] = ((u8 *)in_msg)[offset + i];
+
+ if (sum) {
+ dev_dbg(ec_dev->dev, "Bad received packet checksum %d\n", sum);
+ return -EBADMSG;
+ }
+
+ return 0;
+}
+
+static int cros_ec_pkt_xfer_ish(struct cros_ec_device *ec_dev,
+ struct cros_ec_command *msg)
+{
+ int rv;
+ struct ishtp_cl *cros_ish_cl = ec_dev->priv;
+ struct ishtp_cl_data *client_data = ishtp_get_client_data(cros_ish_cl);
+ struct device *dev = cl_data_to_dev(client_data);
+ struct cros_ish_in_msg *in_msg = (struct cros_ish_in_msg *)ec_dev->din;
+ struct cros_ish_out_msg *out_msg =
+ (struct cros_ish_out_msg *)ec_dev->dout;
+ size_t in_size = sizeof(struct cros_ish_in_msg) + msg->insize;
+ size_t out_size = sizeof(struct cros_ish_out_msg) + msg->outsize;
+
+ /* Proceed only if reset-init is not in progress */
+ if (!down_read_trylock(&init_lock)) {
+ dev_warn(dev,
+ "Host is not ready to send messages to ISH. Try again\n");
+ return -EAGAIN;
+ }
+
+ /* Sanity checks */
+ if (in_size > ec_dev->din_size) {
+ dev_err(dev,
+ "Incoming payload size %zu is too large for ec_dev->din_size %d\n",
+ in_size, ec_dev->din_size);
+ return -EMSGSIZE;
+ }
+
+ if (out_size > ec_dev->dout_size) {
+ dev_err(dev,
+ "Outgoing payload size %zu is too large for ec_dev->dout_size %d\n",
+ out_size, ec_dev->dout_size);
+ return -EMSGSIZE;
+ }
+
+ /* Prepare the package to be sent over ISH TP */
+ out_msg->hdr.channel = CROS_EC_COMMAND;
+ out_msg->hdr.status = 0;
+
+ ec_dev->dout += OUT_MSG_EC_REQUEST_PREAMBLE;
+ cros_ec_prepare_tx(ec_dev, msg);
+ ec_dev->dout -= OUT_MSG_EC_REQUEST_PREAMBLE;
+
+ dev_dbg(dev,
+ "out_msg: struct_ver=0x%x checksum=0x%x command=0x%x command_ver=0x%x data_len=0x%x\n",
+ out_msg->ec_request.struct_version,
+ out_msg->ec_request.checksum,
+ out_msg->ec_request.command,
+ out_msg->ec_request.command_version,
+ out_msg->ec_request.data_len);
+
+ /* Send command to ISH EC firmware and read response */
+ rv = ish_send(client_data,
+ (u8 *)out_msg, out_size,
+ (u8 *)in_msg, in_size);
+ if (rv < 0)
+ goto end_error;
+
+ rv = prepare_cros_ec_rx(ec_dev, in_msg, msg);
+ if (rv)
+ goto end_error;
+
+ rv = in_msg->ec_response.data_len;
+
+ dev_dbg(dev,
+ "in_msg: struct_ver=0x%x checksum=0x%x result=0x%x data_len=0x%x\n",
+ in_msg->ec_response.struct_version,
+ in_msg->ec_response.checksum,
+ in_msg->ec_response.result,
+ in_msg->ec_response.data_len);
+
+end_error:
+ if (msg->command == EC_CMD_REBOOT_EC)
+ msleep(EC_REBOOT_DELAY_MS);
+
+ up_read(&init_lock);
+
+ return rv;
+}
+
+static int cros_ec_dev_init(struct ishtp_cl_data *client_data)
+{
+ struct cros_ec_device *ec_dev;
+ struct device *dev = cl_data_to_dev(client_data);
+
+ ec_dev = devm_kzalloc(dev, sizeof(*ec_dev), GFP_KERNEL);
+ if (!ec_dev)
+ return -ENOMEM;
+
+ client_data->ec_dev = ec_dev;
+ dev->driver_data = ec_dev;
+
+ ec_dev->dev = dev;
+ ec_dev->priv = client_data->cros_ish_cl;
+ ec_dev->cmd_xfer = NULL;
+ ec_dev->pkt_xfer = cros_ec_pkt_xfer_ish;
+ ec_dev->phys_name = dev_name(dev);
+ ec_dev->din_size = sizeof(struct cros_ish_in_msg) +
+ sizeof(struct ec_response_get_protocol_info);
+ ec_dev->dout_size = sizeof(struct cros_ish_out_msg);
+
+ return cros_ec_register(ec_dev);
+}
+
+static void reset_handler(struct work_struct *work)
+{
+ int rv;
+ struct device *dev;
+ struct ishtp_cl *cros_ish_cl;
+ struct ishtp_cl_device *cl_device;
+ struct ishtp_cl_data *client_data =
+ container_of(work, struct ishtp_cl_data, work_ishtp_reset);
+
+ /* Lock for reset to complete */
+ down_write(&init_lock);
+
+ cros_ish_cl = client_data->cros_ish_cl;
+ cl_device = client_data->cl_device;
+
+ /* Unlink, flush queues & start again */
+ ishtp_cl_unlink(cros_ish_cl);
+ ishtp_cl_flush_queues(cros_ish_cl);
+ ishtp_cl_free(cros_ish_cl);
+
+ cros_ish_cl = ishtp_cl_allocate(cl_device);
+ if (!cros_ish_cl) {
+ up_write(&init_lock);
+ return;
+ }
+
+ ishtp_set_drvdata(cl_device, cros_ish_cl);
+ ishtp_set_client_data(cros_ish_cl, client_data);
+ client_data->cros_ish_cl = cros_ish_cl;
+
+ rv = cros_ish_init(cros_ish_cl);
+ if (rv) {
+ ishtp_cl_free(cros_ish_cl);
+ dev_err(cl_data_to_dev(client_data), "Reset Failed\n");
+ up_write(&init_lock);
+ return;
+ }
+
+ /* Refresh ec_dev device pointers */
+ client_data->ec_dev->priv = client_data->cros_ish_cl;
+ dev = cl_data_to_dev(client_data);
+ dev->driver_data = client_data->ec_dev;
+
+ dev_info(cl_data_to_dev(client_data), "Chrome EC ISH reset done\n");
+
+ up_write(&init_lock);
+}
+
+/**
+ * cros_ec_ishtp_probe() - ISHTP client driver probe callback
+ * @cl_device: ISHTP client device instance
+ *
+ * Return: 0 for success, negative error code for failure.
+ */
+static int cros_ec_ishtp_probe(struct ishtp_cl_device *cl_device)
+{
+ int rv;
+ struct ishtp_cl *cros_ish_cl;
+ struct ishtp_cl_data *client_data =
+ devm_kzalloc(ishtp_device(cl_device),
+ sizeof(*client_data), GFP_KERNEL);
+ if (!client_data)
+ return -ENOMEM;
+
+ /* Lock for initialization to complete */
+ down_write(&init_lock);
+
+ cros_ish_cl = ishtp_cl_allocate(cl_device);
+ if (!cros_ish_cl) {
+ rv = -ENOMEM;
+ goto end_ishtp_cl_alloc_error;
+ }
+
+ ishtp_set_drvdata(cl_device, cros_ish_cl);
+ ishtp_set_client_data(cros_ish_cl, client_data);
+ client_data->cros_ish_cl = cros_ish_cl;
+ client_data->cl_device = cl_device;
+
+ init_waitqueue_head(&client_data->response.wait_queue);
+
+ INIT_WORK(&client_data->work_ishtp_reset,
+ reset_handler);
+ INIT_WORK(&client_data->work_ec_evt,
+ ish_evt_handler);
+
+ rv = cros_ish_init(cros_ish_cl);
+ if (rv)
+ goto end_ishtp_cl_init_error;
+
+ ishtp_get_device(cl_device);
+
+ up_write(&init_lock);
+
+ /* Register croc_ec_dev mfd */
+ rv = cros_ec_dev_init(client_data);
+ if (rv)
+ goto end_cros_ec_dev_init_error;
+
+ return 0;
+
+end_cros_ec_dev_init_error:
+ ishtp_set_connection_state(cros_ish_cl, ISHTP_CL_DISCONNECTING);
+ ishtp_cl_disconnect(cros_ish_cl);
+ ishtp_cl_unlink(cros_ish_cl);
+ ishtp_cl_flush_queues(cros_ish_cl);
+ ishtp_put_device(cl_device);
+end_ishtp_cl_init_error:
+ ishtp_cl_free(cros_ish_cl);
+end_ishtp_cl_alloc_error:
+ up_write(&init_lock);
+ return rv;
+}
+
+/**
+ * cros_ec_ishtp_remove() - ISHTP client driver remove callback
+ * @cl_device: ISHTP client device instance
+ *
+ * Return: 0
+ */
+static int cros_ec_ishtp_remove(struct ishtp_cl_device *cl_device)
+{
+ struct ishtp_cl *cros_ish_cl = ishtp_get_drvdata(cl_device);
+ struct ishtp_cl_data *client_data = ishtp_get_client_data(cros_ish_cl);
+
+ cancel_work_sync(&client_data->work_ishtp_reset);
+ cancel_work_sync(&client_data->work_ec_evt);
+ cros_ish_deinit(cros_ish_cl);
+ ishtp_put_device(cl_device);
+
+ return 0;
+}
+
+/**
+ * cros_ec_ishtp_reset() - ISHTP client driver reset callback
+ * @cl_device: ISHTP client device instance
+ *
+ * Return: 0
+ */
+static int cros_ec_ishtp_reset(struct ishtp_cl_device *cl_device)
+{
+ struct ishtp_cl *cros_ish_cl = ishtp_get_drvdata(cl_device);
+ struct ishtp_cl_data *client_data = ishtp_get_client_data(cros_ish_cl);
+
+ schedule_work(&client_data->work_ishtp_reset);
+
+ return 0;
+}
+
+/**
+ * cros_ec_ishtp_suspend() - ISHTP client driver suspend callback
+ * @device: device instance
+ *
+ * Return: 0 for success, negative error code for failure.
+ */
+static int __maybe_unused cros_ec_ishtp_suspend(struct device *device)
+{
+ struct ishtp_cl_device *cl_device = dev_get_drvdata(device);
+ struct ishtp_cl *cros_ish_cl = ishtp_get_drvdata(cl_device);
+ struct ishtp_cl_data *client_data = ishtp_get_client_data(cros_ish_cl);
+
+ return cros_ec_suspend(client_data->ec_dev);
+}
+
+/**
+ * cros_ec_ishtp_resume() - ISHTP client driver resume callback
+ * @device: device instance
+ *
+ * Return: 0 for success, negative error code for failure.
+ */
+static int __maybe_unused cros_ec_ishtp_resume(struct device *device)
+{
+ struct ishtp_cl_device *cl_device = dev_get_drvdata(device);
+ struct ishtp_cl *cros_ish_cl = ishtp_get_drvdata(cl_device);
+ struct ishtp_cl_data *client_data = ishtp_get_client_data(cros_ish_cl);
+
+ return cros_ec_resume(client_data->ec_dev);
+}
+
+static SIMPLE_DEV_PM_OPS(cros_ec_ishtp_pm_ops, cros_ec_ishtp_suspend,
+ cros_ec_ishtp_resume);
+
+static struct ishtp_cl_driver cros_ec_ishtp_driver = {
+ .name = "cros_ec_ishtp",
+ .guid = &cros_ish_guid,
+ .probe = cros_ec_ishtp_probe,
+ .remove = cros_ec_ishtp_remove,
+ .reset = cros_ec_ishtp_reset,
+ .driver = {
+ .pm = &cros_ec_ishtp_pm_ops,
+ },
+};
+
+static int __init cros_ec_ishtp_mod_init(void)
+{
+ return ishtp_cl_driver_register(&cros_ec_ishtp_driver, THIS_MODULE);
+}
+
+static void __exit cros_ec_ishtp_mod_exit(void)
+{
+ ishtp_cl_driver_unregister(&cros_ec_ishtp_driver);
+}
+
+module_init(cros_ec_ishtp_mod_init);
+module_exit(cros_ec_ishtp_mod_exit);
+
+MODULE_DESCRIPTION("ChromeOS EC ISHTP Client Driver");
+MODULE_AUTHOR("Rushikesh S Kadam <rushikesh.s.kadam@intel.com>");
+
+MODULE_LICENSE("GPL v2");
+MODULE_ALIAS("ishtp:*");
--
1.9.1
^ permalink raw reply related
* [PATCH] HID: uclogic: fix dereferences of hdev before null check on hdev
From: Colin King @ 2019-05-04 17:22 UTC (permalink / raw)
To: Jiri Kosina, Benjamin Tissoires, linux-input
Cc: kernel-janitors, linux-kernel
From: Colin Ian King <colin.king@canonical.com>
Currently hdev is being dereferenced when using macro hid_to_usb_dev
before hdev is being null checked, hence there is a potential null
pointer dereference. Fix this by only dereferencing hdev after it has
been null checked.
Fixes: 9614219e9310 ("HID: uclogic: Extract tablet parameter discovery into a module")
Signed-off-by: Colin Ian King <colin.king@canonical.com>
---
drivers/hid/hid-uclogic-params.c | 20 +++++++++++++-------
1 file changed, 13 insertions(+), 7 deletions(-)
diff --git a/drivers/hid/hid-uclogic-params.c b/drivers/hid/hid-uclogic-params.c
index 0187c9f8fc22..bc5a2f860501 100644
--- a/drivers/hid/hid-uclogic-params.c
+++ b/drivers/hid/hid-uclogic-params.c
@@ -65,7 +65,7 @@ static int uclogic_params_get_str_desc(__u8 **pbuf, struct hid_device *hdev,
__u8 idx, size_t len)
{
int rc;
- struct usb_device *udev = hid_to_usb_dev(hdev);
+ struct usb_device *udev;
__u8 *buf = NULL;
/* Check arguments */
@@ -73,6 +73,7 @@ static int uclogic_params_get_str_desc(__u8 **pbuf, struct hid_device *hdev,
rc = -EINVAL;
goto cleanup;
}
+ udev = hid_to_usb_dev(hdev);
buf = kmalloc(len, GFP_KERNEL);
if (buf == NULL) {
@@ -449,7 +450,7 @@ static int uclogic_params_frame_init_v1_buttonpad(
{
int rc;
bool found = false;
- struct usb_device *usb_dev = hid_to_usb_dev(hdev);
+ struct usb_device *usb_dev;
char *str_buf = NULL;
const size_t str_len = 16;
@@ -458,6 +459,7 @@ static int uclogic_params_frame_init_v1_buttonpad(
rc = -EINVAL;
goto cleanup;
}
+ usb_dev = hid_to_usb_dev(hdev);
/*
* Enable generic button mode
@@ -705,7 +707,7 @@ static int uclogic_params_huion_init(struct uclogic_params *params,
struct hid_device *hdev)
{
int rc;
- struct usb_device *udev = hid_to_usb_dev(hdev);
+ struct usb_device *udev;
struct usb_interface *iface = to_usb_interface(hdev->dev.parent);
__u8 bInterfaceNumber = iface->cur_altsetting->desc.bInterfaceNumber;
bool found;
@@ -720,6 +722,7 @@ static int uclogic_params_huion_init(struct uclogic_params *params,
rc = -EINVAL;
goto cleanup;
}
+ udev = hid_to_usb_dev(hdev);
/* If it's not a pen interface */
if (bInterfaceNumber != 0) {
@@ -832,10 +835,9 @@ int uclogic_params_init(struct uclogic_params *params,
struct hid_device *hdev)
{
int rc;
- struct usb_device *udev = hid_to_usb_dev(hdev);
- __u8 bNumInterfaces = udev->config->desc.bNumInterfaces;
- struct usb_interface *iface = to_usb_interface(hdev->dev.parent);
- __u8 bInterfaceNumber = iface->cur_altsetting->desc.bInterfaceNumber;
+ struct usb_device *udev;
+ struct usb_interface *iface;
+ __u8 bNumInterfaces, bInterfaceNumber;
bool found;
/* The resulting parameters (noop) */
struct uclogic_params p = {0, };
@@ -846,6 +848,10 @@ int uclogic_params_init(struct uclogic_params *params,
rc = -EINVAL;
goto cleanup;
}
+ udev = hid_to_usb_dev(hdev);
+ bNumInterfaces = udev->config->desc.bNumInterfaces;
+ iface = to_usb_interface(hdev->dev.parent);
+ bInterfaceNumber = iface->cur_altsetting->desc.bInterfaceNumber;
/*
* Set replacement report descriptor if the original matches the
--
2.20.1
^ permalink raw reply related
* KASAN: use-after-free Read in add_uevent_var
From: syzbot @ 2019-05-04 18:16 UTC (permalink / raw)
To: airlied, dmitry.torokhov, dri-devel, hpa, linux-input,
linux-kernel, mingo, patrik.r.jakobsson, rydberg, syzkaller-bugs,
tglx, wsa, x86
Hello,
syzbot found the following crash on:
HEAD commit: a4ccb5f9 Merge tag 'drm-fixes-2019-05-03' of git://anongit..
git tree: upstream
console output: https://syzkaller.appspot.com/x/log.txt?x=1205d570a00000
kernel config: https://syzkaller.appspot.com/x/.config?x=2bd0da4b8de0b004
dashboard link: https://syzkaller.appspot.com/bug?extid=6da9575ba2db4da91831
compiler: gcc (GCC) 9.0.0 20181231 (experimental)
userspace arch: i386
syz repro: https://syzkaller.appspot.com/x/repro.syz?x=1769f62ca00000
C reproducer: https://syzkaller.appspot.com/x/repro.c?x=167ae984a00000
The bug was bisected to:
commit 0a1c7959acd9674a0e4e59f911f3e5fbf25fd693
Author: Wolfram Sang <wsa@the-dreams.de>
Date: Wed May 17 15:22:18 2017 +0000
gpu: drm: tc35876x: move header file out of I2C realm
bisection log: https://syzkaller.appspot.com/x/bisect.txt?x=138fe12ca00000
final crash: https://syzkaller.appspot.com/x/report.txt?x=104fe12ca00000
console output: https://syzkaller.appspot.com/x/log.txt?x=178fe12ca00000
IMPORTANT: if you fix the bug, please add the following tag to the commit:
Reported-by: syzbot+6da9575ba2db4da91831@syzkaller.appspotmail.com
Fixes: 0a1c7959acd9 ("gpu: drm: tc35876x: move header file out of I2C
realm")
RAX: ffffffffffffffda RBX: 0000000000000003 RCX: 0000000000005502
RDX: 0000000000000000 RSI: 00000000080daf20 RDI: 00000000080f0f84
RBP: 0000000000000000 R08: 0000000000000000 R09: 0000000000000000
R10: 0000000000000000 R11: 0000000000000000 R12: 0000000000000000
R13: 0000000000000000 R14: 0000000000000000 R15: 0000000000000000
==================================================================
BUG: KASAN: use-after-free in string+0x208/0x230 lib/vsprintf.c:606
Read of size 1 at addr ffff8880a55aa200 by task syz-executor222/7839
CPU: 1 PID: 7839 Comm: syz-executor222 Not tainted 5.1.0-rc7+ #98
Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS
Google 01/01/2011
Call Trace:
__dump_stack lib/dump_stack.c:77 [inline]
dump_stack+0x172/0x1f0 lib/dump_stack.c:113
print_address_description.cold+0x7c/0x20d mm/kasan/report.c:187
kasan_report.cold+0x1b/0x40 mm/kasan/report.c:317
__asan_report_load1_noabort+0x14/0x20 mm/kasan/generic_report.c:129
string+0x208/0x230 lib/vsprintf.c:606
vsnprintf+0xbfc/0x1af0 lib/vsprintf.c:2396
add_uevent_var+0x14d/0x310 lib/kobject_uevent.c:661
input_dev_uevent+0x163/0x890 drivers/input/input.c:1594
dev_uevent+0x312/0x580 drivers/base/core.c:1180
kobject_uevent_env+0x487/0x1030 lib/kobject_uevent.c:549
kobject_uevent+0x20/0x26 lib/kobject_uevent.c:638
kobject_cleanup lib/kobject.c:649 [inline]
kobject_release lib/kobject.c:691 [inline]
kref_put include/linux/kref.h:67 [inline]
kobject_put.cold+0x177/0x2ec lib/kobject.c:708
put_device+0x20/0x30 drivers/base/core.c:2205
input_put_device include/linux/input.h:349 [inline]
evdev_free+0x51/0x70 drivers/input/evdev.c:369
device_release+0x7d/0x210 drivers/base/core.c:1064
kobject_cleanup lib/kobject.c:662 [inline]
kobject_release lib/kobject.c:691 [inline]
kref_put include/linux/kref.h:67 [inline]
kobject_put.cold+0x28f/0x2ec lib/kobject.c:708
cdev_default_release+0x41/0x50 fs/char_dev.c:607
kobject_cleanup lib/kobject.c:662 [inline]
kobject_release lib/kobject.c:691 [inline]
kref_put include/linux/kref.h:67 [inline]
kobject_put.cold+0x28f/0x2ec lib/kobject.c:708
cdev_put.part.0+0x39/0x50 fs/char_dev.c:368
cdev_put+0x20/0x30 fs/char_dev.c:366
__fput+0x6df/0x8d0 fs/file_table.c:281
____fput+0x16/0x20 fs/file_table.c:309
task_work_run+0x14a/0x1c0 kernel/task_work.c:113
exit_task_work include/linux/task_work.h:22 [inline]
do_exit+0x90a/0x2fa0 kernel/exit.c:876
do_group_exit+0x135/0x370 kernel/exit.c:980
__do_sys_exit_group kernel/exit.c:991 [inline]
__se_sys_exit_group kernel/exit.c:989 [inline]
__ia32_sys_exit_group+0x44/0x50 kernel/exit.c:989
do_syscall_32_irqs_on arch/x86/entry/common.c:326 [inline]
do_fast_syscall_32+0x281/0xc98 arch/x86/entry/common.c:397
entry_SYSENTER_compat+0x70/0x7f arch/x86/entry/entry_64_compat.S:139
RIP: 0023:0xf7ff7849
Code: 85 d2 74 02 89 0a 5b 5d c3 8b 04 24 c3 8b 14 24 c3 8b 3c 24 c3 90 90
90 90 90 90 90 90 90 90 90 90 51 52 55 89 e5 0f 34 cd 80 <5d> 5a 59 c3 90
90 90 90 eb 0d 90 90 90 90 90 90 90 90 90 90 90 90
RSP: 002b:00000000fff2db8c EFLAGS: 00000292 ORIG_RAX: 00000000000000fc
RAX: ffffffffffffffda RBX: 0000000000000000 RCX: 00000000080f1298
RDX: 0000000000000000 RSI: 00000000080daf1c RDI: 00000000080f12a0
RBP: 0000000000000001 R08: 0000000000000000 R09: 0000000000000000
R10: 0000000000000000 R11: 0000000000000000 R12: 0000000000000000
R13: 0000000000000000 R14: 0000000000000000 R15: 0000000000000000
Allocated by task 7839:
save_stack+0x45/0xd0 mm/kasan/common.c:75
set_track mm/kasan/common.c:87 [inline]
__kasan_kmalloc mm/kasan/common.c:497 [inline]
__kasan_kmalloc.constprop.0+0xcf/0xe0 mm/kasan/common.c:470
kasan_kmalloc+0x9/0x10 mm/kasan/common.c:511
__do_kmalloc mm/slab.c:3727 [inline]
__kmalloc_track_caller+0x158/0x740 mm/slab.c:3742
kstrndup+0x5f/0xf0 mm/util.c:96
uinput_dev_setup+0x1d4/0x310 drivers/input/misc/uinput.c:475
uinput_ioctl_handler.isra.0+0x12b8/0x1cc0 drivers/input/misc/uinput.c:886
uinput_compat_ioctl+0x70/0x90 drivers/input/misc/uinput.c:1062
__do_compat_sys_ioctl fs/compat_ioctl.c:1052 [inline]
__se_compat_sys_ioctl fs/compat_ioctl.c:998 [inline]
__ia32_compat_sys_ioctl+0x197/0x620 fs/compat_ioctl.c:998
do_syscall_32_irqs_on arch/x86/entry/common.c:326 [inline]
do_fast_syscall_32+0x281/0xc98 arch/x86/entry/common.c:397
entry_SYSENTER_compat+0x70/0x7f arch/x86/entry/entry_64_compat.S:139
Freed by task 7839:
save_stack+0x45/0xd0 mm/kasan/common.c:75
set_track mm/kasan/common.c:87 [inline]
__kasan_slab_free+0x102/0x150 mm/kasan/common.c:459
kasan_slab_free+0xe/0x10 mm/kasan/common.c:467
__cache_free mm/slab.c:3499 [inline]
kfree+0xcf/0x230 mm/slab.c:3822
uinput_destroy_device+0xf8/0x250 drivers/input/misc/uinput.c:311
uinput_ioctl_handler.isra.0+0x886/0x1cc0 drivers/input/misc/uinput.c:882
uinput_compat_ioctl+0x70/0x90 drivers/input/misc/uinput.c:1062
__do_compat_sys_ioctl fs/compat_ioctl.c:1052 [inline]
__se_compat_sys_ioctl fs/compat_ioctl.c:998 [inline]
__ia32_compat_sys_ioctl+0x197/0x620 fs/compat_ioctl.c:998
do_syscall_32_irqs_on arch/x86/entry/common.c:326 [inline]
do_fast_syscall_32+0x281/0xc98 arch/x86/entry/common.c:397
entry_SYSENTER_compat+0x70/0x7f arch/x86/entry/entry_64_compat.S:139
The buggy address belongs to the object at ffff8880a55aa200
which belongs to the cache kmalloc-32 of size 32
The buggy address is located 0 bytes inside of
32-byte region [ffff8880a55aa200, ffff8880a55aa220)
The buggy address belongs to the page:
page:ffffea0002956a80 count:1 mapcount:0 mapping:ffff8880aa4001c0
index:0xffff8880a55aafc1
flags: 0x1fffc0000000200(slab)
raw: 01fffc0000000200 ffffea0002949e88 ffffea00029482c8 ffff8880aa4001c0
raw: ffff8880a55aafc1 ffff8880a55aa000 0000000100000039 0000000000000000
page dumped because: kasan: bad access detected
Memory state around the buggy address:
ffff8880a55aa100: fb fb fb fb fc fc fc fc fb fb fb fb fc fc fc fc
ffff8880a55aa180: fb fb fb fb fc fc fc fc fb fb fb fb fc fc fc fc
> ffff8880a55aa200: fb fb fb fb fc fc fc fc fb fb fb fb fc fc fc fc
^
ffff8880a55aa280: fb fb fb fb fc fc fc fc fb fb fb fb fc fc fc fc
ffff8880a55aa300: fb fb fb fb fc fc fc fc fb fb fb fb fc fc fc fc
==================================================================
---
This bug is generated by a bot. It may contain errors.
See https://goo.gl/tpsmEJ for more information about syzbot.
syzbot engineers can be reached at syzkaller@googlegroups.com.
syzbot will keep track of this bug report. See:
https://goo.gl/tpsmEJ#status for how to communicate with syzbot.
For information about bisection process see: https://goo.gl/tpsmEJ#bisection
syzbot can test patches for this bug, for details see:
https://goo.gl/tpsmEJ#testing-patches
^ permalink raw reply
* Re: KASAN: use-after-free Read in add_uevent_var
From: Tetsuo Handa @ 2019-05-05 8:44 UTC (permalink / raw)
To: syzbot, syzkaller-bugs
Cc: airlied, dmitry.torokhov, dri-devel, hpa, linux-input,
linux-kernel, mingo, patrik.r.jakobsson, rydberg, tglx, wsa, x86
In-Reply-To: <000000000000559435058813dc8d@google.com>
This seems to be triggered by "pkg/report: skip printk and other printing functions " on syzbot side.
The fix should be "kobject: Don't trigger kobject_uevent(KOBJ_REMOVE) twice." in linux-next.git.
#syz dup: KASAN: use-after-free Read in string
^ permalink raw reply
* Re: KASAN: use-after-free Read in add_uevent_var
From: Daniel Vetter @ 2019-05-06 8:15 UTC (permalink / raw)
To: syzbot
Cc: airlied, dmitry.torokhov, dri-devel, hpa, linux-input,
linux-kernel, mingo, patrik.r.jakobsson, rydberg, syzkaller-bugs,
tglx, wsa, x86
In-Reply-To: <000000000000559435058813dc8d@google.com>
On Sat, May 04, 2019 at 11:16:05AM -0700, syzbot wrote:
> Hello,
>
> syzbot found the following crash on:
>
> HEAD commit: a4ccb5f9 Merge tag 'drm-fixes-2019-05-03' of git://anongit..
> git tree: upstream
> console output: https://syzkaller.appspot.com/x/log.txt?x=1205d570a00000
> kernel config: https://syzkaller.appspot.com/x/.config?x=2bd0da4b8de0b004
> dashboard link: https://syzkaller.appspot.com/bug?extid=6da9575ba2db4da91831
> compiler: gcc (GCC) 9.0.0 20181231 (experimental)
> userspace arch: i386
> syz repro: https://syzkaller.appspot.com/x/repro.syz?x=1769f62ca00000
> C reproducer: https://syzkaller.appspot.com/x/repro.c?x=167ae984a00000
>
> The bug was bisected to:
>
> commit 0a1c7959acd9674a0e4e59f911f3e5fbf25fd693
> Author: Wolfram Sang <wsa@the-dreams.de>
> Date: Wed May 17 15:22:18 2017 +0000
>
> gpu: drm: tc35876x: move header file out of I2C realm
Bisect seems to have gone off the rails. No idea where or why.
-Daniel
>
> bisection log: https://syzkaller.appspot.com/x/bisect.txt?x=138fe12ca00000
> final crash: https://syzkaller.appspot.com/x/report.txt?x=104fe12ca00000
> console output: https://syzkaller.appspot.com/x/log.txt?x=178fe12ca00000
>
> IMPORTANT: if you fix the bug, please add the following tag to the commit:
> Reported-by: syzbot+6da9575ba2db4da91831@syzkaller.appspotmail.com
> Fixes: 0a1c7959acd9 ("gpu: drm: tc35876x: move header file out of I2C
> realm")
>
> RAX: ffffffffffffffda RBX: 0000000000000003 RCX: 0000000000005502
> RDX: 0000000000000000 RSI: 00000000080daf20 RDI: 00000000080f0f84
> RBP: 0000000000000000 R08: 0000000000000000 R09: 0000000000000000
> R10: 0000000000000000 R11: 0000000000000000 R12: 0000000000000000
> R13: 0000000000000000 R14: 0000000000000000 R15: 0000000000000000
> ==================================================================
> BUG: KASAN: use-after-free in string+0x208/0x230 lib/vsprintf.c:606
> Read of size 1 at addr ffff8880a55aa200 by task syz-executor222/7839
>
> CPU: 1 PID: 7839 Comm: syz-executor222 Not tainted 5.1.0-rc7+ #98
> Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS
> Google 01/01/2011
> Call Trace:
> __dump_stack lib/dump_stack.c:77 [inline]
> dump_stack+0x172/0x1f0 lib/dump_stack.c:113
> print_address_description.cold+0x7c/0x20d mm/kasan/report.c:187
> kasan_report.cold+0x1b/0x40 mm/kasan/report.c:317
> __asan_report_load1_noabort+0x14/0x20 mm/kasan/generic_report.c:129
> string+0x208/0x230 lib/vsprintf.c:606
> vsnprintf+0xbfc/0x1af0 lib/vsprintf.c:2396
> add_uevent_var+0x14d/0x310 lib/kobject_uevent.c:661
> input_dev_uevent+0x163/0x890 drivers/input/input.c:1594
> dev_uevent+0x312/0x580 drivers/base/core.c:1180
> kobject_uevent_env+0x487/0x1030 lib/kobject_uevent.c:549
> kobject_uevent+0x20/0x26 lib/kobject_uevent.c:638
> kobject_cleanup lib/kobject.c:649 [inline]
> kobject_release lib/kobject.c:691 [inline]
> kref_put include/linux/kref.h:67 [inline]
> kobject_put.cold+0x177/0x2ec lib/kobject.c:708
> put_device+0x20/0x30 drivers/base/core.c:2205
> input_put_device include/linux/input.h:349 [inline]
> evdev_free+0x51/0x70 drivers/input/evdev.c:369
> device_release+0x7d/0x210 drivers/base/core.c:1064
> kobject_cleanup lib/kobject.c:662 [inline]
> kobject_release lib/kobject.c:691 [inline]
> kref_put include/linux/kref.h:67 [inline]
> kobject_put.cold+0x28f/0x2ec lib/kobject.c:708
> cdev_default_release+0x41/0x50 fs/char_dev.c:607
> kobject_cleanup lib/kobject.c:662 [inline]
> kobject_release lib/kobject.c:691 [inline]
> kref_put include/linux/kref.h:67 [inline]
> kobject_put.cold+0x28f/0x2ec lib/kobject.c:708
> cdev_put.part.0+0x39/0x50 fs/char_dev.c:368
> cdev_put+0x20/0x30 fs/char_dev.c:366
> __fput+0x6df/0x8d0 fs/file_table.c:281
> ____fput+0x16/0x20 fs/file_table.c:309
> task_work_run+0x14a/0x1c0 kernel/task_work.c:113
> exit_task_work include/linux/task_work.h:22 [inline]
> do_exit+0x90a/0x2fa0 kernel/exit.c:876
> do_group_exit+0x135/0x370 kernel/exit.c:980
> __do_sys_exit_group kernel/exit.c:991 [inline]
> __se_sys_exit_group kernel/exit.c:989 [inline]
> __ia32_sys_exit_group+0x44/0x50 kernel/exit.c:989
> do_syscall_32_irqs_on arch/x86/entry/common.c:326 [inline]
> do_fast_syscall_32+0x281/0xc98 arch/x86/entry/common.c:397
> entry_SYSENTER_compat+0x70/0x7f arch/x86/entry/entry_64_compat.S:139
> RIP: 0023:0xf7ff7849
> Code: 85 d2 74 02 89 0a 5b 5d c3 8b 04 24 c3 8b 14 24 c3 8b 3c 24 c3 90 90
> 90 90 90 90 90 90 90 90 90 90 51 52 55 89 e5 0f 34 cd 80 <5d> 5a 59 c3 90 90
> 90 90 eb 0d 90 90 90 90 90 90 90 90 90 90 90 90
> RSP: 002b:00000000fff2db8c EFLAGS: 00000292 ORIG_RAX: 00000000000000fc
> RAX: ffffffffffffffda RBX: 0000000000000000 RCX: 00000000080f1298
> RDX: 0000000000000000 RSI: 00000000080daf1c RDI: 00000000080f12a0
> RBP: 0000000000000001 R08: 0000000000000000 R09: 0000000000000000
> R10: 0000000000000000 R11: 0000000000000000 R12: 0000000000000000
> R13: 0000000000000000 R14: 0000000000000000 R15: 0000000000000000
>
> Allocated by task 7839:
> save_stack+0x45/0xd0 mm/kasan/common.c:75
> set_track mm/kasan/common.c:87 [inline]
> __kasan_kmalloc mm/kasan/common.c:497 [inline]
> __kasan_kmalloc.constprop.0+0xcf/0xe0 mm/kasan/common.c:470
> kasan_kmalloc+0x9/0x10 mm/kasan/common.c:511
> __do_kmalloc mm/slab.c:3727 [inline]
> __kmalloc_track_caller+0x158/0x740 mm/slab.c:3742
> kstrndup+0x5f/0xf0 mm/util.c:96
> uinput_dev_setup+0x1d4/0x310 drivers/input/misc/uinput.c:475
> uinput_ioctl_handler.isra.0+0x12b8/0x1cc0 drivers/input/misc/uinput.c:886
> uinput_compat_ioctl+0x70/0x90 drivers/input/misc/uinput.c:1062
> __do_compat_sys_ioctl fs/compat_ioctl.c:1052 [inline]
> __se_compat_sys_ioctl fs/compat_ioctl.c:998 [inline]
> __ia32_compat_sys_ioctl+0x197/0x620 fs/compat_ioctl.c:998
> do_syscall_32_irqs_on arch/x86/entry/common.c:326 [inline]
> do_fast_syscall_32+0x281/0xc98 arch/x86/entry/common.c:397
> entry_SYSENTER_compat+0x70/0x7f arch/x86/entry/entry_64_compat.S:139
>
> Freed by task 7839:
> save_stack+0x45/0xd0 mm/kasan/common.c:75
> set_track mm/kasan/common.c:87 [inline]
> __kasan_slab_free+0x102/0x150 mm/kasan/common.c:459
> kasan_slab_free+0xe/0x10 mm/kasan/common.c:467
> __cache_free mm/slab.c:3499 [inline]
> kfree+0xcf/0x230 mm/slab.c:3822
> uinput_destroy_device+0xf8/0x250 drivers/input/misc/uinput.c:311
> uinput_ioctl_handler.isra.0+0x886/0x1cc0 drivers/input/misc/uinput.c:882
> uinput_compat_ioctl+0x70/0x90 drivers/input/misc/uinput.c:1062
> __do_compat_sys_ioctl fs/compat_ioctl.c:1052 [inline]
> __se_compat_sys_ioctl fs/compat_ioctl.c:998 [inline]
> __ia32_compat_sys_ioctl+0x197/0x620 fs/compat_ioctl.c:998
> do_syscall_32_irqs_on arch/x86/entry/common.c:326 [inline]
> do_fast_syscall_32+0x281/0xc98 arch/x86/entry/common.c:397
> entry_SYSENTER_compat+0x70/0x7f arch/x86/entry/entry_64_compat.S:139
>
> The buggy address belongs to the object at ffff8880a55aa200
> which belongs to the cache kmalloc-32 of size 32
> The buggy address is located 0 bytes inside of
> 32-byte region [ffff8880a55aa200, ffff8880a55aa220)
> The buggy address belongs to the page:
> page:ffffea0002956a80 count:1 mapcount:0 mapping:ffff8880aa4001c0
> index:0xffff8880a55aafc1
> flags: 0x1fffc0000000200(slab)
> raw: 01fffc0000000200 ffffea0002949e88 ffffea00029482c8 ffff8880aa4001c0
> raw: ffff8880a55aafc1 ffff8880a55aa000 0000000100000039 0000000000000000
> page dumped because: kasan: bad access detected
>
> Memory state around the buggy address:
> ffff8880a55aa100: fb fb fb fb fc fc fc fc fb fb fb fb fc fc fc fc
> ffff8880a55aa180: fb fb fb fb fc fc fc fc fb fb fb fb fc fc fc fc
> > ffff8880a55aa200: fb fb fb fb fc fc fc fc fb fb fb fb fc fc fc fc
> ^
> ffff8880a55aa280: fb fb fb fb fc fc fc fc fb fb fb fb fc fc fc fc
> ffff8880a55aa300: fb fb fb fb fc fc fc fc fb fb fb fb fc fc fc fc
> ==================================================================
>
>
> ---
> This bug is generated by a bot. It may contain errors.
> See https://goo.gl/tpsmEJ for more information about syzbot.
> syzbot engineers can be reached at syzkaller@googlegroups.com.
>
> syzbot will keep track of this bug report. See:
> https://goo.gl/tpsmEJ#status for how to communicate with syzbot.
> For information about bisection process see: https://goo.gl/tpsmEJ#bisection
> syzbot can test patches for this bug, for details see:
> https://goo.gl/tpsmEJ#testing-patches
> _______________________________________________
> dri-devel mailing list
> dri-devel@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/dri-devel
--
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
^ permalink raw reply
* Re: [PATCH v3 00/26] compat_ioctl: cleanups
From: Andy Shevchenko @ 2019-05-06 9:03 UTC (permalink / raw)
To: Arnd Bergmann
Cc: Linux NVMe Mailinglist, linux-iio, linux-remoteproc, linux-fbdev,
dri-devel, Platform Driver, linux-ide,
open list:MEMORY TECHNOLOGY..., sparclinux, linux1394-devel,
devel, linux-s390, linux-scsi, linux-bluetooth, y2038, qat-linux,
amd-gfx, linux-input, Marcel Holtmann, Linux Media Mailing List,
open list:REAL TIME CLOCK (RTC) SUBSYSTEM,
ALSA Development Mailing List
In-Reply-To: <20190416202013.4034148-1-arnd@arndb.de>
On Tue, Apr 16, 2019 at 11:23 PM Arnd Bergmann <arnd@arndb.de> wrote:
>
> Hi Al,
>
> It took me way longer than I had hoped to revisit this series, see
> https://lore.kernel.org/lkml/20180912150142.157913-1-arnd@arndb.de/
> for the previously posted version.
>
> I've come to the point where all conversion handlers and most
> COMPATIBLE_IOCTL() entries are gone from this file, but for
> now, this series only has the parts that have either been reviewed
> previously, or that are simple enough to include.
>
> The main missing piece is the SG_IO/SG_GET_REQUEST_TABLE conversion.
> I'll post the patches I made for that later, as they need more
> testing and review from the scsi maintainers.
>
> I hope you can still take these for the coming merge window, unless
> new problems come up.
> drivers/platform/x86/wmi.c | 2 +-
Acked-by: Andy Shevchenko <andy.shevchenko@gmail.com>
--
With Best Regards,
Andy Shevchenko
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox