* Re: Dell docking station & Dell Embedded Controller & PS/2 devices
From: Pali Rohár @ 2018-05-07 20:48 UTC (permalink / raw)
To: Mario.Limonciello; +Cc: dmitry.torokhov, linux-input, linux-kernel
In-Reply-To: <05cd71987d8f4a8e99cb1994218a8485@ausx13mpc124.AMER.DELL.COM>
[-- Attachment #1: Type: text/plain, Size: 1267 bytes --]
On Monday 07 May 2018 20:32:16 Mario.Limonciello@dell.com wrote:
> > The items that show up in this structure are supposed to be dynamic
> > values but static addresses. I was asking to check before bootup in
> > case this was a problem of Linux caching SMBIOS table information once.
> > The values I was referring to might be for older generation dock though,
> > I'll see if I can find anything else you can check.
>
> Can you check if structure type 08 or structure type 09 change based on
> dock being plugged in? Again you might have to do it across a boot
> with/without dock in case of Linux kernel caches values.
The only difference is:
--- dmidecode_laptop_docked 2018-05-07 22:34:02.650325758 +0200
+++ dmidecode_laptop_undocked 2018-05-07 22:39:27.580306838 +0200
@@ -913,7 +913,7 @@ System Power Supply
Asset Tag: To Be Filled By O.E.M.
Model Part Number: To Be Filled By O.E.M.
Revision: To Be Filled By O.E.M.
- Max Power Capacity: 90 W
+ Max Power Capacity: Unknown
Status: Present, OK
Type: Switching
Input Voltage Range Switching: Auto-switch
And this is in block Handle 0x003E, DMI type 39, 22 bytes - System Power
Supply. So looks like that DMI data are same.
--
Pali Rohár
pali.rohar@gmail.com
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 195 bytes --]
^ permalink raw reply
* RE: Dell docking station & Dell Embedded Controller & PS/2 devices
From: Mario.Limonciello @ 2018-05-07 20:32 UTC (permalink / raw)
To: pali.rohar; +Cc: dmitry.torokhov, linux-input, linux-kernel
In-Reply-To: <c4668ded2ef1432b94f8668220b1232f@ausx13mpc124.AMER.DELL.COM>
> -----Original Message-----
> From: Limonciello, Mario
> Sent: Monday, May 7, 2018 3:30 PM
> To: 'Pali Rohár'
> Cc: dmitry.torokhov@gmail.com; linux-input@vger.kernel.org; linux-
> kernel@vger.kernel.org
> Subject: RE: Dell docking station & Dell Embedded Controller & PS/2 devices
>
> > -----Original Message-----
> > From: Pali Rohár [mailto:pali.rohar@gmail.com]
> > Sent: Monday, May 7, 2018 3:28 PM
> > To: Limonciello, Mario
> > Cc: dmitry.torokhov@gmail.com; linux-input@vger.kernel.org; linux-
> > kernel@vger.kernel.org
> > Subject: Re: Dell docking station & Dell Embedded Controller & PS/2 devices
> >
> > On Monday 07 May 2018 20:18:30 Mario.Limonciello@dell.com wrote:
> > > > > > So I guess you could write a platform driver that would install i8042
> > > > > > filter on Dell laptops/portables, monitor keyboard data stream and kick
> > > > > > of rescans on serio ports. The problem is filter gets "serio" so you do
> > > > > > not really know whether ACK is spurious or not. And I would really
> > > > > > prefer keeping this crap out of atkbd proper... And all of this is racy
> > > > > > as hell. What happens if we get keyboard reconnected as we reinitialize
> > > > > > it?
> > > > >
> > > > > If it's done as a platform driver I would suspect it's possible to tell whether
> > > > > a dock is connected to at least give you some heuristic here to have a better
> > > > > guess whether it's spurious.
> > > >
> > > > Apparently checking for docking station is not enough. There are also
> > > > Dell Legacy Extenders (or how it is called) which exports internal PS/2,
> > > > Parallel and Serial Ports. It is also connecting to bottom of laptop.
> > > > But currently I do not have them for testing.
> > > >
> > > > > Pali on your system that supports this dock, check and see how many
> > > > > System Enclosure SMBIOS tables (structure type 03) are present.
> > > >
> > > > Do you mean DMI type 3 structure? Here is something from dmidecode:
> > > >
> > > > Handle 0x0003, DMI type 3, 22 bytes
> > > > Chassis Information
> > > > Manufacturer: Dell Inc.
> > > > Type: Laptop
> > > > Lock: Not Present
> > > > Version: Not Specified
> > > > Serial Number: --REMOVED--
> > > > Asset Tag: Not Specified
> > > > Boot-up State: Safe
> > > > Power Supply State: Safe
> > > > Thermal State: Safe
> > > > Security Status: None
> > > > OEM Information: 0x00000000
> > > > Height: Unspecified
> > > > Number Of Power Cords: 1
> > > > Contained Elements: 0
> > > > SKU Number: To be filled by O.E.M.
> > > >
> > > > But probably you mean something different?
> > >
> > > Plug in your dock before you boot up and see if you have a second structure like
> > > that type produced.
> >
> > I already started docked laptop via dock power button. And in dmidecode
> > output is only one DMI type 3 block.
> >
> > > If not, then I guess this isn't a reliable way to find the dock
> > > on that system and I'll have to see if there is another.
> >
> > Seems not. Also detection of dock should work also when you connect
> > laptop at system runtime, not only when connected prior to booting.
> >
>
> The items that show up in this structure are supposed to be dynamic
> values but static addresses. I was asking to check before bootup in
> case this was a problem of Linux caching SMBIOS table information once.
> The values I was referring to might be for older generation dock though,
> I'll see if I can find anything else you can check.
Can you check if structure type 08 or structure type 09 change based on
dock being plugged in? Again you might have to do it across a boot
with/without dock in case of Linux kernel caches values.
^ permalink raw reply
* RE: Dell docking station & Dell Embedded Controller & PS/2 devices
From: Mario.Limonciello @ 2018-05-07 20:30 UTC (permalink / raw)
To: pali.rohar; +Cc: dmitry.torokhov, linux-input, linux-kernel
In-Reply-To: <20180507202822.usgjneo7m35bsait@pali>
> -----Original Message-----
> From: Pali Rohár [mailto:pali.rohar@gmail.com]
> Sent: Monday, May 7, 2018 3:28 PM
> To: Limonciello, Mario
> Cc: dmitry.torokhov@gmail.com; linux-input@vger.kernel.org; linux-
> kernel@vger.kernel.org
> Subject: Re: Dell docking station & Dell Embedded Controller & PS/2 devices
>
> On Monday 07 May 2018 20:18:30 Mario.Limonciello@dell.com wrote:
> > > > > So I guess you could write a platform driver that would install i8042
> > > > > filter on Dell laptops/portables, monitor keyboard data stream and kick
> > > > > of rescans on serio ports. The problem is filter gets "serio" so you do
> > > > > not really know whether ACK is spurious or not. And I would really
> > > > > prefer keeping this crap out of atkbd proper... And all of this is racy
> > > > > as hell. What happens if we get keyboard reconnected as we reinitialize
> > > > > it?
> > > >
> > > > If it's done as a platform driver I would suspect it's possible to tell whether
> > > > a dock is connected to at least give you some heuristic here to have a better
> > > > guess whether it's spurious.
> > >
> > > Apparently checking for docking station is not enough. There are also
> > > Dell Legacy Extenders (or how it is called) which exports internal PS/2,
> > > Parallel and Serial Ports. It is also connecting to bottom of laptop.
> > > But currently I do not have them for testing.
> > >
> > > > Pali on your system that supports this dock, check and see how many
> > > > System Enclosure SMBIOS tables (structure type 03) are present.
> > >
> > > Do you mean DMI type 3 structure? Here is something from dmidecode:
> > >
> > > Handle 0x0003, DMI type 3, 22 bytes
> > > Chassis Information
> > > Manufacturer: Dell Inc.
> > > Type: Laptop
> > > Lock: Not Present
> > > Version: Not Specified
> > > Serial Number: --REMOVED--
> > > Asset Tag: Not Specified
> > > Boot-up State: Safe
> > > Power Supply State: Safe
> > > Thermal State: Safe
> > > Security Status: None
> > > OEM Information: 0x00000000
> > > Height: Unspecified
> > > Number Of Power Cords: 1
> > > Contained Elements: 0
> > > SKU Number: To be filled by O.E.M.
> > >
> > > But probably you mean something different?
> >
> > Plug in your dock before you boot up and see if you have a second structure like
> > that type produced.
>
> I already started docked laptop via dock power button. And in dmidecode
> output is only one DMI type 3 block.
>
> > If not, then I guess this isn't a reliable way to find the dock
> > on that system and I'll have to see if there is another.
>
> Seems not. Also detection of dock should work also when you connect
> laptop at system runtime, not only when connected prior to booting.
>
The items that show up in this structure are supposed to be dynamic
values but static addresses. I was asking to check before bootup in
case this was a problem of Linux caching SMBIOS table information once.
The values I was referring to might be for older generation dock though,
I'll see if I can find anything else you can check.
^ permalink raw reply
* Re: Dell docking station & Dell Embedded Controller & PS/2 devices
From: Pali Rohár @ 2018-05-07 20:28 UTC (permalink / raw)
To: Mario.Limonciello; +Cc: dmitry.torokhov, linux-input, linux-kernel
In-Reply-To: <6825f48ea6da41799979d83ed37adf73@ausx13mpc124.AMER.DELL.COM>
[-- Attachment #1: Type: text/plain, Size: 2492 bytes --]
On Monday 07 May 2018 20:18:30 Mario.Limonciello@dell.com wrote:
> > > > So I guess you could write a platform driver that would install i8042
> > > > filter on Dell laptops/portables, monitor keyboard data stream and kick
> > > > of rescans on serio ports. The problem is filter gets "serio" so you do
> > > > not really know whether ACK is spurious or not. And I would really
> > > > prefer keeping this crap out of atkbd proper... And all of this is racy
> > > > as hell. What happens if we get keyboard reconnected as we reinitialize
> > > > it?
> > >
> > > If it's done as a platform driver I would suspect it's possible to tell whether
> > > a dock is connected to at least give you some heuristic here to have a better
> > > guess whether it's spurious.
> >
> > Apparently checking for docking station is not enough. There are also
> > Dell Legacy Extenders (or how it is called) which exports internal PS/2,
> > Parallel and Serial Ports. It is also connecting to bottom of laptop.
> > But currently I do not have them for testing.
> >
> > > Pali on your system that supports this dock, check and see how many
> > > System Enclosure SMBIOS tables (structure type 03) are present.
> >
> > Do you mean DMI type 3 structure? Here is something from dmidecode:
> >
> > Handle 0x0003, DMI type 3, 22 bytes
> > Chassis Information
> > Manufacturer: Dell Inc.
> > Type: Laptop
> > Lock: Not Present
> > Version: Not Specified
> > Serial Number: --REMOVED--
> > Asset Tag: Not Specified
> > Boot-up State: Safe
> > Power Supply State: Safe
> > Thermal State: Safe
> > Security Status: None
> > OEM Information: 0x00000000
> > Height: Unspecified
> > Number Of Power Cords: 1
> > Contained Elements: 0
> > SKU Number: To be filled by O.E.M.
> >
> > But probably you mean something different?
>
> Plug in your dock before you boot up and see if you have a second structure like
> that type produced.
I already started docked laptop via dock power button. And in dmidecode
output is only one DMI type 3 block.
> If not, then I guess this isn't a reliable way to find the dock
> on that system and I'll have to see if there is another.
Seems not. Also detection of dock should work also when you connect
laptop at system runtime, not only when connected prior to booting.
--
Pali Rohár
pali.rohar@gmail.com
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 195 bytes --]
^ permalink raw reply
* RE: Dell docking station & Dell Embedded Controller & PS/2 devices
From: Mario.Limonciello @ 2018-05-07 20:18 UTC (permalink / raw)
To: pali.rohar; +Cc: dmitry.torokhov, linux-input, linux-kernel
In-Reply-To: <20180507200733.s43zd2hfzw4f4wr2@pali>
> > > So I guess you could write a platform driver that would install i8042
> > > filter on Dell laptops/portables, monitor keyboard data stream and kick
> > > of rescans on serio ports. The problem is filter gets "serio" so you do
> > > not really know whether ACK is spurious or not. And I would really
> > > prefer keeping this crap out of atkbd proper... And all of this is racy
> > > as hell. What happens if we get keyboard reconnected as we reinitialize
> > > it?
> >
> > If it's done as a platform driver I would suspect it's possible to tell whether
> > a dock is connected to at least give you some heuristic here to have a better
> > guess whether it's spurious.
>
> Apparently checking for docking station is not enough. There are also
> Dell Legacy Extenders (or how it is called) which exports internal PS/2,
> Parallel and Serial Ports. It is also connecting to bottom of laptop.
> But currently I do not have them for testing.
>
> > Pali on your system that supports this dock, check and see how many
> > System Enclosure SMBIOS tables (structure type 03) are present.
>
> Do you mean DMI type 3 structure? Here is something from dmidecode:
>
> Handle 0x0003, DMI type 3, 22 bytes
> Chassis Information
> Manufacturer: Dell Inc.
> Type: Laptop
> Lock: Not Present
> Version: Not Specified
> Serial Number: --REMOVED--
> Asset Tag: Not Specified
> Boot-up State: Safe
> Power Supply State: Safe
> Thermal State: Safe
> Security Status: None
> OEM Information: 0x00000000
> Height: Unspecified
> Number Of Power Cords: 1
> Contained Elements: 0
> SKU Number: To be filled by O.E.M.
>
> But probably you mean something different?
Plug in your dock before you boot up and see if you have a second structure like
that type produced.
If not, then I guess this isn't a reliable way to find the dock
on that system and I'll have to see if there is another.
^ permalink raw reply
* Re: Dell docking station & Dell Embedded Controller & PS/2 devices
From: Pali Rohár @ 2018-05-07 20:07 UTC (permalink / raw)
To: Mario.Limonciello; +Cc: dmitry.torokhov, linux-input, linux-kernel
In-Reply-To: <147aa25ad2d14bad975731a6c9cf9281@ausx13mpc124.AMER.DELL.COM>
[-- Attachment #1: Type: text/plain, Size: 11055 bytes --]
On Monday 07 May 2018 19:59:14 Mario.Limonciello@dell.com wrote:
> > -----Original Message-----
> > From: Dmitry Torokhov [mailto:dmitry.torokhov@gmail.com]
> > Sent: Monday, May 7, 2018 2:33 PM
> > To: Pali Rohár
> > Cc: Limonciello, Mario; linux-input@vger.kernel.org; linux-kernel@vger.kernel.org
> > Subject: Re: Dell docking station & Dell Embedded Controller & PS/2 devices
> >
> > On Mon, May 07, 2018 at 10:44:31AM +0200, Pali Rohár wrote:
> > > On Sunday 06 May 2018 15:47:33 Pali Rohár wrote:
> > > > On Thursday 01 February 2018 11:29:45 Dmitry Torokhov wrote:
> > > > > Hi Pali,
> > > > >
> > > > > On Wed, Jan 24, 2018 at 11:41:21AM +0100, Pali Rohár wrote:
> > > > > > Hi Dmitry!
> > > > > >
> > > > > > I'm observing a problem with internal touchpad (handled by psmouse.ko)
> > > > > > on Dell laptops connected to Dell E docking station. When I connect
> > > > > > external PS/2 keyboard to docking station then internal laptop touchpad
> > > > > > switch from multitouch absolute mode to relative bare PS/2 mode.
> > > > > >
> > > > > > And because ALPS driver in psmouse.ko is capable to process interleaved
> > > > > > bare 3-byte PS/2 packets with 6-byte ALPS packets (which handles
> > > > > > trackstick data on some ALPS models), ALPS driver does not show any
> > > > > > message about this "downgrade" from multitouch to bare mode. And
> > > > > > continue working in bare mode.
> > > > > >
> > > > > > When I rmmod psmouse and modprobe it again, then touchpad switch back
> > to
> > > > > > multitouch mode.
> > > > > >
> > > > > > Mario told me that Dell Embedded Controller, which handle internal
> > > > > > keyboard, internal touchpad and external PS/2 keyboard, automatically
> > > > > > send RESET command to *all* those devices when external PS/2 keyboard is
> > > > > > connected. Therefore this is reason why touchpad downgrade to to bare
> > > > > > mode. And according to Mario, host system should issue vendor specific
> > > > > > PS/2 commands to re-initialize all PS/2 devices when this situation
> > > > > > happen. Mario also told me that Windows is doing this action.
> > > > >
> > > > > Yeah, I remember fun with Inspiron 8100 - when you dock it it woudl
> > > > > silently switch Synaptics touchpad into standard mode and it would not
> > > > > come back as Synaptics until you disconnect. And there was no
> > > > > notification to the kernel as far as I could tell.
> > > > >
> > > > > It could be that we need to monitor dock events and then kick reconnect
> > > > > of serio port, either from userspace via udev (I think that would be
> > > > > preferred), or in kernel.
> > > > >
> > > > > >
> > > > > > Every time when I connect external PS/2 keyboard to dock I see this
> > > > > > message in dmesg:
> > > > > >
> > > > > > Spurious ACK... Some program might be trying to access hardware directly.
> > > > > >
> > > > > > I see it also every time when I dock laptop into docking station (to
> > > > > > which is keyboard already connected). And it happens also when I connect
> > > > > > external PS/2 mouse to dock.
> > > > > >
> > > > > > Dmitry, how to handle this situation to re-initialize psmouse.ko when
> > > > > > external PS/2 device is connected to Dell E docking station? According
> > > > > > to Mario, this is how Dell Embedded Controller is designed and suppose
> > > > > > how OS should work with it.
> > > > > >
> > > > > > Manually rmmoding and modprobing for every docking/undocking laptop is
> > > > > > not ideal solution.
> > > > > >
> > > > > > Could it be possible to use that Spurious ATKBD_RET_ACK from atkbd.c be
> > > > > > handled on Dell systems (probably via DMI) as an event to reset and
> > > > > > reinitialize all PS/2 devices?
> > > > >
> > > > > So we need to figure out what exactly we are getting from the docking
> > > > > station in this case. We do try to handle the new device 0xaa 0x00
> > > > > announcements:
> > > > >
> > > > > /* Check if this is a new device announcement (0xAA 0x00) */
> > > > > if (unlikely(psmouse->packet[0] == PSMOUSE_RET_BAT && psmouse-
> > >pktcnt <= 2)) {
> > > > > if (psmouse->pktcnt == 1) {
> > > > > psmouse->last = jiffies;
> > > > > goto out;
> > > > > }
> > > > >
> > > > > if (psmouse->packet[1] == PSMOUSE_RET_ID ||
> > > > > (psmouse->protocol->type == PSMOUSE_HGPK &&
> > > > > psmouse->packet[1] == PSMOUSE_RET_BAT)) {
> > > > > __psmouse_set_state(psmouse, PSMOUSE_IGNORE);
> > > > > serio_reconnect(serio);
> > > > > goto out;
> > > > > }
> > > > >
> > > > > ...
> > > > >
> > > > > I am not sure where the "spurious ACK comes from". Can you enable i8042
> > > > > debug before trying to dock and capture the data stream from the mouse?
> > > > >
> > > > > Thanks.
> > > > >
> > > >
> > > > Hi Dmitry!
> > > >
> > > > I enabled unmask_kbd_data and debug and here is output from dmesg.
> > > >
> > > > echo Y > /sys/module/i8042/parameters/debug
> > > > echo Y > /sys/module/i8042/parameters/unmask_kbd_data
> > > >
> > > > PS/2 keyboard is already connected in dock and laptop was just docked:
> > > >
> > > > [25461.552314] i8042: [6365474] fa <- i8042 (interrupt, 0, 1)
> > > > [25461.552319] atkbd serio0: Spurious ACK on isa0060/serio0. Some program
> > might be trying to access hardware directly.
> > > > [25462.707296] i8042: [6365763] ed -> i8042 (kbd-data)
> > > > [25462.851289] i8042: [6365799] fa <- i8042 (interrupt, 0, 1)
> > > > [25462.851303] i8042: [6365799] 00 -> i8042 (kbd-data)
> > > > [25462.858437] i8042: [6365801] fa <- i8042 (interrupt, 0, 1)
> > > > [25462.869512] i8042: [6365804] fa <- i8042 (interrupt, 0, 1)
> > > > [25462.869517] atkbd serio0: Spurious ACK on isa0060/serio0. Some program
> > might be trying to access hardware directly.
> > > > [25463.670515] i8042: [6366004] ed -> i8042 (kbd-data)
> > > > [25463.670647] i8042: [6366004] fa <- i8042 (interrupt, 0, 1)
> > > > [25463.670655] i8042: [6366004] 02 -> i8042 (kbd-data)
> > > > [25463.676769] i8042: [6366005] fa <- i8042 (interrupt, 0, 1)
> > > >
> > > >
> > > > Laptop is docked and PS/2 keyboard was just connected:
> > > >
> > > > [26571.014368] i8042: [6642848] fa <- i8042 (interrupt, 0, 1)
> > > > [26571.014380] atkbd serio0: Spurious ACK on isa0060/serio0. Some program
> > might be trying to access hardware directly.
> > > >
> > > >
> > > > In both cases there is no events from touchpad, only from keyboard. So
> > > > Dell EC silently reset PS/2 touchpad when PS/2 keyboard is attached.
> > > >
> > > > So I think we should capture 0xFA and on Dell machines we should
> > > > reinitialize PS/2 drivers. As there is really nothing more then 0xFA.
> > >
> > > Info about PS/2 mouse:
> > >
> > > In case I have laptop already docked and just connect PS/2 mouse there
> > > is absolutely no i8042 event.
> > >
> > > To check that mouse is worked I clicked button and then in dmesg
> > > appeared:
> > >
> > > [ 3945.481403] i8042: [986322] 09 <- i8042 (interrupt, 1, 12)
> > > [ 3945.482486] i8042: [986323] 00 <- i8042 (interrupt, 1, 12)
> > > [ 3945.483667] i8042: [986323] 00 <- i8042 (interrupt, 1, 12)
> > > [ 3945.483917] input: PS/2 ALPS Mouse as
> > /devices/platform/i8042/serio1/input/input36
> > > [ 3945.594926] i8042: [986351] 08 <- i8042 (interrupt, 1, 12)
> > > [ 3945.596062] i8042: [986351] 00 <- i8042 (interrupt, 1, 12)
> > > [ 3945.597203] i8042: [986351] 00 <- i8042 (interrupt, 1, 12)
> > >
> > > So we have no way to detect when external PS/2 mouse was connected to
> > > dock. But ALPS driver can deal with it and process these mouse events.
> > >
> > > And when I have already connected PS/2 mouse to the dock and I'm just
> > > putting laptop into dock, then I get following events:
> > >
> > > [ 4336.481381] i8042: [1084079] fa <- i8042 (interrupt, 0, 1)
> > > [ 4336.481388] atkbd serio0: Spurious ACK on isa0060/serio0. Some program
> > might be trying to access hardware directly.
> > > [ 4337.653275] i8042: [1084372] ed -> i8042 (kbd-data)
> >
> > I wonder where this "set leds" command is coming from and where is the
> > parameter... Can you add some more tracing? And maybe boot with
> > libps2.dyndbg=+pf
> >
> > > [ 4337.949198] i8042: [1084446] fa <- i8042 (interrupt, 0, 1)
> > > [ 4337.949202] atkbd serio0: Spurious ACK on isa0060/serio0. Some program
> > might be trying to access hardware directly.
> > > [ 4338.623167] i8042: [1084615] ed -> i8042 (kbd-data)
> > >
> > > So again, no event from mouse, just from keyboard.
> > >
> > > Note that in these tests I have disconnected my PS/2 keyboard from
> > > dock.
> >
> > So I guess you could write a platform driver that would install i8042
> > filter on Dell laptops/portables, monitor keyboard data stream and kick
> > of rescans on serio ports. The problem is filter gets "serio" so you do
> > not really know whether ACK is spurious or not. And I would really
> > prefer keeping this crap out of atkbd proper... And all of this is racy
> > as hell. What happens if we get keyboard reconnected as we reinitialize
> > it?
>
> If it's done as a platform driver I would suspect it's possible to tell whether
> a dock is connected to at least give you some heuristic here to have a better
> guess whether it's spurious.
Apparently checking for docking station is not enough. There are also
Dell Legacy Extenders (or how it is called) which exports internal PS/2,
Parallel and Serial Ports. It is also connecting to bottom of laptop.
But currently I do not have them for testing.
> Pali on your system that supports this dock, check and see how many
> System Enclosure SMBIOS tables (structure type 03) are present.
Do you mean DMI type 3 structure? Here is something from dmidecode:
Handle 0x0003, DMI type 3, 22 bytes
Chassis Information
Manufacturer: Dell Inc.
Type: Laptop
Lock: Not Present
Version: Not Specified
Serial Number: --REMOVED--
Asset Tag: Not Specified
Boot-up State: Safe
Power Supply State: Safe
Thermal State: Safe
Security Status: None
OEM Information: 0x00000000
Height: Unspecified
Number Of Power Cords: 1
Contained Elements: 0
SKU Number: To be filled by O.E.M.
But probably you mean something different?
> There should be a separate one for the dock as far as I can tell with values
> that will vary based on whether it's attached.
>
> Assuming that's true I think making a platform filter driver that only attaches
> to systems that actually support this type of dock should be possible too.
>
> >
> > Mario, how does Windows driver know when it should send "vendor"
> > commands to reinitialize peripherals?
> >
>
> Sorry , I don't know. It's "inbox" Windows drivers that are used here so
> it's a "black box" to me how they work.
>
--
Pali Rohár
pali.rohar@gmail.com
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 195 bytes --]
^ permalink raw reply
* RE: Dell docking station & Dell Embedded Controller & PS/2 devices
From: Mario.Limonciello @ 2018-05-07 19:59 UTC (permalink / raw)
To: dmitry.torokhov, pali.rohar; +Cc: linux-input, linux-kernel
In-Reply-To: <20180507193306.GA31301@dtor-ws>
> -----Original Message-----
> From: Dmitry Torokhov [mailto:dmitry.torokhov@gmail.com]
> Sent: Monday, May 7, 2018 2:33 PM
> To: Pali Rohár
> Cc: Limonciello, Mario; linux-input@vger.kernel.org; linux-kernel@vger.kernel.org
> Subject: Re: Dell docking station & Dell Embedded Controller & PS/2 devices
>
> On Mon, May 07, 2018 at 10:44:31AM +0200, Pali Rohár wrote:
> > On Sunday 06 May 2018 15:47:33 Pali Rohár wrote:
> > > On Thursday 01 February 2018 11:29:45 Dmitry Torokhov wrote:
> > > > Hi Pali,
> > > >
> > > > On Wed, Jan 24, 2018 at 11:41:21AM +0100, Pali Rohár wrote:
> > > > > Hi Dmitry!
> > > > >
> > > > > I'm observing a problem with internal touchpad (handled by psmouse.ko)
> > > > > on Dell laptops connected to Dell E docking station. When I connect
> > > > > external PS/2 keyboard to docking station then internal laptop touchpad
> > > > > switch from multitouch absolute mode to relative bare PS/2 mode.
> > > > >
> > > > > And because ALPS driver in psmouse.ko is capable to process interleaved
> > > > > bare 3-byte PS/2 packets with 6-byte ALPS packets (which handles
> > > > > trackstick data on some ALPS models), ALPS driver does not show any
> > > > > message about this "downgrade" from multitouch to bare mode. And
> > > > > continue working in bare mode.
> > > > >
> > > > > When I rmmod psmouse and modprobe it again, then touchpad switch back
> to
> > > > > multitouch mode.
> > > > >
> > > > > Mario told me that Dell Embedded Controller, which handle internal
> > > > > keyboard, internal touchpad and external PS/2 keyboard, automatically
> > > > > send RESET command to *all* those devices when external PS/2 keyboard is
> > > > > connected. Therefore this is reason why touchpad downgrade to to bare
> > > > > mode. And according to Mario, host system should issue vendor specific
> > > > > PS/2 commands to re-initialize all PS/2 devices when this situation
> > > > > happen. Mario also told me that Windows is doing this action.
> > > >
> > > > Yeah, I remember fun with Inspiron 8100 - when you dock it it woudl
> > > > silently switch Synaptics touchpad into standard mode and it would not
> > > > come back as Synaptics until you disconnect. And there was no
> > > > notification to the kernel as far as I could tell.
> > > >
> > > > It could be that we need to monitor dock events and then kick reconnect
> > > > of serio port, either from userspace via udev (I think that would be
> > > > preferred), or in kernel.
> > > >
> > > > >
> > > > > Every time when I connect external PS/2 keyboard to dock I see this
> > > > > message in dmesg:
> > > > >
> > > > > Spurious ACK... Some program might be trying to access hardware directly.
> > > > >
> > > > > I see it also every time when I dock laptop into docking station (to
> > > > > which is keyboard already connected). And it happens also when I connect
> > > > > external PS/2 mouse to dock.
> > > > >
> > > > > Dmitry, how to handle this situation to re-initialize psmouse.ko when
> > > > > external PS/2 device is connected to Dell E docking station? According
> > > > > to Mario, this is how Dell Embedded Controller is designed and suppose
> > > > > how OS should work with it.
> > > > >
> > > > > Manually rmmoding and modprobing for every docking/undocking laptop is
> > > > > not ideal solution.
> > > > >
> > > > > Could it be possible to use that Spurious ATKBD_RET_ACK from atkbd.c be
> > > > > handled on Dell systems (probably via DMI) as an event to reset and
> > > > > reinitialize all PS/2 devices?
> > > >
> > > > So we need to figure out what exactly we are getting from the docking
> > > > station in this case. We do try to handle the new device 0xaa 0x00
> > > > announcements:
> > > >
> > > > /* Check if this is a new device announcement (0xAA 0x00) */
> > > > if (unlikely(psmouse->packet[0] == PSMOUSE_RET_BAT && psmouse-
> >pktcnt <= 2)) {
> > > > if (psmouse->pktcnt == 1) {
> > > > psmouse->last = jiffies;
> > > > goto out;
> > > > }
> > > >
> > > > if (psmouse->packet[1] == PSMOUSE_RET_ID ||
> > > > (psmouse->protocol->type == PSMOUSE_HGPK &&
> > > > psmouse->packet[1] == PSMOUSE_RET_BAT)) {
> > > > __psmouse_set_state(psmouse, PSMOUSE_IGNORE);
> > > > serio_reconnect(serio);
> > > > goto out;
> > > > }
> > > >
> > > > ...
> > > >
> > > > I am not sure where the "spurious ACK comes from". Can you enable i8042
> > > > debug before trying to dock and capture the data stream from the mouse?
> > > >
> > > > Thanks.
> > > >
> > >
> > > Hi Dmitry!
> > >
> > > I enabled unmask_kbd_data and debug and here is output from dmesg.
> > >
> > > echo Y > /sys/module/i8042/parameters/debug
> > > echo Y > /sys/module/i8042/parameters/unmask_kbd_data
> > >
> > > PS/2 keyboard is already connected in dock and laptop was just docked:
> > >
> > > [25461.552314] i8042: [6365474] fa <- i8042 (interrupt, 0, 1)
> > > [25461.552319] atkbd serio0: Spurious ACK on isa0060/serio0. Some program
> might be trying to access hardware directly.
> > > [25462.707296] i8042: [6365763] ed -> i8042 (kbd-data)
> > > [25462.851289] i8042: [6365799] fa <- i8042 (interrupt, 0, 1)
> > > [25462.851303] i8042: [6365799] 00 -> i8042 (kbd-data)
> > > [25462.858437] i8042: [6365801] fa <- i8042 (interrupt, 0, 1)
> > > [25462.869512] i8042: [6365804] fa <- i8042 (interrupt, 0, 1)
> > > [25462.869517] atkbd serio0: Spurious ACK on isa0060/serio0. Some program
> might be trying to access hardware directly.
> > > [25463.670515] i8042: [6366004] ed -> i8042 (kbd-data)
> > > [25463.670647] i8042: [6366004] fa <- i8042 (interrupt, 0, 1)
> > > [25463.670655] i8042: [6366004] 02 -> i8042 (kbd-data)
> > > [25463.676769] i8042: [6366005] fa <- i8042 (interrupt, 0, 1)
> > >
> > >
> > > Laptop is docked and PS/2 keyboard was just connected:
> > >
> > > [26571.014368] i8042: [6642848] fa <- i8042 (interrupt, 0, 1)
> > > [26571.014380] atkbd serio0: Spurious ACK on isa0060/serio0. Some program
> might be trying to access hardware directly.
> > >
> > >
> > > In both cases there is no events from touchpad, only from keyboard. So
> > > Dell EC silently reset PS/2 touchpad when PS/2 keyboard is attached.
> > >
> > > So I think we should capture 0xFA and on Dell machines we should
> > > reinitialize PS/2 drivers. As there is really nothing more then 0xFA.
> >
> > Info about PS/2 mouse:
> >
> > In case I have laptop already docked and just connect PS/2 mouse there
> > is absolutely no i8042 event.
> >
> > To check that mouse is worked I clicked button and then in dmesg
> > appeared:
> >
> > [ 3945.481403] i8042: [986322] 09 <- i8042 (interrupt, 1, 12)
> > [ 3945.482486] i8042: [986323] 00 <- i8042 (interrupt, 1, 12)
> > [ 3945.483667] i8042: [986323] 00 <- i8042 (interrupt, 1, 12)
> > [ 3945.483917] input: PS/2 ALPS Mouse as
> /devices/platform/i8042/serio1/input/input36
> > [ 3945.594926] i8042: [986351] 08 <- i8042 (interrupt, 1, 12)
> > [ 3945.596062] i8042: [986351] 00 <- i8042 (interrupt, 1, 12)
> > [ 3945.597203] i8042: [986351] 00 <- i8042 (interrupt, 1, 12)
> >
> > So we have no way to detect when external PS/2 mouse was connected to
> > dock. But ALPS driver can deal with it and process these mouse events.
> >
> > And when I have already connected PS/2 mouse to the dock and I'm just
> > putting laptop into dock, then I get following events:
> >
> > [ 4336.481381] i8042: [1084079] fa <- i8042 (interrupt, 0, 1)
> > [ 4336.481388] atkbd serio0: Spurious ACK on isa0060/serio0. Some program
> might be trying to access hardware directly.
> > [ 4337.653275] i8042: [1084372] ed -> i8042 (kbd-data)
>
> I wonder where this "set leds" command is coming from and where is the
> parameter... Can you add some more tracing? And maybe boot with
> libps2.dyndbg=+pf
>
> > [ 4337.949198] i8042: [1084446] fa <- i8042 (interrupt, 0, 1)
> > [ 4337.949202] atkbd serio0: Spurious ACK on isa0060/serio0. Some program
> might be trying to access hardware directly.
> > [ 4338.623167] i8042: [1084615] ed -> i8042 (kbd-data)
> >
> > So again, no event from mouse, just from keyboard.
> >
> > Note that in these tests I have disconnected my PS/2 keyboard from
> > dock.
>
> So I guess you could write a platform driver that would install i8042
> filter on Dell laptops/portables, monitor keyboard data stream and kick
> of rescans on serio ports. The problem is filter gets "serio" so you do
> not really know whether ACK is spurious or not. And I would really
> prefer keeping this crap out of atkbd proper... And all of this is racy
> as hell. What happens if we get keyboard reconnected as we reinitialize
> it?
If it's done as a platform driver I would suspect it's possible to tell whether
a dock is connected to at least give you some heuristic here to have a better
guess whether it's spurious.
Pali on your system that supports this dock, check and see how many
System Enclosure SMBIOS tables (structure type 03) are present.
There should be a separate one for the dock as far as I can tell with values
that will vary based on whether it's attached.
Assuming that's true I think making a platform filter driver that only attaches
to systems that actually support this type of dock should be possible too.
>
> Mario, how does Windows driver know when it should send "vendor"
> commands to reinitialize peripherals?
>
Sorry , I don't know. It's "inbox" Windows drivers that are used here so
it's a "black box" to me how they work.
^ permalink raw reply
* Re: Dell docking station & Dell Embedded Controller & PS/2 devices
From: Pali Rohár @ 2018-05-07 19:58 UTC (permalink / raw)
To: Dmitry Torokhov; +Cc: Mario.Limonciello, linux-input, linux-kernel
In-Reply-To: <20180507193306.GA31301@dtor-ws>
[-- Attachment #1: Type: text/plain, Size: 9432 bytes --]
On Monday 07 May 2018 12:33:06 Dmitry Torokhov wrote:
> On Mon, May 07, 2018 at 10:44:31AM +0200, Pali Rohár wrote:
> > On Sunday 06 May 2018 15:47:33 Pali Rohár wrote:
> > > On Thursday 01 February 2018 11:29:45 Dmitry Torokhov wrote:
> > > > Hi Pali,
> > > >
> > > > On Wed, Jan 24, 2018 at 11:41:21AM +0100, Pali Rohár wrote:
> > > > > Hi Dmitry!
> > > > >
> > > > > I'm observing a problem with internal touchpad (handled by psmouse.ko)
> > > > > on Dell laptops connected to Dell E docking station. When I connect
> > > > > external PS/2 keyboard to docking station then internal laptop touchpad
> > > > > switch from multitouch absolute mode to relative bare PS/2 mode.
> > > > >
> > > > > And because ALPS driver in psmouse.ko is capable to process interleaved
> > > > > bare 3-byte PS/2 packets with 6-byte ALPS packets (which handles
> > > > > trackstick data on some ALPS models), ALPS driver does not show any
> > > > > message about this "downgrade" from multitouch to bare mode. And
> > > > > continue working in bare mode.
> > > > >
> > > > > When I rmmod psmouse and modprobe it again, then touchpad switch back to
> > > > > multitouch mode.
> > > > >
> > > > > Mario told me that Dell Embedded Controller, which handle internal
> > > > > keyboard, internal touchpad and external PS/2 keyboard, automatically
> > > > > send RESET command to *all* those devices when external PS/2 keyboard is
> > > > > connected. Therefore this is reason why touchpad downgrade to to bare
> > > > > mode. And according to Mario, host system should issue vendor specific
> > > > > PS/2 commands to re-initialize all PS/2 devices when this situation
> > > > > happen. Mario also told me that Windows is doing this action.
> > > >
> > > > Yeah, I remember fun with Inspiron 8100 - when you dock it it woudl
> > > > silently switch Synaptics touchpad into standard mode and it would not
> > > > come back as Synaptics until you disconnect. And there was no
> > > > notification to the kernel as far as I could tell.
> > > >
> > > > It could be that we need to monitor dock events and then kick reconnect
> > > > of serio port, either from userspace via udev (I think that would be
> > > > preferred), or in kernel.
> > > >
> > > > >
> > > > > Every time when I connect external PS/2 keyboard to dock I see this
> > > > > message in dmesg:
> > > > >
> > > > > Spurious ACK... Some program might be trying to access hardware directly.
> > > > >
> > > > > I see it also every time when I dock laptop into docking station (to
> > > > > which is keyboard already connected). And it happens also when I connect
> > > > > external PS/2 mouse to dock.
> > > > >
> > > > > Dmitry, how to handle this situation to re-initialize psmouse.ko when
> > > > > external PS/2 device is connected to Dell E docking station? According
> > > > > to Mario, this is how Dell Embedded Controller is designed and suppose
> > > > > how OS should work with it.
> > > > >
> > > > > Manually rmmoding and modprobing for every docking/undocking laptop is
> > > > > not ideal solution.
> > > > >
> > > > > Could it be possible to use that Spurious ATKBD_RET_ACK from atkbd.c be
> > > > > handled on Dell systems (probably via DMI) as an event to reset and
> > > > > reinitialize all PS/2 devices?
> > > >
> > > > So we need to figure out what exactly we are getting from the docking
> > > > station in this case. We do try to handle the new device 0xaa 0x00
> > > > announcements:
> > > >
> > > > /* Check if this is a new device announcement (0xAA 0x00) */
> > > > if (unlikely(psmouse->packet[0] == PSMOUSE_RET_BAT && psmouse->pktcnt <= 2)) {
> > > > if (psmouse->pktcnt == 1) {
> > > > psmouse->last = jiffies;
> > > > goto out;
> > > > }
> > > >
> > > > if (psmouse->packet[1] == PSMOUSE_RET_ID ||
> > > > (psmouse->protocol->type == PSMOUSE_HGPK &&
> > > > psmouse->packet[1] == PSMOUSE_RET_BAT)) {
> > > > __psmouse_set_state(psmouse, PSMOUSE_IGNORE);
> > > > serio_reconnect(serio);
> > > > goto out;
> > > > }
> > > >
> > > > ...
> > > >
> > > > I am not sure where the "spurious ACK comes from". Can you enable i8042
> > > > debug before trying to dock and capture the data stream from the mouse?
> > > >
> > > > Thanks.
> > > >
> > >
> > > Hi Dmitry!
> > >
> > > I enabled unmask_kbd_data and debug and here is output from dmesg.
> > >
> > > echo Y > /sys/module/i8042/parameters/debug
> > > echo Y > /sys/module/i8042/parameters/unmask_kbd_data
> > >
> > > PS/2 keyboard is already connected in dock and laptop was just docked:
> > >
> > > [25461.552314] i8042: [6365474] fa <- i8042 (interrupt, 0, 1)
> > > [25461.552319] atkbd serio0: Spurious ACK on isa0060/serio0. Some program might be trying to access hardware directly.
> > > [25462.707296] i8042: [6365763] ed -> i8042 (kbd-data)
> > > [25462.851289] i8042: [6365799] fa <- i8042 (interrupt, 0, 1)
> > > [25462.851303] i8042: [6365799] 00 -> i8042 (kbd-data)
> > > [25462.858437] i8042: [6365801] fa <- i8042 (interrupt, 0, 1)
> > > [25462.869512] i8042: [6365804] fa <- i8042 (interrupt, 0, 1)
> > > [25462.869517] atkbd serio0: Spurious ACK on isa0060/serio0. Some program might be trying to access hardware directly.
> > > [25463.670515] i8042: [6366004] ed -> i8042 (kbd-data)
> > > [25463.670647] i8042: [6366004] fa <- i8042 (interrupt, 0, 1)
> > > [25463.670655] i8042: [6366004] 02 -> i8042 (kbd-data)
> > > [25463.676769] i8042: [6366005] fa <- i8042 (interrupt, 0, 1)
> > >
> > >
> > > Laptop is docked and PS/2 keyboard was just connected:
> > >
> > > [26571.014368] i8042: [6642848] fa <- i8042 (interrupt, 0, 1)
> > > [26571.014380] atkbd serio0: Spurious ACK on isa0060/serio0. Some program might be trying to access hardware directly.
> > >
> > >
> > > In both cases there is no events from touchpad, only from keyboard. So
> > > Dell EC silently reset PS/2 touchpad when PS/2 keyboard is attached.
> > >
> > > So I think we should capture 0xFA and on Dell machines we should
> > > reinitialize PS/2 drivers. As there is really nothing more then 0xFA.
> >
> > Info about PS/2 mouse:
> >
> > In case I have laptop already docked and just connect PS/2 mouse there
> > is absolutely no i8042 event.
> >
> > To check that mouse is worked I clicked button and then in dmesg
> > appeared:
> >
> > [ 3945.481403] i8042: [986322] 09 <- i8042 (interrupt, 1, 12)
> > [ 3945.482486] i8042: [986323] 00 <- i8042 (interrupt, 1, 12)
> > [ 3945.483667] i8042: [986323] 00 <- i8042 (interrupt, 1, 12)
> > [ 3945.483917] input: PS/2 ALPS Mouse as /devices/platform/i8042/serio1/input/input36
> > [ 3945.594926] i8042: [986351] 08 <- i8042 (interrupt, 1, 12)
> > [ 3945.596062] i8042: [986351] 00 <- i8042 (interrupt, 1, 12)
> > [ 3945.597203] i8042: [986351] 00 <- i8042 (interrupt, 1, 12)
> >
> > So we have no way to detect when external PS/2 mouse was connected to
> > dock. But ALPS driver can deal with it and process these mouse events.
> >
> > And when I have already connected PS/2 mouse to the dock and I'm just
> > putting laptop into dock, then I get following events:
> >
> > [ 4336.481381] i8042: [1084079] fa <- i8042 (interrupt, 0, 1)
> > [ 4336.481388] atkbd serio0: Spurious ACK on isa0060/serio0. Some program might be trying to access hardware directly.
> > [ 4337.653275] i8042: [1084372] ed -> i8042 (kbd-data)
>
> I wonder where this "set leds" command is coming from and where is the
> parameter... Can you add some more tracing? And maybe boot with
> libps2.dyndbg=+pf
>
> > [ 4337.949198] i8042: [1084446] fa <- i8042 (interrupt, 0, 1)
> > [ 4337.949202] atkbd serio0: Spurious ACK on isa0060/serio0. Some program might be trying to access hardware directly.
> > [ 4338.623167] i8042: [1084615] ed -> i8042 (kbd-data)
> >
> > So again, no event from mouse, just from keyboard.
> >
> > Note that in these tests I have disconnected my PS/2 keyboard from
> > dock.
>
> So I guess you could write a platform driver that would install i8042
> filter on Dell laptops/portables, monitor keyboard data stream and kick
> of rescans on serio ports.
Ok. dell-laptop.ko already installs i8042 filter, so it could be
extended.
How can such dell-laptop.ko driver instruct serio0/1 devices to
reinitialize bound drivers (atk and psmouse, probably other)?
> The problem is filter gets "serio" so you do
> not really know whether ACK is spurious or not.
It is possible to extend i8042/serio driver to provide information via
i8042 filter callback if ACK is spurious or not?
> And I would really
> prefer keeping this crap out of atkbd proper... And all of this is racy
> as hell. What happens if we get keyboard reconnected as we reinitialize
> it?
Do not know, such race conditions are hard to test as you need correct
timing. And doing connecting/disconnecting PS/2 cable from dock together
with laptop docking/undocking cannot be done reliable for less then 5s
(need to press two buttons, take/unplug laptop + reconnecting PS/2 slot)
so hard to simulate race condition.
Plus we do not know what is that Dell EC doing with PS/2 data...
> Mario, how does Windows driver know when it should send "vendor"
> commands to reinitialize peripherals?
>
> Thanks.
>
--
Pali Rohár
pali.rohar@gmail.com
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 195 bytes --]
^ permalink raw reply
* Re: Dell docking station & Dell Embedded Controller & PS/2 devices
From: Dmitry Torokhov @ 2018-05-07 19:33 UTC (permalink / raw)
To: Pali Rohár; +Cc: Mario.Limonciello, linux-input, linux-kernel
In-Reply-To: <20180507084431.r2dipv32wt3vbx3k@pali>
On Mon, May 07, 2018 at 10:44:31AM +0200, Pali Rohár wrote:
> On Sunday 06 May 2018 15:47:33 Pali Rohár wrote:
> > On Thursday 01 February 2018 11:29:45 Dmitry Torokhov wrote:
> > > Hi Pali,
> > >
> > > On Wed, Jan 24, 2018 at 11:41:21AM +0100, Pali Rohár wrote:
> > > > Hi Dmitry!
> > > >
> > > > I'm observing a problem with internal touchpad (handled by psmouse.ko)
> > > > on Dell laptops connected to Dell E docking station. When I connect
> > > > external PS/2 keyboard to docking station then internal laptop touchpad
> > > > switch from multitouch absolute mode to relative bare PS/2 mode.
> > > >
> > > > And because ALPS driver in psmouse.ko is capable to process interleaved
> > > > bare 3-byte PS/2 packets with 6-byte ALPS packets (which handles
> > > > trackstick data on some ALPS models), ALPS driver does not show any
> > > > message about this "downgrade" from multitouch to bare mode. And
> > > > continue working in bare mode.
> > > >
> > > > When I rmmod psmouse and modprobe it again, then touchpad switch back to
> > > > multitouch mode.
> > > >
> > > > Mario told me that Dell Embedded Controller, which handle internal
> > > > keyboard, internal touchpad and external PS/2 keyboard, automatically
> > > > send RESET command to *all* those devices when external PS/2 keyboard is
> > > > connected. Therefore this is reason why touchpad downgrade to to bare
> > > > mode. And according to Mario, host system should issue vendor specific
> > > > PS/2 commands to re-initialize all PS/2 devices when this situation
> > > > happen. Mario also told me that Windows is doing this action.
> > >
> > > Yeah, I remember fun with Inspiron 8100 - when you dock it it woudl
> > > silently switch Synaptics touchpad into standard mode and it would not
> > > come back as Synaptics until you disconnect. And there was no
> > > notification to the kernel as far as I could tell.
> > >
> > > It could be that we need to monitor dock events and then kick reconnect
> > > of serio port, either from userspace via udev (I think that would be
> > > preferred), or in kernel.
> > >
> > > >
> > > > Every time when I connect external PS/2 keyboard to dock I see this
> > > > message in dmesg:
> > > >
> > > > Spurious ACK... Some program might be trying to access hardware directly.
> > > >
> > > > I see it also every time when I dock laptop into docking station (to
> > > > which is keyboard already connected). And it happens also when I connect
> > > > external PS/2 mouse to dock.
> > > >
> > > > Dmitry, how to handle this situation to re-initialize psmouse.ko when
> > > > external PS/2 device is connected to Dell E docking station? According
> > > > to Mario, this is how Dell Embedded Controller is designed and suppose
> > > > how OS should work with it.
> > > >
> > > > Manually rmmoding and modprobing for every docking/undocking laptop is
> > > > not ideal solution.
> > > >
> > > > Could it be possible to use that Spurious ATKBD_RET_ACK from atkbd.c be
> > > > handled on Dell systems (probably via DMI) as an event to reset and
> > > > reinitialize all PS/2 devices?
> > >
> > > So we need to figure out what exactly we are getting from the docking
> > > station in this case. We do try to handle the new device 0xaa 0x00
> > > announcements:
> > >
> > > /* Check if this is a new device announcement (0xAA 0x00) */
> > > if (unlikely(psmouse->packet[0] == PSMOUSE_RET_BAT && psmouse->pktcnt <= 2)) {
> > > if (psmouse->pktcnt == 1) {
> > > psmouse->last = jiffies;
> > > goto out;
> > > }
> > >
> > > if (psmouse->packet[1] == PSMOUSE_RET_ID ||
> > > (psmouse->protocol->type == PSMOUSE_HGPK &&
> > > psmouse->packet[1] == PSMOUSE_RET_BAT)) {
> > > __psmouse_set_state(psmouse, PSMOUSE_IGNORE);
> > > serio_reconnect(serio);
> > > goto out;
> > > }
> > >
> > > ...
> > >
> > > I am not sure where the "spurious ACK comes from". Can you enable i8042
> > > debug before trying to dock and capture the data stream from the mouse?
> > >
> > > Thanks.
> > >
> >
> > Hi Dmitry!
> >
> > I enabled unmask_kbd_data and debug and here is output from dmesg.
> >
> > echo Y > /sys/module/i8042/parameters/debug
> > echo Y > /sys/module/i8042/parameters/unmask_kbd_data
> >
> > PS/2 keyboard is already connected in dock and laptop was just docked:
> >
> > [25461.552314] i8042: [6365474] fa <- i8042 (interrupt, 0, 1)
> > [25461.552319] atkbd serio0: Spurious ACK on isa0060/serio0. Some program might be trying to access hardware directly.
> > [25462.707296] i8042: [6365763] ed -> i8042 (kbd-data)
> > [25462.851289] i8042: [6365799] fa <- i8042 (interrupt, 0, 1)
> > [25462.851303] i8042: [6365799] 00 -> i8042 (kbd-data)
> > [25462.858437] i8042: [6365801] fa <- i8042 (interrupt, 0, 1)
> > [25462.869512] i8042: [6365804] fa <- i8042 (interrupt, 0, 1)
> > [25462.869517] atkbd serio0: Spurious ACK on isa0060/serio0. Some program might be trying to access hardware directly.
> > [25463.670515] i8042: [6366004] ed -> i8042 (kbd-data)
> > [25463.670647] i8042: [6366004] fa <- i8042 (interrupt, 0, 1)
> > [25463.670655] i8042: [6366004] 02 -> i8042 (kbd-data)
> > [25463.676769] i8042: [6366005] fa <- i8042 (interrupt, 0, 1)
> >
> >
> > Laptop is docked and PS/2 keyboard was just connected:
> >
> > [26571.014368] i8042: [6642848] fa <- i8042 (interrupt, 0, 1)
> > [26571.014380] atkbd serio0: Spurious ACK on isa0060/serio0. Some program might be trying to access hardware directly.
> >
> >
> > In both cases there is no events from touchpad, only from keyboard. So
> > Dell EC silently reset PS/2 touchpad when PS/2 keyboard is attached.
> >
> > So I think we should capture 0xFA and on Dell machines we should
> > reinitialize PS/2 drivers. As there is really nothing more then 0xFA.
>
> Info about PS/2 mouse:
>
> In case I have laptop already docked and just connect PS/2 mouse there
> is absolutely no i8042 event.
>
> To check that mouse is worked I clicked button and then in dmesg
> appeared:
>
> [ 3945.481403] i8042: [986322] 09 <- i8042 (interrupt, 1, 12)
> [ 3945.482486] i8042: [986323] 00 <- i8042 (interrupt, 1, 12)
> [ 3945.483667] i8042: [986323] 00 <- i8042 (interrupt, 1, 12)
> [ 3945.483917] input: PS/2 ALPS Mouse as /devices/platform/i8042/serio1/input/input36
> [ 3945.594926] i8042: [986351] 08 <- i8042 (interrupt, 1, 12)
> [ 3945.596062] i8042: [986351] 00 <- i8042 (interrupt, 1, 12)
> [ 3945.597203] i8042: [986351] 00 <- i8042 (interrupt, 1, 12)
>
> So we have no way to detect when external PS/2 mouse was connected to
> dock. But ALPS driver can deal with it and process these mouse events.
>
> And when I have already connected PS/2 mouse to the dock and I'm just
> putting laptop into dock, then I get following events:
>
> [ 4336.481381] i8042: [1084079] fa <- i8042 (interrupt, 0, 1)
> [ 4336.481388] atkbd serio0: Spurious ACK on isa0060/serio0. Some program might be trying to access hardware directly.
> [ 4337.653275] i8042: [1084372] ed -> i8042 (kbd-data)
I wonder where this "set leds" command is coming from and where is the
parameter... Can you add some more tracing? And maybe boot with
libps2.dyndbg=+pf
> [ 4337.949198] i8042: [1084446] fa <- i8042 (interrupt, 0, 1)
> [ 4337.949202] atkbd serio0: Spurious ACK on isa0060/serio0. Some program might be trying to access hardware directly.
> [ 4338.623167] i8042: [1084615] ed -> i8042 (kbd-data)
>
> So again, no event from mouse, just from keyboard.
>
> Note that in these tests I have disconnected my PS/2 keyboard from
> dock.
So I guess you could write a platform driver that would install i8042
filter on Dell laptops/portables, monitor keyboard data stream and kick
of rescans on serio ports. The problem is filter gets "serio" so you do
not really know whether ACK is spurious or not. And I would really
prefer keeping this crap out of atkbd proper... And all of this is racy
as hell. What happens if we get keyboard reconnected as we reinitialize
it?
Mario, how does Windows driver know when it should send "vendor"
commands to reinitialize peripherals?
Thanks.
--
Dmitry
^ permalink raw reply
* Re: [PATCH V3] Input: pm8941-pwrkey: add resin key capabilities
From: Bjorn Andersson @ 2018-05-07 18:46 UTC (permalink / raw)
To: Dmitry Torokhov
Cc: Tirupathi Reddy, robh+dt, mark.rutland, linux-input,
linux-arm-msm, devicetree, linux-kernel
In-Reply-To: <20180505001039.GA112416@dtor-ws>
On Fri 04 May 17:10 PDT 2018, Dmitry Torokhov wrote:
> Hi Tirupathi,
>
> On Fri, Mar 23, 2018 at 11:53:12AM +0530, Tirupathi Reddy wrote:
> > Add resin key support to handle different types of key events
> > defined in different platforms.
> >
> > Signed-off-by: Tirupathi Reddy <tirupath@codeaurora.org>
> > ---
> > .../bindings/input/qcom,pm8941-pwrkey.txt | 32 +++++++++
> > drivers/input/misc/pm8941-pwrkey.c | 81 ++++++++++++++++++++++
> > 2 files changed, 113 insertions(+)
> >
> > diff --git a/Documentation/devicetree/bindings/input/qcom,pm8941-pwrkey.txt b/Documentation/devicetree/bindings/input/qcom,pm8941-pwrkey.txt
[..]
> > EXAMPLE
> >
> > pwrkey@800 {
> > @@ -40,4 +66,10 @@ EXAMPLE
> > interrupts = <0x0 0x8 0 IRQ_TYPE_EDGE_BOTH>;
> > debounce = <15625>;
> > bias-pull-up;
> > +
> > + resin {
> > + interrupts = <0x0 0x8 1 IRQ_TYPE_EDGE_BOTH>;
> > + linux,code = <KEY_VOLUMEDOWN>;
> > + bias-pull-up;
> > + };
> > };
>
> The new key and power key bindings are very similar, I would prefer if
> we shared the parsing code and our new DTS looked like:
>
> power {
> ...
> };
>
> resin {
> ...
> };
>
> (we can easily keep backward compatibility with power properties being
> in device node).
>
As discussed here https://patchwork.kernel.org/patch/9751627/ the PON
block does, in addition to providing power and resin key support also
handle the restart reason ("reboot bootloader" in Android).
My interpretation of our conclusion was to come up with a new binding
for the "pon" and a driver for this block that instantiates the power
key device.
It seems reasonable for such binding to describe the two keys, as you
propose here Dmitry, and instantiates the two input devices based on
this.
Regards,
Bjorn
^ permalink raw reply
* Re: [PATCH v4 1/3] resource: Use list_head to link sibling resource
From: kbuild test robot @ 2018-05-07 15:50 UTC (permalink / raw)
Cc: nicolas.pitre-QSEj5FYQhm4dnm+yROfE0A, brijesh.singh-5C7GfCeVMHo,
devicetree-u79uwXL29TY76Z2rM5mHXA, airlied-cv59FeDIM0c,
linux-pci-u79uwXL29TY76Z2rM5mHXA,
richard.weiyang-Re5JQEeQqe8AvxtiuMwx3w,
keith.busch-ral2JQCrhuEAvxtiuMwx3w,
jcmvbkbc-Re5JQEeQqe8AvxtiuMwx3w,
baiyaowei-0p4V/sDNsUmm0O/7XYngnFaTQe2KTcn/,
kys-0li6OtcxBFHby3iVrkZq2A, frowand.list-Re5JQEeQqe8AvxtiuMwx3w,
lorenzo.pieralisi-5wv7dgnIgG8, sthemmin-0li6OtcxBFHby3iVrkZq2A,
Baoquan He, linux-nvdimm-hn68Rpc1hR1g9hUCZPvPmw,
patrik.r.jakobsson-Re5JQEeQqe8AvxtiuMwx3w,
linux-input-u79uwXL29TY76Z2rM5mHXA,
gustavo-THi1TnShQwVAfugRpC6u6w, bp-l3A5Bk7waGM,
dyoung-H+wXaHxf7aLQT0dZR+AlfA, ebiederm-aS9lmoZGLiVWk0Htik3J/w,
thomas.lendacky-5C7GfCeVMHo, haiyangz-0li6OtcxBFHby3iVrkZq2A,
maarten.lankhorst-VuQAYsv1563Yd54FQh9/CA,
josh-iaAMLnmF4UmaiuxdJuQwMA, jglisse-H+wXaHxf7aLQT0dZR+AlfA,
robh+dt-DgEjT+Ai2ygdnm+yROfE0A, seanpaul-F7+t8E8rja9g9hUCZPvPmw,
bhelgaas-hpIqsD4AKlfQT0dZR+AlfA, tglx-hfZtesqFncYOwBW4kG4KsQ,
yinghai-DgEjT+Ai2ygdnm+yROfE0A,
jonathan.derrick-ral2JQCrhuEAvxtiuMwx3w,
chris-YvXeqwSYzG2sTnJN9+BGXg, monstr-pSz03upnqPeHXe+LvDLADg,
linux-parisc-u79uwXL29TY76Z2rM5mHXA,
gregkh-hQyY1W1yCW8ekmWlsbkhG0B+6BGkLq7r, dmitry.torokhov
In-Reply-To: <20180507063224.24229-2-bhe-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
Hi Baoquan,
I love your patch! Yet something to improve:
[auto build test ERROR on linus/master]
[also build test ERROR on v4.17-rc4 next-20180504]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]
url: https://github.com/0day-ci/linux/commits/Baoquan-He/resource-Use-list_head-to-link-sibling-resource/20180507-144345
config: arm-allmodconfig (attached as .config)
compiler: arm-linux-gnueabi-gcc (Debian 7.2.0-11) 7.2.0
reproduce:
wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
chmod +x ~/bin/make.cross
# save the attached .config to linux build tree
make.cross ARCH=arm
All errors (new ones prefixed by >>):
arch/arm/plat-samsung/pm-check.c: In function 's3c_pm_run_res':
>> arch/arm/plat-samsung/pm-check.c:49:18: error: invalid operands to binary != (have 'struct list_head' and 'void *')
if (ptr->child != NULL)
~~~~~~~~~~ ^~
>> arch/arm/plat-samsung/pm-check.c:50:19: error: incompatible type for argument 1 of 's3c_pm_run_res'
s3c_pm_run_res(ptr->child, fn, arg);
^~~
arch/arm/plat-samsung/pm-check.c:46:13: note: expected 'struct resource *' but argument is of type 'struct list_head'
static void s3c_pm_run_res(struct resource *ptr, run_fn_t fn, u32 *arg)
^~~~~~~~~~~~~~
>> arch/arm/plat-samsung/pm-check.c:60:7: error: incompatible types when assigning to type 'struct resource *' from type 'struct list_head'
ptr = ptr->sibling;
^
vim +49 arch/arm/plat-samsung/pm-check.c
549c7e33 arch/arm/plat-s3c/pm-check.c Ben Dooks 2008-12-12 45
549c7e33 arch/arm/plat-s3c/pm-check.c Ben Dooks 2008-12-12 46 static void s3c_pm_run_res(struct resource *ptr, run_fn_t fn, u32 *arg)
549c7e33 arch/arm/plat-s3c/pm-check.c Ben Dooks 2008-12-12 47 {
549c7e33 arch/arm/plat-s3c/pm-check.c Ben Dooks 2008-12-12 48 while (ptr != NULL) {
549c7e33 arch/arm/plat-s3c/pm-check.c Ben Dooks 2008-12-12 @49 if (ptr->child != NULL)
549c7e33 arch/arm/plat-s3c/pm-check.c Ben Dooks 2008-12-12 @50 s3c_pm_run_res(ptr->child, fn, arg);
549c7e33 arch/arm/plat-s3c/pm-check.c Ben Dooks 2008-12-12 51
05fee7cf arch/arm/plat-samsung/pm-check.c Toshi Kani 2016-01-26 52 if ((ptr->flags & IORESOURCE_SYSTEM_RAM)
05fee7cf arch/arm/plat-samsung/pm-check.c Toshi Kani 2016-01-26 53 == IORESOURCE_SYSTEM_RAM) {
549c7e33 arch/arm/plat-s3c/pm-check.c Ben Dooks 2008-12-12 54 S3C_PMDBG("Found system RAM at %08lx..%08lx\n",
840eeeb8 arch/arm/plat-s3c/pm-check.c Ben Dooks 2008-12-12 55 (unsigned long)ptr->start,
840eeeb8 arch/arm/plat-s3c/pm-check.c Ben Dooks 2008-12-12 56 (unsigned long)ptr->end);
549c7e33 arch/arm/plat-s3c/pm-check.c Ben Dooks 2008-12-12 57 arg = (fn)(ptr, arg);
549c7e33 arch/arm/plat-s3c/pm-check.c Ben Dooks 2008-12-12 58 }
549c7e33 arch/arm/plat-s3c/pm-check.c Ben Dooks 2008-12-12 59
549c7e33 arch/arm/plat-s3c/pm-check.c Ben Dooks 2008-12-12 @60 ptr = ptr->sibling;
549c7e33 arch/arm/plat-s3c/pm-check.c Ben Dooks 2008-12-12 61 }
549c7e33 arch/arm/plat-s3c/pm-check.c Ben Dooks 2008-12-12 62 }
549c7e33 arch/arm/plat-s3c/pm-check.c Ben Dooks 2008-12-12 63
:::::: The code at line 49 was first introduced by commit
:::::: 549c7e33aeb9bfe441ecf68639d2227bb90978e7 [ARM] S3C: Split the resume memory check code from pm.c
:::::: TO: Ben Dooks <ben-linux-elnMNo+KYs3YtjvyW6yDsg@public.gmane.org>
:::::: CC: Ben Dooks <ben-linux-elnMNo+KYs3YtjvyW6yDsg@public.gmane.org>
---
0-DAY kernel test infrastructure Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all Intel Corporation
^ permalink raw reply
* [PATCH] Input: ili251x - add support for Ilitek ILI251x touchscreens
From: Philipp Puschmann @ 2018-05-07 13:18 UTC (permalink / raw)
To: dmitry.torokhov
Cc: robh+dt, mark.rutland, rydberg, pp, andi, linux-input, devicetree,
linux-kernel
The driver supports at least the ili2511 chipset but may support other
Ilitek chipsets using Ilitek i2c protocol v3.x.
The tested ili2511-based touchscreen delivers garbage for more than 6
fingers while it should support up to 10 fingers. The reason is still
unclear and this remains a FIXME in the driver for now.
The usage of pressure is optional. Touchscreens may deliver constant
and so useless pressure data.
Signed-off-by: Philipp Puschmann <pp@emlix.com>
---
.../bindings/input/touchscreen/ili251x.txt | 35 ++
drivers/input/touchscreen/Kconfig | 12 +
drivers/input/touchscreen/Makefile | 1 +
drivers/input/touchscreen/ili251x.c | 350 ++++++++++++++++++
4 files changed, 398 insertions(+)
create mode 100644 Documentation/devicetree/bindings/input/touchscreen/ili251x.txt
create mode 100644 drivers/input/touchscreen/ili251x.c
diff --git a/Documentation/devicetree/bindings/input/touchscreen/ili251x.txt b/Documentation/devicetree/bindings/input/touchscreen/ili251x.txt
new file mode 100644
index 000000000000..f21ad93d3bdd
--- /dev/null
+++ b/Documentation/devicetree/bindings/input/touchscreen/ili251x.txt
@@ -0,0 +1,35 @@
+Ilitek ili251x touchscreen driver
+
+This driver uses protocol version 3 and should be compatible with other
+Ilitek touch controllers that use protocol 3.x
+
+Required properties:
+ - compatible: "ili251x"
+ - reg: I2C slave address of the chip (0x41)
+ - interrupt-parent: a phandle pointing to the interrupt controller
+ serving the interrupt for this chip
+ - interrupts: interrupt specification for the touchdetect
+ interrupt
+
+Optional properties:
+ - reset-gpios: GPIO specification for the RESET input
+
+ - pinctrl-names: should be "default"
+ - pinctrl-0: a phandle pointing to the pin settings for the
+ control gpios
+ - max-fingers: the maximum number of fingers to handle
+ - pressure: support pressure data
+ - generic options : See touchscreen.txt
+
+Example:
+
+ ili251x@41 {
+ compatible = "ili251x";
+ reg = <0x41>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_touchpanel>;
+ interrupt-parent = <&gpio5>;
+ interrupts = <20 IRQ_TYPE_EDGE_FALLING>;
+ reset-gpios = <&gpio5 18 GPIO_ACTIVE_HIGH>;
+ max-fingers = <6>;
+ };
diff --git a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconfig
index 4f15496fec8b..569528834d48 100644
--- a/drivers/input/touchscreen/Kconfig
+++ b/drivers/input/touchscreen/Kconfig
@@ -380,6 +380,18 @@ config TOUCHSCREEN_ILI210X
To compile this driver as a module, choose M here: the
module will be called ili210x.
+config TOUCHSCREEN_ILI251X
+ tristate "Ilitek ILI251X based touchscreen"
+ depends on I2C
+ help
+ Say Y here if you have a ILI251X based touchscreen
+ controller. This driver supports ILI2511.
+
+ If unsure, say N.
+
+ To compile this driver as a module, choose M here: the
+ module will be called ili251x.
+
config TOUCHSCREEN_IPROC
tristate "IPROC touch panel driver support"
depends on ARCH_BCM_IPROC || COMPILE_TEST
diff --git a/drivers/input/touchscreen/Makefile b/drivers/input/touchscreen/Makefile
index dddae7973436..e795b62e5f64 100644
--- a/drivers/input/touchscreen/Makefile
+++ b/drivers/input/touchscreen/Makefile
@@ -43,6 +43,7 @@ obj-$(CONFIG_TOUCHSCREEN_FUJITSU) += fujitsu_ts.o
obj-$(CONFIG_TOUCHSCREEN_GOODIX) += goodix.o
obj-$(CONFIG_TOUCHSCREEN_HIDEEP) += hideep.o
obj-$(CONFIG_TOUCHSCREEN_ILI210X) += ili210x.o
+obj-$(CONFIG_TOUCHSCREEN_ILI251X) += ili251x.o
obj-$(CONFIG_TOUCHSCREEN_IMX6UL_TSC) += imx6ul_tsc.o
obj-$(CONFIG_TOUCHSCREEN_INEXIO) += inexio.o
obj-$(CONFIG_TOUCHSCREEN_IPROC) += bcm_iproc_tsc.o
diff --git a/drivers/input/touchscreen/ili251x.c b/drivers/input/touchscreen/ili251x.c
new file mode 100644
index 000000000000..203367b59902
--- /dev/null
+++ b/drivers/input/touchscreen/ili251x.c
@@ -0,0 +1,350 @@
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright (c) 2018, emlix GmbH. All rights reserved. */
+
+#include <linux/module.h>
+#include <linux/i2c.h>
+#include <linux/interrupt.h>
+#include <linux/delay.h>
+#include <linux/gpio/consumer.h>
+#include <linux/slab.h>
+#include <linux/input.h>
+#include <linux/input/mt.h>
+#include <linux/irq.h>
+
+#define MAX_FINGERS 10
+#define REG_TOUCHDATA 0x10
+#define TOUCHDATA_FINGERS 6
+#define REG_TOUCHDATA2 0x14
+#define TOUCHDATA2_FINGERS 4
+#define REG_PANEL_INFO 0x20
+#define REG_FIRMWARE_VERSION 0x40
+#define REG_PROTO_VERSION 0x42
+#define REG_CALIBRATE 0xcc
+
+struct finger {
+ u8 x_high:6;
+ u8 dummy:1;
+ u8 status:1;
+ u8 x_low;
+ u8 y_high;
+ u8 y_low;
+ u8 pressure;
+} __packed;
+
+struct touchdata {
+ u8 status;
+ struct finger fingers[MAX_FINGERS];
+} __packed;
+
+struct panel_info {
+ u8 x_low;
+ u8 x_high;
+ u8 y_low;
+ u8 y_high;
+ u8 xchannel_num;
+ u8 ychannel_num;
+ u8 max_fingers;
+} __packed;
+
+struct firmware_version {
+ u8 id;
+ u8 major;
+ u8 minor;
+} __packed;
+
+struct protocol_version {
+ u8 major;
+ u8 minor;
+} __packed;
+
+struct ili251x_data {
+ struct i2c_client *client;
+ struct input_dev *input;
+ unsigned int max_fingers;
+ bool use_pressure;
+ struct gpio_desc *reset_gpio;
+};
+
+static int ili251x_read_reg(struct i2c_client *client, u8 reg, void *buf,
+ size_t len)
+{
+ struct i2c_msg msg[2] = {
+ {
+ .addr = client->addr,
+ .flags = 0,
+ .len = 1,
+ .buf = ®,
+ },
+ {
+ .addr = client->addr,
+ .flags = I2C_M_RD,
+ .len = len,
+ .buf = buf,
+ }
+ };
+
+ if (i2c_transfer(client->adapter, msg, 2) != 2) {
+ dev_err(&client->dev, "i2c transfer failed\n");
+ return -EIO;
+ }
+
+ return 0;
+}
+
+static void ili251x_report_events(struct ili251x_data *data,
+ const struct touchdata *touchdata)
+{
+ struct input_dev *input = data->input;
+ unsigned int i;
+ bool touch;
+ unsigned int x, y;
+ const struct finger *finger;
+ unsigned int reported_fingers = 0;
+
+ /* the touch chip does not count the real fingers but switches between
+ * 0, 6 and 10 reported fingers *
+ *
+ * FIXME: With a tested ili2511 we received only garbage for fingers
+ * 6-9. As workaround we add a device tree option to limit the
+ * handled number of fingers
+ */
+ if (touchdata->status == 1)
+ reported_fingers = 6;
+ else if (touchdata->status == 2)
+ reported_fingers = 10;
+
+ for (i = 0; i < reported_fingers && i < data->max_fingers; i++) {
+ input_mt_slot(input, i);
+
+ finger = &touchdata->fingers[i];
+
+ touch = finger->status;
+ input_mt_report_slot_state(input, MT_TOOL_FINGER, touch);
+ x = finger->x_low | (finger->x_high << 8);
+ y = finger->y_low | (finger->y_high << 8);
+
+ if (touch) {
+ input_report_abs(input, ABS_MT_POSITION_X, x);
+ input_report_abs(input, ABS_MT_POSITION_Y, y);
+ if (data->use_pressure)
+ input_report_abs(input, ABS_MT_PRESSURE,
+ finger->pressure);
+
+ }
+ }
+
+ input_mt_report_pointer_emulation(input, false);
+ input_sync(input);
+}
+
+static irqreturn_t ili251x_irq(int irq, void *irq_data)
+{
+ struct ili251x_data *data = irq_data;
+ struct i2c_client *client = data->client;
+ struct touchdata touchdata;
+ int error;
+
+ error = ili251x_read_reg(client, REG_TOUCHDATA,
+ &touchdata,
+ sizeof(touchdata) -
+ sizeof(struct finger)*TOUCHDATA2_FINGERS);
+
+ if (!error && touchdata.status == 2 && data->max_fingers > 6)
+ error = ili251x_read_reg(client, REG_TOUCHDATA2,
+ &touchdata.fingers[TOUCHDATA_FINGERS],
+ sizeof(struct finger)*TOUCHDATA2_FINGERS);
+
+ if (!error)
+ ili251x_report_events(data, &touchdata);
+ else
+ dev_err(&client->dev,
+ "Unable to get touchdata, err = %d\n", error);
+
+ return IRQ_HANDLED;
+}
+
+static void ili251x_reset(struct ili251x_data *data)
+{
+ if (data->reset_gpio) {
+ gpiod_set_value(data->reset_gpio, 1);
+ usleep_range(50, 100);
+ gpiod_set_value(data->reset_gpio, 0);
+ msleep(100);
+ }
+}
+
+static int ili251x_i2c_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
+{
+ struct device *dev = &client->dev;
+ struct ili251x_data *data;
+ struct input_dev *input;
+ struct panel_info panel;
+ struct device_node *np = dev->of_node;
+ struct firmware_version firmware;
+ struct protocol_version protocol;
+ int xmax, ymax;
+ int error;
+
+ dev_dbg(dev, "Probing for ili251x I2C Touschreen driver");
+
+ if (client->irq <= 0) {
+ dev_err(dev, "No IRQ!\n");
+ return -EINVAL;
+ }
+
+ data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
+ input = devm_input_allocate_device(dev);
+ if (!data || !input)
+ return -ENOMEM;
+
+ data->client = client;
+ data->input = input;
+ data->use_pressure = false;
+
+ data->reset_gpio = devm_gpiod_get_optional(dev, "reset",
+ GPIOD_OUT_HIGH);
+ if (IS_ERR(data->reset_gpio)) {
+ error = PTR_ERR(data->reset_gpio);
+ if (error != -EPROBE_DEFER)
+ dev_err(dev,
+ "Failed to get reset GPIO: %d\n", error);
+ return error;
+ }
+
+ ili251x_reset(data);
+
+ error = ili251x_read_reg(client, REG_FIRMWARE_VERSION,
+ &firmware, sizeof(firmware));
+ if (error) {
+ dev_err(dev, "Failed to get firmware version, err: %d\n",
+ error);
+ return error;
+ }
+
+ error = ili251x_read_reg(client, REG_PROTO_VERSION,
+ &protocol, sizeof(protocol));
+ if (error) {
+ dev_err(dev, "Failed to get protocol version, err: %d\n",
+ error);
+ return error;
+ }
+ if (protocol.major != 3) {
+ dev_err(dev, "This driver expects protocol version 3.x, Chip uses: %d\n",
+ protocol.major);
+ return -EINVAL;
+ }
+
+ error = ili251x_read_reg(client, REG_PANEL_INFO, &panel, sizeof(panel));
+ if (error) {
+ dev_err(dev, "Failed to get panel information, err: %d\n",
+ error);
+ return error;
+ }
+
+ data->max_fingers = panel.max_fingers;
+ if (np) {
+ int max_fingers;
+
+ error = of_property_read_u32(np, "max-fingers", &max_fingers);
+ if (!error && max_fingers < data->max_fingers)
+ data->max_fingers = max_fingers;
+
+ if (of_property_read_bool(np, "pressure"))
+ data->use_pressure = true;
+ }
+
+ xmax = panel.x_low | (panel.x_high << 8);
+ ymax = panel.y_low | (panel.y_high << 8);
+
+ /* Setup input device */
+ input->name = "ili251x Touchscreen";
+ input->id.bustype = BUS_I2C;
+ input->dev.parent = dev;
+
+ __set_bit(EV_SYN, input->evbit);
+ __set_bit(EV_KEY, input->evbit);
+ __set_bit(EV_ABS, input->evbit);
+ __set_bit(BTN_TOUCH, input->keybit);
+
+ /* Single touch */
+ input_set_abs_params(input, ABS_X, 0, xmax, 0, 0);
+ input_set_abs_params(input, ABS_Y, 0, ymax, 0, 0);
+
+ /* Multi touch */
+ input_mt_init_slots(input, data->max_fingers, 0);
+ input_set_abs_params(input, ABS_MT_POSITION_X, 0, xmax, 0, 0);
+ input_set_abs_params(input, ABS_MT_POSITION_Y, 0, ymax, 0, 0);
+ if (data->use_pressure)
+ input_set_abs_params(input, ABS_MT_PRESSURE, 0, U8_MAX, 0, 0);
+
+ i2c_set_clientdata(client, data);
+
+ error = devm_request_threaded_irq(dev, client->irq, NULL, ili251x_irq,
+ IRQF_ONESHOT, client->name, data);
+
+ if (error) {
+ dev_err(dev, "Unable to request touchscreen IRQ, err: %d\n",
+ error);
+ return error;
+ }
+
+ error = input_register_device(data->input);
+ if (error) {
+ dev_err(dev, "Cannot register input device, err: %d\n", error);
+ return error;
+ }
+
+ device_init_wakeup(dev, 1);
+
+ dev_info(dev,
+ "ili251x initialized (IRQ: %d), firmware version %d.%d.%d fingers %d",
+ client->irq, firmware.id, firmware.major, firmware.minor,
+ data->max_fingers);
+
+ return 0;
+}
+
+static int __maybe_unused ili251x_i2c_suspend(struct device *dev)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+
+ if (device_may_wakeup(&client->dev))
+ enable_irq_wake(client->irq);
+
+ return 0;
+}
+
+static int __maybe_unused ili251x_i2c_resume(struct device *dev)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+
+ if (device_may_wakeup(&client->dev))
+ disable_irq_wake(client->irq);
+
+ return 0;
+}
+
+static SIMPLE_DEV_PM_OPS(ili251x_i2c_pm,
+ ili251x_i2c_suspend, ili251x_i2c_resume);
+
+static const struct i2c_device_id ili251x_i2c_id[] = {
+ { "ili251x", 0 },
+ { }
+};
+MODULE_DEVICE_TABLE(i2c, ili251x_i2c_id);
+
+static struct i2c_driver ili251x_ts_driver = {
+ .driver = {
+ .name = "ili251x_i2c",
+ .pm = &ili251x_i2c_pm,
+ },
+ .id_table = ili251x_i2c_id,
+ .probe = ili251x_i2c_probe,
+};
+
+module_i2c_driver(ili251x_ts_driver);
+
+MODULE_AUTHOR("Philipp Puschmann <pp@emlix.com>");
+MODULE_DESCRIPTION("ili251x I2C Touchscreen Driver");
+MODULE_LICENSE("GPL");
--
2.17.0
^ permalink raw reply related
* Re: [PATCH v4 1/3] resource: Use list_head to link sibling resource
From: kbuild test robot @ 2018-05-07 11:42 UTC (permalink / raw)
Cc: nicolas.pitre-QSEj5FYQhm4dnm+yROfE0A, brijesh.singh-5C7GfCeVMHo,
devicetree-u79uwXL29TY76Z2rM5mHXA, airlied-cv59FeDIM0c,
linux-pci-u79uwXL29TY76Z2rM5mHXA,
richard.weiyang-Re5JQEeQqe8AvxtiuMwx3w,
keith.busch-ral2JQCrhuEAvxtiuMwx3w,
jcmvbkbc-Re5JQEeQqe8AvxtiuMwx3w,
baiyaowei-0p4V/sDNsUmm0O/7XYngnFaTQe2KTcn/,
kys-0li6OtcxBFHby3iVrkZq2A, frowand.list-Re5JQEeQqe8AvxtiuMwx3w,
lorenzo.pieralisi-5wv7dgnIgG8, sthemmin-0li6OtcxBFHby3iVrkZq2A,
Baoquan He, linux-nvdimm-hn68Rpc1hR1g9hUCZPvPmw,
patrik.r.jakobsson-Re5JQEeQqe8AvxtiuMwx3w,
linux-input-u79uwXL29TY76Z2rM5mHXA,
gustavo-THi1TnShQwVAfugRpC6u6w, bp-l3A5Bk7waGM,
dyoung-H+wXaHxf7aLQT0dZR+AlfA, ebiederm-aS9lmoZGLiVWk0Htik3J/w,
thomas.lendacky-5C7GfCeVMHo, haiyangz-0li6OtcxBFHby3iVrkZq2A,
maarten.lankhorst-VuQAYsv1563Yd54FQh9/CA,
josh-iaAMLnmF4UmaiuxdJuQwMA, jglisse-H+wXaHxf7aLQT0dZR+AlfA,
robh+dt-DgEjT+Ai2ygdnm+yROfE0A, seanpaul-F7+t8E8rja9g9hUCZPvPmw,
bhelgaas-hpIqsD4AKlfQT0dZR+AlfA, tglx-hfZtesqFncYOwBW4kG4KsQ,
yinghai-DgEjT+Ai2ygdnm+yROfE0A,
jonathan.derrick-ral2JQCrhuEAvxtiuMwx3w,
chris-YvXeqwSYzG2sTnJN9+BGXg, monstr-pSz03upnqPeHXe+LvDLADg,
linux-parisc-u79uwXL29TY76Z2rM5mHXA,
gregkh-hQyY1W1yCW8ekmWlsbkhG0B+6BGkLq7r, dmitry.torokhov
In-Reply-To: <20180507063224.24229-2-bhe-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
Hi Baoquan,
I love your patch! Yet something to improve:
[auto build test ERROR on linus/master]
[also build test ERROR on v4.17-rc4 next-20180504]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]
url: https://github.com/0day-ci/linux/commits/Baoquan-He/resource-Use-list_head-to-link-sibling-resource/20180507-144345
config: powerpc-defconfig (attached as .config)
compiler: powerpc64-linux-gnu-gcc (Debian 7.2.0-11) 7.2.0
reproduce:
wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
chmod +x ~/bin/make.cross
# save the attached .config to linux build tree
make.cross ARCH=powerpc
All errors (new ones prefixed by >>):
arch/powerpc/kernel/pci-common.c: In function 'pci_process_bridge_OF_ranges':
>> arch/powerpc/kernel/pci-common.c:764:44: error: incompatible types when assigning to type 'struct list_head' from type 'void *'
res->parent = res->child = res->sibling = NULL;
^
arch/powerpc/kernel/pci-common.c: In function 'reparent_resources':
>> arch/powerpc/kernel/pci-common.c:1100:10: error: assignment from incompatible pointer type [-Werror=incompatible-pointer-types]
for (pp = &parent->child; (p = *pp) != NULL; pp = &p->sibling) {
^
arch/powerpc/kernel/pci-common.c:1100:50: error: assignment from incompatible pointer type [-Werror=incompatible-pointer-types]
for (pp = &parent->child; (p = *pp) != NULL; pp = &p->sibling) {
^
>> arch/powerpc/kernel/pci-common.c:1113:13: error: incompatible types when assigning to type 'struct list_head' from type 'struct resource *'
res->child = *firstpp;
^
arch/powerpc/kernel/pci-common.c:1114:15: error: incompatible types when assigning to type 'struct list_head' from type 'struct resource *'
res->sibling = *pp;
^
>> arch/powerpc/kernel/pci-common.c:1117:9: error: incompatible types when assigning to type 'struct resource *' from type 'struct list_head'
for (p = res->child; p != NULL; p = p->sibling) {
^
arch/powerpc/kernel/pci-common.c:1117:36: error: incompatible types when assigning to type 'struct resource *' from type 'struct list_head'
for (p = res->child; p != NULL; p = p->sibling) {
^
cc1: all warnings being treated as errors
vim +764 arch/powerpc/kernel/pci-common.c
13dccb9e Benjamin Herrenschmidt 2007-12-11 642
13dccb9e Benjamin Herrenschmidt 2007-12-11 643 /**
13dccb9e Benjamin Herrenschmidt 2007-12-11 644 * pci_process_bridge_OF_ranges - Parse PCI bridge resources from device tree
13dccb9e Benjamin Herrenschmidt 2007-12-11 645 * @hose: newly allocated pci_controller to be setup
13dccb9e Benjamin Herrenschmidt 2007-12-11 646 * @dev: device node of the host bridge
13dccb9e Benjamin Herrenschmidt 2007-12-11 647 * @primary: set if primary bus (32 bits only, soon to be deprecated)
13dccb9e Benjamin Herrenschmidt 2007-12-11 648 *
13dccb9e Benjamin Herrenschmidt 2007-12-11 649 * This function will parse the "ranges" property of a PCI host bridge device
13dccb9e Benjamin Herrenschmidt 2007-12-11 650 * node and setup the resource mapping of a pci controller based on its
13dccb9e Benjamin Herrenschmidt 2007-12-11 651 * content.
13dccb9e Benjamin Herrenschmidt 2007-12-11 652 *
13dccb9e Benjamin Herrenschmidt 2007-12-11 653 * Life would be boring if it wasn't for a few issues that we have to deal
13dccb9e Benjamin Herrenschmidt 2007-12-11 654 * with here:
13dccb9e Benjamin Herrenschmidt 2007-12-11 655 *
13dccb9e Benjamin Herrenschmidt 2007-12-11 656 * - We can only cope with one IO space range and up to 3 Memory space
13dccb9e Benjamin Herrenschmidt 2007-12-11 657 * ranges. However, some machines (thanks Apple !) tend to split their
13dccb9e Benjamin Herrenschmidt 2007-12-11 658 * space into lots of small contiguous ranges. So we have to coalesce.
13dccb9e Benjamin Herrenschmidt 2007-12-11 659 *
13dccb9e Benjamin Herrenschmidt 2007-12-11 660 * - Some busses have IO space not starting at 0, which causes trouble with
13dccb9e Benjamin Herrenschmidt 2007-12-11 661 * the way we do our IO resource renumbering. The code somewhat deals with
13dccb9e Benjamin Herrenschmidt 2007-12-11 662 * it for 64 bits but I would expect problems on 32 bits.
13dccb9e Benjamin Herrenschmidt 2007-12-11 663 *
13dccb9e Benjamin Herrenschmidt 2007-12-11 664 * - Some 32 bits platforms such as 4xx can have physical space larger than
13dccb9e Benjamin Herrenschmidt 2007-12-11 665 * 32 bits so we need to use 64 bits values for the parsing
13dccb9e Benjamin Herrenschmidt 2007-12-11 666 */
cad5cef6 Greg Kroah-Hartman 2012-12-21 667 void pci_process_bridge_OF_ranges(struct pci_controller *hose,
cad5cef6 Greg Kroah-Hartman 2012-12-21 668 struct device_node *dev, int primary)
13dccb9e Benjamin Herrenschmidt 2007-12-11 669 {
858957ab Kevin Hao 2013-05-16 670 int memno = 0;
13dccb9e Benjamin Herrenschmidt 2007-12-11 671 struct resource *res;
654837e8 Andrew Murray 2014-02-25 672 struct of_pci_range range;
654837e8 Andrew Murray 2014-02-25 673 struct of_pci_range_parser parser;
13dccb9e Benjamin Herrenschmidt 2007-12-11 674
b7c670d6 Rob Herring 2017-08-21 675 printk(KERN_INFO "PCI host bridge %pOF %s ranges:\n",
b7c670d6 Rob Herring 2017-08-21 676 dev, primary ? "(primary)" : "");
13dccb9e Benjamin Herrenschmidt 2007-12-11 677
654837e8 Andrew Murray 2014-02-25 678 /* Check for ranges property */
654837e8 Andrew Murray 2014-02-25 679 if (of_pci_range_parser_init(&parser, dev))
13dccb9e Benjamin Herrenschmidt 2007-12-11 680 return;
13dccb9e Benjamin Herrenschmidt 2007-12-11 681
13dccb9e Benjamin Herrenschmidt 2007-12-11 682 /* Parse it */
654837e8 Andrew Murray 2014-02-25 683 for_each_of_pci_range(&parser, &range) {
e9f82cb7 Benjamin Herrenschmidt 2008-10-14 684 /* If we failed translation or got a zero-sized region
e9f82cb7 Benjamin Herrenschmidt 2008-10-14 685 * (some FW try to feed us with non sensical zero sized regions
e9f82cb7 Benjamin Herrenschmidt 2008-10-14 686 * such as power3 which look like some kind of attempt at exposing
e9f82cb7 Benjamin Herrenschmidt 2008-10-14 687 * the VGA memory hole)
e9f82cb7 Benjamin Herrenschmidt 2008-10-14 688 */
654837e8 Andrew Murray 2014-02-25 689 if (range.cpu_addr == OF_BAD_ADDR || range.size == 0)
13dccb9e Benjamin Herrenschmidt 2007-12-11 690 continue;
13dccb9e Benjamin Herrenschmidt 2007-12-11 691
13dccb9e Benjamin Herrenschmidt 2007-12-11 692 /* Act based on address space type */
13dccb9e Benjamin Herrenschmidt 2007-12-11 693 res = NULL;
654837e8 Andrew Murray 2014-02-25 694 switch (range.flags & IORESOURCE_TYPE_BITS) {
654837e8 Andrew Murray 2014-02-25 695 case IORESOURCE_IO:
13dccb9e Benjamin Herrenschmidt 2007-12-11 696 printk(KERN_INFO
13dccb9e Benjamin Herrenschmidt 2007-12-11 697 " IO 0x%016llx..0x%016llx -> 0x%016llx\n",
654837e8 Andrew Murray 2014-02-25 698 range.cpu_addr, range.cpu_addr + range.size - 1,
654837e8 Andrew Murray 2014-02-25 699 range.pci_addr);
13dccb9e Benjamin Herrenschmidt 2007-12-11 700
13dccb9e Benjamin Herrenschmidt 2007-12-11 701 /* We support only one IO range */
13dccb9e Benjamin Herrenschmidt 2007-12-11 702 if (hose->pci_io_size) {
13dccb9e Benjamin Herrenschmidt 2007-12-11 703 printk(KERN_INFO
13dccb9e Benjamin Herrenschmidt 2007-12-11 704 " \\--> Skipped (too many) !\n");
13dccb9e Benjamin Herrenschmidt 2007-12-11 705 continue;
13dccb9e Benjamin Herrenschmidt 2007-12-11 706 }
13dccb9e Benjamin Herrenschmidt 2007-12-11 707 #ifdef CONFIG_PPC32
13dccb9e Benjamin Herrenschmidt 2007-12-11 708 /* On 32 bits, limit I/O space to 16MB */
654837e8 Andrew Murray 2014-02-25 709 if (range.size > 0x01000000)
654837e8 Andrew Murray 2014-02-25 710 range.size = 0x01000000;
13dccb9e Benjamin Herrenschmidt 2007-12-11 711
13dccb9e Benjamin Herrenschmidt 2007-12-11 712 /* 32 bits needs to map IOs here */
654837e8 Andrew Murray 2014-02-25 713 hose->io_base_virt = ioremap(range.cpu_addr,
654837e8 Andrew Murray 2014-02-25 714 range.size);
13dccb9e Benjamin Herrenschmidt 2007-12-11 715
13dccb9e Benjamin Herrenschmidt 2007-12-11 716 /* Expect trouble if pci_addr is not 0 */
13dccb9e Benjamin Herrenschmidt 2007-12-11 717 if (primary)
13dccb9e Benjamin Herrenschmidt 2007-12-11 718 isa_io_base =
13dccb9e Benjamin Herrenschmidt 2007-12-11 719 (unsigned long)hose->io_base_virt;
13dccb9e Benjamin Herrenschmidt 2007-12-11 720 #endif /* CONFIG_PPC32 */
13dccb9e Benjamin Herrenschmidt 2007-12-11 721 /* pci_io_size and io_base_phys always represent IO
13dccb9e Benjamin Herrenschmidt 2007-12-11 722 * space starting at 0 so we factor in pci_addr
13dccb9e Benjamin Herrenschmidt 2007-12-11 723 */
654837e8 Andrew Murray 2014-02-25 724 hose->pci_io_size = range.pci_addr + range.size;
654837e8 Andrew Murray 2014-02-25 725 hose->io_base_phys = range.cpu_addr - range.pci_addr;
13dccb9e Benjamin Herrenschmidt 2007-12-11 726
13dccb9e Benjamin Herrenschmidt 2007-12-11 727 /* Build resource */
13dccb9e Benjamin Herrenschmidt 2007-12-11 728 res = &hose->io_resource;
654837e8 Andrew Murray 2014-02-25 729 range.cpu_addr = range.pci_addr;
13dccb9e Benjamin Herrenschmidt 2007-12-11 730 break;
654837e8 Andrew Murray 2014-02-25 731 case IORESOURCE_MEM:
13dccb9e Benjamin Herrenschmidt 2007-12-11 732 printk(KERN_INFO
13dccb9e Benjamin Herrenschmidt 2007-12-11 733 " MEM 0x%016llx..0x%016llx -> 0x%016llx %s\n",
654837e8 Andrew Murray 2014-02-25 734 range.cpu_addr, range.cpu_addr + range.size - 1,
654837e8 Andrew Murray 2014-02-25 735 range.pci_addr,
654837e8 Andrew Murray 2014-02-25 736 (range.pci_space & 0x40000000) ?
654837e8 Andrew Murray 2014-02-25 737 "Prefetch" : "");
13dccb9e Benjamin Herrenschmidt 2007-12-11 738
13dccb9e Benjamin Herrenschmidt 2007-12-11 739 /* We support only 3 memory ranges */
13dccb9e Benjamin Herrenschmidt 2007-12-11 740 if (memno >= 3) {
13dccb9e Benjamin Herrenschmidt 2007-12-11 741 printk(KERN_INFO
13dccb9e Benjamin Herrenschmidt 2007-12-11 742 " \\--> Skipped (too many) !\n");
13dccb9e Benjamin Herrenschmidt 2007-12-11 743 continue;
13dccb9e Benjamin Herrenschmidt 2007-12-11 744 }
13dccb9e Benjamin Herrenschmidt 2007-12-11 745 /* Handles ISA memory hole space here */
654837e8 Andrew Murray 2014-02-25 746 if (range.pci_addr == 0) {
13dccb9e Benjamin Herrenschmidt 2007-12-11 747 if (primary || isa_mem_base == 0)
654837e8 Andrew Murray 2014-02-25 748 isa_mem_base = range.cpu_addr;
654837e8 Andrew Murray 2014-02-25 749 hose->isa_mem_phys = range.cpu_addr;
654837e8 Andrew Murray 2014-02-25 750 hose->isa_mem_size = range.size;
13dccb9e Benjamin Herrenschmidt 2007-12-11 751 }
13dccb9e Benjamin Herrenschmidt 2007-12-11 752
13dccb9e Benjamin Herrenschmidt 2007-12-11 753 /* Build resource */
654837e8 Andrew Murray 2014-02-25 754 hose->mem_offset[memno] = range.cpu_addr -
654837e8 Andrew Murray 2014-02-25 755 range.pci_addr;
13dccb9e Benjamin Herrenschmidt 2007-12-11 756 res = &hose->mem_resources[memno++];
13dccb9e Benjamin Herrenschmidt 2007-12-11 757 break;
13dccb9e Benjamin Herrenschmidt 2007-12-11 758 }
13dccb9e Benjamin Herrenschmidt 2007-12-11 759 if (res != NULL) {
aeba3731 Michael Ellerman 2014-10-16 760 res->name = dev->full_name;
aeba3731 Michael Ellerman 2014-10-16 761 res->flags = range.flags;
aeba3731 Michael Ellerman 2014-10-16 762 res->start = range.cpu_addr;
aeba3731 Michael Ellerman 2014-10-16 763 res->end = range.cpu_addr + range.size - 1;
aeba3731 Michael Ellerman 2014-10-16 @764 res->parent = res->child = res->sibling = NULL;
13dccb9e Benjamin Herrenschmidt 2007-12-11 765 }
13dccb9e Benjamin Herrenschmidt 2007-12-11 766 }
13dccb9e Benjamin Herrenschmidt 2007-12-11 767 }
fa462f2d Benjamin Herrenschmidt 2007-12-20 768
:::::: The code at line 764 was first introduced by commit
:::::: aeba3731b150188685225b510886f1370d8814de powerpc/pci: Fix IO space breakage after of_pci_range_to_resource() change
:::::: TO: Michael Ellerman <mpe-Gsx/Oe8HsFggBc27wqDAHg@public.gmane.org>
:::::: CC: Michael Ellerman <mpe-Gsx/Oe8HsFggBc27wqDAHg@public.gmane.org>
---
0-DAY kernel test infrastructure Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all Intel Corporation
^ permalink raw reply
* Re: [PATCH v4 5/9] iio: adc: at91-sama5d2_adc: add support for position and pressure channels
From: Eugen Hristev @ 2018-05-07 10:40 UTC (permalink / raw)
To: Alexandre Belloni
Cc: Jonathan Cameron, ludovic.desroches, linux-arm-kernel, devicetree,
linux-kernel, linux-iio, linux-input, nicolas.ferre,
dmitry.torokhov, robh
In-Reply-To: <20180507102810.GO10960@piout.net>
On 07.05.2018 13:28, Alexandre Belloni wrote:
> On 07/05/2018 09:18:39+0300, Eugen Hristev wrote:
>> On 06.05.2018 20:59, Alexandre Belloni wrote:
>>> Hi,
>>>
>>> On 06/05/2018 18:29:53+0100, Jonathan Cameron wrote:
>>>> On Mon, 30 Apr 2018 13:32:11 +0300
>>>> Eugen Hristev <eugen.hristev@microchip.com> wrote:
>>>>
>>>>> This implements the support for position and pressure for the included
>>>>> touchscreen support in the SAMA5D2 SOC ADC block.
>>>>> Two position channels are added and one for pressure.
>>>>> They can be read in raw format, or through a buffer.
>>>>> A normal use case is for a consumer driver to register a callback buffer
>>>>> for these channels.
>>>>> When the touchscreen channels are in the active scan mask,
>>>>> the driver will start the touchscreen sampling and push the data to the
>>>>> buffer.
>>>>>
>>>>> Some parts of this patch are based on initial original work by
>>>>> Mohamed Jamsheeth Hajanajubudeen and Bandaru Venkateswara Swamy
>>>>>
>>>>> Signed-off-by: Eugen Hristev <eugen.hristev@microchip.com>
>>>> Looks good to me now.
>>>>
>>>> I'm assuming that once Dmitry and others are happy, I'll take the
>>>> series through the IIO tree. Will reply to the cover letter if the
>>>> rest of the patches look good to me to let everyone know that without
>>>> having to catch this comment down in here!
>>>>
>>>
>>> I'm planning to take both DT patches through the at91 tree once you take
>>> the DT bindings patches.
>>
>> Please take into consideration that those DT patches do not build
>> stand-alone, they depend on
>> [PATCH v4 7/9] dt-bindings: iio: adc: at91-sama5d2_adc: add channel specific
>> consumer info
>>
>> (the DT patches add an include statement of a file which is created in this
>> patch).
>>
>
> So the proper way is to actually have the values in the dt instead of
> the define and then patch it on the next version of the kernel.
>
> Or we take the dts patches on the next version.
Taking the DTS patches on the next version is fine for me.
Thanks
>
^ permalink raw reply
* Re: [PATCH v4 5/9] iio: adc: at91-sama5d2_adc: add support for position and pressure channels
From: Alexandre Belloni @ 2018-05-07 10:28 UTC (permalink / raw)
To: Eugen Hristev
Cc: Jonathan Cameron, ludovic.desroches, linux-arm-kernel, devicetree,
linux-kernel, linux-iio, linux-input, nicolas.ferre,
dmitry.torokhov, robh
In-Reply-To: <eaeced9e-390f-0eea-0466-66c789bacdd6@microchip.com>
On 07/05/2018 09:18:39+0300, Eugen Hristev wrote:
> On 06.05.2018 20:59, Alexandre Belloni wrote:
> > Hi,
> >
> > On 06/05/2018 18:29:53+0100, Jonathan Cameron wrote:
> > > On Mon, 30 Apr 2018 13:32:11 +0300
> > > Eugen Hristev <eugen.hristev@microchip.com> wrote:
> > >
> > > > This implements the support for position and pressure for the included
> > > > touchscreen support in the SAMA5D2 SOC ADC block.
> > > > Two position channels are added and one for pressure.
> > > > They can be read in raw format, or through a buffer.
> > > > A normal use case is for a consumer driver to register a callback buffer
> > > > for these channels.
> > > > When the touchscreen channels are in the active scan mask,
> > > > the driver will start the touchscreen sampling and push the data to the
> > > > buffer.
> > > >
> > > > Some parts of this patch are based on initial original work by
> > > > Mohamed Jamsheeth Hajanajubudeen and Bandaru Venkateswara Swamy
> > > >
> > > > Signed-off-by: Eugen Hristev <eugen.hristev@microchip.com>
> > > Looks good to me now.
> > >
> > > I'm assuming that once Dmitry and others are happy, I'll take the
> > > series through the IIO tree. Will reply to the cover letter if the
> > > rest of the patches look good to me to let everyone know that without
> > > having to catch this comment down in here!
> > >
> >
> > I'm planning to take both DT patches through the at91 tree once you take
> > the DT bindings patches.
>
> Please take into consideration that those DT patches do not build
> stand-alone, they depend on
> [PATCH v4 7/9] dt-bindings: iio: adc: at91-sama5d2_adc: add channel specific
> consumer info
>
> (the DT patches add an include statement of a file which is created in this
> patch).
>
So the proper way is to actually have the values in the dt instead of
the define and then patch it on the next version of the kernel.
Or we take the dts patches on the next version.
--
Alexandre Belloni, Bootlin (formerly Free Electrons)
Embedded Linux and Kernel engineering
https://bootlin.com
^ permalink raw reply
* Re: Dell docking station & Dell Embedded Controller & PS/2 devices
From: Pali Rohár @ 2018-05-07 8:44 UTC (permalink / raw)
To: Dmitry Torokhov; +Cc: Mario.Limonciello, linux-input, linux-kernel
In-Reply-To: <20180506134733.zttaitnf6ej4tith@pali>
[-- Attachment #1: Type: text/plain, Size: 7197 bytes --]
On Sunday 06 May 2018 15:47:33 Pali Rohár wrote:
> On Thursday 01 February 2018 11:29:45 Dmitry Torokhov wrote:
> > Hi Pali,
> >
> > On Wed, Jan 24, 2018 at 11:41:21AM +0100, Pali Rohár wrote:
> > > Hi Dmitry!
> > >
> > > I'm observing a problem with internal touchpad (handled by psmouse.ko)
> > > on Dell laptops connected to Dell E docking station. When I connect
> > > external PS/2 keyboard to docking station then internal laptop touchpad
> > > switch from multitouch absolute mode to relative bare PS/2 mode.
> > >
> > > And because ALPS driver in psmouse.ko is capable to process interleaved
> > > bare 3-byte PS/2 packets with 6-byte ALPS packets (which handles
> > > trackstick data on some ALPS models), ALPS driver does not show any
> > > message about this "downgrade" from multitouch to bare mode. And
> > > continue working in bare mode.
> > >
> > > When I rmmod psmouse and modprobe it again, then touchpad switch back to
> > > multitouch mode.
> > >
> > > Mario told me that Dell Embedded Controller, which handle internal
> > > keyboard, internal touchpad and external PS/2 keyboard, automatically
> > > send RESET command to *all* those devices when external PS/2 keyboard is
> > > connected. Therefore this is reason why touchpad downgrade to to bare
> > > mode. And according to Mario, host system should issue vendor specific
> > > PS/2 commands to re-initialize all PS/2 devices when this situation
> > > happen. Mario also told me that Windows is doing this action.
> >
> > Yeah, I remember fun with Inspiron 8100 - when you dock it it woudl
> > silently switch Synaptics touchpad into standard mode and it would not
> > come back as Synaptics until you disconnect. And there was no
> > notification to the kernel as far as I could tell.
> >
> > It could be that we need to monitor dock events and then kick reconnect
> > of serio port, either from userspace via udev (I think that would be
> > preferred), or in kernel.
> >
> > >
> > > Every time when I connect external PS/2 keyboard to dock I see this
> > > message in dmesg:
> > >
> > > Spurious ACK... Some program might be trying to access hardware directly.
> > >
> > > I see it also every time when I dock laptop into docking station (to
> > > which is keyboard already connected). And it happens also when I connect
> > > external PS/2 mouse to dock.
> > >
> > > Dmitry, how to handle this situation to re-initialize psmouse.ko when
> > > external PS/2 device is connected to Dell E docking station? According
> > > to Mario, this is how Dell Embedded Controller is designed and suppose
> > > how OS should work with it.
> > >
> > > Manually rmmoding and modprobing for every docking/undocking laptop is
> > > not ideal solution.
> > >
> > > Could it be possible to use that Spurious ATKBD_RET_ACK from atkbd.c be
> > > handled on Dell systems (probably via DMI) as an event to reset and
> > > reinitialize all PS/2 devices?
> >
> > So we need to figure out what exactly we are getting from the docking
> > station in this case. We do try to handle the new device 0xaa 0x00
> > announcements:
> >
> > /* Check if this is a new device announcement (0xAA 0x00) */
> > if (unlikely(psmouse->packet[0] == PSMOUSE_RET_BAT && psmouse->pktcnt <= 2)) {
> > if (psmouse->pktcnt == 1) {
> > psmouse->last = jiffies;
> > goto out;
> > }
> >
> > if (psmouse->packet[1] == PSMOUSE_RET_ID ||
> > (psmouse->protocol->type == PSMOUSE_HGPK &&
> > psmouse->packet[1] == PSMOUSE_RET_BAT)) {
> > __psmouse_set_state(psmouse, PSMOUSE_IGNORE);
> > serio_reconnect(serio);
> > goto out;
> > }
> >
> > ...
> >
> > I am not sure where the "spurious ACK comes from". Can you enable i8042
> > debug before trying to dock and capture the data stream from the mouse?
> >
> > Thanks.
> >
>
> Hi Dmitry!
>
> I enabled unmask_kbd_data and debug and here is output from dmesg.
>
> echo Y > /sys/module/i8042/parameters/debug
> echo Y > /sys/module/i8042/parameters/unmask_kbd_data
>
> PS/2 keyboard is already connected in dock and laptop was just docked:
>
> [25461.552314] i8042: [6365474] fa <- i8042 (interrupt, 0, 1)
> [25461.552319] atkbd serio0: Spurious ACK on isa0060/serio0. Some program might be trying to access hardware directly.
> [25462.707296] i8042: [6365763] ed -> i8042 (kbd-data)
> [25462.851289] i8042: [6365799] fa <- i8042 (interrupt, 0, 1)
> [25462.851303] i8042: [6365799] 00 -> i8042 (kbd-data)
> [25462.858437] i8042: [6365801] fa <- i8042 (interrupt, 0, 1)
> [25462.869512] i8042: [6365804] fa <- i8042 (interrupt, 0, 1)
> [25462.869517] atkbd serio0: Spurious ACK on isa0060/serio0. Some program might be trying to access hardware directly.
> [25463.670515] i8042: [6366004] ed -> i8042 (kbd-data)
> [25463.670647] i8042: [6366004] fa <- i8042 (interrupt, 0, 1)
> [25463.670655] i8042: [6366004] 02 -> i8042 (kbd-data)
> [25463.676769] i8042: [6366005] fa <- i8042 (interrupt, 0, 1)
>
>
> Laptop is docked and PS/2 keyboard was just connected:
>
> [26571.014368] i8042: [6642848] fa <- i8042 (interrupt, 0, 1)
> [26571.014380] atkbd serio0: Spurious ACK on isa0060/serio0. Some program might be trying to access hardware directly.
>
>
> In both cases there is no events from touchpad, only from keyboard. So
> Dell EC silently reset PS/2 touchpad when PS/2 keyboard is attached.
>
> So I think we should capture 0xFA and on Dell machines we should
> reinitialize PS/2 drivers. As there is really nothing more then 0xFA.
Info about PS/2 mouse:
In case I have laptop already docked and just connect PS/2 mouse there
is absolutely no i8042 event.
To check that mouse is worked I clicked button and then in dmesg
appeared:
[ 3945.481403] i8042: [986322] 09 <- i8042 (interrupt, 1, 12)
[ 3945.482486] i8042: [986323] 00 <- i8042 (interrupt, 1, 12)
[ 3945.483667] i8042: [986323] 00 <- i8042 (interrupt, 1, 12)
[ 3945.483917] input: PS/2 ALPS Mouse as /devices/platform/i8042/serio1/input/input36
[ 3945.594926] i8042: [986351] 08 <- i8042 (interrupt, 1, 12)
[ 3945.596062] i8042: [986351] 00 <- i8042 (interrupt, 1, 12)
[ 3945.597203] i8042: [986351] 00 <- i8042 (interrupt, 1, 12)
So we have no way to detect when external PS/2 mouse was connected to
dock. But ALPS driver can deal with it and process these mouse events.
And when I have already connected PS/2 mouse to the dock and I'm just
putting laptop into dock, then I get following events:
[ 4336.481381] i8042: [1084079] fa <- i8042 (interrupt, 0, 1)
[ 4336.481388] atkbd serio0: Spurious ACK on isa0060/serio0. Some program might be trying to access hardware directly.
[ 4337.653275] i8042: [1084372] ed -> i8042 (kbd-data)
[ 4337.949198] i8042: [1084446] fa <- i8042 (interrupt, 0, 1)
[ 4337.949202] atkbd serio0: Spurious ACK on isa0060/serio0. Some program might be trying to access hardware directly.
[ 4338.623167] i8042: [1084615] ed -> i8042 (kbd-data)
So again, no event from mouse, just from keyboard.
Note that in these tests I have disconnected my PS/2 keyboard from
dock.
--
Pali Rohár
pali.rohar@gmail.com
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 195 bytes --]
^ permalink raw reply
* Re: [BUG] i2c-hid: ELAN Touchpad does not work on ASUS X580GD
From: Chris Chiu @ 2018-05-07 8:07 UTC (permalink / raw)
To: Jian-Hong Pan
Cc: Jiri Kosina, Benjamin Tissoires, Jani Nikula, Hans de Goede,
Dmitry Torokhov, Adrian Salido, Jason Gerecke, linux-input,
Jarkko Nikula, Andy Shevchenko, Mika Westerberg, Wolfram Sang,
linux-i2c, Linux Kernel, Daniel Drake, Linux Upstreaming Team
In-Reply-To: <CAPpJ_ed-JPOzQPtyCdH4_C7dzEeM3fznus8XDuaojaiM_4nFpw@mail.gmail.com>
On Fri, May 4, 2018 at 2:55 PM, Jian-Hong Pan <jian-hong@endlessm.com> wrote:
> Hi,
>
> We have an ASUS X580GD (Intel(R) Core(TM) i5-8300H CPU @ 2.30GHz) laptop
> equipped with ELAN1200 touchpad which does not work totally, but the
> external mouse works fine.
>
> We have checked the input devices by "cat /proc/bus/input/devices", and
> the touchpad does not appear in the list.
>
> According to ASUS' information, the ELAN touchpad is attached to the i2c
> bus of the system. Then, we do find the corresponding error messages in
> dmesg:
>
> with kernel 4.15.15
> [ 10.290192] i2c_hid i2c-ELAN1200:00: i2c-ELAN1200:00 supply vdd not
> found, using dummy regulator
> [ 10.290818] i2c_hid i2c-ELAN1200:00: can't add hid device: -22
> [ 10.290852] i2c_hid: probe of i2c-ELAN1200:00 failed with error -22
>
> with kernel 4.16.7
> [ 10.638729] i2c_hid i2c-ELAN1200:00: i2c-ELAN1200:00 supply vdd not
> found, using dummy regulator
> [ 10.639304] i2c_hid i2c-ELAN1200:00: unexpected HID descriptor
> bcdVersion (0xff00)
>
> Then check the i2c bus and get:
> i2c-7
> name: Synopsys DesignWare I2C adapter
> firmware_path: \_SB_.PCI0.I2C1
> driver: i2c_designware
>
> i2c-ELAN1200:00
> name: ELAN1200:00
> firmware_path: \_SB_.PCI0.I2C1.ETPD
>
> Besides, according to ASUS's input, they observed that after entering
> the OS, the frequency of SCL is too fast (about 600kHz) and the SCL High
> time is around 450ns, not following I2C spec which is 0.6us.
> https://pasteboard.co/HjzSWXd.png
>
> so, we get the kernel 4.17-rc3 and add some debug message:
>
> diff --git a/drivers/i2c/busses/i2c-designware-master.c
> b/drivers/i2c/busses/i2c-designware-master.c
> index fd36c39ddf4e..bbe76e033133 100644
> --- a/drivers/i2c/busses/i2c-designware-master.c
> +++ b/drivers/i2c/busses/i2c-designware-master.c
> @@ -88,10 +88,12 @@ static int i2c_dw_init_master(struct dw_i2c_dev *dev)
> sda_falling_time = dev->sda_falling_time ?: 300; /* ns */
> scl_falling_time = dev->scl_falling_time ?: 300; /* ns */
>
> +printk("%s sda falling %u scl falling %u\n", __func__,
> sda_falling_time, scl_falling_time);
> /* Set SCL timing parameters for standard-mode */
> if (dev->ss_hcnt && dev->ss_lcnt) {
> hcnt = dev->ss_hcnt;
> lcnt = dev->ss_lcnt;
> +printk("%s ss set hcnt %u lcnt %u\n", __func__, hcnt, lcnt);
> } else {
> hcnt = i2c_dw_scl_hcnt(i2c_dw_clk_rate(dev),
> 4000, /* tHD;STA = tHIGH = 4.0 us */
> @@ -102,10 +104,11 @@ static int i2c_dw_init_master(struct dw_i2c_dev *dev)
> 4700, /* tLOW = 4.7 us */
> scl_falling_time,
> 0); /* No offset */
> +printk("%s ss no hcnt %u lcnt %u\n", __func__, hcnt, lcnt);
> }
> dw_writel(dev, hcnt, DW_IC_SS_SCL_HCNT);
> dw_writel(dev, lcnt, DW_IC_SS_SCL_LCNT);
> - dev_dbg(dev->dev, "Standard-mode HCNT:LCNT = %d:%d\n", hcnt, lcnt);
> + dev_err(dev->dev, "Standard-mode HCNT:LCNT = %d:%d\n", hcnt, lcnt);
>
> /* Set SCL timing parameters for fast-mode or fast-mode plus */
> if ((dev->clk_freq == 1000000) && dev->fp_hcnt && dev->fp_lcnt) {
> @@ -114,6 +117,7 @@ static int i2c_dw_init_master(struct dw_i2c_dev *dev)
> } else if (dev->fs_hcnt && dev->fs_lcnt) {
> hcnt = dev->fs_hcnt;
> lcnt = dev->fs_lcnt;
> +printk("%s fs set hcnt %u lcnt %u\n", __func__, hcnt, lcnt);
> } else {
> hcnt = i2c_dw_scl_hcnt(i2c_dw_clk_rate(dev),
> 600, /* tHD;STA = tHIGH = 0.6 us */
> @@ -124,10 +128,11 @@ static int i2c_dw_init_master(struct dw_i2c_dev *dev)
> 1300, /* tLOW = 1.3 us */
> scl_falling_time,
> 0); /* No offset */
> +printk("%s fs no hcnt %u lcnt %u\n", __func__, hcnt, lcnt);
> }
> dw_writel(dev, hcnt, DW_IC_FS_SCL_HCNT);
> dw_writel(dev, lcnt, DW_IC_FS_SCL_LCNT);
> - dev_dbg(dev->dev, "Fast-mode HCNT:LCNT = %d:%d\n", hcnt, lcnt);
> + dev_err(dev->dev, "Fast-mode HCNT:LCNT = %d:%d\n", hcnt, lcnt);
>
> if ((dev->master_cfg & DW_IC_CON_SPEED_MASK) ==
> DW_IC_CON_SPEED_HIGH) {
> @@ -141,7 +146,7 @@ static int i2c_dw_init_master(struct dw_i2c_dev *dev)
> lcnt = dev->hs_lcnt;
> dw_writel(dev, hcnt, DW_IC_HS_SCL_HCNT);
> dw_writel(dev, lcnt, DW_IC_HS_SCL_LCNT);
> - dev_dbg(dev->dev, "HighSpeed-mode HCNT:LCNT = %d:%d\n",
> + dev_err(dev->dev, "HighSpeed-mode HCNT:LCNT = %d:%d\n",
> hcnt, lcnt);
> }
> }
> @@ -152,6 +157,7 @@ static int i2c_dw_init_master(struct dw_i2c_dev *dev)
> if (!dev->sda_hold_time) {
> /* Keep previous hold time setting if no one set it */
> dev->sda_hold_time = dw_readl(dev, DW_IC_SDA_HOLD);
> +printk("%s no sda hold time and read from reg %u\n", __func__,
> dev->sda_hold_time);
> }
> /*
> * Workaround for avoiding TX arbitration lost in case I2C
> @@ -163,7 +169,9 @@ static int i2c_dw_init_master(struct dw_i2c_dev *dev)
> if (!(dev->sda_hold_time & DW_IC_SDA_HOLD_RX_MASK))
> dev->sda_hold_time |= 1 << DW_IC_SDA_HOLD_RX_SHIFT;
> dw_writel(dev, dev->sda_hold_time, DW_IC_SDA_HOLD);
> +printk("%s new ver sda hold time %u\n", __func__, dev->sda_hold_time);
> } else if (dev->sda_hold_time) {
> +printk("%s old sda hold time %u\n", __func__, dev->sda_hold_time);
> dev_warn(dev->dev,
> "Hardware too old to adjust SDA hold time.\n");
> }
> diff --git a/drivers/i2c/busses/i2c-designware-pcidrv.c
> b/drivers/i2c/busses/i2c-designware-pcidrv.c
> index 86e1bd0b82e9..55ac4a6d31da 100644
> --- a/drivers/i2c/busses/i2c-designware-pcidrv.c
> +++ b/drivers/i2c/busses/i2c-designware-pcidrv.c
> @@ -277,6 +277,7 @@ static int i2c_dw_pci_probe(struct pci_dev *pdev,
> dev->tx_fifo_depth = controller->tx_fifo_depth;
> dev->rx_fifo_depth = controller->rx_fifo_depth;
>
> +printk("%s have scl sda config %s\n", __func__,
> controller->scl_sda_cfg?"true":"false");
> adap = &dev->adapter;
> adap->owner = THIS_MODULE;
> adap->class = 0;
> diff --git a/drivers/i2c/busses/i2c-designware-platdrv.c
> b/drivers/i2c/busses/i2c-designware-platdrv.c
> index 5660daf6c92e..90b443c6b472 100644
> --- a/drivers/i2c/busses/i2c-designware-platdrv.c
> +++ b/drivers/i2c/busses/i2c-designware-platdrv.c
> @@ -115,6 +115,7 @@ static int dw_i2c_acpi_configure(struct
> platform_device *pdev)
> dw_i2c_acpi_params(pdev, "HSCN", &dev->hs_hcnt, &dev->hs_lcnt, &hs_ht);
> dw_i2c_acpi_params(pdev, "FMCN", &dev->fs_hcnt, &dev->fs_lcnt, &fs_ht);
>
> +printk("%s: freq %u and ss_ht %u fp_ht %u hs_ht %u fs_ht %u\n",
> __func__, dev->clk_freq, ss_ht, fp_ht, hs_ht, fs_ht);
> switch (dev->clk_freq) {
> case 100000:
> dev->sda_hold_time = ss_ht;
> @@ -310,6 +311,7 @@ static int dw_i2c_plat_probe(struct platform_device *pdev)
> if (has_acpi_companion(&pdev->dev))
> dw_i2c_acpi_configure(pdev);
>
> +printk("%s clk freq %u\n", __func__, dev->clk_freq);
> /*
> * Only standard mode at 100kHz, fast mode at 400kHz,
> * fast mode plus at 1MHz and high speed mode at 3.4MHz are supported.
> @@ -333,6 +335,9 @@ static int dw_i2c_plat_probe(struct platform_device *pdev)
> i2c_dw_configure_master(dev);
>
> dev->clk = devm_clk_get(&pdev->dev, NULL);
> +printk("%s parent clk freq %u\n", __func__, clk_get_rate(dev->clk));
> +if (dev->sda_hold_time)
> + printk("sda hold time %u\n", dev->sda_hold_time);
> if (!i2c_dw_prepare_clk(dev, true)) {
> dev->get_clk_rate_khz = i2c_dw_get_clk_rate_khz;
>
> Rebuild kernel, reboot and check dmesg again:
> (the touchpad still not work)
>
> [ 5.004195] acpi PNP0C14:03: duplicate WMI GUID
> 05901221-D566-11D1-B2F0-00A0C9062910 (first instance was on
> PNP0C14:02)
> [ 5.004250] acpi PNP0C14:04: duplicate WMI GUID
> 05901221-D566-11D1-B2F0-00A0C9062910 (first instance was on
> PNP0C14:02)
> [ 5.022086] intel-lpss 0000:00:15.0: enabling device (0000 -> 0002)
> [ 5.056084] idma64 idma64.0: Found Intel integrated DMA 64-bit
> [ 5.057994] dw_i2c_acpi_configure: freq 400000 and ss_ht 0 fp_ht 0
> hs_ht 0 fs_ht 0
> [ 5.057995] dw_i2c_plat_probe clk freq 400000
> [ 5.058001] dw_i2c_plat_probe parent clk freq 120000000
> [ 5.058025] i2c_dw_init_master sda falling 300 scl falling 300
> [ 5.058026] i2c_dw_init_master ss no hcnt 513 lcnt 599
> [ 5.058028] i2c_designware i2c_designware.0: Standard-mode
> HCNT:LCNT = 513:599
> [ 5.058028] i2c_dw_init_master fs no hcnt 105 lcnt 191
> [ 5.058029] i2c_designware i2c_designware.0: Fast-mode HCNT:LCNT = 105:191
> [ 5.058033] i2c_dw_init_master new ver sda hold time 28
> [ 5.060998] Adding 7776500k swap on /dev/zram0. Priority:-2
> extents:1 across:7776500k SSFS
> [ 5.091397] cfg80211: Loading compiled-in X.509 certificates for
> regulatory database
> [ 5.094840] cfg80211: Loaded X.509 cert 'sforshee: 00b28ddf47aef9cea7'
> [ 5.097905] RAPL PMU: API unit is 2^-32 Joules, 5 fixed counters,
> 655360 ms ovfl timer
> [ 5.097907] RAPL PMU: hw unit of domain pp0-core 2^-14 Joules
> [ 5.097907] RAPL PMU: hw unit of domain package 2^-14 Joules
> [ 5.097908] RAPL PMU: hw unit of domain dram 2^-14 Joules
> [ 5.097908] RAPL PMU: hw unit of domain pp1-gpu 2^-14 Joules
> [ 5.097909] RAPL PMU: hw unit of domain psys 2^-14 Joules
> [ 5.098206] intel-lpss 0000:00:15.1: enabling device (0000 -> 0002)
> [ 5.098570] idma64 idma64.1: Found Intel integrated DMA 64-bit
> [ 5.098676] media: Linux media interface: v0.10
> [ 5.100423] dw_i2c_acpi_configure: freq 400000 and ss_ht 0 fp_ht 0
> hs_ht 0 fs_ht 0
> [ 5.100424] dw_i2c_plat_probe clk freq 400000
> [ 5.100427] dw_i2c_plat_probe parent clk freq 120000000
> [ 5.100435] i2c_dw_init_master sda falling 300 scl falling 300
> [ 5.100436] i2c_dw_init_master ss no hcnt 513 lcnt 599
> [ 5.100437] i2c_designware i2c_designware.1: Standard-mode
> HCNT:LCNT = 513:599
> [ 5.100438] i2c_dw_init_master fs no hcnt 105 lcnt 191
> [ 5.100439] i2c_designware i2c_designware.1: Fast-mode HCNT:LCNT = 105:191
> [ 5.100443] i2c_dw_init_master new ver sda hold time 28
> [ 5.102504] platform regulatory.0: Direct firmware load for
> regulatory.db failed with error -2
> [ 5.102508] cfg80211: failed to load regulatory.db
>
> According to the information "dw_i2c_plat_probe clk freq 400000" in the
> dmesg, the system has the right SCL clock with 400K Hz. But why it is
> apparently not taking effect?
>
> Thnaks,
> Jian-Hong Pan
Some update, we can make the touchpad work by simply modifying the
clk_rate of spt_i2c_info from 120000000 to 133000000 in intel-lpss-pci.c for
specific PCI ID 8086:a368 ~ a36a (CoffeeLake). Is the clock setting different
for the CoffeeLake series?
^ permalink raw reply
* [PATCH v4 3/3] kexec_file: Load kernel at top of system RAM if required
From: Baoquan He @ 2018-05-07 6:32 UTC (permalink / raw)
To: linux-kernel-u79uwXL29TY76Z2rM5mHXA,
akpm-de/tnXTf+JLsfHDXvbKv3WD2FQJk+8+b,
robh+dt-DgEjT+Ai2ygdnm+yROfE0A,
dan.j.williams-ral2JQCrhuEAvxtiuMwx3w,
nicolas.pitre-QSEj5FYQhm4dnm+yROfE0A, josh-iaAMLnmF4UmaiuxdJuQwMA,
fengguang.wu-ral2JQCrhuEAvxtiuMwx3w, bp-l3A5Bk7waGM
Cc: brijesh.singh-5C7GfCeVMHo, devicetree-u79uwXL29TY76Z2rM5mHXA,
airlied-cv59FeDIM0c, linux-pci-u79uwXL29TY76Z2rM5mHXA,
richard.weiyang-Re5JQEeQqe8AvxtiuMwx3w,
keith.busch-ral2JQCrhuEAvxtiuMwx3w,
jcmvbkbc-Re5JQEeQqe8AvxtiuMwx3w,
baiyaowei-0p4V/sDNsUmm0O/7XYngnFaTQe2KTcn/,
kys-0li6OtcxBFHby3iVrkZq2A, frowand.list-Re5JQEeQqe8AvxtiuMwx3w,
lorenzo.pieralisi-5wv7dgnIgG8, sthemmin-0li6OtcxBFHby3iVrkZq2A,
Baoquan He, linux-nvdimm-hn68Rpc1hR1g9hUCZPvPmw,
patrik.r.jakobsson-Re5JQEeQqe8AvxtiuMwx3w,
linux-input-u79uwXL29TY76Z2rM5mHXA,
gustavo-THi1TnShQwVAfugRpC6u6w, dyoung-H+wXaHxf7aLQT0dZR+AlfA,
thomas.lendacky-5C7GfCeVMHo, haiyangz-0li6OtcxBFHby3iVrkZq2A,
maarten.lankhorst-VuQAYsv1563Yd54FQh9/CA,
jglisse-H+wXaHxf7aLQT0dZR+AlfA, seanpaul-F7+t8E8rja9g9hUCZPvPmw,
bhelgaas-hpIqsD4AKlfQT0dZR+AlfA, tglx-hfZtesqFncYOwBW4kG4KsQ,
yinghai-DgEjT+Ai2ygdnm+yROfE0A,
jonathan.derrick-ral2JQCrhuEAvxtiuMwx3w,
chris-YvXeqwSYzG2sTnJN9+BGXg, monstr-pSz03upnqPeHXe+LvDLADg,
linux-parisc-u79uwXL29TY76Z2rM5mHXA,
gregkh-hQyY1W1yCW8ekmWlsbkhG0B+6BGkLq7r,
dmitry.torokhov-Re5JQEeQqe8AvxtiuMwx3w,
kexec-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
ebiederm-aS9lmoZGLiVWk0Htik3J/w,
devel-tBiZLqfeLfOHmIFyCCdPziST3g8Odh+X,
davem-fT/PcQaiUtIeIZ0/mPfg9Q
In-Reply-To: <20180507063224.24229-1-bhe-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
For kexec_file loading, if kexec_buf.top_down is 'true', the memory which
is used to load kernel/initrd/purgatory is supposed to be allocated from
top to down. This is what we have been doing all along in the old kexec
loading interface and the kexec loading is still default setting in some
distributions. However, the current kexec_file loading interface doesn't
do likt this. The function arch_kexec_walk_mem() it calls ignores checking
kexec_buf.top_down, but calls walk_system_ram_res() directly to go through
all resources of System RAM from bottom to up, to try to find memory region
which can contain the specific kexec buffer, then call locate_mem_hole_callback()
to allocate memory in that found memory region from top to down. This brings
confusion especially when KASLR is widely supported , users have to make clear
why kexec/kdump kernel loading position is different between these two
interfaces in order to exclude unnecessary noises. Hence these two interfaces
need be unified on behaviour.
Here add checking if kexec_buf.top_down is 'true' in arch_kexec_walk_mem(),
if yes, call the newly added walk_system_ram_res_rev() to find memory region
from top to down to load kernel.
Signed-off-by: Baoquan He <bhe-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
Cc: Eric Biederman <ebiederm-aS9lmoZGLiVWk0Htik3J/w@public.gmane.org>
Cc: Vivek Goyal <vgoyal-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
Cc: Dave Young <dyoung-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
Cc: Andrew Morton <akpm-de/tnXTf+JLsfHDXvbKv3WD2FQJk+8+b@public.gmane.org>
Cc: Yinghai Lu <yinghai-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
Cc: kexec-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org
---
kernel/kexec_file.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/kernel/kexec_file.c b/kernel/kexec_file.c
index 75d8e7cf040e..7a66d9d5a534 100644
--- a/kernel/kexec_file.c
+++ b/kernel/kexec_file.c
@@ -518,6 +518,8 @@ int __weak arch_kexec_walk_mem(struct kexec_buf *kbuf,
IORESOURCE_SYSTEM_RAM | IORESOURCE_BUSY,
crashk_res.start, crashk_res.end,
kbuf, func);
+ else if (kbuf->top_down)
+ return walk_system_ram_res_rev(0, ULONG_MAX, kbuf, func);
else
return walk_system_ram_res(0, ULONG_MAX, kbuf, func);
}
--
2.13.6
^ permalink raw reply related
* [PATCH v4 2/3] resource: add walk_system_ram_res_rev()
From: Baoquan He @ 2018-05-07 6:32 UTC (permalink / raw)
To: linux-kernel-u79uwXL29TY76Z2rM5mHXA,
akpm-de/tnXTf+JLsfHDXvbKv3WD2FQJk+8+b,
robh+dt-DgEjT+Ai2ygdnm+yROfE0A,
dan.j.williams-ral2JQCrhuEAvxtiuMwx3w,
nicolas.pitre-QSEj5FYQhm4dnm+yROfE0A, josh-iaAMLnmF4UmaiuxdJuQwMA,
fengguang.wu-ral2JQCrhuEAvxtiuMwx3w, bp-l3A5Bk7waGM
Cc: brijesh.singh-5C7GfCeVMHo, devicetree-u79uwXL29TY76Z2rM5mHXA,
airlied-cv59FeDIM0c, linux-pci-u79uwXL29TY76Z2rM5mHXA,
richard.weiyang-Re5JQEeQqe8AvxtiuMwx3w,
keith.busch-ral2JQCrhuEAvxtiuMwx3w,
jcmvbkbc-Re5JQEeQqe8AvxtiuMwx3w,
baiyaowei-0p4V/sDNsUmm0O/7XYngnFaTQe2KTcn/,
kys-0li6OtcxBFHby3iVrkZq2A, frowand.list-Re5JQEeQqe8AvxtiuMwx3w,
lorenzo.pieralisi-5wv7dgnIgG8, sthemmin-0li6OtcxBFHby3iVrkZq2A,
Baoquan He, linux-nvdimm-hn68Rpc1hR1g9hUCZPvPmw,
patrik.r.jakobsson-Re5JQEeQqe8AvxtiuMwx3w,
linux-input-u79uwXL29TY76Z2rM5mHXA,
gustavo-THi1TnShQwVAfugRpC6u6w, dyoung-H+wXaHxf7aLQT0dZR+AlfA,
thomas.lendacky-5C7GfCeVMHo, haiyangz-0li6OtcxBFHby3iVrkZq2A,
maarten.lankhorst-VuQAYsv1563Yd54FQh9/CA,
jglisse-H+wXaHxf7aLQT0dZR+AlfA, seanpaul-F7+t8E8rja9g9hUCZPvPmw,
bhelgaas-hpIqsD4AKlfQT0dZR+AlfA, tglx-hfZtesqFncYOwBW4kG4KsQ,
yinghai-DgEjT+Ai2ygdnm+yROfE0A,
jonathan.derrick-ral2JQCrhuEAvxtiuMwx3w,
chris-YvXeqwSYzG2sTnJN9+BGXg, monstr-pSz03upnqPeHXe+LvDLADg,
linux-parisc-u79uwXL29TY76Z2rM5mHXA,
gregkh-hQyY1W1yCW8ekmWlsbkhG0B+6BGkLq7r,
dmitry.torokhov-Re5JQEeQqe8AvxtiuMwx3w,
kexec-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
ebiederm-aS9lmoZGLiVWk0Htik3J/w,
devel-tBiZLqfeLfOHmIFyCCdPziST3g8Odh+X,
davem-fT/PcQaiUtIeIZ0/mPfg9Q
In-Reply-To: <20180507063224.24229-1-bhe-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
This function, being a variant of walk_system_ram_res() introduced in
commit 8c86e70acead ("resource: provide new functions to walk through
resources"), walks through a list of all the resources of System RAM
in reversed order, i.e., from higher to lower.
It will be used in kexec_file code.
Signed-off-by: Baoquan He <bhe@redhat.com>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Brijesh Singh <brijesh.singh@amd.com>
Cc: "Jérôme Glisse" <jglisse@redhat.com>
Cc: Borislav Petkov <bp@suse.de>
Cc: Tom Lendacky <thomas.lendacky@amd.com>
Cc: Wei Yang <richard.weiyang@gmail.com>
---
include/linux/ioport.h | 3 +++
kernel/resource.c | 40 ++++++++++++++++++++++++++++++++++++++++
2 files changed, 43 insertions(+)
diff --git a/include/linux/ioport.h b/include/linux/ioport.h
index 225d13d3500a..5f2cfb460a14 100644
--- a/include/linux/ioport.h
+++ b/include/linux/ioport.h
@@ -278,6 +278,9 @@ extern int
walk_system_ram_res(u64 start, u64 end, void *arg,
int (*func)(struct resource *, void *));
extern int
+walk_system_ram_res_rev(u64 start, u64 end, void *arg,
+ int (*func)(struct resource *, void *));
+extern int
walk_iomem_res_desc(unsigned long desc, unsigned long flags, u64 start, u64 end,
void *arg, int (*func)(struct resource *, void *));
diff --git a/kernel/resource.c b/kernel/resource.c
index 4f560991c130..6c519b06e3d6 100644
--- a/kernel/resource.c
+++ b/kernel/resource.c
@@ -23,6 +23,8 @@
#include <linux/pfn.h>
#include <linux/mm.h>
#include <linux/resource_ext.h>
+#include <linux/string.h>
+#include <linux/vmalloc.h>
#include <asm/io.h>
@@ -475,6 +477,44 @@ int walk_system_ram_res(u64 start, u64 end, void *arg,
}
/*
+ * This function, being a variant of walk_system_ram_res(), calls the @func
+ * callback against all memory ranges of type System RAM which are marked as
+ * IORESOURCE_SYSTEM_RAM and IORESOUCE_BUSY in reversed order, i.e., from
+ * higher to lower.
+ */
+int walk_system_ram_res_rev(u64 start, u64 end, void *arg,
+ int (*func)(struct resource *, void *))
+{
+ unsigned long flags;
+ struct resource *res;
+ int ret = -1;
+
+ flags = IORESOURCE_SYSTEM_RAM | IORESOURCE_BUSY;
+
+ read_lock(&resource_lock);
+ list_for_each_entry_reverse(res, &iomem_resource.child, sibling) {
+ if (start >= end)
+ break;
+ if ((res->flags & flags) != flags)
+ continue;
+ if (res->desc != IORES_DESC_NONE)
+ continue;
+ if (res->end < start)
+ break;
+
+ if ((res->end >= start) && (res->start < end)) {
+ ret = (*func)(res, arg);
+ if (ret)
+ break;
+ }
+ end = res->start - 1;
+
+ }
+ read_unlock(&resource_lock);
+ return ret;
+}
+
+/*
* This function calls the @func callback against all memory ranges, which
* are ranges marked as IORESOURCE_MEM and IORESOUCE_BUSY.
*/
--
2.13.6
_______________________________________________
Linux-nvdimm mailing list
Linux-nvdimm@lists.01.org
https://lists.01.org/mailman/listinfo/linux-nvdimm
^ permalink raw reply related
* [PATCH v4 1/3] resource: Use list_head to link sibling resource
From: Baoquan He @ 2018-05-07 6:32 UTC (permalink / raw)
To: linux-kernel-u79uwXL29TY76Z2rM5mHXA,
akpm-de/tnXTf+JLsfHDXvbKv3WD2FQJk+8+b,
robh+dt-DgEjT+Ai2ygdnm+yROfE0A,
dan.j.williams-ral2JQCrhuEAvxtiuMwx3w,
nicolas.pitre-QSEj5FYQhm4dnm+yROfE0A, josh-iaAMLnmF4UmaiuxdJuQwMA,
fengguang.wu-ral2JQCrhuEAvxtiuMwx3w, bp-l3A5Bk7waGM
Cc: brijesh.singh-5C7GfCeVMHo, devicetree-u79uwXL29TY76Z2rM5mHXA,
airlied-cv59FeDIM0c, linux-pci-u79uwXL29TY76Z2rM5mHXA,
richard.weiyang-Re5JQEeQqe8AvxtiuMwx3w,
keith.busch-ral2JQCrhuEAvxtiuMwx3w,
jcmvbkbc-Re5JQEeQqe8AvxtiuMwx3w,
baiyaowei-0p4V/sDNsUmm0O/7XYngnFaTQe2KTcn/,
kys-0li6OtcxBFHby3iVrkZq2A, frowand.list-Re5JQEeQqe8AvxtiuMwx3w,
lorenzo.pieralisi-5wv7dgnIgG8, sthemmin-0li6OtcxBFHby3iVrkZq2A,
Baoquan He, linux-nvdimm-hn68Rpc1hR1g9hUCZPvPmw,
patrik.r.jakobsson-Re5JQEeQqe8AvxtiuMwx3w,
linux-input-u79uwXL29TY76Z2rM5mHXA,
gustavo-THi1TnShQwVAfugRpC6u6w, dyoung-H+wXaHxf7aLQT0dZR+AlfA,
thomas.lendacky-5C7GfCeVMHo, haiyangz-0li6OtcxBFHby3iVrkZq2A,
maarten.lankhorst-VuQAYsv1563Yd54FQh9/CA,
jglisse-H+wXaHxf7aLQT0dZR+AlfA, seanpaul-F7+t8E8rja9g9hUCZPvPmw,
bhelgaas-hpIqsD4AKlfQT0dZR+AlfA, tglx-hfZtesqFncYOwBW4kG4KsQ,
yinghai-DgEjT+Ai2ygdnm+yROfE0A,
jonathan.derrick-ral2JQCrhuEAvxtiuMwx3w,
chris-YvXeqwSYzG2sTnJN9+BGXg, monstr-pSz03upnqPeHXe+LvDLADg,
linux-parisc-u79uwXL29TY76Z2rM5mHXA,
gregkh-hQyY1W1yCW8ekmWlsbkhG0B+6BGkLq7r,
dmitry.torokhov-Re5JQEeQqe8AvxtiuMwx3w,
kexec-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
ebiederm-aS9lmoZGLiVWk0Htik3J/w,
devel-tBiZLqfeLfOHmIFyCCdPziST3g8Odh+X,
davem-fT/PcQaiUtIeIZ0/mPfg9Q
In-Reply-To: <20180507063224.24229-1-bhe-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
The struct resource uses singly linked list to link siblings, implemented
by pointer operation. Replace it with list_head for better code readability.
Based on this list_head replacement, it will be very easy to do reverse
iteration on iomem_resource's sibling list in later patch.
Besides, type of member variables of struct resource, sibling and child, are
changed from 'struct resource *' to 'struct list_head'. This brings two
pointers of size increase.
Suggested-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Baoquan He <bhe@redhat.com>
Cc: Patrik Jakobsson <patrik.r.jakobsson@gmail.com>
Cc: David Airlie <airlied@linux.ie>
Cc: "K. Y. Srinivasan" <kys@microsoft.com>
Cc: Haiyang Zhang <haiyangz@microsoft.com>
Cc: Stephen Hemminger <sthemmin@microsoft.com>
Cc: Dmitry Torokhov <dmitry.torokhov@gmail.com>
Cc: Dan Williams <dan.j.williams@intel.com>
Cc: Rob Herring <robh+dt@kernel.org>
Cc: Frank Rowand <frowand.list@gmail.com>
Cc: Keith Busch <keith.busch@intel.com>
Cc: Jonathan Derrick <jonathan.derrick@intel.com>
Cc: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
Cc: Bjorn Helgaas <bhelgaas@google.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Brijesh Singh <brijesh.singh@amd.com>
Cc: "Jérôme Glisse" <jglisse@redhat.com>
Cc: Borislav Petkov <bp@suse.de>
Cc: Tom Lendacky <thomas.lendacky@amd.com>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: Yaowei Bai <baiyaowei@cmss.chinamobile.com>
Cc: Wei Yang <richard.weiyang@gmail.com>
Cc: devel@linuxdriverproject.org
Cc: linux-input@vger.kernel.org
Cc: linux-nvdimm@lists.01.org
Cc: devicetree@vger.kernel.org
Cc: linux-pci@vger.kernel.org
---
v3->v4:
Fix several bugs test robot reported. And change patch log.
v2->v3:
Rename resource functions first_child() and sibling() to
resource_first_chils() and resource_sibling(). Dan suggested this.
Move resource_first_chils() and resource_sibling() to linux/ioport.h
and make them as inline function. Rob suggested this. Accordingly add
linux/list.h including in linux/ioport.h, please help review if this
bring efficiency degradation or code redundancy.
The change on struct resource {} bring two pointers of size increase,
mention this in git log to make it more specifically, Rob suggested
this.
arch/microblaze/pci/pci-common.c | 31 +++--
arch/sparc/kernel/ioport.c | 2 +-
arch/xtensa/include/asm/pci-bridge.h | 4 +-
drivers/eisa/eisa-bus.c | 2 +
drivers/gpu/drm/drm_memory.c | 3 +-
drivers/gpu/drm/gma500/gtt.c | 5 +-
drivers/hv/vmbus_drv.c | 52 ++++----
drivers/input/joystick/iforce/iforce-main.c | 4 +-
drivers/nvdimm/e820.c | 2 +-
drivers/nvdimm/namespace_devs.c | 6 +-
drivers/nvdimm/nd.h | 5 +-
drivers/of/address.c | 4 +-
drivers/parisc/lba_pci.c | 4 +-
drivers/pci/host/vmd.c | 8 +-
drivers/pci/probe.c | 2 +
drivers/pci/setup-bus.c | 2 +-
include/linux/ioport.h | 17 ++-
kernel/resource.c | 181 +++++++++++++---------------
18 files changed, 170 insertions(+), 164 deletions(-)
diff --git a/arch/microblaze/pci/pci-common.c b/arch/microblaze/pci/pci-common.c
index 161f9758c631..56d189cb4be4 100644
--- a/arch/microblaze/pci/pci-common.c
+++ b/arch/microblaze/pci/pci-common.c
@@ -533,7 +533,9 @@ void pci_process_bridge_OF_ranges(struct pci_controller *hose,
res->flags = range.flags;
res->start = range.cpu_addr;
res->end = range.cpu_addr + range.size - 1;
- res->parent = res->child = res->sibling = NULL;
+ res->parent = NULL;
+ INIT_LIST_HEAD(&res->child);
+ INIT_LIST_HEAD(&res->sibling);
}
}
@@ -625,28 +627,31 @@ EXPORT_SYMBOL(pcibios_add_device);
static int __init reparent_resources(struct resource *parent,
struct resource *res)
{
- struct resource *p, **pp;
- struct resource **firstpp = NULL;
+ struct resource *p, *first = NULL;
- for (pp = &parent->child; (p = *pp) != NULL; pp = &p->sibling) {
+ list_for_each_entry(p, &parent->child, sibling) {
if (p->end < res->start)
continue;
if (res->end < p->start)
break;
if (p->start < res->start || p->end > res->end)
return -1; /* not completely contained */
- if (firstpp == NULL)
- firstpp = pp;
+ if (first == NULL)
+ first = p;
}
- if (firstpp == NULL)
+ if (first == NULL)
return -1; /* didn't find any conflicting entries? */
res->parent = parent;
- res->child = *firstpp;
- res->sibling = *pp;
- *firstpp = res;
- *pp = NULL;
- for (p = res->child; p != NULL; p = p->sibling) {
- p->parent = res;
+ list_add(&res->sibling, &p->sibling.prev);
+ INIT_LIST_HEAD(&res->child);
+
+ /*
+ * From first to p's previous sibling, they all fall into
+ * res's region, change them as res's children.
+ */
+ list_cut_position(&res->child, first->sibling.prev, res->sibling.prev);
+ list_for_each_entry(p, &new->child, sibling) {
+ p->parent = new;
pr_debug("PCI: Reparented %s [%llx..%llx] under %s\n",
p->name,
(unsigned long long)p->start,
diff --git a/arch/sparc/kernel/ioport.c b/arch/sparc/kernel/ioport.c
index 3bcef9ce74df..4e91fbbbedcc 100644
--- a/arch/sparc/kernel/ioport.c
+++ b/arch/sparc/kernel/ioport.c
@@ -669,7 +669,7 @@ static int sparc_io_proc_show(struct seq_file *m, void *v)
struct resource *root = m->private, *r;
const char *nm;
- for (r = root->child; r != NULL; r = r->sibling) {
+ list_for_each_entry(r, &root->child, sibling) {
if ((nm = r->name) == NULL) nm = "???";
seq_printf(m, "%016llx-%016llx: %s\n",
(unsigned long long)r->start,
diff --git a/arch/xtensa/include/asm/pci-bridge.h b/arch/xtensa/include/asm/pci-bridge.h
index 0b68c76ec1e6..f487b06817df 100644
--- a/arch/xtensa/include/asm/pci-bridge.h
+++ b/arch/xtensa/include/asm/pci-bridge.h
@@ -71,8 +71,8 @@ static inline void pcibios_init_resource(struct resource *res,
res->flags = flags;
res->name = name;
res->parent = NULL;
- res->sibling = NULL;
- res->child = NULL;
+ INIT_LIST_HEAD(&res->child);
+ INIT_LIST_HEAD(&res->sibling);
}
diff --git a/drivers/eisa/eisa-bus.c b/drivers/eisa/eisa-bus.c
index 1e8062f6dbfc..dba78f75fd06 100644
--- a/drivers/eisa/eisa-bus.c
+++ b/drivers/eisa/eisa-bus.c
@@ -408,6 +408,8 @@ static struct resource eisa_root_res = {
.start = 0,
.end = 0xffffffff,
.flags = IORESOURCE_IO,
+ .sibling = LIST_HEAD_INIT(eisa_root_res.sibling),
+ .child = LIST_HEAD_INIT(eisa_root_res.child),
};
static int eisa_bus_count;
diff --git a/drivers/gpu/drm/drm_memory.c b/drivers/gpu/drm/drm_memory.c
index 3c54044214db..53e300a993dc 100644
--- a/drivers/gpu/drm/drm_memory.c
+++ b/drivers/gpu/drm/drm_memory.c
@@ -155,9 +155,8 @@ u64 drm_get_max_iomem(void)
struct resource *tmp;
resource_size_t max_iomem = 0;
- for (tmp = iomem_resource.child; tmp; tmp = tmp->sibling) {
+ list_for_each_entry(tmp, &iomem_resource.child, sibling)
max_iomem = max(max_iomem, tmp->end);
- }
return max_iomem;
}
diff --git a/drivers/gpu/drm/gma500/gtt.c b/drivers/gpu/drm/gma500/gtt.c
index 3949b0990916..addd3bc009af 100644
--- a/drivers/gpu/drm/gma500/gtt.c
+++ b/drivers/gpu/drm/gma500/gtt.c
@@ -565,7 +565,7 @@ int psb_gtt_init(struct drm_device *dev, int resume)
int psb_gtt_restore(struct drm_device *dev)
{
struct drm_psb_private *dev_priv = dev->dev_private;
- struct resource *r = dev_priv->gtt_mem->child;
+ struct resource *r;
struct gtt_range *range;
unsigned int restored = 0, total = 0, size = 0;
@@ -573,14 +573,13 @@ int psb_gtt_restore(struct drm_device *dev)
mutex_lock(&dev_priv->gtt_mutex);
psb_gtt_init(dev, 1);
- while (r != NULL) {
+ list_for_each_entry(r, &dev_priv->gtt_mem->child, sibling) {
range = container_of(r, struct gtt_range, resource);
if (range->pages) {
psb_gtt_insert(dev, range, 1);
size += range->resource.end - range->resource.start;
restored++;
}
- r = r->sibling;
total++;
}
mutex_unlock(&dev_priv->gtt_mutex);
diff --git a/drivers/hv/vmbus_drv.c b/drivers/hv/vmbus_drv.c
index b10fe26c4891..d87ec5a1bc4c 100644
--- a/drivers/hv/vmbus_drv.c
+++ b/drivers/hv/vmbus_drv.c
@@ -1412,9 +1412,8 @@ static acpi_status vmbus_walk_resources(struct acpi_resource *res, void *ctx)
{
resource_size_t start = 0;
resource_size_t end = 0;
- struct resource *new_res;
+ struct resource *new_res, *tmp;
struct resource **old_res = &hyperv_mmio;
- struct resource **prev_res = NULL;
switch (res->type) {
@@ -1461,44 +1460,36 @@ static acpi_status vmbus_walk_resources(struct acpi_resource *res, void *ctx)
/*
* If two ranges are adjacent, merge them.
*/
- do {
- if (!*old_res) {
- *old_res = new_res;
- break;
- }
-
- if (((*old_res)->end + 1) == new_res->start) {
- (*old_res)->end = new_res->end;
+ if (!*old_res) {
+ *old_res = new_res;
+ return AE_OK;
+ }
+ tmp = *old_res;
+ list_for_each_entry_from(tmp, &tmp->parent->child, sibling) {
+ if ((tmp->end + 1) == new_res->start) {
+ tmp->end = new_res->end;
kfree(new_res);
break;
}
- if ((*old_res)->start == new_res->end + 1) {
- (*old_res)->start = new_res->start;
+ if (tmp->start == new_res->end + 1) {
+ tmp->start = new_res->start;
kfree(new_res);
break;
}
- if ((*old_res)->start > new_res->end) {
- new_res->sibling = *old_res;
- if (prev_res)
- (*prev_res)->sibling = new_res;
- *old_res = new_res;
+ if (tmp->start > new_res->end) {
+ list_add(&new_res->sibling, tmp->sibling.prev);
break;
}
-
- prev_res = old_res;
- old_res = &(*old_res)->sibling;
-
- } while (1);
+ }
return AE_OK;
}
static int vmbus_acpi_remove(struct acpi_device *device)
{
- struct resource *cur_res;
- struct resource *next_res;
+ struct resource *res;
if (hyperv_mmio) {
if (fb_mmio) {
@@ -1507,10 +1498,9 @@ static int vmbus_acpi_remove(struct acpi_device *device)
fb_mmio = NULL;
}
- for (cur_res = hyperv_mmio; cur_res; cur_res = next_res) {
- next_res = cur_res->sibling;
- kfree(cur_res);
- }
+ res = hyperv_mmio;
+ list_for_each_entry_from(res, &res->parent->child, sibling)
+ kfree(res);
}
return 0;
@@ -1596,7 +1586,8 @@ int vmbus_allocate_mmio(struct resource **new, struct hv_device *device_obj,
}
}
- for (iter = hyperv_mmio; iter; iter = iter->sibling) {
+ iter = hyperv_mmio;
+ list_for_each_entry_from(iter, &iter->parent->child, sibling) {
if ((iter->start >= max) || (iter->end <= min))
continue;
@@ -1639,7 +1630,8 @@ void vmbus_free_mmio(resource_size_t start, resource_size_t size)
struct resource *iter;
down(&hyperv_mmio_lock);
- for (iter = hyperv_mmio; iter; iter = iter->sibling) {
+ iter = hyperv_mmio;
+ list_for_each_entry_from(iter, &iter->parent->child, sibling) {
if ((iter->start >= start + size) || (iter->end <= start))
continue;
diff --git a/drivers/input/joystick/iforce/iforce-main.c b/drivers/input/joystick/iforce/iforce-main.c
index daeeb4c7e3b0..5c0be27b33ff 100644
--- a/drivers/input/joystick/iforce/iforce-main.c
+++ b/drivers/input/joystick/iforce/iforce-main.c
@@ -305,8 +305,8 @@ int iforce_init_device(struct iforce *iforce)
iforce->device_memory.end = 200;
iforce->device_memory.flags = IORESOURCE_MEM;
iforce->device_memory.parent = NULL;
- iforce->device_memory.child = NULL;
- iforce->device_memory.sibling = NULL;
+ INIT_LIST_HEAD(&iforce->device_memory.child);
+ INIT_LIST_HEAD(&iforce->device_memory.sibling);
/*
* Wait until device ready - until it sends its first response.
diff --git a/drivers/nvdimm/e820.c b/drivers/nvdimm/e820.c
index 6f9a6ffd7cde..513e661bb0d8 100644
--- a/drivers/nvdimm/e820.c
+++ b/drivers/nvdimm/e820.c
@@ -53,7 +53,7 @@ static int e820_pmem_probe(struct platform_device *pdev)
goto err;
platform_set_drvdata(pdev, nvdimm_bus);
- for (p = iomem_resource.child; p ; p = p->sibling) {
+ list_for_each_entry(p, &iomem_resource.child, sibling) {
struct nd_region_desc ndr_desc;
if (p->desc != IORES_DESC_PERSISTENT_MEMORY_LEGACY)
diff --git a/drivers/nvdimm/namespace_devs.c b/drivers/nvdimm/namespace_devs.c
index 28afdd668905..f53d410d9981 100644
--- a/drivers/nvdimm/namespace_devs.c
+++ b/drivers/nvdimm/namespace_devs.c
@@ -637,7 +637,7 @@ static resource_size_t scan_allocate(struct nd_region *nd_region,
retry:
first = 0;
for_each_dpa_resource(ndd, res) {
- struct resource *next = res->sibling, *new_res = NULL;
+ struct resource *next = resource_sibling(res), *new_res = NULL;
resource_size_t allocate, available = 0;
enum alloc_loc loc = ALLOC_ERR;
const char *action;
@@ -763,7 +763,7 @@ static resource_size_t scan_allocate(struct nd_region *nd_region,
* an initial "pmem-reserve pass". Only do an initial BLK allocation
* when none of the DPA space is reserved.
*/
- if ((is_pmem || !ndd->dpa.child) && n == to_allocate)
+ if ((is_pmem || list_empty(&ndd->dpa.child)) && n == to_allocate)
return init_dpa_allocation(label_id, nd_region, nd_mapping, n);
return n;
}
@@ -779,7 +779,7 @@ static int merge_dpa(struct nd_region *nd_region,
retry:
for_each_dpa_resource(ndd, res) {
int rc;
- struct resource *next = res->sibling;
+ struct resource *next = resource_sibling(res);
resource_size_t end = res->start + resource_size(res);
if (!next || strcmp(res->name, label_id->id) != 0
diff --git a/drivers/nvdimm/nd.h b/drivers/nvdimm/nd.h
index 32e0364b48b9..da7da15e03e7 100644
--- a/drivers/nvdimm/nd.h
+++ b/drivers/nvdimm/nd.h
@@ -102,11 +102,10 @@ unsigned sizeof_namespace_label(struct nvdimm_drvdata *ndd);
(unsigned long long) (res ? res->start : 0), ##arg)
#define for_each_dpa_resource(ndd, res) \
- for (res = (ndd)->dpa.child; res; res = res->sibling)
+ list_for_each_entry(res, &(ndd)->dpa.child, sibling)
#define for_each_dpa_resource_safe(ndd, res, next) \
- for (res = (ndd)->dpa.child, next = res ? res->sibling : NULL; \
- res; res = next, next = next ? next->sibling : NULL)
+ list_for_each_entry_safe(res, next, &(ndd)->dpa.child, sibling)
struct nd_percpu_lane {
int count;
diff --git a/drivers/of/address.c b/drivers/of/address.c
index 53349912ac75..e2e25719ab52 100644
--- a/drivers/of/address.c
+++ b/drivers/of/address.c
@@ -330,7 +330,9 @@ int of_pci_range_to_resource(struct of_pci_range *range,
{
int err;
res->flags = range->flags;
- res->parent = res->child = res->sibling = NULL;
+ res->parent = NULL;
+ INIT_LIST_HEAD(&res->child);
+ INIT_LIST_HEAD(&res->sibling);
res->name = np->full_name;
if (res->flags & IORESOURCE_IO) {
diff --git a/drivers/parisc/lba_pci.c b/drivers/parisc/lba_pci.c
index 69bd98421eb1..7482bdfd1959 100644
--- a/drivers/parisc/lba_pci.c
+++ b/drivers/parisc/lba_pci.c
@@ -170,8 +170,8 @@ lba_dump_res(struct resource *r, int d)
for (i = d; i ; --i) printk(" ");
printk(KERN_DEBUG "%p [%lx,%lx]/%lx\n", r,
(long)r->start, (long)r->end, r->flags);
- lba_dump_res(r->child, d+2);
- lba_dump_res(r->sibling, d);
+ lba_dump_res(resource_first_child(&r->child), d+2);
+ lba_dump_res(resource_sibling(r), d);
}
diff --git a/drivers/pci/host/vmd.c b/drivers/pci/host/vmd.c
index 930a8fa08bd6..c3000af903ea 100644
--- a/drivers/pci/host/vmd.c
+++ b/drivers/pci/host/vmd.c
@@ -520,14 +520,14 @@ static struct pci_ops vmd_ops = {
static void vmd_attach_resources(struct vmd_dev *vmd)
{
- vmd->dev->resource[VMD_MEMBAR1].child = &vmd->resources[1];
- vmd->dev->resource[VMD_MEMBAR2].child = &vmd->resources[2];
+ list_add(&vmd->resources[1].sibling, &vmd->dev->resource[VMD_MEMBAR1].child);
+ list_add(&vmd->resources[2].sibling, &vmd->dev->resource[VMD_MEMBAR2].child);
}
static void vmd_detach_resources(struct vmd_dev *vmd)
{
- vmd->dev->resource[VMD_MEMBAR1].child = NULL;
- vmd->dev->resource[VMD_MEMBAR2].child = NULL;
+ INIT_LIST_HEAD(&vmd->dev->resource[VMD_MEMBAR1].child);
+ INIT_LIST_HEAD(&vmd->dev->resource[VMD_MEMBAR2].child);
}
/*
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
index ac91b6fd0bcd..d162c77bec29 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -59,6 +59,8 @@ static struct resource *get_pci_domain_busn_res(int domain_nr)
r->res.start = 0;
r->res.end = 0xff;
r->res.flags = IORESOURCE_BUS | IORESOURCE_PCI_FIXED;
+ INIT_LIST_HEAD(&r->res.child);
+ INIT_LIST_HEAD(&r->res.sibling);
list_add_tail(&r->list, &pci_domain_busn_res_list);
diff --git a/drivers/pci/setup-bus.c b/drivers/pci/setup-bus.c
index 072784f55ea5..0d5e30004ca6 100644
--- a/drivers/pci/setup-bus.c
+++ b/drivers/pci/setup-bus.c
@@ -2107,7 +2107,7 @@ int pci_reassign_bridge_resources(struct pci_dev *bridge, unsigned long type)
continue;
/* Ignore BARs which are still in use */
- if (res->child)
+ if (!list_empty(&res->child))
continue;
ret = add_to_list(&saved, bridge, res, 0, 0);
diff --git a/include/linux/ioport.h b/include/linux/ioport.h
index da0ebaec25f0..225d13d3500a 100644
--- a/include/linux/ioport.h
+++ b/include/linux/ioport.h
@@ -12,6 +12,7 @@
#ifndef __ASSEMBLY__
#include <linux/compiler.h>
#include <linux/types.h>
+#include <linux/list.h>
/*
* Resources are tree-like, allowing
* nesting etc..
@@ -22,7 +23,8 @@ struct resource {
const char *name;
unsigned long flags;
unsigned long desc;
- struct resource *parent, *sibling, *child;
+ struct list_head child, sibling;
+ struct resource *parent;
};
/*
@@ -215,7 +217,6 @@ static inline bool resource_contains(struct resource *r1, struct resource *r2)
return r1->start <= r2->start && r1->end >= r2->end;
}
-
/* Convenience shorthand with allocation */
#define request_region(start,n,name) __request_region(&ioport_resource, (start), (n), (name), 0)
#define request_muxed_region(start,n,name) __request_region(&ioport_resource, (start), (n), (name), IORESOURCE_MUXED)
@@ -286,6 +287,18 @@ static inline bool resource_overlaps(struct resource *r1, struct resource *r2)
return (r1->start <= r2->end && r1->end >= r2->start);
}
+static inline struct resource *resource_sibling(struct resource *res)
+{
+ if (res->parent && !list_is_last(&res->sibling, &res->parent->child))
+ return list_next_entry(res, sibling);
+ return NULL;
+}
+
+static inline struct resource *resource_first_child(struct list_head *head)
+{
+ return list_first_entry_or_null(head, struct resource, sibling);
+}
+
#endif /* __ASSEMBLY__ */
#endif /* _LINUX_IOPORT_H */
diff --git a/kernel/resource.c b/kernel/resource.c
index 2af6c03858b9..4f560991c130 100644
--- a/kernel/resource.c
+++ b/kernel/resource.c
@@ -31,6 +31,8 @@ struct resource ioport_resource = {
.start = 0,
.end = IO_SPACE_LIMIT,
.flags = IORESOURCE_IO,
+ .sibling = LIST_HEAD_INIT(ioport_resource.sibling),
+ .child = LIST_HEAD_INIT(ioport_resource.child),
};
EXPORT_SYMBOL(ioport_resource);
@@ -39,6 +41,8 @@ struct resource iomem_resource = {
.start = 0,
.end = -1,
.flags = IORESOURCE_MEM,
+ .sibling = LIST_HEAD_INIT(iomem_resource.sibling),
+ .child = LIST_HEAD_INIT(iomem_resource.child),
};
EXPORT_SYMBOL(iomem_resource);
@@ -57,20 +61,20 @@ static DEFINE_RWLOCK(resource_lock);
* by boot mem after the system is up. So for reusing the resource entry
* we need to remember the resource.
*/
-static struct resource *bootmem_resource_free;
+static struct list_head bootmem_resource_free = LIST_HEAD_INIT(bootmem_resource_free);
static DEFINE_SPINLOCK(bootmem_resource_lock);
static struct resource *next_resource(struct resource *p, bool sibling_only)
{
/* Caller wants to traverse through siblings only */
if (sibling_only)
- return p->sibling;
+ return resource_sibling(p);
- if (p->child)
- return p->child;
- while (!p->sibling && p->parent)
+ if (!list_empty(&p->child))
+ return resource_first_child(&p->child);
+ while (!resource_sibling(p) && p->parent)
p = p->parent;
- return p->sibling;
+ return resource_sibling(p);
}
static void *r_next(struct seq_file *m, void *v, loff_t *pos)
@@ -90,7 +94,7 @@ static void *r_start(struct seq_file *m, loff_t *pos)
struct resource *p = m->private;
loff_t l = 0;
read_lock(&resource_lock);
- for (p = p->child; p && l < *pos; p = r_next(m, p, &l))
+ for (p = resource_first_child(&p->child); p && l < *pos; p = r_next(m, p, &l))
;
return p;
}
@@ -186,8 +190,7 @@ static void free_resource(struct resource *res)
if (!PageSlab(virt_to_head_page(res))) {
spin_lock(&bootmem_resource_lock);
- res->sibling = bootmem_resource_free;
- bootmem_resource_free = res;
+ list_add(&res->sibling, &bootmem_resource_free);
spin_unlock(&bootmem_resource_lock);
} else {
kfree(res);
@@ -199,10 +202,9 @@ static struct resource *alloc_resource(gfp_t flags)
struct resource *res = NULL;
spin_lock(&bootmem_resource_lock);
- if (bootmem_resource_free) {
- res = bootmem_resource_free;
- bootmem_resource_free = res->sibling;
- }
+ res = resource_first_child(&bootmem_resource_free);
+ if (res)
+ list_del(&res->sibling);
spin_unlock(&bootmem_resource_lock);
if (res)
@@ -210,6 +212,8 @@ static struct resource *alloc_resource(gfp_t flags)
else
res = kzalloc(sizeof(struct resource), flags);
+ INIT_LIST_HEAD(&res->child);
+ INIT_LIST_HEAD(&res->sibling);
return res;
}
@@ -218,7 +222,7 @@ static struct resource * __request_resource(struct resource *root, struct resour
{
resource_size_t start = new->start;
resource_size_t end = new->end;
- struct resource *tmp, **p;
+ struct resource *tmp;
if (end < start)
return root;
@@ -226,64 +230,62 @@ static struct resource * __request_resource(struct resource *root, struct resour
return root;
if (end > root->end)
return root;
- p = &root->child;
- for (;;) {
- tmp = *p;
- if (!tmp || tmp->start > end) {
- new->sibling = tmp;
- *p = new;
+
+ if (list_empty(&root->child)) {
+ list_add(&new->sibling, &root->child);
+ new->parent = root;
+ INIT_LIST_HEAD(&new->child);
+ return NULL;
+ }
+
+ list_for_each_entry(tmp, &root->child, sibling) {
+ if (tmp->start > end) {
+ list_add(&new->sibling, tmp->sibling.prev);
new->parent = root;
+ INIT_LIST_HEAD(&new->child);
return NULL;
}
- p = &tmp->sibling;
if (tmp->end < start)
continue;
return tmp;
}
+
+ list_add_tail(&new->sibling, &root->child);
+ new->parent = root;
+ INIT_LIST_HEAD(&new->child);
+ return NULL;
}
static int __release_resource(struct resource *old, bool release_child)
{
- struct resource *tmp, **p, *chd;
+ struct resource *tmp, *next, *chd;
- p = &old->parent->child;
- for (;;) {
- tmp = *p;
- if (!tmp)
- break;
+ list_for_each_entry_safe(tmp, next, &old->parent->child, sibling) {
if (tmp == old) {
- if (release_child || !(tmp->child)) {
- *p = tmp->sibling;
+ if (release_child || list_empty(&tmp->child)) {
+ list_del(&tmp->sibling);
} else {
- for (chd = tmp->child;; chd = chd->sibling) {
+ list_for_each_entry(chd, &tmp->child, sibling)
chd->parent = tmp->parent;
- if (!(chd->sibling))
- break;
- }
- *p = tmp->child;
- chd->sibling = tmp->sibling;
+ list_splice(&tmp->child, tmp->sibling.prev);
+ list_del(&tmp->sibling);
}
+
old->parent = NULL;
return 0;
}
- p = &tmp->sibling;
}
return -EINVAL;
}
static void __release_child_resources(struct resource *r)
{
- struct resource *tmp, *p;
+ struct resource *tmp, *next;
resource_size_t size;
- p = r->child;
- r->child = NULL;
- while (p) {
- tmp = p;
- p = p->sibling;
-
+ list_for_each_entry_safe(tmp, next, &r->child, sibling) {
tmp->parent = NULL;
- tmp->sibling = NULL;
+ INIT_LIST_HEAD(&tmp->sibling);
__release_child_resources(tmp);
printk(KERN_DEBUG "release child resource %pR\n", tmp);
@@ -292,6 +294,8 @@ static void __release_child_resources(struct resource *r)
tmp->start = 0;
tmp->end = size - 1;
}
+
+ INIT_LIST_HEAD(&tmp->child);
}
void release_child_resources(struct resource *r)
@@ -376,7 +380,8 @@ static int find_next_iomem_res(struct resource *res, unsigned long desc,
read_lock(&resource_lock);
- for (p = iomem_resource.child; p; p = next_resource(p, sibling_only)) {
+ for (p = resource_first_child(&iomem_resource.child); p;
+ p = next_resource(p, sibling_only)) {
if ((p->flags & res->flags) != res->flags)
continue;
if ((desc != IORES_DESC_NONE) && (desc != p->desc))
@@ -564,7 +569,7 @@ int region_intersects(resource_size_t start, size_t size, unsigned long flags,
struct resource *p;
read_lock(&resource_lock);
- for (p = iomem_resource.child; p ; p = p->sibling) {
+ list_for_each_entry(p, &iomem_resource.child, sibling) {
bool is_type = (((p->flags & flags) == flags) &&
((desc == IORES_DESC_NONE) ||
(desc == p->desc)));
@@ -618,7 +623,7 @@ static int __find_resource(struct resource *root, struct resource *old,
resource_size_t size,
struct resource_constraint *constraint)
{
- struct resource *this = root->child;
+ struct resource *this = resource_first_child(&root->child);
struct resource tmp = *new, avail, alloc;
tmp.start = root->start;
@@ -628,7 +633,7 @@ static int __find_resource(struct resource *root, struct resource *old,
*/
if (this && this->start == root->start) {
tmp.start = (this == old) ? old->start : this->end + 1;
- this = this->sibling;
+ this = resource_sibling(this);
}
for(;;) {
if (this)
@@ -664,7 +669,7 @@ next: if (!this || this->end == root->end)
if (this != old)
tmp.start = this->end + 1;
- this = this->sibling;
+ this = resource_sibling(this);
}
return -EBUSY;
}
@@ -708,7 +713,7 @@ static int reallocate_resource(struct resource *root, struct resource *old,
goto out;
}
- if (old->child) {
+ if (!list_empty(&old->child)) {
err = -EBUSY;
goto out;
}
@@ -789,7 +794,7 @@ struct resource *lookup_resource(struct resource *root, resource_size_t start)
struct resource *res;
read_lock(&resource_lock);
- for (res = root->child; res; res = res->sibling) {
+ list_for_each_entry(res, &root->child, sibling) {
if (res->start == start)
break;
}
@@ -822,32 +827,27 @@ static struct resource * __insert_resource(struct resource *parent, struct resou
break;
}
- for (next = first; ; next = next->sibling) {
+ for (next = first; ; next = resource_sibling(next)) {
/* Partial overlap? Bad, and unfixable */
if (next->start < new->start || next->end > new->end)
return next;
- if (!next->sibling)
+ if (!resource_sibling(next))
break;
- if (next->sibling->start > new->end)
+ if (resource_sibling(next)->start > new->end)
break;
}
-
new->parent = parent;
- new->sibling = next->sibling;
- new->child = first;
+ list_add(&new->sibling, &next->sibling);
+ INIT_LIST_HEAD(&new->child);
- next->sibling = NULL;
- for (next = first; next; next = next->sibling)
+ /*
+ * From first to next, they all fall into new's region, so change them
+ * as new's children.
+ */
+ list_cut_position(&new->child, first->sibling.prev, &next->sibling);
+ list_for_each_entry(next, &new->child, sibling)
next->parent = new;
- if (parent->child == first) {
- parent->child = new;
- } else {
- next = parent->child;
- while (next->sibling != first)
- next = next->sibling;
- next->sibling = new;
- }
return NULL;
}
@@ -969,19 +969,17 @@ static int __adjust_resource(struct resource *res, resource_size_t start,
if ((start < parent->start) || (end > parent->end))
goto out;
- if (res->sibling && (res->sibling->start <= end))
+ if (resource_sibling(res) && (resource_sibling(res)->start <= end))
goto out;
- tmp = parent->child;
- if (tmp != res) {
- while (tmp->sibling != res)
- tmp = tmp->sibling;
+ if (res->sibling.prev != &parent->child) {
+ tmp = list_prev_entry(res, sibling);
if (start <= tmp->end)
goto out;
}
skip:
- for (tmp = res->child; tmp; tmp = tmp->sibling)
+ list_for_each_entry(tmp, &res->child, sibling)
if ((tmp->start < start) || (tmp->end > end))
goto out;
@@ -1206,34 +1204,32 @@ EXPORT_SYMBOL(__request_region);
void __release_region(struct resource *parent, resource_size_t start,
resource_size_t n)
{
- struct resource **p;
+ struct resource *res;
resource_size_t end;
- p = &parent->child;
+ res = resource_first_child(&parent->child);
end = start + n - 1;
write_lock(&resource_lock);
for (;;) {
- struct resource *res = *p;
-
if (!res)
break;
if (res->start <= start && res->end >= end) {
if (!(res->flags & IORESOURCE_BUSY)) {
- p = &res->child;
+ res = resource_first_child(&res->child);
continue;
}
if (res->start != start || res->end != end)
break;
- *p = res->sibling;
+ list_del(&res->sibling);
write_unlock(&resource_lock);
if (res->flags & IORESOURCE_MUXED)
wake_up(&muxed_resource_wait);
free_resource(res);
return;
}
- p = &res->sibling;
+ res = resource_sibling(res);
}
write_unlock(&resource_lock);
@@ -1268,9 +1264,7 @@ EXPORT_SYMBOL(__release_region);
int release_mem_region_adjustable(struct resource *parent,
resource_size_t start, resource_size_t size)
{
- struct resource **p;
- struct resource *res;
- struct resource *new_res;
+ struct resource *res, *new_res;
resource_size_t end;
int ret = -EINVAL;
@@ -1281,16 +1275,16 @@ int release_mem_region_adjustable(struct resource *parent,
/* The alloc_resource() result gets checked later */
new_res = alloc_resource(GFP_KERNEL);
- p = &parent->child;
+ res = resource_first_child(&parent->child);
write_lock(&resource_lock);
- while ((res = *p)) {
+ while ((res)) {
if (res->start >= end)
break;
/* look for the next resource if it does not fit into */
if (res->start > start || res->end < end) {
- p = &res->sibling;
+ res = resource_sibling(res);
continue;
}
@@ -1298,14 +1292,14 @@ int release_mem_region_adjustable(struct resource *parent,
break;
if (!(res->flags & IORESOURCE_BUSY)) {
- p = &res->child;
+ res = resource_first_child(&res->child);
continue;
}
/* found the target resource; let's adjust accordingly */
if (res->start == start && res->end == end) {
/* free the whole entry */
- *p = res->sibling;
+ list_del(&res->sibling);
free_resource(res);
ret = 0;
} else if (res->start == start && res->end != end) {
@@ -1328,14 +1322,13 @@ int release_mem_region_adjustable(struct resource *parent,
new_res->flags = res->flags;
new_res->desc = res->desc;
new_res->parent = res->parent;
- new_res->sibling = res->sibling;
- new_res->child = NULL;
+ INIT_LIST_HEAD(&new_res->child);
ret = __adjust_resource(res, res->start,
start - res->start);
if (ret)
break;
- res->sibling = new_res;
+ list_add(&new_res->sibling, &res->sibling);
new_res = NULL;
}
@@ -1516,7 +1509,7 @@ static int __init reserve_setup(char *str)
res->end = io_start + io_num - 1;
res->flags |= IORESOURCE_BUSY;
res->desc = IORES_DESC_NONE;
- res->child = NULL;
+ INIT_LIST_HEAD(&res->child);
if (request_resource(parent, res) == 0)
reserved = x+1;
}
@@ -1536,7 +1529,7 @@ int iomem_map_sanity_check(resource_size_t addr, unsigned long size)
loff_t l;
read_lock(&resource_lock);
- for (p = p->child; p ; p = r_next(NULL, p, &l)) {
+ for (p = resource_first_child(&p->child); p; p = r_next(NULL, p, &l)) {
/*
* We can probably skip the resources without
* IORESOURCE_IO attribute?
@@ -1592,7 +1585,7 @@ bool iomem_is_exclusive(u64 addr)
addr = addr & PAGE_MASK;
read_lock(&resource_lock);
- for (p = p->child; p ; p = r_next(NULL, p, &l)) {
+ for (p = resource_first_child(&p->child); p; p = r_next(NULL, p, &l)) {
/*
* We can probably skip the resources without
* IORESOURCE_IO attribute?
--
2.13.6
_______________________________________________
Linux-nvdimm mailing list
Linux-nvdimm@lists.01.org
https://lists.01.org/mailman/listinfo/linux-nvdimm
^ permalink raw reply related
* [PATCH v4 0/3] resource: Use list_head to link sibling resource
From: Baoquan He @ 2018-05-07 6:32 UTC (permalink / raw)
To: linux-kernel-u79uwXL29TY76Z2rM5mHXA,
akpm-de/tnXTf+JLsfHDXvbKv3WD2FQJk+8+b,
robh+dt-DgEjT+Ai2ygdnm+yROfE0A,
dan.j.williams-ral2JQCrhuEAvxtiuMwx3w,
nicolas.pitre-QSEj5FYQhm4dnm+yROfE0A, josh-iaAMLnmF4UmaiuxdJuQwMA,
fengguang.wu-ral2JQCrhuEAvxtiuMwx3w, bp-l3A5Bk7waGM
Cc: brijesh.singh-5C7GfCeVMHo, devicetree-u79uwXL29TY76Z2rM5mHXA,
airlied-cv59FeDIM0c, linux-pci-u79uwXL29TY76Z2rM5mHXA,
richard.weiyang-Re5JQEeQqe8AvxtiuMwx3w,
keith.busch-ral2JQCrhuEAvxtiuMwx3w,
jcmvbkbc-Re5JQEeQqe8AvxtiuMwx3w,
baiyaowei-0p4V/sDNsUmm0O/7XYngnFaTQe2KTcn/,
kys-0li6OtcxBFHby3iVrkZq2A, frowand.list-Re5JQEeQqe8AvxtiuMwx3w,
lorenzo.pieralisi-5wv7dgnIgG8, sthemmin-0li6OtcxBFHby3iVrkZq2A,
Baoquan He, linux-nvdimm-hn68Rpc1hR1g9hUCZPvPmw,
patrik.r.jakobsson-Re5JQEeQqe8AvxtiuMwx3w,
linux-input-u79uwXL29TY76Z2rM5mHXA,
gustavo-THi1TnShQwVAfugRpC6u6w, dyoung-H+wXaHxf7aLQT0dZR+AlfA,
thomas.lendacky-5C7GfCeVMHo, haiyangz-0li6OtcxBFHby3iVrkZq2A,
maarten.lankhorst-VuQAYsv1563Yd54FQh9/CA,
jglisse-H+wXaHxf7aLQT0dZR+AlfA, seanpaul-F7+t8E8rja9g9hUCZPvPmw,
bhelgaas-hpIqsD4AKlfQT0dZR+AlfA, tglx-hfZtesqFncYOwBW4kG4KsQ,
yinghai-DgEjT+Ai2ygdnm+yROfE0A,
jonathan.derrick-ral2JQCrhuEAvxtiuMwx3w,
chris-YvXeqwSYzG2sTnJN9+BGXg, monstr-pSz03upnqPeHXe+LvDLADg,
linux-parisc-u79uwXL29TY76Z2rM5mHXA,
gregkh-hQyY1W1yCW8ekmWlsbkhG0B+6BGkLq7r,
dmitry.torokhov-Re5JQEeQqe8AvxtiuMwx3w,
kexec-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
ebiederm-aS9lmoZGLiVWk0Htik3J/w,
devel-tBiZLqfeLfOHmIFyCCdPziST3g8Odh+X,
davem-fT/PcQaiUtIeIZ0/mPfg9Q
This patchset is doing:
1) Replace struct resource's sibling list from singly linked list to
list_head. Clearing out those pointer operation within singly linked
list for better code readability.
2) Based on list_head replacement, add a new function
walk_system_ram_res_rev() which can does reversed iteration on
iomem_resource's siblings.
3) Change kexec_file loading to search system RAM top down for kernel
loadin, using walk_system_ram_res_rev().
Note:
This patchset passed testing on my kvm guest, x86_64 arch with network
enabling. The thing we need pay attetion to is that a root resource's
child member need be initialized specifically with LIST_HEAD_INIT() if
statically defined or INIT_LIST_HEAD() for dynamically definition. Here
Just like we do for iomem_resource/ioport_resource, or the change in
get_pci_domain_busn_res().
Links of the old posting(Boris pointed out that we should use
https://lkml.kernel.org/r/Message-ID, while it can't be opened from
my side, so paste all of them here.):
v3:
https://lkml.kernel.org/r/20180419001848.3041-1-bhe-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org
https://lkml.org/lkml/2018/4/18/767
v2:
https://lkml.kernel.org/r/20180408024724.16812-1-bhe-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org
https://lkml.org/lkml/2018/4/7/169
v1:
https://lkml.kernel.org/r/20180322033722.9279-1-bhe-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org
https://lkml.org/lkml/2018/3/21/952
Changelog:
v3->v4:
Fix several bugs test robot reported. Rewrite cover letter and patch
log according to reviewer's comment.
v2->v3:
Rename resource functions first_child() and sibling() to
resource_first_chils() and resource_sibling(). Dan suggested this.
Move resource_first_chils() and resource_sibling() to linux/ioport.h
and make them as inline function. Rob suggested this. Accordingly add
linux/list.h including in linux/ioport.h, please help review if this
bring efficiency degradation or code redundancy.
The change on struct resource {} bring two pointers of size increase,
mention this in git log to make it more specifically, Rob suggested
this.
v1->v2:
Use list_head instead to link resource siblings. This is suggested by
Andrew.
Rewrite walk_system_ram_res_rev() after list_head is taken to link
resouce siblings.
Baoquan He (3):
resource: Use list_head to link sibling resource
resource: add walk_system_ram_res_rev()
kexec_file: Load kernel at top of system RAM if required
arch/microblaze/pci/pci-common.c | 31 ++--
arch/sparc/kernel/ioport.c | 2 +-
arch/xtensa/include/asm/pci-bridge.h | 4 +-
drivers/eisa/eisa-bus.c | 2 +
drivers/gpu/drm/drm_memory.c | 3 +-
drivers/gpu/drm/gma500/gtt.c | 5 +-
drivers/hv/vmbus_drv.c | 52 +++----
drivers/input/joystick/iforce/iforce-main.c | 4 +-
drivers/nvdimm/e820.c | 2 +-
drivers/nvdimm/namespace_devs.c | 6 +-
drivers/nvdimm/nd.h | 5 +-
drivers/of/address.c | 4 +-
drivers/parisc/lba_pci.c | 4 +-
drivers/pci/host/vmd.c | 8 +-
drivers/pci/probe.c | 2 +
drivers/pci/setup-bus.c | 2 +-
include/linux/ioport.h | 20 ++-
kernel/kexec_file.c | 2 +
kernel/resource.c | 221 ++++++++++++++++------------
19 files changed, 215 insertions(+), 164 deletions(-)
--
2.13.6
^ permalink raw reply
* Re: [PATCH] HID: uhid: fix a missing-check bug
From: David Herrmann @ 2018-05-07 6:27 UTC (permalink / raw)
To: Wenwen Wang
Cc: Kangjie Lu, David Herrmann, Jiri Kosina, Benjamin Tissoires,
open list:UHID USERSPACE HID IO DRIVER:, open list,
Dmitry Torokhov
In-Reply-To: <1525493850-6952-1-git-send-email-wang6495@umn.edu>
Hey
On Sat, May 5, 2018 at 6:17 AM, Wenwen Wang <wang6495@umn.edu> wrote:
> In uhid_event_from_user(), if it is in_compat_syscall(), the 'type' of the
> event is first fetched from the 'buffer' in userspace and checked. If the
> 'type' is UHID_CREATE, it is a messed up request with compat pointer, which
> could be more than 256 bytes, so it is better allocated from the heap, as
> mentioned in the comment. Its fields are then prepared one by one instead
> of using a whole copy. For all other cases, the event object is copied
> directly from user space. In other words, based on the 'type', the memory
> size and structure of the event object vary.
>
> Given that the 'buffer' resides in userspace, a malicious userspace process
> can race to change the 'type' between the two copies, which will cause
> inconsistency issues, potentially security issues. Plus, various operations
> such as uhid_dev_destroy() and uhid_dev_input() are performed based on
> 'type' in function uhid_char_write(). If 'type' is modified by user, there
> could be some issues such as uninitialized uses.
>
> To fix this problem, we need to recheck the type after the second fetch to
> make sure it is not UHID_CREATE.
>
> Signed-off-by: Wenwen Wang <wang6495@umn.edu>
> ---
> drivers/hid/uhid.c | 10 ++++++++--
> 1 file changed, 8 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/hid/uhid.c b/drivers/hid/uhid.c
> index 3c55073..0220385 100644
> --- a/drivers/hid/uhid.c
> +++ b/drivers/hid/uhid.c
> @@ -447,11 +447,17 @@ static int uhid_event_from_user(const char __user *buffer, size_t len,
> event->u.create.country = compat->country;
>
> kfree(compat);
> - return 0;
> + } else {
> + if (copy_from_user(event, buffer,
> + min(len, sizeof(*event))))
> + return -EFAULT;
> + if (event->type == UHID_CREATE)
> + return -EINVAL;
You are correct, the race against malicious/buggy user-space exists.
However, it is harmless. Lets assume user-space rewrites the input,
all that happens is that we end up with garbage in the kernel.
However, input-validation is done *after* this function, hence
everything will work just fine. If user-space rewrites input-buffers,
they better be aware that this might mean random garbage is pushed
into the kernel.
IOW, this race simply allows user-space to circumvent the "compat
conversion". But if user-space wants that... let them. No point in
protecting them from doing something stupid.
Thanks
David
> }
> - /* All others can be copied directly */
> + return 0;
> }
>
> + /* Others can be copied directly */
> if (copy_from_user(event, buffer, min(len, sizeof(*event))))
> return -EFAULT;
>
> --
> 2.7.4
>
^ permalink raw reply
* Re: [PATCH v4 5/9] iio: adc: at91-sama5d2_adc: add support for position and pressure channels
From: Eugen Hristev @ 2018-05-07 6:18 UTC (permalink / raw)
To: Alexandre Belloni, Jonathan Cameron
Cc: ludovic.desroches, linux-arm-kernel, devicetree, linux-kernel,
linux-iio, linux-input, nicolas.ferre, dmitry.torokhov, robh
In-Reply-To: <20180506175914.GL10960@piout.net>
On 06.05.2018 20:59, Alexandre Belloni wrote:
> Hi,
>
> On 06/05/2018 18:29:53+0100, Jonathan Cameron wrote:
>> On Mon, 30 Apr 2018 13:32:11 +0300
>> Eugen Hristev <eugen.hristev@microchip.com> wrote:
>>
>>> This implements the support for position and pressure for the included
>>> touchscreen support in the SAMA5D2 SOC ADC block.
>>> Two position channels are added and one for pressure.
>>> They can be read in raw format, or through a buffer.
>>> A normal use case is for a consumer driver to register a callback buffer
>>> for these channels.
>>> When the touchscreen channels are in the active scan mask,
>>> the driver will start the touchscreen sampling and push the data to the
>>> buffer.
>>>
>>> Some parts of this patch are based on initial original work by
>>> Mohamed Jamsheeth Hajanajubudeen and Bandaru Venkateswara Swamy
>>>
>>> Signed-off-by: Eugen Hristev <eugen.hristev@microchip.com>
>> Looks good to me now.
>>
>> I'm assuming that once Dmitry and others are happy, I'll take the
>> series through the IIO tree. Will reply to the cover letter if the
>> rest of the patches look good to me to let everyone know that without
>> having to catch this comment down in here!
>>
>
> I'm planning to take both DT patches through the at91 tree once you take
> the DT bindings patches.
Please take into consideration that those DT patches do not build
stand-alone, they depend on
[PATCH v4 7/9] dt-bindings: iio: adc: at91-sama5d2_adc: add channel
specific consumer info
(the DT patches add an include statement of a file which is created in
this patch).
Thanks !
Eugen
>
>
^ permalink raw reply
* Re: [PATCH v3 1/3] resource: Use list_head to link sibling resource
From: Baoquan He @ 2018-05-07 1:14 UTC (permalink / raw)
To: Wei Yang
Cc: nicolas.pitre, Brijesh Singh, devicetree, David Airlie, linux-pci,
Keith Busch, Yaowei Bai, Frank Rowand, dan.j.williams,
Lorenzo Pieralisi, Stephen Hemminger, linux-nvdimm,
Patrik Jakobsson, linux-input, Borislav Petkov, Tom Lendacky,
Haiyang Zhang, josh, Jérôme Glisse, robh+dt,
Bjorn Helgaas, Thomas Gleixner, Jonathan Derrick,
Greg Kroah-Hartman
In-Reply-To: <20180426011837.GA79340@WeideMacBook-Pro.local>
Hi Wei Yang,
On 04/26/18 at 09:18am, Wei Yang wrote:
> On Thu, Apr 19, 2018 at 08:18:46AM +0800, Baoquan He wrote:
> >The struct resource uses singly linked list to link siblings. It's not
> >easy to do reverse iteration on sibling list. So replace it with list_head.
> >
>
> Hi, Baoquan
>
> Besides changing the data structure, I have another proposal to do the reverse
> iteration. Which means it would not affect other users, if you just want a
> reverse iteration.
>
> BTW, I don't think Andrew suggest to use linked-list directly. What he wants
> is a better solution to your first proposal in
> https://patchwork.kernel.org/patch/10300819/.
>
> Below is my proposal of resource reverse iteration without changing current
> design.
I got your mail and read it, then interrupted by other thing and forgot
replying, sorry.
I am fine with your code change. As I said before, I have tried to change
code per reviewers' comment, then let reviewers decide which way is
better. Please feel free to post formal patches and joining discussion
about this issue.
Thanks
Baoquan
>
> From 5d7145d44fe48b98572a03884fa3a3aa82e3cef9 Mon Sep 17 00:00:00 2001
> From: Wei Yang <richard.weiyang@gmail.com>
> Date: Sat, 24 Mar 2018 23:25:46 +0800
> Subject: [PATCH] kernel/resource: add walk_system_ram_res_rev()
>
> As discussed on https://patchwork.kernel.org/patch/10300819/, this patch
> comes up with a variant implementation of walk_system_ram_res_rev(), which
> uses iteration instead of allocating array to store those resources.
>
> Signed-off-by: Wei Yang <richard.weiyang@gmail.com>
> ---
> include/linux/ioport.h | 3 ++
> kernel/resource.c | 113 +++++++++++++++++++++++++++++++++++++++++++++++++
> 2 files changed, 116 insertions(+)
>
> diff --git a/include/linux/ioport.h b/include/linux/ioport.h
> index da0ebaec25f0..473f1d9cb97e 100644
> --- a/include/linux/ioport.h
> +++ b/include/linux/ioport.h
> @@ -277,6 +277,9 @@ extern int
> walk_system_ram_res(u64 start, u64 end, void *arg,
> int (*func)(struct resource *, void *));
> extern int
> +walk_system_ram_res_rev(u64 start, u64 end, void *arg,
> + int (*func)(struct resource *, void *));
> +extern int
> walk_iomem_res_desc(unsigned long desc, unsigned long flags, u64 start, u64 end,
> void *arg, int (*func)(struct resource *, void *));
>
> diff --git a/kernel/resource.c b/kernel/resource.c
> index 769109f20fb7..d4ec5fbc6875 100644
> --- a/kernel/resource.c
> +++ b/kernel/resource.c
> @@ -73,6 +73,38 @@ static struct resource *next_resource(struct resource *p, bool sibling_only)
> return p->sibling;
> }
>
> +static struct resource *prev_resource(struct resource *p, bool sibling_only)
> +{
> + struct resource *prev;
> + if (NULL == iomem_resource.child)
> + return NULL;
> +
> + if (p == NULL) {
> + prev = iomem_resource.child;
> + while (prev->sibling)
> + prev = prev->sibling;
> + } else {
> + if (p->parent->child == p) {
> + return p->parent;
> + }
> +
> + for (prev = p->parent->child; prev->sibling != p;
> + prev = prev->sibling) {}
> + }
> +
> + /* Caller wants to traverse through siblings only */
> + if (sibling_only)
> + return prev;
> +
> + for (;prev->child;) {
> + prev = prev->child;
> +
> + while (prev->sibling)
> + prev = prev->sibling;
> + }
> + return prev;
> +}
> +
> static void *r_next(struct seq_file *m, void *v, loff_t *pos)
> {
> struct resource *p = v;
> @@ -401,6 +433,47 @@ static int find_next_iomem_res(struct resource *res, unsigned long desc,
> return 0;
> }
>
> +/*
> + * Finds the highest iomem resource existing within [res->start.res->end).
> + * The caller must specify res->start, res->end, res->flags, and optionally
> + * desc. If found, returns 0, res is overwritten, if not found, returns -1.
> + * This function walks the whole tree and not just first level children until
> + * and unless first_level_children_only is true.
> + */
> +static int find_prev_iomem_res(struct resource *res, unsigned long desc,
> + bool first_level_children_only)
> +{
> + struct resource *p;
> +
> + BUG_ON(!res);
> + BUG_ON(res->start >= res->end);
> +
> + read_lock(&resource_lock);
> +
> + for (p = prev_resource(NULL, first_level_children_only); p;
> + p = prev_resource(p, first_level_children_only)) {
> + if ((p->flags & res->flags) != res->flags)
> + continue;
> + if ((desc != IORES_DESC_NONE) && (desc != p->desc))
> + continue;
> + if (p->end < res->start || p->child == iomem_resource.child) {
> + p = NULL;
> + break;
> + }
> + if ((p->end >= res->start) && (p->start < res->end))
> + break;
> + }
> +
> + read_unlock(&resource_lock);
> + if (!p)
> + return -1;
> + /* copy data */
> + resource_clip(res, p->start, p->end);
> + res->flags = p->flags;
> + res->desc = p->desc;
> + return 0;
> +}
> +
> static int __walk_iomem_res_desc(struct resource *res, unsigned long desc,
> bool first_level_children_only,
> void *arg,
> @@ -422,6 +495,27 @@ static int __walk_iomem_res_desc(struct resource *res, unsigned long desc,
> return ret;
> }
>
> +static int __walk_iomem_res_rev_desc(struct resource *res, unsigned long desc,
> + bool first_level_children_only,
> + void *arg,
> + int (*func)(struct resource *, void *))
> +{
> + u64 orig_start = res->start;
> + int ret = -1;
> +
> + while ((res->start < res->end) &&
> + !find_prev_iomem_res(res, desc, first_level_children_only)) {
> + ret = (*func)(res, arg);
> + if (ret)
> + break;
> +
> + res->end = res->start?(res->start - 1):0;
> + res->start = orig_start;
> + }
> +
> + return ret;
> +}
> +
> /*
> * Walks through iomem resources and calls func() with matching resource
> * ranges. This walks through whole tree and not just first level children.
> @@ -468,6 +562,25 @@ int walk_system_ram_res(u64 start, u64 end, void *arg,
> arg, func);
> }
>
> +/*
> + * This function, being a variant of walk_system_ram_res(), calls the @func
> + * callback against all memory ranges of type System RAM which are marked as
> + * IORESOURCE_SYSTEM_RAM and IORESOUCE_BUSY in reversed order, i.e., from
> + * higher to lower.
> + */
> +int walk_system_ram_res_rev(u64 start, u64 end, void *arg,
> + int (*func)(struct resource *, void *))
> +{
> + struct resource res;
> +
> + res.start = start;
> + res.end = end;
> + res.flags = IORESOURCE_SYSTEM_RAM | IORESOURCE_BUSY;
> +
> + return __walk_iomem_res_rev_desc(&res, IORES_DESC_NONE, true,
> + arg, func);
> +}
> +
> /*
> * This function calls the @func callback against all memory ranges, which
> * are ranges marked as IORESOURCE_MEM and IORESOUCE_BUSY.
> --
> 2.15.1
>
>
> --
> Wei Yang
> Help you, Help me
^ permalink raw reply
* Re: [PATCH v4 0/9] Add support for SAMA5D2 touchscreen
From: Jonathan Cameron @ 2018-05-06 19:04 UTC (permalink / raw)
To: Eugen Hristev
Cc: ludovic.desroches, alexandre.belloni, linux-arm-kernel,
devicetree, linux-kernel, linux-iio, linux-input, nicolas.ferre,
dmitry.torokhov, robh
In-Reply-To: <1525084335-11276-1-git-send-email-eugen.hristev@microchip.com>
On Mon, 30 Apr 2018 13:32:06 +0300
Eugen Hristev <eugen.hristev@microchip.com> wrote:
> Hello,
>
> This patch series is a rework of my previous series named:
> [PATCH 00/14] iio: triggers: add consumer support
>
> This is the version 4 of the series, and addresses the received feedback
> on the v2 series named:
> [PATCH v2 00/10] Add support for SAMA5D2 touchscreen
> and the v3 series named
> [PATCH v3 00/11] Add support for SAMA5D2 touchscreen
>
> This series applies on top of fixes-togreg branch of iio.git,
> specifically on top of commit:
> "f0c8d1f" : iio: adc: at91-sama5d2_adc:
> fix channel configuration for differential channels
>
> Changes in v3 and v4 are presented at the end of the cover letter below.
> Thanks everyone for the feedback. Below is the original v2 cover letter:
>
> In few words, this is the implementation of splitting the functionality
> of the IP block ADC device in SAMA5D2 SoC from ADC with touchscreen
> support. In order to avoid having a MFD device, two separate
> drivers that would work on same register base and split the IRQ,etc,
> as advised on the mailing list, I created a consumer driver for the
> channels, that will connect to the ADC as described in the device tree.
>
> I have collected feedback from everyone and here is the result:
> I have added a new generic resistive touchscreen driver, which acts
> as a iio consumer for the given channels and will create an input
> device and report the events. It uses a callback buffer to register
> to the IIO device and waits for data to be pushed.
> Inside the IIO device, I have kept a similar approach with the first version
> of the series, except that now the driver can take multiple buffers, and
> will configure the touchscreen part of the hardware device if the specific
> channels are requested.
>
> The SAMA5D2 ADC driver registers three new channels: two for the
> position on the X and Y axis, and one for the touch pressure.
> When channels are requested, it will check if the touchscreen channel mask
> includes the requested channels (it is possible that the consumer driver
> will not request pressure for example). If it's the case, it will work
> in touchscreen mode, and will refuse to do usual analog-digital conversion,
> because we have a single trigger and the touchscreen needs it.
> When the scan mask will include only old channels, the driver will function
> in the same way as before. If the scan mask somehow is a mix of the two (the
> masks intersect), the driver will refuse to work whatsoever (cannot have both
> in the same time).
> The driver allows reading raw data for the new channels, if claim direct
> mode works: no touchscreen driver requested anything. The new channels can
> act like the old ones. However, when requesting these channels, the usual
> trigger will not work and will not be enabled. The touchscreen channels
> require special trigger and irq configuration: pen detect, no pen detect
> and a periodic trigger to sample the touchscreen position and pressure.
> If the user attempts to use another trigger while there is a buffer
> that already requested the touchscreen channels (thus the trigger), the
> driver will refuse to comply.
>
> In order to have defines for the channel numbers, I added a bindings include
> file that goes on a separate commit :
> dt-bindings: iio: adc: at91-sama5d2_adc: add channel specific consumer info
> This should go in the same tree with the following commits :
> ARM: dts: at91: sama5d2: add channel cells for ADC device
> ARM: dts: at91: sama5d2: Add resistive touch device
>
> as build will break because these commits depend on the binding one
> which creates the included header file.
>
> Changes in v4:
> - removed patch for inkern module get/set kref
> - addressed feedback on both the ADC and the touchscreen driver. each
> patch has a history inside the patch file for the specific changes.
> - patch that fixes the channel fix
> [PATCH v3 01/11] iio: adc: at91-sama5d2_adc:
> fix channel configuration for differential channels
> was accepted in fixes-togreg branch thus removed from this series.
> - added Reviewed-by for the bindings by Rob Herring
>
> Changes in v3:
> - changed input driver name according to feedback and reworked in commits
> to adapt to binding changes and new name.
> - moved channel index fix in at91-sama5d2_adc at the beginning of the series
> (PATCH 01/11)
> - created a new optional binding for the touchscreen as a separate commit
> and added it to the series :
> [PATCH v3 04/11] dt-bindings: input: touchscreen: add pressure
> threshold touchscreen property
> - changed at91-sama5d2_adc driver patch to address the comments. Exact changes
> are in the patch file for the driver source file.
>
>
> Eugen Hristev (9):
> MAINTAINERS: add generic resistive touchscreen adc
> iio: Add channel for Position Relative
> dt-bindings: input: touchscreen: add pressure threshold touchscreen
> property
> dt-bindings: input: touchscreen: resistive-adc-touch: create bindings
> iio: adc: at91-sama5d2_adc: add support for position and pressure
> channels
> input: touchscreen: resistive-adc-touch: add generic resistive ADC
> touchscreen
> dt-bindings: iio: adc: at91-sama5d2_adc: add channel specific consumer
> info
> ARM: dts: at91: sama5d2: add channel cells for ADC device
> ARM: dts: at91: sama5d2: Add resistive touch device
>
> Documentation/ABI/testing/sysfs-bus-iio | 12 +
> .../bindings/iio/adc/at91-sama5d2_adc.txt | 9 +
> .../input/touchscreen/resistive-adc-touch.txt | 30 +
> .../bindings/input/touchscreen/touchscreen.txt | 3 +
> MAINTAINERS | 6 +
> arch/arm/boot/dts/sama5d2.dtsi | 12 +
> drivers/iio/adc/at91-sama5d2_adc.c | 609 +++++++++++++++++++--
> drivers/iio/industrialio-core.c | 1 +
> drivers/input/touchscreen/Kconfig | 13 +
> drivers/input/touchscreen/Makefile | 1 +
> drivers/input/touchscreen/resistive-adc-touch.c | 199 +++++++
> include/dt-bindings/iio/adc/at91-sama5d2_adc.h | 16 +
> include/uapi/linux/iio/types.h | 1 +
> tools/iio/iio_event_monitor.c | 2 +
> 14 files changed, 856 insertions(+), 58 deletions(-)
> create mode 100644 Documentation/devicetree/bindings/input/touchscreen/resistive-adc-touch.txt
> create mode 100644 drivers/input/touchscreen/resistive-adc-touch.c
> create mode 100644 include/dt-bindings/iio/adc/at91-sama5d2_adc.h
>
Hi All,
This looks to be pretty close to needing a path upstream.
I propose that I take the driver parts (not dts changes obviously) through
iio. I can do an immutable branch if anyone wants one (just let
me know).
Thanks,
Jonathan
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox