linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH V3 0/4] spi: lpspi: Add Slave Mode support for LPSPI
@ 2018-12-07  2:50 Clark Wang
  2018-12-07  2:50 ` [PATCH V3 1/4] spi: lpspi: Replace all "master" with "controller" Clark Wang
                   ` (3 more replies)
  0 siblings, 4 replies; 8+ messages in thread
From: Clark Wang @ 2018-12-07  2:50 UTC (permalink / raw)
  To: broonie; +Cc: linux-spi, linux-kernel, Clark Wang

Hi Mark,

i.MX LPSPI controller only works in Master mode previously. This patch
series adds support slave mode to LPSPI controller, including:
 - Replace all related structure names and object names which is named
   "master" with "controller",
 - adds SPI slave mode support for i.MX7ulp and i.MX8qm/qxp in PIO mode,
 - DT binding updates for slave mode.

Currently SPI Slave mode support patch has the following limitations:
1. The stale data in RXFIFO will be dropped when the Slave does any new
   transfer.
2. One transfer can be finished only after all transfer->len data been
   transferred to master device
3. Slave device only accepts transfer->len data. Any data longer than
   this from master device will be dropped. Any data shorter than this
   from master will cause LPSPI to stuck due to mentioned limitation 2.
4. Only PIO transfer is supported in Slave Mode.

Wire connection:
GND, SCK, MISO(to MISO of slave), MOSI(to MOSI of slave), SCS

Change log:
V2: 
 - Split last version patch into 3 patches, and add the doc update.
V3:
 - Add more detailed description in commit message of the second patch.
 - Keep the description of "fsl,imx8qxp-spi" in spi-fsl-lpspi.txt in the
   fourth patch.

Clark Wang (4):
  spi: lpspi: Replace all "master" with "controller"
  spi: lpspi: Add slave mode support
  spi: lpspi: Let watermark change with send data length
  doc: lpspi: Document DT bindings for LPSPI slave mode

 .../devicetree/bindings/spi/spi-fsl-lpspi.txt |   4 +
 drivers/spi/spi-fsl-lpspi.c                   | 202 ++++++++++++------
 2 files changed, 138 insertions(+), 68 deletions(-)

-- 
2.17.1


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

* [PATCH V3 1/4] spi: lpspi: Replace all "master" with "controller"
  2018-12-07  2:50 [PATCH V3 0/4] spi: lpspi: Add Slave Mode support for LPSPI Clark Wang
@ 2018-12-07  2:50 ` Clark Wang
  2018-12-08  5:14   ` Joe Perches
  2018-12-07  2:50 ` [PATCH V3 2/4] spi: lpspi: Add slave mode support Clark Wang
                   ` (2 subsequent siblings)
  3 siblings, 1 reply; 8+ messages in thread
From: Clark Wang @ 2018-12-07  2:50 UTC (permalink / raw)
  To: broonie; +Cc: linux-spi, linux-kernel, Clark Wang

In order to enable the slave mode and make the code more readable,
replace all related structure names and object names which is
named "master" with "controller".

Signed-off-by: Clark Wang <xiaoning.wang@nxp.com>
---
Change log:
V2/V3:
 - No change.
---
 drivers/spi/spi-fsl-lpspi.c | 84 ++++++++++++++++++++-----------------
 1 file changed, 46 insertions(+), 38 deletions(-)

diff --git a/drivers/spi/spi-fsl-lpspi.c b/drivers/spi/spi-fsl-lpspi.c
index 51670976faa3..725d6ac5f814 100644
--- a/drivers/spi/spi-fsl-lpspi.c
+++ b/drivers/spi/spi-fsl-lpspi.c
@@ -3,6 +3,7 @@
 // Freescale i.MX7ULP LPSPI driver
 //
 // Copyright 2016 Freescale Semiconductor, Inc.
+// Copyright 2018 NXP Semiconductors
 
 #include <linux/clk.h>
 #include <linux/completion.h>
@@ -137,16 +138,18 @@ static void fsl_lpspi_intctrl(struct fsl_lpspi_data *fsl_lpspi,
 	writel(enable, fsl_lpspi->base + IMX7ULP_IER);
 }
 
-static int lpspi_prepare_xfer_hardware(struct spi_master *master)
+static int lpspi_prepare_xfer_hardware(struct spi_controller *controller)
 {
-	struct fsl_lpspi_data *fsl_lpspi = spi_master_get_devdata(master);
+	struct fsl_lpspi_data *fsl_lpspi =
+				spi_controller_get_devdata(controller);
 
 	return clk_prepare_enable(fsl_lpspi->clk);
 }
 
