Linux Input/HID development
 help / color / mirror / Atom feed
* Re: [PATCH 12/14] iio: adc: at91-sama5d2_adc: support for position and pressure channels
From: Jonathan Cameron @ 2018-01-06 15:05 UTC (permalink / raw)
  To: Eugen Hristev
  Cc: devicetree, linux-iio, dmitry.torokhov, linux-kernel,
	ludovic.desroches, alexandre.belloni, linux-input,
	linux-arm-kernel
In-Reply-To: <25045512-f372-3f25-e84f-ed809db9dde3@microchip.com>

On Thu, 4 Jan 2018 17:17:54 +0200
Eugen Hristev <eugen.hristev@microchip.com> wrote:

> On 29.12.2017 19:02, Jonathan Cameron wrote:
> > On Fri, 22 Dec 2017 17:07:19 +0200
> > Eugen Hristev <eugen.hristev@microchip.com> wrote:
> >   
> >> The ADC IP supports position and pressure measurements for a touchpad
> >> connected on channels 0,1,2,3 for a 4-wire touchscreen with pressure
> >> measurement support.
> >> Using the inkern API, a driver can request a trigger and read the
> >> channel values from the ADC.
> >> The implementation provides a trigger named "touch" which can be
> >> connected to a consumer driver.
> >> Once a driver connects and attaches a pollfunc to this trigger, the
> >> configure trigger callback is called, and then the ADC driver will
> >> initialize pad measurement.
> >> First step is to enable touchscreen 4wire support and enable
> >> pen detect IRQ.
> >> Once a pen is detected, a periodic trigger is setup to trigger every
> >> 2 ms (e.g.) and sample the resistive touchscreen values. The trigger poll
> >> is called, and the consumer driver is then woke up, and it can read the
> >> respective channels for the values : X, and Y for position and pressure
> >> channel.
> >> Because only one trigger can be active in hardware in the same time,
> >> while touching the pad, the ADC will block any attempt to use the
> >> triggered buffer. Same, conversions using the software trigger are also
> >> impossible (since the periodic trigger is setup).
> >> If some driver wants to attach while the trigger is in use, it will
> >> also fail.
> >> Once the pen is not detected anymore, the trigger is free for use (hardware
> >> or software trigger, with or without DMA).
> >> Channels 0,1,2 and 3 are unavailable if a touchscreen is enabled.
> >>
> >> Some parts of this patch are based on initial original work by
> >> Mohamed Jamsheeth Hajanajubudeen and Bandaru Venkateswara Swamy
> >>  
> > OK, so comments inline.
> > 
> > What I'm missing currently though is an explanation of why the slightly
> > more standard arrangement of using a callback buffer doesn't work here.
> > The only addition I think you need to do that is to allow a consumer to
> > request a particular trigger.  I also think some of the other provisions
> > could be handled using standard features and slightly reducing the flexibility.
> > I don't know for example if it's useful to allow other channels to be
> > read when touch is not in progress or not.
> > 
> > So restrictions:
> > 
> > 1. Touch screen channels can only be read when touch is enabled.
> >   - use the available_scan_masks to control this. Or the callback that lets
> >     you do the same dynamically.
> > 2. You need to push these channels to your consumer driver.
> >   - register a callback buffer rather than jumping through the hoops to
> >     insert your own pollfunc.  That will call a function in your
> >     consumer, providing the data from the 3 channels directly.
> > 3. You need to make sure it is using the right driver.  For that you
> >     will I think need a new interface.
> > 
> > Various other comments inline. I may well be missing something as this is
> > a fair bit of complex code to read - if so then next version should have
> > a clear cover letter describing why this more standard approach can't be
> > used.  
> 
> Hello Jonathan and thanks for the review of my patch series,
> 
> before starting and working over the required modifications and 
> suggestions that you sent me, I want to be a little more explicit about 
> the design of my implementation.
> Hope this will clarify some things, and maybe I can as well understand 
> better what you have in mind to support this feature set.
> 
> Why have I picked a pollfunction: We discussed a while back on the 
> mailing list that you do not have an inkern mechanism to expose the 
> triggers to other drivers, and that it may be a good idea to have it for 
> such kind of actually multi function device, instead of having a MFD 
> driver, an ADC driver, and an Input driver, all sharing the same 
> register map, the same IRQ , etc, with some kind of synchronization to 
> avoid stepping on each other for the hardware resource.

No disagreement with that principle.

> So I considered to expose the trigger by attaching and detaching 
> pollfunctions to it. Which is the main thing what we use a trigger for.

Hmm. It's definitely one approach. But we do already have other drivers
where the trigger is controlled by a consumer and to my mind that
is a cleaner approach as it doesn't short cut the equivalent of
doing it from userspace.

drivers/iio/potentiostat/lmp91000.c does something similar though
for a rather different use. You need your consumer interface
to get the handle to the trigger in this case
(the lmp91000 is actually providing the trigger rather than
consuming it).


> 
> So, what I had in mind, was to create a consumer driver that will 
> request triggers from the IIO device just like other drivers request 
> channels (part which is already done in IIO).
> In order to do this I had to somehow wake up the consumer driver when 
> new data was available from the touchscreen. So, having the IRQ only in 
> the ADC device, and then on Pen detect and No pen detect just start or 
> stop the periodic trigger, which needs to be polled. The magic part is 
> that the consumer driver has a poll function already attached to this 
> trigger, so the poll function is just called every time we have new 
> data. The poll function is attached as an irq handler, and then we can 
> reuse all the read_raw data by using a scheduled work from the consumer 
> driver, to read the channels.

If you had done this via a callback buffer the only difference is that
the pollfunc would have been a standard one pulling the relevant channels
and passing them on down to the buffer interface which could then decide
what to do with them.

> To do this, the ADC registers a special trigger named "touch trigger" 
> which is never enabled by the ADC driver. Instead, when a pollfunc is 
> attached to it, the attach function will also configure it with enabled 
> state.

Whilst it might not make sense to enable it in the touch screen driver
I'm not sure there is strictly any reason to prevent it being so used.

> In the ADC, this means to start the touchscreen functionality. If 
> the touch is requested, it will standby and wait for pen detect IRQ.
> Once we have pen detect, we can use a periodic trigger to sample the 
> touch data, and poll the "touch" trigger. The consumer driver will wake 
> up and schedule a work , that will use the standard read raw interface 
> (inkern) that will read three virtual channels (position + pressure). 
> They are not actual hardware channels, as the touch information is being 
> received on channels 0,1,2,3, but reading these virtual channels will 
> read from different registers inside the ADC IP ( x position, y 
> position, pressure), do some computations on the data, and feed the 
> consumer with the values , hiding the behind the scenes hardware 
> specific calculations.

I wouldn't worry about whether they are real channels or not. This
is really similar to a differential ADC (some of those do the differential
digitally). Light sensors often have a number of 'real' channels used
to derive (via hideous non linear calculations) the illuminance as
it's hard to build a light sensor with the same sensitivity as the human
eye.  We have worse 'non real' channels as well such as activity channels
on some the accelerometers that report if it thinks you are walking /
running etc.
 
> After trigger is polled , the ADC will resume normal functionality, and 
> the consumer driver will continue to sleep.

So this is where I'm unsure.  Do you actually have a usecase where it
makes the sense to read from the ADC only when there is no touch?  Any
system doing that has an obvious denial of service attack - touch the
screen.

> We need to have a periodic trigger to sample the data because the actual 
> analog to digital conversion inside the IP block needs to be triggered. 
> The touchscreen data measurements cannot happen in hardware without 
> being triggered. If I try with a hrtimer to get a periodic IRQ to just 
> read the data, it will never be ready. The datasheet states that the 
> touchscreen measurements "will be attached to the conversion sequence". 
> So the periodic trigger is forcing a conversion sequence. This could be 
> done with a software trigger as well, but why the hassle to start it 
> every 2 milliseconds (or other time interval), if we can do it by 
> periodic trigger ?

Ah, one reason here would be to allow separate consumers to use the
device. In that case you'd run with a periodic trigger all the time
and have two buffers attached, the buffer_cb that is feeding your
touchscreen and another buffer to deal with the other channels
(presumably the standard one an IIO device has when using buffered
interfaces).

The buffer demux would ensure the data from the right channels
ends up in the right place.  It makes it look to the buffer
consumer like it is the only thing using / controlling the data
flow.

> Once we get the No pen IRQ, we stop the periodic trigger and it can be 
> used in another purpose (software or external as of now in the driver, 
> in the future we can add PWM trigger and Timer trigger)

This case isn't really useful though as any other use is denied
access when touch occurs.

I'll summarise what I think would work for this below.

> 
> In short, the ADC in Sama5D2 also supports touchscreen, and in 
> touchscreen mode , 4 of the channels are being used for this purpose. 
> This however, doesn't stop the ADC to use the other channels . The 
> hardware has 12 total single channels and they can be paired to have 6 
> more differential channels. The only thing that is blocked is the 
> trigger, but only if the pen is touching (when we start the periodic 
> trigger to sample the touchscreen). If the pen is not touching, an 
> external trigger or software trigger can be used without any issues (so 
> why limit the functionality, if this is available from hardware ?). 
> Because of the reason I discussed above (touchscreen sequence must be 
> triggered), we cannot use another trigger in the same time.
> 
> 
> I see your idea with the callback buffer and it's worth exploring. 
> Mainly this series was to actually show you what I had in mind about 
> supporting the resistive touchscreen, and to give you some actually 
> working code/patch, so we can discuss based on real implementation, not 
> just suppositions.

That side of things is fine.

> 
> You are right in many of the other comments that you said, and I will 
> come up with a v2 to this series. For now, I need to know if this is a 
> good or right direction in which I am going, or I should try to change 
> all the mechanism to callback buffer ? Or maybe I am totally in a bad 
> direction ?
> The requirements are that the consumer driver needs to be somehow woke 
> up for every new touch data available, and report to the input 
> subsystem. As it was done before, the at91 old driver, just creates and 
> registers an input device by itself, and then reports the position and 
> touches. I was thinking that with this trigger consumer implementation, 
> things can be better in terms of subsystem separation and support.
> 
> Thanks again and let me know of your thoughts,
> 
> Eugen

So a couple of things come to mind on how I'd structure this.
So what we have (very briefly)

No touch screen case:
* Generic ADC using all sorts of different triggers

Touch screen only case:
* Interrupt to indicate pen on / off
* A need to do a periodic trigger of the device but only
useful when touch is in progress.

Touch screen and other users:
* Interrupt to indicate pen on / off
* Periodic trigger needed for touchscreen when touch in progress.
* Do not have denial of service on other channels.

First two cases are easy enough by having a magic trigger, third
case is harder.
If we have the touchscreen then I would drop support for direct access to
to ADC channels whilst it's in use (so no sysfs - or emulate it if you
really want it by stashing results from scans done when touch is in
progress).

Have your touch screen channels just as normal additional channels,
but only via the buffered interface (no _RAW attribute).
If someone sets up to read them via buffered interface with
a different trigger I think they'll get values - whether they
are right is dependent (if I understand correctly) on whether
there is a touch in progress.  So no harm done and it'll make
the logic simpler.

The moment touch is opened and acquires the IIO channels
fix the trigger (may need new interface) to the periodic one
that you were enabling and disabling on touch.
Things get dicey if there is an existing user so you may
have to do it on driver probe rather than open of the input
device if we effectively want touch to have the highest
priority use of the ADC.

If other channels are enabled for buffered mode then note
this in the driver and have the periodic trigger on all the
time (to ensure they keep getting read)  This will pass
garbage to your touch screen driver, but it'll remove it due
to the pressure value being too low so no harm there.

Normal path will work for non touch channels (and in theory
the touch ones if they are turned on) via IIO buffer
interface.  It'll be restricted in form due to the needs of
the touch driver, but better than nothing and should cover
most usecases.

Now the interrupt on / off on touch bit becomes an optimization
in the case of only the buffer_cb being attached.

I think that fits cleanly in the current IIO framework and
looks more similar to our existing provider consumer approaches.

Still needs the hooks to get hold of the trigger though so
as to be able to tell the ADC which one to use. So rather
than being a trigger consumer interface, it's more of a trigger
configuration interface..  Exact term doesn't matter though.

Jonathan

> 
> 
> 
> [...]
> --
> To unsubscribe from this list: send the line "unsubscribe linux-iio" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply

* [PATCH][next] HID: asus: make array 'buf' static const, shrinks object size
From: Colin King @ 2018-01-06 15:50 UTC (permalink / raw)
  To: Jiri Kosina, Benjamin Tissoires, linux-input
  Cc: kernel-janitors, linux-kernel

From: Colin Ian King <colin.king@canonical.com>

Don't populate the const read-only array 'buf' on the stack but instead
make it stati. Makes the object code smaller by 26 bytes:

Before:
   text	   data	    bss	    dec	    hex	filename
  14378	   2384	     64	  16826	   41ba	linux/drivers/hid/hid-asus.o

After:
   text	   data	    bss	    dec	    hex	filename
  14296	   2440	     64	  16800	   41a0	linux/drivers/hid/hid-asus.o

(gcc version 7.2.0 x86_64)

Signed-off-by: Colin Ian King <colin.king@canonical.com>
---
 drivers/hid/hid-asus.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/hid/hid-asus.c b/drivers/hid/hid-asus.c
