linux-spi.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] spi: sh: Switch to using core message queue
@ 2022-06-10 15:46 Mark Brown
  2022-06-27 20:33 ` Mark Brown
  0 siblings, 1 reply; 2+ messages in thread
From: Mark Brown @ 2022-06-10 15:46 UTC (permalink / raw)
  To: Yoshihiro Shimoda; +Cc: linux-spi, Mark Brown

We deprecated open coding of the transfer queue back in 2017 so it's high
time we finished up converting drivers to use the standard message queue
code. The SH driver is fairly straightforward so convert to use
transfer_one_message(), it looks like the driver would be a good fit for
transfer_one() with a little bit of updating but this smaller change seems
safer.

I'm not actually clear how the driver worked robustly previously, it
clears SSA and CR1 when queueing a transfer which looks like it would
interfere with any running transfer. This clearing has been moved to the
start of the message transfer function.

I'm also unclear how exactly the chip select is managed with this driver.

Signed-off-by: Mark Brown <broonie@kernel.org>
---
 drivers/spi/spi-sh.c | 94 +++++++++++++-------------------------------
 1 file changed, 28 insertions(+), 66 deletions(-)

diff --git a/drivers/spi/spi-sh.c b/drivers/spi/spi-sh.c
index 45f304935332..3e72fad99adf 100644
--- a/drivers/spi/spi-sh.c
+++ b/drivers/spi/spi-sh.c
@@ -73,11 +73,8 @@ struct spi_sh_data {
 	void __iomem *addr;
 	int irq;
 	struct spi_master *master;
-	struct list_head queue;
-	struct work_struct ws;
 	unsigned long cr1;
 	wait_queue_head_t wait;
-	spinlock_t lock;
 	int width;
 };
 
@@ -271,47 +268,39 @@ static int spi_sh_receive(struct spi_sh_data *ss, struct spi_message *mesg,
 	return 0;
 }
 
-static void spi_sh_work(struct work_struct *work)
+static int spi_sh_transfer_one_message(struct spi_controller *ctlr,
+					struct spi_message *mesg)
 {
-	struct spi_sh_data *ss = container_of(work, struct spi_sh_data, ws);
-	struct spi_message *mesg;
+	struct spi_sh_data *ss = spi_controller_get_devdata(ctlr);
 	struct spi_transfer *t;
-	unsigned long flags;
 	int ret;
 
 	pr_debug("%s: enter\n", __func__);
 
-	spin_lock_irqsave(&ss->lock, flags);
-	while (!list_empty(&ss->queue)) {
-		mesg = list_entry(ss->queue.next, struct spi_message, queue);
-		list_del_init(&mesg->queue);
-
-		spin_unlock_irqrestore(&ss->lock, flags);
-		list_for_each_entry(t, &mesg->transfers, transfer_list) {
-			pr_debug("tx_buf = %p, rx_buf = %p\n",
-					t->tx_buf, t->rx_buf);
-			pr_debug("len = %d, delay.value = %d\n",
-					t->len, t->delay.value);
-
-			if (t->tx_buf) {
-				ret = spi_sh_send(ss, mesg, t);
-				if (ret < 0)
-					goto error;
-			}
-			if (t->rx_buf) {
-				ret = spi_sh_receive(ss, mesg, t);
-				if (ret < 0)
-					goto error;
-			}
-			mesg->actual_length += t->len;
-		}
-		spin_lock_irqsave(&ss->lock, flags);
+	spi_sh_clear_bit(ss, SPI_SH_SSA, SPI_SH_CR1);
 
-		mesg->status = 0;
-		if (mesg->complete)
-			mesg->complete(mesg->context);
+	list_for_each_entry(t, &mesg->transfers, transfer_list) {
+		pr_debug("tx_buf = %p, rx_buf = %p\n",
+			 t->tx_buf, t->rx_buf);
+		pr_debug("len = %d, delay.value = %d\n",
+			 t->len, t->delay.value);
+
+		if (t->tx_buf) {
+			ret = spi_sh_send(ss, mesg, t);
+			if (ret < 0)
+				goto error;
+		}
+		if (t->rx_buf) {
+			ret = spi_sh_receive(ss, mesg, t);
+			if (ret < 0)
+				goto error;
+		}
+		mesg->actual_length += t->len;
 	}
 
+	mesg->status = 0;
+	spi_finalize_current_message(ctlr);
+
 	clear_fifo(ss);
 	spi_sh_set_bit(ss, SPI_SH_SSD, SPI_SH_CR1);
 	udelay(100);
@@ -321,12 +310,11 @@ static void spi_sh_work(struct work_struct *work)
 
 	clear_fifo(ss);
 
-	spin_unlock_irqrestore(&ss->lock, flags);
-
-	return;
+	return 0;
 
  error:
 	mesg->status = ret;
+	spi_finalize_current_message(ctlr);
 	if (mesg->complete)
 		mesg->complete(mesg->context);
 
@@ -334,6 +322,7 @@ static void spi_sh_work(struct work_struct *work)
 			 SPI_SH_CR1);
 	clear_fifo(ss);
 
+	return ret;
 }
 
 static int spi_sh_setup(struct spi_device *spi)
@@ -355,29 +344,6 @@ static int spi_sh_setup(struct spi_device *spi)
 	return 0;
 }
 
-static int spi_sh_transfer(struct spi_device *spi, struct spi_message *mesg)
-{
-	struct spi_sh_data *ss = spi_master_get_devdata(spi->master);
-	unsigned long flags;
-
-	pr_debug("%s: enter\n", __func__);
-	pr_debug("\tmode = %02x\n", spi->mode);
-
-	spin_lock_irqsave(&ss->lock, flags);
-
-	mesg->actual_length = 0;
-	mesg->status = -EINPROGRESS;
-
-	spi_sh_clear_bit(ss, SPI_SH_SSA, SPI_SH_CR1);
-
-	list_add_tail(&mesg->queue, &ss->queue);
-	schedule_work(&ss->ws);
-
-	spin_unlock_irqrestore(&ss->lock, flags);
-
-	return 0;
-}
-
 static void spi_sh_cleanup(struct spi_device *spi)
 {
 	struct spi_sh_data *ss = spi_master_get_devdata(spi->master);
@@ -416,7 +382,6 @@ static int spi_sh_remove(struct platform_device *pdev)
 	struct spi_sh_data *ss = platform_get_drvdata(pdev);
 
 	spi_unregister_master(ss->master);
-	flush_work(&ss->ws);
 	free_irq(ss->irq, ss);
 
 	return 0;
@@ -467,9 +432,6 @@ static int spi_sh_probe(struct platform_device *pdev)
 		dev_err(&pdev->dev, "ioremap error.\n");
 		return -ENOMEM;
 	}
-	INIT_LIST_HEAD(&ss->queue);
-	spin_lock_init(&ss->lock);
-	INIT_WORK(&ss->ws, spi_sh_work);
 	init_waitqueue_head(&ss->wait);
 
 	ret = request_irq(irq, spi_sh_irq, 0, "spi_sh", ss);
@@ -481,7 +443,7 @@ static int spi_sh_probe(struct platform_device *pdev)
 	master->num_chipselect = 2;
 	master->bus_num = pdev->id;
 	master->setup = spi_sh_setup;
-	master->transfer = spi_sh_transfer;
+	master->transfer_one_message = spi_sh_transfer_one_message;
 	master->cleanup = spi_sh_cleanup;
 
 	ret = spi_register_master(master);
-- 
2.30.2


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

* Re: [PATCH] spi: sh: Switch to using core message queue
  2022-06-10 15:46 [PATCH] spi: sh: Switch to using core message queue Mark Brown
@ 2022-06-27 20:33 ` Mark Brown
  0 siblings, 0 replies; 2+ messages in thread