-static int lpspi_unprepare_xfer_hardware(struct spi_master *master)
+static int lpspi_unprepare_xfer_hardware(struct spi_controller *controller)
 {
-	struct fsl_lpspi_data *fsl_lpspi = spi_master_get_devdata(master);
+	struct fsl_lpspi_data *fsl_lpspi =
+				spi_controller_get_devdata(controller);
 
 	clk_disable_unprepare(fsl_lpspi->clk);
 
@@ -291,7 +294,8 @@ static int fsl_lpspi_config(struct fsl_lpspi_data *fsl_lpspi)
 static void fsl_lpspi_setup_transfer(struct spi_device *spi,
 				     struct spi_transfer *t)
 {
-	struct fsl_lpspi_data *fsl_lpspi = spi_master_get_devdata(spi->master);
+	struct fsl_lpspi_data *fsl_lpspi =
+				spi_controller_get_devdata(spi->controller);
 
 	fsl_lpspi->config.mode = spi->mode;
 	fsl_lpspi->config.bpw = t ? t->bits_per_word : spi->bits_per_word;
@@ -318,11 +322,12 @@ static void fsl_lpspi_setup_transfer(struct spi_device *spi,
 	fsl_lpspi_config(fsl_lpspi);
 }
 
-static int fsl_lpspi_transfer_one(struct spi_master *master,
+static int fsl_lpspi_transfer_one(struct spi_controller *controller,
 				  struct spi_device *spi,
 				  struct spi_transfer *t)
 {
-	struct fsl_lpspi_data *fsl_lpspi = spi_master_get_devdata(master);
+	struct fsl_lpspi_data *fsl_lpspi =
+				spi_controller_get_devdata(controller);
 	int ret;
 
 	fsl_lpspi->tx_buf = t->tx_buf;
@@ -347,10 +352,11 @@ static int fsl_lpspi_transfer_one(struct spi_master *master,
 	return 0;
 }
 
-static int fsl_lpspi_transfer_one_msg(struct spi_master *master,
+static int fsl_lpspi_transfer_one_msg(struct spi_controller *controller,
 				      struct spi_message *msg)
 {
-	struct fsl_lpspi_data *fsl_lpspi = spi_master_get_devdata(master);
+	struct fsl_lpspi_data *fsl_lpspi =
+				spi_controller_get_devdata(controller);
 	struct spi_device *spi = msg->spi;
 	struct spi_transfer *xfer;
 	bool is_first_xfer = true;
@@ -366,7 +372,7 @@ static int fsl_lpspi_transfer_one_msg(struct spi_master *master,
 
 		is_first_xfer = false;
 
-		ret = fsl_lpspi_transfer_one(master, spi, xfer);
+		ret = fsl_lpspi_transfer_one(controller, spi, xfer);
 		if (ret < 0)
 			goto complete;
 
@@ -380,7 +386,7 @@ static int fsl_lpspi_transfer_one_msg(struct spi_master *master,
 	writel(temp, fsl_lpspi->base + IMX7ULP_TCR);
 
 	msg->status = ret;
-	spi_finalize_current_message(master);
+	spi_finalize_current_message(controller);
 
 	return ret;
 }
@@ -410,30 +416,31 @@ static irqreturn_t fsl_lpspi_isr(int irq, void *dev_id)
 static int fsl_lpspi_probe(struct platform_device *pdev)
 {
 	struct fsl_lpspi_data *fsl_lpspi;
-	struct spi_master *master;
+	struct spi_controller *controller;
 	struct resource *res;
 	int ret, irq;
 	u32 temp;
 
-	master = spi_alloc_master(&pdev->dev, sizeof(struct fsl_lpspi_data));
-	if (!master)
+	controller = spi_alloc_master(&pdev->dev,
+					sizeof(struct fsl_lpspi_data));
+	if (!controller)
 		return -ENOMEM;
 
-	platform_set_drvdata(pdev, master);
+	platform_set_drvdata(pdev, controller);
 
-	master->bits_per_word_mask = SPI_BPW_RANGE_MASK(8, 32);
-	master->bus_num = pdev->id;
+	controller->bits_per_word_mask = SPI_BPW_RANGE_MASK(8, 32);
+	controller->bus_num = pdev->id;
 
-	fsl_lpspi = spi_master_get_devdata(master);
+	fsl_lpspi = spi_controller_get_devdata(controller);
 	fsl_lpspi->dev = &pdev->dev;
 
-	master->transfer_one_message = fsl_lpspi_transfer_one_msg;
-	master->prepare_transfer_hardware = lpspi_prepare_xfer_hardware;
-	master->unprepare_transfer_hardware = lpspi_unprepare_xfer_hardware;
-	master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH;
-	master->flags = SPI_MASTER_MUST_RX | SPI_MASTER_MUST_TX;
-	master->dev.of_node = pdev->dev.of_node;
-	master->bus_num = pdev->id;
+	controller->transfer_one_message = fsl_lpspi_transfer_one_msg;
+	controller->prepare_transfer_hardware = lpspi_prepare_xfer_hardware;
+	controller->unprepare_transfer_hardware = lpspi_unprepare_xfer_hardware;
+	controller->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH;
+	controller->flags = SPI_MASTER_MUST_RX | SPI_MASTER_MUST_TX;
+	controller->dev.of_node = pdev->dev.of_node;
+	controller->bus_num = pdev->id;
 
 	init_completion(&fsl_lpspi->xfer_done);
 
@@ -441,32 +448,32 @@ static int fsl_lpspi_probe(struct platform_device *pdev)
 	fsl_lpspi->base = devm_ioremap_resource(&pdev->dev, res);
 	if (IS_ERR(fsl_lpspi->base)) {
 		ret = PTR_ERR(fsl_lpspi->base);
-		goto out_master_put;
+		goto out_controller_put;
 	}
 
 	irq = platform_get_irq(pdev, 0);
 	if (irq < 0) {
 		ret = irq;
-		goto out_master_put;
+		goto out_controller_put;
 	}
 
 	ret = devm_request_irq(&pdev->dev, irq, fsl_lpspi_isr, 0,
 			       dev_name(&pdev->dev), fsl_lpspi);
 	if (ret) {
 		dev_err(&pdev->dev, "can't get irq%d: %d\n", irq, ret);
-		goto out_master_put;
+		goto out_controller_put;
 	}
 
 	fsl_lpspi->clk = devm_clk_get(&pdev->dev, "ipg");
 	if (IS_ERR(fsl_lpspi->clk)) {
 		ret = PTR_ERR(fsl_lpspi->clk);
-		goto out_master_put;
+		goto out_controller_put;
 	}
 
 	ret = clk_prepare_enable(fsl_lpspi->clk);
 	if (ret) {
 		dev_err(&pdev->dev, "can't enable lpspi clock, ret=%d\n", ret);
-		goto out_master_put;
+		goto out_controller_put;
 	}
 
 	temp = readl(fsl_lpspi->base + IMX7ULP_PARAM);
@@ -475,24 +482,25 @@ static int fsl_lpspi_probe(struct platform_device *pdev)
 
 	clk_disable_unprepare(fsl_lpspi->clk);
 
-	ret = devm_spi_register_master(&pdev->dev, master);
+	ret = devm_spi_register_controller(&pdev->dev, controller);
 	if (ret < 0) {
-		dev_err(&pdev->dev, "spi_register_master error.\n");
-		goto out_master_put;
+		dev_err(&pdev->dev, "spi_register_controller error.\n");
+		goto out_controller_put;
 	}
 
 	return 0;
 
-out_master_put:
-	spi_master_put(master);
+out_controller_put:
+	spi_controller_put(controller);
 
 	return ret;
 }
 
 static int fsl_lpspi_remove(struct platform_device *pdev)
 {
-	struct spi_master *master = platform_get_drvdata(pdev);
-	struct fsl_lpspi_data *fsl_lpspi = spi_master_get_devdata(master);
+	struct spi_controller *controller = platform_get_drvdata(pdev);
+	struct fsl_lpspi_data *fsl_lpspi =
+				spi_controller_get_devdata(controller);
 
 	clk_disable_unprepare(fsl_lpspi->clk);
 
@@ -509,6 +517,6 @@ static struct platform_driver fsl_lpspi_driver = {
 };
 module_platform_driver(fsl_lpspi_driver);
 
-MODULE_DESCRIPTION("LPSPI Master Controller driver");
+MODULE_DESCRIPTION("LPSPI Controller driver");
 MODULE_AUTHOR("Gao Pan <pandy.gao@nxp.com>");
 MODULE_LICENSE("GPL");
-- 
2.17.1


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

* [PATCH V3 2/4] spi: lpspi: Add slave mode support
  2018-12-07  2:50 [PATCH V3 0/4] spi: lpspi: Add Slave Mode support for LPSPI Clark Wang
  2018-12-07  2:50 ` [PATCH V3 1/4] spi: lpspi: Replace all "master" with "controller" Clark Wang
@ 2018-12-07  2:50 ` Clark Wang
  2018-12-07  2:50 ` [PATCH V3 3/4] spi: lpspi: Let watermark change with send data length Clark Wang
  2018-12-07  2:50 ` [PATCH V3 4/4] doc: lpspi: Document DT bindings for LPSPI slave mode Clark Wang
  3 siblings, 0 replies; 8+ messages in thread
From: Clark Wang @ 2018-12-07  2:50 UTC (permalink / raw)
  To: broonie; +Cc: linux-spi, linux-kernel, Clark Wang

Add slave mode support to the fsl-lpspi driver, only in PIO mode.

For now, there are some limitations for slave mode transmission:
1. The stale data in RXFIFO will be dropped when the Slave does any new
   transfer.
2. One transfer can be finished only after all transfer->len data been
   transferred to master device
3. Slave device only accepts transfer->len data. Any data longer than
   this from master device will be dropped. Any data shorter than this
   from master will cause LPSPI to stuck due to mentioned limitation 2.
4. Only PIO transfer is supported in Slave Mode.

Wire connection:
GND, SCK, MISO(to MISO of slave), MOSI(to MOSI of slave), SCS

Signed-off-by: Clark Wang <xiaoning.wang@nxp.com>
---
Change log:
V2: 
 - No change.
V3:
 - Add more detailed description in commit message.
---
 drivers/spi/spi-fsl-lpspi.c | 107 ++++++++++++++++++++++++++----------
 1 file changed, 79 insertions(+), 28 deletions(-)

diff --git a/drivers/spi/spi-fsl-lpspi.c b/drivers/spi/spi-fsl-lpspi.c
index 725d6ac5f814..cbf165e7bd17 100644
--- a/drivers/spi/spi-fsl-lpspi.c
+++ b/drivers/spi/spi-fsl-lpspi.c
@@ -55,6 +55,7 @@
 #define IER_RDIE	BIT(1)
 #define IER_TDIE	BIT(0)
 #define CFGR1_PCSCFG	BIT(27)
+#define CFGR1_PINCFG	(BIT(24)|BIT(25))
 #define CFGR1_PCSPOL	BIT(8)
 #define CFGR1_NOSTALL	BIT(3)
 #define CFGR1_MASTER	BIT(0)
@@ -80,6 +81,7 @@ struct fsl_lpspi_data {
 	struct device *dev;
 	void __iomem *base;
 	struct clk *clk;
+	bool is_slave;
 
 	void *rx_buf;
 	const void *tx_buf;
@@ -92,6 +94,8 @@ struct fsl_lpspi_data {
 
 	struct lpspi_config config;
 	struct completion xfer_done;
+
+	bool slave_aborted;
 };
 
 static const struct of_device_id fsl_lpspi_dt_ids[] = {
@@ -206,21 +210,22 @@ static void fsl_lpspi_set_cmd(struct fsl_lpspi_data *fsl_lpspi,
 	u32 temp = 0;
 
 	temp |= fsl_lpspi->config.bpw - 1;
-	temp |= fsl_lpspi->config.prescale << 27;
 	temp |= (fsl_lpspi->config.mode & 0x3) << 30;
-	temp |= (fsl_lpspi->config.chip_select & 0x3) << 24;
-
-	/*
-	 * Set TCR_CONT will keep SS asserted after current transfer.
-	 * For the first transfer, clear TCR_CONTC to assert SS.
-	 * For subsequent transfer, set TCR_CONTC to keep SS asserted.
-	 */
-	temp |= TCR_CONT;
-	if (is_first_xfer)
-		temp &= ~TCR_CONTC;
-	else
-		temp |= TCR_CONTC;
-
+	if (!fsl_lpspi->is_slave) {
+		temp |= fsl_lpspi->config.prescale << 27;
+		temp |= (fsl_lpspi->config.chip_select & 0x3) << 24;
+
+		/*
+		 * Set TCR_CONT will keep SS asserted after current transfer.
+		 * For the first transfer, clear TCR_CONTC to assert SS.
+		 * For subsequent transfer, set TCR_CONTC to keep SS asserted.
+		 */
+		temp |= TCR_CONT;
+		if (is_first_xfer)
+			temp &= ~TCR_CONTC;
+		else
+			temp |= TCR_CONTC;
+	}
 	writel(temp, fsl_lpspi->base + IMX7ULP_TCR);
 
 	dev_dbg(fsl_lpspi->dev, "TCR=0x%x\n", temp);
@@ -273,13 +278,18 @@ static int fsl_lpspi_config(struct fsl_lpspi_data *fsl_lpspi)
 	writel(temp, fsl_lpspi->base + IMX7ULP_CR);
 	writel(0, fsl_lpspi->base + IMX7ULP_CR);
 
-	ret = fsl_lpspi_set_bitrate(fsl_lpspi);
-	if (ret)
-		return ret;
+	if (!fsl_lpspi->is_slave) {
+		ret = fsl_lpspi_set_bitrate(fsl_lpspi);
+		if (ret)
+			return ret;
+	}
 
 	fsl_lpspi_set_watermark(fsl_lpspi);
 
-	temp = CFGR1_PCSCFG | CFGR1_MASTER;
+	if (!fsl_lpspi->is_slave)
+		temp = CFGR1_MASTER;
+	else
+		temp = CFGR1_PINCFG;
 	if (fsl_lpspi->config.mode & SPI_CS_HIGH)
 		temp |= CFGR1_PCSPOL;
 	writel(temp, fsl_lpspi->base + IMX7ULP_CFGR1);
@@ -322,6 +332,37 @@ static void fsl_lpspi_setup_transfer(struct spi_device *spi,
 	fsl_lpspi_config(fsl_lpspi);
 }
 
+static int fsl_lpspi_slave_abort(struct spi_controller *controller)
+{
+	struct fsl_lpspi_data *fsl_lpspi =
+				spi_controller_get_devdata(controller);
+
+	fsl_lpspi->slave_aborted = true;
+	complete(&fsl_lpspi->xfer_done);
+	return 0;
+}
+
+static int fsl_lpspi_wait_for_completion(struct spi_controller *controller)
+{
+	struct fsl_lpspi_data *fsl_lpspi =
+				spi_controller_get_devdata(controller);
+
+	if (fsl_lpspi->is_slave) {
+		if (wait_for_completion_interruptible(&fsl_lpspi->xfer_done) ||
+			fsl_lpspi->slave_aborted) {
+			dev_dbg(fsl_lpspi->dev, "interrupted\n");
+			return -EINTR;
+		}
+	} else {
+		if (!wait_for_completion_timeout(&fsl_lpspi->xfer_done, HZ)) {
+			dev_dbg(fsl_lpspi->dev, "wait for completion timeout\n");
+			return -ETIMEDOUT;
+		}
+	}
+
+	return 0;
+}
+
 static int fsl_lpspi_transfer_one(struct spi_controller *controller,
 				  struct spi_device *spi,
 				  struct spi_transfer *t)
@@ -335,13 +376,13 @@ static int fsl_lpspi_transfer_one(struct spi_controller *controller,
 	fsl_lpspi->remain = t->len;
 
 	reinit_completion(&fsl_lpspi->xfer_done);
+	fsl_lpspi->slave_aborted = false;
+
 	fsl_lpspi_write_tx_fifo(fsl_lpspi);
 
-	ret = wait_for_completion_timeout(&fsl_lpspi->xfer_done, HZ);
-	if (!ret) {
-		dev_dbg(fsl_lpspi->dev, "wait for completion timeout\n");
-		return -ETIMEDOUT;
-	}
+	ret = fsl_lpspi_wait_for_completion(controller);
+	if (ret)
+		return ret;
 
 	ret = fsl_lpspi_txfifo_empty(fsl_lpspi);
 	if (ret)
@@ -380,10 +421,12 @@ static int fsl_lpspi_transfer_one_msg(struct spi_controller *controller,
 	}
 
 complete:
-	/* de-assert SS, then finalize current message */
-	temp = readl(fsl_lpspi->base + IMX7ULP_TCR);
-	temp &= ~TCR_CONTC;
-	writel(temp, fsl_lpspi->base + IMX7ULP_TCR);
+	if (!fsl_lpspi->is_slave) {
+		/* de-assert SS, then finalize current message */
+		temp = readl(fsl_lpspi->base + IMX7ULP_TCR);
+		temp &= ~TCR_CONTC;
+		writel(temp, fsl_lpspi->base + IMX7ULP_TCR);
+	}
 
 	msg->status = ret;
 	spi_finalize_current_message(controller);
@@ -421,8 +464,13 @@ static int fsl_lpspi_probe(struct platform_device *pdev)
 	int ret, irq;
 	u32 temp;
 
-	controller = spi_alloc_master(&pdev->dev,
+	if (of_property_read_bool((&pdev->dev)->of_node, "spi-slave"))
+		controller = spi_alloc_slave(&pdev->dev,
+					sizeof(struct fsl_lpspi_data));
+	else
+		controller = spi_alloc_master(&pdev->dev,
 					sizeof(struct fsl_lpspi_data));
+
 	if (!controller)
 		return -ENOMEM;
 
@@ -433,6 +481,8 @@ static int fsl_lpspi_probe(struct platform_device *pdev)
 
 	fsl_lpspi = spi_controller_get_devdata(controller);
 	fsl_lpspi->dev = &pdev->dev;
+	fsl_lpspi->is_slave = of_property_read_bool((&pdev->dev)->of_node,
+						    "spi-slave");
 
 	controller->transfer_one_message = fsl_lpspi_transfer_one_msg;
 	controller->prepare_transfer_hardware = lpspi_prepare_xfer_hardware;
@@ -441,6 +491,7 @@ static int fsl_lpspi_probe(struct platform_device *pdev)
 	controller->flags = SPI_MASTER_MUST_RX | SPI_MASTER_MUST_TX;
 	controller->dev.of_node = pdev->dev.of_node;
 	controller->bus_num = pdev->id;
+	controller->slave_abort = fsl_lpspi_slave_abort;
 
 	init_completion(&fsl_lpspi->xfer_done);
 
-- 
2.17.1


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

* [PATCH V3 3/4] spi: lpspi: Let watermark change with send data length
  2018-12-07  2:50 [PATCH V3 0/4] spi: lpspi: Add Slave Mode support for LPSPI Clark Wang
  2018-12-07  2:50 ` [PATCH V3 1/4] spi: lpspi: Replace all "master" with "controller" Clark Wang
  2018-12-07  2:50 ` [PATCH V3 2/4] spi: lpspi: Add slave mode support Clark Wang
@ 2018-12-07  2:50 ` Clark Wang
  2018-12-07  2:50 ` [PATCH V3 4/4] doc: lpspi: Document DT bindings for LPSPI slave mode Clark Wang
  3 siblings, 0 replies; 8+ messages in thread
From: Clark Wang @ 2018-12-07  2:50 UTC (permalink / raw)
  To: broonie; +Cc: linux-spi, linux-kernel, Clark Wang

Configure watermark to change with the length of the sent data.
Support LPSPI sending message shorter than tx/rxfifosize.

Signed-off-by: Clark Wang <xiaoning.wang@nxp.com>
---
Change log:
V2/V3:
 - No change.
---
 drivers/spi/spi-fsl-lpspi.c | 11 +++++++++--
 1 file changed, 9 insertions(+), 2 deletions(-)

diff --git a/drivers/spi/spi-fsl-lpspi.c b/drivers/spi/spi-fsl-lpspi.c
index cbf165e7bd17..08dcc3c22e88 100644
--- a/drivers/spi/spi-fsl-lpspi.c
+++ b/drivers/spi/spi-fsl-lpspi.c
@@ -89,6 +89,7 @@ struct fsl_lpspi_data {
 	void (*rx)(struct fsl_lpspi_data *);
 
 	u32 remain;
+	u8 watermark;
 	u8 txfifosize;
 	u8 rxfifosize;
 
@@ -235,7 +236,7 @@ static void fsl_lpspi_set_watermark(struct fsl_lpspi_data *fsl_lpspi)
 {
 	u32 temp;
 
-	temp = fsl_lpspi->txfifosize >> 1 | (fsl_lpspi->rxfifosize >> 1) << 16;
+	temp = fsl_lpspi->watermark >> 1 | (fsl_lpspi->watermark >> 1) << 16;
 
 	writel(temp, fsl_lpspi->base + IMX7ULP_FCR);
 
@@ -261,7 +262,8 @@ static int fsl_lpspi_set_bitrate(struct fsl_lpspi_data *fsl_lpspi)
 	if (prescale == 8 && scldiv >= 256)
 		return -EINVAL;
 
-	writel(scldiv, fsl_lpspi->base + IMX7ULP_CCR);
+	writel(scldiv | (scldiv << 8) | ((scldiv >> 1) << 16),
+					fsl_lpspi->base + IMX7ULP_CCR);
 
 	dev_dbg(fsl_lpspi->dev, "perclk=%d, speed=%d, prescale =%d, scldiv=%d\n",
 		perclk_rate, config.speed_hz, prescale, scldiv);
@@ -329,6 +331,11 @@ static void fsl_lpspi_setup_transfer(struct spi_device *spi,
 		fsl_lpspi->tx = fsl_lpspi_buf_tx_u32;
 	}
 
+	if (t->len <= fsl_lpspi->txfifosize)
+		fsl_lpspi->watermark = t->len;
+	else
+		fsl_lpspi->watermark = fsl_lpspi->txfifosize;
+
 	fsl_lpspi_config(fsl_lpspi);
 }
 
-- 
2.17.1


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

* [PATCH V3 4/4] doc: lpspi: Document DT bindings for LPSPI slave mode
  2018-12-07  2:50 [PATCH V3 0/4] spi: lpspi: Add Slave Mode support for LPSPI Clark Wang
                   ` (2 preceding siblings ...)
  2018-12-07  2:50 ` [PATCH V3 3/4] spi: lpspi: Let watermark change with send data length Clark Wang
@ 2018-12-07  2:50 ` Clark Wang
  2018-12-13 12:09   ` Applied "doc: lpspi: Document DT bindings for LPSPI slave mode" to the spi tree Mark Brown
  3 siblings, 1 reply; 8+ messages in thread
From: Clark Wang @ 2018-12-07  2:50 UTC (permalink / raw)
  To: broonie; +Cc: linux-spi, linux-kernel, Clark Wang

Add introductions of interrupt-parent and spi-slave.

Signed-off-by: Clark Wang <xiaoning.wang@nxp.com>
---
Change log:
V2:
 - No change.
V3:
 - Keep the description of "fsl,imx8qxp-spi" in spi-fsl-lpspi.txt.
---
 Documentation/devicetree/bindings/spi/spi-fsl-lpspi.txt | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/Documentation/devicetree/bindings/spi/spi-fsl-lpspi.txt b/Documentation/devicetree/bindings/spi/spi-fsl-lpspi.txt
index 8d178a4503cf..6cc3c6fe25a3 100644
--- a/Documentation/devicetree/bindings/spi/spi-fsl-lpspi.txt
+++ b/Documentation/devicetree/bindings/spi/spi-fsl-lpspi.txt
@@ -5,8 +5,11 @@ Required properties:
   - "fsl,imx7ulp-spi" for LPSPI compatible with the one integrated on i.MX7ULP soc
   - "fsl,imx8qxp-spi" for LPSPI compatible with the one integrated on i.MX8QXP soc
 - reg : address and length of the lpspi master registers
+- interrupt-parent : core interrupt controller
 - interrupts : lpspi interrupt
 - clocks : lpspi clock specifier
+- spi-slave : spi slave mode support. In slave mode, add this attribute without
+	      value. In master mode, remove it.
 
 Examples:
 
@@ -16,4 +19,5 @@ lpspi2: lpspi@40290000 {
 	interrupt-parent = <&intc>;
 	interrupts = <GIC_SPI 28 IRQ_TYPE_LEVEL_HIGH>;
 	clocks = <&clks IMX7ULP_CLK_LPSPI2>;
+	spi-slave;
 };
-- 
2.17.1


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

* Re: [PATCH V3 1/4] spi: lpspi: Replace all "master" with "controller"
  2018-12-07  2:50 ` [PATCH V3 1/4] spi: lpspi: Replace all "master" with "controller" Clark Wang
@ 2018-12-08  5:14   ` Joe Perches
  2018-12-08  5:42     ` Clark Wang
  0 siblings, 1 reply; 8+ messages in thread
From: Joe Perches @ 2018-12-08  5:14 UTC (permalink / raw)
  To: Clark Wang, broonie; +Cc: linux-spi, linux-kernel

On Fri, 2018-12-07 at 02:50 +0000, Clark Wang wrote:
> In order to enable the slave mode and make the code more readable,
> replace all related structure names and object names which is
> named "master" with "controller".

In what sense does this make the code more readable?



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

* RE: [PATCH V3 1/4] spi: lpspi: Replace all "master" with "controller"
  2018-12-08  5:14   ` Joe Perches
@ 2018-12-08  5:42     ` Clark Wang
  0 siblings, 0 replies; 8+ messages in thread
From: Clark Wang @ 2018-12-08  5:42 UTC (permalink / raw)
  To: Joe Perches, broonie; +Cc: linux-spi, linux-kernel

Hi Joe,

This patch series adds slave mode for lpspi controller. So this driver can support both master and slave mode for lpspi controller after apply this patch series. Currently, both master mode and slave mode share the code in this driver. Therefore, using spi_master to represent the structure of slave mode will cause confusion.

When Geert Uytterhoeven add the slave support for spi, he had done " Generalize SPI 'master' to 'controller'" step, too. The commit ID is 8caab75fd2c2a92667cbb1cd315720bede3feaa9.

Thank you.

Regards,
Clark Wang

> -----Original Message-----
> From: Joe Perches <joe@perches.com>
> Sent: Saturday, December 8, 2018 13:14
> To: Clark Wang <xiaoning.wang@nxp.com>; broonie@kernel.org
> Cc: linux-spi@vger.kernel.org; linux-kernel@vger.kernel.org
> Subject: Re: [PATCH V3 1/4] spi: lpspi: Replace all "master" with "controller"
> 
> On Fri, 2018-12-07 at 02:50 +0000, Clark Wang wrote:
> > In order to enable the slave mode and make the code more readable,
> > replace all related structure names and object names which is named
> > "master" with "controller".
> 
> In what sense does this make the code more readable?
> 


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

* Applied "doc: lpspi: Document DT bindings for LPSPI slave mode" to the spi tree
  2018-12-07  2:50 ` [PATCH V3 4/4] doc: lpspi: Document DT bindings for LPSPI slave mode Clark Wang
@ 2018-12-13 12:09   ` Mark Brown
  0 siblings, 0 replies; 8+ messages in thread
From: Mark Brown @ 2018-12-13 12:09 UTC (permalink / raw)
  To: Clark Wang; +Cc: Mark Brown, broonie, linux-spi, linux-kernel, linux-spi

The patch

   doc: lpspi: Document DT bindings for LPSPI slave mode

has been applied to the spi tree at

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

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

From 62f82df488ce16f7068c7285820b2b7f7dcd7597 Mon Sep 17 00:00:00 2001
From: Clark Wang <xiaoning.wang@nxp.com>
Date: Fri, 7 Dec 2018 02:50:41 +0000
Subject: [PATCH] doc: lpspi: Document DT bindings for LPSPI slave mode

Add introductions of interrupt-parent and spi-slave.

Signed-off-by: Clark Wang <xiaoning.wang@nxp.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
---
 Documentation/devicetree/bindings/spi/spi-fsl-lpspi.txt | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/Documentation/devicetree/bindings/spi/spi-fsl-lpspi.txt b/Documentation/devicetree/bindings/spi/spi-fsl-lpspi.txt
index 8d178a4503cf..6cc3c6fe25a3 100644
--- a/Documentation/devicetree/bindings/spi/spi-fsl-lpspi.txt
+++ b/Documentation/devicetree/bindings/spi/spi-fsl-lpspi.txt
@@ -5,8 +5,11 @@ Required properties:
   - "fsl,imx7ulp-spi" for LPSPI compatible with the one integrated on i.MX7ULP soc
   - "fsl,imx8qxp-spi" for LPSPI compatible with the one integrated on i.MX8QXP soc
 - reg : address and length of the lpspi master registers
+- interrupt-parent : core interrupt controller
 - interrupts : lpspi interrupt
 - clocks : lpspi clock specifier
+- spi-slave : spi slave mode support. In slave mode, add this attribute without
+	      value. In master mode, remove it.
 
 Examples:
 
@@ -16,4 +19,5 @@ lpspi2: lpspi@40290000 {
 	interrupt-parent = <&intc>;
 	interrupts = <GIC_SPI 28 IRQ_TYPE_LEVEL_HIGH>;
 	clocks = <&clks IMX7ULP_CLK_LPSPI2>;
+	spi-slave;
 };
-- 
2.19.0.rc2


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

end of thread, other threads:[~2018-12-13 12:09 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-12-07  2:50 [PATCH V3 0/4] spi: lpspi: Add Slave Mode support for LPSPI Clark Wang
2018-12-07  2:50 ` [PATCH V3 1/4] spi: lpspi: Replace all "master" with "controller" Clark Wang
2018-12-08  5:14   ` Joe Perches
2018-12-08  5:42     ` Clark Wang
2018-12-07  2:50 ` [PATCH V3 2/4] spi: lpspi: Add slave mode support Clark Wang
2018-12-07  2:50 ` [PATCH V3 3/4] spi: lpspi: Let watermark change with send data length Clark Wang
2018-12-07  2:50 ` [PATCH V3 4/4] doc: lpspi: Document DT bindings for LPSPI slave mode Clark Wang
2018-12-13 12:09   ` Applied "doc: lpspi: Document DT bindings for LPSPI slave mode" to the spi tree 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).