i2c: i801: Allow ACPI AML access I/O ports not reserved for SMBus
[ Upstream commit 7fd6d98b89
]
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>
Signed-off-by: Wolfram Sang <wsa@the-dreams.de>
Signed-off-by: Sasha Levin <alexander.levin@microsoft.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
pull/10/head
parent
647b6d4ff6
commit
23210d92f6
|
@ -1416,6 +1416,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)
|
||||
|
@ -1431,7 +1438,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");
|
||||
|
|
Loading…
Reference in New Issue