[openwrt/openwrt] ath79: replace chipselect workaround with a proper patch
LEDE Commits
lede-commits at lists.infradead.org
Thu Mar 4 23:04:52 GMT 2021
blocktrron pushed a commit to openwrt/openwrt.git, branch master:
https://git.openwrt.org/82b9713ce8f5ff90d1d89dbf667aeab5b0aec358
commit 82b9713ce8f5ff90d1d89dbf667aeab5b0aec358
Author: David Bauer <mail at david-bauer.net>
AuthorDate: Wed Mar 3 17:23:16 2021 +0100
ath79: replace chipselect workaround with a proper patch
Debugging the SPI CS issue with kernel 5.10 resulted in a better
understanding for the root cause and a proper patch with a better
explanation.
Exchange the old hack patch with a more efficient (and upstreamable)
solution.
Signed-off-by: David Bauer <mail at david-bauer.net>
---
.../patches-5.10/0054-spi-always-write-cs.patch | 31 --------
...0054-spi-sync-up-initial-chipselect-state.patch | 89 ++++++++++++++++++++++
2 files changed, 89 insertions(+), 31 deletions(-)
diff --git a/target/linux/ath79/patches-5.10/0054-spi-always-write-cs.patch b/target/linux/ath79/patches-5.10/0054-spi-always-write-cs.patch
deleted file mode 100644
index 1e461cee0a..0000000000
--- a/target/linux/ath79/patches-5.10/0054-spi-always-write-cs.patch
+++ /dev/null
@@ -1,31 +0,0 @@
-Upstream commit d40f0b6f2e21 ("spi: Avoid settingthe chip select if
-we don't need to") causes the SPI CS only to be asserted once and not
-if it's state stays the same.
-
-This seems to cause problems with the SPI on the AR724x and the AR913x
-(but not the AR71xx). AR934x and subsequent chips do not look affected.
-
-ToDo:
- - Analyze if this is a hardware bug or a bug in the software.
- - Send a cleaned up patch upstream.
-
-Signed-off-by: David Bauer <mail at david-bauer.net>
-
---- a/drivers/spi/spi.c
-+++ b/drivers/spi/spi.c
-@@ -791,6 +791,7 @@ static void spi_set_cs(struct spi_device
- {
- bool enable1 = enable;
-
-+#if 0
- /*
- * Avoid calling into the driver (or doing delays) if the chip select
- * isn't actually changing from the last time this was called.
-@@ -801,6 +802,7 @@ static void spi_set_cs(struct spi_device
-
- spi->controller->last_cs_enable = enable;
- spi->controller->last_cs_mode_high = spi->mode & SPI_CS_HIGH;
-+#endif
-
- if (!spi->controller->set_cs_timing) {
- if (enable1)
diff --git a/target/linux/ath79/patches-5.10/0054-spi-sync-up-initial-chipselect-state.patch b/target/linux/ath79/patches-5.10/0054-spi-sync-up-initial-chipselect-state.patch
new file mode 100644
index 0000000000..7329ae5827
--- /dev/null
+++ b/target/linux/ath79/patches-5.10/0054-spi-sync-up-initial-chipselect-state.patch
@@ -0,0 +1,89 @@
+From 4b7d7f85abac1e7ad9e8b745694e470f0729f527 Mon Sep 17 00:00:00 2001
+From: David Bauer <mail at david-bauer.net>
+Date: Wed, 3 Mar 2021 17:11:34 +0100
+Subject: [PATCH] spi: sync up initial chipselect state
+
+When initially probing the SPI slave device, the call for disabling an
+SPI device without the SPI_CS_HIGH flag is not applied, as the
+condition for checking whether or not the state to be applied equals the
+one currently set evaluates to true.
+
+This however might not necessarily be the case, as the chipselect might
+be active.
+
+Add a force flag to spi_set_cs which allows to override this
+early access condition. Set it to false everywhere except when called
+from spi_setup to sync up the initial CS state.
+
+Fixes commit d40f0b6f2e21 ("spi: Avoid setting the chip select if we don't
+need to")
+
+Signed-off-by: David Bauer <mail at david-bauer.net>
+---
+ drivers/spi/spi.c | 16 ++++++++--------
+ 1 file changed, 8 insertions(+), 8 deletions(-)
+
+--- a/drivers/spi/spi.c
++++ b/drivers/spi/spi.c
+@@ -787,7 +787,7 @@ int spi_register_board_info(struct spi_b
+
+ /*-------------------------------------------------------------------------*/
+
+-static void spi_set_cs(struct spi_device *spi, bool enable)
++static void spi_set_cs(struct spi_device *spi, bool enable, bool force)
+ {
+ bool enable1 = enable;
+
+@@ -795,7 +795,7 @@ static void spi_set_cs(struct spi_device
+ * Avoid calling into the driver (or doing delays) if the chip select
+ * isn't actually changing from the last time this was called.
+ */
+- if ((spi->controller->last_cs_enable == enable) &&
++ if (!force && (spi->controller->last_cs_enable == enable) &&
+ (spi->controller->last_cs_mode_high == (spi->mode & SPI_CS_HIGH)))
+ return;
+
+@@ -1243,7 +1243,7 @@ static int spi_transfer_one_message(stru
+ struct spi_statistics *statm = &ctlr->statistics;
+ struct spi_statistics *stats = &msg->spi->statistics;
+
+- spi_set_cs(msg->spi, true);
++ spi_set_cs(msg->spi, true, false);
+
+ SPI_STATISTICS_INCREMENT_FIELD(statm, messages);
+ SPI_STATISTICS_INCREMENT_FIELD(stats, messages);
+@@ -1311,9 +1311,9 @@ fallback_pio:
+ &msg->transfers)) {
+ keep_cs = true;
+ } else {
+- spi_set_cs(msg->spi, false);
++ spi_set_cs(msg->spi, false, false);
+ _spi_transfer_cs_change_delay(msg, xfer);
+- spi_set_cs(msg->spi, true);
++ spi_set_cs(msg->spi, true, false);
+ }
+ }
+
+@@ -1322,7 +1322,7 @@ fallback_pio:
+
+ out:
+ if (ret != 0 || !keep_cs)
+- spi_set_cs(msg->spi, false);
++ spi_set_cs(msg->spi, false, false);
+
+ if (msg->status == -EINPROGRESS)
+ msg->status = ret;
+@@ -3400,11 +3400,11 @@ int spi_setup(struct spi_device *spi)
+ */
+ status = 0;
+
+- spi_set_cs(spi, false);
++ spi_set_cs(spi, false, true);
+ pm_runtime_mark_last_busy(spi->controller->dev.parent);
+ pm_runtime_put_autosuspend(spi->controller->dev.parent);
+ } else {
+- spi_set_cs(spi, false);
++ spi_set_cs(spi, false, true);
+ }
+
+ mutex_unlock(&spi->controller->io_mutex);
More information about the lede-commits
mailing list