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-prev] [thread-next>] [day] [month] [year] [list]
Date:   Tue, 18 Feb 2020 19:19:06 +0530
From:   Shobhit Srivastava <shobhit.srivastava@...el.com>
To:     daniel@...que.org, haojian.zhuang@...il.com,
        robert.jarzmik@...e.fr, broonie@...nel.org,
        linux-arm-kernel@...ts.infradead.org, linux-spi@...r.kernel.org,
        linux-kernel@...r.kernel.org
Cc:     furquan@...gle.com, rajatja@...gle.com, evgreen@...gle.com,
        andriy.shevchenko@...ux.intel.com
Subject: [PATCH 1/1] spi: pxa2xx: Enable SSP controller for CS toggle

In some circumstances on Intel LPSS controllers, toggling the LPSS
CS control register doesn't actually cause the CS line to toggle.
This ruins SPI transactions that either rely on delay_usecs,
or toggle the CS line without sending any data.
This seems to be because the SSP controller is in disabled state.
As per the spec, the controller needs to be enabled for CS change
to take effect.
This issue is not seen in cases where there is data to be
transferred because then the SSCR0 gets enabled via
pxa2xx_configure_sscr0().

Signed-off-by: Shobhit Srivastava <shobhit.srivastava@...el.com>

---

 drivers/spi/spi-pxa2xx.c | 13 ++++++++++++-
 1 file changed, 12 insertions(+), 1 deletion(-)

diff --git a/drivers/spi/spi-pxa2xx.c b/drivers/spi/spi-pxa2xx.c
index 4c7a71f0fb3e..414afc72ef44 100644
--- a/drivers/spi/spi-pxa2xx.c
+++ b/drivers/spi/spi-pxa2xx.c
@@ -370,7 +370,7 @@ static void lpss_ssp_cs_control(struct spi_device *spi, bool enable)
 	struct driver_data *drv_data =
 		spi_controller_get_devdata(spi->controller);
 	const struct lpss_config *config;
-	u32 value;
+	u32 value, sscr0;
 
 	config = lpss_get_config(drv_data);
 
@@ -382,7 +382,18 @@ static void lpss_ssp_cs_control(struct spi_device *spi, bool enable)
 		value &= ~LPSS_CS_CONTROL_CS_HIGH;
 	else
 		value |= LPSS_CS_CONTROL_CS_HIGH;
+
+	/* To propagate CS value to output, the controller should
+	 * be enabled. This is needed for devices that just do
+	 * CS assert, wait and CS deassert without sending any data.
+	 */
+	sscr0 = pxa2xx_spi_read(drv_data, SSCR0);
+	pxa2xx_spi_write(drv_data, SSCR0, sscr0 | SSCR0_SSE);
+
 	__lpss_ssp_write_priv(drv_data, config->reg_cs_ctrl, value);
+
+	/* Restore the original SSCR0 config*/
+	 pxa2xx_spi_write(drv_data, SSCR0, sscr0);
 }
 
 static void cs_assert(struct spi_device *spi)
-- 
2.17.1

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