diff mbox series

[v2] i2c: i801: Allow ACPI AML access I/O ports not reserved for SMBus

Message ID 20180830085013.64021-1-mika.westerberg@linux.intel.com
State Accepted
Headers show
Series [v2] i2c: i801: Allow ACPI AML access I/O ports not reserved for SMBus | expand

Commit Message

Mika Westerberg Aug. 30, 2018, 8:50 a.m. UTC
Commit 7ae81952cda ("i2c: i801: Allow ACPI SystemIO OpRegion to conflict
with PCI BAR") made it possible for AML code to access SMBus I/O ports
by installing custom SystemIO OpRegion handler and blocking i80i driver
access upon first AML read/write to this OpRegion.

However, while ThinkPad T560 does have SystemIO OpRegion declared under
the SMBus device, it does not access any of the SMBus registers:

    Device (SMBU)
    {
        ...

        OperationRegion (SMBP, PCI_Config, 0x50, 0x04)
        Field (SMBP, DWordAcc, NoLock, Preserve)
        {
            ,   5,
            TCOB,   11,
            Offset (0x04)
        }

        Name (TCBV, 0x00)
        Method (TCBS, 0, NotSerialized)
        {
            If ((TCBV == 0x00))
            {
            TCBV = (\_SB.PCI0.SMBU.TCOB << 0x05)
            }

            Return (TCBV) /* \_SB_.PCI0.SMBU.TCBV */
        }

        OperationRegion (TCBA, SystemIO, TCBS (), 0x10)
        Field (TCBA, ByteAcc, NoLock, Preserve)
        {
            Offset (0x04),
            ,   9,
            CPSC,   1
        }
    }

Problem with the current approach is that it blocks all I/O port access
and because this system has touchpad connected to the SMBus controller
after first AML access (happens during suspend/resume cycle) the
touchpad fails to work anymore.

Fix this so that we allow ACPI AML I/O port access if it does not touch
the region reserved for the SMBus.

Fixes: 7ae81952cda ("i2c: i801: Allow ACPI SystemIO OpRegion to conflict with PCI BAR")
Link: https://bugzilla.kernel.org/show_bug.cgi?id=200737
Reported-by: Yussuf Khalil <dev@pp3345.net>
Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
Reviewed-by: Jean Delvare <jdelvare@suse.de>
---
Changes from v1:

  - Correct off-by-one in the address check
  - Added Jean's tag

 drivers/i2c/busses/i2c-i801.c | 9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)

Comments

Wolfram Sang Aug. 30, 2018, 8:54 p.m. UTC | #1
On Thu, Aug 30, 2018 at 11:50:13AM +0300, Mika Westerberg wrote:
> Commit 7ae81952cda ("i2c: i801: Allow ACPI SystemIO OpRegion to conflict
> with PCI BAR") made it possible for AML code to access SMBus I/O ports
> by installing custom SystemIO OpRegion handler and blocking i80i driver
> access upon first AML read/write to this OpRegion.
> 
> However, while ThinkPad T560 does have SystemIO OpRegion declared under
> the SMBus device, it does not access any of the SMBus registers:
> 
>     Device (SMBU)
>     {
>         ...
> 
>         OperationRegion (SMBP, PCI_Config, 0x50, 0x04)
>         Field (SMBP, DWordAcc, NoLock, Preserve)
>         {
>             ,   5,
>             TCOB,   11,
>             Offset (0x04)
>         }
> 
>         Name (TCBV, 0x00)
>         Method (TCBS, 0, NotSerialized)
>         {
>             If ((TCBV == 0x00))
>             {
>             TCBV = (\_SB.PCI0.SMBU.TCOB << 0x05)
>             }
> 
>             Return (TCBV) /* \_SB_.PCI0.SMBU.TCBV */
>         }
> 
>         OperationRegion (TCBA, SystemIO, TCBS (), 0x10)
>         Field (TCBA, ByteAcc, NoLock, Preserve)
>         {
>             Offset (0x04),
>             ,   9,
>             CPSC,   1
>         }
>     }
> 
> Problem with the current approach is that it blocks all I/O port access
> and because this system has touchpad connected to the SMBus controller
> after first AML access (happens during suspend/resume cycle) the
> touchpad fails to work anymore.
> 
> Fix this so that we allow ACPI AML I/O port access if it does not touch
> the region reserved for the SMBus.
> 
> Fixes: 7ae81952cda ("i2c: i801: Allow ACPI SystemIO OpRegion to conflict with PCI BAR")
> Link: https://bugzilla.kernel.org/show_bug.cgi?id=200737
> Reported-by: Yussuf Khalil <dev@pp3345.net>
> Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
> Reviewed-by: Jean Delvare <jdelvare@suse.de>

Applied to for-current, thanks!
diff mbox series

Patch

diff --git a/drivers/i2c/busses/i2c-i801.c b/drivers/i2c/busses/i2c-i801.c
index 941c223f6491..04b60a349d7e 100644
--- a/drivers/i2c/busses/i2c-i801.c
+++ b/drivers/i2c/busses/i2c-i801.c
@@ -1415,6 +1415,13 @@  static void i801_add_tco(struct i801_priv *priv)
 }
 
 #ifdef CONFIG_ACPI
+static bool i801_acpi_is_smbus_ioport(const struct i801_priv *priv,
+				      acpi_physical_address address)
+{
+	return address >= priv->smba &&
+	       address <= pci_resource_end(priv->pci_dev, SMBBAR);
+}
+
 static acpi_status
 i801_acpi_io_handler(u32 function, acpi_physical_address address, u32 bits,
 		     u64 *value, void *handler_context, void *region_context)
@@ -1430,7 +1437,7 @@  i801_acpi_io_handler(u32 function, acpi_physical_address address, u32 bits,
 	 */
 	mutex_lock(&priv->acpi_lock);
 
-	if (!priv->acpi_reserved) {
+	if (!priv->acpi_reserved && i801_acpi_is_smbus_ioport(priv, address)) {
 		priv->acpi_reserved = true;
 
 		dev_warn(&pdev->dev, "BIOS is accessing SMBus registers\n");