From: Mark Brown @ 2022-06-27 20:33 UTC (permalink / raw)
  To: yoshihiro.shimoda.uh, broonie; +Cc: linux-spi

On Fri, 10 Jun 2022 16:46:49 +0100, Mark Brown wrote:
> We deprecated open coding of the transfer queue back in 2017 so it's high
> time we finished up converting drivers to use the standard message queue
> code. The SH driver is fairly straightforward so convert to use
> transfer_one_message(), it looks like the driver would be a good fit for
> transfer_one() with a little bit of updating but this smaller change seems
> safer.
> 
> [...]

Applied to

   https://git.kernel.org/pub/scm/linux/kernel/git/broonie/spi.git for-next

Thanks!

[1/1] spi: sh: Switch to using core message queue
      commit: e2185072a4a4786eb46be046cf20494c08dcc78f

All being well this means that it will be integrated into the linux-next
tree (usually sometime in the next 24 hours) and sent to Linus during
the next merge window (or sooner if it is a bug fix), however if
problems are discovered then the patch may be dropped or reverted.

You may get further e-mails resulting from automated or manual testing
and review of the tree, please engage with people reporting problems and
send followup patches addressing any issues that are reported if needed.

If any updates are required or you are submitting further changes they
should be sent as incremental updates against current git, existing
patches will not be replaced.

Please add any relevant lists and maintainers to the CCs when replying
to this mail.

Thanks,
Mark

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

end of thread, other threads:[~2022-06-27 20:33 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-06-10 15:46 [PATCH] spi: sh: Switch to using core message queue Mark Brown
2022-06-27 20:33 ` Mark Brown

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).