• Hans de Goede's avatar
    ACPI: button: Add DMI quirk for Acer Switch 10 SW5-032 lid-switch · 90ed9c63
    Hans de Goede authored
    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.
    
    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: default avatarHans de Goede <hdegoede@redhat.com>
    Reviewed-by: default avatarMika Westerberg <mika.westerberg@linux.intel.com>
    Reviewed-by: default avatarAndy Shevchenko <andriy.shevchenko@linux.intel.com>
    Signed-off-by: default avatarRafael J. Wysocki <rafael.j.wysocki@intel.com>
    90ed9c63
button.c 17.8 KB