All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] i2c: i801: Allow ACPI SystemIO OpRegion to conflict with PCI BAR
@ 2016-04-28 10:23 Mika Westerberg
  2016-04-28 18:34 ` Andy Lutomirski
  2016-04-29 20:21 ` Rafael J. Wysocki
  0 siblings, 2 replies; 23+ messages in thread
From: Mika Westerberg @ 2016-04-28 10:23 UTC (permalink / raw)
  To: Jean Delvare, Wolfram Sang
  Cc: Jarkko Nikula, Rafael J. Wysocki, Mika Westerberg, linux-i2c, linux-acpi

Many Intel systems the BIOS declares a SystemIO OpRegion below the SMBus
PCI device as can be seen in ACPI DSDT table from Lenovo Yoga 900:

  Device (SBUS)
  {
      OperationRegion (SMBI, SystemIO, (SBAR << 0x05), 0x10)
      Field (SMBI, ByteAcc, NoLock, Preserve)
      {
          HSTS,   8,
          Offset (0x02),
          HCON,   8,
          HCOM,   8,
          TXSA,   8,
          DAT0,   8,
          DAT1,   8,
          HBDR,   8,
          PECR,   8,
          RXSA,   8,
          SDAT,   16
      }

There are also bunch of ASL methods that that the BIOS can use to access
these fields. Most of the systems in question ASL methods accessing the
SMBI OpRegion are never used.

Now, because of this SMBI OpRegion many systems fail to load the SMBus
driver with an error looking like one below:

  ACPI Warning: SystemIO range 0x0000000000003040-0x000000000000305F
       conflicts with OpRegion 0x0000000000003040-0x000000000000304F
       (\_SB.PCI0.SBUS.SMBI) (20160108/utaddress-255)
  ACPI: If an ACPI driver is available for this device, you should use
       it instead of the native driver

The reason is that this SMBI OpRegion conflicts with the PCI BAR used by
the SMBus driver.

It turns out that we can install a custom SystemIO address space handler
for the SMBus device to intercept all accesses through that OpRegion. This
allows us to share the PCI BAR with the ASL code if it for some reason is
using it. We do not expect that this OpRegion handler will ever be called
but if it is we print a warning and execute the read/write operation under
a lock which prevents ASL and OS from messing each other.

Suggested-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
---
 drivers/i2c/busses/i2c-i801.c | 83 ++++++++++++++++++++++++++++++++++++++++---
 1 file changed, 79 insertions(+), 4 deletions(-)

diff --git a/drivers/i2c/busses/i2c-i801.c b/drivers/i2c/busses/i2c-i801.c
index 5652bf6ce9be..7c0957870ee8 100644
--- a/drivers/i2c/busses/i2c-i801.c
+++ b/drivers/i2c/busses/i2c-i801.c
@@ -247,6 +247,9 @@ struct i801_priv {
 	struct platform_device *mux_pdev;
 #endif
 	struct platform_device *tco_pdev;
+
+	/* Serialize ACPI ASL and OS access to the registers */
+	struct mutex acpi_lock;
 };
 
 #define FEATURE_SMBUS_PEC	(1 << 0)
@@ -721,6 +724,7 @@ static s32 i801_access(struct i2c_adapter *adap, u16 addr,
 	struct i801_priv *priv = i2c_get_adapdata(adap);
 
 	pm_runtime_get_sync(&priv->pci_dev->dev);
+	mutex_lock(&priv->acpi_lock);
 
 	hwpec = (priv->features & FEATURE_SMBUS_PEC) && (flags & I2C_CLIENT_PEC)
 		&& size != I2C_SMBUS_QUICK
@@ -820,6 +824,7 @@ static s32 i801_access(struct i2c_adapter *adap, u16 addr,
 	}
 
 out:
+	mutex_unlock(&priv->acpi_lock);
 	pm_runtime_mark_last_busy(&priv->pci_dev->dev);
 	pm_runtime_put_autosuspend(&priv->pci_dev->dev);
 	return ret;
@@ -1260,6 +1265,75 @@ static void i801_add_tco(struct i801_priv *priv)
 	priv->tco_pdev = pdev;
 }
 
+#ifdef CONFIG_ACPI
+static acpi_status
+i801_acpi_io_handler(u32 function, acpi_physical_address address, u32 bits,
+		     u64 *value, void *handler_context, void *region_context)
+{
+	struct i801_priv *priv = handler_context;
+	struct pci_dev *pdev = priv->pci_dev;
+	acpi_status status;
+
+	dev_warn_once(&pdev->dev,
+		      "BIOS is accessing SMBus registers from ASL\n");
+
+	/*
+	 * ASL code is trying to access the I/O port. Make sure we do not
+	 * access the bus at the same time from OS side by taking the lock
+	 * here.
+	 */
+	pm_runtime_get_sync(&pdev->dev);
+	mutex_lock(&priv->acpi_lock);
+
+	if (function == ACPI_READ) {
+		u32 val = (u32)*value;
+		status = acpi_os_read_port(address, &val, bits);
+		if (ACPI_SUCCESS(status))
+			*value = val;
+	} else {
+		status = acpi_os_write_port(address, (u32)*value, bits);
+	}
+
+	mutex_unlock(&priv->acpi_lock);
+	pm_runtime_mark_last_busy(&pdev->dev);
+	pm_runtime_put_autosuspend(&pdev->dev);
+
+	return status;
+}
+
+static int i801_acpi_probe(struct i801_priv *priv)
+{
+	struct acpi_device *adev;
+	acpi_status status;
+
+	adev = ACPI_COMPANION(&priv->pci_dev->dev);
+	if (adev) {
+		status = acpi_install_address_space_handler(adev->handle,
+				ACPI_ADR_SPACE_SYSTEM_IO, i801_acpi_io_handler,
+				NULL, priv);
+		if (ACPI_SUCCESS(status))
+			return 0;
+	}
+
+	return acpi_check_resource_conflict(&priv->pci_dev->resource[SMBBAR]);
+}
+
+static void i801_acpi_remove(struct i801_priv *priv)
+{
+	struct acpi_device *adev;
+
+	adev = ACPI_COMPANION(&priv->pci_dev->dev);
+	if (!adev)
+		return;
+
+	acpi_remove_address_space_handler(adev->handle,
+		ACPI_ADR_SPACE_SYSTEM_IO, i801_acpi_io_handler);
+}
+#else
+static inline int i801_acpi_probe(struct i801_priv *priv) { return 0; }
+static inline void i801_acpi_remove(struct i801_priv *priv) { }
+#endif
+
 static int i801_probe(struct pci_dev *dev, const struct pci_device_id *id)
 {
 	unsigned char temp;
@@ -1277,6 +1351,7 @@ static int i801_probe(struct pci_dev *dev, const struct pci_device_id *id)
 	priv->adapter.dev.parent = &dev->dev;
 	ACPI_COMPANION_SET(&priv->adapter.dev, ACPI_COMPANION(&dev->dev));
 	priv->adapter.retries = 3;
+	mutex_init(&priv->acpi_lock);
 
 	priv->pci_dev = dev;
 	switch (dev->device) {
@@ -1339,10 +1414,9 @@ static int i801_probe(struct pci_dev *dev, const struct pci_device_id *id)
 		return -ENODEV;
 	}
 
-	err = acpi_check_resource_conflict(&dev->resource[SMBBAR]);
-	if (err) {
-		return -ENODEV;
-	}
+	err = i801_acpi_probe(priv);
+	if (err)
+		return err;
 
 	err = pcim_iomap_regions(dev, 1 << SMBBAR,
 				 dev_driver_string(&dev->dev));
@@ -1439,6 +1513,7 @@ static void i801_remove(struct pci_dev *dev)
 	pm_runtime_forbid(&dev->dev);
 	pm_runtime_get_noresume(&dev->dev);
 
+	i801_acpi_remove(priv);
 	i801_del_mux(priv);
 	i2c_del_adapter(&priv->adapter);
 	pci_write_config_byte(dev, SMBHSTCFG, priv->original_hstcfg);
-- 
2.8.0.rc3


^ permalink raw reply related	[flat|nested] 23+ messages in thread

* Re: [PATCH] i2c: i801: Allow ACPI SystemIO OpRegion to conflict with PCI BAR
  2016-04-28 10:23 [PATCH] i2c: i801: Allow ACPI SystemIO OpRegion to conflict with PCI BAR Mika Westerberg
@ 2016-04-28 18:34 ` Andy Lutomirski
  2016-04-29  8:56   ` Mika Westerberg
  2016-04-29  9:03   ` Pali Rohár
  2016-04-29 20:21 ` Rafael J. Wysocki
  1 sibling, 2 replies; 23+ messages in thread
From: Andy Lutomirski @ 2016-04-28 18:34 UTC (permalink / raw)
  To: Mika Westerberg, Jean Delvare, Wolfram Sang
  Cc: Jarkko Nikula, Rafael J. Wysocki, linux-i2c, linux-acpi,
	Pali Rohár, Mario Limonciello

On 04/28/2016 03:23 AM, Mika Westerberg wrote:
> Many Intel systems the BIOS declares a SystemIO OpRegion below the SMBus
> PCI device as can be seen in ACPI DSDT table from Lenovo Yoga 900:
>
>   Device (SBUS)
>   {
>       OperationRegion (SMBI, SystemIO, (SBAR << 0x05), 0x10)
>       Field (SMBI, ByteAcc, NoLock, Preserve)
>       {
>           HSTS,   8,
>           Offset (0x02),
>           HCON,   8,
>           HCOM,   8,
>           TXSA,   8,
>           DAT0,   8,
>           DAT1,   8,
>           HBDR,   8,
>           PECR,   8,
>           RXSA,   8,
>           SDAT,   16
>       }
>
> There are also bunch of ASL methods that that the BIOS can use to access
> these fields. Most of the systems in question ASL methods accessing the
> SMBI OpRegion are never used.
>
> Now, because of this SMBI OpRegion many systems fail to load the SMBus
> driver with an error looking like one below:
>
>   ACPI Warning: SystemIO range 0x0000000000003040-0x000000000000305F
>        conflicts with OpRegion 0x0000000000003040-0x000000000000304F
>        (\_SB.PCI0.SBUS.SMBI) (20160108/utaddress-255)
>   ACPI: If an ACPI driver is available for this device, you should use
>        it instead of the native driver
>
> The reason is that this SMBI OpRegion conflicts with the PCI BAR used by
> the SMBus driver.
>
> It turns out that we can install a custom SystemIO address space handler
> for the SMBus device to intercept all accesses through that OpRegion. This
> allows us to share the PCI BAR with the ASL code if it for some reason is
> using it. We do not expect that this OpRegion handler will ever be called
> but if it is we print a warning and execute the read/write operation under
> a lock which prevents ASL and OS from messing each other.

Tested-by: Andy Lutomirski <luto@kernel.org> # Dell XPS 13 9350

This successfully works around:

https://bugzilla.kernel.org/show_bug.cgi?id=110041

but the BIOS people should still fix their ASL.  Sigh.

On the Dell laptop, the observable effect is that the driver loads and 
finds the iTCO thing.

Pali, this may be considerably more useful on your laptop.

--Andy

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [PATCH] i2c: i801: Allow ACPI SystemIO OpRegion to conflict with PCI BAR
  2016-04-28 18:34 ` Andy Lutomirski
@ 2016-04-29  8:56   ` Mika Westerberg
  2016-04-30  1:13     ` Andy Lutomirski
  2016-04-29  9:03   ` Pali Rohár
  1 sibling, 1 reply; 23+ messages in thread
From: Mika Westerberg @ 2016-04-29  8:56 UTC (permalink / raw)
  To: Andy Lutomirski
  Cc: Jean Delvare, Wolfram Sang, Jarkko Nikula, Rafael J. Wysocki,
	linux-i2c, linux-acpi, Pali Rohár, Mario Limonciello

On Thu, Apr 28, 2016 at 11:34:38AM -0700, Andy Lutomirski wrote:
> On 04/28/2016 03:23 AM, Mika Westerberg wrote:
> >Many Intel systems the BIOS declares a SystemIO OpRegion below the SMBus
> >PCI device as can be seen in ACPI DSDT table from Lenovo Yoga 900:
> >
> >  Device (SBUS)
> >  {
> >      OperationRegion (SMBI, SystemIO, (SBAR << 0x05), 0x10)
> >      Field (SMBI, ByteAcc, NoLock, Preserve)
> >      {
> >          HSTS,   8,
> >          Offset (0x02),
> >          HCON,   8,
> >          HCOM,   8,
> >          TXSA,   8,
> >          DAT0,   8,
> >          DAT1,   8,
> >          HBDR,   8,
> >          PECR,   8,
> >          RXSA,   8,
> >          SDAT,   16
> >      }
> >
> >There are also bunch of ASL methods that that the BIOS can use to access
> >these fields. Most of the systems in question ASL methods accessing the
> >SMBI OpRegion are never used.
> >
> >Now, because of this SMBI OpRegion many systems fail to load the SMBus
> >driver with an error looking like one below:
> >
> >  ACPI Warning: SystemIO range 0x0000000000003040-0x000000000000305F
> >       conflicts with OpRegion 0x0000000000003040-0x000000000000304F
> >       (\_SB.PCI0.SBUS.SMBI) (20160108/utaddress-255)
> >  ACPI: If an ACPI driver is available for this device, you should use
> >       it instead of the native driver
> >
> >The reason is that this SMBI OpRegion conflicts with the PCI BAR used by
> >the SMBus driver.
> >
> >It turns out that we can install a custom SystemIO address space handler
> >for the SMBus device to intercept all accesses through that OpRegion. This
> >allows us to share the PCI BAR with the ASL code if it for some reason is
> >using it. We do not expect that this OpRegion handler will ever be called
> >but if it is we print a warning and execute the read/write operation under
> >a lock which prevents ASL and OS from messing each other.
> 
> Tested-by: Andy Lutomirski <luto@kernel.org> # Dell XPS 13 9350

Thanks for testing!

> This successfully works around:
> 
> https://bugzilla.kernel.org/show_bug.cgi?id=110041
> 
> but the BIOS people should still fix their ASL.  Sigh.

For what it's worth Kabylake BIOS should not have this OpRegion anymore.

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [PATCH] i2c: i801: Allow ACPI SystemIO OpRegion to conflict with PCI BAR
  2016-04-28 18:34 ` Andy Lutomirski
  2016-04-29  8:56   ` Mika Westerberg
@ 2016-04-29  9:03   ` Pali Rohár
  2016-04-29 18:10     ` Andy Lutomirski
  1 sibling, 1 reply; 23+ messages in thread
From: Pali Rohár @ 2016-04-29  9:03 UTC (permalink / raw)
  To: Andy Lutomirski
  Cc: Mika Westerberg, Jean Delvare, Wolfram Sang, Jarkko Nikula,
	Rafael J. Wysocki, linux-i2c, linux-acpi, Mario Limonciello

On Thursday 28 April 2016 11:34:38 Andy Lutomirski wrote:
> On 04/28/2016 03:23 AM, Mika Westerberg wrote:
> >Many Intel systems the BIOS declares a SystemIO OpRegion below the SMBus
> >PCI device as can be seen in ACPI DSDT table from Lenovo Yoga 900:
> >
> >  Device (SBUS)
> >  {
> >      OperationRegion (SMBI, SystemIO, (SBAR << 0x05), 0x10)
> >      Field (SMBI, ByteAcc, NoLock, Preserve)
> >      {
> >          HSTS,   8,
> >          Offset (0x02),
> >          HCON,   8,
> >          HCOM,   8,
> >          TXSA,   8,
> >          DAT0,   8,
> >          DAT1,   8,
> >          HBDR,   8,
> >          PECR,   8,
> >          RXSA,   8,
> >          SDAT,   16
> >      }
> >
> >There are also bunch of ASL methods that that the BIOS can use to access
> >these fields. Most of the systems in question ASL methods accessing the
> >SMBI OpRegion are never used.
> >
> >Now, because of this SMBI OpRegion many systems fail to load the SMBus
> >driver with an error looking like one below:
> >
> >  ACPI Warning: SystemIO range 0x0000000000003040-0x000000000000305F
> >       conflicts with OpRegion 0x0000000000003040-0x000000000000304F
> >       (\_SB.PCI0.SBUS.SMBI) (20160108/utaddress-255)
> >  ACPI: If an ACPI driver is available for this device, you should use
> >       it instead of the native driver
> >
> >The reason is that this SMBI OpRegion conflicts with the PCI BAR used by
> >the SMBus driver.
> >
> >It turns out that we can install a custom SystemIO address space handler
> >for the SMBus device to intercept all accesses through that OpRegion. This
> >allows us to share the PCI BAR with the ASL code if it for some reason is
> >using it. We do not expect that this OpRegion handler will ever be called
> >but if it is we print a warning and execute the read/write operation under
> >a lock which prevents ASL and OS from messing each other.
> 
> Tested-by: Andy Lutomirski <luto@kernel.org> # Dell XPS 13 9350
> 
> This successfully works around:
> 
> https://bugzilla.kernel.org/show_bug.cgi?id=110041
> 
> but the BIOS people should still fix their ASL.  Sigh.
> 
> On the Dell laptop, the observable effect is that the driver loads and finds
> the iTCO thing.
> 
> Pali, this may be considerably more useful on your laptop.

Andy, I am right that I will be able to load i2c-i801.ko driver without
acpi_enforce_resources=lax parameter?

If yes, then it sounds good! Finally I would be able to bind
lis3lv02d_i2c.ko driver for accelerometer which is on my E6440 machine.

Andy, is there any way to tell i2c-i801.ko driver that on i2c bus (which
that driver exports) is present some i2c device? Months ago I got list
of Latitude machines on which i2c address is that accelerometer present.

It is possible to hardcode that mapping (DMI name of laptop --> i2c
address) into dell-laptop driver, so i2c-i801.ko and lis3lv02d_i2c.ko
will be automatically loaded and lis3l binded correctly to i801 i2c address?

-- 
Pali Rohár
pali.rohar@gmail.com
--
To unsubscribe from this list: send the line "unsubscribe linux-acpi" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [PATCH] i2c: i801: Allow ACPI SystemIO OpRegion to conflict with PCI BAR
  2016-04-29  9:03   ` Pali Rohár
@ 2016-04-29 18:10     ` Andy Lutomirski
  2016-04-29 21:00       ` Pali Rohár
  0 siblings, 1 reply; 23+ messages in thread
From: Andy Lutomirski @ 2016-04-29 18:10 UTC (permalink / raw)
  To: Pali Rohár
  Cc: Andy Lutomirski, Mika Westerberg, Jean Delvare, Wolfram Sang,
	Jarkko Nikula, Rafael J. Wysocki, linux-i2c, Linux ACPI,
	Mario Limonciello

On Fri, Apr 29, 2016 at 2:03 AM, Pali Rohár <pali.rohar@gmail.com> wrote:
> On Thursday 28 April 2016 11:34:38 Andy Lutomirski wrote:
>> On 04/28/2016 03:23 AM, Mika Westerberg wrote:
>> >Many Intel systems the BIOS declares a SystemIO OpRegion below the SMBus
>> >PCI device as can be seen in ACPI DSDT table from Lenovo Yoga 900:
>> >
>> >  Device (SBUS)
>> >  {
>> >      OperationRegion (SMBI, SystemIO, (SBAR << 0x05), 0x10)
>> >      Field (SMBI, ByteAcc, NoLock, Preserve)
>> >      {
>> >          HSTS,   8,
>> >          Offset (0x02),
>> >          HCON,   8,
>> >          HCOM,   8,
>> >          TXSA,   8,
>> >          DAT0,   8,
>> >          DAT1,   8,
>> >          HBDR,   8,
>> >          PECR,   8,
>> >          RXSA,   8,
>> >          SDAT,   16
>> >      }
>> >
>> >There are also bunch of ASL methods that that the BIOS can use to access
>> >these fields. Most of the systems in question ASL methods accessing the
>> >SMBI OpRegion are never used.
>> >
>> >Now, because of this SMBI OpRegion many systems fail to load the SMBus
>> >driver with an error looking like one below:
>> >
>> >  ACPI Warning: SystemIO range 0x0000000000003040-0x000000000000305F
>> >       conflicts with OpRegion 0x0000000000003040-0x000000000000304F
>> >       (\_SB.PCI0.SBUS.SMBI) (20160108/utaddress-255)
>> >  ACPI: If an ACPI driver is available for this device, you should use
>> >       it instead of the native driver
>> >
>> >The reason is that this SMBI OpRegion conflicts with the PCI BAR used by
>> >the SMBus driver.
>> >
>> >It turns out that we can install a custom SystemIO address space handler
>> >for the SMBus device to intercept all accesses through that OpRegion. This
>> >allows us to share the PCI BAR with the ASL code if it for some reason is
>> >using it. We do not expect that this OpRegion handler will ever be called
>> >but if it is we print a warning and execute the read/write operation under
>> >a lock which prevents ASL and OS from messing each other.
>>
>> Tested-by: Andy Lutomirski <luto@kernel.org> # Dell XPS 13 9350
>>
>> This successfully works around:
>>
>> https://bugzilla.kernel.org/show_bug.cgi?id=110041
>>
>> but the BIOS people should still fix their ASL.  Sigh.
>>
>> On the Dell laptop, the observable effect is that the driver loads and finds
>> the iTCO thing.
>>
>> Pali, this may be considerably more useful on your laptop.
>
> Andy, I am right that I will be able to load i2c-i801.ko driver without
> acpi_enforce_resources=lax parameter?

Yes, and it works on my laptop.

>
> If yes, then it sounds good! Finally I would be able to bind
> lis3lv02d_i2c.ko driver for accelerometer which is on my E6440 machine.
>
> Andy, is there any way to tell i2c-i801.ko driver that on i2c bus (which
> that driver exports) is present some i2c device? Months ago I got list
> of Latitude machines on which i2c address is that accelerometer present.
>
> It is possible to hardcode that mapping (DMI name of laptop --> i2c
> address) into dell-laptop driver, so i2c-i801.ko and lis3lv02d_i2c.ko
> will be automatically loaded and lis3l binded correctly to i801 i2c address?

I don't know how this part works, but I doubt that doing it in
dell-laptop will be convenient.  After all, dell-laptop can load
before i2c-i801.

Jean and Wolfram: is there a quirk mechanism to add i2c devices that
aren't directly enumerable but are known to exist due to DMI?

--Andy
--
To unsubscribe from this list: send the line "unsubscribe linux-acpi" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [PATCH] i2c: i801: Allow ACPI SystemIO OpRegion to conflict with PCI BAR
  2016-04-28 10:23 [PATCH] i2c: i801: Allow ACPI SystemIO OpRegion to conflict with PCI BAR Mika Westerberg
  2016-04-28 18:34 ` Andy Lutomirski
@ 2016-04-29 20:21 ` Rafael J. Wysocki
  2016-05-02 10:21   ` Mika Westerberg
  1 sibling, 1 reply; 23+ messages in thread
From: Rafael J. Wysocki @ 2016-04-29 20:21 UTC (permalink / raw)
  To: Mika Westerberg
  Cc: Jean Delvare, Wolfram Sang, Jarkko Nikula, Rafael J. Wysocki,
	linux-i2c, ACPI Devel Maling List

On Thu, Apr 28, 2016 at 12:23 PM, Mika Westerberg
<mika.westerberg@linux.intel.com> wrote:
> Many Intel systems the BIOS declares a SystemIO OpRegion below the SMBus
> PCI device as can be seen in ACPI DSDT table from Lenovo Yoga 900:
>
>   Device (SBUS)
>   {
>       OperationRegion (SMBI, SystemIO, (SBAR << 0x05), 0x10)
>       Field (SMBI, ByteAcc, NoLock, Preserve)
>       {
>           HSTS,   8,
>           Offset (0x02),
>           HCON,   8,
>           HCOM,   8,
>           TXSA,   8,
>           DAT0,   8,
>           DAT1,   8,
>           HBDR,   8,
>           PECR,   8,
>           RXSA,   8,
>           SDAT,   16
>       }
>
> There are also bunch of ASL methods that that the BIOS can use to access
> these fields. Most of the systems in question ASL methods accessing the
> SMBI OpRegion are never used.
>
> Now, because of this SMBI OpRegion many systems fail to load the SMBus
> driver with an error looking like one below:
>
>   ACPI Warning: SystemIO range 0x0000000000003040-0x000000000000305F
>        conflicts with OpRegion 0x0000000000003040-0x000000000000304F
>        (\_SB.PCI0.SBUS.SMBI) (20160108/utaddress-255)
>   ACPI: If an ACPI driver is available for this device, you should use
>        it instead of the native driver
>
> The reason is that this SMBI OpRegion conflicts with the PCI BAR used by
> the SMBus driver.
>
> It turns out that we can install a custom SystemIO address space handler
> for the SMBus device to intercept all accesses through that OpRegion. This
> allows us to share the PCI BAR with the ASL code if it for some reason is
> using it. We do not expect that this OpRegion handler will ever be called
> but if it is we print a warning and execute the read/write operation under
> a lock which prevents ASL and OS from messing each other.
>
> Suggested-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
> Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>

Acked-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>

If it addresses any public BZ bugs, it would be good to add Link: tags
for those and maybe Reported-by: for the reporters?


> ---
>  drivers/i2c/busses/i2c-i801.c | 83 ++++++++++++++++++++++++++++++++++++++++---
>  1 file changed, 79 insertions(+), 4 deletions(-)
>
> diff --git a/drivers/i2c/busses/i2c-i801.c b/drivers/i2c/busses/i2c-i801.c
> index 5652bf6ce9be..7c0957870ee8 100644
> --- a/drivers/i2c/busses/i2c-i801.c
> +++ b/drivers/i2c/busses/i2c-i801.c
> @@ -247,6 +247,9 @@ struct i801_priv {
>         struct platform_device *mux_pdev;
>  #endif
>         struct platform_device *tco_pdev;
> +
> +       /* Serialize ACPI ASL and OS access to the registers */
> +       struct mutex acpi_lock;
>  };
>
>  #define FEATURE_SMBUS_PEC      (1 << 0)
> @@ -721,6 +724,7 @@ static s32 i801_access(struct i2c_adapter *adap, u16 addr,
>         struct i801_priv *priv = i2c_get_adapdata(adap);
>
>         pm_runtime_get_sync(&priv->pci_dev->dev);
> +       mutex_lock(&priv->acpi_lock);
>
>         hwpec = (priv->features & FEATURE_SMBUS_PEC) && (flags & I2C_CLIENT_PEC)
>                 && size != I2C_SMBUS_QUICK
> @@ -820,6 +824,7 @@ static s32 i801_access(struct i2c_adapter *adap, u16 addr,
>         }
>
>  out:
> +       mutex_unlock(&priv->acpi_lock);
>         pm_runtime_mark_last_busy(&priv->pci_dev->dev);
>         pm_runtime_put_autosuspend(&priv->pci_dev->dev);
>         return ret;
> @@ -1260,6 +1265,75 @@ static void i801_add_tco(struct i801_priv *priv)
>         priv->tco_pdev = pdev;
>  }
>
> +#ifdef CONFIG_ACPI
> +static acpi_status
> +i801_acpi_io_handler(u32 function, acpi_physical_address address, u32 bits,
> +                    u64 *value, void *handler_context, void *region_context)
> +{
> +       struct i801_priv *priv = handler_context;
> +       struct pci_dev *pdev = priv->pci_dev;
> +       acpi_status status;
> +
> +       dev_warn_once(&pdev->dev,
> +                     "BIOS is accessing SMBus registers from ASL\n");
> +
> +       /*
> +        * ASL code is trying to access the I/O port. Make sure we do not
> +        * access the bus at the same time from OS side by taking the lock
> +        * here.
> +        */
> +       pm_runtime_get_sync(&pdev->dev);
> +       mutex_lock(&priv->acpi_lock);
> +
> +       if (function == ACPI_READ) {
> +               u32 val = (u32)*value;
> +               status = acpi_os_read_port(address, &val, bits);
> +               if (ACPI_SUCCESS(status))
> +                       *value = val;
> +       } else {
> +               status = acpi_os_write_port(address, (u32)*value, bits);
> +       }
> +
> +       mutex_unlock(&priv->acpi_lock);
> +       pm_runtime_mark_last_busy(&pdev->dev);
> +       pm_runtime_put_autosuspend(&pdev->dev);
> +
> +       return status;
> +}
> +
> +static int i801_acpi_probe(struct i801_priv *priv)
> +{
> +       struct acpi_device *adev;
> +       acpi_status status;
> +
> +       adev = ACPI_COMPANION(&priv->pci_dev->dev);
> +       if (adev) {
> +               status = acpi_install_address_space_handler(adev->handle,
> +                               ACPI_ADR_SPACE_SYSTEM_IO, i801_acpi_io_handler,
> +                               NULL, priv);
> +               if (ACPI_SUCCESS(status))
> +                       return 0;
> +       }
> +
> +       return acpi_check_resource_conflict(&priv->pci_dev->resource[SMBBAR]);
> +}
> +
> +static void i801_acpi_remove(struct i801_priv *priv)
> +{
> +       struct acpi_device *adev;
> +
> +       adev = ACPI_COMPANION(&priv->pci_dev->dev);
> +       if (!adev)
> +               return;
> +
> +       acpi_remove_address_space_handler(adev->handle,
> +               ACPI_ADR_SPACE_SYSTEM_IO, i801_acpi_io_handler);
> +}
> +#else
> +static inline int i801_acpi_probe(struct i801_priv *priv) { return 0; }
> +static inline void i801_acpi_remove(struct i801_priv *priv) { }
> +#endif
> +
>  static int i801_probe(struct pci_dev *dev, const struct pci_device_id *id)
>  {
>         unsigned char temp;
> @@ -1277,6 +1351,7 @@ static int i801_probe(struct pci_dev *dev, const struct pci_device_id *id)
>         priv->adapter.dev.parent = &dev->dev;
>         ACPI_COMPANION_SET(&priv->adapter.dev, ACPI_COMPANION(&dev->dev));
>         priv->adapter.retries = 3;
> +       mutex_init(&priv->acpi_lock);
>
>         priv->pci_dev = dev;
>         switch (dev->device) {
> @@ -1339,10 +1414,9 @@ static int i801_probe(struct pci_dev *dev, const struct pci_device_id *id)
>                 return -ENODEV;
>         }
>
> -       err = acpi_check_resource_conflict(&dev->resource[SMBBAR]);
> -       if (err) {
> -               return -ENODEV;
> -       }
> +       err = i801_acpi_probe(priv);
> +       if (err)
> +               return err;
>
>         err = pcim_iomap_regions(dev, 1 << SMBBAR,
>                                  dev_driver_string(&dev->dev));
> @@ -1439,6 +1513,7 @@ static void i801_remove(struct pci_dev *dev)
>         pm_runtime_forbid(&dev->dev);
>         pm_runtime_get_noresume(&dev->dev);
>
> +       i801_acpi_remove(priv);
>         i801_del_mux(priv);
>         i2c_del_adapter(&priv->adapter);
>         pci_write_config_byte(dev, SMBHSTCFG, priv->original_hstcfg);
> --
> 2.8.0.rc3
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-acpi" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [PATCH] i2c: i801: Allow ACPI SystemIO OpRegion to conflict with PCI BAR
  2016-04-29 18:10     ` Andy Lutomirski
@ 2016-04-29 21:00       ` Pali Rohár
  2016-04-29 21:42         ` Andy Lutomirski
  0 siblings, 1 reply; 23+ messages in thread
From: Pali Rohár @ 2016-04-29 21:00 UTC (permalink / raw)
  To: Andy Lutomirski
  Cc: Andy Lutomirski, Mika Westerberg, Jean Delvare, Wolfram Sang,
	Jarkko Nikula, Rafael J. Wysocki, linux-i2c, Linux ACPI,
	Mario Limonciello

[-- Attachment #1: Type: Text/Plain, Size: 3989 bytes --]

On Friday 29 April 2016 20:10:23 Andy Lutomirski wrote:
> On Fri, Apr 29, 2016 at 2:03 AM, Pali Rohár <pali.rohar@gmail.com>
> wrote:
> > On Thursday 28 April 2016 11:34:38 Andy Lutomirski wrote:
> >> On 04/28/2016 03:23 AM, Mika Westerberg wrote:
> >> >Many Intel systems the BIOS declares a SystemIO OpRegion below
> >> >the SMBus
> >> >
> >> >PCI device as can be seen in ACPI DSDT table from Lenovo Yoga 900:
> >> >  Device (SBUS)
> >> >  {
> >> >  
> >> >      OperationRegion (SMBI, SystemIO, (SBAR << 0x05), 0x10)
> >> >      Field (SMBI, ByteAcc, NoLock, Preserve)
> >> >      {
> >> >      
> >> >          HSTS,   8,
> >> >          Offset (0x02),
> >> >          HCON,   8,
> >> >          HCOM,   8,
> >> >          TXSA,   8,
> >> >          DAT0,   8,
> >> >          DAT1,   8,
> >> >          HBDR,   8,
> >> >          PECR,   8,
> >> >          RXSA,   8,
> >> >          SDAT,   16
> >> >      
> >> >      }
> >> >
> >> >There are also bunch of ASL methods that that the BIOS can use to
> >> >access these fields. Most of the systems in question ASL methods
> >> >accessing the SMBI OpRegion are never used.
> >> >
> >> >Now, because of this SMBI OpRegion many systems fail to load the
> >> >SMBus
> >> >
> >> >driver with an error looking like one below:
> >> >  ACPI Warning: SystemIO range
> >> >  0x0000000000003040-0x000000000000305F
> >> >  
> >> >       conflicts with OpRegion
> >> >       0x0000000000003040-0x000000000000304F
> >> >       (\_SB.PCI0.SBUS.SMBI) (20160108/utaddress-255)
> >> >  
> >> >  ACPI: If an ACPI driver is available for this device, you
> >> >  should use
> >> >  
> >> >       it instead of the native driver
> >> >
> >> >The reason is that this SMBI OpRegion conflicts with the PCI BAR
> >> >used by the SMBus driver.
> >> >
> >> >It turns out that we can install a custom SystemIO address space
> >> >handler for the SMBus device to intercept all accesses through
> >> >that OpRegion. This allows us to share the PCI BAR with the ASL
> >> >code if it for some reason is using it. We do not expect that
> >> >this OpRegion handler will ever be called but if it is we print
> >> >a warning and execute the read/write operation under a lock
> >> >which prevents ASL and OS from messing each other.
> >> 
> >> Tested-by: Andy Lutomirski <luto@kernel.org> # Dell XPS 13 9350
> >> 
> >> This successfully works around:
> >> 
> >> https://bugzilla.kernel.org/show_bug.cgi?id=110041
> >> 
> >> but the BIOS people should still fix their ASL.  Sigh.
> >> 
> >> On the Dell laptop, the observable effect is that the driver loads
> >> and finds the iTCO thing.
> >> 
> >> Pali, this may be considerably more useful on your laptop.
> > 
> > Andy, I am right that I will be able to load i2c-i801.ko driver
> > without acpi_enforce_resources=lax parameter?
> 
> Yes, and it works on my laptop.

Looks like it is working also on my laptop.

> > If yes, then it sounds good! Finally I would be able to bind
> > lis3lv02d_i2c.ko driver for accelerometer which is on my E6440
> > machine.
> > 
> > Andy, is there any way to tell i2c-i801.ko driver that on i2c bus
> > (which that driver exports) is present some i2c device? Months ago
> > I got list of Latitude machines on which i2c address is that
> > accelerometer present.
> > 
> > It is possible to hardcode that mapping (DMI name of laptop --> i2c
> > address) into dell-laptop driver, so i2c-i801.ko and
> > lis3lv02d_i2c.ko will be automatically loaded and lis3l binded
> > correctly to i801 i2c address?
> 
> I don't know how this part works, but I doubt that doing it in
> dell-laptop will be convenient.  After all, dell-laptop can load
> before i2c-i801.
> 
> Jean and Wolfram: is there a quirk mechanism to add i2c devices that
> aren't directly enumerable but are known to exist due to DMI?

Maybe something like i2c_register_board_info()?

-- 
Pali Rohár
pali.rohar@gmail.com

[-- Attachment #2: This is a digitally signed message part. --]
[-- Type: application/pgp-signature, Size: 198 bytes --]

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [PATCH] i2c: i801: Allow ACPI SystemIO OpRegion to conflict with PCI BAR
  2016-04-29 21:00       ` Pali Rohár
@ 2016-04-29 21:42         ` Andy Lutomirski
  2016-04-30  0:56           ` Andy Lutomirski
  0 siblings, 1 reply; 23+ messages in thread
From: Andy Lutomirski @ 2016-04-29 21:42 UTC (permalink / raw)
  To: Pali Rohár
  Cc: Andy Lutomirski, Mika Westerberg, Jean Delvare, Wolfram Sang,
	Jarkko Nikula, Rafael J. Wysocki, linux-i2c, Linux ACPI,
	Mario Limonciello

On Fri, Apr 29, 2016 at 2:00 PM, Pali Rohár <pali.rohar@gmail.com> wrote:
> On Friday 29 April 2016 20:10:23 Andy Lutomirski wrote:
>> On Fri, Apr 29, 2016 at 2:03 AM, Pali Rohár <pali.rohar@gmail.com>
>> wrote:
>> > On Thursday 28 April 2016 11:34:38 Andy Lutomirski wrote:
>> >> On 04/28/2016 03:23 AM, Mika Westerberg wrote:
>> >> >Many Intel systems the BIOS declares a SystemIO OpRegion below
>> >> >the SMBus
>> >> >
>> >> >PCI device as can be seen in ACPI DSDT table from Lenovo Yoga 900:
>> >> >  Device (SBUS)
>> >> >  {
>> >> >
>> >> >      OperationRegion (SMBI, SystemIO, (SBAR << 0x05), 0x10)
>> >> >      Field (SMBI, ByteAcc, NoLock, Preserve)
>> >> >      {
>> >> >
>> >> >          HSTS,   8,
>> >> >          Offset (0x02),
>> >> >          HCON,   8,
>> >> >          HCOM,   8,
>> >> >          TXSA,   8,
>> >> >          DAT0,   8,
>> >> >          DAT1,   8,
>> >> >          HBDR,   8,
>> >> >          PECR,   8,
>> >> >          RXSA,   8,
>> >> >          SDAT,   16
>> >> >
>> >> >      }
>> >> >
>> >> >There are also bunch of ASL methods that that the BIOS can use to
>> >> >access these fields. Most of the systems in question ASL methods
>> >> >accessing the SMBI OpRegion are never used.
>> >> >
>> >> >Now, because of this SMBI OpRegion many systems fail to load the
>> >> >SMBus
>> >> >
>> >> >driver with an error looking like one below:
>> >> >  ACPI Warning: SystemIO range
>> >> >  0x0000000000003040-0x000000000000305F
>> >> >
>> >> >       conflicts with OpRegion
>> >> >       0x0000000000003040-0x000000000000304F
>> >> >       (\_SB.PCI0.SBUS.SMBI) (20160108/utaddress-255)
>> >> >
>> >> >  ACPI: If an ACPI driver is available for this device, you
>> >> >  should use
>> >> >
>> >> >       it instead of the native driver
>> >> >
>> >> >The reason is that this SMBI OpRegion conflicts with the PCI BAR
>> >> >used by the SMBus driver.
>> >> >
>> >> >It turns out that we can install a custom SystemIO address space
>> >> >handler for the SMBus device to intercept all accesses through
>> >> >that OpRegion. This allows us to share the PCI BAR with the ASL
>> >> >code if it for some reason is using it. We do not expect that
>> >> >this OpRegion handler will ever be called but if it is we print
>> >> >a warning and execute the read/write operation under a lock
>> >> >which prevents ASL and OS from messing each other.
>> >>
>> >> Tested-by: Andy Lutomirski <luto@kernel.org> # Dell XPS 13 9350
>> >>
>> >> This successfully works around:
>> >>
>> >> https://bugzilla.kernel.org/show_bug.cgi?id=110041
>> >>
>> >> but the BIOS people should still fix their ASL.  Sigh.
>> >>
>> >> On the Dell laptop, the observable effect is that the driver loads
>> >> and finds the iTCO thing.
>> >>
>> >> Pali, this may be considerably more useful on your laptop.
>> >
>> > Andy, I am right that I will be able to load i2c-i801.ko driver
>> > without acpi_enforce_resources=lax parameter?
>>
>> Yes, and it works on my laptop.
>
> Looks like it is working also on my laptop.
>
>> > If yes, then it sounds good! Finally I would be able to bind
>> > lis3lv02d_i2c.ko driver for accelerometer which is on my E6440
>> > machine.
>> >
>> > Andy, is there any way to tell i2c-i801.ko driver that on i2c bus
>> > (which that driver exports) is present some i2c device? Months ago
>> > I got list of Latitude machines on which i2c address is that
>> > accelerometer present.
>> >
>> > It is possible to hardcode that mapping (DMI name of laptop --> i2c
>> > address) into dell-laptop driver, so i2c-i801.ko and
>> > lis3lv02d_i2c.ko will be automatically loaded and lis3l binded
>> > correctly to i801 i2c address?
>>
>> I don't know how this part works, but I doubt that doing it in
>> dell-laptop will be convenient.  After all, dell-laptop can load
>> before i2c-i801.
>>
>> Jean and Wolfram: is there a quirk mechanism to add i2c devices that
>> aren't directly enumerable but are known to exist due to DMI?
>
> Maybe something like i2c_register_board_info()?

Maybe.  i think that wants to be called before the adapter shows up, though.

--Andy
--
To unsubscribe from this list: send the line "unsubscribe linux-acpi" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [PATCH] i2c: i801: Allow ACPI SystemIO OpRegion to conflict with PCI BAR
  2016-04-29 21:42         ` Andy Lutomirski
@ 2016-04-30  0:56           ` Andy Lutomirski
  2016-04-30  8:12             ` Pali Rohár
                               ` (2 more replies)
  0 siblings, 3 replies; 23+ messages in thread
From: Andy Lutomirski @ 2016-04-30  0:56 UTC (permalink / raw)
  To: Pali Rohár
  Cc: Andy Lutomirski, Mika Westerberg, Jean Delvare, Wolfram Sang,
	Jarkko Nikula, Rafael J. Wysocki, linux-i2c, Linux ACPI,
	Mario Limonciello

On Fri, Apr 29, 2016 at 2:42 PM, Andy Lutomirski <luto@amacapital.net> wrote:
> On Fri, Apr 29, 2016 at 2:00 PM, Pali Rohár <pali.rohar@gmail.com> wrote:
>> On Friday 29 April 2016 20:10:23 Andy Lutomirski wrote:
>>> On Fri, Apr 29, 2016 at 2:03 AM, Pali Rohár <pali.rohar@gmail.com>
>>> wrote:
>>> > On Thursday 28 April 2016 11:34:38 Andy Lutomirski wrote:
>>> >> On 04/28/2016 03:23 AM, Mika Westerberg wrote:
>>> >> >Many Intel systems the BIOS declares a SystemIO OpRegion below
>>> >> >the SMBus
>>> >> >
>>> >> >PCI device as can be seen in ACPI DSDT table from Lenovo Yoga 900:
>>> >> >  Device (SBUS)
>>> >> >  {
>>> >> >
>>> >> >      OperationRegion (SMBI, SystemIO, (SBAR << 0x05), 0x10)
>>> >> >      Field (SMBI, ByteAcc, NoLock, Preserve)
>>> >> >      {
>>> >> >
>>> >> >          HSTS,   8,
>>> >> >          Offset (0x02),
>>> >> >          HCON,   8,
>>> >> >          HCOM,   8,
>>> >> >          TXSA,   8,
>>> >> >          DAT0,   8,
>>> >> >          DAT1,   8,
>>> >> >          HBDR,   8,
>>> >> >          PECR,   8,
>>> >> >          RXSA,   8,
>>> >> >          SDAT,   16
>>> >> >
>>> >> >      }
>>> >> >
>>> >> >There are also bunch of ASL methods that that the BIOS can use to
>>> >> >access these fields. Most of the systems in question ASL methods
>>> >> >accessing the SMBI OpRegion are never used.
>>> >> >
>>> >> >Now, because of this SMBI OpRegion many systems fail to load the
>>> >> >SMBus
>>> >> >
>>> >> >driver with an error looking like one below:
>>> >> >  ACPI Warning: SystemIO range
>>> >> >  0x0000000000003040-0x000000000000305F
>>> >> >
>>> >> >       conflicts with OpRegion
>>> >> >       0x0000000000003040-0x000000000000304F
>>> >> >       (\_SB.PCI0.SBUS.SMBI) (20160108/utaddress-255)
>>> >> >
>>> >> >  ACPI: If an ACPI driver is available for this device, you
>>> >> >  should use
>>> >> >
>>> >> >       it instead of the native driver
>>> >> >
>>> >> >The reason is that this SMBI OpRegion conflicts with the PCI BAR
>>> >> >used by the SMBus driver.
>>> >> >
>>> >> >It turns out that we can install a custom SystemIO address space
>>> >> >handler for the SMBus device to intercept all accesses through
>>> >> >that OpRegion. This allows us to share the PCI BAR with the ASL
>>> >> >code if it for some reason is using it. We do not expect that
>>> >> >this OpRegion handler will ever be called but if it is we print
>>> >> >a warning and execute the read/write operation under a lock
>>> >> >which prevents ASL and OS from messing each other.
>>> >>
>>> >> Tested-by: Andy Lutomirski <luto@kernel.org> # Dell XPS 13 9350
>>> >>
>>> >> This successfully works around:
>>> >>
>>> >> https://bugzilla.kernel.org/show_bug.cgi?id=110041
>>> >>
>>> >> but the BIOS people should still fix their ASL.  Sigh.
>>> >>
>>> >> On the Dell laptop, the observable effect is that the driver loads
>>> >> and finds the iTCO thing.
>>> >>
>>> >> Pali, this may be considerably more useful on your laptop.
>>> >
>>> > Andy, I am right that I will be able to load i2c-i801.ko driver
>>> > without acpi_enforce_resources=lax parameter?
>>>
>>> Yes, and it works on my laptop.
>>
>> Looks like it is working also on my laptop.
>>
>>> > If yes, then it sounds good! Finally I would be able to bind
>>> > lis3lv02d_i2c.ko driver for accelerometer which is on my E6440
>>> > machine.
>>> >
>>> > Andy, is there any way to tell i2c-i801.ko driver that on i2c bus
>>> > (which that driver exports) is present some i2c device? Months ago
>>> > I got list of Latitude machines on which i2c address is that
>>> > accelerometer present.
>>> >
>>> > It is possible to hardcode that mapping (DMI name of laptop --> i2c
>>> > address) into dell-laptop driver, so i2c-i801.ko and
>>> > lis3lv02d_i2c.ko will be automatically loaded and lis3l binded
>>> > correctly to i801 i2c address?
>>>
>>> I don't know how this part works, but I doubt that doing it in
>>> dell-laptop will be convenient.  After all, dell-laptop can load
>>> before i2c-i801.
>>>
>>> Jean and Wolfram: is there a quirk mechanism to add i2c devices that
>>> aren't directly enumerable but are known to exist due to DMI?
>>
>> Maybe something like i2c_register_board_info()?
>
> Maybe.  i think that wants to be called before the adapter shows up, though.

i2c_probe_optional_slaves may be a more appropriate place to put this.

Also, is there any indication in your DSDT that this thing exists?

--Andy
--
To unsubscribe from this list: send the line "unsubscribe linux-acpi" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [PATCH] i2c: i801: Allow ACPI SystemIO OpRegion to conflict with PCI BAR
  2016-04-29  8:56   ` Mika Westerberg
@ 2016-04-30  1:13     ` Andy Lutomirski
  2016-05-02 10:12       ` Mika Westerberg
  0 siblings, 1 reply; 23+ messages in thread
From: Andy Lutomirski @ 2016-04-30  1:13 UTC (permalink / raw)
  To: Mika Westerberg
  Cc: Andy Lutomirski, Jean Delvare, Wolfram Sang, Jarkko Nikula,
	Rafael J. Wysocki, linux-i2c, Linux ACPI, Pali Rohár,
	Mario Limonciello

On Fri, Apr 29, 2016 at 1:56 AM, Mika Westerberg
<mika.westerberg@linux.intel.com> wrote:
> On Thu, Apr 28, 2016 at 11:34:38AM -0700, Andy Lutomirski wrote:
>> On 04/28/2016 03:23 AM, Mika Westerberg wrote:
>> >Many Intel systems the BIOS declares a SystemIO OpRegion below the SMBus
>> >PCI device as can be seen in ACPI DSDT table from Lenovo Yoga 900:
>> >
>> >  Device (SBUS)
>> >  {
>> >      OperationRegion (SMBI, SystemIO, (SBAR << 0x05), 0x10)
>> >      Field (SMBI, ByteAcc, NoLock, Preserve)
>> >      {
>> >          HSTS,   8,
>> >          Offset (0x02),
>> >          HCON,   8,
>> >          HCOM,   8,
>> >          TXSA,   8,
>> >          DAT0,   8,
>> >          DAT1,   8,
>> >          HBDR,   8,
>> >          PECR,   8,
>> >          RXSA,   8,
>> >          SDAT,   16
>> >      }
>> >
>> >There are also bunch of ASL methods that that the BIOS can use to access
>> >these fields. Most of the systems in question ASL methods accessing the
>> >SMBI OpRegion are never used.
>> >
>> >Now, because of this SMBI OpRegion many systems fail to load the SMBus
>> >driver with an error looking like one below:
>> >
>> >  ACPI Warning: SystemIO range 0x0000000000003040-0x000000000000305F
>> >       conflicts with OpRegion 0x0000000000003040-0x000000000000304F
>> >       (\_SB.PCI0.SBUS.SMBI) (20160108/utaddress-255)
>> >  ACPI: If an ACPI driver is available for this device, you should use
>> >       it instead of the native driver
>> >
>> >The reason is that this SMBI OpRegion conflicts with the PCI BAR used by
>> >the SMBus driver.
>> >
>> >It turns out that we can install a custom SystemIO address space handler
>> >for the SMBus device to intercept all accesses through that OpRegion. This
>> >allows us to share the PCI BAR with the ASL code if it for some reason is
>> >using it. We do not expect that this OpRegion handler will ever be called
>> >but if it is we print a warning and execute the read/write operation under
>> >a lock which prevents ASL and OS from messing each other.
>>
>> Tested-by: Andy Lutomirski <luto@kernel.org> # Dell XPS 13 9350
>
> Thanks for testing!

A question, though: there's nothing that keeps i801_access from being
called in between consecutive ACPI accesses.  Could this confuse the
ASL code?  Would it be helpful if i801_access were to save away the
old register state and restore it when it's done in the event that an
opregion access has been seen so that the ASL-configured state doesn't
get stomped on?

Also, what happens if i801_access happens while the i801 master is
busy with an ASL-initiated transaction?  Will it wait for the
transaction to finish?

If this is a problem, an alternative approach might be to virtualize
the registers as seen by ACPI and to only load them into the real
registers when a transaction starts.

Also, what happens if the opregion is declared globally instead of in
the scope of the ACPI companion?  Does that happen?  If so, it might
make sense to deny loading the driver unless in lax mode.

--Andy

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [PATCH] i2c: i801: Allow ACPI SystemIO OpRegion to conflict with PCI BAR
  2016-04-30  0:56           ` Andy Lutomirski
@ 2016-04-30  8:12             ` Pali Rohár
  2016-05-05  8:27             ` Pali Rohár
  2016-05-07 15:06             ` Jean Delvare
  2 siblings, 0 replies; 23+ messages in thread
From: Pali Rohár @ 2016-04-30  8:12 UTC (permalink / raw)
  To: Andy Lutomirski
  Cc: Andy Lutomirski, Mika Westerberg, Jean Delvare, Wolfram Sang,
	Jarkko Nikula, Rafael J. Wysocki, linux-i2c, Linux ACPI,
	Mario Limonciello

[-- Attachment #1: Type: Text/Plain, Size: 5507 bytes --]

On Saturday 30 April 2016 02:56:14 Andy Lutomirski wrote:
> On Fri, Apr 29, 2016 at 2:42 PM, Andy Lutomirski <luto@amacapital.net>
> wrote:
> > On Fri, Apr 29, 2016 at 2:00 PM, Pali Rohár <pali.rohar@gmail.com>
> > wrote:
> >> On Friday 29 April 2016 20:10:23 Andy Lutomirski wrote:
> >>> On Fri, Apr 29, 2016 at 2:03 AM, Pali Rohár
> >>> <pali.rohar@gmail.com>
> >>> 
> >>> wrote:
> >>> > On Thursday 28 April 2016 11:34:38 Andy Lutomirski wrote:
> >>> >> On 04/28/2016 03:23 AM, Mika Westerberg wrote:
> >>> >> >Many Intel systems the BIOS declares a SystemIO OpRegion
> >>> >> >below the SMBus
> >>> >> >
> >>> >> >PCI device as can be seen in ACPI DSDT table from Lenovo Yoga
> >>> >> >900:
> >>> >> >  Device (SBUS)
> >>> >> >  {
> >>> >> >  
> >>> >> >      OperationRegion (SMBI, SystemIO, (SBAR << 0x05), 0x10)
> >>> >> >      Field (SMBI, ByteAcc, NoLock, Preserve)
> >>> >> >      {
> >>> >> >      
> >>> >> >          HSTS,   8,
> >>> >> >          Offset (0x02),
> >>> >> >          HCON,   8,
> >>> >> >          HCOM,   8,
> >>> >> >          TXSA,   8,
> >>> >> >          DAT0,   8,
> >>> >> >          DAT1,   8,
> >>> >> >          HBDR,   8,
> >>> >> >          PECR,   8,
> >>> >> >          RXSA,   8,
> >>> >> >          SDAT,   16
> >>> >> >      
> >>> >> >      }
> >>> >> >
> >>> >> >There are also bunch of ASL methods that that the BIOS can
> >>> >> >use to access these fields. Most of the systems in question
> >>> >> >ASL methods accessing the SMBI OpRegion are never used.
> >>> >> >
> >>> >> >Now, because of this SMBI OpRegion many systems fail to load
> >>> >> >the SMBus
> >>> >> >
> >>> >> >driver with an error looking like one below:
> >>> >> >  ACPI Warning: SystemIO range
> >>> >> >  0x0000000000003040-0x000000000000305F
> >>> >> >  
> >>> >> >       conflicts with OpRegion
> >>> >> >       0x0000000000003040-0x000000000000304F
> >>> >> >       (\_SB.PCI0.SBUS.SMBI) (20160108/utaddress-255)
> >>> >> >  
> >>> >> >  ACPI: If an ACPI driver is available for this device, you
> >>> >> >  should use
> >>> >> >  
> >>> >> >       it instead of the native driver
> >>> >> >
> >>> >> >The reason is that this SMBI OpRegion conflicts with the PCI
> >>> >> >BAR used by the SMBus driver.
> >>> >> >
> >>> >> >It turns out that we can install a custom SystemIO address
> >>> >> >space handler for the SMBus device to intercept all accesses
> >>> >> >through that OpRegion. This allows us to share the PCI BAR
> >>> >> >with the ASL code if it for some reason is using it. We do
> >>> >> >not expect that this OpRegion handler will ever be called
> >>> >> >but if it is we print a warning and execute the read/write
> >>> >> >operation under a lock which prevents ASL and OS from
> >>> >> >messing each other.
> >>> >> 
> >>> >> Tested-by: Andy Lutomirski <luto@kernel.org> # Dell XPS 13
> >>> >> 9350
> >>> >> 
> >>> >> This successfully works around:
> >>> >> 
> >>> >> https://bugzilla.kernel.org/show_bug.cgi?id=110041
> >>> >> 
> >>> >> but the BIOS people should still fix their ASL.  Sigh.
> >>> >> 
> >>> >> On the Dell laptop, the observable effect is that the driver
> >>> >> loads and finds the iTCO thing.
> >>> >> 
> >>> >> Pali, this may be considerably more useful on your laptop.
> >>> > 
> >>> > Andy, I am right that I will be able to load i2c-i801.ko driver
> >>> > without acpi_enforce_resources=lax parameter?
> >>> 
> >>> Yes, and it works on my laptop.
> >> 
> >> Looks like it is working also on my laptop.
> >> 
> >>> > If yes, then it sounds good! Finally I would be able to bind
> >>> > lis3lv02d_i2c.ko driver for accelerometer which is on my E6440
> >>> > machine.
> >>> > 
> >>> > Andy, is there any way to tell i2c-i801.ko driver that on i2c
> >>> > bus (which that driver exports) is present some i2c device?
> >>> > Months ago I got list of Latitude machines on which i2c
> >>> > address is that accelerometer present.
> >>> > 
> >>> > It is possible to hardcode that mapping (DMI name of laptop -->
> >>> > i2c address) into dell-laptop driver, so i2c-i801.ko and
> >>> > lis3lv02d_i2c.ko will be automatically loaded and lis3l binded
> >>> > correctly to i801 i2c address?
> >>> 
> >>> I don't know how this part works, but I doubt that doing it in
> >>> dell-laptop will be convenient.  After all, dell-laptop can load
> >>> before i2c-i801.
> >>> 
> >>> Jean and Wolfram: is there a quirk mechanism to add i2c devices
> >>> that aren't directly enumerable but are known to exist due to
> >>> DMI?
> >> 
> >> Maybe something like i2c_register_board_info()?
> > 
> > Maybe.  i think that wants to be called before the adapter shows
> > up, though.
> 
> i2c_probe_optional_slaves may be a more appropriate place to put
> this.
> 
> Also, is there any indication in your DSDT that this thing exists?

No :-( There is nothing which can tell us presence of accelerometer. 
Dell people told me that on Latitude machines E6540, E6440, E6440 ATG, 
E5250, E5450 and E5550 is accelerometer present on 0x29 address. So 
there is no other way than hardcode those DMI strings and do manual 
configuration...

Maybe it should go into dell-smo8800.ko driver. That one is ACPI and 
from DSDT provides IRQ number (issued when laptop. fall)...

So maybe, we can guess, when SMO ACPI device is present there is 
accelerometer on i2c bus, but we do not know exact address...

-- 
Pali Rohár
pali.rohar@gmail.com

[-- Attachment #2: This is a digitally signed message part. --]
[-- Type: application/pgp-signature, Size: 198 bytes --]

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [PATCH] i2c: i801: Allow ACPI SystemIO OpRegion to conflict with PCI BAR
  2016-04-30  1:13     ` Andy Lutomirski
@ 2016-05-02 10:12       ` Mika Westerberg
  2016-05-02 11:42         ` Rafael J. Wysocki
  2016-05-02 15:29         ` Andy Lutomirski
  0 siblings, 2 replies; 23+ messages in thread
From: Mika Westerberg @ 2016-05-02 10:12 UTC (permalink / raw)
  To: Andy Lutomirski
  Cc: Andy Lutomirski, Jean Delvare, Wolfram Sang, Jarkko Nikula,
	Rafael J. Wysocki, linux-i2c, Linux ACPI, Pali Rohár,
	Mario Limonciello

On Fri, Apr 29, 2016 at 06:13:52PM -0700, Andy Lutomirski wrote:
> A question, though: there's nothing that keeps i801_access from being
> called in between consecutive ACPI accesses.  Could this confuse the
> ASL code?  Would it be helpful if i801_access were to save away the
> old register state and restore it when it's done in the event that an
> opregion access has been seen so that the ASL-configured state doesn't
> get stomped on?

Looking at those ASL methods of Lenovo Yoga 900 for example they seem to
initialize the hardware, do the transaction and cleanup in one go.
That's also what the i2c-i801.c driver is doing as far as I can say. So
in that sense they should not mess with each other.

Of course this all breaks if the ASL code expects the state to survive
between transactions.

> Also, what happens if i801_access happens while the i801 master is
> busy with an ASL-initiated transaction?  Will it wait for the
> transaction to finish?

Yes, it should since ->acpi_lock is taken by i801_acpi_io_handler().

> If this is a problem, an alternative approach might be to virtualize
> the registers as seen by ACPI and to only load them into the real
> registers when a transaction starts.
> 
> Also, what happens if the opregion is declared globally instead of in
> the scope of the ACPI companion?  Does that happen?  If so, it might
> make sense to deny loading the driver unless in lax mode.

I don't know if that happens but it is certainly possible.

Actually reading ACPI 6.1 spec again, chapter 5.5.2.4.3 says this:

  If a platform uses a PCI BAR Target operation region, an ACPI OS will
  not load a native device driver for the associated PCI function. For
  example, if any of the BARs in a PCI function are associated with a PCI
  BAR Target operation region, then the OS will assume that the PCI
  function is to be entirely under the control of the ACPI system
  firmware. No driver will be loaded.

So what we are currently doing (preventing the driver from loading) is
the right thing to do according the above. Maybe we can change that
warning into debug/info message instead?

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [PATCH] i2c: i801: Allow ACPI SystemIO OpRegion to conflict with PCI BAR
  2016-04-29 20:21 ` Rafael J. Wysocki
@ 2016-05-02 10:21   ` Mika Westerberg
  0 siblings, 0 replies; 23+ messages in thread
From: Mika Westerberg @ 2016-05-02 10:21 UTC (permalink / raw)
  To: Rafael J. Wysocki
  Cc: Jean Delvare, Wolfram Sang, Jarkko Nikula, Rafael J. Wysocki,
	linux-i2c, ACPI Devel Maling List, Andy Lutomirski

On Fri, Apr 29, 2016 at 10:21:29PM +0200, Rafael J. Wysocki wrote:
> On Thu, Apr 28, 2016 at 12:23 PM, Mika Westerberg
> <mika.westerberg@linux.intel.com> wrote:
> > Many Intel systems the BIOS declares a SystemIO OpRegion below the SMBus
> > PCI device as can be seen in ACPI DSDT table from Lenovo Yoga 900:
> >
> >   Device (SBUS)
> >   {
> >       OperationRegion (SMBI, SystemIO, (SBAR << 0x05), 0x10)
> >       Field (SMBI, ByteAcc, NoLock, Preserve)
> >       {
> >           HSTS,   8,
> >           Offset (0x02),
> >           HCON,   8,
> >           HCOM,   8,
> >           TXSA,   8,
> >           DAT0,   8,
> >           DAT1,   8,
> >           HBDR,   8,
> >           PECR,   8,
> >           RXSA,   8,
> >           SDAT,   16
> >       }
> >
> > There are also bunch of ASL methods that that the BIOS can use to access
> > these fields. Most of the systems in question ASL methods accessing the
> > SMBI OpRegion are never used.
> >
> > Now, because of this SMBI OpRegion many systems fail to load the SMBus
> > driver with an error looking like one below:
> >
> >   ACPI Warning: SystemIO range 0x0000000000003040-0x000000000000305F
> >        conflicts with OpRegion 0x0000000000003040-0x000000000000304F
> >        (\_SB.PCI0.SBUS.SMBI) (20160108/utaddress-255)
> >   ACPI: If an ACPI driver is available for this device, you should use
> >        it instead of the native driver
> >
> > The reason is that this SMBI OpRegion conflicts with the PCI BAR used by
> > the SMBus driver.
> >
> > It turns out that we can install a custom SystemIO address space handler
> > for the SMBus device to intercept all accesses through that OpRegion. This
> > allows us to share the PCI BAR with the ASL code if it for some reason is
> > using it. We do not expect that this OpRegion handler will ever be called
> > but if it is we print a warning and execute the read/write operation under
> > a lock which prevents ASL and OS from messing each other.
> >
> > Suggested-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
> > Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
> 
> Acked-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>

Thanks!

> If it addresses any public BZ bugs, it would be good to add Link: tags
> for those and maybe Reported-by: for the reporters?

Good point. I can add those.

However, after reading ACPI 6.1 spec again, I'm having second thoughts
about this patch. See my other email to Andy on this thread.

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [PATCH] i2c: i801: Allow ACPI SystemIO OpRegion to conflict with PCI BAR
  2016-05-02 10:12       ` Mika Westerberg
@ 2016-05-02 11:42         ` Rafael J. Wysocki
  2016-05-02 12:40           ` Mika Westerberg
  2016-05-02 15:29         ` Andy Lutomirski
  1 sibling, 1 reply; 23+ messages in thread
From: Rafael J. Wysocki @ 2016-05-02 11:42 UTC (permalink / raw)
  To: Mika Westerberg
  Cc: Andy Lutomirski, Andy Lutomirski, Jean Delvare, Wolfram Sang,
	Jarkko Nikula, Rafael J. Wysocki, linux-i2c, Linux ACPI,
	Pali Rohár, Mario Limonciello

On Mon, May 2, 2016 at 12:12 PM, Mika Westerberg
<mika.westerberg@linux.intel.com> wrote:
> On Fri, Apr 29, 2016 at 06:13:52PM -0700, Andy Lutomirski wrote:
>> A question, though: there's nothing that keeps i801_access from being
>> called in between consecutive ACPI accesses.  Could this confuse the
>> ASL code?  Would it be helpful if i801_access were to save away the
>> old register state and restore it when it's done in the event that an
>> opregion access has been seen so that the ASL-configured state doesn't
>> get stomped on?
>
> Looking at those ASL methods of Lenovo Yoga 900 for example they seem to
> initialize the hardware, do the transaction and cleanup in one go.
> That's also what the i2c-i801.c driver is doing as far as I can say. So
> in that sense they should not mess with each other.
>
> Of course this all breaks if the ASL code expects the state to survive
> between transactions.
>
>> Also, what happens if i801_access happens while the i801 master is
>> busy with an ASL-initiated transaction?  Will it wait for the
>> transaction to finish?
>
> Yes, it should since ->acpi_lock is taken by i801_acpi_io_handler().
>
>> If this is a problem, an alternative approach might be to virtualize
>> the registers as seen by ACPI and to only load them into the real
>> registers when a transaction starts.
>>
>> Also, what happens if the opregion is declared globally instead of in
>> the scope of the ACPI companion?  Does that happen?  If so, it might
>> make sense to deny loading the driver unless in lax mode.
>
> I don't know if that happens but it is certainly possible.
>
> Actually reading ACPI 6.1 spec again, chapter 5.5.2.4.3 says this:
>
>   If a platform uses a PCI BAR Target operation region, an ACPI OS will
>   not load a native device driver for the associated PCI function. For
>   example, if any of the BARs in a PCI function are associated with a PCI
>   BAR Target operation region, then the OS will assume that the PCI
>   function is to be entirely under the control of the ACPI system
>   firmware. No driver will be loaded.
>
> So what we are currently doing (preventing the driver from loading) is
> the right thing to do according the above.

In general, that is the right thing to do.  That's why we do it as a rule. :-)

However, in this particular case we actually know that the opregion
declaration is bogus at least on some systems.  So, this is a
workaround for a known defect in some systems' ACPI tables.

> Maybe we can change that warning into debug/info message instead?

I wouldn't do that if it affected other cases in which opregion
declarations were actually correct.

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [PATCH] i2c: i801: Allow ACPI SystemIO OpRegion to conflict with PCI BAR
  2016-05-02 11:42         ` Rafael J. Wysocki
@ 2016-05-02 12:40           ` Mika Westerberg
  0 siblings, 0 replies; 23+ messages in thread
From: Mika Westerberg @ 2016-05-02 12:40 UTC (permalink / raw)
  To: Rafael J. Wysocki
  Cc: Andy Lutomirski, Andy Lutomirski, Jean Delvare, Wolfram Sang,
	Jarkko Nikula, Rafael J. Wysocki, linux-i2c, Linux ACPI,
	Pali Rohár, Mario Limonciello

On Mon, May 02, 2016 at 01:42:41PM +0200, Rafael J. Wysocki wrote:
> > So what we are currently doing (preventing the driver from loading) is
> > the right thing to do according the above.
> 
> In general, that is the right thing to do.  That's why we do it as a rule. :-)
> 
> However, in this particular case we actually know that the opregion
> declaration is bogus at least on some systems.  So, this is a
> workaround for a known defect in some systems' ACPI tables.

Fair enough :)

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [PATCH] i2c: i801: Allow ACPI SystemIO OpRegion to conflict with PCI BAR
  2016-05-02 10:12       ` Mika Westerberg
  2016-05-02 11:42         ` Rafael J. Wysocki
@ 2016-05-02 15:29         ` Andy Lutomirski
  2016-05-02 15:50           ` Mika Westerberg
  1 sibling, 1 reply; 23+ messages in thread
From: Andy Lutomirski @ 2016-05-02 15:29 UTC (permalink / raw)
  To: Mika Westerberg
  Cc: Andy Lutomirski, Jean Delvare, Wolfram Sang, Jarkko Nikula,
	Rafael J. Wysocki, linux-i2c, Linux ACPI, Pali Rohár,
	Mario Limonciello

On Mon, May 2, 2016 at 3:12 AM, Mika Westerberg
<mika.westerberg@linux.intel.com> wrote:
> On Fri, Apr 29, 2016 at 06:13:52PM -0700, Andy Lutomirski wrote:
>> A question, though: there's nothing that keeps i801_access from being
>> called in between consecutive ACPI accesses.  Could this confuse the
>> ASL code?  Would it be helpful if i801_access were to save away the
>> old register state and restore it when it's done in the event that an
>> opregion access has been seen so that the ASL-configured state doesn't
>> get stomped on?
>
> Looking at those ASL methods of Lenovo Yoga 900 for example they seem to
> initialize the hardware, do the transaction and cleanup in one go.
> That's also what the i2c-i801.c driver is doing as far as I can say. So
> in that sense they should not mess with each other.
>

Is your locking actually sufficient to get that right?  You're taking
acpi_lock, which is private to the driver, so you're only holding it
during actual opregion access AFAICT.  That means that, if one thread
is in the ACPI interpreter in one of these blocks and another thread
is in the driver, they could still interleave their accesses.  Am I
missing something?

> Of course this all breaks if the ASL code expects the state to survive
> between transactions.
>
>> Also, what happens if i801_access happens while the i801 master is
>> busy with an ASL-initiated transaction?  Will it wait for the
>> transaction to finish?
>
> Yes, it should since ->acpi_lock is taken by i801_acpi_io_handler().

But i801_acpi_io_handler has no concept of a transaction AFAICT.

>
>> If this is a problem, an alternative approach might be to virtualize
>> the registers as seen by ACPI and to only load them into the real
>> registers when a transaction starts.
>>
>> Also, what happens if the opregion is declared globally instead of in
>> the scope of the ACPI companion?  Does that happen?  If so, it might
>> make sense to deny loading the driver unless in lax mode.
>
> I don't know if that happens but it is certainly possible.
>
> Actually reading ACPI 6.1 spec again, chapter 5.5.2.4.3 says this:
>
>   If a platform uses a PCI BAR Target operation region, an ACPI OS will
>   not load a native device driver for the associated PCI function. For
>   example, if any of the BARs in a PCI function are associated with a PCI
>   BAR Target operation region, then the OS will assume that the PCI
>   function is to be entirely under the control of the ACPI system
>   firmware. No driver will be loaded.
>
> So what we are currently doing (preventing the driver from loading) is
> the right thing to do according the above. Maybe we can change that
> warning into debug/info message instead?

Is there a way to ask the ACPI core to tell you the scope of the
conflict?  This is more a question for Rafael and the ACPI folks: this
patch installs an io handler for a region in the scope of the ACPI
companion of the device, but what if the ASL code does IO using an
opregion declared outside the scope of the device?  Or is the opregion
handler for memory actually global?

Given that this seems to be purely hypothetical, this may not be a big deal.

--Andy

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [PATCH] i2c: i801: Allow ACPI SystemIO OpRegion to conflict with PCI BAR
  2016-05-02 15:29         ` Andy Lutomirski
@ 2016-05-02 15:50           ` Mika Westerberg
  2016-05-02 15:53             ` Andy Lutomirski
  2016-05-02 21:29             ` Rafael J. Wysocki
  0 siblings, 2 replies; 23+ messages in thread
From: Mika Westerberg @ 2016-05-02 15:50 UTC (permalink / raw)
  To: Andy Lutomirski
  Cc: Andy Lutomirski, Jean Delvare, Wolfram Sang, Jarkko Nikula,
	Rafael J. Wysocki, linux-i2c, Linux ACPI, Pali Rohár,
	Mario Limonciello

On Mon, May 02, 2016 at 08:29:42AM -0700, Andy Lutomirski wrote:
> On Mon, May 2, 2016 at 3:12 AM, Mika Westerberg
> <mika.westerberg@linux.intel.com> wrote:
> > On Fri, Apr 29, 2016 at 06:13:52PM -0700, Andy Lutomirski wrote:
> >> A question, though: there's nothing that keeps i801_access from being
> >> called in between consecutive ACPI accesses.  Could this confuse the
> >> ASL code?  Would it be helpful if i801_access were to save away the
> >> old register state and restore it when it's done in the event that an
> >> opregion access has been seen so that the ASL-configured state doesn't
> >> get stomped on?
> >
> > Looking at those ASL methods of Lenovo Yoga 900 for example they seem to
> > initialize the hardware, do the transaction and cleanup in one go.
> > That's also what the i2c-i801.c driver is doing as far as I can say. So
> > in that sense they should not mess with each other.
> >
> 
> Is your locking actually sufficient to get that right?  You're taking
> acpi_lock, which is private to the driver, so you're only holding it
> during actual opregion access AFAICT.  That means that, if one thread
> is in the ACPI interpreter in one of these blocks and another thread
> is in the driver, they could still interleave their accesses.  Am I
> missing something?

No, you are right.

> > Of course this all breaks if the ASL code expects the state to survive
> > between transactions.
> >
> >> Also, what happens if i801_access happens while the i801 master is
> >> busy with an ASL-initiated transaction?  Will it wait for the
> >> transaction to finish?
> >
> > Yes, it should since ->acpi_lock is taken by i801_acpi_io_handler().
> 
> But i801_acpi_io_handler has no concept of a transaction AFAICT.

Indeed it only handles access one-by-one not by transaction. So if the
ASL code is in middle of a transaction and i2c-i801.c starts one as well
it will mess the registers.

Back to drawing board :-/

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [PATCH] i2c: i801: Allow ACPI SystemIO OpRegion to conflict with PCI BAR
  2016-05-02 15:50           ` Mika Westerberg
@ 2016-05-02 15:53             ` Andy Lutomirski
  2016-05-02 21:29             ` Rafael J. Wysocki
  1 sibling, 0 replies; 23+ messages in thread
From: Andy Lutomirski @ 2016-05-02 15:53 UTC (permalink / raw)
  To: Mika Westerberg
  Cc: Andy Lutomirski, Jean Delvare, Wolfram Sang, Jarkko Nikula,
	Rafael J. Wysocki, linux-i2c, Linux ACPI, Pali Rohár,
	Mario Limonciello

On Mon, May 2, 2016 at 8:50 AM, Mika Westerberg
<mika.westerberg@linux.intel.com> wrote:
> On Mon, May 02, 2016 at 08:29:42AM -0700, Andy Lutomirski wrote:
>> On Mon, May 2, 2016 at 3:12 AM, Mika Westerberg
>> <mika.westerberg@linux.intel.com> wrote:
>> > On Fri, Apr 29, 2016 at 06:13:52PM -0700, Andy Lutomirski wrote:
>> >> A question, though: there's nothing that keeps i801_access from being
>> >> called in between consecutive ACPI accesses.  Could this confuse the
>> >> ASL code?  Would it be helpful if i801_access were to save away the
>> >> old register state and restore it when it's done in the event that an
>> >> opregion access has been seen so that the ASL-configured state doesn't
>> >> get stomped on?
>> >
>> > Looking at those ASL methods of Lenovo Yoga 900 for example they seem to
>> > initialize the hardware, do the transaction and cleanup in one go.
>> > That's also what the i2c-i801.c driver is doing as far as I can say. So
>> > in that sense they should not mess with each other.
>> >
>>
>> Is your locking actually sufficient to get that right?  You're taking
>> acpi_lock, which is private to the driver, so you're only holding it
>> during actual opregion access AFAICT.  That means that, if one thread
>> is in the ACPI interpreter in one of these blocks and another thread
>> is in the driver, they could still interleave their accesses.  Am I
>> missing something?
>
> No, you are right.
>
>> > Of course this all breaks if the ASL code expects the state to survive
>> > between transactions.
>> >
>> >> Also, what happens if i801_access happens while the i801 master is
>> >> busy with an ASL-initiated transaction?  Will it wait for the
>> >> transaction to finish?
>> >
>> > Yes, it should since ->acpi_lock is taken by i801_acpi_io_handler().
>>
>> But i801_acpi_io_handler has no concept of a transaction AFAICT.
>
> Indeed it only handles access one-by-one not by transaction. So if the
> ASL code is in middle of a transaction and i2c-i801.c starts one as well
> it will mess the registers.
>
> Back to drawing board :-/

:-/

I can try to test using the ACPI debugger maybe, but my laptop with
this problem doesn't have any calls to the offending ASL at all, so
just booting it won't exercise any of the interesting cases at all.

-- 
Andy Lutomirski
AMA Capital Management, LLC

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [PATCH] i2c: i801: Allow ACPI SystemIO OpRegion to conflict with PCI BAR
  2016-05-02 15:50           ` Mika Westerberg
  2016-05-02 15:53             ` Andy Lutomirski
@ 2016-05-02 21:29             ` Rafael J. Wysocki
  2016-05-03  8:53               ` Mika Westerberg
  1 sibling, 1 reply; 23+ messages in thread
From: Rafael J. Wysocki @ 2016-05-02 21:29 UTC (permalink / raw)
  To: Mika Westerberg
  Cc: Andy Lutomirski, Andy Lutomirski, Jean Delvare, Wolfram Sang,
	Jarkko Nikula, Rafael J. Wysocki, linux-i2c, Linux ACPI,
	Pali Rohár, Mario Limonciello

On Mon, May 2, 2016 at 5:50 PM, Mika Westerberg
<mika.westerberg@linux.intel.com> wrote:
> On Mon, May 02, 2016 at 08:29:42AM -0700, Andy Lutomirski wrote:
>> On Mon, May 2, 2016 at 3:12 AM, Mika Westerberg
>> <mika.westerberg@linux.intel.com> wrote:
>> > On Fri, Apr 29, 2016 at 06:13:52PM -0700, Andy Lutomirski wrote:
>> >> A question, though: there's nothing that keeps i801_access from being
>> >> called in between consecutive ACPI accesses.  Could this confuse the
>> >> ASL code?  Would it be helpful if i801_access were to save away the
>> >> old register state and restore it when it's done in the event that an
>> >> opregion access has been seen so that the ASL-configured state doesn't
>> >> get stomped on?
>> >
>> > Looking at those ASL methods of Lenovo Yoga 900 for example they seem to
>> > initialize the hardware, do the transaction and cleanup in one go.
>> > That's also what the i2c-i801.c driver is doing as far as I can say. So
>> > in that sense they should not mess with each other.
>> >
>>
>> Is your locking actually sufficient to get that right?  You're taking
>> acpi_lock, which is private to the driver, so you're only holding it
>> during actual opregion access AFAICT.  That means that, if one thread
>> is in the ACPI interpreter in one of these blocks and another thread
>> is in the driver, they could still interleave their accesses.  Am I
>> missing something?
>
> No, you are right.
>
>> > Of course this all breaks if the ASL code expects the state to survive
>> > between transactions.
>> >
>> >> Also, what happens if i801_access happens while the i801 master is
>> >> busy with an ASL-initiated transaction?  Will it wait for the
>> >> transaction to finish?
>> >
>> > Yes, it should since ->acpi_lock is taken by i801_acpi_io_handler().
>>
>> But i801_acpi_io_handler has no concept of a transaction AFAICT.
>
> Indeed it only handles access one-by-one not by transaction. So if the
> ASL code is in middle of a transaction and i2c-i801.c starts one as well
> it will mess the registers.
>
> Back to drawing board :-/

It doesn't look like trying to make it safe for both the driver and
AML to use the same range of addresses is a realistic goal.  At least
the benefit will not outweigh the resulting complexity if the opregion
is actually never used by AML in practice.

So, why don't we have a flag that will make i801_access() return an
error on every invocation when set (the callers of it should be able
to cope with that or they are broken IMO) and why don't we set it when
AML accesses the opregion first time?

Yes, that will prevent the driver from actually working *when* AML
turns out to use the opregion, but IMO that's a bit more friendly than
preventing the driver from loading at all.

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [PATCH] i2c: i801: Allow ACPI SystemIO OpRegion to conflict with PCI BAR
  2016-05-02 21:29             ` Rafael J. Wysocki
@ 2016-05-03  8:53               ` Mika Westerberg
  0 siblings, 0 replies; 23+ messages in thread
From: Mika Westerberg @ 2016-05-03  8:53 UTC (permalink / raw)
  To: Rafael J. Wysocki
  Cc: Andy Lutomirski, Andy Lutomirski, Jean Delvare, Wolfram Sang,
	Jarkko Nikula, Rafael J. Wysocki, linux-i2c, Linux ACPI,
	Pali Rohár, Mario Limonciello

On Mon, May 02, 2016 at 11:29:01PM +0200, Rafael J. Wysocki wrote:
> It doesn't look like trying to make it safe for both the driver and
> AML to use the same range of addresses is a realistic goal.  At least
> the benefit will not outweigh the resulting complexity if the opregion
> is actually never used by AML in practice.
> 
> So, why don't we have a flag that will make i801_access() return an
> error on every invocation when set (the callers of it should be able
> to cope with that or they are broken IMO) and why don't we set it when
> AML accesses the opregion first time?

Yeah, that occured to me also yesterday evening :)

> Yes, that will prevent the driver from actually working *when* AML
> turns out to use the opregion, but IMO that's a bit more friendly than
> preventing the driver from loading at all.

I agree. If nobody objects, I'm going to create v2 of the patch that
prevents further driver access if AML touches the OpRegion.

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [PATCH] i2c: i801: Allow ACPI SystemIO OpRegion to conflict with PCI BAR
  2016-04-30  0:56           ` Andy Lutomirski
  2016-04-30  8:12             ` Pali Rohár
@ 2016-05-05  8:27             ` Pali Rohár
       [not found]               ` <CALCETrW3i7QkVNRo4RQkRViPBo8dSn=4mKDZiA=Ar3v7=dgz1A@mail.gmail.com>
  2016-05-07 15:06             ` Jean Delvare
  2 siblings, 1 reply; 23+ messages in thread
From: Pali Rohár @ 2016-05-05  8:27 UTC (permalink / raw)
  To: Andy Lutomirski
  Cc: Andy Lutomirski, Mika Westerberg, Jean Delvare, Wolfram Sang,
	Jarkko Nikula, Rafael J. Wysocki, linux-i2c, Linux ACPI,
	Mario Limonciello

On Friday 29 April 2016 17:56:14 Andy Lutomirski wrote:
> On Fri, Apr 29, 2016 at 2:42 PM, Andy Lutomirski <luto@amacapital.net> wrote:
> > On Fri, Apr 29, 2016 at 2:00 PM, Pali Rohár <pali.rohar@gmail.com> wrote:
> >> On Friday 29 April 2016 20:10:23 Andy Lutomirski wrote:
> >>> Jean and Wolfram: is there a quirk mechanism to add i2c devices that
> >>> aren't directly enumerable but are known to exist due to DMI?
> >>
> >> Maybe something like i2c_register_board_info()?
> >
> > Maybe.  i think that wants to be called before the adapter shows up, though.
> 
> i2c_probe_optional_slaves may be a more appropriate place to put this.

I cannot find function i2c_probe_optional_slaves. Where is it?

-- 
Pali Rohár
pali.rohar@gmail.com

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [PATCH] i2c: i801: Allow ACPI SystemIO OpRegion to conflict with PCI BAR
       [not found]               ` <CALCETrW3i7QkVNRo4RQkRViPBo8dSn=4mKDZiA=Ar3v7=dgz1A@mail.gmail.com>
@ 2016-05-07 14:11                 ` Pali Rohár
  0 siblings, 0 replies; 23+ messages in thread
From: Pali Rohár @ 2016-05-07 14:11 UTC (permalink / raw)
  To: Andy Lutomirski
  Cc: linux-i2c, Linux ACPI, Mario Limonciello, Wolfram Sang,
	Mika Westerberg, Rafael J. Wysocki, Jean Delvare, Jarkko Nikula

[-- Attachment #1: Type: Text/Plain, Size: 1195 bytes --]

On Friday 06 May 2016 21:00:25 Andy Lutomirski wrote:
> On May 5, 2016 1:27 AM, "Pali Rohár" <pali.rohar@gmail.com> wrote:
> > On Friday 29 April 2016 17:56:14 Andy Lutomirski wrote:
> > > On Fri, Apr 29, 2016 at 2:42 PM, Andy Lutomirski
> > > <luto@amacapital.net>
> 
> wrote:
> > > > On Fri, Apr 29, 2016 at 2:00 PM, Pali Rohár
> > > > <pali.rohar@gmail.com>
> 
> wrote:
> > > >> On Friday 29 April 2016 20:10:23 Andy Lutomirski wrote:
> > > >>> Jean and Wolfram: is there a quirk mechanism to add i2c
> > > >>> devices that aren't directly enumerable but are known to
> > > >>> exist due to DMI?
> > > >> 
> > > >> Maybe something like i2c_register_board_info()?
> > > > 
> > > > Maybe.  i think that wants to be called before the adapter
> > > > shows up,
> 
> though.
> 
> > > i2c_probe_optional_slaves may be a more appropriate place to put
> > > this.
> > 
> > I cannot find function i2c_probe_optional_slaves. Where is it?
> 
> Sorry, I meant i801_probe_optional_slaves.

Hm... that could probably work. I will look at dell-smo8800.c and 
lis3lv02d_i2c.c and i2c-i801.c how to interconnect all those devices...

-- 
Pali Rohár
pali.rohar@gmail.com

[-- Attachment #2: This is a digitally signed message part. --]
[-- Type: application/pgp-signature, Size: 198 bytes --]

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [PATCH] i2c: i801: Allow ACPI SystemIO OpRegion to conflict with PCI BAR
  2016-04-30  0:56           ` Andy Lutomirski
  2016-04-30  8:12             ` Pali Rohár
  2016-05-05  8:27             ` Pali Rohár
@ 2016-05-07 15:06             ` Jean Delvare
  2 siblings, 0 replies; 23+ messages in thread
From: Jean Delvare @ 2016-05-07 15:06 UTC (permalink / raw)
  To: Andy Lutomirski
  Cc: Pali Rohár, Andy Lutomirski, Mika Westerberg, Jean Delvare,
	Wolfram Sang, Jarkko Nikula, Rafael J. Wysocki, linux-i2c,
	Linux ACPI, Mario Limonciello

Hi Andy, Pali,

On Fri, 29 Apr 2016 17:56:14 -0700, Andy Lutomirski wrote:
> On Fri, Apr 29, 2016 at 2:42 PM, Andy Lutomirski <luto@amacapital.net> wrote:
> > On Fri, Apr 29, 2016 at 2:00 PM, Pali Rohár <pali.rohar@gmail.com> wrote:
> >> On Friday 29 April 2016 20:10:23 Andy Lutomirski wrote:
> >>> Jean and Wolfram: is there a quirk mechanism to add i2c devices that
> >>> aren't directly enumerable but are known to exist due to DMI?
> >>
> >> Maybe something like i2c_register_board_info()?
> >
> > Maybe.  i think that wants to be called before the adapter shows up, though.
> 
> i2c_probe_optional_slaves may be a more appropriate place to put this.

I can't find any function by that name in the vanilla kernel.

Someone wrote Documentation/i2c/instantiating-devices to explain the
different options to declare an I2C slave device on the system.

In this specific case I suspect option #2 is appropriate, using
i2c_new_probed_device() (or even i2c_new_device() if you are 100%
certain.)

-- 
Jean Delvare
SUSE L3 Support

^ permalink raw reply	[flat|nested] 23+ messages in thread

end of thread, other threads:[~2016-05-07 15:06 UTC | newest]

Thread overview: 23+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-04-28 10:23 [PATCH] i2c: i801: Allow ACPI SystemIO OpRegion to conflict with PCI BAR Mika Westerberg
2016-04-28 18:34 ` Andy Lutomirski
2016-04-29  8:56   ` Mika Westerberg
2016-04-30  1:13     ` Andy Lutomirski
2016-05-02 10:12       ` Mika Westerberg
2016-05-02 11:42         ` Rafael J. Wysocki
2016-05-02 12:40           ` Mika Westerberg
2016-05-02 15:29         ` Andy Lutomirski
2016-05-02 15:50           ` Mika Westerberg
2016-05-02 15:53             ` Andy Lutomirski
2016-05-02 21:29             ` Rafael J. Wysocki
2016-05-03  8:53               ` Mika Westerberg
2016-04-29  9:03   ` Pali Rohár
2016-04-29 18:10     ` Andy Lutomirski
2016-04-29 21:00       ` Pali Rohár
2016-04-29 21:42         ` Andy Lutomirski
2016-04-30  0:56           ` Andy Lutomirski
2016-04-30  8:12             ` Pali Rohár
2016-05-05  8:27             ` Pali Rohár
     [not found]               ` <CALCETrW3i7QkVNRo4RQkRViPBo8dSn=4mKDZiA=Ar3v7=dgz1A@mail.gmail.com>
2016-05-07 14:11                 ` Pali Rohár
2016-05-07 15:06             ` Jean Delvare
2016-04-29 20:21 ` Rafael J. Wysocki
2016-05-02 10:21   ` Mika Westerberg

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.