linux-gpio.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Hans de Goede <hdegoede@redhat.com>
To: Mika Westerberg <mika.westerberg@linux.intel.com>
Cc: "Rafael J . Wysocki" <rjw@rjwysocki.net>,
	Len Brown <lenb@kernel.org>,
	Andy Shevchenko <andriy.shevchenko@linux.intel.com>,
	linux-gpio@vger.kernel.org, linux-acpi@vger.kernel.org
Subject: Re: [PATCH] ACPI / button: Add DMI quirk for Acer Switch 10 SW5-032 lid-switch
Date: Tue, 19 Nov 2019 12:12:35 +0100	[thread overview]
Message-ID: <7a2ac981-1c28-5abb-0599-68da44675bdc@redhat.com> (raw)
In-Reply-To: <20191119082642.GF11621@lahna.fi.intel.com>

Hi,

On 19-11-2019 09:26, Mika Westerberg wrote:
> On Mon, Nov 18, 2019 at 04:35:56PM +0100, Hans de Goede wrote:
>> The Acer Switch 10 SW5-032 _LID method is quite broken, it looks like this:
>>
>>              Method (_LID, 0, NotSerialized)  // _LID: Lid Status
>>              {
>>                  If ((STAS & One))
>>                  {
>>                      Local0 = One
>>                      PBCG |= 0x05000000
>>                      HMCG |= 0x05000000
>>                  }
>>                  Else
>>                  {
>>                      Local0 = Zero
>>                      PBCG &= 0xF0FFFFFF
>>                      HMCG &= 0xF0FFFFFF
>>                  }
>>
>>                  ^^PCI0.GFX0.CLID = Local0
>>                  Return (Local0)
>>              }
>>
>> The problem here is the accesses to the PBCG and HMCG, these are the
>> pinconf0 registers for the power, resp. the home button GPIO,
>> e.g. PBCG is declared as:
>>
>>              OperationRegion (PWBT, SystemMemory, 0xFED0E080, 0x10)
>>              Field (PWBT, DWordAcc, NoLock, Preserve)
>>              {
>>                  PBCG,   32,
>>                  PBV1,   32,
>>                  PBSA,   32,
>>                  PBV2,   32
>>              }
>>
>> Where 0xFED0E000 is the base address of the GPO2 device and 0x80 is
>> the offset for the pin used for the powerbutton.
>>
>> The problem here is this line in _LID:
>>                      PBCG |= 0x05000000
>>
>> This changes the trigger flags of the GPIO, changing when it generates
>> interrupts. Note it does not clear the original flags. Linux uses an
>> edge triggered interrupt on both positive and negative edges. This |=
>> adds the BYT_TRIG_LVL flag to this, so now it is turned into a level
>> interrupt which fires both when low and high, iow it simply always
>> fires leading to an interrupt storm, the tablet immediately waking up
>> from suspend again, etc.
> 
> Hmm, does it work in Windows?

I bought this machine 2nd hand and the Windows install is broken
(the eMMC is dead) so I do not know with 100% certainty.

I guess it does work in Windows, I would assume so at least. I suspect
that the Windows driver for "PNP0C40" GPIO buttons devices uses level
interrupts only listening for presses which would match the "5" in the
mask.  Note that that would very much go against the ACPI description,
which describes the 4 GPIOs for pwrbutton/home/vol+/vol- as follows:

     Method (_CRS, 0, NotSerialized)  // _CRS: Current Resource Settings
     {
         Name (RBUF, ResourceTemplate ()
         {
             GpioInt (Edge, ActiveBoth, ExclusiveAndWake, PullDefault, 0x0000,
                 "\\_SB.GPO2", 0x00, ResourceConsumer, ,
                 )
                 {   // Pin list
                     0x0010
                 }
             GpioInt (Edge, ActiveBoth, ExclusiveAndWake, PullDefault, 0x0000,
                 "\\_SB.GPO2", 0x00, ResourceConsumer, ,
                 )
                 {   // Pin list
                     0x0015
                 }
             GpioInt (Edge, ActiveBoth, ExclusiveAndWake, PullDefault, 0x0000,
                 "\\_SB.GPO0", 0x00, ResourceConsumer, ,
                 )
                 {   // Pin list
                     0x0001
                 }
             GpioInt (Edge, ActiveBoth, ExclusiveAndWake, PullDefault, 0x0000,
                 "\\_SB.GPO0", 0x00, ResourceConsumer, ,
                 )
                 {   // Pin list
                     0x0000
                 }
         })
         Return (RBUF) /* \_SB_.TBAD._CRS.RBUF */
     }

Notice how all GPIOs are specified as GpioInt's which are active on
both edges and this is what the linux gpio_keys driver uses.

Working around this is not impossible, but it will be quite ugly and given
the age of the machine IMHO not worth it. I've also found out that I need a
DSDT override to be able to control the LCD backlight, this is controlled by
the 1st PWM controller in the SoC LPSS block, which is normally enumerated
through ACPI but the entire Device (PWM1) {} block is missing from the
DSDT :|  Adding it from similar hardware fixes things and makes the backlight
controllable. TL;DR: it seems that this is one of the rare cased where
people who want to run Linux will need to do a manual DSDT override :|

When they do that override they can also fix the _LID method and
then re-enable LID functionality on the kernel commandline overriding
this DMI quirk.

I will probably do a blog post on this (some people have asked me
to do some blogposts about how to analyze DSDT-s, this will be a nice
example) and add a link to the DSDT override to the blogpost, I believe
that this is the best we can do for users of this device.

In the meantime this quirk at least avoids the interrupt storm making
the device mostly usable even without the DSDT override.

>> There is nothing we can do to fix this, except for a DSDT override,
>> which the user needs to do manually. The only thing we can do is
>> never call _LID, which requires disabling the lid-switch functionality
>> altogether.
>>
>> This commit adds a quirk for this, as no lid-switch function is better
>> then the interrupt storm. A user manually applying a DSDT override can
>> also override the quirk on the kernel cmdline.
>>
>> Signed-off-by: Hans de Goede <hdegoede@redhat.com>
> 
> Reviewed-by: Mika Westerberg <mika.westerberg@linux.intel.com>

Thanks.

Regards,

Hans


  reply	other threads:[~2019-11-19 11:12 UTC|newest]

Thread overview: 10+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-11-18 15:35 [PATCH] ACPI / button: Add DMI quirk for Acer Switch 10 SW5-032 lid-switch Hans de Goede
2019-11-19  8:26 ` Mika Westerberg
2019-11-19 11:12   ` Hans de Goede [this message]
2019-11-19 11:52     ` Mika Westerberg
2019-11-19 12:44     ` Andy Shevchenko
2019-11-19 12:57       ` Mika Westerberg
2019-11-19 15:38         ` Hans de Goede
2019-11-19 16:07           ` Mika Westerberg
2019-11-19 12:46 ` Andy Shevchenko
2019-11-29 11:20 ` Rafael J. Wysocki

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=7a2ac981-1c28-5abb-0599-68da44675bdc@redhat.com \
    --to=hdegoede@redhat.com \
    --cc=andriy.shevchenko@linux.intel.com \
    --cc=lenb@kernel.org \
    --cc=linux-acpi@vger.kernel.org \
    --cc=linux-gpio@vger.kernel.org \
    --cc=mika.westerberg@linux.intel.com \
    --cc=rjw@rjwysocki.net \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).