All of lore.kernel.org
 help / color / mirror / Atom feed
From: David Lechner <dlechner@baylibre.com>
To: linux-spi@vger.kernel.org
Cc: "David Lechner" <dlechner@baylibre.com>,
	"Mark Brown" <broonie@kernel.org>,
	"Michael Hennerich" <michael.hennerich@analog.com>,
	"Nuno Sá" <nuno.sa@analog.com>,
	linux-kernel@vger.kernel.org,
	"Lars-Peter Clausen" <lars@metafoo.de>
Subject: [PATCH 9/9] spi: axi-spi-engine: add watchdog timer
Date: Mon,  4 Dec 2023 11:33:35 -0600	[thread overview]
Message-ID: <20231204-axi-spi-engine-series-2-v1-9-063672323fce@baylibre.com> (raw)
In-Reply-To: <20231204-axi-spi-engine-series-2-v1-0-063672323fce@baylibre.com>

If there is an issue with the AXI SPI Engine hardware a scheduled
transfer might never be completed and spi_sync() will block forever.
This due to the uninterruptible wait for completion waiting for the
spi_finalize_current_message() that never comes.

Add a watchdog timer that will abort a transfer 5 seconds after it has
been started. This will potentially leave the hardware in a broken state
but it allows software to recover and allow to better diagnose the
underlying issue.

Co-developed-by: Lars-Peter Clausen <lars@metafoo.de>
Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
Signed-off-by: David Lechner <dlechner@baylibre.com>
---
 drivers/spi/spi-axi-spi-engine.c | 29 ++++++++++++++++++++++++++---
 1 file changed, 26 insertions(+), 3 deletions(-)

diff --git a/drivers/spi/spi-axi-spi-engine.c b/drivers/spi/spi-axi-spi-engine.c
index 78221715ba81..58280dd1c901 100644
--- a/drivers/spi/spi-axi-spi-engine.c
+++ b/drivers/spi/spi-axi-spi-engine.c
@@ -13,6 +13,7 @@
 #include <linux/module.h>
 #include <linux/platform_device.h>
 #include <linux/spi/spi.h>
+#include <linux/timer.h>
 
 #define SPI_ENGINE_VERSION_MAJOR(x)	((x >> 16) & 0xff)
 #define SPI_ENGINE_VERSION_MINOR(x)	((x >> 8) & 0xff)
@@ -114,6 +115,8 @@ struct spi_engine {
 
 	void __iomem *base;
 	struct ida sync_ida;
+	struct timer_list watchdog_timer;
+	struct spi_controller *controller;
 
 	unsigned int int_enable;
 };
@@ -488,9 +491,11 @@ static irqreturn_t spi_engine_irq(int irq, void *devid)
 		struct spi_engine_message_state *st = msg->state;
 
 		if (completed_id == st->sync_id) {
-			msg->status = 0;
-			msg->actual_length = msg->frame_length;
-			spi_finalize_current_message(host);
+			if (timer_delete_sync(&spi_engine->watchdog_timer)) {
+				msg->status = 0;
+				msg->actual_length = msg->frame_length;
+				spi_finalize_current_message(host);
+			}
 			disable_int |= SPI_ENGINE_INT_SYNC;
 		}
 	}
@@ -573,6 +578,8 @@ static int spi_engine_transfer_one_message(struct spi_controller *host,
 	unsigned int int_enable = 0;
 	unsigned long flags;
 
+	mod_timer(&spi_engine->watchdog_timer, jiffies + msecs_to_jiffies(5000));
+
 	spin_lock_irqsave(&spi_engine->lock, flags);
 
 	if (spi_engine_write_cmd_fifo(spi_engine, msg))
@@ -596,6 +603,20 @@ static int spi_engine_transfer_one_message(struct spi_controller *host,
 	return 0;
 }
 
+static void spi_engine_timeout(struct timer_list *timer)
+{
+	struct spi_engine *spi_engine = from_timer(spi_engine, timer, watchdog_timer);
+	struct spi_controller *host = spi_engine->controller;
+
+	if (WARN_ON(!host->cur_msg))
+		return;
+
+	dev_err(&host->dev,
+		"Timeout occurred while waiting for transfer to complete. Hardware is probably broken.\n");
+	host->cur_msg->status = -ETIMEDOUT;
+	spi_finalize_current_message(host);
+}
+
 static void spi_engine_release_hw(void *p)
 {
 	struct spi_engine *spi_engine = p;
@@ -625,6 +646,8 @@ static int spi_engine_probe(struct platform_device *pdev)
 
 	spin_lock_init(&spi_engine->lock);
 	ida_init(&spi_engine->sync_ida);
+	timer_setup(&spi_engine->watchdog_timer, spi_engine_timeout, TIMER_IRQSAFE);
+	spi_engine->controller = host;
 
 	spi_engine->clk = devm_clk_get_enabled(&pdev->dev, "s_axi_aclk");
 	if (IS_ERR(spi_engine->clk))

-- 
2.43.0


  parent reply	other threads:[~2023-12-04 17:36 UTC|newest]

Thread overview: 13+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-12-04 17:33 [PATCH 0/9] spi: axi-spi-engine: improvements round 2 David Lechner
2023-12-04 17:33 ` [PATCH 1/9] spi: axi-spi-engine: return void from spi_engine_compile_message() David Lechner
2023-12-04 17:33 ` [PATCH 2/9] spi: axi-spi-engine: populate xfer->effective_speed_hz David Lechner
2023-12-04 17:33 ` [PATCH 3/9] spi: axi-spi-engine: remove spi_engine_get_clk_div() David Lechner
2023-12-04 17:33 ` [PATCH 4/9] spi: axi-spi-engine: fix sleep ticks calculation David Lechner
2023-12-04 17:33 ` [PATCH 5/9] spi: axi-spi-engine: remove xfer arg from spi_engine_gen_sleep() David Lechner
2023-12-04 17:33 ` [PATCH 6/9] spi: axi-spi-engine: implement xfer->cs_change_delay David Lechner
2023-12-04 17:33 ` [PATCH 7/9] spi: axi-spi-engine: restore clkdiv at end of message David Lechner
2023-12-04 17:33 ` [PATCH 8/9] spi: axi-spi-engine: remove delay from CS assertion David Lechner
2023-12-04 17:33 ` David Lechner [this message]
2023-12-05 15:12 ` [PATCH 0/9] spi: axi-spi-engine: improvements round 2 Nuno Sá
2023-12-05 15:52   ` Hennerich, Michael
2023-12-06 21:04 ` Mark Brown

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20231204-axi-spi-engine-series-2-v1-9-063672323fce@baylibre.com \
    --to=dlechner@baylibre.com \
    --cc=broonie@kernel.org \
    --cc=lars@metafoo.de \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-spi@vger.kernel.org \
    --cc=michael.hennerich@analog.com \
    --cc=nuno.sa@analog.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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.