index 6d2894b7d8e7..89d29f323366 100644
--- a/drivers/hid/hid-asus.c
+++ b/drivers/hid/hid-asus.c
@@ -561,7 +561,9 @@ static int asus_input_mapping(struct hid_device *hdev,
 static int asus_start_multitouch(struct hid_device *hdev)
 {
 	int ret;
-	const unsigned char buf[] = { FEATURE_REPORT_ID, 0x00, 0x03, 0x01, 0x00 };
+	static const unsigned char buf[] = {
+		FEATURE_REPORT_ID, 0x00, 0x03, 0x01, 0x00
+	};
 	unsigned char *dmabuf = kmemdup(buf, sizeof(buf), GFP_KERNEL);
 
 	if (!dmabuf) {
-- 
2.15.1


^ permalink raw reply related

* Re: [RFP] iio: Support of gesture sensor as a standard IIO sensor
From: Pandruvada, Srinivas @ 2018-01-06 17:43 UTC (permalink / raw)
  To: gnomes@lxorguk.ukuu.org.uk, jic23@kernel.org
  Cc: linux-input@vger.kernel.org, linux-kernel@vger.kernel.org,
	linux-iio@vger.kernel.org
In-Reply-To: <20180106131231.078492c3@archlinux>

On Sat, 2018-01-06 at 13:12 +0000, Jonathan Cameron wrote:
> On Sat, 6 Jan 2018 00:20:24 +0000
> Alan Cox <gnomes@lxorguk.ukuu.org.uk> wrote:
> 
> > 
> > > 
> > > > 
> > > > From an IIO sensor point of view A Gesture sensor:    
> > > Outputs
> > > 	A pre defined activity type
> > > 		WAKE
> > > 		TILT
> > > 		GLANCE
> > > 		PICK_UP
> > > 		 &
> > > 		 more
> > > 
> > > 	A user defined activity type as "string"
> > > 
> > > Inputs
> > > 	A raw binary cdev interface to download templates/patterns
> > > 
> > > 
> > > I want to gather more opinions before submitting a RFC patch.  
> > The only question I have is should it appear under IIO or should it
> > be an
> > input event interface. It feels to me more like an input device in
> > that in
> > this case while it's not keys or joystick it is still 'please do
> > X'. That
> > might also make it much easier (in the non-Android space in
> > particular)
> > to bind these activities to actions in things like web browsers.
> > 
> I agree that this may well be an option for many of the gestures
> specifically
> metioned (flicks etc and glyphs).
> 
> However, there are other obvious uses of this technology such as step
> detection
> or activity classification (running, walking sitting) that so far
> have fallen
> in the scope of IIO as they aren't really things you expect the
> device to
> perform an an action in response to.  Another one of those messy
> corners
> that fall through the gaps!
> 
> The drivers/iio/accel/mma9553.c does activity detection, but that
> isn't
> really 'events' in the same way as we have here...
> 
> So right answer might be a hybrid of an underlying flexible IIO
> device
> and an input front end for when it makes sense.

What about we can also send an input event, if the event is one of the
input event type which is defined in uapi/linux/input-event-codes.h?


> 
> We probably need to get the in kernel use of IIO events sorted.  Non
> event
> stuff has been sorted for years, but this last corner was never of
> enough
> interest to anyone to actually implement it (it's fairly straight
> forward
> to do).
Currently in IIO event is a u64 value in Fifo. But here we need some
user defined events also. Since this ABI may already may be in use so
can't change u64 to a structure with data type definition and
associated data. But we can define additional predefined ids for custom
events (Similar to HID sensor usage spec added CUSTOM usage ids).

Thanks,
Srinivas

> 
> > 
> > (+ linux-input)
> > 
> > Alan

^ permalink raw reply

* Re: [PATCH v5 2/3] input: evdev: Replace timeval with timespec64
From: Deepa Dinamani @ 2018-01-06 21:43 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: Dmitry Torokhov, open list:HID CORE LAYER,
	Linux Kernel Mailing List, Peter Hutterer, y2038 Mailman List
In-Reply-To: <CAK8P3a0EEGtSJ6g1JWwkZWaKTDFNN=q-ZQXcmzK4q3-xiBC+4Q@mail.gmail.com>

On Tue, Jan 2, 2018 at 7:35 AM, Arnd Bergmann <arnd@arndb.de> wrote:
> On Tue, Jan 2, 2018 at 7:46 AM, Dmitry Torokhov
> <dmitry.torokhov@gmail.com> wrote:
>> On Sun, Dec 17, 2017 at 09:18:43PM -0800, Deepa Dinamani wrote:
>>> @@ -304,12 +314,11 @@ static void evdev_events(struct input_handle *handle,
>>>  {
>>>       struct evdev *evdev = handle->private;
>>>       struct evdev_client *client;
>>> -     ktime_t ev_time[EV_CLK_MAX];
>>> +     struct timespec64 ev_time[EV_CLK_MAX];
>>>
>>> -     ev_time[EV_CLK_MONO] = ktime_get();
>>> -     ev_time[EV_CLK_REAL] = ktime_mono_to_real(ev_time[EV_CLK_MONO]);
>>> -     ev_time[EV_CLK_BOOT] = ktime_mono_to_any(ev_time[EV_CLK_MONO],
>>> -                                              TK_OFFS_BOOT);
>>> +     ktime_get_ts64(&ev_time[EV_CLK_MONO]);
>>> +     ktime_get_real_ts64(&ev_time[EV_CLK_REAL]);
>>> +     get_monotonic_boottime64(&ev_time[EV_CLK_BOOT]);
>>
>> This may result in different ev_time[] members holding different times,
>> whereas the original code would take one time sample and convert it to
>> different clocks.
>
> Is this important? On each client we only return one of the two
> times, and I would guess that you cannot rely on a correlation
> between timestamps on different devices, since the boot and real
> offsets can change over time.

Right. I didn't think this was an issue either.

>> Also, why can't we keep using ktime_t internally? It is y2038 safe,
>> right?
>
> Correct, but there may also be a performance difference if we get
> a lot of events, not sure if that matters.
>
>> I think you should drop this patch and adjust the 3rd one to
>> massage the input event timestamp patch to do ktime->timespec64->input
>> timestamp conversion.
>
> The change in __evdev_queue_syn_dropped still seems useful to me
> as ktime_get_*ts64() is a bit more efficient than ktime_get*() followed by
> a slow ktime_to_timespec64() or ktime_to_timeval().
>
> For evdev_events(), doing a single ktime_get() followed by a
> ktime_to_timespec64/ktime_to_timeval can be faster than three
> ktime_get_*ts64 (depending on the hardware clock source), or
> it can be slower depending on the CPU and the clocksource
> hardware. Again, no idea if this matters at the usual rate of
> input events.
>
> I guess dropping the evdev_events() change and replacing it with a
> ktime_to_timespec64 change in evdev_pass_values()
> would be fine here, it should keep the current performance
> behavior and get rid of the timeval.

I was trying to use timespec64 everywhere so that we would not have
conversions back and forth at the input layer.
I dropped the ktime_t conversions for now and merged this patch with
the next one as requested.

Let me know if you would like to keep the changes Arnd preferred above
for __evdev_queue_syn_dropped(). I can submit a separate patch if this
is preferred.

-Deepa

^ permalink raw reply

* [PATCH v6 0/1] Make input drivers y2038 safe
From: Deepa Dinamani @ 2018-01-07  0:19 UTC (permalink / raw)
  To: dmitry.torokhov, linux-input, linux-kernel; +Cc: y2038, peter.hutterer, arnd

The series is aimed at making input events y2038 safe.
It extends the lifetime of the realtime timestamps in the
events to year 2106.
The series is also a necessary update as glibc is set to provide
64 bit time_t support for 32 bit binaries. glibc plan is detailed
at https://sourceware.org/glibc/wiki/Y2038ProofnessDesign .

The series is a result of discussions with Arnd Bergmann and
Dmitry Torokhov at last Plumbers.

The plan is to deprecate realtime timestamps anyway as they
are not appropriate for these timestamps as noted in the patch
a80b83b7b8 by John Stultz.

The design also updates the format of the input events read/ written
to the device nodes. This breaks 32 bit interface to the input
events at compile time as preferred by the maintainer.

The userspace library changes to libevdev, libuinput and mtdev
will be posted to the respective mailing groups for review.

Changes from v5:
* Dropped patch 1, since it has already been applied
* Combined patches 2 and 3
* Addressed minor review comments
Changes from v4:
* Dropped serio hil patch
Changes from v3:
* Updated uinput to support monotonic time only
* Addressed review comments
Changes from v2:
* Updated the design to break 32 bit interfaces at compile time.
Changes from v1:
* Updated changes according to review comments.
* Posted userspace library changes that go along with the series.

Deepa Dinamani (1):
  input: Deprecate real timestamps beyond year 2106

 drivers/input/evdev.c        | 16 ++++++++++++----
 drivers/input/input-compat.c |  8 ++++----
 drivers/input/input-compat.h |  3 ++-
 drivers/input/misc/uinput.c  |  4 ++--
 include/uapi/linux/input.h   | 12 +++++++++++-
 5 files changed, 31 insertions(+), 12 deletions(-)


base-commit: 0c1f9d81ac360d8ad31cbfd2bdcf44de8204188e
prerequisite-patch-id: 6c903c00c9d5191619efe9f26e2600197336e6b2
-- 
2.14.1

_______________________________________________
Y2038 mailing list
Y2038@lists.linaro.org
https://lists.linaro.org/mailman/listinfo/y2038

^ permalink raw reply

* [PATCH v6 1/1] input: Deprecate real timestamps beyond year 2106
From: Deepa Dinamani @ 2018-01-07  0:19 UTC (permalink / raw)
  To: dmitry.torokhov, linux-input, linux-kernel; +Cc: peter.hutterer, arnd, y2038
In-Reply-To: <20180107001915.15287-1-deepa.kernel@gmail.com>

struct timeval is not y2038 safe.
All usage of timeval in the kernel will be replaced by
y2038 safe structures.
The change is also necessary as glibc is introducing support
for 32 bit applications to use 64 bit time_t. Without this
change, many applications would incorrectly interpret values
in the struct input_event.
More details about glibc at
https://sourceware.org/glibc/wiki/Y2038ProofnessDesign .

struct input_event maintains time for each input event.
Real time timestamps are not ideal for input as this
time can go backwards as noted in the patch a80b83b7b8
by John Stultz. Hence, having the input_event.time fields
only big enough for monotonic and boot times are
sufficient.

The change leaves the representation of struct input_event as is
on 64 bit architectures. But uses 2 unsigned long values on 32 bit
machines to support real timestamps until year 2106.
This intentionally breaks the ABI on 32 bit architectures and
compat handling on 64 bit architectures.
This is as per maintainer's preference to introduce compile time errors
rather than run into runtime incompatibilities.

The change requires any 32 bit userspace utilities reading or writing
from event nodes to update their reading format to match the new
input_event. The changes to the popular libraries will be posted once
we agree on the kernel change.

Suggested-by: Arnd Bergmann <arnd@arndb.de>
Signed-off-by: Deepa Dinamani <deepa.kernel@gmail.com>
Acked-by: Peter Hutterer <peter.hutterer@who-t.net>
---
 drivers/input/evdev.c        | 16 ++++++++++++----
 drivers/input/input-compat.c |  8 ++++----
 drivers/input/input-compat.h |  3 ++-
 drivers/input/misc/uinput.c  |  4 ++--
 include/uapi/linux/input.h   | 12 +++++++++++-
 5 files changed, 31 insertions(+), 12 deletions(-)

diff --git a/drivers/input/evdev.c b/drivers/input/evdev.c
index 0193dd4f0452..8a8a905ab886 100644
--- a/drivers/input/evdev.c
+++ b/drivers/input/evdev.c
@@ -135,7 +135,8 @@ static void __evdev_flush_queue(struct evdev_client *client, unsigned int type)
 			continue;
 		} else if (head != i) {
 			/* move entry to fill the gap */
-			client->buffer[head].time = ev->time;
+			client->buffer[head].input_event_sec = ev->input_event_sec;
+			client->buffer[head].input_event_usec = ev->input_event_usec;
 			client->buffer[head].type = ev->type;
 			client->buffer[head].code = ev->code;
 			client->buffer[head].value = ev->value;
@@ -157,6 +158,7 @@ static void __evdev_queue_syn_dropped(struct evdev_client *client)
 {
 	struct input_event ev;
 	ktime_t time;
+	struct timespec64 ts;
 
 	time = client->clk_type == EV_CLK_REAL ?
 			ktime_get_real() :
@@ -164,7 +166,9 @@ static void __evdev_queue_syn_dropped(struct evdev_client *client)
 				ktime_get() :
 				ktime_get_boottime();
 
-	ev.time = ktime_to_timeval(time);
+	ts = ktime_to_timespec64(time);
+	ev.input_event_sec = ts.tv_sec;
+	ev.input_event_usec = ts.tv_nsec / NSEC_PER_USEC;
 	ev.type = EV_SYN;
 	ev.code = SYN_DROPPED;
 	ev.value = 0;
@@ -241,7 +245,8 @@ static void __pass_event(struct evdev_client *client,
 		 */
 		client->tail = (client->head - 2) & (client->bufsize - 1);
 
-		client->buffer[client->tail].time = event->time;
+		client->buffer[client->tail].input_event_sec = event->input_event_sec;
+		client->buffer[client->tail].input_event_usec = event->input_event_usec;
 		client->buffer[client->tail].type = EV_SYN;
 		client->buffer[client->tail].code = SYN_DROPPED;
 		client->buffer[client->tail].value = 0;
@@ -262,12 +267,15 @@ static void evdev_pass_values(struct evdev_client *client,
 	struct evdev *evdev = client->evdev;
 	const struct input_value *v;
 	struct input_event event;
+	struct timespec64 ts;
 	bool wakeup = false;
 
 	if (client->revoked)
 		return;
 
-	event.time = ktime_to_timeval(ev_time[client->clk_type]);
+	ts = ktime_to_timespec64(ev_time[client->clk_type]);
+	event.input_event_sec = ts.tv_sec;
+	event.input_event_usec = ts.tv_nsec / NSEC_PER_USEC;
 
 	/* Interrupts are disabled, just acquire the lock. */
 	spin_lock(&client->buffer_lock);
diff --git a/drivers/input/input-compat.c b/drivers/input/input-compat.c
index 2186f71c9fe5..fda8d6d2a268 100644
--- a/drivers/input/input-compat.c
+++ b/drivers/input/input-compat.c
@@ -24,8 +24,8 @@ int input_event_from_user(const char __user *buffer,
 				   sizeof(struct input_event_compat)))
 			return -EFAULT;
 
-		event->time.tv_sec = compat_event.time.tv_sec;
-		event->time.tv_usec = compat_event.time.tv_usec;
+		event->input_event_sec = compat_event.sec;
+		event->input_event_usec = compat_event.usec;
 		event->type = compat_event.type;
 		event->code = compat_event.code;
 		event->value = compat_event.value;
@@ -44,8 +44,8 @@ int input_event_to_user(char __user *buffer,
 	if (in_compat_syscall() && !COMPAT_USE_64BIT_TIME) {
 		struct input_event_compat compat_event;
 
-		compat_event.time.tv_sec = event->time.tv_sec;
-		compat_event.time.tv_usec = event->time.tv_usec;
+		compat_event.sec = event->input_event_sec;
+		compat_event.usec = event->input_event_usec;
 		compat_event.type = event->type;
 		compat_event.code = event->code;
 		compat_event.value = event->value;
diff --git a/drivers/input/input-compat.h b/drivers/input/input-compat.h
index 1563160a7af3..08cd755e73fd 100644
--- a/drivers/input/input-compat.h
+++ b/drivers/input/input-compat.h
@@ -18,7 +18,8 @@
 #ifdef CONFIG_COMPAT
 
 struct input_event_compat {
-	struct compat_timeval time;
+	compat_ulong_t sec;
+	compat_ulong_t usec;
 	__u16 type;
 	__u16 code;
 	__s32 value;
diff --git a/drivers/input/misc/uinput.c b/drivers/input/misc/uinput.c
index 9251765645d1..03d22fc90a45 100644
--- a/drivers/input/misc/uinput.c
+++ b/drivers/input/misc/uinput.c
@@ -90,8 +90,8 @@ static int uinput_dev_event(struct input_dev *dev,
 	udev->buff[udev->head].code = code;
 	udev->buff[udev->head].value = value;
 	ktime_get_ts64(&ts);
-	udev->buff[udev->head].time.tv_sec = ts.tv_sec;
-	udev->buff[udev->head].time.tv_usec = ts.tv_nsec / NSEC_PER_USEC;
+	udev->buff[udev->head].input_event_sec = ts.tv_sec;
+	udev->buff[udev->head].input_event_usec = ts.tv_nsec / NSEC_PER_USEC;
 	udev->head = (udev->head + 1) % UINPUT_BUFFER_SIZE;
 
 	wake_up_interruptible(&udev->waitq);
diff --git a/include/uapi/linux/input.h b/include/uapi/linux/input.h
index 8c5a0bf6ee35..9c5105ff5cc6 100644
--- a/include/uapi/linux/input.h
+++ b/include/uapi/linux/input.h
@@ -21,10 +21,20 @@
 
 /*
  * The event structure itself
+ * Note that __USE_TIME_BITS64 is defined by libc based on
+ * application's request to use 64 bit time_t.
  */
-
 struct input_event {
+#if	(__BITS_PER_LONG != 32 || !defined(__USE_TIME_BITS64)) && !defined(__KERNEL)
 	struct timeval time;
+#define input_event_sec time.tv_sec
+#define input_event_usec time.tv_usec
+#else
+	__kernel_ulong_t __sec;
+	__kernel_ulong_t __usec;
+#define input_event_sec  __sec
+#define input_event_usec __usec
+#endif
 	__u16 type;
 	__u16 code;
 	__s32 value;
-- 
2.14.1


^ permalink raw reply related

* Re: [PATCH] Revert "Input: trackpoint - add new trackpoint firmware ID"
From: Dmitry Torokhov @ 2018-01-07  6:52 UTC (permalink / raw)
  To: Aaron Ma; +Cc: Greg KH, Sebastian Schmidt, linux-input
In-Reply-To: <20180105162313.higyrbd6unumgtjb@dtor-ws>

On Fri, Jan 05, 2018 at 08:23:13AM -0800, Dmitry Torokhov wrote:
> Hi Aaron,
> 
> On Fri, Jan 05, 2018 at 09:29:26PM +0800, Aaron Ma wrote:
> > Hi Dmitry:
> > 
> > Got the official info from Lenovo:
> > Lenovo introduced new TrackPoint compatible sticks ( ELAN/Alps/NXP
> > sticks) from 2016.
> > These new devices only support the minimum commands described in the
> > spec, which has been used in the current Windows driver.
> 
> What is the exact list of the commands supported by each variant?
> 
> > 
> > Legacy TrackPoint: 0101 – 0E01
> > ALPS: 0102 – FF02
> > ELAN:0103 – FF03
> > NXP: 0104 – FF04
> > 
> > 2.4.18 READ SECONDARY ID (x"E1")
> > This command will read the secondary device ID of the pointing device (2
> > bytes).  The least significant byte is sent first.  For the first byte,
> > the legacy TrackPoint controller from IBM will always return x"01", the
> > pointing stick from ALPS will always return x"02", the pointing stick
> > from Elan will always return x"03”, and the pointing stick from NXP will
> > always return 0x”04".  And a second byte which denotes a specific set of
> > functional specifications.  Differing ROM versions are used to denote
> > changes within a given functional set.
> 
> Can you/Lenovo share the updated spec?
> 
> > 
> > The new devices (include Legacy ID:01) will not support the sysfs like
> > speed.
> > 
> > So it is not right to revert the commit, it is about to add another 0x04
> > ID in it.
> > 
> > Old sysfs could be stayed for old legacy device ID:01 or removed.
> 
> No, because there are devices that have trackpoints properly
> implementing the protocol, before Lenovo started their "innovation".
> 
> Do we have any way to distinguish between properly implemented
> trackpoints and Lenovo "improved" ones? I played with gen3 Carbon, and
> while it does not error out on "speed" attribute, unlike gen5, it still
> has no visible effects. Additionally, the "press to select"
> functionality seems to be disabled, and trying to enable it via sysfs
> results in register content being reverted to the original "disabled"
> setting in a second or two. Setting to swap X and Y axes does not work
> either, not sure about other bits of that control register.
> "sensitivity" does work though, again unlike my gen5.
> 
> Thanks.
> 
> -- 
> Dmitry

Guys, could you please try the patch below? It will not solve the
"speed" issue on 0x01 devices, but hopefully we won't be exposing
non-existing controls on others.

Thanks!

-- 
Dmitry


Input: trackpoint - only expose supported controls for Elan, ALPS and NXP

From: Dmitry Torokhov <dmitry.torokhov@gmail.com>

The newer trackpoints from ALPS, Elan and NXP implement a very limited
subset of extended commands and controls that the original trackpoints
implemented, so we should not be exposing not working controls in sysfs.
The newer trackpoints also do not implement "Power On Reset" or "Read
Extended Button Status", so we should not be using these commands during
initialization.

While we are at it, let's change "unsigned char" to u8 for byte data or
bool for booleans and use better suited error codes instead of -1.

Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
---
 drivers/input/mouse/trackpoint.c |  241 +++++++++++++++++++++++---------------
 drivers/input/mouse/trackpoint.h |   34 +++--
 2 files changed, 168 insertions(+), 107 deletions(-)

diff --git a/drivers/input/mouse/trackpoint.c b/drivers/input/mouse/trackpoint.c
index 0871010f18d5..0ca80f465359 100644
--- a/drivers/input/mouse/trackpoint.c
+++ b/drivers/input/mouse/trackpoint.c
@@ -19,6 +19,13 @@
 #include "psmouse.h"
 #include "trackpoint.h"
 
+static const char * const trackpoint_variants[] = {
+	[TP_VARIANT_IBM]	= "IBM",
+	[TP_VARIANT_ALPS]	= "ALPS",
+	[TP_VARIANT_ELAN]	= "Elan",
+	[TP_VARIANT_NXP]	= "NXP",
+};
+
 /*
  * Power-on Reset: Resets all trackpoint parameters, including RAM values,
  * to defaults.
@@ -26,7 +33,7 @@
  */
 static int trackpoint_power_on_reset(struct ps2dev *ps2dev)
 {
-	unsigned char results[2];
+	u8 results[2];
 	int tries = 0;
 
 	/* Issue POR command, and repeat up to once if 0xFC00 received */
@@ -38,7 +45,7 @@ static int trackpoint_power_on_reset(struct ps2dev *ps2dev)
 
 	/* Check for success response -- 0xAA00 */
 	if (results[0] != 0xAA || results[1] != 0x00)
-		return -1;
+		return -ENODEV;
 
 	return 0;
 }
@@ -46,8 +53,7 @@ static int trackpoint_power_on_reset(struct ps2dev *ps2dev)
 /*
  * Device IO: read, write and toggle bit
  */
-static int trackpoint_read(struct ps2dev *ps2dev,
-			   unsigned char loc, unsigned char *results)
+static int trackpoint_read(struct ps2dev *ps2dev, u8 loc, u8 *results)
 {
 	if (ps2_command(ps2dev, NULL, MAKE_PS2_CMD(0, 0, TP_COMMAND)) ||
 	    ps2_command(ps2dev, results, MAKE_PS2_CMD(0, 1, loc))) {
@@ -57,8 +63,7 @@ static int trackpoint_read(struct ps2dev *ps2dev,
 	return 0;
 }
 
-static int trackpoint_write(struct ps2dev *ps2dev,
-			    unsigned char loc, unsigned char val)
+static int trackpoint_write(struct ps2dev *ps2dev, u8 loc, u8 val)
 {
 	if (ps2_command(ps2dev, NULL, MAKE_PS2_CMD(0, 0, TP_COMMAND)) ||
 	    ps2_command(ps2dev, NULL, MAKE_PS2_CMD(0, 0, TP_WRITE_MEM)) ||
@@ -70,8 +75,7 @@ static int trackpoint_write(struct ps2dev *ps2dev,
 	return 0;
 }
 
-static int trackpoint_toggle_bit(struct ps2dev *ps2dev,
-				 unsigned char loc, unsigned char mask)
+static int trackpoint_toggle_bit(struct ps2dev *ps2dev, u8 loc, u8 mask)
 {
 	/* Bad things will happen if the loc param isn't in this range */
 	if (loc < 0x20 || loc >= 0x2F)
@@ -87,11 +91,11 @@ static int trackpoint_toggle_bit(struct ps2dev *ps2dev,
 	return 0;
 }
 
-static int trackpoint_update_bit(struct ps2dev *ps2dev, unsigned char loc,
-				 unsigned char mask, unsigned char value)
+static int trackpoint_update_bit(struct ps2dev *ps2dev,
+				 u8 loc, u8 mask, u8 value)
 {
 	int retval = 0;
-	unsigned char data;
+	u8 data;
 
 	trackpoint_read(ps2dev, loc, &data);
 	if (((data & mask) == mask) != !!value)
@@ -105,17 +109,18 @@ static int trackpoint_update_bit(struct ps2dev *ps2dev, unsigned char loc,
  */
 struct trackpoint_attr_data {
 	size_t field_offset;
-	unsigned char command;
-	unsigned char mask;
-	unsigned char inverted;
-	unsigned char power_on_default;
+	u8 command;
+	u8 mask;
+	bool inverted;
+	u8 power_on_default;
 };
 
-static ssize_t trackpoint_show_int_attr(struct psmouse *psmouse, void *data, char *buf)
+static ssize_t trackpoint_show_int_attr(struct psmouse *psmouse,
+					void *data, char *buf)
 {
 	struct trackpoint_data *tp = psmouse->private;
 	struct trackpoint_attr_data *attr = data;
-	unsigned char value = *(unsigned char *)((char *)tp + attr->field_offset);
+	u8 value = *(u8 *)((void *)tp + attr->field_offset);
 
 	if (attr->inverted)
 		value = !value;
@@ -128,8 +133,8 @@ static ssize_t trackpoint_set_int_attr(struct psmouse *psmouse, void *data,
 {
 	struct trackpoint_data *tp = psmouse->private;
 	struct trackpoint_attr_data *attr = data;
-	unsigned char *field = (unsigned char *)((char *)tp + attr->field_offset);
-	unsigned char value;
+	u8 *field = (void *)tp + attr->field_offset;
+	u8 value;
 	int err;
 
 	err = kstrtou8(buf, 10, &value);
@@ -157,17 +162,14 @@ static ssize_t trackpoint_set_bit_attr(struct psmouse *psmouse, void *data,
 {
 	struct trackpoint_data *tp = psmouse->private;
 	struct trackpoint_attr_data *attr = data;
-	unsigned char *field = (unsigned char *)((char *)tp + attr->field_offset);
-	unsigned int value;
+	bool *field = (void *)tp + attr->field_offset;
+	bool value;
 	int err;
 
-	err = kstrtouint(buf, 10, &value);
+	err = kstrtobool(buf, &value);
 	if (err)
 		return err;
 
-	if (value > 1)
-		return -EINVAL;
-
 	if (attr->inverted)
 		value = !value;
 
@@ -193,30 +195,6 @@ PSMOUSE_DEFINE_ATTR(_name, S_IWUSR | S_IRUGO,				\
 		    &trackpoint_attr_##_name,				\
 		    trackpoint_show_int_attr, trackpoint_set_bit_attr)
 
-#define TRACKPOINT_UPDATE_BIT(_psmouse, _tp, _name)			\
-do {									\
-	struct trackpoint_attr_data *_attr = &trackpoint_attr_##_name;	\
-									\
-	trackpoint_update_bit(&_psmouse->ps2dev,			\
-			_attr->command, _attr->mask, _tp->_name);	\
-} while (0)
-
-#define TRACKPOINT_UPDATE(_power_on, _psmouse, _tp, _name)		\
-do {									\
-	if (!_power_on ||						\
-	    _tp->_name != trackpoint_attr_##_name.power_on_default) {	\
-		if (!trackpoint_attr_##_name.mask)			\
-			trackpoint_write(&_psmouse->ps2dev,		\
-				 trackpoint_attr_##_name.command,	\
-				 _tp->_name);				\
-		else							\
-			TRACKPOINT_UPDATE_BIT(_psmouse, _tp, _name);	\
-	}								\
-} while (0)
-
-#define TRACKPOINT_SET_POWER_ON_DEFAULT(_tp, _name)				\
-	(_tp->_name = trackpoint_attr_##_name.power_on_default)
-
 TRACKPOINT_INT_ATTR(sensitivity, TP_SENS, TP_DEF_SENS);
 TRACKPOINT_INT_ATTR(speed, TP_SPEED, TP_DEF_SPEED);
 TRACKPOINT_INT_ATTR(inertia, TP_INERTIA, TP_DEF_INERTIA);
@@ -229,13 +207,33 @@ TRACKPOINT_INT_ATTR(ztime, TP_Z_TIME, TP_DEF_Z_TIME);
 TRACKPOINT_INT_ATTR(jenks, TP_JENKS_CURV, TP_DEF_JENKS_CURV);
 TRACKPOINT_INT_ATTR(drift_time, TP_DRIFT_TIME, TP_DEF_DRIFT_TIME);
 
-TRACKPOINT_BIT_ATTR(press_to_select, TP_TOGGLE_PTSON, TP_MASK_PTSON, 0,
+TRACKPOINT_BIT_ATTR(press_to_select, TP_TOGGLE_PTSON, TP_MASK_PTSON, false,
 		    TP_DEF_PTSON);
-TRACKPOINT_BIT_ATTR(skipback, TP_TOGGLE_SKIPBACK, TP_MASK_SKIPBACK, 0,
+TRACKPOINT_BIT_ATTR(skipback, TP_TOGGLE_SKIPBACK, TP_MASK_SKIPBACK, false,
 		    TP_DEF_SKIPBACK);
-TRACKPOINT_BIT_ATTR(ext_dev, TP_TOGGLE_EXT_DEV, TP_MASK_EXT_DEV, 1,
+TRACKPOINT_BIT_ATTR(ext_dev, TP_TOGGLE_EXT_DEV, TP_MASK_EXT_DEV, true,
 		    TP_DEF_EXT_DEV);
 
+static bool trackpoint_is_attr_available(struct psmouse *psmouse,
+					 struct attribute *attr)
+{
+	struct trackpoint_data *tp = psmouse->private;
+
+	return tp->variant_id == TP_VARIANT_IBM ||
+		attr == &psmouse_attr_sensitivity.dattr.attr ||
+		attr == &psmouse_attr_press_to_select.dattr.attr;
+}
+
+static umode_t trackpoint_is_attr_visible(struct kobject *kobj,
+					  struct attribute *attr, int n)
+{
+	struct device *dev = container_of(kobj, struct device, kobj);
+	struct serio *serio = to_serio_port(dev);
+	struct psmouse *psmouse = serio_get_drvdata(serio);
+
+	return trackpoint_is_attr_available(psmouse, attr) ? attr->mode : 0;
+}
+
 static struct attribute *trackpoint_attrs[] = {
 	&psmouse_attr_sensitivity.dattr.attr,
 	&psmouse_attr_speed.dattr.attr,
@@ -255,24 +253,56 @@ static struct attribute *trackpoint_attrs[] = {
 };
 
 static struct attribute_group trackpoint_attr_group = {
-	.attrs = trackpoint_attrs,
+	.is_visible	= trackpoint_is_attr_visible,
+	.attrs		= trackpoint_attrs,
 };
 
-static int trackpoint_start_protocol(struct psmouse *psmouse, unsigned char *firmware_id)
-{
-	unsigned char param[2] = { 0 };
+#define TRACKPOINT_UPDATE(_power_on, _psmouse, _tp, _name)		\
+do {									\
+	struct trackpoint_attr_data *_attr = &trackpoint_attr_##_name;	\
+									\
+	if ((!_power_on || _tp->_name != _attr->power_on_default) &&	\
+	    trackpoint_is_attr_available(_psmouse,			\
+				&psmouse_attr_##_name.dattr.attr)) {	\
+		if (!_attr->mask)					\
+			trackpoint_write(&_psmouse->ps2dev,		\
+					 _attr->command, _tp->_name);	\
+		else							\
+			trackpoint_update_bit(&_psmouse->ps2dev,	\
+					_attr->command, _attr->mask,	\
+					_tp->_name);			\
+	}								\
+} while (0)
 
-	if (ps2_command(&psmouse->ps2dev, param, MAKE_PS2_CMD(0, 2, TP_READ_ID)))
-		return -1;
+#define TRACKPOINT_SET_POWER_ON_DEFAULT(_tp, _name)			\
+do {									\
+	_tp->_name = trackpoint_attr_##_name.power_on_default;		\
+} while (0)
 
-	/* add new TP ID. */
-	if (!(param[0] & TP_MAGIC_IDENT))
-		return -1;
+static int trackpoint_start_protocol(struct psmouse *psmouse,
+				     u8 *variant_id, u8 *firmware_id)
+{
+	u8 param[2] = { 0 };
+	int error;
 
-	if (firmware_id)
-		*firmware_id = param[1];
+	error = ps2_command(&psmouse->ps2dev,
+			    param, MAKE_PS2_CMD(0, 2, TP_READ_ID));
+	if (error)
+		return error;
+
+	switch (param[0]) {
+	case TP_VARIANT_IBM:
+	case TP_VARIANT_ALPS:
+	case TP_VARIANT_ELAN:
+	case TP_VARIANT_NXP:
+		if (variant_id)
+			*variant_id = param[0];
+		if (firmware_id)
+			*firmware_id = param[1];
+		break;
+	}
 
-	return 0;
+	return -ENODEV;
 }
 
 /*
@@ -285,7 +315,7 @@ static int trackpoint_sync(struct psmouse *psmouse, bool in_power_on_state)
 {
 	struct trackpoint_data *tp = psmouse->private;
 
-	if (!in_power_on_state) {
+	if (!in_power_on_state && tp->variant_id == TP_VARIANT_IBM) {
 		/*
 		 * Disable features that may make device unusable
 		 * with this driver.
@@ -347,7 +377,8 @@ static void trackpoint_defaults(struct trackpoint_data *tp)
 
 static void trackpoint_disconnect(struct psmouse *psmouse)
 {
-	sysfs_remove_group(&psmouse->ps2dev.serio->dev.kobj, &trackpoint_attr_group);
+	device_remove_group(&psmouse->ps2dev.serio->dev,
+			    &trackpoint_attr_group);
 
 	kfree(psmouse->private);
 	psmouse->private = NULL;
@@ -355,14 +386,20 @@ static void trackpoint_disconnect(struct psmouse *psmouse)
 
 static int trackpoint_reconnect(struct psmouse *psmouse)
 {
-	int reset_fail;
+	struct trackpoint_data *tp = psmouse->private;
+	int error;
+	bool was_reset;
 
-	if (trackpoint_start_protocol(psmouse, NULL))
-		return -1;
+	error = trackpoint_start_protocol(psmouse, NULL, NULL);
+	if (error)
+		return error;
 
-	reset_fail = trackpoint_power_on_reset(&psmouse->ps2dev);
-	if (trackpoint_sync(psmouse, !reset_fail))
-		return -1;
+	was_reset = tp->variant_id == TP_VARIANT_IBM &&
+		    trackpoint_power_on_reset(&psmouse->ps2dev) == 0;
+
+	error = trackpoint_sync(psmouse, was_reset);
+	if (error)
+		return error;
 
 	return 0;
 }
@@ -370,46 +407,62 @@ static int trackpoint_reconnect(struct psmouse *psmouse)
 int trackpoint_detect(struct psmouse *psmouse, bool set_properties)
 {
 	struct ps2dev *ps2dev = &psmouse->ps2dev;
-	unsigned char firmware_id;
-	unsigned char button_info;
+	struct trackpoint_data *tp;
+	u8 variant_id;
+	u8 firmware_id;
+	u8 button_info;
 	int error;
 
-	if (trackpoint_start_protocol(psmouse, &firmware_id))
-		return -1;
+	error = trackpoint_start_protocol(psmouse, &variant_id, &firmware_id);
+	if (error)
+		return error;
 
 	if (!set_properties)
 		return 0;
 
-	if (trackpoint_read(ps2dev, TP_EXT_BTN, &button_info)) {
-		psmouse_warn(psmouse, "failed to get extended button data, assuming 3 buttons\n");
-		button_info = 0x33;
-	}
-
-	psmouse->private = kzalloc(sizeof(struct trackpoint_data), GFP_KERNEL);
-	if (!psmouse->private)
+	tp = kzalloc(sizeof(*tp), GFP_KERNEL);
+	if (!tp)
 		return -ENOMEM;
 
-	psmouse->vendor = "IBM";
+	trackpoint_defaults(tp);
+	tp->variant_id = variant_id;
+	tp->firmware_id = firmware_id;
+
+	psmouse->private = tp;
+
+	psmouse->vendor = trackpoint_variants[variant_id];
 	psmouse->name = "TrackPoint";
 
 	psmouse->reconnect = trackpoint_reconnect;
 	psmouse->disconnect = trackpoint_disconnect;
 
+	if (variant_id != TP_VARIANT_IBM) {
+		/* Newer variants do not support extended button query. */
+		button_info = 0x33;
+	} else {
+		error = trackpoint_read(ps2dev, TP_EXT_BTN, &button_info);
+		if (error) {
+			psmouse_warn(psmouse,
+				     "failed to get extended button data, assuming 3 buttons\n");
+			button_info = 0x33;
+		}
+	}
+
 	if ((button_info & 0x0f) >= 3)
-		__set_bit(BTN_MIDDLE, psmouse->dev->keybit);
+		input_set_capability(psmouse->dev, EV_KEY, BTN_MIDDLE);
 
 	__set_bit(INPUT_PROP_POINTER, psmouse->dev->propbit);
 	__set_bit(INPUT_PROP_POINTING_STICK, psmouse->dev->propbit);
 
-	trackpoint_defaults(psmouse->private);
-
-	error = trackpoint_power_on_reset(ps2dev);
-
-	/* Write defaults to TP only if reset fails. */
-	if (error)
+	if (variant_id != TP_VARIANT_IBM ||
+	    trackpoint_power_on_reset(ps2dev) != 0) {
+		/*
+		 * Write defaults to TP if we did not reset the trackpoint.
+		 */
 		trackpoint_sync(psmouse, false);
+	}
 
-	error = sysfs_create_group(&ps2dev->serio->dev.kobj, &trackpoint_attr_group);
+	error = device_add_group(&ps2dev->serio->dev, &trackpoint_attr_group);
 	if (error) {
 		psmouse_err(psmouse,
 			    "failed to create sysfs attributes, error: %d\n",
@@ -420,8 +473,8 @@ int trackpoint_detect(struct psmouse *psmouse, bool set_properties)
 	}
 
 	psmouse_info(psmouse,
-		     "IBM TrackPoint firmware: 0x%02x, buttons: %d/%d\n",
-		     firmware_id,
+		     "%s TrackPoint firmware: 0x%02x, buttons: %d/%d\n",
+		     psmouse->vendor, firmware_id,
 		     (button_info & 0xf0) >> 4, button_info & 0x0f);
 
 	return 0;
diff --git a/drivers/input/mouse/trackpoint.h b/drivers/input/mouse/trackpoint.h
index 88055755f82e..10a039148234 100644
--- a/drivers/input/mouse/trackpoint.h
+++ b/drivers/input/mouse/trackpoint.h
@@ -21,10 +21,16 @@
 #define TP_COMMAND		0xE2	/* Commands start with this */
 
 #define TP_READ_ID		0xE1	/* Sent for device identification */
-#define TP_MAGIC_IDENT		0x03	/* Sent after a TP_READ_ID followed */
-					/* by the firmware ID */
-					/* Firmware ID includes 0x1, 0x2, 0x3 */
 
+/*
+ * Valid first byte responses to the "Read Secondary ID" (0xE1) command.
+ * 0x01 was the original IBM trackpoint, others implement very limited
+ * subset of trackpoint features.
+ */
+#define TP_VARIANT_IBM		0x01
+#define TP_VARIANT_ALPS		0x02
+#define TP_VARIANT_ELAN		0x03
+#define TP_VARIANT_NXP		0x04
 
 /*
  * Commands
@@ -136,18 +142,20 @@
 
 #define MAKE_PS2_CMD(params, results, cmd) ((params<<12) | (results<<8) | (cmd))
 
-struct trackpoint_data
-{
-	unsigned char sensitivity, speed, inertia, reach;
-	unsigned char draghys, mindrag;
-	unsigned char thresh, upthresh;
-	unsigned char ztime, jenks;
-	unsigned char drift_time;
+struct trackpoint_data {
+	u8 variant_id;
+	u8 firmware_id;
+
+	u8 sensitivity, speed, inertia, reach;
+	u8 draghys, mindrag;
+	u8 thresh, upthresh;
+	u8 ztime, jenks;
+	u8 drift_time;
 
 	/* toggles */
-	unsigned char press_to_select;
-	unsigned char skipback;
-	unsigned char ext_dev;
+	bool press_to_select;
+	bool skipback;
+	bool ext_dev;
 };
 
 #ifdef CONFIG_MOUSE_PS2_TRACKPOINT

^ permalink raw reply related

* [PATCH v2 1/2] HID: i2c-hid: fix size check and type usage
From: Aaron Ma @ 2018-01-08  2:41 UTC (permalink / raw)
  To: linux-kernel, linux-input, jikos, benjamin.tissoires, aaron.ma

When convert char array with signed int, if the inbuf[x] is negative then
upper bits will be set to 1. Fix this by using u8 instead of char.

ret_size has to be at least 3, hid_input_report use it after minus 2 bytes.

Cc: stable@vger.kernel.org
Signed-off-by: Aaron Ma <aaron.ma@canonical.com>
---
 drivers/hid/i2c-hid/i2c-hid.c | 13 +++++++------
 1 file changed, 7 insertions(+), 6 deletions(-)

diff --git a/drivers/hid/i2c-hid/i2c-hid.c b/drivers/hid/i2c-hid/i2c-hid.c
index e054ee43c1e2..d17d1950392b 100644
--- a/drivers/hid/i2c-hid/i2c-hid.c
+++ b/drivers/hid/i2c-hid/i2c-hid.c
@@ -144,10 +144,10 @@ struct i2c_hid {
 						   * register of the HID
 						   * descriptor. */
 	unsigned int		bufsize;	/* i2c buffer size */
-	char			*inbuf;		/* Input buffer */
-	char			*rawbuf;	/* Raw Input buffer */
-	char			*cmdbuf;	/* Command buffer */
-	char			*argsbuf;	/* Command arguments buffer */
+	u8			*inbuf;		/* Input buffer */
+	u8			*rawbuf;	/* Raw Input buffer */
+	u8			*cmdbuf;	/* Command buffer */
+	u8			*argsbuf;	/* Command arguments buffer */
 
 	unsigned long		flags;		/* device flags */
 	unsigned long		quirks;		/* Various quirks */
@@ -455,7 +455,8 @@ static int i2c_hid_hwreset(struct i2c_client *client)
 
 static void i2c_hid_get_input(struct i2c_hid *ihid)
 {
-	int ret, ret_size;
+	int ret;
+	u32 ret_size;
 	int size = le16_to_cpu(ihid->hdesc.wMaxInputLength);
 
 	if (size > ihid->bufsize)
@@ -480,7 +481,7 @@ static void i2c_hid_get_input(struct i2c_hid *ihid)
 		return;
 	}
 
-	if (ret_size > size) {
+	if ((ret_size > size) || (ret_size <= 2)) {
 		dev_err(&ihid->client->dev, "%s: incomplete report (%d/%d)\n",
 			__func__, size, ret_size);
 		return;
-- 
2.14.3


^ permalink raw reply related

* [PATCH v2 2/2] HID: core: Fix size as type u32
From: Aaron Ma @ 2018-01-08  2:41 UTC (permalink / raw)
  To: linux-kernel, linux-input, jikos, benjamin.tissoires, aaron.ma
In-Reply-To: <20180108024141.10590-1-aaron.ma@canonical.com>

When size is negative, calling memset will make segment fault.
Declare the size as type u32 to keep memset safe.

size in struct hid_report is unsigned, fix return type of
hid_report_len to u32.

Cc: stable@vger.kernel.org
Signed-off-by: Aaron Ma <aaron.ma@canonical.com>
---
 drivers/hid/hid-core.c | 10 +++++-----
 include/linux/hid.h    |  6 +++---
 2 files changed, 8 insertions(+), 8 deletions(-)

diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c
index 0c3f608131cf..cf81c53e3b98 100644
--- a/drivers/hid/hid-core.c
+++ b/drivers/hid/hid-core.c
@@ -1390,7 +1390,7 @@ u8 *hid_alloc_report_buf(struct hid_report *report, gfp_t flags)
 	 * of implement() working on 8 byte chunks
 	 */
 
-	int len = hid_report_len(report) + 7;
+	u32 len = hid_report_len(report) + 7;
 
 	return kmalloc(len, flags);
 }
@@ -1455,7 +1455,7 @@ void __hid_request(struct hid_device *hid, struct hid_report *report,
 {
 	char *buf;
 	int ret;
-	int len;
+	u32 len;
 
 	buf = hid_alloc_report_buf(report, GFP_KERNEL);
 	if (!buf)
@@ -1481,14 +1481,14 @@ void __hid_request(struct hid_device *hid, struct hid_report *report,
 }
 EXPORT_SYMBOL_GPL(__hid_request);
 
-int hid_report_raw_event(struct hid_device *hid, int type, u8 *data, int size,
+int hid_report_raw_event(struct hid_device *hid, int type, u8 *data, u32 size,
 		int interrupt)
 {
 	struct hid_report_enum *report_enum = hid->report_enum + type;
 	struct hid_report *report;
 	struct hid_driver *hdrv;
 	unsigned int a;
-	int rsize, csize = size;
+	u32 rsize, csize = size;
 	u8 *cdata = data;
 	int ret = 0;
 
@@ -1546,7 +1546,7 @@ EXPORT_SYMBOL_GPL(hid_report_raw_event);
  *
  * This is data entry for lower layers.
  */
-int hid_input_report(struct hid_device *hid, int type, u8 *data, int size, int interrupt)
+int hid_input_report(struct hid_device *hid, int type, u8 *data, u32 size, int interrupt)
 {
 	struct hid_report_enum *report_enum;
 	struct hid_driver *hdrv;
diff --git a/include/linux/hid.h b/include/linux/hid.h
index d491027a7c22..9bc296eebc98 100644
--- a/include/linux/hid.h
+++ b/include/linux/hid.h
@@ -841,7 +841,7 @@ extern int hidinput_connect(struct hid_device *hid, unsigned int force);
 extern void hidinput_disconnect(struct hid_device *);
 
 int hid_set_field(struct hid_field *, unsigned, __s32);
-int hid_input_report(struct hid_device *, int type, u8 *, int, int);
+int hid_input_report(struct hid_device *, int type, u8 *, u32, int);
 int hidinput_find_field(struct hid_device *hid, unsigned int type, unsigned int code, struct hid_field **field);
 struct hid_field *hidinput_get_led_field(struct hid_device *hid);
 unsigned int hidinput_count_leds(struct hid_device *hid);
@@ -1088,13 +1088,13 @@ static inline void hid_hw_wait(struct hid_device *hdev)
  *
  * @report: the report we want to know the length
  */
-static inline int hid_report_len(struct hid_report *report)
+static inline u32 hid_report_len(struct hid_report *report)
 {
 	/* equivalent to DIV_ROUND_UP(report->size, 8) + !!(report->id > 0) */
 	return ((report->size - 1) >> 3) + 1 + (report->id > 0);
 }
 
-int hid_report_raw_event(struct hid_device *hid, int type, u8 *data, int size,
+int hid_report_raw_event(struct hid_device *hid, int type, u8 *data, u32 size,
 		int interrupt);
 
 /* HID quirks API */
-- 
2.14.3


^ permalink raw reply related

* Re: [PATCH 1/3] Input: twl4030-vibra: fix sibling-node lookup
From: Johan Hovold @ 2018-01-08 13:55 UTC (permalink / raw)
  To: Dmitry Torokhov
  Cc: linux-input, linux-kernel, Johan Hovold, stable, Peter Ujfalusi,
	Marek Belisko
In-Reply-To: <20171211102121.GJ5672@localhost>

On Mon, Dec 11, 2017 at 11:21:21AM +0100, Johan Hovold wrote:
> On Sat, Nov 11, 2017 at 04:43:37PM +0100, Johan Hovold wrote:
> > A helper purported to look up a child node based on its name was using
> > the wrong of-helper and ended up prematurely freeing the parent of-node
> > while searching the whole device tree depth-first starting at the parent
> > node.
> > 
> > Fixes: 64b9e4d803b1 ("input: twl4030-vibra: Support for DT booted kernel")
> > Fixes: e661d0a04462 ("Input: twl4030-vibra - fix ERROR: Bad of_node_put() warning")
> > Cc: stable <stable@vger.kernel.org>     # 3.7
> > Cc: Peter Ujfalusi <peter.ujfalusi@ti.com>
> > Cc: Marek Belisko <marek@goldelico.com>
> > Signed-off-by: Johan Hovold <johan@kernel.org>
> > ---
> 
> Just wanted to send a reminder about this series. I believe these bugs
> need to be fixes regardless of whether MFD-core eventually provides some
> means of avoiding such lookups in cell drivers (i.e. the discussion
> which appears to have stalled).

Another month, another reminder: Will you pick this series up for 4.16,
Dmitry?

Thanks,
Johan

^ permalink raw reply

* Re: [PATCH 12/14] iio: adc: at91-sama5d2_adc: support for position and pressure channels
From: Ludovic Desroches @ 2018-01-08 14:12 UTC (permalink / raw)
  To: Jonathan Cameron
  Cc: Eugen Hristev, nicolas.ferre-UWL1GkI3JZL3oGB3hsPCZA,
	ludovic.desroches-UWL1GkI3JZL3oGB3hsPCZA,
	alexandre.belloni-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8,
	linux-iio-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	linux-input-u79uwXL29TY76Z2rM5mHXA,
	dmitry.torokhov-Re5JQEeQqe8AvxtiuMwx3w
In-Reply-To: <20180106150537.684345f3@archlinux>

Hi Jonathan, Eugen,

On Sat, Jan 06, 2018 at 03:05:37PM +0000, Jonathan Cameron wrote:
> On Thu, 4 Jan 2018 17:17:54 +0200
> Eugen Hristev <eugen.hristev-UWL1GkI3JZL3oGB3hsPCZA@public.gmane.org> wrote:
> 
> > On 29.12.2017 19:02, Jonathan Cameron wrote:
> > > On Fri, 22 Dec 2017 17:07:19 +0200
> > > Eugen Hristev <eugen.hristev-UWL1GkI3JZL3oGB3hsPCZA@public.gmane.org> wrote:
> > >   
> > >> The ADC IP supports position and pressure measurements for a touchpad
> > >> connected on channels 0,1,2,3 for a 4-wire touchscreen with pressure
> > >> measurement support.
> > >> Using the inkern API, a driver can request a trigger and read the
> > >> channel values from the ADC.
> > >> The implementation provides a trigger named "touch" which can be
> > >> connected to a consumer driver.
> > >> Once a driver connects and attaches a pollfunc to this trigger, the
> > >> configure trigger callback is called, and then the ADC driver will
> > >> initialize pad measurement.
> > >> First step is to enable touchscreen 4wire support and enable
> > >> pen detect IRQ.
> > >> Once a pen is detected, a periodic trigger is setup to trigger every
> > >> 2 ms (e.g.) and sample the resistive touchscreen values. The trigger poll
> > >> is called, and the consumer driver is then woke up, and it can read the
> > >> respective channels for the values : X, and Y for position and pressure
> > >> channel.
> > >> Because only one trigger can be active in hardware in the same time,
> > >> while touching the pad, the ADC will block any attempt to use the
> > >> triggered buffer. Same, conversions using the software trigger are also
> > >> impossible (since the periodic trigger is setup).
> > >> If some driver wants to attach while the trigger is in use, it will
> > >> also fail.
> > >> Once the pen is not detected anymore, the trigger is free for use (hardware
> > >> or software trigger, with or without DMA).
> > >> Channels 0,1,2 and 3 are unavailable if a touchscreen is enabled.
> > >>
> > >> Some parts of this patch are based on initial original work by
> > >> Mohamed Jamsheeth Hajanajubudeen and Bandaru Venkateswara Swamy
> > >>  
> > > OK, so comments inline.
> > > 
> > > What I'm missing currently though is an explanation of why the slightly
> > > more standard arrangement of using a callback buffer doesn't work here.
> > > The only addition I think you need to do that is to allow a consumer to
> > > request a particular trigger.  I also think some of the other provisions
> > > could be handled using standard features and slightly reducing the flexibility.
> > > I don't know for example if it's useful to allow other channels to be
> > > read when touch is not in progress or not.
> > > 
> > > So restrictions:
> > > 
> > > 1. Touch screen channels can only be read when touch is enabled.
> > >   - use the available_scan_masks to control this. Or the callback that lets
> > >     you do the same dynamically.
> > > 2. You need to push these channels to your consumer driver.
> > >   - register a callback buffer rather than jumping through the hoops to
> > >     insert your own pollfunc.  That will call a function in your
> > >     consumer, providing the data from the 3 channels directly.
> > > 3. You need to make sure it is using the right driver.  For that you
> > >     will I think need a new interface.
> > > 
> > > Various other comments inline. I may well be missing something as this is
> > > a fair bit of complex code to read - if so then next version should have
> > > a clear cover letter describing why this more standard approach can't be
> > > used.  
> > 
> > Hello Jonathan and thanks for the review of my patch series,
> > 
> > before starting and working over the required modifications and 
> > suggestions that you sent me, I want to be a little more explicit about 
> > the design of my implementation.
> > Hope this will clarify some things, and maybe I can as well understand 
> > better what you have in mind to support this feature set.
> > 
> > Why have I picked a pollfunction: We discussed a while back on the 
> > mailing list that you do not have an inkern mechanism to expose the 
> > triggers to other drivers, and that it may be a good idea to have it for 
> > such kind of actually multi function device, instead of having a MFD 
> > driver, an ADC driver, and an Input driver, all sharing the same 
> > register map, the same IRQ , etc, with some kind of synchronization to 
> > avoid stepping on each other for the hardware resource.
> 
> No disagreement with that principle.
> 
> > So I considered to expose the trigger by attaching and detaching 
> > pollfunctions to it. Which is the main thing what we use a trigger for.
> 
> Hmm. It's definitely one approach. But we do already have other drivers
> where the trigger is controlled by a consumer and to my mind that
> is a cleaner approach as it doesn't short cut the equivalent of
> doing it from userspace.
> 
> drivers/iio/potentiostat/lmp91000.c does something similar though
> for a rather different use. You need your consumer interface
> to get the handle to the trigger in this case
> (the lmp91000 is actually providing the trigger rather than
> consuming it).
> 
> 
> > 
> > So, what I had in mind, was to create a consumer driver that will 
> > request triggers from the IIO device just like other drivers request 
> > channels (part which is already done in IIO).
> > In order to do this I had to somehow wake up the consumer driver when 
> > new data was available from the touchscreen. So, having the IRQ only in 
> > the ADC device, and then on Pen detect and No pen detect just start or 
> > stop the periodic trigger, which needs to be polled. The magic part is 
> > that the consumer driver has a poll function already attached to this 
> > trigger, so the poll function is just called every time we have new 
> > data. The poll function is attached as an irq handler, and then we can 
> > reuse all the read_raw data by using a scheduled work from the consumer 
> > driver, to read the channels.
> 
> If you had done this via a callback buffer the only difference is that
> the pollfunc would have been a standard one pulling the relevant channels
> and passing them on down to the buffer interface which could then decide
> what to do with them.
> 
> > To do this, the ADC registers a special trigger named "touch trigger" 
> > which is never enabled by the ADC driver. Instead, when a pollfunc is 
> > attached to it, the attach function will also configure it with enabled 
> > state.
> 
> Whilst it might not make sense to enable it in the touch screen driver
> I'm not sure there is strictly any reason to prevent it being so used.
> 
> > In the ADC, this means to start the touchscreen functionality. If 
> > the touch is requested, it will standby and wait for pen detect IRQ.
> > Once we have pen detect, we can use a periodic trigger to sample the 
> > touch data, and poll the "touch" trigger. The consumer driver will wake 
> > up and schedule a work , that will use the standard read raw interface 
> > (inkern) that will read three virtual channels (position + pressure). 
> > They are not actual hardware channels, as the touch information is being 
> > received on channels 0,1,2,3, but reading these virtual channels will 
> > read from different registers inside the ADC IP ( x position, y 
> > position, pressure), do some computations on the data, and feed the 
> > consumer with the values , hiding the behind the scenes hardware 
> > specific calculations.
> 
> I wouldn't worry about whether they are real channels or not. This
> is really similar to a differential ADC (some of those do the differential
> digitally). Light sensors often have a number of 'real' channels used
> to derive (via hideous non linear calculations) the illuminance as
> it's hard to build a light sensor with the same sensitivity as the human
> eye.  We have worse 'non real' channels as well such as activity channels
> on some the accelerometers that report if it thinks you are walking /
> running etc.
>  
> > After trigger is polled , the ADC will resume normal functionality, and 
> > the consumer driver will continue to sleep.
> 
> So this is where I'm unsure.  Do you actually have a usecase where it
> makes the sense to read from the ADC only when there is no touch?  Any
> system doing that has an obvious denial of service attack - touch the
> screen.
> 

You're right. We have an issue in this case due to the hardware. Using
touchscreen has side effects on other channels. We can use only one
trigger for all the channels. The situation would have been better with
a trigger dedicated to the touchscreen.

At the moment, we have not really stated about the exclusive use or not
of the touchscreen. We suppose we can get some customers wanting to use
both touchscreen and ADC. Eugen tried to deal with this case but, as you
noticed, it can lead to DoS.

> > We need to have a periodic trigger to sample the data because the actual 
> > analog to digital conversion inside the IP block needs to be triggered. 
> > The touchscreen data measurements cannot happen in hardware without 
> > being triggered. If I try with a hrtimer to get a periodic IRQ to just 
> > read the data, it will never be ready. The datasheet states that the 
> > touchscreen measurements "will be attached to the conversion sequence". 
> > So the periodic trigger is forcing a conversion sequence. This could be 
> > done with a software trigger as well, but why the hassle to start it 
> > every 2 milliseconds (or other time interval), if we can do it by 
> > periodic trigger ?
> 
> Ah, one reason here would be to allow separate consumers to use the
> device. In that case you'd run with a periodic trigger all the time
> and have two buffers attached, the buffer_cb that is feeding your
> touchscreen and another buffer to deal with the other channels
> (presumably the standard one an IIO device has when using buffered
> interfaces).

The issue is that we are sharing the periodic trigger so we have to use
the same period for both usage.

Regards

Ludovic

> 
> The buffer demux would ensure the data from the right channels
> ends up in the right place.  It makes it look to the buffer
> consumer like it is the only thing using / controlling the data
> flow.
> 
> > Once we get the No pen IRQ, we stop the periodic trigger and it can be 
> > used in another purpose (software or external as of now in the driver, 
> > in the future we can add PWM trigger and Timer trigger)
> 
> This case isn't really useful though as any other use is denied
> access when touch occurs.
> 
> I'll summarise what I think would work for this below.
> 
> > 
> > In short, the ADC in Sama5D2 also supports touchscreen, and in 
> > touchscreen mode , 4 of the channels are being used for this purpose. 
> > This however, doesn't stop the ADC to use the other channels . The 
> > hardware has 12 total single channels and they can be paired to have 6 
> > more differential channels. The only thing that is blocked is the 
> > trigger, but only if the pen is touching (when we start the periodic 
> > trigger to sample the touchscreen). If the pen is not touching, an 
> > external trigger or software trigger can be used without any issues (so 
> > why limit the functionality, if this is available from hardware ?). 
> > Because of the reason I discussed above (touchscreen sequence must be 
> > triggered), we cannot use another trigger in the same time.
> > 
> > 
> > I see your idea with the callback buffer and it's worth exploring. 
> > Mainly this series was to actually show you what I had in mind about 
> > supporting the resistive touchscreen, and to give you some actually 
> > working code/patch, so we can discuss based on real implementation, not 
> > just suppositions.
> 
> That side of things is fine.
> 
> > 
> > You are right in many of the other comments that you said, and I will 
> > come up with a v2 to this series. For now, I need to know if this is a 
> > good or right direction in which I am going, or I should try to change 
> > all the mechanism to callback buffer ? Or maybe I am totally in a bad 
> > direction ?
> > The requirements are that the consumer driver needs to be somehow woke 
> > up for every new touch data available, and report to the input 
> > subsystem. As it was done before, the at91 old driver, just creates and 
> > registers an input device by itself, and then reports the position and 
> > touches. I was thinking that with this trigger consumer implementation, 
> > things can be better in terms of subsystem separation and support.
> > 
> > Thanks again and let me know of your thoughts,
> > 
> > Eugen
> 
> So a couple of things come to mind on how I'd structure this.
> So what we have (very briefly)
> 
> No touch screen case:
> * Generic ADC using all sorts of different triggers
> 
> Touch screen only case:
> * Interrupt to indicate pen on / off
> * A need to do a periodic trigger of the device but only
> useful when touch is in progress.
> 
> Touch screen and other users:
> * Interrupt to indicate pen on / off
> * Periodic trigger needed for touchscreen when touch in progress.
> * Do not have denial of service on other channels.
> 
> First two cases are easy enough by having a magic trigger, third
> case is harder.
> If we have the touchscreen then I would drop support for direct access to
> to ADC channels whilst it's in use (so no sysfs - or emulate it if you
> really want it by stashing results from scans done when touch is in
> progress).
> 
> Have your touch screen channels just as normal additional channels,
> but only via the buffered interface (no _RAW attribute).
> If someone sets up to read them via buffered interface with
> a different trigger I think they'll get values - whether they
> are right is dependent (if I understand correctly) on whether
> there is a touch in progress.  So no harm done and it'll make
> the logic simpler.
> 
> The moment touch is opened and acquires the IIO channels
> fix the trigger (may need new interface) to the periodic one
> that you were enabling and disabling on touch.
> Things get dicey if there is an existing user so you may
> have to do it on driver probe rather than open of the input
> device if we effectively want touch to have the highest
> priority use of the ADC.
> 
> If other channels are enabled for buffered mode then note
> this in the driver and have the periodic trigger on all the
> time (to ensure they keep getting read)  This will pass
> garbage to your touch screen driver, but it'll remove it due
> to the pressure value being too low so no harm there.
> 
> Normal path will work for non touch channels (and in theory
> the touch ones if they are turned on) via IIO buffer
> interface.  It'll be restricted in form due to the needs of
> the touch driver, but better than nothing and should cover
> most usecases.
> 
> Now the interrupt on / off on touch bit becomes an optimization
> in the case of only the buffer_cb being attached.
> 
> I think that fits cleanly in the current IIO framework and
> looks more similar to our existing provider consumer approaches.
> 
> Still needs the hooks to get hold of the trigger though so
> as to be able to tell the ADC which one to use. So rather
> than being a trigger consumer interface, it's more of a trigger
> configuration interface..  Exact term doesn't matter though.
> 
> Jonathan
> 
> > 
> > 
> > 
> > [...]
> > --
> > To unsubscribe from this list: send the line "unsubscribe linux-iio" in
> > the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
> > More majordomo info at  http://vger.kernel.org/majordomo-info.html
> 

^ permalink raw reply

* Re: [PATCH] Revert "Input: trackpoint - add new trackpoint firmware ID"
From: Sebastian Schmidt @ 2018-01-08 15:11 UTC (permalink / raw)
  To: Dmitry Torokhov; +Cc: Aaron Ma, Greg KH, linux-input
In-Reply-To: <20180107065201.q2xck62unijt3avr@dtor-ws>

Hi Dmitry,

On Sat, Jan 06, 2018 at 10:52:01PM -0800, Dmitry Torokhov wrote:
> Guys, could you please try the patch below? It will not solve the
> "speed" issue on 0x01 devices, but hopefully we won't be exposing
> non-existing controls on others.

Thanks for looking into this. Which speed issue on 0x01 devices? I
thought those were the legacy ones that used to work and still do as
ever.

I've tried your (slightly modified, see below) patch and the trackpoint
now gets apparently[1] correctly detected as "psmouse serio2:
trackpoint: Elan TrackPoint firmware: 0x04, buttons: 3/3". However, I
still have the feeling that it's a lot more sensitive (or faster?) than
with the regular PS/2 driver - even with libinput accel speed turned to
-1. I don't know how I could measure this objectively, but there must be
some difference between the trackpoint driver and the regular one. Is it
maybe an init sequence that causes it to report more sensitively, or a
different resolution, or ...? I really have no idea how mice work. :)

Also, I'm wondering, since my trackpoint works just fine as "Generic
PS/2 Mouse", including the third button. The driver even says:
| /*
|  * Bare PS/2 protocol "detection". Always succeeds.
|  */
| static int ps2bare_detect(struct psmouse *psmouse, bool set_properties)
| {
| [...]
|         /*
|          * We have no way of figuring true number of buttons so let's
|          * assume that the device has 3.
|          */
|         __set_bit(BTN_MIDDLE, psmouse->dev->keybit);
|     }
| 
|     return 0;
| }

So I wonder what driver Aaron was using that didn't report a third
button. What vendor/firmwares did you (get reports of) have that middle
mouse button problem on, Aaron?

Thanks,

Sebastian


1: If it's actually Elan. I've taken out my battery but could only
find FRU numbers on the back of the keyboard, no signs of a vendor.
<https://photos.app.goo.gl/iafpfzvRY042dOBo2> or
<https://t.yath.de/IMG_20180108_143205.jpg>

In trackpoint_start_protocol:
> +   switch (param[0]) {
> +   case TP_VARIANT_IBM:
> +   case TP_VARIANT_ALPS:
> +   case TP_VARIANT_ELAN:
> +   case TP_VARIANT_NXP:
> +       if (variant_id)
> +           *variant_id = param[0];
> +       if (firmware_id)
> +           *firmware_id = param[1];
> +       break;
          ^^^^^
          That should be a return 0.
> +   }
> 
> -   return 0;
> +   return -ENODEV;
>  }

^ permalink raw reply

* Re: [PATCH v5 2/3] input: evdev: Replace timeval with timespec64
From: Dmitry Torokhov @ 2018-01-08 20:54 UTC (permalink / raw)
  To: Deepa Dinamani
  Cc: Arnd Bergmann, open list:HID CORE LAYER,
	Linux Kernel Mailing List, Peter Hutterer, y2038 Mailman List
In-Reply-To: <CABeXuvpo4cGPZ9heU3ZqWt88WSCbF3qp2NmfU+q94zc4-o0C_g@mail.gmail.com>

On Sat, Jan 06, 2018 at 01:43:34PM -0800, Deepa Dinamani wrote:
> On Tue, Jan 2, 2018 at 7:35 AM, Arnd Bergmann <arnd@arndb.de> wrote:
> > On Tue, Jan 2, 2018 at 7:46 AM, Dmitry Torokhov
> > <dmitry.torokhov@gmail.com> wrote:
> >> On Sun, Dec 17, 2017 at 09:18:43PM -0800, Deepa Dinamani wrote:
> >>> @@ -304,12 +314,11 @@ static void evdev_events(struct input_handle *handle,
> >>>  {
> >>>       struct evdev *evdev = handle->private;
> >>>       struct evdev_client *client;
> >>> -     ktime_t ev_time[EV_CLK_MAX];
> >>> +     struct timespec64 ev_time[EV_CLK_MAX];
> >>>
> >>> -     ev_time[EV_CLK_MONO] = ktime_get();
> >>> -     ev_time[EV_CLK_REAL] = ktime_mono_to_real(ev_time[EV_CLK_MONO]);
> >>> -     ev_time[EV_CLK_BOOT] = ktime_mono_to_any(ev_time[EV_CLK_MONO],
> >>> -                                              TK_OFFS_BOOT);
> >>> +     ktime_get_ts64(&ev_time[EV_CLK_MONO]);
> >>> +     ktime_get_real_ts64(&ev_time[EV_CLK_REAL]);
> >>> +     get_monotonic_boottime64(&ev_time[EV_CLK_BOOT]);
> >>
> >> This may result in different ev_time[] members holding different times,
> >> whereas the original code would take one time sample and convert it to
> >> different clocks.
> >
> > Is this important? On each client we only return one of the two
> > times, and I would guess that you cannot rely on a correlation
> > between timestamps on different devices, since the boot and real
> > offsets can change over time.
> 
> Right. I didn't think this was an issue either.
> 
> >> Also, why can't we keep using ktime_t internally? It is y2038 safe,
> >> right?
> >
> > Correct, but there may also be a performance difference if we get
> > a lot of events, not sure if that matters.
> >
> >> I think you should drop this patch and adjust the 3rd one to
> >> massage the input event timestamp patch to do ktime->timespec64->input
> >> timestamp conversion.
> >
> > The change in __evdev_queue_syn_dropped still seems useful to me
> > as ktime_get_*ts64() is a bit more efficient than ktime_get*() followed by
> > a slow ktime_to_timespec64() or ktime_to_timeval().
> >
> > For evdev_events(), doing a single ktime_get() followed by a
> > ktime_to_timespec64/ktime_to_timeval can be faster than three
> > ktime_get_*ts64 (depending on the hardware clock source), or
> > it can be slower depending on the CPU and the clocksource
> > hardware. Again, no idea if this matters at the usual rate of
> > input events.
> >
> > I guess dropping the evdev_events() change and replacing it with a
> > ktime_to_timespec64 change in evdev_pass_values()
> > would be fine here, it should keep the current performance
> > behavior and get rid of the timeval.
> 
> I was trying to use timespec64 everywhere so that we would not have
> conversions back and forth at the input layer.
> I dropped the ktime_t conversions for now and merged this patch with
> the next one as requested.
> 
> Let me know if you would like to keep the changes Arnd preferred above
> for __evdev_queue_syn_dropped(). I can submit a separate patch if this
> is preferred.

__evdev_queue_syn_dropped() is extremely cold path (hopefully, if it is
not we have much bigger problems) so I'd leave it as is.

Thanks!

-- 
Dmitry

^ permalink raw reply

* Re: [PATCH v6 1/1] input: Deprecate real timestamps beyond year 2106
From: Dmitry Torokhov @ 2018-01-08 21:51 UTC (permalink / raw)
  To: Deepa Dinamani; +Cc: y2038, peter.hutterer, linux-kernel, arnd, linux-input
In-Reply-To: <20180107001915.15287-2-deepa.kernel@gmail.com>

Hi Deepa,

On Sat, Jan 06, 2018 at 04:19:15PM -0800, Deepa Dinamani wrote:
> struct timeval is not y2038 safe.
> All usage of timeval in the kernel will be replaced by
> y2038 safe structures.
> The change is also necessary as glibc is introducing support
> for 32 bit applications to use 64 bit time_t. Without this
> change, many applications would incorrectly interpret values
> in the struct input_event.
> More details about glibc at
> https://sourceware.org/glibc/wiki/Y2038ProofnessDesign .
> 
> struct input_event maintains time for each input event.
> Real time timestamps are not ideal for input as this
> time can go backwards as noted in the patch a80b83b7b8
> by John Stultz. Hence, having the input_event.time fields
> only big enough for monotonic and boot times are
> sufficient.

I am happy with the patch, but have some concerns about changelog. The
change does not really prevent anyone from using CLOCK_REALTIME past
2106, especially on 64 bit arches. We are simply extending range of
reported seconds in input event by converting from signed to unsigned
value.

> 
> The change leaves the representation of struct input_event as is
> on 64 bit architectures. But uses 2 unsigned long values on 32 bit
> machines to support real timestamps until year 2106.
> This intentionally breaks the ABI on 32 bit architectures and
> compat handling on 64 bit architectures.
> This is as per maintainer's preference to introduce compile time errors
> rather than run into runtime incompatibilities.

We are breaking API, not ABI though. The ABI for existing programs is
exactly the same, it is only when system starts using the newer glibc
supporting extended time the compilation will break.

> The change requires any 32 bit userspace utilities reading or writing
> from event nodes to update their reading format to match the new
> input_event. The changes to the popular libraries will be posted once
> we agree on the kernel change.

I propose we have the following changelog:


Input: extend usable life of event timestamps to 2106 on 32 bit systems

The input events use struct timeval to store event time, unfortunately
this structure is not y2038 safe and is being replaced in kernel with
y2038 safe structures.

Because of ABI concerns we can not change the size or the layout of
structure input_event, so we opt to re-interpreting the 'seconds' part
of timestamp as an unsigned value, effectively doubling the range of
values, to year 2106.

Newer glibc that has support for 32 bit applications to use 64 bit
time_t supplies __USE_TIME_BITS64 define [1], that we can use to present
the userspace with updated input_event layout. The updated layout will
cause the compile time breakage, alerting applications and distributions
maintainers to the issue. Existing 32 binaries will continue working
without any changes until 2038.

Ultimately userspace applications should switch to using monotonic or
boot time clocks, as realtime clock is not very well suited for input
event timestamps as it can go backwards (see a80b83b7b8 "Input: evdev -
add CLOCK_BOOTTIME support" by by John Stultz). With monotonic clock the
practical range of reported times will always fit into the pair of 32
bit values, as we do not expect any system to stay up for a hundred
years without a single reboot.

[1] https://sourceware.org/glibc/wiki/Y2038ProofnessDesign


Please let me know if you disagee with the above.

Thanks!

-- 
Dmitry
_______________________________________________
Y2038 mailing list
Y2038@lists.linaro.org
https://lists.linaro.org/mailman/listinfo/y2038

^ permalink raw reply

* [PATCH] Input: cyapa - remove duplicated macro definitions
From: Rasmus Villemoes @ 2018-01-08 21:54 UTC (permalink / raw)
  To: Dmitry Torokhov; +Cc: Rasmus Villemoes, linux-input, linux-kernel

Apart from whitespace differences, this block of macros is repeated
twice:

$ x=./drivers/input/mouse/cyapa_gen3.c; diff -w -u <(sed -n '139,181p' $x) <(sed -n '182,224p' $x)
$

Signed-off-by: Rasmus Villemoes <linux@rasmusvillemoes.dk>
---
 drivers/input/mouse/cyapa_gen3.c | 43 ----------------------------------------
 1 file changed, 43 deletions(-)

diff --git a/drivers/input/mouse/cyapa_gen3.c b/drivers/input/mouse/cyapa_gen3.c
index 1cbfa4a6e830..076dda4a66da 100644
--- a/drivers/input/mouse/cyapa_gen3.c
+++ b/drivers/input/mouse/cyapa_gen3.c
@@ -136,49 +136,6 @@ static const u8 bl_exit[] = { 0x00, 0xff, 0xa5, 0x00, 0x01, 0x02, 0x03, 0x04,
 		0x05, 0x06, 0x07 };
 
 
- /* for byte read/write command */
-#define CMD_RESET      0
-#define CMD_POWER_MODE 1
-#define CMD_DEV_STATUS 2
-#define CMD_REPORT_MAX_BASELINE 3
-#define CMD_REPORT_MIN_BASELINE 4
-#define SMBUS_BYTE_CMD(cmd) (((cmd) & 0x3f) << 1)
-#define CYAPA_SMBUS_RESET         SMBUS_BYTE_CMD(CMD_RESET)
-#define CYAPA_SMBUS_POWER_MODE    SMBUS_BYTE_CMD(CMD_POWER_MODE)
-#define CYAPA_SMBUS_DEV_STATUS    SMBUS_BYTE_CMD(CMD_DEV_STATUS)
-#define CYAPA_SMBUS_MAX_BASELINE  SMBUS_BYTE_CMD(CMD_REPORT_MAX_BASELINE)
-#define CYAPA_SMBUS_MIN_BASELINE  SMBUS_BYTE_CMD(CMD_REPORT_MIN_BASELINE)
-
- /* for group registers read/write command */
-#define REG_GROUP_DATA 0
-#define REG_GROUP_CMD 2
-#define REG_GROUP_QUERY 3
-#define SMBUS_GROUP_CMD(grp) (0x80 | (((grp) & 0x07) << 3))
-#define CYAPA_SMBUS_GROUP_DATA	 SMBUS_GROUP_CMD(REG_GROUP_DATA)
-#define CYAPA_SMBUS_GROUP_CMD	 SMBUS_GROUP_CMD(REG_GROUP_CMD)
-#define CYAPA_SMBUS_GROUP_QUERY	 SMBUS_GROUP_CMD(REG_GROUP_QUERY)
-
- /* for register block read/write command */
-#define CMD_BL_STATUS 0
-#define CMD_BL_HEAD 1
-#define CMD_BL_CMD 2
-#define CMD_BL_DATA 3
-#define CMD_BL_ALL 4
-#define CMD_BLK_PRODUCT_ID 5
-#define CMD_BLK_HEAD 6
-#define SMBUS_BLOCK_CMD(cmd) (0xc0 | (((cmd) & 0x1f) << 1))
-
-/* register block read/write command in bootloader mode */
-#define CYAPA_SMBUS_BL_STATUS  SMBUS_BLOCK_CMD(CMD_BL_STATUS)
-#define CYAPA_SMBUS_BL_HEAD    SMBUS_BLOCK_CMD(CMD_BL_HEAD)
-#define CYAPA_SMBUS_BL_CMD     SMBUS_BLOCK_CMD(CMD_BL_CMD)
-#define CYAPA_SMBUS_BL_DATA    SMBUS_BLOCK_CMD(CMD_BL_DATA)
-#define CYAPA_SMBUS_BL_ALL     SMBUS_BLOCK_CMD(CMD_BL_ALL)
-
-/* register block read/write command in operational mode */
-#define CYAPA_SMBUS_BLK_PRODUCT_ID SMBUS_BLOCK_CMD(CMD_BLK_PRODUCT_ID)
-#define CYAPA_SMBUS_BLK_HEAD SMBUS_BLOCK_CMD(CMD_BLK_HEAD)
-
  /* for byte read/write command */
 #define CMD_RESET 0
 #define CMD_POWER_MODE 1
-- 
2.15.1

^ permalink raw reply related

* Re: [PATCH] HID: intel-ish-hid: Enable Cannon Lake and Coffee Lake laptop/desktop
From: Srinivas Pandruvada @ 2018-01-08 22:12 UTC (permalink / raw)
  To: jikos; +Cc: linux-input, linux-kernel
In-Reply-To: <20171220192410.87748-1-srinivas.pandruvada@linux.intel.com>

Hi Jiri,

Hope this fine to queue this for 4.16.

Thanks,
Srinivas

On Wed, 2017-12-20 at 11:24 -0800, Srinivas Pandruvada wrote:
> Added PCI ID for Cannon Lake and Coffee Lake laptop/desktop skews.
> 
> Signed-off-by: Srinivas Pandruvada <srinivas.pandruvada@linux.intel.c
> om>
> ---
>  drivers/hid/intel-ish-hid/ipc/hw-ish.h  | 1 +
>  drivers/hid/intel-ish-hid/ipc/pci-ish.c | 1 +
>  2 files changed, 2 insertions(+)
> 
> diff --git a/drivers/hid/intel-ish-hid/ipc/hw-ish.h
> b/drivers/hid/intel-ish-hid/ipc/hw-ish.h
> index 2aac097c3f70..97869b7410eb 100644
> --- a/drivers/hid/intel-ish-hid/ipc/hw-ish.h
> +++ b/drivers/hid/intel-ish-hid/ipc/hw-ish.h
> @@ -28,6 +28,7 @@
>  #define SPT_Ax_DEVICE_ID	0x9D35
>  #define CNL_Ax_DEVICE_ID	0x9DFC
>  #define GLK_Ax_DEVICE_ID	0x31A2
> +#define CNL_H_DEVICE_ID		0xA37C
>  
>  #define	REVISION_ID_CHT_A0	0x6
>  #define	REVISION_ID_CHT_Ax_SI	0x0
> diff --git a/drivers/hid/intel-ish-hid/ipc/pci-ish.c
> b/drivers/hid/intel-ish-hid/ipc/pci-ish.c
> index 20d824f74f99..582e449be9fe 100644
> --- a/drivers/hid/intel-ish-hid/ipc/pci-ish.c
> +++ b/drivers/hid/intel-ish-hid/ipc/pci-ish.c
> @@ -37,6 +37,7 @@ static const struct pci_device_id ish_pci_tbl[] = {
>  	{PCI_DEVICE(PCI_VENDOR_ID_INTEL, SPT_Ax_DEVICE_ID)},
>  	{PCI_DEVICE(PCI_VENDOR_ID_INTEL, CNL_Ax_DEVICE_ID)},
>  	{PCI_DEVICE(PCI_VENDOR_ID_INTEL, GLK_Ax_DEVICE_ID)},
> +	{PCI_DEVICE(PCI_VENDOR_ID_INTEL, CNL_H_DEVICE_ID)},
>  	{0, }
>  };
>  MODULE_DEVICE_TABLE(pci, ish_pci_tbl);

^ permalink raw reply

* Re: [PATCH v6 1/1] input: Deprecate real timestamps beyond year 2106
From: Deepa Dinamani @ 2018-01-09  0:07 UTC (permalink / raw)
  To: Dmitry Torokhov
  Cc: y2038 Mailman List, Peter Hutterer, Linux Kernel Mailing List,
	Arnd Bergmann, open list:HID CORE LAYER
In-Reply-To: <20180108215111.tqnhr5k5easbrh4b@dtor-ws>

On Mon, Jan 8, 2018 at 1:51 PM, Dmitry Torokhov
<dmitry.torokhov@gmail.com> wrote:
> Hi Deepa,
>
> On Sat, Jan 06, 2018 at 04:19:15PM -0800, Deepa Dinamani wrote:
>> struct timeval is not y2038 safe.
>> All usage of timeval in the kernel will be replaced by
>> y2038 safe structures.
>> The change is also necessary as glibc is introducing support
>> for 32 bit applications to use 64 bit time_t. Without this
>> change, many applications would incorrectly interpret values
>> in the struct input_event.
>> More details about glibc at
>> https://sourceware.org/glibc/wiki/Y2038ProofnessDesign .
>>
>> struct input_event maintains time for each input event.
>> Real time timestamps are not ideal for input as this
>> time can go backwards as noted in the patch a80b83b7b8
>> by John Stultz. Hence, having the input_event.time fields
>> only big enough for monotonic and boot times are
>> sufficient.
>
> I am happy with the patch, but have some concerns about changelog. The
> change does not really prevent anyone from using CLOCK_REALTIME past
> 2106, especially on 64 bit arches. We are simply extending range of
> reported seconds in input event by converting from signed to unsigned
> value.

I was interpreting working incorrectly on 32 bit architectures, but
working correctly on 64 bit architectures as a failure of the feature
to use realtime clock at all.
But, you are correct that the patch does not actively do anything to
stop people from using realtime clock.

>>
>> The change leaves the representation of struct input_event as is
>> on 64 bit architectures. But uses 2 unsigned long values on 32 bit
>> machines to support real timestamps until year 2106.
>> This intentionally breaks the ABI on 32 bit architectures and
>> compat handling on 64 bit architectures.
>> This is as per maintainer's preference to introduce compile time errors
>> rather than run into runtime incompatibilities.
>
> We are breaking API, not ABI though. The ABI for existing programs is
> exactly the same, it is only when system starts using the newer glibc
> supporting extended time the compilation will break.

I was interpreting not being able to use negative timestamps on 32 bit
machines as breaking the ABI.

>> The change requires any 32 bit userspace utilities reading or writing
>> from event nodes to update their reading format to match the new
>> input_event. The changes to the popular libraries will be posted once
>> we agree on the kernel change.
> I propose we have the following changelog:
>
>
> Input: extend usable life of event timestamps to 2106 on 32 bit systems
>
> The input events use struct timeval to store event time, unfortunately
> this structure is not y2038 safe and is being replaced in kernel with
> y2038 safe structures.
>
> Because of ABI concerns we can not change the size or the layout of
> structure input_event, so we opt to re-interpreting the 'seconds' part
> of timestamp as an unsigned value, effectively doubling the range of
> values, to year 2106.
> Newer glibc that has support for 32 bit applications to use 64 bit
> time_t supplies __USE_TIME_BITS64 define [1], that we can use to present
> the userspace with updated input_event layout. The updated layout will
> cause the compile time breakage, alerting applications and distributions
> maintainers to the issue. Existing 32 binaries will continue working
> without any changes until 2038.
>
> Ultimately userspace applications should switch to using monotonic or
> boot time clocks, as realtime clock is not very well suited for input
> event timestamps as it can go backwards (see a80b83b7b8 "Input: evdev -
> add CLOCK_BOOTTIME support" by by John Stultz). With monotonic clock the
> practical range of reported times will always fit into the pair of 32
> bit values, as we do not expect any system to stay up for a hundred
> years without a single reboot.
>
> [1] https://sourceware.org/glibc/wiki/Y2038ProofnessDesign
>
>
> Please let me know if you disagee with the above.

I'm fine with this commit text. Let me know if you would like me to update this.

Thanks,
Deepa
_______________________________________________
Y2038 mailing list
Y2038@lists.linaro.org
https://lists.linaro.org/mailman/listinfo/y2038

^ permalink raw reply

* Re: [PATCH v6 1/1] input: Deprecate real timestamps beyond year 2106
From: Dmitry Torokhov @ 2018-01-09  0:32 UTC (permalink / raw)
  To: Deepa Dinamani
  Cc: open list:HID CORE LAYER, Linux Kernel Mailing List,
	Peter Hutterer, Arnd Bergmann, y2038 Mailman List
In-Reply-To: <CABeXuvr0a_h5tYbe0_yyUOqnpnqYvvRckyK7GbxNj8JzofY1dg@mail.gmail.com>

On Mon, Jan 08, 2018 at 04:07:22PM -0800, Deepa Dinamani wrote:
> On Mon, Jan 8, 2018 at 1:51 PM, Dmitry Torokhov
> <dmitry.torokhov@gmail.com> wrote:
> > Hi Deepa,
> >
> > On Sat, Jan 06, 2018 at 04:19:15PM -0800, Deepa Dinamani wrote:
> >> struct timeval is not y2038 safe.
> >> All usage of timeval in the kernel will be replaced by
> >> y2038 safe structures.
> >> The change is also necessary as glibc is introducing support
> >> for 32 bit applications to use 64 bit time_t. Without this
> >> change, many applications would incorrectly interpret values
> >> in the struct input_event.
> >> More details about glibc at
> >> https://sourceware.org/glibc/wiki/Y2038ProofnessDesign .
> >>
> >> struct input_event maintains time for each input event.
> >> Real time timestamps are not ideal for input as this
> >> time can go backwards as noted in the patch a80b83b7b8
> >> by John Stultz. Hence, having the input_event.time fields
> >> only big enough for monotonic and boot times are
> >> sufficient.
> >
> > I am happy with the patch, but have some concerns about changelog. The
> > change does not really prevent anyone from using CLOCK_REALTIME past
> > 2106, especially on 64 bit arches. We are simply extending range of
> > reported seconds in input event by converting from signed to unsigned
> > value.
> 
> I was interpreting working incorrectly on 32 bit architectures, but
> working correctly on 64 bit architectures as a failure of the feature
> to use realtime clock at all.
> But, you are correct that the patch does not actively do anything to
> stop people from using realtime clock.
> 
> >>
> >> The change leaves the representation of struct input_event as is
> >> on 64 bit architectures. But uses 2 unsigned long values on 32 bit
> >> machines to support real timestamps until year 2106.
> >> This intentionally breaks the ABI on 32 bit architectures and
> >> compat handling on 64 bit architectures.
> >> This is as per maintainer's preference to introduce compile time errors
> >> rather than run into runtime incompatibilities.
> >
> > We are breaking API, not ABI though. The ABI for existing programs is
> > exactly the same, it is only when system starts using the newer glibc
> > supporting extended time the compilation will break.
> 
> I was interpreting not being able to use negative timestamps on 32 bit
> machines as breaking the ABI.
> 
> >> The change requires any 32 bit userspace utilities reading or writing
> >> from event nodes to update their reading format to match the new
> >> input_event. The changes to the popular libraries will be posted once
> >> we agree on the kernel change.
> > I propose we have the following changelog:
> >
> >
> > Input: extend usable life of event timestamps to 2106 on 32 bit systems
> >
> > The input events use struct timeval to store event time, unfortunately
> > this structure is not y2038 safe and is being replaced in kernel with
> > y2038 safe structures.
> >
> > Because of ABI concerns we can not change the size or the layout of
> > structure input_event, so we opt to re-interpreting the 'seconds' part
> > of timestamp as an unsigned value, effectively doubling the range of
> > values, to year 2106.
> > Newer glibc that has support for 32 bit applications to use 64 bit
> > time_t supplies __USE_TIME_BITS64 define [1], that we can use to present
> > the userspace with updated input_event layout. The updated layout will
> > cause the compile time breakage, alerting applications and distributions
> > maintainers to the issue. Existing 32 binaries will continue working
> > without any changes until 2038.
> >
> > Ultimately userspace applications should switch to using monotonic or
> > boot time clocks, as realtime clock is not very well suited for input
> > event timestamps as it can go backwards (see a80b83b7b8 "Input: evdev -
> > add CLOCK_BOOTTIME support" by by John Stultz). With monotonic clock the
> > practical range of reported times will always fit into the pair of 32
> > bit values, as we do not expect any system to stay up for a hundred
> > years without a single reboot.
> >
> > [1] https://sourceware.org/glibc/wiki/Y2038ProofnessDesign
> >
> >
> > Please let me know if you disagee with the above.
> 
> I'm fine with this commit text. Let me know if you would like me to update this.

No, unless somebody yells I'll change it on my side.

Thanks.

-- 
Dmitry

^ permalink raw reply

* Re: [PATCH] Revert "Input: trackpoint - add new trackpoint firmware ID"
From: Dmitry Torokhov @ 2018-01-09  0:40 UTC (permalink / raw)
  To: Sebastian Schmidt; +Cc: Aaron Ma, Greg KH, linux-input, Peter Hutterer
In-Reply-To: <20180108151101.GA2220@marax.lan.yath.de>

Hi Sebastian,

On Mon, Jan 08, 2018 at 04:11:01PM +0100, Sebastian Schmidt wrote:
> Hi Dmitry,
> 
> On Sat, Jan 06, 2018 at 10:52:01PM -0800, Dmitry Torokhov wrote:
> > Guys, could you please try the patch below? It will not solve the
> > "speed" issue on 0x01 devices, but hopefully we won't be exposing
> > non-existing controls on others.
> 
> Thanks for looking into this. Which speed issue on 0x01 devices? I
> thought those were the legacy ones that used to work and still do as
> ever.
> 
> I've tried your (slightly modified, see below) patch and the trackpoint
> now gets apparently[1] correctly detected as "psmouse serio2:
> trackpoint: Elan TrackPoint firmware: 0x04, buttons: 3/3". However, I
> still have the feeling that it's a lot more sensitive (or faster?) than
> with the regular PS/2 driver - even with libinput accel speed turned to
> -1. I don't know how I could measure this objectively, but there must be
> some difference between the trackpoint driver and the regular one. Is it
> maybe an init sequence that causes it to report more sensitively, or a
> different resolution, or ...? I really have no idea how mice work. :)

Hmm.. Can you try writing different values to "sensitivity" attribute
and let me know if this changes behavior. Try 0x66, 0x73, 0x80, 0x8F,
0xA0, 0xB3, 0xC9, 0xE1, 0xFC values (smaller should be less sensitive).
I believe we try to program it to 0x80 by default.

Also, I think libinput/udev is trying to "normalize" trackstick feel,
see /lib/udev/hwdb.d/70-pointingstick.hwdb I am adding Peter Hutterer to
see if he has any more info.

> 
> Also, I'm wondering, since my trackpoint works just fine as "Generic
> PS/2 Mouse", including the third button. The driver even says:
> | /*
> |  * Bare PS/2 protocol "detection". Always succeeds.
> |  */
> | static int ps2bare_detect(struct psmouse *psmouse, bool set_properties)
> | {
> | [...]
> |         /*
> |          * We have no way of figuring true number of buttons so let's
> |          * assume that the device has 3.
> |          */
> |         __set_bit(BTN_MIDDLE, psmouse->dev->keybit);
> |     }
> | 
> |     return 0;
> | }
> 
> So I wonder what driver Aaron was using that didn't report a third
> button. What vendor/firmwares did you (get reports of) have that middle
> mouse button problem on, Aaron?

No, the functionality Aaron is after is scrolling with the trackpoint -
if you hold middle button and press onto the trackpoint upwards or
downwards it should scroll window content.

> 
> Thanks,
> 
> Sebastian
> 
> 
> 1: If it's actually Elan. I've taken out my battery but could only
> find FRU numbers on the back of the keyboard, no signs of a vendor.
> <https://photos.app.goo.gl/iafpfzvRY042dOBo2> or
> <https://t.yath.de/IMG_20180108_143205.jpg>
> 
> In trackpoint_start_protocol:
> > +   switch (param[0]) {
> > +   case TP_VARIANT_IBM:
> > +   case TP_VARIANT_ALPS:
> > +   case TP_VARIANT_ELAN:
> > +   case TP_VARIANT_NXP:
> > +       if (variant_id)
> > +           *variant_id = param[0];
> > +       if (firmware_id)
> > +           *firmware_id = param[1];
> > +       break;
>           ^^^^^
>           That should be a return 0.

Yes, indeed.

> > +   }
> > 
> > -   return 0;
> > +   return -ENODEV;
> >  }

-- 
Dmitry

^ permalink raw reply

* Re: [PATCH 1/3] Input: twl4030-vibra: fix sibling-node lookup
From: Dmitry Torokhov @ 2018-01-09  1:17 UTC (permalink / raw)
  To: Johan Hovold
  Cc: linux-input, linux-kernel, stable, Peter Ujfalusi, Marek Belisko
In-Reply-To: <20171111154339.16875-1-johan@kernel.org>

On Sat, Nov 11, 2017 at 04:43:37PM +0100, Johan Hovold wrote:
> A helper purported to look up a child node based on its name was using
> the wrong of-helper and ended up prematurely freeing the parent of-node
> while searching the whole device tree depth-first starting at the parent
> node.
> 
> Fixes: 64b9e4d803b1 ("input: twl4030-vibra: Support for DT booted kernel")
> Fixes: e661d0a04462 ("Input: twl4030-vibra - fix ERROR: Bad of_node_put() warning")
> Cc: stable <stable@vger.kernel.org>     # 3.7
> Cc: Peter Ujfalusi <peter.ujfalusi@ti.com>
> Cc: Marek Belisko <marek@goldelico.com>
> Signed-off-by: Johan Hovold <johan@kernel.org>

Applied, thank you.

> ---
>  drivers/input/misc/twl4030-vibra.c | 6 ++++--
>  1 file changed, 4 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/input/misc/twl4030-vibra.c b/drivers/input/misc/twl4030-vibra.c
> index 6c51d404874b..c37aea9ac272 100644
> --- a/drivers/input/misc/twl4030-vibra.c
> +++ b/drivers/input/misc/twl4030-vibra.c
> @@ -178,12 +178,14 @@ static SIMPLE_DEV_PM_OPS(twl4030_vibra_pm_ops,
>  			 twl4030_vibra_suspend, twl4030_vibra_resume);
>  
>  static bool twl4030_vibra_check_coexist(struct twl4030_vibra_data *pdata,
> -			      struct device_node *node)
> +			      struct device_node *parent)
>  {
> +	struct device_node *node;
> +
>  	if (pdata && pdata->coexist)
>  		return true;
>  
> -	node = of_find_node_by_name(node, "codec");
> +	node = of_get_child_by_name(parent, "codec");
>  	if (node) {
>  		of_node_put(node);
>  		return true;
> -- 
> 2.15.0
> 

-- 
Dmitry

^ permalink raw reply

* [PATCH] HID: asus: only support backlight when it's not driven by WMI
From: Daniel Drake @ 2018-01-09  1:20 UTC (permalink / raw)
  To: jikos, benjamin.tissoires
  Cc: linux-input, linux, carlo, corentin.chary, acpi4asus-user,
	platform-driver-x86

The Asus GL502VSK has the same 0B05:1837 keyboard as we've seen in
several Republic of Gamers laptops.

However, in this model, the keybard backlight control exposed by hid-asus
has no effect on the keyboard backlight. Instead, the keyboard
backlight is correctly driven by asus-wmi.

With two keyboard backlight devices available (and only the acer-wmi
one working), GNOME is picking the wrong one to drive in the UI.

Avoid this problem by not creating the backlight interface when we
detect a WMI-driven keyboard backlight.

We have also tested Asus GL702VMK which does have the hid-asus
backlight present, and it still works fine with this patch (WMI method
call returns UNSUPPORTED_METHOD).

Signed-off-by: Daniel Drake <drake@endlessm.com>
---
 drivers/hid/Kconfig    |  1 +
 drivers/hid/hid-asus.c | 53 +++++++++++++++++++++++++++++++++++++++++++++++++-
 2 files changed, 53 insertions(+), 1 deletion(-)

diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig
index 779c5ae47f36..6d95abc9d8a1 100644
--- a/drivers/hid/Kconfig
+++ b/drivers/hid/Kconfig
@@ -149,6 +149,7 @@ config HID_APPLEIR
 config HID_ASUS
 	tristate "Asus"
 	depends on LEDS_CLASS
+	depends on ACPI_WMI
 	---help---
 	Support for Asus notebook built-in keyboard and touchpad via i2c, and
 	the Asus Republic of Gamers laptop keyboard special keys.
diff --git a/drivers/hid/hid-asus.c b/drivers/hid/hid-asus.c
index 1bb7b63b3150..e6830946b4a4 100644
--- a/drivers/hid/hid-asus.c
+++ b/drivers/hid/hid-asus.c
@@ -26,6 +26,7 @@
  * any later version.
  */
 
+#include <linux/acpi.h>
 #include <linux/hid.h>
 #include <linux/module.h>
 #include <linux/input/mt.h>
@@ -78,6 +79,12 @@ MODULE_DESCRIPTION("Asus HID Keyboard and TouchPad");
 
 #define TRKID_SGN       ((TRKID_MAX + 1) >> 1)
 
+#define ASUS_WMI_MGMT_GUID		"97845ED0-4E6D-11DE-8A39-0800200C9A66"
+#define ASUS_WMI_METHODID_DSTS2		0x53545344 /* Device STatuS #2*/
+#define ASUS_WMI_DEVID_KBD_BACKLIGHT	0x00050021
+#define ASUS_WMI_UNSUPPORTED_METHOD	0xFFFFFFFE
+#define ASUS_WMI_DSTS_PRESENCE_BIT	0x00010000
+
 struct asus_kbd_leds {
 	struct led_classdev cdev;
 	struct hid_device *hdev;
@@ -330,6 +337,48 @@ static void asus_kbd_backlight_work(struct work_struct *work)
 		hid_err(led->hdev, "Asus failed to set keyboard backlight: %d\n", ret);
 }
 
+/* WMI-based keyboard backlight LED control (via asus-wmi driver) takes
+ * precedence. We only activate HID-based backlight control when the
+ * WMI control is not available.
+ */
+static bool asus_kbd_wmi_led_control_present(struct hid_device *hdev)
+{
+	u32 args[] = { ASUS_WMI_DEVID_KBD_BACKLIGHT, 0 };
+	struct acpi_buffer input = { (acpi_size) sizeof(args), &args };
+	struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL };
+	acpi_status status;
+	union acpi_object *obj;
+	u32 value;
+
+	status = wmi_evaluate_method(ASUS_WMI_MGMT_GUID, 0,
+				     ASUS_WMI_METHODID_DSTS2,
+				     &input, &output);
+
+	if (ACPI_FAILURE(status)) {
+		hid_dbg(hdev, "WMI backlight method failed: %d", status);
+		return false;
+	}
+
+	obj = (union acpi_object *)output.pointer;
+	if (!obj || obj->type != ACPI_TYPE_INTEGER) {
+		hid_dbg(hdev, "WMI backlight method unexpected return type");
+		kfree(obj);
+		return false;
+	}
+
+	value = (u32) obj->integer.value;
+	kfree(obj);
+
+	hid_dbg(hdev, "WMI backlight check: method returned %x", value);
+
+	if (value == ASUS_WMI_UNSUPPORTED_METHOD) {
+		hid_dbg(hdev, "WMI backlight method unsupported");
+		return false;
+	}
+
+	return !!(value & ASUS_WMI_DSTS_PRESENCE_BIT);
+}
+
 static int asus_kbd_register_leds(struct hid_device *hdev)
 {
 	struct asus_drvdata *drvdata = hid_get_drvdata(hdev);
@@ -417,7 +466,9 @@ static int asus_input_configured(struct hid_device *hdev, struct hid_input *hi)
 
 	drvdata->input = input;
 
-	if (drvdata->enable_backlight && asus_kbd_register_leds(hdev))
+	if (drvdata->enable_backlight &&
+	    !asus_kbd_wmi_led_control_present(hdev) &&
+	    asus_kbd_register_leds(hdev))
 		hid_warn(hdev, "Failed to initialize backlight.\n");
 
 	return 0;
-- 
2.14.1


^ permalink raw reply related

* Re: [PATCH 1/3] Input: twl4030-vibra: fix sibling-node lookup
From: Dmitry Torokhov @ 2018-01-09  1:35 UTC (permalink / raw)
  To: Johan Hovold
  Cc: linux-input, linux-kernel, stable, Peter Ujfalusi, Marek Belisko
In-Reply-To: <20171111154339.16875-1-johan@kernel.org>

On Sat, Nov 11, 2017 at 04:43:37PM +0100, Johan Hovold wrote:
> A helper purported to look up a child node based on its name was using
> the wrong of-helper and ended up prematurely freeing the parent of-node
> while searching the whole device tree depth-first starting at the parent
> node.
> 
> Fixes: 64b9e4d803b1 ("input: twl4030-vibra: Support for DT booted kernel")
> Fixes: e661d0a04462 ("Input: twl4030-vibra - fix ERROR: Bad of_node_put() warning")
> Cc: stable <stable@vger.kernel.org>     # 3.7
> Cc: Peter Ujfalusi <peter.ujfalusi@ti.com>
> Cc: Marek Belisko <marek@goldelico.com>
> Signed-off-by: Johan Hovold <johan@kernel.org>

Applied, thank you.

> ---
>  drivers/input/misc/twl4030-vibra.c | 6 ++++--
>  1 file changed, 4 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/input/misc/twl4030-vibra.c b/drivers/input/misc/twl4030-vibra.c
> index 6c51d404874b..c37aea9ac272 100644
> --- a/drivers/input/misc/twl4030-vibra.c
> +++ b/drivers/input/misc/twl4030-vibra.c
> @@ -178,12 +178,14 @@ static SIMPLE_DEV_PM_OPS(twl4030_vibra_pm_ops,
>  			 twl4030_vibra_suspend, twl4030_vibra_resume);
>  
>  static bool twl4030_vibra_check_coexist(struct twl4030_vibra_data *pdata,
> -			      struct device_node *node)
> +			      struct device_node *parent)
>  {
> +	struct device_node *node;
> +
>  	if (pdata && pdata->coexist)
>  		return true;
>  
> -	node = of_find_node_by_name(node, "codec");
> +	node = of_get_child_by_name(parent, "codec");
>  	if (node) {
>  		of_node_put(node);
>  		return true;
> -- 
> 2.15.0
> 

-- 
Dmitry

^ permalink raw reply

* Re: [PATCH 2/3] Input: twl6040-vibra: fix child-node lookup
From: Dmitry Torokhov @ 2018-01-09  1:35 UTC (permalink / raw)
  To: Johan Hovold
  Cc: linux-input, linux-kernel, stable, Peter Ujfalusi,
	H . Nikolaus Schaller
In-Reply-To: <20171111154339.16875-2-johan@kernel.org>

On Sat, Nov 11, 2017 at 04:43:38PM +0100, Johan Hovold wrote:
> Fix child-node lookup during probe, which ended up searching the whole
> device tree depth-first starting at parent rather than just matching on
> its children.
> 
> Later sanity checks on node properties (which would likely be missing)
> should prevent this from causing much trouble however, especially as the
> original premature free of the parent node has already been fixed
> separately (but that "fix" was apparently never backported to stable).
> 
> Fixes: e7ec014a47e4 ("Input: twl6040-vibra - update for device tree support")
> Fixes: c52c545ead97 ("Input: twl6040-vibra - fix DT node memory management")
> Cc: stable <stable@vger.kernel.org>     # 3.6
> Cc: Peter Ujfalusi <peter.ujfalusi@ti.com>
> Cc: H. Nikolaus Schaller <hns@goldelico.com>
> Signed-off-by: Johan Hovold <johan@kernel.org>

Applied, thank you.

> ---
>  drivers/input/misc/twl6040-vibra.c | 3 +--
>  1 file changed, 1 insertion(+), 2 deletions(-)
> 
> diff --git a/drivers/input/misc/twl6040-vibra.c b/drivers/input/misc/twl6040-vibra.c
> index 5690eb7ff954..15e0d352c4cc 100644
> --- a/drivers/input/misc/twl6040-vibra.c
> +++ b/drivers/input/misc/twl6040-vibra.c
> @@ -248,8 +248,7 @@ static int twl6040_vibra_probe(struct platform_device *pdev)
>  	int vddvibr_uV = 0;
>  	int error;
>  
> -	of_node_get(twl6040_core_dev->of_node);
> -	twl6040_core_node = of_find_node_by_name(twl6040_core_dev->of_node,
> +	twl6040_core_node = of_get_child_by_name(twl6040_core_dev->of_node,
>  						 "vibra");
>  	if (!twl6040_core_node) {
>  		dev_err(&pdev->dev, "parent of node is missing?\n");
> -- 
> 2.15.0
> 

-- 
Dmitry

^ permalink raw reply

* Re: [PATCH] Revert "Input: trackpoint - add new trackpoint firmware ID"
From: Peter Hutterer @ 2018-01-09  1:35 UTC (permalink / raw)
  To: Dmitry Torokhov; +Cc: Sebastian Schmidt, Aaron Ma, Greg KH, linux-input
In-Reply-To: <20180109004035.znq4alueyhds45f5@dtor-ws>

On Mon, Jan 08, 2018 at 04:40:35PM -0800, Dmitry Torokhov wrote:
> Hi Sebastian,
> 
> On Mon, Jan 08, 2018 at 04:11:01PM +0100, Sebastian Schmidt wrote:
> > Hi Dmitry,
> > 
> > On Sat, Jan 06, 2018 at 10:52:01PM -0800, Dmitry Torokhov wrote:
> > > Guys, could you please try the patch below? It will not solve the
> > > "speed" issue on 0x01 devices, but hopefully we won't be exposing
> > > non-existing controls on others.
> > 
> > Thanks for looking into this. Which speed issue on 0x01 devices? I
> > thought those were the legacy ones that used to work and still do as
> > ever.
> > 
> > I've tried your (slightly modified, see below) patch and the trackpoint
> > now gets apparently[1] correctly detected as "psmouse serio2:
> > trackpoint: Elan TrackPoint firmware: 0x04, buttons: 3/3". However, I
> > still have the feeling that it's a lot more sensitive (or faster?) than
> > with the regular PS/2 driver - even with libinput accel speed turned to
> > -1. I don't know how I could measure this objectively, but there must be
> > some difference between the trackpoint driver and the regular one. Is it
> > maybe an init sequence that causes it to report more sensitively, or a
> > different resolution, or ...? I really have no idea how mice work. :)
> 
> Hmm.. Can you try writing different values to "sensitivity" attribute
> and let me know if this changes behavior. Try 0x66, 0x73, 0x80, 0x8F,
> 0xA0, 0xB3, 0xC9, 0xE1, 0xFC values (smaller should be less sensitive).
> I believe we try to program it to 0x80 by default.
> 
> Also, I think libinput/udev is trying to "normalize" trackstick feel,
> see /lib/udev/hwdb.d/70-pointingstick.hwdb I am adding Peter Hutterer to
> see if he has any more info.

yeah, it is, and it also undoes the effect of the POINTINGSTICK_SENSITIVITY
udev property (for backwards compatibility we assume this always matches the
sysfs entry, we don't look at the sysfs entry directly). Having said that,
we only check that property on device plug, so if you keep messing with the
sysfs files you'll still see the various changes to the pointer speed.

in other words: messing around with the sensitivity attribute will still see
changes in pointer motion and is good enough for testing.

Cheers,
   Peter

> > Also, I'm wondering, since my trackpoint works just fine as "Generic
> > PS/2 Mouse", including the third button. The driver even says:
> > | /*
> > |  * Bare PS/2 protocol "detection". Always succeeds.
> > |  */
> > | static int ps2bare_detect(struct psmouse *psmouse, bool set_properties)
> > | {
> > | [...]
> > |         /*
> > |          * We have no way of figuring true number of buttons so let's
> > |          * assume that the device has 3.
> > |          */
> > |         __set_bit(BTN_MIDDLE, psmouse->dev->keybit);
> > |     }
> > | 
> > |     return 0;
> > | }
> > 
> > So I wonder what driver Aaron was using that didn't report a third
> > button. What vendor/firmwares did you (get reports of) have that middle
> > mouse button problem on, Aaron?
> 
> No, the functionality Aaron is after is scrolling with the trackpoint -
> if you hold middle button and press onto the trackpoint upwards or
> downwards it should scroll window content.
> 
> > 
> > Thanks,
> > 
> > Sebastian
> > 
> > 
> > 1: If it's actually Elan. I've taken out my battery but could only
> > find FRU numbers on the back of the keyboard, no signs of a vendor.
> > <https://photos.app.goo.gl/iafpfzvRY042dOBo2> or
> > <https://t.yath.de/IMG_20180108_143205.jpg>
> > 
> > In trackpoint_start_protocol:
> > > +   switch (param[0]) {
> > > +   case TP_VARIANT_IBM:
> > > +   case TP_VARIANT_ALPS:
> > > +   case TP_VARIANT_ELAN:
> > > +   case TP_VARIANT_NXP:
> > > +       if (variant_id)
> > > +           *variant_id = param[0];
> > > +       if (firmware_id)
> > > +           *firmware_id = param[1];
> > > +       break;
> >           ^^^^^
> >           That should be a return 0.
> 
> Yes, indeed.
> 
> > > +   }
> > > 
> > > -   return 0;
> > > +   return -ENODEV;
> > >  }
> 
> -- 
> Dmitry
> --
> To unsubscribe from this list: send the line "unsubscribe linux-input" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> 

^ permalink raw reply

* Re: [PATCH 3/3] Input: 88pm860x-ts: fix child-node lookup
From: Dmitry Torokhov @ 2018-01-09  1:35 UTC (permalink / raw)
  To: Johan Hovold; +Cc: linux-input, linux-kernel, stable, Haojian Zhuang
In-Reply-To: <20171111154339.16875-3-johan@kernel.org>

On Sat, Nov 11, 2017 at 04:43:39PM +0100, Johan Hovold wrote:
> Fix child node-lookup during probe, which ended up searching the whole
> device tree depth-first starting at parent rather than just matching on
> its children.
> 
> To make things worse, the parent node was prematurely freed, while the
> child node was leaked.
> 
> Fixes: 2e57d56747e6 ("mfd: 88pm860x: Device tree support")
> Cc: stable <stable@vger.kernel.org>     # 3.7
> Cc: Haojian Zhuang <haojian.zhuang@gmail.com>
> Signed-off-by: Johan Hovold <johan@kernel.org>

Applied, thank you.

> ---
>  drivers/input/touchscreen/88pm860x-ts.c | 16 ++++++++++++----
>  1 file changed, 12 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/input/touchscreen/88pm860x-ts.c b/drivers/input/touchscreen/88pm860x-ts.c
> index 7ed828a51f4c..3486d9403805 100644
> --- a/drivers/input/touchscreen/88pm860x-ts.c
> +++ b/drivers/input/touchscreen/88pm860x-ts.c
> @@ -126,7 +126,7 @@ static int pm860x_touch_dt_init(struct platform_device *pdev,
>  	int data, n, ret;
>  	if (!np)
>  		return -ENODEV;
> -	np = of_find_node_by_name(np, "touch");
> +	np = of_get_child_by_name(np, "touch");
>  	if (!np) {
>  		dev_err(&pdev->dev, "Can't find touch node\n");
>  		return -EINVAL;
> @@ -144,13 +144,13 @@ static int pm860x_touch_dt_init(struct platform_device *pdev,
>  	if (data) {
>  		ret = pm860x_reg_write(i2c, PM8607_GPADC_MISC1, data);
>  		if (ret < 0)
> -			return -EINVAL;
> +			goto err_put_node;
>  	}
>  	/* set tsi prebias time */
>  	if (!of_property_read_u32(np, "marvell,88pm860x-tsi-prebias", &data)) {
>  		ret = pm860x_reg_write(i2c, PM8607_TSI_PREBIAS, data);
>  		if (ret < 0)
> -			return -EINVAL;
> +			goto err_put_node;
>  	}
>  	/* set prebias & prechg time of pen detect */
>  	data = 0;
> @@ -161,10 +161,18 @@ static int pm860x_touch_dt_init(struct platform_device *pdev,
>  	if (data) {
>  		ret = pm860x_reg_write(i2c, PM8607_PD_PREBIAS, data);
>  		if (ret < 0)
> -			return -EINVAL;
> +			goto err_put_node;
>  	}
>  	of_property_read_u32(np, "marvell,88pm860x-resistor-X", res_x);
> +
> +	of_node_put(np);
> +
>  	return 0;
> +
> +err_put_node:
> +	of_node_put(np);
> +
> +	return -EINVAL;
>  }
>  #else
>  #define pm860x_touch_dt_init(x, y, z)	(-1)
> -- 
> 2.15.0
> 

-- 
Dmitry

^ permalink raw reply


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