lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Date:   Sun, 23 Jul 2017 23:02:19 -0700
From:   Furquan Shaikh <furquan@...gle.com>
To:     "Lee Jones )" <lee.jones@...aro.org>
Cc:     linux-kernel@...r.kernel.org, rajatja@...gle.com,
        drinkcat@...gle.com, azhar.shaikh@...el.com,
        gregkh@...uxfoundation.org, mika.westerberg@...ux.intel.com,
        andriy.shevchenko@...ux.intel.com, furquan@...gle.com
Subject: [PATCH] mfd: intel-lpss: Put I2C and SPI controllers into reset state on suspend

Commit 274e43edcda6f ("mfd: intel-lpss: Do not put device in reset
state on suspend") changed the behavior on suspend by not putting LPSS
controllers into reset. This was done because S3/S0ix fail if UART
device is put into reset and no_console_suspend flag is enabled.

Because of the above change, I2C controller gets into a bad state if
it observes that the I2C lines are pulled low when power to I2C device
is cut off during suspend (generally, I2C lines are pulled to power
rail of the I2C device in order to ensure that there is no leakage
because of the pulls when device is turned off). This results in the
controller timing out for all future I2C operations after resume. It
is primarily because of the following sequence of operations:

During suspend:
1. I2C controller is disabled, but it is not put into reset.
2. Power to I2C device is cut off.
3. #2 results in the I2C lines being pulled low.

==> At this point the I2C controller gets into a bad state

On resume:
1. Power to I2C device is enabled.
2. #2 results in the I2C lines being pulled high.
3. I2C controller is enabled.

However, even after enabling the I2C controller, all future I2C xfers
fail since the controller is in a bad state and does not attempt to
make any transactions and hence times out.

In order to ensure that the controller does not get into a bad state,
this change puts it into reset if the controller type is not
UART. With this change, the order of operations is:

During suspend:
1. I2C controller is disabled and put into reset.
2. Power to I2C device is cut off.
3. #2 results in the I2C lines being pulled low.

On resume:
1. Power to I2C device is enabled.
2. #2 results in the I2C lines being pulled high.
3. I2C controller is enabled and taken out of reset.

Signed-off-by: Furquan Shaikh <furquan@...gle.com>
---
 drivers/mfd/intel-lpss.c | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/drivers/mfd/intel-lpss.c b/drivers/mfd/intel-lpss.c
index 70c646b0097d..0e0ab9bb1530 100644
--- a/drivers/mfd/intel-lpss.c
+++ b/drivers/mfd/intel-lpss.c
@@ -502,6 +502,14 @@ int intel_lpss_suspend(struct device *dev)
 	for (i = 0; i < LPSS_PRIV_REG_COUNT; i++)
 		lpss->priv_ctx[i] = readl(lpss->priv + i * 4);
 
+	/*
+	 * If the device type is not UART, then put the controller into
+	 * reset. UART cannot be put into reset since S3/S0ix fail when
+	 * no_console_suspend flag is enabled.
+	 */
+	if (lpss->type != LPSS_DEV_UART)
+		writel(0, lpss->priv + LPSS_PRIV_RESETS);
+
 	return 0;
 }
 EXPORT_SYMBOL_GPL(intel_lpss_suspend);
-- 
2.14.0.rc0.284.gd933b75aa4-goog

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