All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2 0/6] mtd: spi-nor: Move cadence-qaudspi to spi-mem framework
@ 2020-05-26  9:35 ` Vignesh Raghavendra
  0 siblings, 0 replies; 36+ messages in thread
From: Vignesh Raghavendra @ 2020-05-26  9:35 UTC (permalink / raw)
  To: Tudor Ambarus, Mark Brown
  Cc: Vignesh Raghavendra, Boris Brezillon, Ramuthevar Vadivel Murugan,
	linux-mtd, linux-kernel, linux-spi, simon.k.r.goldschmidt,
	dinguyen, marex

mtd: spi-nor: Move cadence-qaudspi to spi-mem framework

This series is a subset of "[PATCH v12 0/4] spi: cadence-quadspi: Add
support for the Cadence QSPI controller" by Ramuthevar,Vadivel MuruganX
<vadivel.muruganx.ramuthevar@linux.intel.com> that intended to move
cadence-quadspi driver to spi-mem framework

Those patches were trying to accomplish too many things in a single set
of patches and need to split into smaller patches. This is reduced
version of above series.

Changes that are intended to make migration easy are split into separate
patches. Patches 1 to 3 drop features that cannot be supported under
spi-mem at the moment (backward compatibility is maintained).
Patch 4-5 are trivial cleanups. Patch 6 does the actual conversion to
spi-mem and patch 7 moves the driver to drivers/spi folder.

I have tested both INDAC mode (used by non TI platforms like Altera
SoCFPGA) and DAC mode (used by TI platforms) on TI EVMs.

Patches to move move bindings over to
"Documentation/devicetree/bindings/spi/" directory and also conversion
of bindig doc to YAML will be posted separately.  Support for Intel
platform would follow that.

v2:
Rework patch 1/6 to keep "cdns,is-decoded-cs" property supported.


Ramuthevar Vadivel Murugan (2):
  mtd: spi-nor: Convert cadence-quadspi to use spi-mem framework
  spi: Move cadence-quadspi driver to drivers/spi/

Vignesh Raghavendra (4):
  mtd: spi-nor: cadence-quadspi: Make driver independent of flash
    geometry
  mtd: spi-nor: cadence-quadspi: Provide a way to disable DAC mode
  mtd: spi-nor: cadence-quadspi: Don't initialize rx_dma_complete on
    failure
  mtd: spi-nor: cadence-quadspi: Fix error path on failure to acquire
    reset lines

 drivers/mtd/spi-nor/controllers/Kconfig       |  11 -
 drivers/mtd/spi-nor/controllers/Makefile      |   1 -
 drivers/spi/Kconfig                           |  11 +
 drivers/spi/Makefile                          |   1 +
 .../spi-cadence-quadspi.c}                    | 521 +++++++-----------
 5 files changed, 206 insertions(+), 339 deletions(-)
 rename drivers/{mtd/spi-nor/controllers/cadence-quadspi.c => spi/spi-cadence-quadspi.c} (74%)

-- 
2.26.2


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

* [PATCH v2 0/6] mtd: spi-nor: Move cadence-qaudspi to spi-mem framework
@ 2020-05-26  9:35 ` Vignesh Raghavendra
  0 siblings, 0 replies; 36+ messages in thread
From: Vignesh Raghavendra @ 2020-05-26  9:35 UTC (permalink / raw)
  To: Tudor Ambarus, Mark Brown
  Cc: marex, Vignesh Raghavendra, Boris Brezillon, dinguyen,
	simon.k.r.goldschmidt, linux-kernel, linux-spi,
	Ramuthevar Vadivel Murugan, linux-mtd

mtd: spi-nor: Move cadence-qaudspi to spi-mem framework

This series is a subset of "[PATCH v12 0/4] spi: cadence-quadspi: Add
support for the Cadence QSPI controller" by Ramuthevar,Vadivel MuruganX
<vadivel.muruganx.ramuthevar@linux.intel.com> that intended to move
cadence-quadspi driver to spi-mem framework

Those patches were trying to accomplish too many things in a single set
of patches and need to split into smaller patches. This is reduced
version of above series.

Changes that are intended to make migration easy are split into separate
patches. Patches 1 to 3 drop features that cannot be supported under
spi-mem at the moment (backward compatibility is maintained).
Patch 4-5 are trivial cleanups. Patch 6 does the actual conversion to
spi-mem and patch 7 moves the driver to drivers/spi folder.

I have tested both INDAC mode (used by non TI platforms like Altera
SoCFPGA) and DAC mode (used by TI platforms) on TI EVMs.

Patches to move move bindings over to
"Documentation/devicetree/bindings/spi/" directory and also conversion
of bindig doc to YAML will be posted separately.  Support for Intel
platform would follow that.

v2:
Rework patch 1/6 to keep "cdns,is-decoded-cs" property supported.


Ramuthevar Vadivel Murugan (2):
  mtd: spi-nor: Convert cadence-quadspi to use spi-mem framework
  spi: Move cadence-quadspi driver to drivers/spi/

Vignesh Raghavendra (4):
  mtd: spi-nor: cadence-quadspi: Make driver independent of flash
    geometry
  mtd: spi-nor: cadence-quadspi: Provide a way to disable DAC mode
  mtd: spi-nor: cadence-quadspi: Don't initialize rx_dma_complete on
    failure
  mtd: spi-nor: cadence-quadspi: Fix error path on failure to acquire
    reset lines

 drivers/mtd/spi-nor/controllers/Kconfig       |  11 -
 drivers/mtd/spi-nor/controllers/Makefile      |   1 -
 drivers/spi/Kconfig                           |  11 +
 drivers/spi/Makefile                          |   1 +
 .../spi-cadence-quadspi.c}                    | 521 +++++++-----------
 5 files changed, 206 insertions(+), 339 deletions(-)
 rename drivers/{mtd/spi-nor/controllers/cadence-quadspi.c => spi/spi-cadence-quadspi.c} (74%)

-- 
2.26.2


______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/

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

* [PATCH v2 1/6] mtd: spi-nor: cadence-quadspi: Make driver independent of flash geometry
  2020-05-26  9:35 ` Vignesh Raghavendra
@ 2020-05-26  9:35   ` Vignesh Raghavendra
  -1 siblings, 0 replies; 36+ messages in thread
From: Vignesh Raghavendra @ 2020-05-26  9:35 UTC (permalink / raw)
  To: Tudor Ambarus, Mark Brown
  Cc: Vignesh Raghavendra, Boris Brezillon, Ramuthevar Vadivel Murugan,
	linux-mtd, linux-kernel, linux-spi, simon.k.r.goldschmidt,
	dinguyen, marex

Drop configuration of Flash size, erase size and page size
configuration. Flash size is needed only if using AHB decoder (BIT 23 of
CONFIG_REG) which is not used by the driver.
Erase size and page size are needed if IP is configured to send WREN
automatically. But since SPI NOR layer takes care of sending WREN, there
is no need to configure these fields either.

Therefore drop these in preparation to move the driver to spi-mem
framework where flash geometry is not visible to controller driver.

Signed-off-by: Vignesh Raghavendra <vigneshr@ti.com>
---
 .../mtd/spi-nor/controllers/cadence-quadspi.c | 36 +------------------
 1 file changed, 1 insertion(+), 35 deletions(-)

diff --git a/drivers/mtd/spi-nor/controllers/cadence-quadspi.c b/drivers/mtd/spi-nor/controllers/cadence-quadspi.c
index 494dcab4aaaa..9b8554d44fac 100644
--- a/drivers/mtd/spi-nor/controllers/cadence-quadspi.c
+++ b/drivers/mtd/spi-nor/controllers/cadence-quadspi.c
@@ -77,9 +77,6 @@ struct cqspi_st {
 	dma_addr_t		mmap_phys_base;
 
 	int			current_cs;
-	int			current_page_size;
-	int			current_erase_size;
-	int			current_addr_width;
 	unsigned long		master_ref_clk_hz;
 	bool			is_decoded_cs;
 	u32			fifo_depth;
@@ -736,32 +733,6 @@ static void cqspi_chipselect(struct spi_nor *nor)
 	writel(reg, reg_base + CQSPI_REG_CONFIG);
 }
 
-static void cqspi_configure_cs_and_sizes(struct spi_nor *nor)
-{
-	struct cqspi_flash_pdata *f_pdata = nor->priv;
-	struct cqspi_st *cqspi = f_pdata->cqspi;
-	void __iomem *iobase = cqspi->iobase;
-	unsigned int reg;
-
-	/* configure page size and block size. */
-	reg = readl(iobase + CQSPI_REG_SIZE);
-	reg &= ~(CQSPI_REG_SIZE_PAGE_MASK << CQSPI_REG_SIZE_PAGE_LSB);
-	reg &= ~(CQSPI_REG_SIZE_BLOCK_MASK << CQSPI_REG_SIZE_BLOCK_LSB);
-	reg &= ~CQSPI_REG_SIZE_ADDRESS_MASK;
-	reg |= (nor->page_size << CQSPI_REG_SIZE_PAGE_LSB);
-	reg |= (ilog2(nor->mtd.erasesize) << CQSPI_REG_SIZE_BLOCK_LSB);
-	reg |= (nor->addr_width - 1);
-	writel(reg, iobase + CQSPI_REG_SIZE);
-
-	/* configure the chip select */
-	cqspi_chipselect(nor);
-
-	/* Store the new configuration of the controller */
-	cqspi->current_page_size = nor->page_size;
-	cqspi->current_erase_size = nor->mtd.erasesize;
-	cqspi->current_addr_width = nor->addr_width;
-}
-
 static unsigned int calculate_ticks_for_ns(const unsigned int ref_clk_hz,
 					   const unsigned int ns_val)
 {
@@ -867,18 +838,13 @@ static void cqspi_configure(struct spi_nor *nor)
 	int switch_cs = (cqspi->current_cs != f_pdata->cs);
 	int switch_ck = (cqspi->sclk != sclk);
 
-	if ((cqspi->current_page_size != nor->page_size) ||
-	    (cqspi->current_erase_size != nor->mtd.erasesize) ||
-	    (cqspi->current_addr_width != nor->addr_width))
-		switch_cs = 1;
-
 	if (switch_cs || switch_ck)
 		cqspi_controller_enable(cqspi, 0);
 
 	/* Switch chip select. */
 	if (switch_cs) {
 		cqspi->current_cs = f_pdata->cs;
-		cqspi_configure_cs_and_sizes(nor);
+		cqspi_chipselect(nor);
 	}
 
 	/* Setup baudrate divisor and delays */
-- 
2.26.2


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

* [PATCH v2 1/6] mtd: spi-nor: cadence-quadspi: Make driver independent of flash geometry
@ 2020-05-26  9:35   ` Vignesh Raghavendra
  0 siblings, 0 replies; 36+ messages in thread
From: Vignesh Raghavendra @ 2020-05-26  9:35 UTC (permalink / raw)
  To: Tudor Ambarus, Mark Brown
  Cc: marex, Vignesh Raghavendra, Boris Brezillon, dinguyen,
	simon.k.r.goldschmidt, linux-kernel, linux-spi,
	Ramuthevar Vadivel Murugan, linux-mtd

Drop configuration of Flash size, erase size and page size
configuration. Flash size is needed only if using AHB decoder (BIT 23 of
CONFIG_REG) which is not used by the driver.
Erase size and page size are needed if IP is configured to send WREN
automatically. But since SPI NOR layer takes care of sending WREN, there
is no need to configure these fields either.

Therefore drop these in preparation to move the driver to spi-mem
framework where flash geometry is not visible to controller driver.

Signed-off-by: Vignesh Raghavendra <vigneshr@ti.com>
---
 .../mtd/spi-nor/controllers/cadence-quadspi.c | 36 +------------------
 1 file changed, 1 insertion(+), 35 deletions(-)

diff --git a/drivers/mtd/spi-nor/controllers/cadence-quadspi.c b/drivers/mtd/spi-nor/controllers/cadence-quadspi.c
index 494dcab4aaaa..9b8554d44fac 100644
--- a/drivers/mtd/spi-nor/controllers/cadence-quadspi.c
+++ b/drivers/mtd/spi-nor/controllers/cadence-quadspi.c
@@ -77,9 +77,6 @@ struct cqspi_st {
 	dma_addr_t		mmap_phys_base;
 
 	int			current_cs;
-	int			current_page_size;
-	int			current_erase_size;
-	int			current_addr_width;
 	unsigned long		master_ref_clk_hz;
 	bool			is_decoded_cs;
 	u32			fifo_depth;
@@ -736,32 +733,6 @@ static void cqspi_chipselect(struct spi_nor *nor)
 	writel(reg, reg_base + CQSPI_REG_CONFIG);
 }
 
-static void cqspi_configure_cs_and_sizes(struct spi_nor *nor)
-{
-	struct cqspi_flash_pdata *f_pdata = nor->priv;
-	struct cqspi_st *cqspi = f_pdata->cqspi;
-	void __iomem *iobase = cqspi->iobase;
-	unsigned int reg;
-
-	/* configure page size and block size. */
-	reg = readl(iobase + CQSPI_REG_SIZE);
-	reg &= ~(CQSPI_REG_SIZE_PAGE_MASK << CQSPI_REG_SIZE_PAGE_LSB);
-	reg &= ~(CQSPI_REG_SIZE_BLOCK_MASK << CQSPI_REG_SIZE_BLOCK_LSB);
-	reg &= ~CQSPI_REG_SIZE_ADDRESS_MASK;
-	reg |= (nor->page_size << CQSPI_REG_SIZE_PAGE_LSB);
-	reg |= (ilog2(nor->mtd.erasesize) << CQSPI_REG_SIZE_BLOCK_LSB);
-	reg |= (nor->addr_width - 1);
-	writel(reg, iobase + CQSPI_REG_SIZE);
-
-	/* configure the chip select */
-	cqspi_chipselect(nor);
-
-	/* Store the new configuration of the controller */
-	cqspi->current_page_size = nor->page_size;
-	cqspi->current_erase_size = nor->mtd.erasesize;
-	cqspi->current_addr_width = nor->addr_width;
-}
-
 static unsigned int calculate_ticks_for_ns(const unsigned int ref_clk_hz,
 					   const unsigned int ns_val)
 {
@@ -867,18 +838,13 @@ static void cqspi_configure(struct spi_nor *nor)
 	int switch_cs = (cqspi->current_cs != f_pdata->cs);
 	int switch_ck = (cqspi->sclk != sclk);
 
-	if ((cqspi->current_page_size != nor->page_size) ||
-	    (cqspi->current_erase_size != nor->mtd.erasesize) ||
-	    (cqspi->current_addr_width != nor->addr_width))
-		switch_cs = 1;
-
 	if (switch_cs || switch_ck)
 		cqspi_controller_enable(cqspi, 0);
 
 	/* Switch chip select. */
 	if (switch_cs) {
 		cqspi->current_cs = f_pdata->cs;
-		cqspi_configure_cs_and_sizes(nor);
+		cqspi_chipselect(nor);
 	}
 
 	/* Setup baudrate divisor and delays */
-- 
2.26.2


______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/

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

* [PATCH v2 2/6] mtd: spi-nor: cadence-quadspi: Provide a way to disable DAC mode
  2020-05-26  9:35 ` Vignesh Raghavendra
@ 2020-05-26  9:36   ` Vignesh Raghavendra
  -1 siblings, 0 replies; 36+ messages in thread
From: Vignesh Raghavendra @ 2020-05-26  9:36 UTC (permalink / raw)
  To: Tudor Ambarus, Mark Brown
  Cc: Vignesh Raghavendra, Boris Brezillon, Ramuthevar Vadivel Murugan,
	linux-mtd, linux-kernel, linux-spi, simon.k.r.goldschmidt,
	dinguyen, marex

Currently direct access mode is used on platforms that have AHB window
(memory mapped window) larger than flash size. This feature is limited
to TI platforms as non TI platforms have < 1MB of AHB window.
Therefore introduce a driver quirk to disable DAC mode and set it for
non TI compatibles. This is in preparation to move to spi-mem framework
where flash geometry cannot be known.

Signed-off-by: Vignesh Raghavendra <vigneshr@ti.com>
---
 drivers/mtd/spi-nor/controllers/cadence-quadspi.c | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/drivers/mtd/spi-nor/controllers/cadence-quadspi.c b/drivers/mtd/spi-nor/controllers/cadence-quadspi.c
index 9b8554d44fac..8a9e17f79d8d 100644
--- a/drivers/mtd/spi-nor/controllers/cadence-quadspi.c
+++ b/drivers/mtd/spi-nor/controllers/cadence-quadspi.c
@@ -34,6 +34,7 @@
 
 /* Quirks */
 #define CQSPI_NEEDS_WR_DELAY		BIT(0)
+#define CQSPI_DISABLE_DAC_MODE		BIT(1)
 
 /* Capabilities mask */
 #define CQSPI_BASE_HWCAPS_MASK					\
@@ -1261,7 +1262,8 @@ static int cqspi_setup_flash(struct cqspi_st *cqspi, struct device_node *np)
 
 		f_pdata->registered = true;
 
-		if (mtd->size <= cqspi->ahb_size) {
+		if (mtd->size <= cqspi->ahb_size &&
+		    !(ddata->quirks & CQSPI_DISABLE_DAC_MODE)) {
 			f_pdata->use_direct_mode = true;
 			dev_dbg(nor->dev, "using direct mode for %s\n",
 				mtd->name);
@@ -1457,6 +1459,7 @@ static const struct dev_pm_ops cqspi__dev_pm_ops = {
 
 static const struct cqspi_driver_platdata cdns_qspi = {
 	.hwcaps_mask = CQSPI_BASE_HWCAPS_MASK,
+	.quirks = CQSPI_DISABLE_DAC_MODE,
 };
 
 static const struct cqspi_driver_platdata k2g_qspi = {
-- 
2.26.2


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

* [PATCH v2 2/6] mtd: spi-nor: cadence-quadspi: Provide a way to disable DAC mode
@ 2020-05-26  9:36   ` Vignesh Raghavendra
  0 siblings, 0 replies; 36+ messages in thread
From: Vignesh Raghavendra @ 2020-05-26  9:36 UTC (permalink / raw)
  To: Tudor Ambarus, Mark Brown
  Cc: marex, Vignesh Raghavendra, Boris Brezillon, dinguyen,
	simon.k.r.goldschmidt, linux-kernel, linux-spi,
	Ramuthevar Vadivel Murugan, linux-mtd

Currently direct access mode is used on platforms that have AHB window
(memory mapped window) larger than flash size. This feature is limited
to TI platforms as non TI platforms have < 1MB of AHB window.
Therefore introduce a driver quirk to disable DAC mode and set it for
non TI compatibles. This is in preparation to move to spi-mem framework
where flash geometry cannot be known.

Signed-off-by: Vignesh Raghavendra <vigneshr@ti.com>
---
 drivers/mtd/spi-nor/controllers/cadence-quadspi.c | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/drivers/mtd/spi-nor/controllers/cadence-quadspi.c b/drivers/mtd/spi-nor/controllers/cadence-quadspi.c
index 9b8554d44fac..8a9e17f79d8d 100644
--- a/drivers/mtd/spi-nor/controllers/cadence-quadspi.c
+++ b/drivers/mtd/spi-nor/controllers/cadence-quadspi.c
@@ -34,6 +34,7 @@
 
 /* Quirks */
 #define CQSPI_NEEDS_WR_DELAY		BIT(0)
+#define CQSPI_DISABLE_DAC_MODE		BIT(1)
 
 /* Capabilities mask */
 #define CQSPI_BASE_HWCAPS_MASK					\
@@ -1261,7 +1262,8 @@ static int cqspi_setup_flash(struct cqspi_st *cqspi, struct device_node *np)
 
 		f_pdata->registered = true;
 
-		if (mtd->size <= cqspi->ahb_size) {
+		if (mtd->size <= cqspi->ahb_size &&
+		    !(ddata->quirks & CQSPI_DISABLE_DAC_MODE)) {
 			f_pdata->use_direct_mode = true;
 			dev_dbg(nor->dev, "using direct mode for %s\n",
 				mtd->name);
@@ -1457,6 +1459,7 @@ static const struct dev_pm_ops cqspi__dev_pm_ops = {
 
 static const struct cqspi_driver_platdata cdns_qspi = {
 	.hwcaps_mask = CQSPI_BASE_HWCAPS_MASK,
+	.quirks = CQSPI_DISABLE_DAC_MODE,
 };
 
 static const struct cqspi_driver_platdata k2g_qspi = {
-- 
2.26.2


______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/

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

* [PATCH v2 3/6] mtd: spi-nor: cadence-quadspi: Don't initialize rx_dma_complete on failure
  2020-05-26  9:35 ` Vignesh Raghavendra
@ 2020-05-26  9:36   ` Vignesh Raghavendra
  -1 siblings, 0 replies; 36+ messages in thread
From: Vignesh Raghavendra @ 2020-05-26  9:36 UTC (permalink / raw)
  To: Tudor Ambarus, Mark Brown
  Cc: Vignesh Raghavendra, Boris Brezillon, Ramuthevar Vadivel Murugan,
	linux-mtd, linux-kernel, linux-spi, simon.k.r.goldschmidt,
	dinguyen, marex

If driver fails to acquire DMA channel then don't initialize
rx_dma_complete struct as it won't be used.

Signed-off-by: Vignesh Raghavendra <vigneshr@ti.com>
---
 drivers/mtd/spi-nor/controllers/cadence-quadspi.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/mtd/spi-nor/controllers/cadence-quadspi.c b/drivers/mtd/spi-nor/controllers/cadence-quadspi.c
index 8a9e17f79d8d..379e22c11c87 100644
--- a/drivers/mtd/spi-nor/controllers/cadence-quadspi.c
+++ b/drivers/mtd/spi-nor/controllers/cadence-quadspi.c
@@ -1180,6 +1180,7 @@ static void cqspi_request_mmap_dma(struct cqspi_st *cqspi)
 	if (IS_ERR(cqspi->rx_chan)) {
 		dev_err(&cqspi->pdev->dev, "No Rx DMA available\n");
 		cqspi->rx_chan = NULL;
+		return;
 	}
 	init_completion(&cqspi->rx_dma_complete);
 }
-- 
2.26.2


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

* [PATCH v2 3/6] mtd: spi-nor: cadence-quadspi: Don't initialize rx_dma_complete on failure
@ 2020-05-26  9:36   ` Vignesh Raghavendra
  0 siblings, 0 replies; 36+ messages in thread
From: Vignesh Raghavendra @ 2020-05-26  9:36 UTC (permalink / raw)
  To: Tudor Ambarus, Mark Brown
  Cc: marex, Vignesh Raghavendra, Boris Brezillon, dinguyen,
	simon.k.r.goldschmidt, linux-kernel, linux-spi,
	Ramuthevar Vadivel Murugan, linux-mtd

If driver fails to acquire DMA channel then don't initialize
rx_dma_complete struct as it won't be used.

Signed-off-by: Vignesh Raghavendra <vigneshr@ti.com>
---
 drivers/mtd/spi-nor/controllers/cadence-quadspi.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/mtd/spi-nor/controllers/cadence-quadspi.c b/drivers/mtd/spi-nor/controllers/cadence-quadspi.c
index 8a9e17f79d8d..379e22c11c87 100644
--- a/drivers/mtd/spi-nor/controllers/cadence-quadspi.c
+++ b/drivers/mtd/spi-nor/controllers/cadence-quadspi.c
@@ -1180,6 +1180,7 @@ static void cqspi_request_mmap_dma(struct cqspi_st *cqspi)
 	if (IS_ERR(cqspi->rx_chan)) {
 		dev_err(&cqspi->pdev->dev, "No Rx DMA available\n");
 		cqspi->rx_chan = NULL;
+		return;
 	}
 	init_completion(&cqspi->rx_dma_complete);
 }
-- 
2.26.2


______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/

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

* [PATCH v2 4/6] mtd: spi-nor: cadence-quadspi: Fix error path on failure to acquire reset lines
  2020-05-26  9:35 ` Vignesh Raghavendra
@ 2020-05-26  9:36   ` Vignesh Raghavendra
  -1 siblings, 0 replies; 36+ messages in thread
From: Vignesh Raghavendra @ 2020-05-26  9:36 UTC (permalink / raw)
  To: Tudor Ambarus, Mark Brown
  Cc: Vignesh Raghavendra, Boris Brezillon, Ramuthevar Vadivel Murugan,
	linux-mtd, linux-kernel, linux-spi, simon.k.r.goldschmidt,
	dinguyen, marex

Make sure to undo the prior changes done by the driver when exiting due
to failure to acquire reset lines.

Signed-off-by: Vignesh Raghavendra <vigneshr@ti.com>
---
 drivers/mtd/spi-nor/controllers/cadence-quadspi.c | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/mtd/spi-nor/controllers/cadence-quadspi.c b/drivers/mtd/spi-nor/controllers/cadence-quadspi.c
index 379e22c11c87..608ca657ff7f 100644
--- a/drivers/mtd/spi-nor/controllers/cadence-quadspi.c
+++ b/drivers/mtd/spi-nor/controllers/cadence-quadspi.c
@@ -1359,13 +1359,13 @@ static int cqspi_probe(struct platform_device *pdev)
 	rstc = devm_reset_control_get_optional_exclusive(dev, "qspi");
 	if (IS_ERR(rstc)) {
 		dev_err(dev, "Cannot get QSPI reset.\n");
-		return PTR_ERR(rstc);
+		goto probe_reset_failed;
 	}
 
 	rstc_ocp = devm_reset_control_get_optional_exclusive(dev, "qspi-ocp");
 	if (IS_ERR(rstc_ocp)) {
 		dev_err(dev, "Cannot get QSPI OCP reset.\n");
-		return PTR_ERR(rstc_ocp);
+		goto probe_reset_failed;
 	}
 
 	reset_control_assert(rstc);
@@ -1384,7 +1384,7 @@ static int cqspi_probe(struct platform_device *pdev)
 			       pdev->name, cqspi);
 	if (ret) {
 		dev_err(dev, "Cannot request IRQ.\n");
-		goto probe_irq_failed;
+		goto probe_reset_failed;
 	}
 
 	cqspi_wait_idle(cqspi);
@@ -1401,7 +1401,7 @@ static int cqspi_probe(struct platform_device *pdev)
 	return ret;
 probe_setup_failed:
 	cqspi_controller_enable(cqspi, 0);
-probe_irq_failed:
+probe_reset_failed:
 	clk_disable_unprepare(cqspi->clk);
 probe_clk_failed:
 	pm_runtime_put_sync(dev);
-- 
2.26.2


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

* [PATCH v2 4/6] mtd: spi-nor: cadence-quadspi: Fix error path on failure to acquire reset lines
@ 2020-05-26  9:36   ` Vignesh Raghavendra
  0 siblings, 0 replies; 36+ messages in thread
From: Vignesh Raghavendra @ 2020-05-26  9:36 UTC (permalink / raw)
  To: Tudor Ambarus, Mark Brown
  Cc: marex, Vignesh Raghavendra, Boris Brezillon, dinguyen,
	simon.k.r.goldschmidt, linux-kernel, linux-spi,
	Ramuthevar Vadivel Murugan, linux-mtd

Make sure to undo the prior changes done by the driver when exiting due
to failure to acquire reset lines.

Signed-off-by: Vignesh Raghavendra <vigneshr@ti.com>
---
 drivers/mtd/spi-nor/controllers/cadence-quadspi.c | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/mtd/spi-nor/controllers/cadence-quadspi.c b/drivers/mtd/spi-nor/controllers/cadence-quadspi.c
index 379e22c11c87..608ca657ff7f 100644
--- a/drivers/mtd/spi-nor/controllers/cadence-quadspi.c
+++ b/drivers/mtd/spi-nor/controllers/cadence-quadspi.c
@@ -1359,13 +1359,13 @@ static int cqspi_probe(struct platform_device *pdev)
 	rstc = devm_reset_control_get_optional_exclusive(dev, "qspi");
 	if (IS_ERR(rstc)) {
 		dev_err(dev, "Cannot get QSPI reset.\n");
-		return PTR_ERR(rstc);
+		goto probe_reset_failed;
 	}
 
 	rstc_ocp = devm_reset_control_get_optional_exclusive(dev, "qspi-ocp");
 	if (IS_ERR(rstc_ocp)) {
 		dev_err(dev, "Cannot get QSPI OCP reset.\n");
-		return PTR_ERR(rstc_ocp);
+		goto probe_reset_failed;
 	}
 
 	reset_control_assert(rstc);
@@ -1384,7 +1384,7 @@ static int cqspi_probe(struct platform_device *pdev)
 			       pdev->name, cqspi);
 	if (ret) {
 		dev_err(dev, "Cannot request IRQ.\n");
-		goto probe_irq_failed;
+		goto probe_reset_failed;
 	}
 
 	cqspi_wait_idle(cqspi);
@@ -1401,7 +1401,7 @@ static int cqspi_probe(struct platform_device *pdev)
 	return ret;
 probe_setup_failed:
 	cqspi_controller_enable(cqspi, 0);
-probe_irq_failed:
+probe_reset_failed:
 	clk_disable_unprepare(cqspi->clk);
 probe_clk_failed:
 	pm_runtime_put_sync(dev);
-- 
2.26.2


______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/

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

* [PATCH v2 5/6] mtd: spi-nor: Convert cadence-quadspi to use spi-mem framework
  2020-05-26  9:35 ` Vignesh Raghavendra
@ 2020-05-26  9:36   ` Vignesh Raghavendra
  -1 siblings, 0 replies; 36+ messages in thread
From: Vignesh Raghavendra @ 2020-05-26  9:36 UTC (permalink / raw)
  To: Tudor Ambarus, Mark Brown
  Cc: Vignesh Raghavendra, Boris Brezillon, Ramuthevar Vadivel Murugan,
	linux-mtd, linux-kernel, linux-spi, simon.k.r.goldschmidt,
	dinguyen, marex

From: Ramuthevar Vadivel Murugan <vadivel.muruganx.ramuthevar@linux.intel.com>

Move cadence-quadspi driver to use spi-mem framework. This is required
to make the driver support for SPI NAND flashes in future.

Driver is feature compliant with existing SPI NOR version.

Signed-off-by: Ramuthevar Vadivel Murugan <vadivel.muruganx.ramuthevar@linux.intel.com>
Signed-off-by: Vignesh Raghavendra <vigneshr@ti.com>
---
 .../mtd/spi-nor/controllers/cadence-quadspi.c | 469 +++++++-----------
 1 file changed, 183 insertions(+), 286 deletions(-)

diff --git a/drivers/mtd/spi-nor/controllers/cadence-quadspi.c b/drivers/mtd/spi-nor/controllers/cadence-quadspi.c
index 608ca657ff7f..c1df4b221889 100644
--- a/drivers/mtd/spi-nor/controllers/cadence-quadspi.c
+++ b/drivers/mtd/spi-nor/controllers/cadence-quadspi.c
@@ -3,6 +3,8 @@
  * Driver for Cadence QSPI Controller
  *
  * Copyright Altera Corporation (C) 2012-2014. All rights reserved.
+ * Copyright Intel Corporation (C) 2019-2020. All rights reserved.
+ * Copyright (C) 2020 Texas Instruments Incorporated - http://www.ti.com
  */
 #include <linux/clk.h>
 #include <linux/completion.h>
@@ -17,9 +19,6 @@
 #include <linux/jiffies.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
-#include <linux/mtd/mtd.h>
-#include <linux/mtd/partitions.h>
-#include <linux/mtd/spi-nor.h>
 #include <linux/of_device.h>
 #include <linux/of.h>
 #include <linux/platform_device.h>
@@ -27,6 +26,7 @@
 #include <linux/reset.h>
 #include <linux/sched.h>
 #include <linux/spi/spi.h>
+#include <linux/spi/spi-mem.h>
 #include <linux/timer.h>
 
 #define CQSPI_NAME			"cadence-qspi"
@@ -36,16 +36,12 @@
 #define CQSPI_NEEDS_WR_DELAY		BIT(0)
 #define CQSPI_DISABLE_DAC_MODE		BIT(1)
 
-/* Capabilities mask */
-#define CQSPI_BASE_HWCAPS_MASK					\
-	(SNOR_HWCAPS_READ | SNOR_HWCAPS_READ_FAST |		\
-	SNOR_HWCAPS_READ_1_1_2 | SNOR_HWCAPS_READ_1_1_4 |	\
-	SNOR_HWCAPS_PP)
+/* Capabilities */
+#define CQSPI_SUPPORTS_OCTAL		BIT(0)
 
 struct cqspi_st;
 
 struct cqspi_flash_pdata {
-	struct spi_nor	nor;
 	struct cqspi_st	*cqspi;
 	u32		clk_rate;
 	u32		read_delay;
@@ -58,7 +54,6 @@ struct cqspi_flash_pdata {
 	u8		data_width;
 	u8		cs;
 	bool		registered;
-	bool		use_direct_mode;
 };
 
 struct cqspi_st {
@@ -71,7 +66,6 @@ struct cqspi_st {
 	void __iomem		*ahb_base;
 	resource_size_t		ahb_size;
 	struct completion	transfer_complete;
-	struct mutex		bus_mutex;
 
 	struct dma_chan		*rx_chan;
 	struct completion	rx_dma_complete;
@@ -85,6 +79,7 @@ struct cqspi_st {
 	bool			rclk_en;
 	u32			trigger_address;
 	u32			wr_delay;
+	bool			use_dac_mode;
 	struct cqspi_flash_pdata f_pdata[CQSPI_MAX_CHIPSELECT];
 };
 
@@ -283,9 +278,8 @@ static irqreturn_t cqspi_irq_handler(int this_irq, void *dev)
 	return IRQ_HANDLED;
 }
 
-static unsigned int cqspi_calc_rdreg(struct spi_nor *nor)
+static unsigned int cqspi_calc_rdreg(struct cqspi_flash_pdata *f_pdata)
 {
-	struct cqspi_flash_pdata *f_pdata = nor->priv;
 	u32 rdreg = 0;
 
 	rdreg |= f_pdata->inst_width << CQSPI_REG_RD_INSTR_TYPE_INSTR_LSB;
@@ -352,19 +346,21 @@ static int cqspi_exec_flash_cmd(struct cqspi_st *cqspi, unsigned int reg)
 	return cqspi_wait_idle(cqspi);
 }
 
-static int cqspi_command_read(struct spi_nor *nor, u8 opcode,
-			      u8 *rxbuf, size_t n_rx)
+static int cqspi_command_read(struct cqspi_flash_pdata *f_pdata,
+			      const struct spi_mem_op *op)
 {
-	struct cqspi_flash_pdata *f_pdata = nor->priv;
 	struct cqspi_st *cqspi = f_pdata->cqspi;
 	void __iomem *reg_base = cqspi->iobase;
+	u8 *rxbuf = op->data.buf.in;
+	u8 opcode = op->cmd.opcode;
+	size_t n_rx = op->data.nbytes;
 	unsigned int rdreg;
 	unsigned int reg;
 	size_t read_len;
 	int status;
 
 	if (!n_rx || n_rx > CQSPI_STIG_DATA_LEN_MAX || !rxbuf) {
-		dev_err(nor->dev,
+		dev_err(&cqspi->pdev->dev,
 			"Invalid input argument, len %zu rxbuf 0x%p\n",
 			n_rx, rxbuf);
 		return -EINVAL;
@@ -372,7 +368,7 @@ static int cqspi_command_read(struct spi_nor *nor, u8 opcode,
 
 	reg = opcode << CQSPI_REG_CMDCTRL_OPCODE_LSB;
 
-	rdreg = cqspi_calc_rdreg(nor);
+	rdreg = cqspi_calc_rdreg(f_pdata);
 	writel(rdreg, reg_base + CQSPI_REG_RD_INSTR);
 
 	reg |= (0x1 << CQSPI_REG_CMDCTRL_RD_EN_LSB);
@@ -401,25 +397,35 @@ static int cqspi_command_read(struct spi_nor *nor, u8 opcode,
 	return 0;
 }
 
-static int cqspi_command_write(struct spi_nor *nor, const u8 opcode,
-			       const u8 *txbuf, size_t n_tx)
+static int cqspi_command_write(struct cqspi_flash_pdata *f_pdata,
+			       const struct spi_mem_op *op)
 {
-	struct cqspi_flash_pdata *f_pdata = nor->priv;
 	struct cqspi_st *cqspi = f_pdata->cqspi;
 	void __iomem *reg_base = cqspi->iobase;
+	const u8 opcode = op->cmd.opcode;
+	const u8 *txbuf = op->data.buf.out;
+	size_t n_tx = op->data.nbytes;
 	unsigned int reg;
 	unsigned int data;
 	size_t write_len;
-	int ret;
 
 	if (n_tx > CQSPI_STIG_DATA_LEN_MAX || (n_tx && !txbuf)) {
-		dev_err(nor->dev,
+		dev_err(&cqspi->pdev->dev,
 			"Invalid input argument, cmdlen %zu txbuf 0x%p\n",
 			n_tx, txbuf);
 		return -EINVAL;
 	}
 
 	reg = opcode << CQSPI_REG_CMDCTRL_OPCODE_LSB;
+
+	if (op->addr.nbytes) {
+		reg |= (0x1 << CQSPI_REG_CMDCTRL_ADDR_EN_LSB);
+		reg |= ((op->addr.nbytes - 1) & CQSPI_REG_CMDCTRL_ADD_BYTES_MASK)
+		<< CQSPI_REG_CMDCTRL_ADD_BYTES_LSB;
+
+		writel(op->addr.val, reg_base + CQSPI_REG_CMDADDRESS);
+	}
+
 	if (n_tx) {
 		reg |= (0x1 << CQSPI_REG_CMDCTRL_WR_EN_LSB);
 		reg |= ((n_tx - 1) & CQSPI_REG_CMDCTRL_WR_BYTES_MASK)
@@ -437,73 +443,46 @@ static int cqspi_command_write(struct spi_nor *nor, const u8 opcode,
 			writel(data, reg_base + CQSPI_REG_CMDWRITEDATAUPPER);
 		}
 	}
-	ret = cqspi_exec_flash_cmd(cqspi, reg);
-	return ret;
-}
-
-static int cqspi_command_write_addr(struct spi_nor *nor,
-				    const u8 opcode, const unsigned int addr)
-{
-	struct cqspi_flash_pdata *f_pdata = nor->priv;
-	struct cqspi_st *cqspi = f_pdata->cqspi;
-	void __iomem *reg_base = cqspi->iobase;
-	unsigned int reg;
-
-	reg = opcode << CQSPI_REG_CMDCTRL_OPCODE_LSB;
-	reg |= (0x1 << CQSPI_REG_CMDCTRL_ADDR_EN_LSB);
-	reg |= ((nor->addr_width - 1) & CQSPI_REG_CMDCTRL_ADD_BYTES_MASK)
-		<< CQSPI_REG_CMDCTRL_ADD_BYTES_LSB;
-
-	writel(addr, reg_base + CQSPI_REG_CMDADDRESS);
 
 	return cqspi_exec_flash_cmd(cqspi, reg);
 }
 
-static int cqspi_read_setup(struct spi_nor *nor)
+static int cqspi_read_setup(struct cqspi_flash_pdata *f_pdata,
+			    const struct spi_mem_op *op)
 {
-	struct cqspi_flash_pdata *f_pdata = nor->priv;
 	struct cqspi_st *cqspi = f_pdata->cqspi;
 	void __iomem *reg_base = cqspi->iobase;
 	unsigned int dummy_clk = 0;
 	unsigned int reg;
 
-	reg = nor->read_opcode << CQSPI_REG_RD_INSTR_OPCODE_LSB;
-	reg |= cqspi_calc_rdreg(nor);
+	reg = op->cmd.opcode << CQSPI_REG_RD_INSTR_OPCODE_LSB;
+	reg |= cqspi_calc_rdreg(f_pdata);
 
 	/* Setup dummy clock cycles */
-	dummy_clk = nor->read_dummy;
+	dummy_clk = op->dummy.nbytes * 8;
 	if (dummy_clk > CQSPI_DUMMY_CLKS_MAX)
 		dummy_clk = CQSPI_DUMMY_CLKS_MAX;
 
-	if (dummy_clk / 8) {
-		reg |= (1 << CQSPI_REG_RD_INSTR_MODE_EN_LSB);
-		/* Set mode bits high to ensure chip doesn't enter XIP */
-		writel(0xFF, reg_base + CQSPI_REG_MODE_BIT);
-
-		/* Need to subtract the mode byte (8 clocks). */
-		if (f_pdata->inst_width != CQSPI_INST_TYPE_QUAD)
-			dummy_clk -= 8;
-
-		if (dummy_clk)
-			reg |= (dummy_clk & CQSPI_REG_RD_INSTR_DUMMY_MASK)
-			       << CQSPI_REG_RD_INSTR_DUMMY_LSB;
-	}
+	if (dummy_clk / 8)
+		reg |= (dummy_clk & CQSPI_REG_RD_INSTR_DUMMY_MASK)
+		       << CQSPI_REG_RD_INSTR_DUMMY_LSB;
 
 	writel(reg, reg_base + CQSPI_REG_RD_INSTR);
 
 	/* Set address width */
 	reg = readl(reg_base + CQSPI_REG_SIZE);
 	reg &= ~CQSPI_REG_SIZE_ADDRESS_MASK;
-	reg |= (nor->addr_width - 1);
+	reg |= (op->addr.nbytes - 1);
 	writel(reg, reg_base + CQSPI_REG_SIZE);
 	return 0;
 }
 
-static int cqspi_indirect_read_execute(struct spi_nor *nor, u8 *rxbuf,
-				       loff_t from_addr, const size_t n_rx)
+static int cqspi_indirect_read_execute(struct cqspi_flash_pdata *f_pdata,
+				       u8 *rxbuf, loff_t from_addr,
+				       const size_t n_rx)
 {
-	struct cqspi_flash_pdata *f_pdata = nor->priv;
 	struct cqspi_st *cqspi = f_pdata->cqspi;
+	struct device *dev = &cqspi->pdev->dev;
 	void __iomem *reg_base = cqspi->iobase;
 	void __iomem *ahb_base = cqspi->ahb_base;
 	unsigned int remaining = n_rx;
@@ -526,13 +505,13 @@ static int cqspi_indirect_read_execute(struct spi_nor *nor, u8 *rxbuf,
 
 	while (remaining > 0) {
 		if (!wait_for_completion_timeout(&cqspi->transfer_complete,
-				msecs_to_jiffies(CQSPI_READ_TIMEOUT_MS)))
+						 msecs_to_jiffies(CQSPI_READ_TIMEOUT_MS)))
 			ret = -ETIMEDOUT;
 
 		bytes_to_read = cqspi_get_rd_sram_level(cqspi);
 
 		if (ret && bytes_to_read == 0) {
-			dev_err(nor->dev, "Indirect read timeout, no bytes\n");
+			dev_err(dev, "Indirect read timeout, no bytes\n");
 			goto failrd;
 		}
 
@@ -568,8 +547,7 @@ static int cqspi_indirect_read_execute(struct spi_nor *nor, u8 *rxbuf,
 	ret = cqspi_wait_for_bit(reg_base + CQSPI_REG_INDIRECTRD,
 				 CQSPI_REG_INDIRECTRD_DONE_MASK, 0);
 	if (ret) {
-		dev_err(nor->dev,
-			"Indirect read completion error (%i)\n", ret);
+		dev_err(dev, "Indirect read completion error (%i)\n", ret);
 		goto failrd;
 	}
 
@@ -591,32 +569,32 @@ static int cqspi_indirect_read_execute(struct spi_nor *nor, u8 *rxbuf,
 	return ret;
 }
 
-static int cqspi_write_setup(struct spi_nor *nor)
+static int cqspi_write_setup(struct cqspi_flash_pdata *f_pdata,
+			     const struct spi_mem_op *op)
 {
 	unsigned int reg;
-	struct cqspi_flash_pdata *f_pdata = nor->priv;
 	struct cqspi_st *cqspi = f_pdata->cqspi;
 	void __iomem *reg_base = cqspi->iobase;
 
 	/* Set opcode. */
-	reg = nor->program_opcode << CQSPI_REG_WR_INSTR_OPCODE_LSB;
+	reg = op->cmd.opcode << CQSPI_REG_WR_INSTR_OPCODE_LSB;
 	writel(reg, reg_base + CQSPI_REG_WR_INSTR);
-	reg = cqspi_calc_rdreg(nor);
+	reg = cqspi_calc_rdreg(f_pdata);
 	writel(reg, reg_base + CQSPI_REG_RD_INSTR);
 
 	reg = readl(reg_base + CQSPI_REG_SIZE);
 	reg &= ~CQSPI_REG_SIZE_ADDRESS_MASK;
-	reg |= (nor->addr_width - 1);
+	reg |= (op->addr.nbytes - 1);
 	writel(reg, reg_base + CQSPI_REG_SIZE);
 	return 0;
 }
 
-static int cqspi_indirect_write_execute(struct spi_nor *nor, loff_t to_addr,
-					const u8 *txbuf, const size_t n_tx)
+static int cqspi_indirect_write_execute(struct cqspi_flash_pdata *f_pdata,
+					loff_t to_addr, const u8 *txbuf,
+					const size_t n_tx)
 {
-	const unsigned int page_size = nor->page_size;
-	struct cqspi_flash_pdata *f_pdata = nor->priv;
 	struct cqspi_st *cqspi = f_pdata->cqspi;
+	struct device *dev = &cqspi->pdev->dev;
 	void __iomem *reg_base = cqspi->iobase;
 	unsigned int remaining = n_tx;
 	unsigned int write_bytes;
@@ -646,7 +624,7 @@ static int cqspi_indirect_write_execute(struct spi_nor *nor, loff_t to_addr,
 	while (remaining > 0) {
 		size_t write_words, mod_bytes;
 
-		write_bytes = remaining > page_size ? page_size : remaining;
+		write_bytes = remaining;
 		write_words = write_bytes / 4;
 		mod_bytes = write_bytes % 4;
 		/* Write 4 bytes at a time then single bytes. */
@@ -663,8 +641,8 @@ static int cqspi_indirect_write_execute(struct spi_nor *nor, loff_t to_addr,
 		}
 
 		if (!wait_for_completion_timeout(&cqspi->transfer_complete,
-					msecs_to_jiffies(CQSPI_TIMEOUT_MS))) {
-			dev_err(nor->dev, "Indirect write timeout\n");
+						 msecs_to_jiffies(CQSPI_TIMEOUT_MS))) {
+			dev_err(dev, "Indirect write timeout\n");
 			ret = -ETIMEDOUT;
 			goto failwr;
 		}
@@ -679,8 +657,7 @@ static int cqspi_indirect_write_execute(struct spi_nor *nor, loff_t to_addr,
 	ret = cqspi_wait_for_bit(reg_base + CQSPI_REG_INDIRECTWR,
 				 CQSPI_REG_INDIRECTWR_DONE_MASK, 0);
 	if (ret) {
-		dev_err(nor->dev,
-			"Indirect write completion error (%i)\n", ret);
+		dev_err(dev, "Indirect write completion error (%i)\n", ret);
 		goto failwr;
 	}
 
@@ -704,9 +681,8 @@ static int cqspi_indirect_write_execute(struct spi_nor *nor, loff_t to_addr,
 	return ret;
 }
 
-static void cqspi_chipselect(struct spi_nor *nor)
+static void cqspi_chipselect(struct cqspi_flash_pdata *f_pdata)
 {
-	struct cqspi_flash_pdata *f_pdata = nor->priv;
 	struct cqspi_st *cqspi = f_pdata->cqspi;
 	void __iomem *reg_base = cqspi->iobase;
 	unsigned int chip_select = f_pdata->cs;
@@ -745,9 +721,8 @@ static unsigned int calculate_ticks_for_ns(const unsigned int ref_clk_hz,
 	return ticks;
 }
 
-static void cqspi_delay(struct spi_nor *nor)
+static void cqspi_delay(struct cqspi_flash_pdata *f_pdata)
 {
-	struct cqspi_flash_pdata *f_pdata = nor->priv;
 	struct cqspi_st *cqspi = f_pdata->cqspi;
 	void __iomem *iobase = cqspi->iobase;
 	const unsigned int ref_clk_hz = cqspi->master_ref_clk_hz;
@@ -831,11 +806,10 @@ static void cqspi_controller_enable(struct cqspi_st *cqspi, bool enable)
 	writel(reg, reg_base + CQSPI_REG_CONFIG);
 }
 
-static void cqspi_configure(struct spi_nor *nor)
+static void cqspi_configure(struct cqspi_flash_pdata *f_pdata,
+			    unsigned long sclk)
 {
-	struct cqspi_flash_pdata *f_pdata = nor->priv;
 	struct cqspi_st *cqspi = f_pdata->cqspi;
-	const unsigned int sclk = f_pdata->clk_rate;
 	int switch_cs = (cqspi->current_cs != f_pdata->cs);
 	int switch_ck = (cqspi->sclk != sclk);
 
@@ -845,14 +819,14 @@ static void cqspi_configure(struct spi_nor *nor)
 	/* Switch chip select. */
 	if (switch_cs) {
 		cqspi->current_cs = f_pdata->cs;
-		cqspi_chipselect(nor);
+		cqspi_chipselect(f_pdata);
 	}
 
 	/* Setup baudrate divisor and delays */
 	if (switch_ck) {
 		cqspi->sclk = sclk;
 		cqspi_config_baudrate_div(cqspi);
-		cqspi_delay(nor);
+		cqspi_delay(f_pdata);
 		cqspi_readdata_capture(cqspi, !cqspi->rclk_en,
 				       f_pdata->read_delay);
 	}
@@ -861,26 +835,25 @@ static void cqspi_configure(struct spi_nor *nor)
 		cqspi_controller_enable(cqspi, 1);
 }
 
-static int cqspi_set_protocol(struct spi_nor *nor, const int read)
+static int cqspi_set_protocol(struct cqspi_flash_pdata *f_pdata,
+			      const struct spi_mem_op *op)
 {
-	struct cqspi_flash_pdata *f_pdata = nor->priv;
-
 	f_pdata->inst_width = CQSPI_INST_TYPE_SINGLE;
 	f_pdata->addr_width = CQSPI_INST_TYPE_SINGLE;
 	f_pdata->data_width = CQSPI_INST_TYPE_SINGLE;
 
-	if (read) {
-		switch (nor->read_proto) {
-		case SNOR_PROTO_1_1_1:
+	if (op->data.dir == SPI_MEM_DATA_IN) {
+		switch (op->data.buswidth) {
+		case 1:
 			f_pdata->data_width = CQSPI_INST_TYPE_SINGLE;
 			break;
-		case SNOR_PROTO_1_1_2:
+		case 2:
 			f_pdata->data_width = CQSPI_INST_TYPE_DUAL;
 			break;
-		case SNOR_PROTO_1_1_4:
+		case 4:
 			f_pdata->data_width = CQSPI_INST_TYPE_QUAD;
 			break;
-		case SNOR_PROTO_1_1_8:
+		case 8:
 			f_pdata->data_width = CQSPI_INST_TYPE_OCTAL;
 			break;
 		default:
@@ -888,36 +861,32 @@ static int cqspi_set_protocol(struct spi_nor *nor, const int read)
 		}
 	}
 
-	cqspi_configure(nor);
-
 	return 0;
 }
 
-static ssize_t cqspi_write(struct spi_nor *nor, loff_t to,
-			   size_t len, const u_char *buf)
+static ssize_t cqspi_write(struct cqspi_flash_pdata *f_pdata,
+			   const struct spi_mem_op *op)
 {
-	struct cqspi_flash_pdata *f_pdata = nor->priv;
 	struct cqspi_st *cqspi = f_pdata->cqspi;
+	loff_t to = op->addr.val;
+	size_t len = op->data.nbytes;
+	const u_char *buf = op->data.buf.out;
 	int ret;
 
-	ret = cqspi_set_protocol(nor, 0);
+	ret = cqspi_set_protocol(f_pdata, op);
 	if (ret)
 		return ret;
 
-	ret = cqspi_write_setup(nor);
+	ret = cqspi_write_setup(f_pdata, op);
 	if (ret)
 		return ret;
 
-	if (f_pdata->use_direct_mode) {
+	if (cqspi->use_dac_mode && ((to + len) <= cqspi->ahb_size)) {
 		memcpy_toio(cqspi->ahb_base + to, buf, len);
-		ret = cqspi_wait_idle(cqspi);
-	} else {
-		ret = cqspi_indirect_write_execute(nor, to, buf, len);
+		return cqspi_wait_idle(cqspi);
 	}
-	if (ret)
-		return ret;
 
-	return len;
+	return cqspi_indirect_write_execute(f_pdata, to, buf, len);
 }
 
 static void cqspi_rx_dma_callback(void *param)
@@ -927,11 +896,11 @@ static void cqspi_rx_dma_callback(void *param)
 	complete(&cqspi->rx_dma_complete);
 }
 
-static int cqspi_direct_read_execute(struct spi_nor *nor, u_char *buf,
-				     loff_t from, size_t len)
+static int cqspi_direct_read_execute(struct cqspi_flash_pdata *f_pdata,
+				     u_char *buf, loff_t from, size_t len)
 {
-	struct cqspi_flash_pdata *f_pdata = nor->priv;
 	struct cqspi_st *cqspi = f_pdata->cqspi;
+	struct device *dev = &cqspi->pdev->dev;
 	enum dma_ctrl_flags flags = DMA_CTRL_ACK | DMA_PREP_INTERRUPT;
 	dma_addr_t dma_src = (dma_addr_t)cqspi->mmap_phys_base + from;
 	int ret = 0;
@@ -944,15 +913,15 @@ static int cqspi_direct_read_execute(struct spi_nor *nor, u_char *buf,
 		return 0;
 	}
 
-	dma_dst = dma_map_single(nor->dev, buf, len, DMA_FROM_DEVICE);
-	if (dma_mapping_error(nor->dev, dma_dst)) {
-		dev_err(nor->dev, "dma mapping failed\n");
+	dma_dst = dma_map_single(dev, buf, len, DMA_FROM_DEVICE);
+	if (dma_mapping_error(dev, dma_dst)) {
+		dev_err(dev, "dma mapping failed\n");
 		return -ENOMEM;
 	}
 	tx = dmaengine_prep_dma_memcpy(cqspi->rx_chan, dma_dst, dma_src,
 				       len, flags);
 	if (!tx) {
-		dev_err(nor->dev, "device_prep_dma_memcpy error\n");
+		dev_err(dev, "device_prep_dma_memcpy error\n");
 		ret = -EIO;
 		goto err_unmap;
 	}
@@ -964,7 +933,7 @@ static int cqspi_direct_read_execute(struct spi_nor *nor, u_char *buf,
 
 	ret = dma_submit_error(cookie);
 	if (ret) {
-		dev_err(nor->dev, "dma_submit_error %d\n", cookie);
+		dev_err(dev, "dma_submit_error %d\n", cookie);
 		ret = -EIO;
 		goto err_unmap;
 	}
@@ -973,99 +942,68 @@ static int cqspi_direct_read_execute(struct spi_nor *nor, u_char *buf,
 	if (!wait_for_completion_timeout(&cqspi->rx_dma_complete,
 					 msecs_to_jiffies(len))) {
 		dmaengine_terminate_sync(cqspi->rx_chan);
-		dev_err(nor->dev, "DMA wait_for_completion_timeout\n");
+		dev_err(dev, "DMA wait_for_completion_timeout\n");
 		ret = -ETIMEDOUT;
 		goto err_unmap;
 	}
 
 err_unmap:
-	dma_unmap_single(nor->dev, dma_dst, len, DMA_FROM_DEVICE);
+	dma_unmap_single(dev, dma_dst, len, DMA_FROM_DEVICE);
 
 	return ret;
 }
 
-static ssize_t cqspi_read(struct spi_nor *nor, loff_t from,
-			  size_t len, u_char *buf)
-{
-	struct cqspi_flash_pdata *f_pdata = nor->priv;
-	int ret;
-
-	ret = cqspi_set_protocol(nor, 1);
-	if (ret)
-		return ret;
-
-	ret = cqspi_read_setup(nor);
-	if (ret)
-		return ret;
-
-	if (f_pdata->use_direct_mode)
-		ret = cqspi_direct_read_execute(nor, buf, from, len);
-	else
-		ret = cqspi_indirect_read_execute(nor, buf, from, len);
-	if (ret)
-		return ret;
-
-	return len;
-}
-
-static int cqspi_erase(struct spi_nor *nor, loff_t offs)
+static ssize_t cqspi_read(struct cqspi_flash_pdata *f_pdata,
+			  const struct spi_mem_op *op)
 {
+	struct cqspi_st *cqspi = f_pdata->cqspi;
+	loff_t from = op->addr.val;
+	size_t len = op->data.nbytes;
+	u_char *buf = op->data.buf.in;
 	int ret;
 
-	ret = cqspi_set_protocol(nor, 0);
+	ret = cqspi_set_protocol(f_pdata, op);
 	if (ret)
 		return ret;
 
-	/* Send write enable, then erase commands. */
-	ret = nor->controller_ops->write_reg(nor, SPINOR_OP_WREN, NULL, 0);
+	ret = cqspi_read_setup(f_pdata, op);
 	if (ret)
 		return ret;
 
-	/* Set up command buffer. */
-	ret = cqspi_command_write_addr(nor, nor->erase_opcode, offs);
-	if (ret)
-		return ret;
+	if (cqspi->use_dac_mode && ((from + len) <= cqspi->ahb_size))
+		return cqspi_direct_read_execute(f_pdata, buf, from, len);
 
-	return 0;
+	return cqspi_indirect_read_execute(f_pdata, buf, from, len);
 }
 
-static int cqspi_prep(struct spi_nor *nor)
+static int cqspi_mem_process(struct spi_mem *mem, const struct spi_mem_op *op)
 {
-	struct cqspi_flash_pdata *f_pdata = nor->priv;
-	struct cqspi_st *cqspi = f_pdata->cqspi;
-
-	mutex_lock(&cqspi->bus_mutex);
-
-	return 0;
-}
+	struct cqspi_st *cqspi = spi_master_get_devdata(mem->spi->master);
+	struct cqspi_flash_pdata *f_pdata;
 
-static void cqspi_unprep(struct spi_nor *nor)
-{
-	struct cqspi_flash_pdata *f_pdata = nor->priv;
-	struct cqspi_st *cqspi = f_pdata->cqspi;
+	f_pdata = &cqspi->f_pdata[mem->spi->chip_select];
+	cqspi_configure(f_pdata, mem->spi->max_speed_hz);
 
-	mutex_unlock(&cqspi->bus_mutex);
-}
+	if (op->data.dir == SPI_MEM_DATA_IN && op->data.buf.in) {
+		if (!op->addr.nbytes)
+			return cqspi_command_read(f_pdata, op);
 
-static int cqspi_read_reg(struct spi_nor *nor, u8 opcode, u8 *buf, size_t len)
-{
-	int ret;
+		return cqspi_read(f_pdata, op);
+	}
 
-	ret = cqspi_set_protocol(nor, 0);
-	if (!ret)
-		ret = cqspi_command_read(nor, opcode, buf, len);
+	if (!op->addr.nbytes || !op->data.buf.out)
+		return cqspi_command_write(f_pdata, op);
 
-	return ret;
+	return cqspi_write(f_pdata, op);
 }
 
-static int cqspi_write_reg(struct spi_nor *nor, u8 opcode, const u8 *buf,
-			   size_t len)
+static int cqspi_exec_mem_op(struct spi_mem *mem, const struct spi_mem_op *op)
 {
 	int ret;
 
-	ret = cqspi_set_protocol(nor, 0);
-	if (!ret)
-		ret = cqspi_command_write(nor, opcode, buf, len);
+	ret = cqspi_mem_process(mem, op);
+	if (ret)
+		dev_err(&mem->spi->dev, "operation failed with %d\n", ret);
 
 	return ret;
 }
@@ -1107,26 +1045,26 @@ static int cqspi_of_get_flash_pdata(struct platform_device *pdev,
 	return 0;
 }
 
-static int cqspi_of_get_pdata(struct platform_device *pdev)
+static int cqspi_of_get_pdata(struct cqspi_st *cqspi)
 {
-	struct device_node *np = pdev->dev.of_node;
-	struct cqspi_st *cqspi = platform_get_drvdata(pdev);
+	struct device *dev = &cqspi->pdev->dev;
+	struct device_node *np = dev->of_node;
 
 	cqspi->is_decoded_cs = of_property_read_bool(np, "cdns,is-decoded-cs");
 
 	if (of_property_read_u32(np, "cdns,fifo-depth", &cqspi->fifo_depth)) {
-		dev_err(&pdev->dev, "couldn't determine fifo-depth\n");
+		dev_err(dev, "couldn't determine fifo-depth\n");
 		return -ENXIO;
 	}
 
 	if (of_property_read_u32(np, "cdns,fifo-width", &cqspi->fifo_width)) {
-		dev_err(&pdev->dev, "couldn't determine fifo-width\n");
+		dev_err(dev, "couldn't determine fifo-width\n");
 		return -ENXIO;
 	}
 
 	if (of_property_read_u32(np, "cdns,trigger-address",
 				 &cqspi->trigger_address)) {
-		dev_err(&pdev->dev, "couldn't determine trigger-address\n");
+		dev_err(dev, "couldn't determine trigger-address\n");
 		return -ENXIO;
 	}
 
@@ -1169,7 +1107,7 @@ static void cqspi_controller_init(struct cqspi_st *cqspi)
 	cqspi_controller_enable(cqspi, 1);
 }
 
-static void cqspi_request_mmap_dma(struct cqspi_st *cqspi)
+static int cqspi_request_mmap_dma(struct cqspi_st *cqspi)
 {
 	dma_cap_mask_t mask;
 
@@ -1178,133 +1116,79 @@ static void cqspi_request_mmap_dma(struct cqspi_st *cqspi)
 
 	cqspi->rx_chan = dma_request_chan_by_mask(&mask);
 	if (IS_ERR(cqspi->rx_chan)) {
-		dev_err(&cqspi->pdev->dev, "No Rx DMA available\n");
+		int ret = PTR_ERR(cqspi->rx_chan);
+
+		if (ret != -EPROBE_DEFER)
+			dev_err(&cqspi->pdev->dev, "No Rx DMA available\n");
 		cqspi->rx_chan = NULL;
-		return;
+		return ret;
 	}
 	init_completion(&cqspi->rx_dma_complete);
+
+	return 0;
 }
 
-static const struct spi_nor_controller_ops cqspi_controller_ops = {
-	.prepare = cqspi_prep,
-	.unprepare = cqspi_unprep,
-	.read_reg = cqspi_read_reg,
-	.write_reg = cqspi_write_reg,
-	.read = cqspi_read,
-	.write = cqspi_write,
-	.erase = cqspi_erase,
+static const struct spi_controller_mem_ops cqspi_mem_ops = {
+	.exec_op = cqspi_exec_mem_op,
 };
 
-static int cqspi_setup_flash(struct cqspi_st *cqspi, struct device_node *np)
+static int cqspi_setup_flash(struct cqspi_st *cqspi)
 {
 	struct platform_device *pdev = cqspi->pdev;
 	struct device *dev = &pdev->dev;
-	const struct cqspi_driver_platdata *ddata;
-	struct spi_nor_hwcaps hwcaps;
+	struct device_node *np = dev->of_node;
 	struct cqspi_flash_pdata *f_pdata;
-	struct spi_nor *nor;
-	struct mtd_info *mtd;
 	unsigned int cs;
-	int i, ret;
-
-	ddata = of_device_get_match_data(dev);
-	if (!ddata) {
-		dev_err(dev, "Couldn't find driver data\n");
-		return -EINVAL;
-	}
-	hwcaps.mask = ddata->hwcaps_mask;
 
 	/* Get flash device data */
 	for_each_available_child_of_node(dev->of_node, np) {
-		ret = of_property_read_u32(np, "reg", &cs);
-		if (ret) {
+		if (of_property_read_u32(np, "reg", &cs)) {
 			dev_err(dev, "Couldn't determine chip select.\n");
-			goto err;
+			continue;
 		}
 
 		if (cs >= CQSPI_MAX_CHIPSELECT) {
-			ret = -EINVAL;
 			dev_err(dev, "Chip select %d out of range.\n", cs);
-			goto err;
+			continue;
 		}
 
 		f_pdata = &cqspi->f_pdata[cs];
 		f_pdata->cqspi = cqspi;
 		f_pdata->cs = cs;
 
-		ret = cqspi_of_get_flash_pdata(pdev, f_pdata, np);
-		if (ret)
-			goto err;
-
-		nor = &f_pdata->nor;
-		mtd = &nor->mtd;
-
-		mtd->priv = nor;
-
-		nor->dev = dev;
-		spi_nor_set_flash_node(nor, np);
-		nor->priv = f_pdata;
-		nor->controller_ops = &cqspi_controller_ops;
-
-		mtd->name = devm_kasprintf(dev, GFP_KERNEL, "%s.%d",
-					   dev_name(dev), cs);
-		if (!mtd->name) {
-			ret = -ENOMEM;
-			goto err;
-		}
-
-		ret = spi_nor_scan(nor, NULL, &hwcaps);
-		if (ret)
-			goto err;
-
-		ret = mtd_device_register(mtd, NULL, 0);
-		if (ret)
-			goto err;
-
-		f_pdata->registered = true;
-
-		if (mtd->size <= cqspi->ahb_size &&
-		    !(ddata->quirks & CQSPI_DISABLE_DAC_MODE)) {
-			f_pdata->use_direct_mode = true;
-			dev_dbg(nor->dev, "using direct mode for %s\n",
-				mtd->name);
-
-			if (!cqspi->rx_chan)
-				cqspi_request_mmap_dma(cqspi);
-		}
+		return cqspi_of_get_flash_pdata(pdev, f_pdata, np);
 	}
 
 	return 0;
-
-err:
-	for (i = 0; i < CQSPI_MAX_CHIPSELECT; i++)
-		if (cqspi->f_pdata[i].registered)
-			mtd_device_unregister(&cqspi->f_pdata[i].nor.mtd);
-	return ret;
 }
 
 static int cqspi_probe(struct platform_device *pdev)
 {
-	struct device_node *np = pdev->dev.of_node;
+	const struct cqspi_driver_platdata *ddata;
+	struct reset_control *rstc, *rstc_ocp;
 	struct device *dev = &pdev->dev;
+	struct spi_master *master;
+	struct resource *res_ahb;
 	struct cqspi_st *cqspi;
 	struct resource *res;
-	struct resource *res_ahb;
-	struct reset_control *rstc, *rstc_ocp;
-	const struct cqspi_driver_platdata *ddata;
 	int ret;
 	int irq;
 
-	cqspi = devm_kzalloc(dev, sizeof(*cqspi), GFP_KERNEL);
-	if (!cqspi)
+	master = spi_alloc_master(&pdev->dev, sizeof(*cqspi));
+	if (!master) {
+		dev_err(&pdev->dev, "spi_alloc_master failed\n");
 		return -ENOMEM;
+	}
+	master->mode_bits = SPI_RX_QUAD | SPI_RX_DUAL;
+	master->mem_ops = &cqspi_mem_ops;
+	master->dev.of_node = pdev->dev.of_node;
+
+	cqspi = spi_master_get_devdata(master);
 
-	mutex_init(&cqspi->bus_mutex);
 	cqspi->pdev = pdev;
-	platform_set_drvdata(pdev, cqspi);
 
 	/* Obtain configuration from OF. */
-	ret = cqspi_of_get_pdata(pdev);
+	ret = cqspi_of_get_pdata(cqspi);
 	if (ret) {
 		dev_err(dev, "Cannot get mandatory OF data.\n");
 		return -ENODEV;
@@ -1376,9 +1260,15 @@ static int cqspi_probe(struct platform_device *pdev)
 
 	cqspi->master_ref_clk_hz = clk_get_rate(cqspi->clk);
 	ddata  = of_device_get_match_data(dev);
-	if (ddata && (ddata->quirks & CQSPI_NEEDS_WR_DELAY))
-		cqspi->wr_delay = 5 * DIV_ROUND_UP(NSEC_PER_SEC,
-						   cqspi->master_ref_clk_hz);
+	if (ddata) {
+		if (ddata->quirks & CQSPI_NEEDS_WR_DELAY)
+			cqspi->wr_delay = 5 * DIV_ROUND_UP(NSEC_PER_SEC,
+						cqspi->master_ref_clk_hz);
+		if (ddata->hwcaps_mask & CQSPI_SUPPORTS_OCTAL)
+			master->mode_bits |= SPI_RX_OCTAL;
+		if (!(ddata->quirks & CQSPI_DISABLE_DAC_MODE))
+			cqspi->use_dac_mode = true;
+	}
 
 	ret = devm_request_irq(dev, irq, cqspi_irq_handler, 0,
 			       pdev->name, cqspi);
@@ -1392,13 +1282,25 @@ static int cqspi_probe(struct platform_device *pdev)
 	cqspi->current_cs = -1;
 	cqspi->sclk = 0;
 
-	ret = cqspi_setup_flash(cqspi, np);
+	ret = cqspi_setup_flash(cqspi);
 	if (ret) {
-		dev_err(dev, "Cadence QSPI NOR probe failed %d\n", ret);
+		dev_err(dev, "failed to setup flash parameters %d\n", ret);
 		goto probe_setup_failed;
 	}
 
-	return ret;
+	if (cqspi->use_dac_mode) {
+		ret = cqspi_request_mmap_dma(cqspi);
+		if (ret == -EPROBE_DEFER)
+			goto probe_setup_failed;
+	}
+
+	ret = devm_spi_register_master(dev, master);
+	if (ret) {
+		dev_err(&pdev->dev, "failed to register SPI ctlr %d\n", ret);
+		goto probe_setup_failed;
+	}
+
+	return 0;
 probe_setup_failed:
 	cqspi_controller_enable(cqspi, 0);
 probe_reset_failed:
@@ -1412,11 +1314,6 @@ static int cqspi_probe(struct platform_device *pdev)
 static int cqspi_remove(struct platform_device *pdev)
 {
 	struct cqspi_st *cqspi = platform_get_drvdata(pdev);
-	int i;
-
-	for (i = 0; i < CQSPI_MAX_CHIPSELECT; i++)
-		if (cqspi->f_pdata[i].registered)
-			mtd_device_unregister(&cqspi->f_pdata[i].nor.mtd);
 
 	cqspi_controller_enable(cqspi, 0);
 
@@ -1459,17 +1356,15 @@ static const struct dev_pm_ops cqspi__dev_pm_ops = {
 #endif
 
 static const struct cqspi_driver_platdata cdns_qspi = {
-	.hwcaps_mask = CQSPI_BASE_HWCAPS_MASK,
 	.quirks = CQSPI_DISABLE_DAC_MODE,
 };
 
 static const struct cqspi_driver_platdata k2g_qspi = {
-	.hwcaps_mask = CQSPI_BASE_HWCAPS_MASK,
 	.quirks = CQSPI_NEEDS_WR_DELAY,
 };
 
 static const struct cqspi_driver_platdata am654_ospi = {
-	.hwcaps_mask = CQSPI_BASE_HWCAPS_MASK | SNOR_HWCAPS_READ_1_1_8,
+	.hwcaps_mask = CQSPI_SUPPORTS_OCTAL,
 	.quirks = CQSPI_NEEDS_WR_DELAY,
 };
 
@@ -1508,3 +1403,5 @@ MODULE_LICENSE("GPL v2");
 MODULE_ALIAS("platform:" CQSPI_NAME);
 MODULE_AUTHOR("Ley Foon Tan <lftan@altera.com>");
 MODULE_AUTHOR("Graham Moore <grmoore@opensource.altera.com>");
+MODULE_AUTHOR("Vadivel Murugan R <vadivel.muruganx.ramuthevar@intel.com>");
+MODULE_AUTHOR("Vignesh Raghavendra <vigneshr@ti.com>");
-- 
2.26.2


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

* [PATCH v2 5/6] mtd: spi-nor: Convert cadence-quadspi to use spi-mem framework
@ 2020-05-26  9:36   ` Vignesh Raghavendra
  0 siblings, 0 replies; 36+ messages in thread
From: Vignesh Raghavendra @ 2020-05-26  9:36 UTC (permalink / raw)
  To: Tudor Ambarus, Mark Brown
  Cc: marex, Vignesh Raghavendra, Boris Brezillon, dinguyen,
	simon.k.r.goldschmidt, linux-kernel, linux-spi,
	Ramuthevar Vadivel Murugan, linux-mtd

From: Ramuthevar Vadivel Murugan <vadivel.muruganx.ramuthevar@linux.intel.com>

Move cadence-quadspi driver to use spi-mem framework. This is required
to make the driver support for SPI NAND flashes in future.

Driver is feature compliant with existing SPI NOR version.

Signed-off-by: Ramuthevar Vadivel Murugan <vadivel.muruganx.ramuthevar@linux.intel.com>
Signed-off-by: Vignesh Raghavendra <vigneshr@ti.com>
---
 .../mtd/spi-nor/controllers/cadence-quadspi.c | 469 +++++++-----------
 1 file changed, 183 insertions(+), 286 deletions(-)

diff --git a/drivers/mtd/spi-nor/controllers/cadence-quadspi.c b/drivers/mtd/spi-nor/controllers/cadence-quadspi.c
index 608ca657ff7f..c1df4b221889 100644
--- a/drivers/mtd/spi-nor/controllers/cadence-quadspi.c
+++ b/drivers/mtd/spi-nor/controllers/cadence-quadspi.c
@@ -3,6 +3,8 @@
  * Driver for Cadence QSPI Controller
  *
  * Copyright Altera Corporation (C) 2012-2014. All rights reserved.
+ * Copyright Intel Corporation (C) 2019-2020. All rights reserved.
+ * Copyright (C) 2020 Texas Instruments Incorporated - http://www.ti.com
  */
 #include <linux/clk.h>
 #include <linux/completion.h>
@@ -17,9 +19,6 @@
 #include <linux/jiffies.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
-#include <linux/mtd/mtd.h>
-#include <linux/mtd/partitions.h>
-#include <linux/mtd/spi-nor.h>
 #include <linux/of_device.h>
 #include <linux/of.h>
 #include <linux/platform_device.h>
@@ -27,6 +26,7 @@
 #include <linux/reset.h>
 #include <linux/sched.h>
 #include <linux/spi/spi.h>
+#include <linux/spi/spi-mem.h>
 #include <linux/timer.h>
 
 #define CQSPI_NAME			"cadence-qspi"
@@ -36,16 +36,12 @@
 #define CQSPI_NEEDS_WR_DELAY		BIT(0)
 #define CQSPI_DISABLE_DAC_MODE		BIT(1)
 
-/* Capabilities mask */
-#define CQSPI_BASE_HWCAPS_MASK					\
-	(SNOR_HWCAPS_READ | SNOR_HWCAPS_READ_FAST |		\
-	SNOR_HWCAPS_READ_1_1_2 | SNOR_HWCAPS_READ_1_1_4 |	\
-	SNOR_HWCAPS_PP)
+/* Capabilities */
+#define CQSPI_SUPPORTS_OCTAL		BIT(0)
 
 struct cqspi_st;
 
 struct cqspi_flash_pdata {
-	struct spi_nor	nor;
 	struct cqspi_st	*cqspi;
 	u32		clk_rate;
 	u32		read_delay;
@@ -58,7 +54,6 @@ struct cqspi_flash_pdata {
 	u8		data_width;
 	u8		cs;
 	bool		registered;
-	bool		use_direct_mode;
 };
 
 struct cqspi_st {
@@ -71,7 +66,6 @@ struct cqspi_st {
 	void __iomem		*ahb_base;
 	resource_size_t		ahb_size;
 	struct completion	transfer_complete;
-	struct mutex		bus_mutex;
 
 	struct dma_chan		*rx_chan;
 	struct completion	rx_dma_complete;
@@ -85,6 +79,7 @@ struct cqspi_st {
 	bool			rclk_en;
 	u32			trigger_address;
 	u32			wr_delay;
+	bool			use_dac_mode;
 	struct cqspi_flash_pdata f_pdata[CQSPI_MAX_CHIPSELECT];
 };
 
@@ -283,9 +278,8 @@ static irqreturn_t cqspi_irq_handler(int this_irq, void *dev)
 	return IRQ_HANDLED;
 }
 
-static unsigned int cqspi_calc_rdreg(struct spi_nor *nor)
+static unsigned int cqspi_calc_rdreg(struct cqspi_flash_pdata *f_pdata)
 {
-	struct cqspi_flash_pdata *f_pdata = nor->priv;
 	u32 rdreg = 0;
 
 	rdreg |= f_pdata->inst_width << CQSPI_REG_RD_INSTR_TYPE_INSTR_LSB;
@@ -352,19 +346,21 @@ static int cqspi_exec_flash_cmd(struct cqspi_st *cqspi, unsigned int reg)
 	return cqspi_wait_idle(cqspi);
 }
 
-static int cqspi_command_read(struct spi_nor *nor, u8 opcode,
-			      u8 *rxbuf, size_t n_rx)
+static int cqspi_command_read(struct cqspi_flash_pdata *f_pdata,
+			      const struct spi_mem_op *op)
 {
-	struct cqspi_flash_pdata *f_pdata = nor->priv;
 	struct cqspi_st *cqspi = f_pdata->cqspi;
 	void __iomem *reg_base = cqspi->iobase;
+	u8 *rxbuf = op->data.buf.in;
+	u8 opcode = op->cmd.opcode;
+	size_t n_rx = op->data.nbytes;
 	unsigned int rdreg;
 	unsigned int reg;
 	size_t read_len;
 	int status;
 
 	if (!n_rx || n_rx > CQSPI_STIG_DATA_LEN_MAX || !rxbuf) {
-		dev_err(nor->dev,
+		dev_err(&cqspi->pdev->dev,
 			"Invalid input argument, len %zu rxbuf 0x%p\n",
 			n_rx, rxbuf);
 		return -EINVAL;
@@ -372,7 +368,7 @@ static int cqspi_command_read(struct spi_nor *nor, u8 opcode,
 
 	reg = opcode << CQSPI_REG_CMDCTRL_OPCODE_LSB;
 
-	rdreg = cqspi_calc_rdreg(nor);
+	rdreg = cqspi_calc_rdreg(f_pdata);
 	writel(rdreg, reg_base + CQSPI_REG_RD_INSTR);
 
 	reg |= (0x1 << CQSPI_REG_CMDCTRL_RD_EN_LSB);
@@ -401,25 +397,35 @@ static int cqspi_command_read(struct spi_nor *nor, u8 opcode,
 	return 0;
 }
 
-static int cqspi_command_write(struct spi_nor *nor, const u8 opcode,
-			       const u8 *txbuf, size_t n_tx)
+static int cqspi_command_write(struct cqspi_flash_pdata *f_pdata,
+			       const struct spi_mem_op *op)
 {
-	struct cqspi_flash_pdata *f_pdata = nor->priv;
 	struct cqspi_st *cqspi = f_pdata->cqspi;
 	void __iomem *reg_base = cqspi->iobase;
+	const u8 opcode = op->cmd.opcode;
+	const u8 *txbuf = op->data.buf.out;
+	size_t n_tx = op->data.nbytes;
 	unsigned int reg;
 	unsigned int data;
 	size_t write_len;
-	int ret;
 
 	if (n_tx > CQSPI_STIG_DATA_LEN_MAX || (n_tx && !txbuf)) {
-		dev_err(nor->dev,
+		dev_err(&cqspi->pdev->dev,
 			"Invalid input argument, cmdlen %zu txbuf 0x%p\n",
 			n_tx, txbuf);
 		return -EINVAL;
 	}
 
 	reg = opcode << CQSPI_REG_CMDCTRL_OPCODE_LSB;
+
+	if (op->addr.nbytes) {
+		reg |= (0x1 << CQSPI_REG_CMDCTRL_ADDR_EN_LSB);
+		reg |= ((op->addr.nbytes - 1) & CQSPI_REG_CMDCTRL_ADD_BYTES_MASK)
+		<< CQSPI_REG_CMDCTRL_ADD_BYTES_LSB;
+
+		writel(op->addr.val, reg_base + CQSPI_REG_CMDADDRESS);
+	}
+
 	if (n_tx) {
 		reg |= (0x1 << CQSPI_REG_CMDCTRL_WR_EN_LSB);
 		reg |= ((n_tx - 1) & CQSPI_REG_CMDCTRL_WR_BYTES_MASK)
@@ -437,73 +443,46 @@ static int cqspi_command_write(struct spi_nor *nor, const u8 opcode,
 			writel(data, reg_base + CQSPI_REG_CMDWRITEDATAUPPER);
 		}
 	}
-	ret = cqspi_exec_flash_cmd(cqspi, reg);
-	return ret;
-}
-
-static int cqspi_command_write_addr(struct spi_nor *nor,
-				    const u8 opcode, const unsigned int addr)
-{
-	struct cqspi_flash_pdata *f_pdata = nor->priv;
-	struct cqspi_st *cqspi = f_pdata->cqspi;
-	void __iomem *reg_base = cqspi->iobase;
-	unsigned int reg;
-
-	reg = opcode << CQSPI_REG_CMDCTRL_OPCODE_LSB;
-	reg |= (0x1 << CQSPI_REG_CMDCTRL_ADDR_EN_LSB);
-	reg |= ((nor->addr_width - 1) & CQSPI_REG_CMDCTRL_ADD_BYTES_MASK)
-		<< CQSPI_REG_CMDCTRL_ADD_BYTES_LSB;
-
-	writel(addr, reg_base + CQSPI_REG_CMDADDRESS);
 
 	return cqspi_exec_flash_cmd(cqspi, reg);
 }
 
-static int cqspi_read_setup(struct spi_nor *nor)
+static int cqspi_read_setup(struct cqspi_flash_pdata *f_pdata,
+			    const struct spi_mem_op *op)
 {
-	struct cqspi_flash_pdata *f_pdata = nor->priv;
 	struct cqspi_st *cqspi = f_pdata->cqspi;
 	void __iomem *reg_base = cqspi->iobase;
 	unsigned int dummy_clk = 0;
 	unsigned int reg;
 
-	reg = nor->read_opcode << CQSPI_REG_RD_INSTR_OPCODE_LSB;
-	reg |= cqspi_calc_rdreg(nor);
+	reg = op->cmd.opcode << CQSPI_REG_RD_INSTR_OPCODE_LSB;
+	reg |= cqspi_calc_rdreg(f_pdata);
 
 	/* Setup dummy clock cycles */
-	dummy_clk = nor->read_dummy;
+	dummy_clk = op->dummy.nbytes * 8;
 	if (dummy_clk > CQSPI_DUMMY_CLKS_MAX)
 		dummy_clk = CQSPI_DUMMY_CLKS_MAX;
 
-	if (dummy_clk / 8) {
-		reg |= (1 << CQSPI_REG_RD_INSTR_MODE_EN_LSB);
-		/* Set mode bits high to ensure chip doesn't enter XIP */
-		writel(0xFF, reg_base + CQSPI_REG_MODE_BIT);
-
-		/* Need to subtract the mode byte (8 clocks). */
-		if (f_pdata->inst_width != CQSPI_INST_TYPE_QUAD)
-			dummy_clk -= 8;
-
-		if (dummy_clk)
-			reg |= (dummy_clk & CQSPI_REG_RD_INSTR_DUMMY_MASK)
-			       << CQSPI_REG_RD_INSTR_DUMMY_LSB;
-	}
+	if (dummy_clk / 8)
+		reg |= (dummy_clk & CQSPI_REG_RD_INSTR_DUMMY_MASK)
+		       << CQSPI_REG_RD_INSTR_DUMMY_LSB;
 
 	writel(reg, reg_base + CQSPI_REG_RD_INSTR);
 
 	/* Set address width */
 	reg = readl(reg_base + CQSPI_REG_SIZE);
 	reg &= ~CQSPI_REG_SIZE_ADDRESS_MASK;
-	reg |= (nor->addr_width - 1);
+	reg |= (op->addr.nbytes - 1);
 	writel(reg, reg_base + CQSPI_REG_SIZE);
 	return 0;
 }
 
-static int cqspi_indirect_read_execute(struct spi_nor *nor, u8 *rxbuf,
-				       loff_t from_addr, const size_t n_rx)
+static int cqspi_indirect_read_execute(struct cqspi_flash_pdata *f_pdata,
+				       u8 *rxbuf, loff_t from_addr,
+				       const size_t n_rx)
 {
-	struct cqspi_flash_pdata *f_pdata = nor->priv;
 	struct cqspi_st *cqspi = f_pdata->cqspi;
+	struct device *dev = &cqspi->pdev->dev;
 	void __iomem *reg_base = cqspi->iobase;
 	void __iomem *ahb_base = cqspi->ahb_base;
 	unsigned int remaining = n_rx;
@@ -526,13 +505,13 @@ static int cqspi_indirect_read_execute(struct spi_nor *nor, u8 *rxbuf,
 
 	while (remaining > 0) {
 		if (!wait_for_completion_timeout(&cqspi->transfer_complete,
-				msecs_to_jiffies(CQSPI_READ_TIMEOUT_MS)))
+						 msecs_to_jiffies(CQSPI_READ_TIMEOUT_MS)))
 			ret = -ETIMEDOUT;
 
 		bytes_to_read = cqspi_get_rd_sram_level(cqspi);
 
 		if (ret && bytes_to_read == 0) {
-			dev_err(nor->dev, "Indirect read timeout, no bytes\n");
+			dev_err(dev, "Indirect read timeout, no bytes\n");
 			goto failrd;
 		}
 
@@ -568,8 +547,7 @@ static int cqspi_indirect_read_execute(struct spi_nor *nor, u8 *rxbuf,
 	ret = cqspi_wait_for_bit(reg_base + CQSPI_REG_INDIRECTRD,
 				 CQSPI_REG_INDIRECTRD_DONE_MASK, 0);
 	if (ret) {
-		dev_err(nor->dev,
-			"Indirect read completion error (%i)\n", ret);
+		dev_err(dev, "Indirect read completion error (%i)\n", ret);
 		goto failrd;
 	}
 
@@ -591,32 +569,32 @@ static int cqspi_indirect_read_execute(struct spi_nor *nor, u8 *rxbuf,
 	return ret;
 }
 
-static int cqspi_write_setup(struct spi_nor *nor)
+static int cqspi_write_setup(struct cqspi_flash_pdata *f_pdata,
+			     const struct spi_mem_op *op)
 {
 	unsigned int reg;
-	struct cqspi_flash_pdata *f_pdata = nor->priv;
 	struct cqspi_st *cqspi = f_pdata->cqspi;
 	void __iomem *reg_base = cqspi->iobase;
 
 	/* Set opcode. */
-	reg = nor->program_opcode << CQSPI_REG_WR_INSTR_OPCODE_LSB;
+	reg = op->cmd.opcode << CQSPI_REG_WR_INSTR_OPCODE_LSB;
 	writel(reg, reg_base + CQSPI_REG_WR_INSTR);
-	reg = cqspi_calc_rdreg(nor);
+	reg = cqspi_calc_rdreg(f_pdata);
 	writel(reg, reg_base + CQSPI_REG_RD_INSTR);
 
 	reg = readl(reg_base + CQSPI_REG_SIZE);
 	reg &= ~CQSPI_REG_SIZE_ADDRESS_MASK;
-	reg |= (nor->addr_width - 1);
+	reg |= (op->addr.nbytes - 1);
 	writel(reg, reg_base + CQSPI_REG_SIZE);
 	return 0;
 }
 
-static int cqspi_indirect_write_execute(struct spi_nor *nor, loff_t to_addr,
-					const u8 *txbuf, const size_t n_tx)
+static int cqspi_indirect_write_execute(struct cqspi_flash_pdata *f_pdata,
+					loff_t to_addr, const u8 *txbuf,
+					const size_t n_tx)
 {
-	const unsigned int page_size = nor->page_size;
-	struct cqspi_flash_pdata *f_pdata = nor->priv;
 	struct cqspi_st *cqspi = f_pdata->cqspi;
+	struct device *dev = &cqspi->pdev->dev;
 	void __iomem *reg_base = cqspi->iobase;
 	unsigned int remaining = n_tx;
 	unsigned int write_bytes;
@@ -646,7 +624,7 @@ static int cqspi_indirect_write_execute(struct spi_nor *nor, loff_t to_addr,
 	while (remaining > 0) {
 		size_t write_words, mod_bytes;
 
-		write_bytes = remaining > page_size ? page_size : remaining;
+		write_bytes = remaining;
 		write_words = write_bytes / 4;
 		mod_bytes = write_bytes % 4;
 		/* Write 4 bytes at a time then single bytes. */
@@ -663,8 +641,8 @@ static int cqspi_indirect_write_execute(struct spi_nor *nor, loff_t to_addr,
 		}
 
 		if (!wait_for_completion_timeout(&cqspi->transfer_complete,
-					msecs_to_jiffies(CQSPI_TIMEOUT_MS))) {
-			dev_err(nor->dev, "Indirect write timeout\n");
+						 msecs_to_jiffies(CQSPI_TIMEOUT_MS))) {
+			dev_err(dev, "Indirect write timeout\n");
 			ret = -ETIMEDOUT;
 			goto failwr;
 		}
@@ -679,8 +657,7 @@ static int cqspi_indirect_write_execute(struct spi_nor *nor, loff_t to_addr,
 	ret = cqspi_wait_for_bit(reg_base + CQSPI_REG_INDIRECTWR,
 				 CQSPI_REG_INDIRECTWR_DONE_MASK, 0);
 	if (ret) {
-		dev_err(nor->dev,
-			"Indirect write completion error (%i)\n", ret);
+		dev_err(dev, "Indirect write completion error (%i)\n", ret);
 		goto failwr;
 	}
 
@@ -704,9 +681,8 @@ static int cqspi_indirect_write_execute(struct spi_nor *nor, loff_t to_addr,
 	return ret;
 }
 
-static void cqspi_chipselect(struct spi_nor *nor)
+static void cqspi_chipselect(struct cqspi_flash_pdata *f_pdata)
 {
-	struct cqspi_flash_pdata *f_pdata = nor->priv;
 	struct cqspi_st *cqspi = f_pdata->cqspi;
 	void __iomem *reg_base = cqspi->iobase;
 	unsigned int chip_select = f_pdata->cs;
@@ -745,9 +721,8 @@ static unsigned int calculate_ticks_for_ns(const unsigned int ref_clk_hz,
 	return ticks;
 }
 
-static void cqspi_delay(struct spi_nor *nor)
+static void cqspi_delay(struct cqspi_flash_pdata *f_pdata)
 {
-	struct cqspi_flash_pdata *f_pdata = nor->priv;
 	struct cqspi_st *cqspi = f_pdata->cqspi;
 	void __iomem *iobase = cqspi->iobase;
 	const unsigned int ref_clk_hz = cqspi->master_ref_clk_hz;
@@ -831,11 +806,10 @@ static void cqspi_controller_enable(struct cqspi_st *cqspi, bool enable)
 	writel(reg, reg_base + CQSPI_REG_CONFIG);
 }
 
-static void cqspi_configure(struct spi_nor *nor)
+static void cqspi_configure(struct cqspi_flash_pdata *f_pdata,
+			    unsigned long sclk)
 {
-	struct cqspi_flash_pdata *f_pdata = nor->priv;
 	struct cqspi_st *cqspi = f_pdata->cqspi;
-	const unsigned int sclk = f_pdata->clk_rate;
 	int switch_cs = (cqspi->current_cs != f_pdata->cs);
 	int switch_ck = (cqspi->sclk != sclk);
 
@@ -845,14 +819,14 @@ static void cqspi_configure(struct spi_nor *nor)
 	/* Switch chip select. */
 	if (switch_cs) {
 		cqspi->current_cs = f_pdata->cs;
-		cqspi_chipselect(nor);
+		cqspi_chipselect(f_pdata);
 	}
 
 	/* Setup baudrate divisor and delays */
 	if (switch_ck) {
 		cqspi->sclk = sclk;
 		cqspi_config_baudrate_div(cqspi);
-		cqspi_delay(nor);
+		cqspi_delay(f_pdata);
 		cqspi_readdata_capture(cqspi, !cqspi->rclk_en,
 				       f_pdata->read_delay);
 	}
@@ -861,26 +835,25 @@ static void cqspi_configure(struct spi_nor *nor)
 		cqspi_controller_enable(cqspi, 1);
 }
 
-static int cqspi_set_protocol(struct spi_nor *nor, const int read)
+static int cqspi_set_protocol(struct cqspi_flash_pdata *f_pdata,
+			      const struct spi_mem_op *op)
 {
-	struct cqspi_flash_pdata *f_pdata = nor->priv;
-
 	f_pdata->inst_width = CQSPI_INST_TYPE_SINGLE;
 	f_pdata->addr_width = CQSPI_INST_TYPE_SINGLE;
 	f_pdata->data_width = CQSPI_INST_TYPE_SINGLE;
 
-	if (read) {
-		switch (nor->read_proto) {
-		case SNOR_PROTO_1_1_1:
+	if (op->data.dir == SPI_MEM_DATA_IN) {
+		switch (op->data.buswidth) {
+		case 1:
 			f_pdata->data_width = CQSPI_INST_TYPE_SINGLE;
 			break;
-		case SNOR_PROTO_1_1_2:
+		case 2:
 			f_pdata->data_width = CQSPI_INST_TYPE_DUAL;
 			break;
-		case SNOR_PROTO_1_1_4:
+		case 4:
 			f_pdata->data_width = CQSPI_INST_TYPE_QUAD;
 			break;
-		case SNOR_PROTO_1_1_8:
+		case 8:
 			f_pdata->data_width = CQSPI_INST_TYPE_OCTAL;
 			break;
 		default:
@@ -888,36 +861,32 @@ static int cqspi_set_protocol(struct spi_nor *nor, const int read)
 		}
 	}
 
-	cqspi_configure(nor);
-
 	return 0;
 }
 
-static ssize_t cqspi_write(struct spi_nor *nor, loff_t to,
-			   size_t len, const u_char *buf)
+static ssize_t cqspi_write(struct cqspi_flash_pdata *f_pdata,
+			   const struct spi_mem_op *op)
 {
-	struct cqspi_flash_pdata *f_pdata = nor->priv;
 	struct cqspi_st *cqspi = f_pdata->cqspi;
+	loff_t to = op->addr.val;
+	size_t len = op->data.nbytes;
+	const u_char *buf = op->data.buf.out;
 	int ret;
 
-	ret = cqspi_set_protocol(nor, 0);
+	ret = cqspi_set_protocol(f_pdata, op);
 	if (ret)
 		return ret;
 
-	ret = cqspi_write_setup(nor);
+	ret = cqspi_write_setup(f_pdata, op);
 	if (ret)
 		return ret;
 
-	if (f_pdata->use_direct_mode) {
+	if (cqspi->use_dac_mode && ((to + len) <= cqspi->ahb_size)) {
 		memcpy_toio(cqspi->ahb_base + to, buf, len);
-		ret = cqspi_wait_idle(cqspi);
-	} else {
-		ret = cqspi_indirect_write_execute(nor, to, buf, len);
+		return cqspi_wait_idle(cqspi);
 	}
-	if (ret)
-		return ret;
 
-	return len;
+	return cqspi_indirect_write_execute(f_pdata, to, buf, len);
 }
 
 static void cqspi_rx_dma_callback(void *param)
@@ -927,11 +896,11 @@ static void cqspi_rx_dma_callback(void *param)
 	complete(&cqspi->rx_dma_complete);
 }
 
-static int cqspi_direct_read_execute(struct spi_nor *nor, u_char *buf,
-				     loff_t from, size_t len)
+static int cqspi_direct_read_execute(struct cqspi_flash_pdata *f_pdata,
+				     u_char *buf, loff_t from, size_t len)
 {
-	struct cqspi_flash_pdata *f_pdata = nor->priv;
 	struct cqspi_st *cqspi = f_pdata->cqspi;
+	struct device *dev = &cqspi->pdev->dev;
 	enum dma_ctrl_flags flags = DMA_CTRL_ACK | DMA_PREP_INTERRUPT;
 	dma_addr_t dma_src = (dma_addr_t)cqspi->mmap_phys_base + from;
 	int ret = 0;
@@ -944,15 +913,15 @@ static int cqspi_direct_read_execute(struct spi_nor *nor, u_char *buf,
 		return 0;
 	}
 
-	dma_dst = dma_map_single(nor->dev, buf, len, DMA_FROM_DEVICE);
-	if (dma_mapping_error(nor->dev, dma_dst)) {
-		dev_err(nor->dev, "dma mapping failed\n");
+	dma_dst = dma_map_single(dev, buf, len, DMA_FROM_DEVICE);
+	if (dma_mapping_error(dev, dma_dst)) {
+		dev_err(dev, "dma mapping failed\n");
 		return -ENOMEM;
 	}
 	tx = dmaengine_prep_dma_memcpy(cqspi->rx_chan, dma_dst, dma_src,
 				       len, flags);
 	if (!tx) {
-		dev_err(nor->dev, "device_prep_dma_memcpy error\n");
+		dev_err(dev, "device_prep_dma_memcpy error\n");
 		ret = -EIO;
 		goto err_unmap;
 	}
@@ -964,7 +933,7 @@ static int cqspi_direct_read_execute(struct spi_nor *nor, u_char *buf,
 
 	ret = dma_submit_error(cookie);
 	if (ret) {
-		dev_err(nor->dev, "dma_submit_error %d\n", cookie);
+		dev_err(dev, "dma_submit_error %d\n", cookie);
 		ret = -EIO;
 		goto err_unmap;
 	}
@@ -973,99 +942,68 @@ static int cqspi_direct_read_execute(struct spi_nor *nor, u_char *buf,
 	if (!wait_for_completion_timeout(&cqspi->rx_dma_complete,
 					 msecs_to_jiffies(len))) {
 		dmaengine_terminate_sync(cqspi->rx_chan);
-		dev_err(nor->dev, "DMA wait_for_completion_timeout\n");
+		dev_err(dev, "DMA wait_for_completion_timeout\n");
 		ret = -ETIMEDOUT;
 		goto err_unmap;
 	}
 
 err_unmap:
-	dma_unmap_single(nor->dev, dma_dst, len, DMA_FROM_DEVICE);
+	dma_unmap_single(dev, dma_dst, len, DMA_FROM_DEVICE);
 
 	return ret;
 }
 
-static ssize_t cqspi_read(struct spi_nor *nor, loff_t from,
-			  size_t len, u_char *buf)
-{
-	struct cqspi_flash_pdata *f_pdata = nor->priv;
-	int ret;
-
-	ret = cqspi_set_protocol(nor, 1);
-	if (ret)
-		return ret;
-
-	ret = cqspi_read_setup(nor);
-	if (ret)
-		return ret;
-
-	if (f_pdata->use_direct_mode)
-		ret = cqspi_direct_read_execute(nor, buf, from, len);
-	else
-		ret = cqspi_indirect_read_execute(nor, buf, from, len);
-	if (ret)
-		return ret;
-
-	return len;
-}
-
-static int cqspi_erase(struct spi_nor *nor, loff_t offs)
+static ssize_t cqspi_read(struct cqspi_flash_pdata *f_pdata,
+			  const struct spi_mem_op *op)
 {
+	struct cqspi_st *cqspi = f_pdata->cqspi;
+	loff_t from = op->addr.val;
+	size_t len = op->data.nbytes;
+	u_char *buf = op->data.buf.in;
 	int ret;
 
-	ret = cqspi_set_protocol(nor, 0);
+	ret = cqspi_set_protocol(f_pdata, op);
 	if (ret)
 		return ret;
 
-	/* Send write enable, then erase commands. */
-	ret = nor->controller_ops->write_reg(nor, SPINOR_OP_WREN, NULL, 0);
+	ret = cqspi_read_setup(f_pdata, op);
 	if (ret)
 		return ret;
 
-	/* Set up command buffer. */
-	ret = cqspi_command_write_addr(nor, nor->erase_opcode, offs);
-	if (ret)
-		return ret;
+	if (cqspi->use_dac_mode && ((from + len) <= cqspi->ahb_size))
+		return cqspi_direct_read_execute(f_pdata, buf, from, len);
 
-	return 0;
+	return cqspi_indirect_read_execute(f_pdata, buf, from, len);
 }
 
-static int cqspi_prep(struct spi_nor *nor)
+static int cqspi_mem_process(struct spi_mem *mem, const struct spi_mem_op *op)
 {
-	struct cqspi_flash_pdata *f_pdata = nor->priv;
-	struct cqspi_st *cqspi = f_pdata->cqspi;
-
-	mutex_lock(&cqspi->bus_mutex);
-
-	return 0;
-}
+	struct cqspi_st *cqspi = spi_master_get_devdata(mem->spi->master);
+	struct cqspi_flash_pdata *f_pdata;
 
-static void cqspi_unprep(struct spi_nor *nor)
-{
-	struct cqspi_flash_pdata *f_pdata = nor->priv;
-	struct cqspi_st *cqspi = f_pdata->cqspi;
+	f_pdata = &cqspi->f_pdata[mem->spi->chip_select];
+	cqspi_configure(f_pdata, mem->spi->max_speed_hz);
 
-	mutex_unlock(&cqspi->bus_mutex);
-}
+	if (op->data.dir == SPI_MEM_DATA_IN && op->data.buf.in) {
+		if (!op->addr.nbytes)
+			return cqspi_command_read(f_pdata, op);
 
-static int cqspi_read_reg(struct spi_nor *nor, u8 opcode, u8 *buf, size_t len)
-{
-	int ret;
+		return cqspi_read(f_pdata, op);
+	}
 
-	ret = cqspi_set_protocol(nor, 0);
-	if (!ret)
-		ret = cqspi_command_read(nor, opcode, buf, len);
+	if (!op->addr.nbytes || !op->data.buf.out)
+		return cqspi_command_write(f_pdata, op);
 
-	return ret;
+	return cqspi_write(f_pdata, op);
 }
 
-static int cqspi_write_reg(struct spi_nor *nor, u8 opcode, const u8 *buf,
-			   size_t len)
+static int cqspi_exec_mem_op(struct spi_mem *mem, const struct spi_mem_op *op)
 {
 	int ret;
 
-	ret = cqspi_set_protocol(nor, 0);
-	if (!ret)
-		ret = cqspi_command_write(nor, opcode, buf, len);
+	ret = cqspi_mem_process(mem, op);
+	if (ret)
+		dev_err(&mem->spi->dev, "operation failed with %d\n", ret);
 
 	return ret;
 }
@@ -1107,26 +1045,26 @@ static int cqspi_of_get_flash_pdata(struct platform_device *pdev,
 	return 0;
 }
 
-static int cqspi_of_get_pdata(struct platform_device *pdev)
+static int cqspi_of_get_pdata(struct cqspi_st *cqspi)
 {
-	struct device_node *np = pdev->dev.of_node;
-	struct cqspi_st *cqspi = platform_get_drvdata(pdev);
+	struct device *dev = &cqspi->pdev->dev;
+	struct device_node *np = dev->of_node;
 
 	cqspi->is_decoded_cs = of_property_read_bool(np, "cdns,is-decoded-cs");
 
 	if (of_property_read_u32(np, "cdns,fifo-depth", &cqspi->fifo_depth)) {
-		dev_err(&pdev->dev, "couldn't determine fifo-depth\n");
+		dev_err(dev, "couldn't determine fifo-depth\n");
 		return -ENXIO;
 	}
 
 	if (of_property_read_u32(np, "cdns,fifo-width", &cqspi->fifo_width)) {
-		dev_err(&pdev->dev, "couldn't determine fifo-width\n");
+		dev_err(dev, "couldn't determine fifo-width\n");
 		return -ENXIO;
 	}
 
 	if (of_property_read_u32(np, "cdns,trigger-address",
 				 &cqspi->trigger_address)) {
-		dev_err(&pdev->dev, "couldn't determine trigger-address\n");
+		dev_err(dev, "couldn't determine trigger-address\n");
 		return -ENXIO;
 	}
 
@@ -1169,7 +1107,7 @@ static void cqspi_controller_init(struct cqspi_st *cqspi)
 	cqspi_controller_enable(cqspi, 1);
 }
 
-static void cqspi_request_mmap_dma(struct cqspi_st *cqspi)
+static int cqspi_request_mmap_dma(struct cqspi_st *cqspi)
 {
 	dma_cap_mask_t mask;
 
@@ -1178,133 +1116,79 @@ static void cqspi_request_mmap_dma(struct cqspi_st *cqspi)
 
 	cqspi->rx_chan = dma_request_chan_by_mask(&mask);
 	if (IS_ERR(cqspi->rx_chan)) {
-		dev_err(&cqspi->pdev->dev, "No Rx DMA available\n");
+		int ret = PTR_ERR(cqspi->rx_chan);
+
+		if (ret != -EPROBE_DEFER)
+			dev_err(&cqspi->pdev->dev, "No Rx DMA available\n");
 		cqspi->rx_chan = NULL;
-		return;
+		return ret;
 	}
 	init_completion(&cqspi->rx_dma_complete);
+
+	return 0;
 }
 
-static const struct spi_nor_controller_ops cqspi_controller_ops = {
-	.prepare = cqspi_prep,
-	.unprepare = cqspi_unprep,
-	.read_reg = cqspi_read_reg,
-	.write_reg = cqspi_write_reg,
-	.read = cqspi_read,
-	.write = cqspi_write,
-	.erase = cqspi_erase,
+static const struct spi_controller_mem_ops cqspi_mem_ops = {
+	.exec_op = cqspi_exec_mem_op,
 };
 
-static int cqspi_setup_flash(struct cqspi_st *cqspi, struct device_node *np)
+static int cqspi_setup_flash(struct cqspi_st *cqspi)
 {
 	struct platform_device *pdev = cqspi->pdev;
 	struct device *dev = &pdev->dev;
-	const struct cqspi_driver_platdata *ddata;
-	struct spi_nor_hwcaps hwcaps;
+	struct device_node *np = dev->of_node;
 	struct cqspi_flash_pdata *f_pdata;
-	struct spi_nor *nor;
-	struct mtd_info *mtd;
 	unsigned int cs;
-	int i, ret;
-
-	ddata = of_device_get_match_data(dev);
-	if (!ddata) {
-		dev_err(dev, "Couldn't find driver data\n");
-		return -EINVAL;
-	}
-	hwcaps.mask = ddata->hwcaps_mask;
 
 	/* Get flash device data */
 	for_each_available_child_of_node(dev->of_node, np) {
-		ret = of_property_read_u32(np, "reg", &cs);
-		if (ret) {
+		if (of_property_read_u32(np, "reg", &cs)) {
 			dev_err(dev, "Couldn't determine chip select.\n");
-			goto err;
+			continue;
 		}
 
 		if (cs >= CQSPI_MAX_CHIPSELECT) {
-			ret = -EINVAL;
 			dev_err(dev, "Chip select %d out of range.\n", cs);
-			goto err;
+			continue;
 		}
 
 		f_pdata = &cqspi->f_pdata[cs];
 		f_pdata->cqspi = cqspi;
 		f_pdata->cs = cs;
 
-		ret = cqspi_of_get_flash_pdata(pdev, f_pdata, np);
-		if (ret)
-			goto err;
-
-		nor = &f_pdata->nor;
-		mtd = &nor->mtd;
-
-		mtd->priv = nor;
-
-		nor->dev = dev;
-		spi_nor_set_flash_node(nor, np);
-		nor->priv = f_pdata;
-		nor->controller_ops = &cqspi_controller_ops;
-
-		mtd->name = devm_kasprintf(dev, GFP_KERNEL, "%s.%d",
-					   dev_name(dev), cs);
-		if (!mtd->name) {
-			ret = -ENOMEM;
-			goto err;
-		}
-
-		ret = spi_nor_scan(nor, NULL, &hwcaps);
-		if (ret)
-			goto err;
-
-		ret = mtd_device_register(mtd, NULL, 0);
-		if (ret)
-			goto err;
-
-		f_pdata->registered = true;
-
-		if (mtd->size <= cqspi->ahb_size &&
-		    !(ddata->quirks & CQSPI_DISABLE_DAC_MODE)) {
-			f_pdata->use_direct_mode = true;
-			dev_dbg(nor->dev, "using direct mode for %s\n",
-				mtd->name);
-
-			if (!cqspi->rx_chan)
-				cqspi_request_mmap_dma(cqspi);
-		}
+		return cqspi_of_get_flash_pdata(pdev, f_pdata, np);
 	}
 
 	return 0;
-
-err:
-	for (i = 0; i < CQSPI_MAX_CHIPSELECT; i++)
-		if (cqspi->f_pdata[i].registered)
-			mtd_device_unregister(&cqspi->f_pdata[i].nor.mtd);
-	return ret;
 }
 
 static int cqspi_probe(struct platform_device *pdev)
 {
-	struct device_node *np = pdev->dev.of_node;
+	const struct cqspi_driver_platdata *ddata;
+	struct reset_control *rstc, *rstc_ocp;
 	struct device *dev = &pdev->dev;
+	struct spi_master *master;
+	struct resource *res_ahb;
 	struct cqspi_st *cqspi;
 	struct resource *res;
-	struct resource *res_ahb;
-	struct reset_control *rstc, *rstc_ocp;
-	const struct cqspi_driver_platdata *ddata;
 	int ret;
 	int irq;
 
-	cqspi = devm_kzalloc(dev, sizeof(*cqspi), GFP_KERNEL);
-	if (!cqspi)
+	master = spi_alloc_master(&pdev->dev, sizeof(*cqspi));
+	if (!master) {
+		dev_err(&pdev->dev, "spi_alloc_master failed\n");
 		return -ENOMEM;
+	}
+	master->mode_bits = SPI_RX_QUAD | SPI_RX_DUAL;
+	master->mem_ops = &cqspi_mem_ops;
+	master->dev.of_node = pdev->dev.of_node;
+
+	cqspi = spi_master_get_devdata(master);
 
-	mutex_init(&cqspi->bus_mutex);
 	cqspi->pdev = pdev;
-	platform_set_drvdata(pdev, cqspi);
 
 	/* Obtain configuration from OF. */
-	ret = cqspi_of_get_pdata(pdev);
+	ret = cqspi_of_get_pdata(cqspi);
 	if (ret) {
 		dev_err(dev, "Cannot get mandatory OF data.\n");
 		return -ENODEV;
@@ -1376,9 +1260,15 @@ static int cqspi_probe(struct platform_device *pdev)
 
 	cqspi->master_ref_clk_hz = clk_get_rate(cqspi->clk);
 	ddata  = of_device_get_match_data(dev);
-	if (ddata && (ddata->quirks & CQSPI_NEEDS_WR_DELAY))
-		cqspi->wr_delay = 5 * DIV_ROUND_UP(NSEC_PER_SEC,
-						   cqspi->master_ref_clk_hz);
+	if (ddata) {
+		if (ddata->quirks & CQSPI_NEEDS_WR_DELAY)
+			cqspi->wr_delay = 5 * DIV_ROUND_UP(NSEC_PER_SEC,
+						cqspi->master_ref_clk_hz);
+		if (ddata->hwcaps_mask & CQSPI_SUPPORTS_OCTAL)
+			master->mode_bits |= SPI_RX_OCTAL;
+		if (!(ddata->quirks & CQSPI_DISABLE_DAC_MODE))
+			cqspi->use_dac_mode = true;
+	}
 
 	ret = devm_request_irq(dev, irq, cqspi_irq_handler, 0,
 			       pdev->name, cqspi);
@@ -1392,13 +1282,25 @@ static int cqspi_probe(struct platform_device *pdev)
 	cqspi->current_cs = -1;
 	cqspi->sclk = 0;
 
-	ret = cqspi_setup_flash(cqspi, np);
+	ret = cqspi_setup_flash(cqspi);
 	if (ret) {
-		dev_err(dev, "Cadence QSPI NOR probe failed %d\n", ret);
+		dev_err(dev, "failed to setup flash parameters %d\n", ret);
 		goto probe_setup_failed;
 	}
 
-	return ret;
+	if (cqspi->use_dac_mode) {
+		ret = cqspi_request_mmap_dma(cqspi);
+		if (ret == -EPROBE_DEFER)
+			goto probe_setup_failed;
+	}
+
+	ret = devm_spi_register_master(dev, master);
+	if (ret) {
+		dev_err(&pdev->dev, "failed to register SPI ctlr %d\n", ret);
+		goto probe_setup_failed;
+	}
+
+	return 0;
 probe_setup_failed:
 	cqspi_controller_enable(cqspi, 0);
 probe_reset_failed:
@@ -1412,11 +1314,6 @@ static int cqspi_probe(struct platform_device *pdev)
 static int cqspi_remove(struct platform_device *pdev)
 {
 	struct cqspi_st *cqspi = platform_get_drvdata(pdev);
-	int i;
-
-	for (i = 0; i < CQSPI_MAX_CHIPSELECT; i++)
-		if (cqspi->f_pdata[i].registered)
-			mtd_device_unregister(&cqspi->f_pdata[i].nor.mtd);
 
 	cqspi_controller_enable(cqspi, 0);
 
@@ -1459,17 +1356,15 @@ static const struct dev_pm_ops cqspi__dev_pm_ops = {
 #endif
 
 static const struct cqspi_driver_platdata cdns_qspi = {
-	.hwcaps_mask = CQSPI_BASE_HWCAPS_MASK,
 	.quirks = CQSPI_DISABLE_DAC_MODE,
 };
 
 static const struct cqspi_driver_platdata k2g_qspi = {
-	.hwcaps_mask = CQSPI_BASE_HWCAPS_MASK,
 	.quirks = CQSPI_NEEDS_WR_DELAY,
 };
 
 static const struct cqspi_driver_platdata am654_ospi = {
-	.hwcaps_mask = CQSPI_BASE_HWCAPS_MASK | SNOR_HWCAPS_READ_1_1_8,
+	.hwcaps_mask = CQSPI_SUPPORTS_OCTAL,
 	.quirks = CQSPI_NEEDS_WR_DELAY,
 };
 
@@ -1508,3 +1403,5 @@ MODULE_LICENSE("GPL v2");
 MODULE_ALIAS("platform:" CQSPI_NAME);
 MODULE_AUTHOR("Ley Foon Tan <lftan@altera.com>");
 MODULE_AUTHOR("Graham Moore <grmoore@opensource.altera.com>");
+MODULE_AUTHOR("Vadivel Murugan R <vadivel.muruganx.ramuthevar@intel.com>");
+MODULE_AUTHOR("Vignesh Raghavendra <vigneshr@ti.com>");
-- 
2.26.2


______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/

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

* [PATCH v2 6/6] spi: Move cadence-quadspi driver to drivers/spi/
  2020-05-26  9:35 ` Vignesh Raghavendra
@ 2020-05-26  9:36   ` Vignesh Raghavendra
  -1 siblings, 0 replies; 36+ messages in thread
From: Vignesh Raghavendra @ 2020-05-26  9:36 UTC (permalink / raw)
  To: Tudor Ambarus, Mark Brown
  Cc: Vignesh Raghavendra, Boris Brezillon, Ramuthevar Vadivel Murugan,
	linux-mtd, linux-kernel, linux-spi, simon.k.r.goldschmidt,
	dinguyen, marex

From: Ramuthevar Vadivel Murugan <vadivel.muruganx.ramuthevar@linux.intel.com>

Now that cadence-quadspi has been converted to use spi-mem framework,
move it under drivers/spi/

Update license header to match SPI subsystem style

Signed-off-by: Ramuthevar Vadivel Murugan <vadivel.muruganx.ramuthevar@linux.intel.com>
Signed-off-by: Vignesh Raghavendra <vigneshr@ti.com>
---
 drivers/mtd/spi-nor/controllers/Kconfig            | 11 -----------
 drivers/mtd/spi-nor/controllers/Makefile           |  1 -
 drivers/spi/Kconfig                                | 11 +++++++++++
 drivers/spi/Makefile                               |  1 +
 .../spi-cadence-quadspi.c}                         | 14 +++++++-------
 5 files changed, 19 insertions(+), 19 deletions(-)
 rename drivers/{mtd/spi-nor/controllers/cadence-quadspi.c => spi/spi-cadence-quadspi.c} (99%)

diff --git a/drivers/mtd/spi-nor/controllers/Kconfig b/drivers/mtd/spi-nor/controllers/Kconfig
index 10b86660b821..95fcd4b435be 100644
--- a/drivers/mtd/spi-nor/controllers/Kconfig
+++ b/drivers/mtd/spi-nor/controllers/Kconfig
@@ -9,17 +9,6 @@ config SPI_ASPEED_SMC
 	  and support for the SPI flash memory controller (SPI) for
 	  the host firmware. The implementation only supports SPI NOR.
 
-config SPI_CADENCE_QUADSPI
-	tristate "Cadence Quad SPI controller"
-	depends on OF && (ARM || ARM64 || COMPILE_TEST)
-	help
-	  Enable support for the Cadence Quad SPI Flash controller.
-
-	  Cadence QSPI is a specialized controller for connecting an SPI
-	  Flash over 1/2/4-bit wide bus. Enable this option if you have a
-	  device with a Cadence QSPI controller and want to access the
-	  Flash as an MTD device.
-
 config SPI_HISI_SFC
 	tristate "Hisilicon FMC SPI-NOR Flash Controller(SFC)"
 	depends on ARCH_HISI || COMPILE_TEST
diff --git a/drivers/mtd/spi-nor/controllers/Makefile b/drivers/mtd/spi-nor/controllers/Makefile
index 46e6fbe586e3..e7abba491d98 100644
--- a/drivers/mtd/spi-nor/controllers/Makefile
+++ b/drivers/mtd/spi-nor/controllers/Makefile
@@ -1,6 +1,5 @@
 # SPDX-License-Identifier: GPL-2.0
 obj-$(CONFIG_SPI_ASPEED_SMC)	+= aspeed-smc.o
-obj-$(CONFIG_SPI_CADENCE_QUADSPI)	+= cadence-quadspi.o
 obj-$(CONFIG_SPI_HISI_SFC)	+= hisi-sfc.o
 obj-$(CONFIG_SPI_NXP_SPIFI)	+= nxp-spifi.o
 obj-$(CONFIG_SPI_INTEL_SPI)	+= intel-spi.o
diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig
index 099d6a75a371..2de8098b26c1 100644
--- a/drivers/spi/Kconfig
+++ b/drivers/spi/Kconfig
@@ -200,6 +200,17 @@ config SPI_CADENCE
 	  This selects the Cadence SPI controller master driver
 	  used by Xilinx Zynq and ZynqMP.
 
+config SPI_CADENCE_QUADSPI
+	tristate "Cadence Quad SPI controller"
+	depends on OF && (ARM || ARM64 || COMPILE_TEST)
+	help
+	  Enable support for the Cadence Quad SPI Flash controller.
+
+	  Cadence QSPI is a specialized controller for connecting an SPI
+	  Flash over 1/2/4-bit wide bus. Enable this option if you have a
+	  device with a Cadence QSPI controller and want to access the
+	  Flash as an MTD device.
+
 config SPI_CLPS711X
 	tristate "CLPS711X host SPI controller"
 	depends on ARCH_CLPS711X || COMPILE_TEST
diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile
index 889368f4ad53..f03834d1d312 100644
--- a/drivers/spi/Makefile
+++ b/drivers/spi/Makefile
@@ -31,6 +31,7 @@ obj-$(CONFIG_SPI_BCM_QSPI)		+= spi-iproc-qspi.o spi-brcmstb-qspi.o spi-bcm-qspi.
 obj-$(CONFIG_SPI_BITBANG)		+= spi-bitbang.o
 obj-$(CONFIG_SPI_BUTTERFLY)		+= spi-butterfly.o
 obj-$(CONFIG_SPI_CADENCE)		+= spi-cadence.o
+obj-$(CONFIG_SPI_CADENCE_QUADSPI)	+= spi-cadence-quadspi.o
 obj-$(CONFIG_SPI_CLPS711X)		+= spi-clps711x.o
 obj-$(CONFIG_SPI_COLDFIRE_QSPI)		+= spi-coldfire-qspi.o
 obj-$(CONFIG_SPI_DAVINCI)		+= spi-davinci.o
diff --git a/drivers/mtd/spi-nor/controllers/cadence-quadspi.c b/drivers/spi/spi-cadence-quadspi.c
similarity index 99%
rename from drivers/mtd/spi-nor/controllers/cadence-quadspi.c
rename to drivers/spi/spi-cadence-quadspi.c
index c1df4b221889..8e8937ec5b1b 100644
--- a/drivers/mtd/spi-nor/controllers/cadence-quadspi.c
+++ b/drivers/spi/spi-cadence-quadspi.c
@@ -1,11 +1,11 @@
 // SPDX-License-Identifier: GPL-2.0-only
-/*
- * Driver for Cadence QSPI Controller
- *
- * Copyright Altera Corporation (C) 2012-2014. All rights reserved.
- * Copyright Intel Corporation (C) 2019-2020. All rights reserved.
- * Copyright (C) 2020 Texas Instruments Incorporated - http://www.ti.com
- */
+//
+// Driver for Cadence QSPI Controller
+//
+// Copyright Altera Corporation (C) 2012-2014. All rights reserved.
+// Copyright Intel Corporation (C) 2019-2020. All rights reserved.
+// Copyright (C) 2020 Texas Instruments Incorporated - http://www.ti.com
+
 #include <linux/clk.h>
 #include <linux/completion.h>
 #include <linux/delay.h>
-- 
2.26.2


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

* [PATCH v2 6/6] spi: Move cadence-quadspi driver to drivers/spi/
@ 2020-05-26  9:36   ` Vignesh Raghavendra
  0 siblings, 0 replies; 36+ messages in thread
From: Vignesh Raghavendra @ 2020-05-26  9:36 UTC (permalink / raw)
  To: Tudor Ambarus, Mark Brown
  Cc: marex, Vignesh Raghavendra, Boris Brezillon, dinguyen,
	simon.k.r.goldschmidt, linux-kernel, linux-spi,
	Ramuthevar Vadivel Murugan, linux-mtd

From: Ramuthevar Vadivel Murugan <vadivel.muruganx.ramuthevar@linux.intel.com>

Now that cadence-quadspi has been converted to use spi-mem framework,
move it under drivers/spi/

Update license header to match SPI subsystem style

Signed-off-by: Ramuthevar Vadivel Murugan <vadivel.muruganx.ramuthevar@linux.intel.com>
Signed-off-by: Vignesh Raghavendra <vigneshr@ti.com>
---
 drivers/mtd/spi-nor/controllers/Kconfig            | 11 -----------
 drivers/mtd/spi-nor/controllers/Makefile           |  1 -
 drivers/spi/Kconfig                                | 11 +++++++++++
 drivers/spi/Makefile                               |  1 +
 .../spi-cadence-quadspi.c}                         | 14 +++++++-------
 5 files changed, 19 insertions(+), 19 deletions(-)
 rename drivers/{mtd/spi-nor/controllers/cadence-quadspi.c => spi/spi-cadence-quadspi.c} (99%)

diff --git a/drivers/mtd/spi-nor/controllers/Kconfig b/drivers/mtd/spi-nor/controllers/Kconfig
index 10b86660b821..95fcd4b435be 100644
--- a/drivers/mtd/spi-nor/controllers/Kconfig
+++ b/drivers/mtd/spi-nor/controllers/Kconfig
@@ -9,17 +9,6 @@ config SPI_ASPEED_SMC
 	  and support for the SPI flash memory controller (SPI) for
 	  the host firmware. The implementation only supports SPI NOR.
 
-config SPI_CADENCE_QUADSPI
-	tristate "Cadence Quad SPI controller"
-	depends on OF && (ARM || ARM64 || COMPILE_TEST)
-	help
-	  Enable support for the Cadence Quad SPI Flash controller.
-
-	  Cadence QSPI is a specialized controller for connecting an SPI
-	  Flash over 1/2/4-bit wide bus. Enable this option if you have a
-	  device with a Cadence QSPI controller and want to access the
-	  Flash as an MTD device.
-
 config SPI_HISI_SFC
 	tristate "Hisilicon FMC SPI-NOR Flash Controller(SFC)"
 	depends on ARCH_HISI || COMPILE_TEST
diff --git a/drivers/mtd/spi-nor/controllers/Makefile b/drivers/mtd/spi-nor/controllers/Makefile
index 46e6fbe586e3..e7abba491d98 100644
--- a/drivers/mtd/spi-nor/controllers/Makefile
+++ b/drivers/mtd/spi-nor/controllers/Makefile
@@ -1,6 +1,5 @@
 # SPDX-License-Identifier: GPL-2.0
 obj-$(CONFIG_SPI_ASPEED_SMC)	+= aspeed-smc.o
-obj-$(CONFIG_SPI_CADENCE_QUADSPI)	+= cadence-quadspi.o
 obj-$(CONFIG_SPI_HISI_SFC)	+= hisi-sfc.o
 obj-$(CONFIG_SPI_NXP_SPIFI)	+= nxp-spifi.o
 obj-$(CONFIG_SPI_INTEL_SPI)	+= intel-spi.o
diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig
index 099d6a75a371..2de8098b26c1 100644
--- a/drivers/spi/Kconfig
+++ b/drivers/spi/Kconfig
@@ -200,6 +200,17 @@ config SPI_CADENCE
 	  This selects the Cadence SPI controller master driver
 	  used by Xilinx Zynq and ZynqMP.
 
+config SPI_CADENCE_QUADSPI
+	tristate "Cadence Quad SPI controller"
+	depends on OF && (ARM || ARM64 || COMPILE_TEST)
+	help
+	  Enable support for the Cadence Quad SPI Flash controller.
+
+	  Cadence QSPI is a specialized controller for connecting an SPI
+	  Flash over 1/2/4-bit wide bus. Enable this option if you have a
+	  device with a Cadence QSPI controller and want to access the
+	  Flash as an MTD device.
+
 config SPI_CLPS711X
 	tristate "CLPS711X host SPI controller"
 	depends on ARCH_CLPS711X || COMPILE_TEST
diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile
index 889368f4ad53..f03834d1d312 100644
--- a/drivers/spi/Makefile
+++ b/drivers/spi/Makefile
@@ -31,6 +31,7 @@ obj-$(CONFIG_SPI_BCM_QSPI)		+= spi-iproc-qspi.o spi-brcmstb-qspi.o spi-bcm-qspi.
 obj-$(CONFIG_SPI_BITBANG)		+= spi-bitbang.o
 obj-$(CONFIG_SPI_BUTTERFLY)		+= spi-butterfly.o
 obj-$(CONFIG_SPI_CADENCE)		+= spi-cadence.o
+obj-$(CONFIG_SPI_CADENCE_QUADSPI)	+= spi-cadence-quadspi.o
 obj-$(CONFIG_SPI_CLPS711X)		+= spi-clps711x.o
 obj-$(CONFIG_SPI_COLDFIRE_QSPI)		+= spi-coldfire-qspi.o
 obj-$(CONFIG_SPI_DAVINCI)		+= spi-davinci.o
diff --git a/drivers/mtd/spi-nor/controllers/cadence-quadspi.c b/drivers/spi/spi-cadence-quadspi.c
similarity index 99%
rename from drivers/mtd/spi-nor/controllers/cadence-quadspi.c
rename to drivers/spi/spi-cadence-quadspi.c
index c1df4b221889..8e8937ec5b1b 100644
--- a/drivers/mtd/spi-nor/controllers/cadence-quadspi.c
+++ b/drivers/spi/spi-cadence-quadspi.c
@@ -1,11 +1,11 @@
 // SPDX-License-Identifier: GPL-2.0-only
-/*
- * Driver for Cadence QSPI Controller
- *
- * Copyright Altera Corporation (C) 2012-2014. All rights reserved.
- * Copyright Intel Corporation (C) 2019-2020. All rights reserved.
- * Copyright (C) 2020 Texas Instruments Incorporated - http://www.ti.com
- */
+//
+// Driver for Cadence QSPI Controller
+//
+// Copyright Altera Corporation (C) 2012-2014. All rights reserved.
+// Copyright Intel Corporation (C) 2019-2020. All rights reserved.
+// Copyright (C) 2020 Texas Instruments Incorporated - http://www.ti.com
+
 #include <linux/clk.h>
 #include <linux/completion.h>
 #include <linux/delay.h>
-- 
2.26.2


______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/

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

* Re: [PATCH v2 6/6] spi: Move cadence-quadspi driver to drivers/spi/
  2020-05-26  9:36   ` Vignesh Raghavendra
  (?)
@ 2020-05-27 20:58     ` kbuild test robot
  -1 siblings, 0 replies; 36+ messages in thread
From: kbuild test robot @ 2020-05-27 20:58 UTC (permalink / raw)
  To: Vignesh Raghavendra, Tudor Ambarus, Mark Brown
  Cc: kbuild-all, Vignesh Raghavendra, Boris Brezillon,
	Ramuthevar Vadivel Murugan, linux-mtd, linux-kernel, linux-spi,
	simon.k.r.goldschmidt, dinguyen, marex

[-- Attachment #1: Type: text/plain, Size: 12379 bytes --]

Hi Vignesh,

Thank you for the patch! Perhaps something to improve:

[auto build test WARNING on spi/for-next]
[also build test WARNING on linus/master v5.7-rc7 next-20200526]
[cannot apply to mtd/master]
[if your patch is applied to the wrong git tree, please drop us a note to help
improve the system. BTW, we also suggest to use '--base' option to specify the
base tree in git format-patch, please see https://stackoverflow.com/a/37406982]

url:    https://github.com/0day-ci/linux/commits/Vignesh-Raghavendra/mtd-spi-nor-Move-cadence-qaudspi-to-spi-mem-framework/20200526-174159
base:   https://git.kernel.org/pub/scm/linux/kernel/git/broonie/spi.git for-next
config: xtensa-allyesconfig (attached as .config)
compiler: xtensa-linux-gcc (GCC) 9.3.0
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # save the attached .config to linux build tree
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-9.3.0 make.cross ARCH=xtensa 

If you fix the issue, kindly add following tag as appropriate
Reported-by: kbuild test robot <lkp@intel.com>

All warnings (new ones prefixed by >>, old ones prefixed by <<):

In file included from include/linux/err.h:5,
from include/linux/clk.h:12,
from drivers/spi/spi-cadence-quadspi.c:9:
include/linux/scatterlist.h: In function 'sg_set_buf':
arch/xtensa/include/asm/page.h:193:9: warning: comparison of unsigned expression >= 0 is always true [-Wtype-limits]
193 |  ((pfn) >= ARCH_PFN_OFFSET && ((pfn) - ARCH_PFN_OFFSET) < max_mapnr)
|         ^~
include/linux/compiler.h:78:42: note: in definition of macro 'unlikely'
78 | # define unlikely(x) __builtin_expect(!!(x), 0)
|                                          ^
include/linux/scatterlist.h:143:2: note: in expansion of macro 'BUG_ON'
143 |  BUG_ON(!virt_addr_valid(buf));
|  ^~~~~~
arch/xtensa/include/asm/page.h:201:32: note: in expansion of macro 'pfn_valid'
201 | #define virt_addr_valid(kaddr) pfn_valid(__pa(kaddr) >> PAGE_SHIFT)
|                                ^~~~~~~~~
include/linux/scatterlist.h:143:10: note: in expansion of macro 'virt_addr_valid'
143 |  BUG_ON(!virt_addr_valid(buf));
|          ^~~~~~~~~~~~~~~
In file included from ./arch/xtensa/include/generated/asm/bug.h:1,
from include/linux/bug.h:5,
from include/linux/thread_info.h:12,
from arch/xtensa/include/asm/current.h:18,
from include/linux/mutex.h:14,
from include/linux/notifier.h:14,
from include/linux/clk.h:14,
from drivers/spi/spi-cadence-quadspi.c:9:
include/linux/dma-mapping.h: In function 'dma_map_resource':
arch/xtensa/include/asm/page.h:193:9: warning: comparison of unsigned expression >= 0 is always true [-Wtype-limits]
193 |  ((pfn) >= ARCH_PFN_OFFSET && ((pfn) - ARCH_PFN_OFFSET) < max_mapnr)
|         ^~
include/asm-generic/bug.h:139:27: note: in definition of macro 'WARN_ON_ONCE'
139 |  int __ret_warn_once = !!(condition);            |                           ^~~~~~~~~
include/linux/dma-mapping.h:352:19: note: in expansion of macro 'pfn_valid'
352 |  if (WARN_ON_ONCE(pfn_valid(PHYS_PFN(phys_addr))))
|                   ^~~~~~~~~
In file included from include/linux/shm.h:6,
from include/linux/sched.h:16,
from include/linux/ratelimit.h:6,
from include/linux/dev_printk.h:16,
from include/linux/device.h:15,
from include/linux/dma-mapping.h:7,
from drivers/spi/spi-cadence-quadspi.c:12:
drivers/spi/spi-cadence-quadspi.c: In function 'cqspi_direct_read_execute':
arch/xtensa/include/asm/page.h:193:9: warning: comparison of unsigned expression >= 0 is always true [-Wtype-limits]
193 |  ((pfn) >= ARCH_PFN_OFFSET && ((pfn) - ARCH_PFN_OFFSET) < max_mapnr)
|         ^~
arch/xtensa/include/asm/page.h:201:32: note: in expansion of macro 'pfn_valid'
201 | #define virt_addr_valid(kaddr) pfn_valid(__pa(kaddr) >> PAGE_SHIFT)
|                                ^~~~~~~~~
>> drivers/spi/spi-cadence-quadspi.c:911:26: note: in expansion of macro 'virt_addr_valid'
911 |  if (!cqspi->rx_chan || !virt_addr_valid(buf)) {
|                          ^~~~~~~~~~~~~~~

vim +/virt_addr_valid +911 drivers/spi/spi-cadence-quadspi.c

ffa639e069fb55 drivers/mtd/spi-nor/cadence-quadspi.c             Vignesh R                  2018-04-10  898  
d467c948c5d40f drivers/mtd/spi-nor/controllers/cadence-quadspi.c Ramuthevar Vadivel Murugan 2020-05-26  899  static int cqspi_direct_read_execute(struct cqspi_flash_pdata *f_pdata,
d467c948c5d40f drivers/mtd/spi-nor/controllers/cadence-quadspi.c Ramuthevar Vadivel Murugan 2020-05-26  900  				     u_char *buf, loff_t from, size_t len)
ffa639e069fb55 drivers/mtd/spi-nor/cadence-quadspi.c             Vignesh R                  2018-04-10  901  {
ffa639e069fb55 drivers/mtd/spi-nor/cadence-quadspi.c             Vignesh R                  2018-04-10  902  	struct cqspi_st *cqspi = f_pdata->cqspi;
d467c948c5d40f drivers/mtd/spi-nor/controllers/cadence-quadspi.c Ramuthevar Vadivel Murugan 2020-05-26  903  	struct device *dev = &cqspi->pdev->dev;
ffa639e069fb55 drivers/mtd/spi-nor/cadence-quadspi.c             Vignesh R                  2018-04-10  904  	enum dma_ctrl_flags flags = DMA_CTRL_ACK | DMA_PREP_INTERRUPT;
ffa639e069fb55 drivers/mtd/spi-nor/cadence-quadspi.c             Vignesh R                  2018-04-10  905  	dma_addr_t dma_src = (dma_addr_t)cqspi->mmap_phys_base + from;
ffa639e069fb55 drivers/mtd/spi-nor/cadence-quadspi.c             Vignesh R                  2018-04-10  906  	int ret = 0;
ffa639e069fb55 drivers/mtd/spi-nor/cadence-quadspi.c             Vignesh R                  2018-04-10  907  	struct dma_async_tx_descriptor *tx;
ffa639e069fb55 drivers/mtd/spi-nor/cadence-quadspi.c             Vignesh R                  2018-04-10  908  	dma_cookie_t cookie;
ffa639e069fb55 drivers/mtd/spi-nor/cadence-quadspi.c             Vignesh R                  2018-04-10  909  	dma_addr_t dma_dst;
ffa639e069fb55 drivers/mtd/spi-nor/cadence-quadspi.c             Vignesh R                  2018-04-10  910  
ffa639e069fb55 drivers/mtd/spi-nor/cadence-quadspi.c             Vignesh R                  2018-04-10 @911  	if (!cqspi->rx_chan || !virt_addr_valid(buf)) {
ffa639e069fb55 drivers/mtd/spi-nor/cadence-quadspi.c             Vignesh R                  2018-04-10  912  		memcpy_fromio(buf, cqspi->ahb_base + from, len);
ffa639e069fb55 drivers/mtd/spi-nor/cadence-quadspi.c             Vignesh R                  2018-04-10  913  		return 0;
ffa639e069fb55 drivers/mtd/spi-nor/cadence-quadspi.c             Vignesh R                  2018-04-10  914  	}
ffa639e069fb55 drivers/mtd/spi-nor/cadence-quadspi.c             Vignesh R                  2018-04-10  915  
d467c948c5d40f drivers/mtd/spi-nor/controllers/cadence-quadspi.c Ramuthevar Vadivel Murugan 2020-05-26  916  	dma_dst = dma_map_single(dev, buf, len, DMA_FROM_DEVICE);
d467c948c5d40f drivers/mtd/spi-nor/controllers/cadence-quadspi.c Ramuthevar Vadivel Murugan 2020-05-26  917  	if (dma_mapping_error(dev, dma_dst)) {
d467c948c5d40f drivers/mtd/spi-nor/controllers/cadence-quadspi.c Ramuthevar Vadivel Murugan 2020-05-26  918  		dev_err(dev, "dma mapping failed\n");
ffa639e069fb55 drivers/mtd/spi-nor/cadence-quadspi.c             Vignesh R                  2018-04-10  919  		return -ENOMEM;
ffa639e069fb55 drivers/mtd/spi-nor/cadence-quadspi.c             Vignesh R                  2018-04-10  920  	}
ffa639e069fb55 drivers/mtd/spi-nor/cadence-quadspi.c             Vignesh R                  2018-04-10  921  	tx = dmaengine_prep_dma_memcpy(cqspi->rx_chan, dma_dst, dma_src,
ffa639e069fb55 drivers/mtd/spi-nor/cadence-quadspi.c             Vignesh R                  2018-04-10  922  				       len, flags);
ffa639e069fb55 drivers/mtd/spi-nor/cadence-quadspi.c             Vignesh R                  2018-04-10  923  	if (!tx) {
d467c948c5d40f drivers/mtd/spi-nor/controllers/cadence-quadspi.c Ramuthevar Vadivel Murugan 2020-05-26  924  		dev_err(dev, "device_prep_dma_memcpy error\n");
ffa639e069fb55 drivers/mtd/spi-nor/cadence-quadspi.c             Vignesh R                  2018-04-10  925  		ret = -EIO;
ffa639e069fb55 drivers/mtd/spi-nor/cadence-quadspi.c             Vignesh R                  2018-04-10  926  		goto err_unmap;
ffa639e069fb55 drivers/mtd/spi-nor/cadence-quadspi.c             Vignesh R                  2018-04-10  927  	}
ffa639e069fb55 drivers/mtd/spi-nor/cadence-quadspi.c             Vignesh R                  2018-04-10  928  
ffa639e069fb55 drivers/mtd/spi-nor/cadence-quadspi.c             Vignesh R                  2018-04-10  929  	tx->callback = cqspi_rx_dma_callback;
ffa639e069fb55 drivers/mtd/spi-nor/cadence-quadspi.c             Vignesh R                  2018-04-10  930  	tx->callback_param = cqspi;
ffa639e069fb55 drivers/mtd/spi-nor/cadence-quadspi.c             Vignesh R                  2018-04-10  931  	cookie = tx->tx_submit(tx);
ffa639e069fb55 drivers/mtd/spi-nor/cadence-quadspi.c             Vignesh R                  2018-04-10  932  	reinit_completion(&cqspi->rx_dma_complete);
ffa639e069fb55 drivers/mtd/spi-nor/cadence-quadspi.c             Vignesh R                  2018-04-10  933  
ffa639e069fb55 drivers/mtd/spi-nor/cadence-quadspi.c             Vignesh R                  2018-04-10  934  	ret = dma_submit_error(cookie);
ffa639e069fb55 drivers/mtd/spi-nor/cadence-quadspi.c             Vignesh R                  2018-04-10  935  	if (ret) {
d467c948c5d40f drivers/mtd/spi-nor/controllers/cadence-quadspi.c Ramuthevar Vadivel Murugan 2020-05-26  936  		dev_err(dev, "dma_submit_error %d\n", cookie);
ffa639e069fb55 drivers/mtd/spi-nor/cadence-quadspi.c             Vignesh R                  2018-04-10  937  		ret = -EIO;
ffa639e069fb55 drivers/mtd/spi-nor/cadence-quadspi.c             Vignesh R                  2018-04-10  938  		goto err_unmap;
ffa639e069fb55 drivers/mtd/spi-nor/cadence-quadspi.c             Vignesh R                  2018-04-10  939  	}
ffa639e069fb55 drivers/mtd/spi-nor/cadence-quadspi.c             Vignesh R                  2018-04-10  940  
ffa639e069fb55 drivers/mtd/spi-nor/cadence-quadspi.c             Vignesh R                  2018-04-10  941  	dma_async_issue_pending(cqspi->rx_chan);
3938c0d4cf6047 drivers/mtd/spi-nor/cadence-quadspi.c             Nicholas Mc Guire          2018-07-21  942  	if (!wait_for_completion_timeout(&cqspi->rx_dma_complete,
3938c0d4cf6047 drivers/mtd/spi-nor/cadence-quadspi.c             Nicholas Mc Guire          2018-07-21  943  					 msecs_to_jiffies(len))) {
ffa639e069fb55 drivers/mtd/spi-nor/cadence-quadspi.c             Vignesh R                  2018-04-10  944  		dmaengine_terminate_sync(cqspi->rx_chan);
d467c948c5d40f drivers/mtd/spi-nor/controllers/cadence-quadspi.c Ramuthevar Vadivel Murugan 2020-05-26  945  		dev_err(dev, "DMA wait_for_completion_timeout\n");
ffa639e069fb55 drivers/mtd/spi-nor/cadence-quadspi.c             Vignesh R                  2018-04-10  946  		ret = -ETIMEDOUT;
ffa639e069fb55 drivers/mtd/spi-nor/cadence-quadspi.c             Vignesh R                  2018-04-10  947  		goto err_unmap;
ffa639e069fb55 drivers/mtd/spi-nor/cadence-quadspi.c             Vignesh R                  2018-04-10  948  	}
ffa639e069fb55 drivers/mtd/spi-nor/cadence-quadspi.c             Vignesh R                  2018-04-10  949  
ffa639e069fb55 drivers/mtd/spi-nor/cadence-quadspi.c             Vignesh R                  2018-04-10  950  err_unmap:
d467c948c5d40f drivers/mtd/spi-nor/controllers/cadence-quadspi.c Ramuthevar Vadivel Murugan 2020-05-26  951  	dma_unmap_single(dev, dma_dst, len, DMA_FROM_DEVICE);
ffa639e069fb55 drivers/mtd/spi-nor/cadence-quadspi.c             Vignesh R                  2018-04-10  952  
91d7b67000c6e9 drivers/mtd/spi-nor/cadence-quadspi.c             Christophe JAILLET         2018-10-16  953  	return ret;
ffa639e069fb55 drivers/mtd/spi-nor/cadence-quadspi.c             Vignesh R                  2018-04-10  954  }
ffa639e069fb55 drivers/mtd/spi-nor/cadence-quadspi.c             Vignesh R                  2018-04-10  955  

:::::: The code at line 911 was first introduced by commit
:::::: ffa639e069fb55a150a2f14af6762b2c429e6d50 mtd: spi-nor: cadence-quadspi: Add DMA support for direct mode reads

:::::: TO: Vignesh R <vigneshr@ti.com>
:::::: CC: Boris Brezillon <boris.brezillon@bootlin.com>

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org

[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 62791 bytes --]

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

* Re: [PATCH v2 6/6] spi: Move cadence-quadspi driver to drivers/spi/
@ 2020-05-27 20:58     ` kbuild test robot
  0 siblings, 0 replies; 36+ messages in thread
From: kbuild test robot @ 2020-05-27 20:58 UTC (permalink / raw)
  To: Vignesh Raghavendra, Tudor Ambarus, Mark Brown
  Cc: marex, kbuild-all, Vignesh Raghavendra, Boris Brezillon,
	dinguyen, simon.k.r.goldschmidt, linux-kernel, linux-spi,
	Ramuthevar Vadivel Murugan, linux-mtd

[-- Attachment #1: Type: text/plain, Size: 12379 bytes --]

Hi Vignesh,

Thank you for the patch! Perhaps something to improve:

[auto build test WARNING on spi/for-next]
[also build test WARNING on linus/master v5.7-rc7 next-20200526]
[cannot apply to mtd/master]
[if your patch is applied to the wrong git tree, please drop us a note to help
improve the system. BTW, we also suggest to use '--base' option to specify the
base tree in git format-patch, please see https://stackoverflow.com/a/37406982]

url:    https://github.com/0day-ci/linux/commits/Vignesh-Raghavendra/mtd-spi-nor-Move-cadence-qaudspi-to-spi-mem-framework/20200526-174159
base:   https://git.kernel.org/pub/scm/linux/kernel/git/broonie/spi.git for-next
config: xtensa-allyesconfig (attached as .config)
compiler: xtensa-linux-gcc (GCC) 9.3.0
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # save the attached .config to linux build tree
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-9.3.0 make.cross ARCH=xtensa 

If you fix the issue, kindly add following tag as appropriate
Reported-by: kbuild test robot <lkp@intel.com>

All warnings (new ones prefixed by >>, old ones prefixed by <<):

In file included from include/linux/err.h:5,
from include/linux/clk.h:12,
from drivers/spi/spi-cadence-quadspi.c:9:
include/linux/scatterlist.h: In function 'sg_set_buf':
arch/xtensa/include/asm/page.h:193:9: warning: comparison of unsigned expression >= 0 is always true [-Wtype-limits]
193 |  ((pfn) >= ARCH_PFN_OFFSET && ((pfn) - ARCH_PFN_OFFSET) < max_mapnr)
|         ^~
include/linux/compiler.h:78:42: note: in definition of macro 'unlikely'
78 | # define unlikely(x) __builtin_expect(!!(x), 0)
|                                          ^
include/linux/scatterlist.h:143:2: note: in expansion of macro 'BUG_ON'
143 |  BUG_ON(!virt_addr_valid(buf));
|  ^~~~~~
arch/xtensa/include/asm/page.h:201:32: note: in expansion of macro 'pfn_valid'
201 | #define virt_addr_valid(kaddr) pfn_valid(__pa(kaddr) >> PAGE_SHIFT)
|                                ^~~~~~~~~
include/linux/scatterlist.h:143:10: note: in expansion of macro 'virt_addr_valid'
143 |  BUG_ON(!virt_addr_valid(buf));
|          ^~~~~~~~~~~~~~~
In file included from ./arch/xtensa/include/generated/asm/bug.h:1,
from include/linux/bug.h:5,
from include/linux/thread_info.h:12,
from arch/xtensa/include/asm/current.h:18,
from include/linux/mutex.h:14,
from include/linux/notifier.h:14,
from include/linux/clk.h:14,
from drivers/spi/spi-cadence-quadspi.c:9:
include/linux/dma-mapping.h: In function 'dma_map_resource':
arch/xtensa/include/asm/page.h:193:9: warning: comparison of unsigned expression >= 0 is always true [-Wtype-limits]
193 |  ((pfn) >= ARCH_PFN_OFFSET && ((pfn) - ARCH_PFN_OFFSET) < max_mapnr)
|         ^~
include/asm-generic/bug.h:139:27: note: in definition of macro 'WARN_ON_ONCE'
139 |  int __ret_warn_once = !!(condition);            |                           ^~~~~~~~~
include/linux/dma-mapping.h:352:19: note: in expansion of macro 'pfn_valid'
352 |  if (WARN_ON_ONCE(pfn_valid(PHYS_PFN(phys_addr))))
|                   ^~~~~~~~~
In file included from include/linux/shm.h:6,
from include/linux/sched.h:16,
from include/linux/ratelimit.h:6,
from include/linux/dev_printk.h:16,
from include/linux/device.h:15,
from include/linux/dma-mapping.h:7,
from drivers/spi/spi-cadence-quadspi.c:12:
drivers/spi/spi-cadence-quadspi.c: In function 'cqspi_direct_read_execute':
arch/xtensa/include/asm/page.h:193:9: warning: comparison of unsigned expression >= 0 is always true [-Wtype-limits]
193 |  ((pfn) >= ARCH_PFN_OFFSET && ((pfn) - ARCH_PFN_OFFSET) < max_mapnr)
|         ^~
arch/xtensa/include/asm/page.h:201:32: note: in expansion of macro 'pfn_valid'
201 | #define virt_addr_valid(kaddr) pfn_valid(__pa(kaddr) >> PAGE_SHIFT)
|                                ^~~~~~~~~
>> drivers/spi/spi-cadence-quadspi.c:911:26: note: in expansion of macro 'virt_addr_valid'
911 |  if (!cqspi->rx_chan || !virt_addr_valid(buf)) {
|                          ^~~~~~~~~~~~~~~

vim +/virt_addr_valid +911 drivers/spi/spi-cadence-quadspi.c

ffa639e069fb55 drivers/mtd/spi-nor/cadence-quadspi.c             Vignesh R                  2018-04-10  898  
d467c948c5d40f drivers/mtd/spi-nor/controllers/cadence-quadspi.c Ramuthevar Vadivel Murugan 2020-05-26  899  static int cqspi_direct_read_execute(struct cqspi_flash_pdata *f_pdata,
d467c948c5d40f drivers/mtd/spi-nor/controllers/cadence-quadspi.c Ramuthevar Vadivel Murugan 2020-05-26  900  				     u_char *buf, loff_t from, size_t len)
ffa639e069fb55 drivers/mtd/spi-nor/cadence-quadspi.c             Vignesh R                  2018-04-10  901  {
ffa639e069fb55 drivers/mtd/spi-nor/cadence-quadspi.c             Vignesh R                  2018-04-10  902  	struct cqspi_st *cqspi = f_pdata->cqspi;
d467c948c5d40f drivers/mtd/spi-nor/controllers/cadence-quadspi.c Ramuthevar Vadivel Murugan 2020-05-26  903  	struct device *dev = &cqspi->pdev->dev;
ffa639e069fb55 drivers/mtd/spi-nor/cadence-quadspi.c             Vignesh R                  2018-04-10  904  	enum dma_ctrl_flags flags = DMA_CTRL_ACK | DMA_PREP_INTERRUPT;
ffa639e069fb55 drivers/mtd/spi-nor/cadence-quadspi.c             Vignesh R                  2018-04-10  905  	dma_addr_t dma_src = (dma_addr_t)cqspi->mmap_phys_base + from;
ffa639e069fb55 drivers/mtd/spi-nor/cadence-quadspi.c             Vignesh R                  2018-04-10  906  	int ret = 0;
ffa639e069fb55 drivers/mtd/spi-nor/cadence-quadspi.c             Vignesh R                  2018-04-10  907  	struct dma_async_tx_descriptor *tx;
ffa639e069fb55 drivers/mtd/spi-nor/cadence-quadspi.c             Vignesh R                  2018-04-10  908  	dma_cookie_t cookie;
ffa639e069fb55 drivers/mtd/spi-nor/cadence-quadspi.c             Vignesh R                  2018-04-10  909  	dma_addr_t dma_dst;
ffa639e069fb55 drivers/mtd/spi-nor/cadence-quadspi.c             Vignesh R                  2018-04-10  910  
ffa639e069fb55 drivers/mtd/spi-nor/cadence-quadspi.c             Vignesh R                  2018-04-10 @911  	if (!cqspi->rx_chan || !virt_addr_valid(buf)) {
ffa639e069fb55 drivers/mtd/spi-nor/cadence-quadspi.c             Vignesh R                  2018-04-10  912  		memcpy_fromio(buf, cqspi->ahb_base + from, len);
ffa639e069fb55 drivers/mtd/spi-nor/cadence-quadspi.c             Vignesh R                  2018-04-10  913  		return 0;
ffa639e069fb55 drivers/mtd/spi-nor/cadence-quadspi.c             Vignesh R                  2018-04-10  914  	}
ffa639e069fb55 drivers/mtd/spi-nor/cadence-quadspi.c             Vignesh R                  2018-04-10  915  
d467c948c5d40f drivers/mtd/spi-nor/controllers/cadence-quadspi.c Ramuthevar Vadivel Murugan 2020-05-26  916  	dma_dst = dma_map_single(dev, buf, len, DMA_FROM_DEVICE);
d467c948c5d40f drivers/mtd/spi-nor/controllers/cadence-quadspi.c Ramuthevar Vadivel Murugan 2020-05-26  917  	if (dma_mapping_error(dev, dma_dst)) {
d467c948c5d40f drivers/mtd/spi-nor/controllers/cadence-quadspi.c Ramuthevar Vadivel Murugan 2020-05-26  918  		dev_err(dev, "dma mapping failed\n");
ffa639e069fb55 drivers/mtd/spi-nor/cadence-quadspi.c             Vignesh R                  2018-04-10  919  		return -ENOMEM;
ffa639e069fb55 drivers/mtd/spi-nor/cadence-quadspi.c             Vignesh R                  2018-04-10  920  	}
ffa639e069fb55 drivers/mtd/spi-nor/cadence-quadspi.c             Vignesh R                  2018-04-10  921  	tx = dmaengine_prep_dma_memcpy(cqspi->rx_chan, dma_dst, dma_src,
ffa639e069fb55 drivers/mtd/spi-nor/cadence-quadspi.c             Vignesh R                  2018-04-10  922  				       len, flags);
ffa639e069fb55 drivers/mtd/spi-nor/cadence-quadspi.c             Vignesh R                  2018-04-10  923  	if (!tx) {
d467c948c5d40f drivers/mtd/spi-nor/controllers/cadence-quadspi.c Ramuthevar Vadivel Murugan 2020-05-26  924  		dev_err(dev, "device_prep_dma_memcpy error\n");
ffa639e069fb55 drivers/mtd/spi-nor/cadence-quadspi.c             Vignesh R                  2018-04-10  925  		ret = -EIO;
ffa639e069fb55 drivers/mtd/spi-nor/cadence-quadspi.c             Vignesh R                  2018-04-10  926  		goto err_unmap;
ffa639e069fb55 drivers/mtd/spi-nor/cadence-quadspi.c             Vignesh R                  2018-04-10  927  	}
ffa639e069fb55 drivers/mtd/spi-nor/cadence-quadspi.c             Vignesh R                  2018-04-10  928  
ffa639e069fb55 drivers/mtd/spi-nor/cadence-quadspi.c             Vignesh R                  2018-04-10  929  	tx->callback = cqspi_rx_dma_callback;
ffa639e069fb55 drivers/mtd/spi-nor/cadence-quadspi.c             Vignesh R                  2018-04-10  930  	tx->callback_param = cqspi;
ffa639e069fb55 drivers/mtd/spi-nor/cadence-quadspi.c             Vignesh R                  2018-04-10  931  	cookie = tx->tx_submit(tx);
ffa639e069fb55 drivers/mtd/spi-nor/cadence-quadspi.c             Vignesh R                  2018-04-10  932  	reinit_completion(&cqspi->rx_dma_complete);
ffa639e069fb55 drivers/mtd/spi-nor/cadence-quadspi.c             Vignesh R                  2018-04-10  933  
ffa639e069fb55 drivers/mtd/spi-nor/cadence-quadspi.c             Vignesh R                  2018-04-10  934  	ret = dma_submit_error(cookie);
ffa639e069fb55 drivers/mtd/spi-nor/cadence-quadspi.c             Vignesh R                  2018-04-10  935  	if (ret) {
d467c948c5d40f drivers/mtd/spi-nor/controllers/cadence-quadspi.c Ramuthevar Vadivel Murugan 2020-05-26  936  		dev_err(dev, "dma_submit_error %d\n", cookie);
ffa639e069fb55 drivers/mtd/spi-nor/cadence-quadspi.c             Vignesh R                  2018-04-10  937  		ret = -EIO;
ffa639e069fb55 drivers/mtd/spi-nor/cadence-quadspi.c             Vignesh R                  2018-04-10  938  		goto err_unmap;
ffa639e069fb55 drivers/mtd/spi-nor/cadence-quadspi.c             Vignesh R                  2018-04-10  939  	}
ffa639e069fb55 drivers/mtd/spi-nor/cadence-quadspi.c             Vignesh R                  2018-04-10  940  
ffa639e069fb55 drivers/mtd/spi-nor/cadence-quadspi.c             Vignesh R                  2018-04-10  941  	dma_async_issue_pending(cqspi->rx_chan);
3938c0d4cf6047 drivers/mtd/spi-nor/cadence-quadspi.c             Nicholas Mc Guire          2018-07-21  942  	if (!wait_for_completion_timeout(&cqspi->rx_dma_complete,
3938c0d4cf6047 drivers/mtd/spi-nor/cadence-quadspi.c             Nicholas Mc Guire          2018-07-21  943  					 msecs_to_jiffies(len))) {
ffa639e069fb55 drivers/mtd/spi-nor/cadence-quadspi.c             Vignesh R                  2018-04-10  944  		dmaengine_terminate_sync(cqspi->rx_chan);
d467c948c5d40f drivers/mtd/spi-nor/controllers/cadence-quadspi.c Ramuthevar Vadivel Murugan 2020-05-26  945  		dev_err(dev, "DMA wait_for_completion_timeout\n");
ffa639e069fb55 drivers/mtd/spi-nor/cadence-quadspi.c             Vignesh R                  2018-04-10  946  		ret = -ETIMEDOUT;
ffa639e069fb55 drivers/mtd/spi-nor/cadence-quadspi.c             Vignesh R                  2018-04-10  947  		goto err_unmap;
ffa639e069fb55 drivers/mtd/spi-nor/cadence-quadspi.c             Vignesh R                  2018-04-10  948  	}
ffa639e069fb55 drivers/mtd/spi-nor/cadence-quadspi.c             Vignesh R                  2018-04-10  949  
ffa639e069fb55 drivers/mtd/spi-nor/cadence-quadspi.c             Vignesh R                  2018-04-10  950  err_unmap:
d467c948c5d40f drivers/mtd/spi-nor/controllers/cadence-quadspi.c Ramuthevar Vadivel Murugan 2020-05-26  951  	dma_unmap_single(dev, dma_dst, len, DMA_FROM_DEVICE);
ffa639e069fb55 drivers/mtd/spi-nor/cadence-quadspi.c             Vignesh R                  2018-04-10  952  
91d7b67000c6e9 drivers/mtd/spi-nor/cadence-quadspi.c             Christophe JAILLET         2018-10-16  953  	return ret;
ffa639e069fb55 drivers/mtd/spi-nor/cadence-quadspi.c             Vignesh R                  2018-04-10  954  }
ffa639e069fb55 drivers/mtd/spi-nor/cadence-quadspi.c             Vignesh R                  2018-04-10  955  

:::::: The code at line 911 was first introduced by commit
:::::: ffa639e069fb55a150a2f14af6762b2c429e6d50 mtd: spi-nor: cadence-quadspi: Add DMA support for direct mode reads

:::::: TO: Vignesh R <vigneshr@ti.com>
:::::: CC: Boris Brezillon <boris.brezillon@bootlin.com>

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org

[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 62791 bytes --]

[-- Attachment #3: Type: text/plain, Size: 144 bytes --]

______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/

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

* Re: [PATCH v2 6/6] spi: Move cadence-quadspi driver to drivers/spi/
@ 2020-05-27 20:58     ` kbuild test robot
  0 siblings, 0 replies; 36+ messages in thread
From: kbuild test robot @ 2020-05-27 20:58 UTC (permalink / raw)
  To: kbuild-all

[-- Attachment #1: Type: text/plain, Size: 12531 bytes --]

Hi Vignesh,

Thank you for the patch! Perhaps something to improve:

[auto build test WARNING on spi/for-next]
[also build test WARNING on linus/master v5.7-rc7 next-20200526]
[cannot apply to mtd/master]
[if your patch is applied to the wrong git tree, please drop us a note to help
improve the system. BTW, we also suggest to use '--base' option to specify the
base tree in git format-patch, please see https://stackoverflow.com/a/37406982]

url:    https://github.com/0day-ci/linux/commits/Vignesh-Raghavendra/mtd-spi-nor-Move-cadence-qaudspi-to-spi-mem-framework/20200526-174159
base:   https://git.kernel.org/pub/scm/linux/kernel/git/broonie/spi.git for-next
config: xtensa-allyesconfig (attached as .config)
compiler: xtensa-linux-gcc (GCC) 9.3.0
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # save the attached .config to linux build tree
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-9.3.0 make.cross ARCH=xtensa 

If you fix the issue, kindly add following tag as appropriate
Reported-by: kbuild test robot <lkp@intel.com>

All warnings (new ones prefixed by >>, old ones prefixed by <<):

In file included from include/linux/err.h:5,
from include/linux/clk.h:12,
from drivers/spi/spi-cadence-quadspi.c:9:
include/linux/scatterlist.h: In function 'sg_set_buf':
arch/xtensa/include/asm/page.h:193:9: warning: comparison of unsigned expression >= 0 is always true [-Wtype-limits]
193 |  ((pfn) >= ARCH_PFN_OFFSET && ((pfn) - ARCH_PFN_OFFSET) < max_mapnr)
|         ^~
include/linux/compiler.h:78:42: note: in definition of macro 'unlikely'
78 | # define unlikely(x) __builtin_expect(!!(x), 0)
|                                          ^
include/linux/scatterlist.h:143:2: note: in expansion of macro 'BUG_ON'
143 |  BUG_ON(!virt_addr_valid(buf));
|  ^~~~~~
arch/xtensa/include/asm/page.h:201:32: note: in expansion of macro 'pfn_valid'
201 | #define virt_addr_valid(kaddr) pfn_valid(__pa(kaddr) >> PAGE_SHIFT)
|                                ^~~~~~~~~
include/linux/scatterlist.h:143:10: note: in expansion of macro 'virt_addr_valid'
143 |  BUG_ON(!virt_addr_valid(buf));
|          ^~~~~~~~~~~~~~~
In file included from ./arch/xtensa/include/generated/asm/bug.h:1,
from include/linux/bug.h:5,
from include/linux/thread_info.h:12,
from arch/xtensa/include/asm/current.h:18,
from include/linux/mutex.h:14,
from include/linux/notifier.h:14,
from include/linux/clk.h:14,
from drivers/spi/spi-cadence-quadspi.c:9:
include/linux/dma-mapping.h: In function 'dma_map_resource':
arch/xtensa/include/asm/page.h:193:9: warning: comparison of unsigned expression >= 0 is always true [-Wtype-limits]
193 |  ((pfn) >= ARCH_PFN_OFFSET && ((pfn) - ARCH_PFN_OFFSET) < max_mapnr)
|         ^~
include/asm-generic/bug.h:139:27: note: in definition of macro 'WARN_ON_ONCE'
139 |  int __ret_warn_once = !!(condition);            |                           ^~~~~~~~~
include/linux/dma-mapping.h:352:19: note: in expansion of macro 'pfn_valid'
352 |  if (WARN_ON_ONCE(pfn_valid(PHYS_PFN(phys_addr))))
|                   ^~~~~~~~~
In file included from include/linux/shm.h:6,
from include/linux/sched.h:16,
from include/linux/ratelimit.h:6,
from include/linux/dev_printk.h:16,
from include/linux/device.h:15,
from include/linux/dma-mapping.h:7,
from drivers/spi/spi-cadence-quadspi.c:12:
drivers/spi/spi-cadence-quadspi.c: In function 'cqspi_direct_read_execute':
arch/xtensa/include/asm/page.h:193:9: warning: comparison of unsigned expression >= 0 is always true [-Wtype-limits]
193 |  ((pfn) >= ARCH_PFN_OFFSET && ((pfn) - ARCH_PFN_OFFSET) < max_mapnr)
|         ^~
arch/xtensa/include/asm/page.h:201:32: note: in expansion of macro 'pfn_valid'
201 | #define virt_addr_valid(kaddr) pfn_valid(__pa(kaddr) >> PAGE_SHIFT)
|                                ^~~~~~~~~
>> drivers/spi/spi-cadence-quadspi.c:911:26: note: in expansion of macro 'virt_addr_valid'
911 |  if (!cqspi->rx_chan || !virt_addr_valid(buf)) {
|                          ^~~~~~~~~~~~~~~

vim +/virt_addr_valid +911 drivers/spi/spi-cadence-quadspi.c

ffa639e069fb55 drivers/mtd/spi-nor/cadence-quadspi.c             Vignesh R                  2018-04-10  898  
d467c948c5d40f drivers/mtd/spi-nor/controllers/cadence-quadspi.c Ramuthevar Vadivel Murugan 2020-05-26  899  static int cqspi_direct_read_execute(struct cqspi_flash_pdata *f_pdata,
d467c948c5d40f drivers/mtd/spi-nor/controllers/cadence-quadspi.c Ramuthevar Vadivel Murugan 2020-05-26  900  				     u_char *buf, loff_t from, size_t len)
ffa639e069fb55 drivers/mtd/spi-nor/cadence-quadspi.c             Vignesh R                  2018-04-10  901  {
ffa639e069fb55 drivers/mtd/spi-nor/cadence-quadspi.c             Vignesh R                  2018-04-10  902  	struct cqspi_st *cqspi = f_pdata->cqspi;
d467c948c5d40f drivers/mtd/spi-nor/controllers/cadence-quadspi.c Ramuthevar Vadivel Murugan 2020-05-26  903  	struct device *dev = &cqspi->pdev->dev;
ffa639e069fb55 drivers/mtd/spi-nor/cadence-quadspi.c             Vignesh R                  2018-04-10  904  	enum dma_ctrl_flags flags = DMA_CTRL_ACK | DMA_PREP_INTERRUPT;
ffa639e069fb55 drivers/mtd/spi-nor/cadence-quadspi.c             Vignesh R                  2018-04-10  905  	dma_addr_t dma_src = (dma_addr_t)cqspi->mmap_phys_base + from;
ffa639e069fb55 drivers/mtd/spi-nor/cadence-quadspi.c             Vignesh R                  2018-04-10  906  	int ret = 0;
ffa639e069fb55 drivers/mtd/spi-nor/cadence-quadspi.c             Vignesh R                  2018-04-10  907  	struct dma_async_tx_descriptor *tx;
ffa639e069fb55 drivers/mtd/spi-nor/cadence-quadspi.c             Vignesh R                  2018-04-10  908  	dma_cookie_t cookie;
ffa639e069fb55 drivers/mtd/spi-nor/cadence-quadspi.c             Vignesh R                  2018-04-10  909  	dma_addr_t dma_dst;
ffa639e069fb55 drivers/mtd/spi-nor/cadence-quadspi.c             Vignesh R                  2018-04-10  910  
ffa639e069fb55 drivers/mtd/spi-nor/cadence-quadspi.c             Vignesh R                  2018-04-10 @911  	if (!cqspi->rx_chan || !virt_addr_valid(buf)) {
ffa639e069fb55 drivers/mtd/spi-nor/cadence-quadspi.c             Vignesh R                  2018-04-10  912  		memcpy_fromio(buf, cqspi->ahb_base + from, len);
ffa639e069fb55 drivers/mtd/spi-nor/cadence-quadspi.c             Vignesh R                  2018-04-10  913  		return 0;
ffa639e069fb55 drivers/mtd/spi-nor/cadence-quadspi.c             Vignesh R                  2018-04-10  914  	}
ffa639e069fb55 drivers/mtd/spi-nor/cadence-quadspi.c             Vignesh R                  2018-04-10  915  
d467c948c5d40f drivers/mtd/spi-nor/controllers/cadence-quadspi.c Ramuthevar Vadivel Murugan 2020-05-26  916  	dma_dst = dma_map_single(dev, buf, len, DMA_FROM_DEVICE);
d467c948c5d40f drivers/mtd/spi-nor/controllers/cadence-quadspi.c Ramuthevar Vadivel Murugan 2020-05-26  917  	if (dma_mapping_error(dev, dma_dst)) {
d467c948c5d40f drivers/mtd/spi-nor/controllers/cadence-quadspi.c Ramuthevar Vadivel Murugan 2020-05-26  918  		dev_err(dev, "dma mapping failed\n");
ffa639e069fb55 drivers/mtd/spi-nor/cadence-quadspi.c             Vignesh R                  2018-04-10  919  		return -ENOMEM;
ffa639e069fb55 drivers/mtd/spi-nor/cadence-quadspi.c             Vignesh R                  2018-04-10  920  	}
ffa639e069fb55 drivers/mtd/spi-nor/cadence-quadspi.c             Vignesh R                  2018-04-10  921  	tx = dmaengine_prep_dma_memcpy(cqspi->rx_chan, dma_dst, dma_src,
ffa639e069fb55 drivers/mtd/spi-nor/cadence-quadspi.c             Vignesh R                  2018-04-10  922  				       len, flags);
ffa639e069fb55 drivers/mtd/spi-nor/cadence-quadspi.c             Vignesh R                  2018-04-10  923  	if (!tx) {
d467c948c5d40f drivers/mtd/spi-nor/controllers/cadence-quadspi.c Ramuthevar Vadivel Murugan 2020-05-26  924  		dev_err(dev, "device_prep_dma_memcpy error\n");
ffa639e069fb55 drivers/mtd/spi-nor/cadence-quadspi.c             Vignesh R                  2018-04-10  925  		ret = -EIO;
ffa639e069fb55 drivers/mtd/spi-nor/cadence-quadspi.c             Vignesh R                  2018-04-10  926  		goto err_unmap;
ffa639e069fb55 drivers/mtd/spi-nor/cadence-quadspi.c             Vignesh R                  2018-04-10  927  	}
ffa639e069fb55 drivers/mtd/spi-nor/cadence-quadspi.c             Vignesh R                  2018-04-10  928  
ffa639e069fb55 drivers/mtd/spi-nor/cadence-quadspi.c             Vignesh R                  2018-04-10  929  	tx->callback = cqspi_rx_dma_callback;
ffa639e069fb55 drivers/mtd/spi-nor/cadence-quadspi.c             Vignesh R                  2018-04-10  930  	tx->callback_param = cqspi;
ffa639e069fb55 drivers/mtd/spi-nor/cadence-quadspi.c             Vignesh R                  2018-04-10  931  	cookie = tx->tx_submit(tx);
ffa639e069fb55 drivers/mtd/spi-nor/cadence-quadspi.c             Vignesh R                  2018-04-10  932  	reinit_completion(&cqspi->rx_dma_complete);
ffa639e069fb55 drivers/mtd/spi-nor/cadence-quadspi.c             Vignesh R                  2018-04-10  933  
ffa639e069fb55 drivers/mtd/spi-nor/cadence-quadspi.c             Vignesh R                  2018-04-10  934  	ret = dma_submit_error(cookie);
ffa639e069fb55 drivers/mtd/spi-nor/cadence-quadspi.c             Vignesh R                  2018-04-10  935  	if (ret) {
d467c948c5d40f drivers/mtd/spi-nor/controllers/cadence-quadspi.c Ramuthevar Vadivel Murugan 2020-05-26  936  		dev_err(dev, "dma_submit_error %d\n", cookie);
ffa639e069fb55 drivers/mtd/spi-nor/cadence-quadspi.c             Vignesh R                  2018-04-10  937  		ret = -EIO;
ffa639e069fb55 drivers/mtd/spi-nor/cadence-quadspi.c             Vignesh R                  2018-04-10  938  		goto err_unmap;
ffa639e069fb55 drivers/mtd/spi-nor/cadence-quadspi.c             Vignesh R                  2018-04-10  939  	}
ffa639e069fb55 drivers/mtd/spi-nor/cadence-quadspi.c             Vignesh R                  2018-04-10  940  
ffa639e069fb55 drivers/mtd/spi-nor/cadence-quadspi.c             Vignesh R                  2018-04-10  941  	dma_async_issue_pending(cqspi->rx_chan);
3938c0d4cf6047 drivers/mtd/spi-nor/cadence-quadspi.c             Nicholas Mc Guire          2018-07-21  942  	if (!wait_for_completion_timeout(&cqspi->rx_dma_complete,
3938c0d4cf6047 drivers/mtd/spi-nor/cadence-quadspi.c             Nicholas Mc Guire          2018-07-21  943  					 msecs_to_jiffies(len))) {
ffa639e069fb55 drivers/mtd/spi-nor/cadence-quadspi.c             Vignesh R                  2018-04-10  944  		dmaengine_terminate_sync(cqspi->rx_chan);
d467c948c5d40f drivers/mtd/spi-nor/controllers/cadence-quadspi.c Ramuthevar Vadivel Murugan 2020-05-26  945  		dev_err(dev, "DMA wait_for_completion_timeout\n");
ffa639e069fb55 drivers/mtd/spi-nor/cadence-quadspi.c             Vignesh R                  2018-04-10  946  		ret = -ETIMEDOUT;
ffa639e069fb55 drivers/mtd/spi-nor/cadence-quadspi.c             Vignesh R                  2018-04-10  947  		goto err_unmap;
ffa639e069fb55 drivers/mtd/spi-nor/cadence-quadspi.c             Vignesh R                  2018-04-10  948  	}
ffa639e069fb55 drivers/mtd/spi-nor/cadence-quadspi.c             Vignesh R                  2018-04-10  949  
ffa639e069fb55 drivers/mtd/spi-nor/cadence-quadspi.c             Vignesh R                  2018-04-10  950  err_unmap:
d467c948c5d40f drivers/mtd/spi-nor/controllers/cadence-quadspi.c Ramuthevar Vadivel Murugan 2020-05-26  951  	dma_unmap_single(dev, dma_dst, len, DMA_FROM_DEVICE);
ffa639e069fb55 drivers/mtd/spi-nor/cadence-quadspi.c             Vignesh R                  2018-04-10  952  
91d7b67000c6e9 drivers/mtd/spi-nor/cadence-quadspi.c             Christophe JAILLET         2018-10-16  953  	return ret;
ffa639e069fb55 drivers/mtd/spi-nor/cadence-quadspi.c             Vignesh R                  2018-04-10  954  }
ffa639e069fb55 drivers/mtd/spi-nor/cadence-quadspi.c             Vignesh R                  2018-04-10  955  

:::::: The code at line 911 was first introduced by commit
:::::: ffa639e069fb55a150a2f14af6762b2c429e6d50 mtd: spi-nor: cadence-quadspi: Add DMA support for direct mode reads

:::::: TO: Vignesh R <vigneshr@ti.com>
:::::: CC: Boris Brezillon <boris.brezillon@bootlin.com>

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all(a)lists.01.org

[-- Attachment #2: config.gz --]
[-- Type: application/gzip, Size: 62791 bytes --]

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

* Re: [PATCH v2 6/6] spi: Move cadence-quadspi driver to drivers/spi/
  2020-05-27 20:58     ` kbuild test robot
  (?)
@ 2020-05-28  9:54       ` Vignesh Raghavendra
  -1 siblings, 0 replies; 36+ messages in thread
From: Vignesh Raghavendra @ 2020-05-28  9:54 UTC (permalink / raw)
  To: kbuild test robot, Tudor Ambarus, Mark Brown
  Cc: kbuild-all, Boris Brezillon, Ramuthevar Vadivel Murugan,
	linux-mtd, linux-kernel, linux-spi, simon.k.r.goldschmidt,
	dinguyen, marex

Hi,

On 28/05/20 2:28 am, kbuild test robot wrote:
> Hi Vignesh,
> 
[...]
> 
> In file included from include/linux/err.h:5,
> from include/linux/clk.h:12,
> from drivers/spi/spi-cadence-quadspi.c:9:
> include/linux/scatterlist.h: In function 'sg_set_buf':
> arch/xtensa/include/asm/page.h:193:9: warning: comparison of unsigned expression >= 0 is always true [-Wtype-limits]
> 193 |  ((pfn) >= ARCH_PFN_OFFSET && ((pfn) - ARCH_PFN_OFFSET) < max_mapnr)
> |         ^~
> include/linux/compiler.h:78:42: note: in definition of macro 'unlikely'
> 78 | # define unlikely(x) __builtin_expect(!!(x), 0)
> |                                          ^
> include/linux/scatterlist.h:143:2: note: in expansion of macro 'BUG_ON'
> 143 |  BUG_ON(!virt_addr_valid(buf));
> |  ^~~~~~
> arch/xtensa/include/asm/page.h:201:32: note: in expansion of macro 'pfn_valid'
> 201 | #define virt_addr_valid(kaddr) pfn_valid(__pa(kaddr) >> PAGE_SHIFT)
> |                                ^~~~~~~~~
> include/linux/scatterlist.h:143:10: note: in expansion of macro 'virt_addr_valid'
> 143 |  BUG_ON(!virt_addr_valid(buf));
> |          ^~~~~~~~~~~~~~~
> In file included from ./arch/xtensa/include/generated/asm/bug.h:1,
> from include/linux/bug.h:5,
> from include/linux/thread_info.h:12,
> from arch/xtensa/include/asm/current.h:18,
> from include/linux/mutex.h:14,
> from include/linux/notifier.h:14,
> from include/linux/clk.h:14,
> from drivers/spi/spi-cadence-quadspi.c:9:
> include/linux/dma-mapping.h: In function 'dma_map_resource':
> arch/xtensa/include/asm/page.h:193:9: warning: comparison of unsigned expression >= 0 is always true [-Wtype-limits]
> 193 |  ((pfn) >= ARCH_PFN_OFFSET && ((pfn) - ARCH_PFN_OFFSET) < max_mapnr)
> |         ^~
> include/asm-generic/bug.h:139:27: note: in definition of macro 'WARN_ON_ONCE'
> 139 |  int __ret_warn_once = !!(condition);            |                           ^~~~~~~~~
> include/linux/dma-mapping.h:352:19: note: in expansion of macro 'pfn_valid'
> 352 |  if (WARN_ON_ONCE(pfn_valid(PHYS_PFN(phys_addr))))
> |                   ^~~~~~~~~
> In file included from include/linux/shm.h:6,
> from include/linux/sched.h:16,
> from include/linux/ratelimit.h:6,
> from include/linux/dev_printk.h:16,
> from include/linux/device.h:15,
> from include/linux/dma-mapping.h:7,
> from drivers/spi/spi-cadence-quadspi.c:12:
> drivers/spi/spi-cadence-quadspi.c: In function 'cqspi_direct_read_execute':
> arch/xtensa/include/asm/page.h:193:9: warning: comparison of unsigned expression >= 0 is always true [-Wtype-limits]
> 193 |  ((pfn) >= ARCH_PFN_OFFSET && ((pfn) - ARCH_PFN_OFFSET) < max_mapnr)
> |         ^~
> arch/xtensa/include/asm/page.h:201:32: note: in expansion of macro 'pfn_valid'
> 201 | #define virt_addr_valid(kaddr) pfn_valid(__pa(kaddr) >> PAGE_SHIFT)
> |                                ^~~~~~~~~
>>> drivers/spi/spi-cadence-quadspi.c:911:26: note: in expansion of macro 'virt_addr_valid'
> 911 |  if (!cqspi->rx_chan || !virt_addr_valid(buf)) {
> |                          ^~~~~~~~~~~~~~~


Thanks for the report! But it seems with ARCH=xtensa and config that was
attached, I see above warning for every file in the kernel that uses
virt_addr_valid(), So, the fix for this warning is really in xtensa arch
code and therefore should not block this series from being merged.


Regards
Vignesh

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

* Re: [PATCH v2 6/6] spi: Move cadence-quadspi driver to drivers/spi/
@ 2020-05-28  9:54       ` Vignesh Raghavendra
  0 siblings, 0 replies; 36+ messages in thread
From: Vignesh Raghavendra @ 2020-05-28  9:54 UTC (permalink / raw)
  To: kbuild test robot, Tudor Ambarus, Mark Brown
  Cc: marex, kbuild-all, Boris Brezillon, dinguyen,
	simon.k.r.goldschmidt, linux-kernel, linux-spi,
	Ramuthevar Vadivel Murugan, linux-mtd

Hi,

On 28/05/20 2:28 am, kbuild test robot wrote:
> Hi Vignesh,
> 
[...]
> 
> In file included from include/linux/err.h:5,
> from include/linux/clk.h:12,
> from drivers/spi/spi-cadence-quadspi.c:9:
> include/linux/scatterlist.h: In function 'sg_set_buf':
> arch/xtensa/include/asm/page.h:193:9: warning: comparison of unsigned expression >= 0 is always true [-Wtype-limits]
> 193 |  ((pfn) >= ARCH_PFN_OFFSET && ((pfn) - ARCH_PFN_OFFSET) < max_mapnr)
> |         ^~
> include/linux/compiler.h:78:42: note: in definition of macro 'unlikely'
> 78 | # define unlikely(x) __builtin_expect(!!(x), 0)
> |                                          ^
> include/linux/scatterlist.h:143:2: note: in expansion of macro 'BUG_ON'
> 143 |  BUG_ON(!virt_addr_valid(buf));
> |  ^~~~~~
> arch/xtensa/include/asm/page.h:201:32: note: in expansion of macro 'pfn_valid'
> 201 | #define virt_addr_valid(kaddr) pfn_valid(__pa(kaddr) >> PAGE_SHIFT)
> |                                ^~~~~~~~~
> include/linux/scatterlist.h:143:10: note: in expansion of macro 'virt_addr_valid'
> 143 |  BUG_ON(!virt_addr_valid(buf));
> |          ^~~~~~~~~~~~~~~
> In file included from ./arch/xtensa/include/generated/asm/bug.h:1,
> from include/linux/bug.h:5,
> from include/linux/thread_info.h:12,
> from arch/xtensa/include/asm/current.h:18,
> from include/linux/mutex.h:14,
> from include/linux/notifier.h:14,
> from include/linux/clk.h:14,
> from drivers/spi/spi-cadence-quadspi.c:9:
> include/linux/dma-mapping.h: In function 'dma_map_resource':
> arch/xtensa/include/asm/page.h:193:9: warning: comparison of unsigned expression >= 0 is always true [-Wtype-limits]
> 193 |  ((pfn) >= ARCH_PFN_OFFSET && ((pfn) - ARCH_PFN_OFFSET) < max_mapnr)
> |         ^~
> include/asm-generic/bug.h:139:27: note: in definition of macro 'WARN_ON_ONCE'
> 139 |  int __ret_warn_once = !!(condition);            |                           ^~~~~~~~~
> include/linux/dma-mapping.h:352:19: note: in expansion of macro 'pfn_valid'
> 352 |  if (WARN_ON_ONCE(pfn_valid(PHYS_PFN(phys_addr))))
> |                   ^~~~~~~~~
> In file included from include/linux/shm.h:6,
> from include/linux/sched.h:16,
> from include/linux/ratelimit.h:6,
> from include/linux/dev_printk.h:16,
> from include/linux/device.h:15,
> from include/linux/dma-mapping.h:7,
> from drivers/spi/spi-cadence-quadspi.c:12:
> drivers/spi/spi-cadence-quadspi.c: In function 'cqspi_direct_read_execute':
> arch/xtensa/include/asm/page.h:193:9: warning: comparison of unsigned expression >= 0 is always true [-Wtype-limits]
> 193 |  ((pfn) >= ARCH_PFN_OFFSET && ((pfn) - ARCH_PFN_OFFSET) < max_mapnr)
> |         ^~
> arch/xtensa/include/asm/page.h:201:32: note: in expansion of macro 'pfn_valid'
> 201 | #define virt_addr_valid(kaddr) pfn_valid(__pa(kaddr) >> PAGE_SHIFT)
> |                                ^~~~~~~~~
>>> drivers/spi/spi-cadence-quadspi.c:911:26: note: in expansion of macro 'virt_addr_valid'
> 911 |  if (!cqspi->rx_chan || !virt_addr_valid(buf)) {
> |                          ^~~~~~~~~~~~~~~


Thanks for the report! But it seems with ARCH=xtensa and config that was
attached, I see above warning for every file in the kernel that uses
virt_addr_valid(), So, the fix for this warning is really in xtensa arch
code and therefore should not block this series from being merged.


Regards
Vignesh

______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/

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

* Re: [PATCH v2 6/6] spi: Move cadence-quadspi driver to drivers/spi/
@ 2020-05-28  9:54       ` Vignesh Raghavendra
  0 siblings, 0 replies; 36+ messages in thread
From: Vignesh Raghavendra @ 2020-05-28  9:54 UTC (permalink / raw)
  To: kbuild-all

[-- Attachment #1: Type: text/plain, Size: 3395 bytes --]

Hi,

On 28/05/20 2:28 am, kbuild test robot wrote:
> Hi Vignesh,
> 
[...]
> 
> In file included from include/linux/err.h:5,
> from include/linux/clk.h:12,
> from drivers/spi/spi-cadence-quadspi.c:9:
> include/linux/scatterlist.h: In function 'sg_set_buf':
> arch/xtensa/include/asm/page.h:193:9: warning: comparison of unsigned expression >= 0 is always true [-Wtype-limits]
> 193 |  ((pfn) >= ARCH_PFN_OFFSET && ((pfn) - ARCH_PFN_OFFSET) < max_mapnr)
> |         ^~
> include/linux/compiler.h:78:42: note: in definition of macro 'unlikely'
> 78 | # define unlikely(x) __builtin_expect(!!(x), 0)
> |                                          ^
> include/linux/scatterlist.h:143:2: note: in expansion of macro 'BUG_ON'
> 143 |  BUG_ON(!virt_addr_valid(buf));
> |  ^~~~~~
> arch/xtensa/include/asm/page.h:201:32: note: in expansion of macro 'pfn_valid'
> 201 | #define virt_addr_valid(kaddr) pfn_valid(__pa(kaddr) >> PAGE_SHIFT)
> |                                ^~~~~~~~~
> include/linux/scatterlist.h:143:10: note: in expansion of macro 'virt_addr_valid'
> 143 |  BUG_ON(!virt_addr_valid(buf));
> |          ^~~~~~~~~~~~~~~
> In file included from ./arch/xtensa/include/generated/asm/bug.h:1,
> from include/linux/bug.h:5,
> from include/linux/thread_info.h:12,
> from arch/xtensa/include/asm/current.h:18,
> from include/linux/mutex.h:14,
> from include/linux/notifier.h:14,
> from include/linux/clk.h:14,
> from drivers/spi/spi-cadence-quadspi.c:9:
> include/linux/dma-mapping.h: In function 'dma_map_resource':
> arch/xtensa/include/asm/page.h:193:9: warning: comparison of unsigned expression >= 0 is always true [-Wtype-limits]
> 193 |  ((pfn) >= ARCH_PFN_OFFSET && ((pfn) - ARCH_PFN_OFFSET) < max_mapnr)
> |         ^~
> include/asm-generic/bug.h:139:27: note: in definition of macro 'WARN_ON_ONCE'
> 139 |  int __ret_warn_once = !!(condition);            |                           ^~~~~~~~~
> include/linux/dma-mapping.h:352:19: note: in expansion of macro 'pfn_valid'
> 352 |  if (WARN_ON_ONCE(pfn_valid(PHYS_PFN(phys_addr))))
> |                   ^~~~~~~~~
> In file included from include/linux/shm.h:6,
> from include/linux/sched.h:16,
> from include/linux/ratelimit.h:6,
> from include/linux/dev_printk.h:16,
> from include/linux/device.h:15,
> from include/linux/dma-mapping.h:7,
> from drivers/spi/spi-cadence-quadspi.c:12:
> drivers/spi/spi-cadence-quadspi.c: In function 'cqspi_direct_read_execute':
> arch/xtensa/include/asm/page.h:193:9: warning: comparison of unsigned expression >= 0 is always true [-Wtype-limits]
> 193 |  ((pfn) >= ARCH_PFN_OFFSET && ((pfn) - ARCH_PFN_OFFSET) < max_mapnr)
> |         ^~
> arch/xtensa/include/asm/page.h:201:32: note: in expansion of macro 'pfn_valid'
> 201 | #define virt_addr_valid(kaddr) pfn_valid(__pa(kaddr) >> PAGE_SHIFT)
> |                                ^~~~~~~~~
>>> drivers/spi/spi-cadence-quadspi.c:911:26: note: in expansion of macro 'virt_addr_valid'
> 911 |  if (!cqspi->rx_chan || !virt_addr_valid(buf)) {
> |                          ^~~~~~~~~~~~~~~


Thanks for the report! But it seems with ARCH=xtensa and config that was
attached, I see above warning for every file in the kernel that uses
virt_addr_valid(), So, the fix for this warning is really in xtensa arch
code and therefore should not block this series from being merged.


Regards
Vignesh

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

* Re: [PATCH v2 1/6] mtd: spi-nor: cadence-quadspi: Make driver independent of flash geometry
  2020-05-26  9:35   ` Vignesh Raghavendra
@ 2020-05-28 11:41     ` Tudor.Ambarus
  -1 siblings, 0 replies; 36+ messages in thread
From: Tudor.Ambarus @ 2020-05-28 11:41 UTC (permalink / raw)
  To: vigneshr
  Cc: broonie, bbrezillon, vadivel.muruganx.ramuthevar, linux-mtd,
	linux-kernel, linux-spi, simon.k.r.goldschmidt, dinguyen, marex

On Tuesday, May 26, 2020 12:35:59 PM EEST Vignesh Raghavendra wrote:
> Drop configuration of Flash size, erase size and page size
> configuration. Flash size is needed only if using AHB decoder (BIT 23 of
> CONFIG_REG) which is not used by the driver.
> Erase size and page size are needed if IP is configured to send WREN
> automatically. But since SPI NOR layer takes care of sending WREN, there
> is no need to configure these fields either.
> 
> Therefore drop these in preparation to move the driver to spi-mem
> framework where flash geometry is not visible to controller driver.
> 
> Signed-off-by: Vignesh Raghavendra <vigneshr@ti.com>
> ---
>  .../mtd/spi-nor/controllers/cadence-quadspi.c | 36 +------------------
>  1 file changed, 1 insertion(+), 35 deletions(-)

Reviewed-by: Tudor Ambarus <tudor.ambarus@microchip.com>


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

* Re: [PATCH v2 1/6] mtd: spi-nor: cadence-quadspi: Make driver independent of flash geometry
@ 2020-05-28 11:41     ` Tudor.Ambarus
  0 siblings, 0 replies; 36+ messages in thread
From: Tudor.Ambarus @ 2020-05-28 11:41 UTC (permalink / raw)
  To: vigneshr
  Cc: marex, bbrezillon, dinguyen, simon.k.r.goldschmidt, linux-kernel,
	linux-spi, vadivel.muruganx.ramuthevar, broonie, linux-mtd

On Tuesday, May 26, 2020 12:35:59 PM EEST Vignesh Raghavendra wrote:
> Drop configuration of Flash size, erase size and page size
> configuration. Flash size is needed only if using AHB decoder (BIT 23 of
> CONFIG_REG) which is not used by the driver.
> Erase size and page size are needed if IP is configured to send WREN
> automatically. But since SPI NOR layer takes care of sending WREN, there
> is no need to configure these fields either.
> 
> Therefore drop these in preparation to move the driver to spi-mem
> framework where flash geometry is not visible to controller driver.
> 
> Signed-off-by: Vignesh Raghavendra <vigneshr@ti.com>
> ---
>  .../mtd/spi-nor/controllers/cadence-quadspi.c | 36 +------------------
>  1 file changed, 1 insertion(+), 35 deletions(-)

Reviewed-by: Tudor Ambarus <tudor.ambarus@microchip.com>


______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/

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

* Re: [PATCH v2 2/6] mtd: spi-nor: cadence-quadspi: Provide a way to disable DAC mode
  2020-05-26  9:36   ` Vignesh Raghavendra
@ 2020-05-28 18:41     ` Tudor.Ambarus
  -1 siblings, 0 replies; 36+ messages in thread
From: Tudor.Ambarus @ 2020-05-28 18:41 UTC (permalink / raw)
  To: vigneshr
  Cc: broonie, bbrezillon, vadivel.muruganx.ramuthevar, linux-mtd,
	linux-kernel, linux-spi, simon.k.r.goldschmidt, dinguyen, marex

On Tuesday, May 26, 2020 12:36:00 PM EEST Vignesh Raghavendra wrote:
> Currently direct access mode is used on platforms that have AHB window
> (memory mapped window) larger than flash size. This feature is limited
> to TI platforms as non TI platforms have < 1MB of AHB window.
> Therefore introduce a driver quirk to disable DAC mode and set it for
> non TI compatibles. This is in preparation to move to spi-mem framework
> where flash geometry cannot be known.
> 
> Signed-off-by: Vignesh Raghavendra <vigneshr@ti.com>
> ---
>  drivers/mtd/spi-nor/controllers/cadence-quadspi.c | 5 ++++-
>  1 file changed, 4 insertions(+), 1 deletion(-)

Reviewed-by: Tudor Ambarus <tudor.ambarus@microchip.com>


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

* Re: [PATCH v2 2/6] mtd: spi-nor: cadence-quadspi: Provide a way to disable DAC mode
@ 2020-05-28 18:41     ` Tudor.Ambarus
  0 siblings, 0 replies; 36+ messages in thread
From: Tudor.Ambarus @ 2020-05-28 18:41 UTC (permalink / raw)
  To: vigneshr
  Cc: marex, bbrezillon, dinguyen, simon.k.r.goldschmidt, linux-kernel,
	linux-spi, vadivel.muruganx.ramuthevar, broonie, linux-mtd

On Tuesday, May 26, 2020 12:36:00 PM EEST Vignesh Raghavendra wrote:
> Currently direct access mode is used on platforms that have AHB window
> (memory mapped window) larger than flash size. This feature is limited
> to TI platforms as non TI platforms have < 1MB of AHB window.
> Therefore introduce a driver quirk to disable DAC mode and set it for
> non TI compatibles. This is in preparation to move to spi-mem framework
> where flash geometry cannot be known.
> 
> Signed-off-by: Vignesh Raghavendra <vigneshr@ti.com>
> ---
>  drivers/mtd/spi-nor/controllers/cadence-quadspi.c | 5 ++++-
>  1 file changed, 4 insertions(+), 1 deletion(-)

Reviewed-by: Tudor Ambarus <tudor.ambarus@microchip.com>


______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/

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

* Re: [PATCH v2 3/6] mtd: spi-nor: cadence-quadspi: Don't initialize rx_dma_complete on failure
  2020-05-26  9:36   ` Vignesh Raghavendra
@ 2020-05-28 18:42     ` Tudor.Ambarus
  -1 siblings, 0 replies; 36+ messages in thread
From: Tudor.Ambarus @ 2020-05-28 18:42 UTC (permalink / raw)
  To: vigneshr
  Cc: broonie, bbrezillon, vadivel.muruganx.ramuthevar, linux-mtd,
	linux-kernel, linux-spi, simon.k.r.goldschmidt, dinguyen, marex

On Tuesday, May 26, 2020 12:36:01 PM EEST Vignesh Raghavendra wrote:
> If driver fails to acquire DMA channel then don't initialize
> rx_dma_complete struct as it won't be used.
> 
> Signed-off-by: Vignesh Raghavendra <vigneshr@ti.com>
> ---
>  drivers/mtd/spi-nor/controllers/cadence-quadspi.c | 1 +
>  1 file changed, 1 insertion(+)

Reviewed-by: Tudor Ambarus <tudor.ambarus@microchip.com>


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

* Re: [PATCH v2 3/6] mtd: spi-nor: cadence-quadspi: Don't initialize rx_dma_complete on failure
@ 2020-05-28 18:42     ` Tudor.Ambarus
  0 siblings, 0 replies; 36+ messages in thread
From: Tudor.Ambarus @ 2020-05-28 18:42 UTC (permalink / raw)
  To: vigneshr
  Cc: marex, bbrezillon, dinguyen, simon.k.r.goldschmidt, linux-kernel,
	linux-spi, vadivel.muruganx.ramuthevar, broonie, linux-mtd

On Tuesday, May 26, 2020 12:36:01 PM EEST Vignesh Raghavendra wrote:
> If driver fails to acquire DMA channel then don't initialize
> rx_dma_complete struct as it won't be used.
> 
> Signed-off-by: Vignesh Raghavendra <vigneshr@ti.com>
> ---
>  drivers/mtd/spi-nor/controllers/cadence-quadspi.c | 1 +
>  1 file changed, 1 insertion(+)

Reviewed-by: Tudor Ambarus <tudor.ambarus@microchip.com>


______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/

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

* Re: [PATCH v2 4/6] mtd: spi-nor: cadence-quadspi: Fix error path on failure to acquire reset lines
  2020-05-26  9:36   ` Vignesh Raghavendra
@ 2020-05-28 18:46     ` Tudor.Ambarus
  -1 siblings, 0 replies; 36+ messages in thread
From: Tudor.Ambarus @ 2020-05-28 18:46 UTC (permalink / raw)
  To: vigneshr
  Cc: broonie, bbrezillon, vadivel.muruganx.ramuthevar, linux-mtd,
	linux-kernel, linux-spi, simon.k.r.goldschmidt, dinguyen, marex

On Tuesday, May 26, 2020 12:36:02 PM EEST Vignesh Raghavendra wrote:
> Make sure to undo the prior changes done by the driver when exiting due
> to failure to acquire reset lines.
> 
> Signed-off-by: Vignesh Raghavendra <vigneshr@ti.com>
> ---
>  drivers/mtd/spi-nor/controllers/cadence-quadspi.c | 8 ++++----
>  1 file changed, 4 insertions(+), 4 deletions(-)

Reviewed-by: Tudor Ambarus <tudor.ambarus@microchip.com>


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

* Re: [PATCH v2 4/6] mtd: spi-nor: cadence-quadspi: Fix error path on failure to acquire reset lines
@ 2020-05-28 18:46     ` Tudor.Ambarus
  0 siblings, 0 replies; 36+ messages in thread
From: Tudor.Ambarus @ 2020-05-28 18:46 UTC (permalink / raw)
  To: vigneshr
  Cc: marex, bbrezillon, dinguyen, simon.k.r.goldschmidt, linux-kernel,
	linux-spi, vadivel.muruganx.ramuthevar, broonie, linux-mtd

On Tuesday, May 26, 2020 12:36:02 PM EEST Vignesh Raghavendra wrote:
> Make sure to undo the prior changes done by the driver when exiting due
> to failure to acquire reset lines.
> 
> Signed-off-by: Vignesh Raghavendra <vigneshr@ti.com>
> ---
>  drivers/mtd/spi-nor/controllers/cadence-quadspi.c | 8 ++++----
>  1 file changed, 4 insertions(+), 4 deletions(-)

Reviewed-by: Tudor Ambarus <tudor.ambarus@microchip.com>


______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/

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

* Re: [PATCH v2 5/6] mtd: spi-nor: Convert cadence-quadspi to use spi-mem framework
  2020-05-26  9:36   ` Vignesh Raghavendra
@ 2020-05-30 13:50     ` Tudor.Ambarus
  -1 siblings, 0 replies; 36+ messages in thread
From: Tudor.Ambarus @ 2020-05-30 13:50 UTC (permalink / raw)
  To: vigneshr
  Cc: broonie, bbrezillon, vadivel.muruganx.ramuthevar, linux-mtd,
	linux-kernel, linux-spi, simon.k.r.goldschmidt, dinguyen, marex

Hi, Vignesh,

On Tuesday, May 26, 2020 12:36:03 PM EEST Vignesh Raghavendra wrote:
> EXTERNAL EMAIL: Do not click links or open attachments unless you know the
> content is safe
> 
> From: Ramuthevar Vadivel Murugan
> <vadivel.muruganx.ramuthevar@linux.intel.com>
> 
> Move cadence-quadspi driver to use spi-mem framework. This is required
> to make the driver support for SPI NAND flashes in future.
> 
> Driver is feature compliant with existing SPI NOR version.
> 
> Signed-off-by: Ramuthevar Vadivel Murugan
> <vadivel.muruganx.ramuthevar@linux.intel.com> Signed-off-by: Vignesh
> Raghavendra <vigneshr@ti.com>
> ---
>  .../mtd/spi-nor/controllers/cadence-quadspi.c | 469 +++++++-----------
>  1 file changed, 183 insertions(+), 286 deletions(-)
> 
> diff --git a/drivers/mtd/spi-nor/controllers/cadence-quadspi.c
> b/drivers/mtd/spi-nor/controllers/cadence-quadspi.c index
> 608ca657ff7f..c1df4b221889 100644
> --- a/drivers/mtd/spi-nor/controllers/cadence-quadspi.c
> +++ b/drivers/mtd/spi-nor/controllers/cadence-quadspi.c
> @@ -3,6 +3,8 @@
>   * Driver for Cadence QSPI Controller
>   *
>   * Copyright Altera Corporation (C) 2012-2014. All rights reserved.
> + * Copyright Intel Corporation (C) 2019-2020. All rights reserved.
> + * Copyright (C) 2020 Texas Instruments Incorporated - http://www.ti.com
>   */
>  #include <linux/clk.h>
>  #include <linux/completion.h>
> @@ -17,9 +19,6 @@
>  #include <linux/jiffies.h>
>  #include <linux/kernel.h>
>  #include <linux/module.h>
> -#include <linux/mtd/mtd.h>
> -#include <linux/mtd/partitions.h>
> -#include <linux/mtd/spi-nor.h>
>  #include <linux/of_device.h>
>  #include <linux/of.h>
>  #include <linux/platform_device.h>
> @@ -27,6 +26,7 @@
>  #include <linux/reset.h>
>  #include <linux/sched.h>
>  #include <linux/spi/spi.h>
> +#include <linux/spi/spi-mem.h>
>  #include <linux/timer.h>
> 
>  #define CQSPI_NAME                     "cadence-qspi"
> @@ -36,16 +36,12 @@
>  #define CQSPI_NEEDS_WR_DELAY           BIT(0)
>  #define CQSPI_DISABLE_DAC_MODE         BIT(1)
> 
> -/* Capabilities mask */
> -#define CQSPI_BASE_HWCAPS_MASK                                 \
> -       (SNOR_HWCAPS_READ | SNOR_HWCAPS_READ_FAST |             \
> -       SNOR_HWCAPS_READ_1_1_2 | SNOR_HWCAPS_READ_1_1_4 |       \
> -       SNOR_HWCAPS_PP)
> +/* Capabilities */
> +#define CQSPI_SUPPORTS_OCTAL           BIT(0)
> 
>  struct cqspi_st;
> 
>  struct cqspi_flash_pdata {
> -       struct spi_nor  nor;
>         struct cqspi_st *cqspi;
>         u32             clk_rate;
>         u32             read_delay;
> @@ -58,7 +54,6 @@ struct cqspi_flash_pdata {
>         u8              data_width;
>         u8              cs;
>         bool            registered;

you can drop this, as it is no longer used

> -       bool            use_direct_mode;
>  };
> 
>  struct cqspi_st {
> @@ -71,7 +66,6 @@ struct cqspi_st {
>         void __iomem            *ahb_base;
>         resource_size_t         ahb_size;
>         struct completion       transfer_complete;
> -       struct mutex            bus_mutex;
> 
>         struct dma_chan         *rx_chan;
>         struct completion       rx_dma_complete;
> @@ -85,6 +79,7 @@ struct cqspi_st {
>         bool                    rclk_en;
>         u32                     trigger_address;
>         u32                     wr_delay;
> +       bool                    use_dac_mode;

is use_dac_mode better than use_direct_mode? If you prefer "dac", maybe you 
can rename this variable in 2/6

>         struct cqspi_flash_pdata f_pdata[CQSPI_MAX_CHIPSELECT];
>  };
> 
> @@ -283,9 +278,8 @@ static irqreturn_t cqspi_irq_handler(int this_irq, void
> *dev) return IRQ_HANDLED;
>  }
> 
> -static unsigned int cqspi_calc_rdreg(struct spi_nor *nor)
> +static unsigned int cqspi_calc_rdreg(struct cqspi_flash_pdata *f_pdata)
>  {
> -       struct cqspi_flash_pdata *f_pdata = nor->priv;
>         u32 rdreg = 0;
> 
>         rdreg |= f_pdata->inst_width << CQSPI_REG_RD_INSTR_TYPE_INSTR_LSB;
> @@ -352,19 +346,21 @@ static int cqspi_exec_flash_cmd(struct cqspi_st
> *cqspi, unsigned int reg) return cqspi_wait_idle(cqspi);
>  }
> 
> -static int cqspi_command_read(struct spi_nor *nor, u8 opcode,
> -                             u8 *rxbuf, size_t n_rx)
> +static int cqspi_command_read(struct cqspi_flash_pdata *f_pdata,
> +                             const struct spi_mem_op *op)
>  {
> -       struct cqspi_flash_pdata *f_pdata = nor->priv;
>         struct cqspi_st *cqspi = f_pdata->cqspi;
>         void __iomem *reg_base = cqspi->iobase;
> +       u8 *rxbuf = op->data.buf.in;
> +       u8 opcode = op->cmd.opcode;

dedicated variable for opcode is not really needed, it is used only once.

> +       size_t n_rx = op->data.nbytes;
>         unsigned int rdreg;
>         unsigned int reg;
>         size_t read_len;
>         int status;
> 
>         if (!n_rx || n_rx > CQSPI_STIG_DATA_LEN_MAX || !rxbuf) {
> -               dev_err(nor->dev,
> +               dev_err(&cqspi->pdev->dev,
>                         "Invalid input argument, len %zu rxbuf 0x%p\n",
>                         n_rx, rxbuf);
>                 return -EINVAL;
> @@ -372,7 +368,7 @@ static int cqspi_command_read(struct spi_nor *nor, u8
> opcode,
> 
>         reg = opcode << CQSPI_REG_CMDCTRL_OPCODE_LSB;
> 
> -       rdreg = cqspi_calc_rdreg(nor);
> +       rdreg = cqspi_calc_rdreg(f_pdata);
>         writel(rdreg, reg_base + CQSPI_REG_RD_INSTR);
> 
>         reg |= (0x1 << CQSPI_REG_CMDCTRL_RD_EN_LSB);
> @@ -401,25 +397,35 @@ static int cqspi_command_read(struct spi_nor *nor, u8
> opcode, return 0;
>  }
> 
> -static int cqspi_command_write(struct spi_nor *nor, const u8 opcode,
> -                              const u8 *txbuf, size_t n_tx)
> +static int cqspi_command_write(struct cqspi_flash_pdata *f_pdata,
> +                              const struct spi_mem_op *op)
>  {
> -       struct cqspi_flash_pdata *f_pdata = nor->priv;
>         struct cqspi_st *cqspi = f_pdata->cqspi;
>         void __iomem *reg_base = cqspi->iobase;
> +       const u8 opcode = op->cmd.opcode;

dedicated variable for opcode is not really needed, it is used only once.

> +       const u8 *txbuf = op->data.buf.out;
> +       size_t n_tx = op->data.nbytes;
>         unsigned int reg;
>         unsigned int data;
>         size_t write_len;
> -       int ret;
> 
>         if (n_tx > CQSPI_STIG_DATA_LEN_MAX || (n_tx && !txbuf)) {
> -               dev_err(nor->dev,
> +               dev_err(&cqspi->pdev->dev,
>                         "Invalid input argument, cmdlen %zu txbuf 0x%p\n",
>                         n_tx, txbuf);
>                 return -EINVAL;
>         }
> 
>         reg = opcode << CQSPI_REG_CMDCTRL_OPCODE_LSB;
> +
> +       if (op->addr.nbytes) {
> +               reg |= (0x1 << CQSPI_REG_CMDCTRL_ADDR_EN_LSB);
> +               reg |= ((op->addr.nbytes - 1) &
> CQSPI_REG_CMDCTRL_ADD_BYTES_MASK)
> +               <<
> CQSPI_REG_CMDCTRL_ADD_BYTES_LSB;

you have a 80 chars checkpatch warning here, maybe replace it with smth like
	reg |= ((op->addr.nbytes - 1) &
	            CQSPI_REG_CMDCTRL_ADD_BYTES_MASK) <<
	           CQSPI_REG_CMDCTRL_ADD_BYTES_LSB;

> +
> +               writel(op->addr.val, reg_base + CQSPI_REG_CMDADDRESS);
> +       }
> +
>         if (n_tx) {
>                 reg |= (0x1 << CQSPI_REG_CMDCTRL_WR_EN_LSB);
>                 reg |= ((n_tx - 1) & CQSPI_REG_CMDCTRL_WR_BYTES_MASK)
> @@ -437,73 +443,46 @@ static int cqspi_command_write(struct spi_nor *nor,
> const u8 opcode, writel(data, reg_base + CQSPI_REG_CMDWRITEDATAUPPER); }
>         }
> -       ret = cqspi_exec_flash_cmd(cqspi, reg);
> -       return ret;
> -}
> -
> -static int cqspi_command_write_addr(struct spi_nor *nor,
> -                                   const u8 opcode, const unsigned int
> addr) -{
> -       struct cqspi_flash_pdata *f_pdata = nor->priv;
> -       struct cqspi_st *cqspi = f_pdata->cqspi;
> -       void __iomem *reg_base = cqspi->iobase;
> -       unsigned int reg;
> -
> -       reg = opcode << CQSPI_REG_CMDCTRL_OPCODE_LSB;
> -       reg |= (0x1 << CQSPI_REG_CMDCTRL_ADDR_EN_LSB);
> -       reg |= ((nor->addr_width - 1) & CQSPI_REG_CMDCTRL_ADD_BYTES_MASK)
> -               << CQSPI_REG_CMDCTRL_ADD_BYTES_LSB;
> -
> -       writel(addr, reg_base + CQSPI_REG_CMDADDRESS);
> 
>         return cqspi_exec_flash_cmd(cqspi, reg);
>  }
> 
> -static int cqspi_read_setup(struct spi_nor *nor)
> +static int cqspi_read_setup(struct cqspi_flash_pdata *f_pdata,
> +                           const struct spi_mem_op *op)
>  {
> -       struct cqspi_flash_pdata *f_pdata = nor->priv;
>         struct cqspi_st *cqspi = f_pdata->cqspi;
>         void __iomem *reg_base = cqspi->iobase;
>         unsigned int dummy_clk = 0;
>         unsigned int reg;
> 
> -       reg = nor->read_opcode << CQSPI_REG_RD_INSTR_OPCODE_LSB;
> -       reg |= cqspi_calc_rdreg(nor);
> +       reg = op->cmd.opcode << CQSPI_REG_RD_INSTR_OPCODE_LSB;
> +       reg |= cqspi_calc_rdreg(f_pdata);
> 
>         /* Setup dummy clock cycles */
> -       dummy_clk = nor->read_dummy;
> +       dummy_clk = op->dummy.nbytes * 8;
>         if (dummy_clk > CQSPI_DUMMY_CLKS_MAX)
>                 dummy_clk = CQSPI_DUMMY_CLKS_MAX;
> 
> -       if (dummy_clk / 8) {
> -               reg |= (1 << CQSPI_REG_RD_INSTR_MODE_EN_LSB);
> -               /* Set mode bits high to ensure chip doesn't enter XIP */
> -               writel(0xFF, reg_base + CQSPI_REG_MODE_BIT);
> -
> -               /* Need to subtract the mode byte (8 clocks). */
> -               if (f_pdata->inst_width != CQSPI_INST_TYPE_QUAD)
> -                       dummy_clk -= 8;
> -
> -               if (dummy_clk)
> -                       reg |= (dummy_clk & CQSPI_REG_RD_INSTR_DUMMY_MASK)
> -                              << CQSPI_REG_RD_INSTR_DUMMY_LSB;
> -       }
> +       if (dummy_clk / 8)

if (dummy_clk) should be enough. dummy_clk is either zero, or a multiple of 
eight, or CQSPI_DUMMY_CLKS_MAX.

> +               reg |= (dummy_clk & CQSPI_REG_RD_INSTR_DUMMY_MASK)
> +                      << CQSPI_REG_RD_INSTR_DUMMY_LSB;

> 
>         writel(reg, reg_base + CQSPI_REG_RD_INSTR);
> 
>         /* Set address width */
>         reg = readl(reg_base + CQSPI_REG_SIZE);
>         reg &= ~CQSPI_REG_SIZE_ADDRESS_MASK;
> -       reg |= (nor->addr_width - 1);
> +       reg |= (op->addr.nbytes - 1);
>         writel(reg, reg_base + CQSPI_REG_SIZE);
>         return 0;
>  }
> 
> -static int cqspi_indirect_read_execute(struct spi_nor *nor, u8 *rxbuf,
> -                                      loff_t from_addr, const size_t n_rx)
> +static int cqspi_indirect_read_execute(struct cqspi_flash_pdata *f_pdata,
> +                                      u8 *rxbuf, loff_t from_addr,
> +                                      const size_t n_rx)
>  {
> -       struct cqspi_flash_pdata *f_pdata = nor->priv;
>         struct cqspi_st *cqspi = f_pdata->cqspi;
> +       struct device *dev = &cqspi->pdev->dev;
>         void __iomem *reg_base = cqspi->iobase;
>         void __iomem *ahb_base = cqspi->ahb_base;
>         unsigned int remaining = n_rx;
> @@ -526,13 +505,13 @@ static int cqspi_indirect_read_execute(struct spi_nor
> *nor, u8 *rxbuf,
> 
>         while (remaining > 0) {
>                 if (!wait_for_completion_timeout(&cqspi->transfer_complete,
> -                               msecs_to_jiffies(CQSPI_READ_TIMEOUT_MS)))
> +                                               
> msecs_to_jiffies(CQSPI_READ_TIMEOUT_MS))) ret = -ETIMEDOUT;
> 
>                 bytes_to_read = cqspi_get_rd_sram_level(cqspi);
> 
>                 if (ret && bytes_to_read == 0) {
> -                       dev_err(nor->dev, "Indirect read timeout, no
> bytes\n"); +                       dev_err(dev, "Indirect read timeout, no
> bytes\n"); goto failrd;
>                 }
> 
> @@ -568,8 +547,7 @@ static int cqspi_indirect_read_execute(struct spi_nor
> *nor, u8 *rxbuf, ret = cqspi_wait_for_bit(reg_base + CQSPI_REG_INDIRECTRD,
>                                  CQSPI_REG_INDIRECTRD_DONE_MASK, 0);
>         if (ret) {
> -               dev_err(nor->dev,
> -                       "Indirect read completion error (%i)\n", ret);
> +               dev_err(dev, "Indirect read completion error (%i)\n", ret);
>                 goto failrd;
>         }
> 
> @@ -591,32 +569,32 @@ static int cqspi_indirect_read_execute(struct spi_nor
> *nor, u8 *rxbuf, return ret;
>  }
> 
> -static int cqspi_write_setup(struct spi_nor *nor)
> +static int cqspi_write_setup(struct cqspi_flash_pdata *f_pdata,
> +                            const struct spi_mem_op *op)
>  {
>         unsigned int reg;
> -       struct cqspi_flash_pdata *f_pdata = nor->priv;
>         struct cqspi_st *cqspi = f_pdata->cqspi;
>         void __iomem *reg_base = cqspi->iobase;
> 
>         /* Set opcode. */
> -       reg = nor->program_opcode << CQSPI_REG_WR_INSTR_OPCODE_LSB;
> +       reg = op->cmd.opcode << CQSPI_REG_WR_INSTR_OPCODE_LSB;
>         writel(reg, reg_base + CQSPI_REG_WR_INSTR);
> -       reg = cqspi_calc_rdreg(nor);
> +       reg = cqspi_calc_rdreg(f_pdata);
>         writel(reg, reg_base + CQSPI_REG_RD_INSTR);
> 
>         reg = readl(reg_base + CQSPI_REG_SIZE);
>         reg &= ~CQSPI_REG_SIZE_ADDRESS_MASK;
> -       reg |= (nor->addr_width - 1);
> +       reg |= (op->addr.nbytes - 1);
>         writel(reg, reg_base + CQSPI_REG_SIZE);
>         return 0;
>  }
> 
> -static int cqspi_indirect_write_execute(struct spi_nor *nor, loff_t
> to_addr, -                                       const u8 *txbuf, const
> size_t n_tx) +static int cqspi_indirect_write_execute(struct
> cqspi_flash_pdata *f_pdata, +                                       loff_t
> to_addr, const u8 *txbuf, +                                       const
> size_t n_tx)
>  {
> -       const unsigned int page_size = nor->page_size;
> -       struct cqspi_flash_pdata *f_pdata = nor->priv;
>         struct cqspi_st *cqspi = f_pdata->cqspi;
> +       struct device *dev = &cqspi->pdev->dev;
>         void __iomem *reg_base = cqspi->iobase;
>         unsigned int remaining = n_tx;
>         unsigned int write_bytes;
> @@ -646,7 +624,7 @@ static int cqspi_indirect_write_execute(struct spi_nor
> *nor, loff_t to_addr, while (remaining > 0) {
>                 size_t write_words, mod_bytes;
> 
> -               write_bytes = remaining > page_size ? page_size : remaining;
> +               write_bytes = remaining;
>                 write_words = write_bytes / 4;
>                 mod_bytes = write_bytes % 4;
>                 /* Write 4 bytes at a time then single bytes. */
> @@ -663,8 +641,8 @@ static int cqspi_indirect_write_execute(struct spi_nor
> *nor, loff_t to_addr, }
> 
>                 if (!wait_for_completion_timeout(&cqspi->transfer_complete,
> -                                       msecs_to_jiffies(CQSPI_TIMEOUT_MS)))
> { -                       dev_err(nor->dev, "Indirect write timeout\n"); + 
>                                              
> msecs_to_jiffies(CQSPI_TIMEOUT_MS))) { +                       dev_err(dev,
> "Indirect write timeout\n");
>                         ret = -ETIMEDOUT;
>                         goto failwr;
>                 }
> @@ -679,8 +657,7 @@ static int cqspi_indirect_write_execute(struct spi_nor
> *nor, loff_t to_addr, ret = cqspi_wait_for_bit(reg_base +
> CQSPI_REG_INDIRECTWR,
>                                  CQSPI_REG_INDIRECTWR_DONE_MASK, 0);
>         if (ret) {
> -               dev_err(nor->dev,
> -                       "Indirect write completion error (%i)\n", ret);
> +               dev_err(dev, "Indirect write completion error (%i)\n", ret);
> goto failwr;
>         }
> 
> @@ -704,9 +681,8 @@ static int cqspi_indirect_write_execute(struct spi_nor
> *nor, loff_t to_addr, return ret;
>  }
> 
> -static void cqspi_chipselect(struct spi_nor *nor)
> +static void cqspi_chipselect(struct cqspi_flash_pdata *f_pdata)
>  {
> -       struct cqspi_flash_pdata *f_pdata = nor->priv;
>         struct cqspi_st *cqspi = f_pdata->cqspi;
>         void __iomem *reg_base = cqspi->iobase;
>         unsigned int chip_select = f_pdata->cs;
> @@ -745,9 +721,8 @@ static unsigned int calculate_ticks_for_ns(const
> unsigned int ref_clk_hz, return ticks;
>  }
> 
> -static void cqspi_delay(struct spi_nor *nor)
> +static void cqspi_delay(struct cqspi_flash_pdata *f_pdata)
>  {
> -       struct cqspi_flash_pdata *f_pdata = nor->priv;
>         struct cqspi_st *cqspi = f_pdata->cqspi;
>         void __iomem *iobase = cqspi->iobase;
>         const unsigned int ref_clk_hz = cqspi->master_ref_clk_hz;
> @@ -831,11 +806,10 @@ static void cqspi_controller_enable(struct cqspi_st
> *cqspi, bool enable) writel(reg, reg_base + CQSPI_REG_CONFIG);
>  }
> 
> -static void cqspi_configure(struct spi_nor *nor)
> +static void cqspi_configure(struct cqspi_flash_pdata *f_pdata,
> +                           unsigned long sclk)
>  {
> -       struct cqspi_flash_pdata *f_pdata = nor->priv;
>         struct cqspi_st *cqspi = f_pdata->cqspi;
> -       const unsigned int sclk = f_pdata->clk_rate;
>         int switch_cs = (cqspi->current_cs != f_pdata->cs);
>         int switch_ck = (cqspi->sclk != sclk);
> 
> @@ -845,14 +819,14 @@ static void cqspi_configure(struct spi_nor *nor)
>         /* Switch chip select. */
>         if (switch_cs) {
>                 cqspi->current_cs = f_pdata->cs;
> -               cqspi_chipselect(nor);
> +               cqspi_chipselect(f_pdata);
>         }
> 
>         /* Setup baudrate divisor and delays */
>         if (switch_ck) {
>                 cqspi->sclk = sclk;
>                 cqspi_config_baudrate_div(cqspi);
> -               cqspi_delay(nor);
> +               cqspi_delay(f_pdata);
>                 cqspi_readdata_capture(cqspi, !cqspi->rclk_en,
>                                        f_pdata->read_delay);
>         }
> @@ -861,26 +835,25 @@ static void cqspi_configure(struct spi_nor *nor)
>                 cqspi_controller_enable(cqspi, 1);
>  }
> 
> -static int cqspi_set_protocol(struct spi_nor *nor, const int read)
> +static int cqspi_set_protocol(struct cqspi_flash_pdata *f_pdata,
> +                             const struct spi_mem_op *op)
>  {
> -       struct cqspi_flash_pdata *f_pdata = nor->priv;
> -
>         f_pdata->inst_width = CQSPI_INST_TYPE_SINGLE;
>         f_pdata->addr_width = CQSPI_INST_TYPE_SINGLE;
>         f_pdata->data_width = CQSPI_INST_TYPE_SINGLE;
> 
> -       if (read) {
> -               switch (nor->read_proto) {
> -               case SNOR_PROTO_1_1_1:
> +       if (op->data.dir == SPI_MEM_DATA_IN) {
> +               switch (op->data.buswidth) {
> +               case 1:
>                         f_pdata->data_width = CQSPI_INST_TYPE_SINGLE;
>                         break;
> -               case SNOR_PROTO_1_1_2:
> +               case 2:
>                         f_pdata->data_width = CQSPI_INST_TYPE_DUAL;
>                         break;
> -               case SNOR_PROTO_1_1_4:
> +               case 4:
>                         f_pdata->data_width = CQSPI_INST_TYPE_QUAD;
>                         break;
> -               case SNOR_PROTO_1_1_8:
> +               case 8:
>                         f_pdata->data_width = CQSPI_INST_TYPE_OCTAL;
>                         break;
>                 default:
> @@ -888,36 +861,32 @@ static int cqspi_set_protocol(struct spi_nor *nor,
> const int read) }
>         }
> 
> -       cqspi_configure(nor);
> -
>         return 0;
>  }
> 
> -static ssize_t cqspi_write(struct spi_nor *nor, loff_t to,
> -                          size_t len, const u_char *buf)
> +static ssize_t cqspi_write(struct cqspi_flash_pdata *f_pdata,
> +                          const struct spi_mem_op *op)
>  {
> -       struct cqspi_flash_pdata *f_pdata = nor->priv;
>         struct cqspi_st *cqspi = f_pdata->cqspi;
> +       loff_t to = op->addr.val;
> +       size_t len = op->data.nbytes;
> +       const u_char *buf = op->data.buf.out;
>         int ret;
> 
> -       ret = cqspi_set_protocol(nor, 0);
> +       ret = cqspi_set_protocol(f_pdata, op);
>         if (ret)
>                 return ret;
> 
> -       ret = cqspi_write_setup(nor);
> +       ret = cqspi_write_setup(f_pdata, op);
>         if (ret)
>                 return ret;
> 
> -       if (f_pdata->use_direct_mode) {
> +       if (cqspi->use_dac_mode && ((to + len) <= cqspi->ahb_size)) {
>                 memcpy_toio(cqspi->ahb_base + to, buf, len);
> -               ret = cqspi_wait_idle(cqspi);
> -       } else {
> -               ret = cqspi_indirect_write_execute(nor, to, buf, len);
> +               return cqspi_wait_idle(cqspi);
>         }
> -       if (ret)
> -               return ret;
> 
> -       return len;
> +       return cqspi_indirect_write_execute(f_pdata, to, buf, len);
>  }
> 
>  static void cqspi_rx_dma_callback(void *param)
> @@ -927,11 +896,11 @@ static void cqspi_rx_dma_callback(void *param)
>         complete(&cqspi->rx_dma_complete);
>  }
> 
> -static int cqspi_direct_read_execute(struct spi_nor *nor, u_char *buf,
> -                                    loff_t from, size_t len)
> +static int cqspi_direct_read_execute(struct cqspi_flash_pdata *f_pdata,
> +                                    u_char *buf, loff_t from, size_t len)
>  {
> -       struct cqspi_flash_pdata *f_pdata = nor->priv;
>         struct cqspi_st *cqspi = f_pdata->cqspi;
> +       struct device *dev = &cqspi->pdev->dev;
>         enum dma_ctrl_flags flags = DMA_CTRL_ACK | DMA_PREP_INTERRUPT;
>         dma_addr_t dma_src = (dma_addr_t)cqspi->mmap_phys_base + from;
>         int ret = 0;
> @@ -944,15 +913,15 @@ static int cqspi_direct_read_execute(struct spi_nor
> *nor, u_char *buf, return 0;
>         }
> 
> -       dma_dst = dma_map_single(nor->dev, buf, len, DMA_FROM_DEVICE);
> -       if (dma_mapping_error(nor->dev, dma_dst)) {
> -               dev_err(nor->dev, "dma mapping failed\n");
> +       dma_dst = dma_map_single(dev, buf, len, DMA_FROM_DEVICE);
> +       if (dma_mapping_error(dev, dma_dst)) {
> +               dev_err(dev, "dma mapping failed\n");
>                 return -ENOMEM;
>         }
>         tx = dmaengine_prep_dma_memcpy(cqspi->rx_chan, dma_dst, dma_src,
>                                        len, flags);
>         if (!tx) {
> -               dev_err(nor->dev, "device_prep_dma_memcpy error\n");
> +               dev_err(dev, "device_prep_dma_memcpy error\n");
>                 ret = -EIO;
>                 goto err_unmap;
>         }
> @@ -964,7 +933,7 @@ static int cqspi_direct_read_execute(struct spi_nor
> *nor, u_char *buf,
> 
>         ret = dma_submit_error(cookie);
>         if (ret) {
> -               dev_err(nor->dev, "dma_submit_error %d\n", cookie);
> +               dev_err(dev, "dma_submit_error %d\n", cookie);
>                 ret = -EIO;
>                 goto err_unmap;
>         }
> @@ -973,99 +942,68 @@ static int cqspi_direct_read_execute(struct spi_nor
> *nor, u_char *buf, if
> (!wait_for_completion_timeout(&cqspi->rx_dma_complete,
>                                          msecs_to_jiffies(len))) {
>                 dmaengine_terminate_sync(cqspi->rx_chan);
> -               dev_err(nor->dev, "DMA wait_for_completion_timeout\n");
> +               dev_err(dev, "DMA wait_for_completion_timeout\n");
>                 ret = -ETIMEDOUT;
>                 goto err_unmap;
>         }
> 
>  err_unmap:
> -       dma_unmap_single(nor->dev, dma_dst, len, DMA_FROM_DEVICE);
> +       dma_unmap_single(dev, dma_dst, len, DMA_FROM_DEVICE);
> 
>         return ret;
>  }
> 
> -static ssize_t cqspi_read(struct spi_nor *nor, loff_t from,
> -                         size_t len, u_char *buf)
> -{
> -       struct cqspi_flash_pdata *f_pdata = nor->priv;
> -       int ret;
> -
> -       ret = cqspi_set_protocol(nor, 1);
> -       if (ret)
> -               return ret;
> -
> -       ret = cqspi_read_setup(nor);
> -       if (ret)
> -               return ret;
> -
> -       if (f_pdata->use_direct_mode)
> -               ret = cqspi_direct_read_execute(nor, buf, from, len);
> -       else
> -               ret = cqspi_indirect_read_execute(nor, buf, from, len);
> -       if (ret)
> -               return ret;
> -
> -       return len;
> -}
> -
> -static int cqspi_erase(struct spi_nor *nor, loff_t offs)
> +static ssize_t cqspi_read(struct cqspi_flash_pdata *f_pdata,
> +                         const struct spi_mem_op *op)
>  {
> +       struct cqspi_st *cqspi = f_pdata->cqspi;
> +       loff_t from = op->addr.val;
> +       size_t len = op->data.nbytes;
> +       u_char *buf = op->data.buf.in;
>         int ret;
> 
> -       ret = cqspi_set_protocol(nor, 0);
> +       ret = cqspi_set_protocol(f_pdata, op);
>         if (ret)
>                 return ret;
> 
> -       /* Send write enable, then erase commands. */
> -       ret = nor->controller_ops->write_reg(nor, SPINOR_OP_WREN, NULL, 0);

Dropping the Write Enable for erases can be done in a separate patch, since it 
is already done in the SPI NOR core. This would ease the review.

> +       ret = cqspi_read_setup(f_pdata, op);
>         if (ret)
>                 return ret;
> 
> -       /* Set up command buffer. */
> -       ret = cqspi_command_write_addr(nor, nor->erase_opcode, offs);
> -       if (ret)
> -               return ret;
> +       if (cqspi->use_dac_mode && ((from + len) <= cqspi->ahb_size))
> +               return cqspi_direct_read_execute(f_pdata, buf, from, len);
> 
> -       return 0;
> +       return cqspi_indirect_read_execute(f_pdata, buf, from, len);
>  }
> 
> -static int cqspi_prep(struct spi_nor *nor)
> +static int cqspi_mem_process(struct spi_mem *mem, const struct spi_mem_op
> *op) {
> -       struct cqspi_flash_pdata *f_pdata = nor->priv;
> -       struct cqspi_st *cqspi = f_pdata->cqspi;
> -
> -       mutex_lock(&cqspi->bus_mutex);
> -
> -       return 0;
> -}
> +       struct cqspi_st *cqspi = spi_master_get_devdata(mem->spi->master);
> +       struct cqspi_flash_pdata *f_pdata;
> 
> -static void cqspi_unprep(struct spi_nor *nor)
> -{
> -       struct cqspi_flash_pdata *f_pdata = nor->priv;
> -       struct cqspi_st *cqspi = f_pdata->cqspi;
> +       f_pdata = &cqspi->f_pdata[mem->spi->chip_select];
> +       cqspi_configure(f_pdata, mem->spi->max_speed_hz);
> 
> -       mutex_unlock(&cqspi->bus_mutex);
> -}
> +       if (op->data.dir == SPI_MEM_DATA_IN && op->data.buf.in) {
> +               if (!op->addr.nbytes)
> +                       return cqspi_command_read(f_pdata, op);
> 
> -static int cqspi_read_reg(struct spi_nor *nor, u8 opcode, u8 *buf, size_t
> len) -{
> -       int ret;
> +               return cqspi_read(f_pdata, op);
> +       }
> 
> -       ret = cqspi_set_protocol(nor, 0);
> -       if (!ret)
> -               ret = cqspi_command_read(nor, opcode, buf, len);
> +       if (!op->addr.nbytes || !op->data.buf.out)
> +               return cqspi_command_write(f_pdata, op);
> 
> -       return ret;
> +       return cqspi_write(f_pdata, op);
>  }
> 
> -static int cqspi_write_reg(struct spi_nor *nor, u8 opcode, const u8 *buf,
> -                          size_t len)
> +static int cqspi_exec_mem_op(struct spi_mem *mem, const struct spi_mem_op
> *op) {
>         int ret;
> 
> -       ret = cqspi_set_protocol(nor, 0);
> -       if (!ret)
> -               ret = cqspi_command_write(nor, opcode, buf, len);
> +       ret = cqspi_mem_process(mem, op);
> +       if (ret)
> +               dev_err(&mem->spi->dev, "operation failed with %d\n", ret);
> 
>         return ret;
>  }
> @@ -1107,26 +1045,26 @@ static int cqspi_of_get_flash_pdata(struct
> platform_device *pdev, return 0;
>  }
> 
> -static int cqspi_of_get_pdata(struct platform_device *pdev)
> +static int cqspi_of_get_pdata(struct cqspi_st *cqspi)
>  {
> -       struct device_node *np = pdev->dev.of_node;
> -       struct cqspi_st *cqspi = platform_get_drvdata(pdev);
> +       struct device *dev = &cqspi->pdev->dev;
> +       struct device_node *np = dev->of_node;
> 
>         cqspi->is_decoded_cs = of_property_read_bool(np,
> "cdns,is-decoded-cs");
> 
>         if (of_property_read_u32(np, "cdns,fifo-depth", &cqspi->fifo_depth))
> { -               dev_err(&pdev->dev, "couldn't determine fifo-depth\n"); +
>               dev_err(dev, "couldn't determine fifo-depth\n");
>                 return -ENXIO;
>         }
> 
>         if (of_property_read_u32(np, "cdns,fifo-width", &cqspi->fifo_width))
> { -               dev_err(&pdev->dev, "couldn't determine fifo-width\n"); +
>               dev_err(dev, "couldn't determine fifo-width\n");
>                 return -ENXIO;
>         }
> 
>         if (of_property_read_u32(np, "cdns,trigger-address",
>                                  &cqspi->trigger_address)) {
> -               dev_err(&pdev->dev, "couldn't determine trigger-address\n");
> +               dev_err(dev, "couldn't determine trigger-address\n");
> return -ENXIO;
>         }
> 
> @@ -1169,7 +1107,7 @@ static void cqspi_controller_init(struct cqspi_st
> *cqspi) cqspi_controller_enable(cqspi, 1);
>  }
> 
> -static void cqspi_request_mmap_dma(struct cqspi_st *cqspi)
> +static int cqspi_request_mmap_dma(struct cqspi_st *cqspi)
>  {
>         dma_cap_mask_t mask;
> 
> @@ -1178,133 +1116,79 @@ static void cqspi_request_mmap_dma(struct cqspi_st
> *cqspi)
> 
>         cqspi->rx_chan = dma_request_chan_by_mask(&mask);
>         if (IS_ERR(cqspi->rx_chan)) {
> -               dev_err(&cqspi->pdev->dev, "No Rx DMA available\n");
> +               int ret = PTR_ERR(cqspi->rx_chan);
> +
> +               if (ret != -EPROBE_DEFER)
> +                       dev_err(&cqspi->pdev->dev, "No Rx DMA available\n");
> cqspi->rx_chan = NULL;
> -               return;
> +               return ret;
>         }
>         init_completion(&cqspi->rx_dma_complete);
> +
> +       return 0;
>  }

Can we have the EPROBE_DEFER changes in a dedicated patch?

> 
> -static const struct spi_nor_controller_ops cqspi_controller_ops = {
> -       .prepare = cqspi_prep,
> -       .unprepare = cqspi_unprep,
> -       .read_reg = cqspi_read_reg,
> -       .write_reg = cqspi_write_reg,
> -       .read = cqspi_read,
> -       .write = cqspi_write,
> -       .erase = cqspi_erase,
> +static const struct spi_controller_mem_ops cqspi_mem_ops = {
> +       .exec_op = cqspi_exec_mem_op,
>  };
> 
> -static int cqspi_setup_flash(struct cqspi_st *cqspi, struct device_node
> *np) +static int cqspi_setup_flash(struct cqspi_st *cqspi)
>  {
>         struct platform_device *pdev = cqspi->pdev;
>         struct device *dev = &pdev->dev;
> -       const struct cqspi_driver_platdata *ddata;
> -       struct spi_nor_hwcaps hwcaps;
> +       struct device_node *np = dev->of_node;
>         struct cqspi_flash_pdata *f_pdata;
> -       struct spi_nor *nor;
> -       struct mtd_info *mtd;
>         unsigned int cs;
> -       int i, ret;
> -
> -       ddata = of_device_get_match_data(dev);
> -       if (!ddata) {
> -               dev_err(dev, "Couldn't find driver data\n");
> -               return -EINVAL;
> -       }
> -       hwcaps.mask = ddata->hwcaps_mask;
> 
>         /* Get flash device data */
>         for_each_available_child_of_node(dev->of_node, np) {
> -               ret = of_property_read_u32(np, "reg", &cs);
> -               if (ret) {
> +               if (of_property_read_u32(np, "reg", &cs)) {
>                         dev_err(dev, "Couldn't determine chip select.\n");
> -                       goto err;
> +                       continue;

reg is mandatory, you should keep the behaviour as it was.

>                 }
> 
>                 if (cs >= CQSPI_MAX_CHIPSELECT) {
> -                       ret = -EINVAL;
>                         dev_err(dev, "Chip select %d out of range.\n", cs);
> -                       goto err;
> +                       continue;
>                 }
> 
>                 f_pdata = &cqspi->f_pdata[cs];
>                 f_pdata->cqspi = cqspi;
>                 f_pdata->cs = cs;
> 
> -               ret = cqspi_of_get_flash_pdata(pdev, f_pdata, np);
> -               if (ret)
> -                       goto err;
> -
> -               nor = &f_pdata->nor;
> -               mtd = &nor->mtd;
> -
> -               mtd->priv = nor;
> -
> -               nor->dev = dev;
> -               spi_nor_set_flash_node(nor, np);
> -               nor->priv = f_pdata;
> -               nor->controller_ops = &cqspi_controller_ops;
> -
> -               mtd->name = devm_kasprintf(dev, GFP_KERNEL, "%s.%d",
> -                                          dev_name(dev), cs);
> -               if (!mtd->name) {
> -                       ret = -ENOMEM;
> -                       goto err;
> -               }
> -
> -               ret = spi_nor_scan(nor, NULL, &hwcaps);
> -               if (ret)
> -                       goto err;
> -
> -               ret = mtd_device_register(mtd, NULL, 0);
> -               if (ret)
> -                       goto err;
> -
> -               f_pdata->registered = true;
> -
> -               if (mtd->size <= cqspi->ahb_size &&
> -                   !(ddata->quirks & CQSPI_DISABLE_DAC_MODE)) {
> -                       f_pdata->use_direct_mode = true;
> -                       dev_dbg(nor->dev, "using direct mode for %s\n",
> -                               mtd->name);
> -
> -                       if (!cqspi->rx_chan)
> -                               cqspi_request_mmap_dma(cqspi);
> -               }
> +               return cqspi_of_get_flash_pdata(pdev, f_pdata, np);

drop the return. you now parse just the first discovered flash, whereas before 
your changes we parsed all the described flashes.

>         }
> 
>         return 0;
> -
> -err:
> -       for (i = 0; i < CQSPI_MAX_CHIPSELECT; i++)
> -               if (cqspi->f_pdata[i].registered)
> -                       mtd_device_unregister(&cqspi->f_pdata[i].nor.mtd);
> -       return ret;
>  }
> 
>  static int cqspi_probe(struct platform_device *pdev)
>  {
> -       struct device_node *np = pdev->dev.of_node;
> +       const struct cqspi_driver_platdata *ddata;
> +       struct reset_control *rstc, *rstc_ocp;
>         struct device *dev = &pdev->dev;
> +       struct spi_master *master;
> +       struct resource *res_ahb;
>         struct cqspi_st *cqspi;
>         struct resource *res;
> -       struct resource *res_ahb;
> -       struct reset_control *rstc, *rstc_ocp;
> -       const struct cqspi_driver_platdata *ddata;
>         int ret;
>         int irq;
> 
> -       cqspi = devm_kzalloc(dev, sizeof(*cqspi), GFP_KERNEL);
> -       if (!cqspi)
> +       master = spi_alloc_master(&pdev->dev, sizeof(*cqspi));
> +       if (!master) {
> +               dev_err(&pdev->dev, "spi_alloc_master failed\n");
>                 return -ENOMEM;
> +       }
> +       master->mode_bits = SPI_RX_QUAD | SPI_RX_DUAL;
> +       master->mem_ops = &cqspi_mem_ops;
> +       master->dev.of_node = pdev->dev.of_node;
> +
> +       cqspi = spi_master_get_devdata(master);
> 
> -       mutex_init(&cqspi->bus_mutex);
>         cqspi->pdev = pdev;
> -       platform_set_drvdata(pdev, cqspi);
> 
>         /* Obtain configuration from OF. */
> -       ret = cqspi_of_get_pdata(pdev);
> +       ret = cqspi_of_get_pdata(cqspi);
>         if (ret) {

spi_controller_put() to not leak memory.

Cheers,
ta


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

* Re: [PATCH v2 5/6] mtd: spi-nor: Convert cadence-quadspi to use spi-mem framework
@ 2020-05-30 13:50     ` Tudor.Ambarus
  0 siblings, 0 replies; 36+ messages in thread
From: Tudor.Ambarus @ 2020-05-30 13:50 UTC (permalink / raw)
  To: vigneshr
  Cc: marex, bbrezillon, dinguyen, simon.k.r.goldschmidt, linux-kernel,
	linux-spi, vadivel.muruganx.ramuthevar, broonie, linux-mtd

Hi, Vignesh,

On Tuesday, May 26, 2020 12:36:03 PM EEST Vignesh Raghavendra wrote:
> EXTERNAL EMAIL: Do not click links or open attachments unless you know the
> content is safe
> 
> From: Ramuthevar Vadivel Murugan
> <vadivel.muruganx.ramuthevar@linux.intel.com>
> 
> Move cadence-quadspi driver to use spi-mem framework. This is required
> to make the driver support for SPI NAND flashes in future.
> 
> Driver is feature compliant with existing SPI NOR version.
> 
> Signed-off-by: Ramuthevar Vadivel Murugan
> <vadivel.muruganx.ramuthevar@linux.intel.com> Signed-off-by: Vignesh
> Raghavendra <vigneshr@ti.com>
> ---
>  .../mtd/spi-nor/controllers/cadence-quadspi.c | 469 +++++++-----------
>  1 file changed, 183 insertions(+), 286 deletions(-)
> 
> diff --git a/drivers/mtd/spi-nor/controllers/cadence-quadspi.c
> b/drivers/mtd/spi-nor/controllers/cadence-quadspi.c index
> 608ca657ff7f..c1df4b221889 100644
> --- a/drivers/mtd/spi-nor/controllers/cadence-quadspi.c
> +++ b/drivers/mtd/spi-nor/controllers/cadence-quadspi.c
> @@ -3,6 +3,8 @@
>   * Driver for Cadence QSPI Controller
>   *
>   * Copyright Altera Corporation (C) 2012-2014. All rights reserved.
> + * Copyright Intel Corporation (C) 2019-2020. All rights reserved.
> + * Copyright (C) 2020 Texas Instruments Incorporated - http://www.ti.com
>   */
>  #include <linux/clk.h>
>  #include <linux/completion.h>
> @@ -17,9 +19,6 @@
>  #include <linux/jiffies.h>
>  #include <linux/kernel.h>
>  #include <linux/module.h>
> -#include <linux/mtd/mtd.h>
> -#include <linux/mtd/partitions.h>
> -#include <linux/mtd/spi-nor.h>
>  #include <linux/of_device.h>
>  #include <linux/of.h>
>  #include <linux/platform_device.h>
> @@ -27,6 +26,7 @@
>  #include <linux/reset.h>
>  #include <linux/sched.h>
>  #include <linux/spi/spi.h>
> +#include <linux/spi/spi-mem.h>
>  #include <linux/timer.h>
> 
>  #define CQSPI_NAME                     "cadence-qspi"
> @@ -36,16 +36,12 @@
>  #define CQSPI_NEEDS_WR_DELAY           BIT(0)
>  #define CQSPI_DISABLE_DAC_MODE         BIT(1)
> 
> -/* Capabilities mask */
> -#define CQSPI_BASE_HWCAPS_MASK                                 \
> -       (SNOR_HWCAPS_READ | SNOR_HWCAPS_READ_FAST |             \
> -       SNOR_HWCAPS_READ_1_1_2 | SNOR_HWCAPS_READ_1_1_4 |       \
> -       SNOR_HWCAPS_PP)
> +/* Capabilities */
> +#define CQSPI_SUPPORTS_OCTAL           BIT(0)
> 
>  struct cqspi_st;
> 
>  struct cqspi_flash_pdata {
> -       struct spi_nor  nor;
>         struct cqspi_st *cqspi;
>         u32             clk_rate;
>         u32             read_delay;
> @@ -58,7 +54,6 @@ struct cqspi_flash_pdata {
>         u8              data_width;
>         u8              cs;
>         bool            registered;

you can drop this, as it is no longer used

> -       bool            use_direct_mode;
>  };
> 
>  struct cqspi_st {
> @@ -71,7 +66,6 @@ struct cqspi_st {
>         void __iomem            *ahb_base;
>         resource_size_t         ahb_size;
>         struct completion       transfer_complete;
> -       struct mutex            bus_mutex;
> 
>         struct dma_chan         *rx_chan;
>         struct completion       rx_dma_complete;
> @@ -85,6 +79,7 @@ struct cqspi_st {
>         bool                    rclk_en;
>         u32                     trigger_address;
>         u32                     wr_delay;
> +       bool                    use_dac_mode;

is use_dac_mode better than use_direct_mode? If you prefer "dac", maybe you 
can rename this variable in 2/6

>         struct cqspi_flash_pdata f_pdata[CQSPI_MAX_CHIPSELECT];
>  };
> 
> @@ -283,9 +278,8 @@ static irqreturn_t cqspi_irq_handler(int this_irq, void
> *dev) return IRQ_HANDLED;
>  }
> 
> -static unsigned int cqspi_calc_rdreg(struct spi_nor *nor)
> +static unsigned int cqspi_calc_rdreg(struct cqspi_flash_pdata *f_pdata)
>  {
> -       struct cqspi_flash_pdata *f_pdata = nor->priv;
>         u32 rdreg = 0;
> 
>         rdreg |= f_pdata->inst_width << CQSPI_REG_RD_INSTR_TYPE_INSTR_LSB;
> @@ -352,19 +346,21 @@ static int cqspi_exec_flash_cmd(struct cqspi_st
> *cqspi, unsigned int reg) return cqspi_wait_idle(cqspi);
>  }
> 
> -static int cqspi_command_read(struct spi_nor *nor, u8 opcode,
> -                             u8 *rxbuf, size_t n_rx)
> +static int cqspi_command_read(struct cqspi_flash_pdata *f_pdata,
> +                             const struct spi_mem_op *op)
>  {
> -       struct cqspi_flash_pdata *f_pdata = nor->priv;
>         struct cqspi_st *cqspi = f_pdata->cqspi;
>         void __iomem *reg_base = cqspi->iobase;
> +       u8 *rxbuf = op->data.buf.in;
> +       u8 opcode = op->cmd.opcode;

dedicated variable for opcode is not really needed, it is used only once.

> +       size_t n_rx = op->data.nbytes;
>         unsigned int rdreg;
>         unsigned int reg;
>         size_t read_len;
>         int status;
> 
>         if (!n_rx || n_rx > CQSPI_STIG_DATA_LEN_MAX || !rxbuf) {
> -               dev_err(nor->dev,
> +               dev_err(&cqspi->pdev->dev,
>                         "Invalid input argument, len %zu rxbuf 0x%p\n",
>                         n_rx, rxbuf);
>                 return -EINVAL;
> @@ -372,7 +368,7 @@ static int cqspi_command_read(struct spi_nor *nor, u8
> opcode,
> 
>         reg = opcode << CQSPI_REG_CMDCTRL_OPCODE_LSB;
> 
> -       rdreg = cqspi_calc_rdreg(nor);
> +       rdreg = cqspi_calc_rdreg(f_pdata);
>         writel(rdreg, reg_base + CQSPI_REG_RD_INSTR);
> 
>         reg |= (0x1 << CQSPI_REG_CMDCTRL_RD_EN_LSB);
> @@ -401,25 +397,35 @@ static int cqspi_command_read(struct spi_nor *nor, u8
> opcode, return 0;
>  }
> 
> -static int cqspi_command_write(struct spi_nor *nor, const u8 opcode,
> -                              const u8 *txbuf, size_t n_tx)
> +static int cqspi_command_write(struct cqspi_flash_pdata *f_pdata,
> +                              const struct spi_mem_op *op)
>  {
> -       struct cqspi_flash_pdata *f_pdata = nor->priv;
>         struct cqspi_st *cqspi = f_pdata->cqspi;
>         void __iomem *reg_base = cqspi->iobase;
> +       const u8 opcode = op->cmd.opcode;

dedicated variable for opcode is not really needed, it is used only once.

> +       const u8 *txbuf = op->data.buf.out;
> +       size_t n_tx = op->data.nbytes;
>         unsigned int reg;
>         unsigned int data;
>         size_t write_len;
> -       int ret;
> 
>         if (n_tx > CQSPI_STIG_DATA_LEN_MAX || (n_tx && !txbuf)) {
> -               dev_err(nor->dev,
> +               dev_err(&cqspi->pdev->dev,
>                         "Invalid input argument, cmdlen %zu txbuf 0x%p\n",
>                         n_tx, txbuf);
>                 return -EINVAL;
>         }
> 
>         reg = opcode << CQSPI_REG_CMDCTRL_OPCODE_LSB;
> +
> +       if (op->addr.nbytes) {
> +               reg |= (0x1 << CQSPI_REG_CMDCTRL_ADDR_EN_LSB);
> +               reg |= ((op->addr.nbytes - 1) &
> CQSPI_REG_CMDCTRL_ADD_BYTES_MASK)
> +               <<
> CQSPI_REG_CMDCTRL_ADD_BYTES_LSB;

you have a 80 chars checkpatch warning here, maybe replace it with smth like
	reg |= ((op->addr.nbytes - 1) &
	            CQSPI_REG_CMDCTRL_ADD_BYTES_MASK) <<
	           CQSPI_REG_CMDCTRL_ADD_BYTES_LSB;

> +
> +               writel(op->addr.val, reg_base + CQSPI_REG_CMDADDRESS);
> +       }
> +
>         if (n_tx) {
>                 reg |= (0x1 << CQSPI_REG_CMDCTRL_WR_EN_LSB);
>                 reg |= ((n_tx - 1) & CQSPI_REG_CMDCTRL_WR_BYTES_MASK)
> @@ -437,73 +443,46 @@ static int cqspi_command_write(struct spi_nor *nor,
> const u8 opcode, writel(data, reg_base + CQSPI_REG_CMDWRITEDATAUPPER); }
>         }
> -       ret = cqspi_exec_flash_cmd(cqspi, reg);
> -       return ret;
> -}
> -
> -static int cqspi_command_write_addr(struct spi_nor *nor,
> -                                   const u8 opcode, const unsigned int
> addr) -{
> -       struct cqspi_flash_pdata *f_pdata = nor->priv;
> -       struct cqspi_st *cqspi = f_pdata->cqspi;
> -       void __iomem *reg_base = cqspi->iobase;
> -       unsigned int reg;
> -
> -       reg = opcode << CQSPI_REG_CMDCTRL_OPCODE_LSB;
> -       reg |= (0x1 << CQSPI_REG_CMDCTRL_ADDR_EN_LSB);
> -       reg |= ((nor->addr_width - 1) & CQSPI_REG_CMDCTRL_ADD_BYTES_MASK)
> -               << CQSPI_REG_CMDCTRL_ADD_BYTES_LSB;
> -
> -       writel(addr, reg_base + CQSPI_REG_CMDADDRESS);
> 
>         return cqspi_exec_flash_cmd(cqspi, reg);
>  }
> 
> -static int cqspi_read_setup(struct spi_nor *nor)
> +static int cqspi_read_setup(struct cqspi_flash_pdata *f_pdata,
> +                           const struct spi_mem_op *op)
>  {
> -       struct cqspi_flash_pdata *f_pdata = nor->priv;
>         struct cqspi_st *cqspi = f_pdata->cqspi;
>         void __iomem *reg_base = cqspi->iobase;
>         unsigned int dummy_clk = 0;
>         unsigned int reg;
> 
> -       reg = nor->read_opcode << CQSPI_REG_RD_INSTR_OPCODE_LSB;
> -       reg |= cqspi_calc_rdreg(nor);
> +       reg = op->cmd.opcode << CQSPI_REG_RD_INSTR_OPCODE_LSB;
> +       reg |= cqspi_calc_rdreg(f_pdata);
> 
>         /* Setup dummy clock cycles */
> -       dummy_clk = nor->read_dummy;
> +       dummy_clk = op->dummy.nbytes * 8;
>         if (dummy_clk > CQSPI_DUMMY_CLKS_MAX)
>                 dummy_clk = CQSPI_DUMMY_CLKS_MAX;
> 
> -       if (dummy_clk / 8) {
> -               reg |= (1 << CQSPI_REG_RD_INSTR_MODE_EN_LSB);
> -               /* Set mode bits high to ensure chip doesn't enter XIP */
> -               writel(0xFF, reg_base + CQSPI_REG_MODE_BIT);
> -
> -               /* Need to subtract the mode byte (8 clocks). */
> -               if (f_pdata->inst_width != CQSPI_INST_TYPE_QUAD)
> -                       dummy_clk -= 8;
> -
> -               if (dummy_clk)
> -                       reg |= (dummy_clk & CQSPI_REG_RD_INSTR_DUMMY_MASK)
> -                              << CQSPI_REG_RD_INSTR_DUMMY_LSB;
> -       }
> +       if (dummy_clk / 8)

if (dummy_clk) should be enough. dummy_clk is either zero, or a multiple of 
eight, or CQSPI_DUMMY_CLKS_MAX.

> +               reg |= (dummy_clk & CQSPI_REG_RD_INSTR_DUMMY_MASK)
> +                      << CQSPI_REG_RD_INSTR_DUMMY_LSB;

> 
>         writel(reg, reg_base + CQSPI_REG_RD_INSTR);
> 
>         /* Set address width */
>         reg = readl(reg_base + CQSPI_REG_SIZE);
>         reg &= ~CQSPI_REG_SIZE_ADDRESS_MASK;
> -       reg |= (nor->addr_width - 1);
> +       reg |= (op->addr.nbytes - 1);
>         writel(reg, reg_base + CQSPI_REG_SIZE);
>         return 0;
>  }
> 
> -static int cqspi_indirect_read_execute(struct spi_nor *nor, u8 *rxbuf,
> -                                      loff_t from_addr, const size_t n_rx)
> +static int cqspi_indirect_read_execute(struct cqspi_flash_pdata *f_pdata,
> +                                      u8 *rxbuf, loff_t from_addr,
> +                                      const size_t n_rx)
>  {
> -       struct cqspi_flash_pdata *f_pdata = nor->priv;
>         struct cqspi_st *cqspi = f_pdata->cqspi;
> +       struct device *dev = &cqspi->pdev->dev;
>         void __iomem *reg_base = cqspi->iobase;
>         void __iomem *ahb_base = cqspi->ahb_base;
>         unsigned int remaining = n_rx;
> @@ -526,13 +505,13 @@ static int cqspi_indirect_read_execute(struct spi_nor
> *nor, u8 *rxbuf,
> 
>         while (remaining > 0) {
>                 if (!wait_for_completion_timeout(&cqspi->transfer_complete,
> -                               msecs_to_jiffies(CQSPI_READ_TIMEOUT_MS)))
> +                                               
> msecs_to_jiffies(CQSPI_READ_TIMEOUT_MS))) ret = -ETIMEDOUT;
> 
>                 bytes_to_read = cqspi_get_rd_sram_level(cqspi);
> 
>                 if (ret && bytes_to_read == 0) {
> -                       dev_err(nor->dev, "Indirect read timeout, no
> bytes\n"); +                       dev_err(dev, "Indirect read timeout, no
> bytes\n"); goto failrd;
>                 }
> 
> @@ -568,8 +547,7 @@ static int cqspi_indirect_read_execute(struct spi_nor
> *nor, u8 *rxbuf, ret = cqspi_wait_for_bit(reg_base + CQSPI_REG_INDIRECTRD,
>                                  CQSPI_REG_INDIRECTRD_DONE_MASK, 0);
>         if (ret) {
> -               dev_err(nor->dev,
> -                       "Indirect read completion error (%i)\n", ret);
> +               dev_err(dev, "Indirect read completion error (%i)\n", ret);
>                 goto failrd;
>         }
> 
> @@ -591,32 +569,32 @@ static int cqspi_indirect_read_execute(struct spi_nor
> *nor, u8 *rxbuf, return ret;
>  }
> 
> -static int cqspi_write_setup(struct spi_nor *nor)
> +static int cqspi_write_setup(struct cqspi_flash_pdata *f_pdata,
> +                            const struct spi_mem_op *op)
>  {
>         unsigned int reg;
> -       struct cqspi_flash_pdata *f_pdata = nor->priv;
>         struct cqspi_st *cqspi = f_pdata->cqspi;
>         void __iomem *reg_base = cqspi->iobase;
> 
>         /* Set opcode. */
> -       reg = nor->program_opcode << CQSPI_REG_WR_INSTR_OPCODE_LSB;
> +       reg = op->cmd.opcode << CQSPI_REG_WR_INSTR_OPCODE_LSB;
>         writel(reg, reg_base + CQSPI_REG_WR_INSTR);
> -       reg = cqspi_calc_rdreg(nor);
> +       reg = cqspi_calc_rdreg(f_pdata);
>         writel(reg, reg_base + CQSPI_REG_RD_INSTR);
> 
>         reg = readl(reg_base + CQSPI_REG_SIZE);
>         reg &= ~CQSPI_REG_SIZE_ADDRESS_MASK;
> -       reg |= (nor->addr_width - 1);
> +       reg |= (op->addr.nbytes - 1);
>         writel(reg, reg_base + CQSPI_REG_SIZE);
>         return 0;
>  }
> 
> -static int cqspi_indirect_write_execute(struct spi_nor *nor, loff_t
> to_addr, -                                       const u8 *txbuf, const
> size_t n_tx) +static int cqspi_indirect_write_execute(struct
> cqspi_flash_pdata *f_pdata, +                                       loff_t
> to_addr, const u8 *txbuf, +                                       const
> size_t n_tx)
>  {
> -       const unsigned int page_size = nor->page_size;
> -       struct cqspi_flash_pdata *f_pdata = nor->priv;
>         struct cqspi_st *cqspi = f_pdata->cqspi;
> +       struct device *dev = &cqspi->pdev->dev;
>         void __iomem *reg_base = cqspi->iobase;
>         unsigned int remaining = n_tx;
>         unsigned int write_bytes;
> @@ -646,7 +624,7 @@ static int cqspi_indirect_write_execute(struct spi_nor
> *nor, loff_t to_addr, while (remaining > 0) {
>                 size_t write_words, mod_bytes;
> 
> -               write_bytes = remaining > page_size ? page_size : remaining;
> +               write_bytes = remaining;
>                 write_words = write_bytes / 4;
>                 mod_bytes = write_bytes % 4;
>                 /* Write 4 bytes at a time then single bytes. */
> @@ -663,8 +641,8 @@ static int cqspi_indirect_write_execute(struct spi_nor
> *nor, loff_t to_addr, }
> 
>                 if (!wait_for_completion_timeout(&cqspi->transfer_complete,
> -                                       msecs_to_jiffies(CQSPI_TIMEOUT_MS)))
> { -                       dev_err(nor->dev, "Indirect write timeout\n"); + 
>                                              
> msecs_to_jiffies(CQSPI_TIMEOUT_MS))) { +                       dev_err(dev,
> "Indirect write timeout\n");
>                         ret = -ETIMEDOUT;
>                         goto failwr;
>                 }
> @@ -679,8 +657,7 @@ static int cqspi_indirect_write_execute(struct spi_nor
> *nor, loff_t to_addr, ret = cqspi_wait_for_bit(reg_base +
> CQSPI_REG_INDIRECTWR,
>                                  CQSPI_REG_INDIRECTWR_DONE_MASK, 0);
>         if (ret) {
> -               dev_err(nor->dev,
> -                       "Indirect write completion error (%i)\n", ret);
> +               dev_err(dev, "Indirect write completion error (%i)\n", ret);
> goto failwr;
>         }
> 
> @@ -704,9 +681,8 @@ static int cqspi_indirect_write_execute(struct spi_nor
> *nor, loff_t to_addr, return ret;
>  }
> 
> -static void cqspi_chipselect(struct spi_nor *nor)
> +static void cqspi_chipselect(struct cqspi_flash_pdata *f_pdata)
>  {
> -       struct cqspi_flash_pdata *f_pdata = nor->priv;
>         struct cqspi_st *cqspi = f_pdata->cqspi;
>         void __iomem *reg_base = cqspi->iobase;
>         unsigned int chip_select = f_pdata->cs;
> @@ -745,9 +721,8 @@ static unsigned int calculate_ticks_for_ns(const
> unsigned int ref_clk_hz, return ticks;
>  }
> 
> -static void cqspi_delay(struct spi_nor *nor)
> +static void cqspi_delay(struct cqspi_flash_pdata *f_pdata)
>  {
> -       struct cqspi_flash_pdata *f_pdata = nor->priv;
>         struct cqspi_st *cqspi = f_pdata->cqspi;
>         void __iomem *iobase = cqspi->iobase;
>         const unsigned int ref_clk_hz = cqspi->master_ref_clk_hz;
> @@ -831,11 +806,10 @@ static void cqspi_controller_enable(struct cqspi_st
> *cqspi, bool enable) writel(reg, reg_base + CQSPI_REG_CONFIG);
>  }
> 
> -static void cqspi_configure(struct spi_nor *nor)
> +static void cqspi_configure(struct cqspi_flash_pdata *f_pdata,
> +                           unsigned long sclk)
>  {
> -       struct cqspi_flash_pdata *f_pdata = nor->priv;
>         struct cqspi_st *cqspi = f_pdata->cqspi;
> -       const unsigned int sclk = f_pdata->clk_rate;
>         int switch_cs = (cqspi->current_cs != f_pdata->cs);
>         int switch_ck = (cqspi->sclk != sclk);
> 
> @@ -845,14 +819,14 @@ static void cqspi_configure(struct spi_nor *nor)
>         /* Switch chip select. */
>         if (switch_cs) {
>                 cqspi->current_cs = f_pdata->cs;
> -               cqspi_chipselect(nor);
> +               cqspi_chipselect(f_pdata);
>         }
> 
>         /* Setup baudrate divisor and delays */
>         if (switch_ck) {
>                 cqspi->sclk = sclk;
>                 cqspi_config_baudrate_div(cqspi);
> -               cqspi_delay(nor);
> +               cqspi_delay(f_pdata);
>                 cqspi_readdata_capture(cqspi, !cqspi->rclk_en,
>                                        f_pdata->read_delay);
>         }
> @@ -861,26 +835,25 @@ static void cqspi_configure(struct spi_nor *nor)
>                 cqspi_controller_enable(cqspi, 1);
>  }
> 
> -static int cqspi_set_protocol(struct spi_nor *nor, const int read)
> +static int cqspi_set_protocol(struct cqspi_flash_pdata *f_pdata,
> +                             const struct spi_mem_op *op)
>  {
> -       struct cqspi_flash_pdata *f_pdata = nor->priv;
> -
>         f_pdata->inst_width = CQSPI_INST_TYPE_SINGLE;
>         f_pdata->addr_width = CQSPI_INST_TYPE_SINGLE;
>         f_pdata->data_width = CQSPI_INST_TYPE_SINGLE;
> 
> -       if (read) {
> -               switch (nor->read_proto) {
> -               case SNOR_PROTO_1_1_1:
> +       if (op->data.dir == SPI_MEM_DATA_IN) {
> +               switch (op->data.buswidth) {
> +               case 1:
>                         f_pdata->data_width = CQSPI_INST_TYPE_SINGLE;
>                         break;
> -               case SNOR_PROTO_1_1_2:
> +               case 2:
>                         f_pdata->data_width = CQSPI_INST_TYPE_DUAL;
>                         break;
> -               case SNOR_PROTO_1_1_4:
> +               case 4:
>                         f_pdata->data_width = CQSPI_INST_TYPE_QUAD;
>                         break;
> -               case SNOR_PROTO_1_1_8:
> +               case 8:
>                         f_pdata->data_width = CQSPI_INST_TYPE_OCTAL;
>                         break;
>                 default:
> @@ -888,36 +861,32 @@ static int cqspi_set_protocol(struct spi_nor *nor,
> const int read) }
>         }
> 
> -       cqspi_configure(nor);
> -
>         return 0;
>  }
> 
> -static ssize_t cqspi_write(struct spi_nor *nor, loff_t to,
> -                          size_t len, const u_char *buf)
> +static ssize_t cqspi_write(struct cqspi_flash_pdata *f_pdata,
> +                          const struct spi_mem_op *op)
>  {
> -       struct cqspi_flash_pdata *f_pdata = nor->priv;
>         struct cqspi_st *cqspi = f_pdata->cqspi;
> +       loff_t to = op->addr.val;
> +       size_t len = op->data.nbytes;
> +       const u_char *buf = op->data.buf.out;
>         int ret;
> 
> -       ret = cqspi_set_protocol(nor, 0);
> +       ret = cqspi_set_protocol(f_pdata, op);
>         if (ret)
>                 return ret;
> 
> -       ret = cqspi_write_setup(nor);
> +       ret = cqspi_write_setup(f_pdata, op);
>         if (ret)
>                 return ret;
> 
> -       if (f_pdata->use_direct_mode) {
> +       if (cqspi->use_dac_mode && ((to + len) <= cqspi->ahb_size)) {
>                 memcpy_toio(cqspi->ahb_base + to, buf, len);
> -               ret = cqspi_wait_idle(cqspi);
> -       } else {
> -               ret = cqspi_indirect_write_execute(nor, to, buf, len);
> +               return cqspi_wait_idle(cqspi);
>         }
> -       if (ret)
> -               return ret;
> 
> -       return len;
> +       return cqspi_indirect_write_execute(f_pdata, to, buf, len);
>  }
> 
>  static void cqspi_rx_dma_callback(void *param)
> @@ -927,11 +896,11 @@ static void cqspi_rx_dma_callback(void *param)
>         complete(&cqspi->rx_dma_complete);
>  }
> 
> -static int cqspi_direct_read_execute(struct spi_nor *nor, u_char *buf,
> -                                    loff_t from, size_t len)
> +static int cqspi_direct_read_execute(struct cqspi_flash_pdata *f_pdata,
> +                                    u_char *buf, loff_t from, size_t len)
>  {
> -       struct cqspi_flash_pdata *f_pdata = nor->priv;
>         struct cqspi_st *cqspi = f_pdata->cqspi;
> +       struct device *dev = &cqspi->pdev->dev;
>         enum dma_ctrl_flags flags = DMA_CTRL_ACK | DMA_PREP_INTERRUPT;
>         dma_addr_t dma_src = (dma_addr_t)cqspi->mmap_phys_base + from;
>         int ret = 0;
> @@ -944,15 +913,15 @@ static int cqspi_direct_read_execute(struct spi_nor
> *nor, u_char *buf, return 0;
>         }
> 
> -       dma_dst = dma_map_single(nor->dev, buf, len, DMA_FROM_DEVICE);
> -       if (dma_mapping_error(nor->dev, dma_dst)) {
> -               dev_err(nor->dev, "dma mapping failed\n");
> +       dma_dst = dma_map_single(dev, buf, len, DMA_FROM_DEVICE);
> +       if (dma_mapping_error(dev, dma_dst)) {
> +               dev_err(dev, "dma mapping failed\n");
>                 return -ENOMEM;
>         }
>         tx = dmaengine_prep_dma_memcpy(cqspi->rx_chan, dma_dst, dma_src,
>                                        len, flags);
>         if (!tx) {
> -               dev_err(nor->dev, "device_prep_dma_memcpy error\n");
> +               dev_err(dev, "device_prep_dma_memcpy error\n");
>                 ret = -EIO;
>                 goto err_unmap;
>         }
> @@ -964,7 +933,7 @@ static int cqspi_direct_read_execute(struct spi_nor
> *nor, u_char *buf,
> 
>         ret = dma_submit_error(cookie);
>         if (ret) {
> -               dev_err(nor->dev, "dma_submit_error %d\n", cookie);
> +               dev_err(dev, "dma_submit_error %d\n", cookie);
>                 ret = -EIO;
>                 goto err_unmap;
>         }
> @@ -973,99 +942,68 @@ static int cqspi_direct_read_execute(struct spi_nor
> *nor, u_char *buf, if
> (!wait_for_completion_timeout(&cqspi->rx_dma_complete,
>                                          msecs_to_jiffies(len))) {
>                 dmaengine_terminate_sync(cqspi->rx_chan);
> -               dev_err(nor->dev, "DMA wait_for_completion_timeout\n");
> +               dev_err(dev, "DMA wait_for_completion_timeout\n");
>                 ret = -ETIMEDOUT;
>                 goto err_unmap;
>         }
> 
>  err_unmap:
> -       dma_unmap_single(nor->dev, dma_dst, len, DMA_FROM_DEVICE);
> +       dma_unmap_single(dev, dma_dst, len, DMA_FROM_DEVICE);
> 
>         return ret;
>  }
> 
> -static ssize_t cqspi_read(struct spi_nor *nor, loff_t from,
> -                         size_t len, u_char *buf)
> -{
> -       struct cqspi_flash_pdata *f_pdata = nor->priv;
> -       int ret;
> -
> -       ret = cqspi_set_protocol(nor, 1);
> -       if (ret)
> -               return ret;
> -
> -       ret = cqspi_read_setup(nor);
> -       if (ret)
> -               return ret;
> -
> -       if (f_pdata->use_direct_mode)
> -               ret = cqspi_direct_read_execute(nor, buf, from, len);
> -       else
> -               ret = cqspi_indirect_read_execute(nor, buf, from, len);
> -       if (ret)
> -               return ret;
> -
> -       return len;
> -}
> -
> -static int cqspi_erase(struct spi_nor *nor, loff_t offs)
> +static ssize_t cqspi_read(struct cqspi_flash_pdata *f_pdata,
> +                         const struct spi_mem_op *op)
>  {
> +       struct cqspi_st *cqspi = f_pdata->cqspi;
> +       loff_t from = op->addr.val;
> +       size_t len = op->data.nbytes;
> +       u_char *buf = op->data.buf.in;
>         int ret;
> 
> -       ret = cqspi_set_protocol(nor, 0);
> +       ret = cqspi_set_protocol(f_pdata, op);
>         if (ret)
>                 return ret;
> 
> -       /* Send write enable, then erase commands. */
> -       ret = nor->controller_ops->write_reg(nor, SPINOR_OP_WREN, NULL, 0);

Dropping the Write Enable for erases can be done in a separate patch, since it 
is already done in the SPI NOR core. This would ease the review.

> +       ret = cqspi_read_setup(f_pdata, op);
>         if (ret)
>                 return ret;
> 
> -       /* Set up command buffer. */
> -       ret = cqspi_command_write_addr(nor, nor->erase_opcode, offs);
> -       if (ret)
> -               return ret;
> +       if (cqspi->use_dac_mode && ((from + len) <= cqspi->ahb_size))
> +               return cqspi_direct_read_execute(f_pdata, buf, from, len);
> 
> -       return 0;
> +       return cqspi_indirect_read_execute(f_pdata, buf, from, len);
>  }
> 
> -static int cqspi_prep(struct spi_nor *nor)
> +static int cqspi_mem_process(struct spi_mem *mem, const struct spi_mem_op
> *op) {
> -       struct cqspi_flash_pdata *f_pdata = nor->priv;
> -       struct cqspi_st *cqspi = f_pdata->cqspi;
> -
> -       mutex_lock(&cqspi->bus_mutex);
> -
> -       return 0;
> -}
> +       struct cqspi_st *cqspi = spi_master_get_devdata(mem->spi->master);
> +       struct cqspi_flash_pdata *f_pdata;
> 
> -static void cqspi_unprep(struct spi_nor *nor)
> -{
> -       struct cqspi_flash_pdata *f_pdata = nor->priv;
> -       struct cqspi_st *cqspi = f_pdata->cqspi;
> +       f_pdata = &cqspi->f_pdata[mem->spi->chip_select];
> +       cqspi_configure(f_pdata, mem->spi->max_speed_hz);
> 
> -       mutex_unlock(&cqspi->bus_mutex);
> -}
> +       if (op->data.dir == SPI_MEM_DATA_IN && op->data.buf.in) {
> +               if (!op->addr.nbytes)
> +                       return cqspi_command_read(f_pdata, op);
> 
> -static int cqspi_read_reg(struct spi_nor *nor, u8 opcode, u8 *buf, size_t
> len) -{
> -       int ret;
> +               return cqspi_read(f_pdata, op);
> +       }
> 
> -       ret = cqspi_set_protocol(nor, 0);
> -       if (!ret)
> -               ret = cqspi_command_read(nor, opcode, buf, len);
> +       if (!op->addr.nbytes || !op->data.buf.out)
> +               return cqspi_command_write(f_pdata, op);
> 
> -       return ret;
> +       return cqspi_write(f_pdata, op);
>  }
> 
> -static int cqspi_write_reg(struct spi_nor *nor, u8 opcode, const u8 *buf,
> -                          size_t len)
> +static int cqspi_exec_mem_op(struct spi_mem *mem, const struct spi_mem_op
> *op) {
>         int ret;
> 
> -       ret = cqspi_set_protocol(nor, 0);
> -       if (!ret)
> -               ret = cqspi_command_write(nor, opcode, buf, len);
> +       ret = cqspi_mem_process(mem, op);
> +       if (ret)
> +               dev_err(&mem->spi->dev, "operation failed with %d\n", ret);
> 
>         return ret;
>  }
> @@ -1107,26 +1045,26 @@ static int cqspi_of_get_flash_pdata(struct
> platform_device *pdev, return 0;
>  }
> 
> -static int cqspi_of_get_pdata(struct platform_device *pdev)
> +static int cqspi_of_get_pdata(struct cqspi_st *cqspi)
>  {
> -       struct device_node *np = pdev->dev.of_node;
> -       struct cqspi_st *cqspi = platform_get_drvdata(pdev);
> +       struct device *dev = &cqspi->pdev->dev;
> +       struct device_node *np = dev->of_node;
> 
>         cqspi->is_decoded_cs = of_property_read_bool(np,
> "cdns,is-decoded-cs");
> 
>         if (of_property_read_u32(np, "cdns,fifo-depth", &cqspi->fifo_depth))
> { -               dev_err(&pdev->dev, "couldn't determine fifo-depth\n"); +
>               dev_err(dev, "couldn't determine fifo-depth\n");
>                 return -ENXIO;
>         }
> 
>         if (of_property_read_u32(np, "cdns,fifo-width", &cqspi->fifo_width))
> { -               dev_err(&pdev->dev, "couldn't determine fifo-width\n"); +
>               dev_err(dev, "couldn't determine fifo-width\n");
>                 return -ENXIO;
>         }
> 
>         if (of_property_read_u32(np, "cdns,trigger-address",
>                                  &cqspi->trigger_address)) {
> -               dev_err(&pdev->dev, "couldn't determine trigger-address\n");
> +               dev_err(dev, "couldn't determine trigger-address\n");
> return -ENXIO;
>         }
> 
> @@ -1169,7 +1107,7 @@ static void cqspi_controller_init(struct cqspi_st
> *cqspi) cqspi_controller_enable(cqspi, 1);
>  }
> 
> -static void cqspi_request_mmap_dma(struct cqspi_st *cqspi)
> +static int cqspi_request_mmap_dma(struct cqspi_st *cqspi)
>  {
>         dma_cap_mask_t mask;
> 
> @@ -1178,133 +1116,79 @@ static void cqspi_request_mmap_dma(struct cqspi_st
> *cqspi)
> 
>         cqspi->rx_chan = dma_request_chan_by_mask(&mask);
>         if (IS_ERR(cqspi->rx_chan)) {
> -               dev_err(&cqspi->pdev->dev, "No Rx DMA available\n");
> +               int ret = PTR_ERR(cqspi->rx_chan);
> +
> +               if (ret != -EPROBE_DEFER)
> +                       dev_err(&cqspi->pdev->dev, "No Rx DMA available\n");
> cqspi->rx_chan = NULL;
> -               return;
> +               return ret;
>         }
>         init_completion(&cqspi->rx_dma_complete);
> +
> +       return 0;
>  }

Can we have the EPROBE_DEFER changes in a dedicated patch?

> 
> -static const struct spi_nor_controller_ops cqspi_controller_ops = {
> -       .prepare = cqspi_prep,
> -       .unprepare = cqspi_unprep,
> -       .read_reg = cqspi_read_reg,
> -       .write_reg = cqspi_write_reg,
> -       .read = cqspi_read,
> -       .write = cqspi_write,
> -       .erase = cqspi_erase,
> +static const struct spi_controller_mem_ops cqspi_mem_ops = {
> +       .exec_op = cqspi_exec_mem_op,
>  };
> 
> -static int cqspi_setup_flash(struct cqspi_st *cqspi, struct device_node
> *np) +static int cqspi_setup_flash(struct cqspi_st *cqspi)
>  {
>         struct platform_device *pdev = cqspi->pdev;
>         struct device *dev = &pdev->dev;
> -       const struct cqspi_driver_platdata *ddata;
> -       struct spi_nor_hwcaps hwcaps;
> +       struct device_node *np = dev->of_node;
>         struct cqspi_flash_pdata *f_pdata;
> -       struct spi_nor *nor;
> -       struct mtd_info *mtd;
>         unsigned int cs;
> -       int i, ret;
> -
> -       ddata = of_device_get_match_data(dev);
> -       if (!ddata) {
> -               dev_err(dev, "Couldn't find driver data\n");
> -               return -EINVAL;
> -       }
> -       hwcaps.mask = ddata->hwcaps_mask;
> 
>         /* Get flash device data */
>         for_each_available_child_of_node(dev->of_node, np) {
> -               ret = of_property_read_u32(np, "reg", &cs);
> -               if (ret) {
> +               if (of_property_read_u32(np, "reg", &cs)) {
>                         dev_err(dev, "Couldn't determine chip select.\n");
> -                       goto err;
> +                       continue;

reg is mandatory, you should keep the behaviour as it was.

>                 }
> 
>                 if (cs >= CQSPI_MAX_CHIPSELECT) {
> -                       ret = -EINVAL;
>                         dev_err(dev, "Chip select %d out of range.\n", cs);
> -                       goto err;
> +                       continue;
>                 }
> 
>                 f_pdata = &cqspi->f_pdata[cs];
>                 f_pdata->cqspi = cqspi;
>                 f_pdata->cs = cs;
> 
> -               ret = cqspi_of_get_flash_pdata(pdev, f_pdata, np);
> -               if (ret)
> -                       goto err;
> -
> -               nor = &f_pdata->nor;
> -               mtd = &nor->mtd;
> -
> -               mtd->priv = nor;
> -
> -               nor->dev = dev;
> -               spi_nor_set_flash_node(nor, np);
> -               nor->priv = f_pdata;
> -               nor->controller_ops = &cqspi_controller_ops;
> -
> -               mtd->name = devm_kasprintf(dev, GFP_KERNEL, "%s.%d",
> -                                          dev_name(dev), cs);
> -               if (!mtd->name) {
> -                       ret = -ENOMEM;
> -                       goto err;
> -               }
> -
> -               ret = spi_nor_scan(nor, NULL, &hwcaps);
> -               if (ret)
> -                       goto err;
> -
> -               ret = mtd_device_register(mtd, NULL, 0);
> -               if (ret)
> -                       goto err;
> -
> -               f_pdata->registered = true;
> -
> -               if (mtd->size <= cqspi->ahb_size &&
> -                   !(ddata->quirks & CQSPI_DISABLE_DAC_MODE)) {
> -                       f_pdata->use_direct_mode = true;
> -                       dev_dbg(nor->dev, "using direct mode for %s\n",
> -                               mtd->name);
> -
> -                       if (!cqspi->rx_chan)
> -                               cqspi_request_mmap_dma(cqspi);
> -               }
> +               return cqspi_of_get_flash_pdata(pdev, f_pdata, np);

drop the return. you now parse just the first discovered flash, whereas before 
your changes we parsed all the described flashes.

>         }
> 
>         return 0;
> -
> -err:
> -       for (i = 0; i < CQSPI_MAX_CHIPSELECT; i++)
> -               if (cqspi->f_pdata[i].registered)
> -                       mtd_device_unregister(&cqspi->f_pdata[i].nor.mtd);
> -       return ret;
>  }
> 
>  static int cqspi_probe(struct platform_device *pdev)
>  {
> -       struct device_node *np = pdev->dev.of_node;
> +       const struct cqspi_driver_platdata *ddata;
> +       struct reset_control *rstc, *rstc_ocp;
>         struct device *dev = &pdev->dev;
> +       struct spi_master *master;
> +       struct resource *res_ahb;
>         struct cqspi_st *cqspi;
>         struct resource *res;
> -       struct resource *res_ahb;
> -       struct reset_control *rstc, *rstc_ocp;
> -       const struct cqspi_driver_platdata *ddata;
>         int ret;
>         int irq;
> 
> -       cqspi = devm_kzalloc(dev, sizeof(*cqspi), GFP_KERNEL);
> -       if (!cqspi)
> +       master = spi_alloc_master(&pdev->dev, sizeof(*cqspi));
> +       if (!master) {
> +               dev_err(&pdev->dev, "spi_alloc_master failed\n");
>                 return -ENOMEM;
> +       }
> +       master->mode_bits = SPI_RX_QUAD | SPI_RX_DUAL;
> +       master->mem_ops = &cqspi_mem_ops;
> +       master->dev.of_node = pdev->dev.of_node;
> +
> +       cqspi = spi_master_get_devdata(master);
> 
> -       mutex_init(&cqspi->bus_mutex);
>         cqspi->pdev = pdev;
> -       platform_set_drvdata(pdev, cqspi);
> 
>         /* Obtain configuration from OF. */
> -       ret = cqspi_of_get_pdata(pdev);
> +       ret = cqspi_of_get_pdata(cqspi);
>         if (ret) {

spi_controller_put() to not leak memory.

Cheers,
ta


______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/

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

* Re: [PATCH v2 6/6] spi: Move cadence-quadspi driver to drivers/spi/
  2020-05-26  9:36   ` Vignesh Raghavendra
@ 2020-05-30 14:03     ` Tudor.Ambarus
  -1 siblings, 0 replies; 36+ messages in thread
From: Tudor.Ambarus @ 2020-05-30 14:03 UTC (permalink / raw)
  To: vigneshr
  Cc: broonie, bbrezillon, vadivel.muruganx.ramuthevar, linux-mtd,
	linux-kernel, linux-spi, simon.k.r.goldschmidt, dinguyen, marex

On Tuesday, May 26, 2020 12:36:04 PM EEST Vignesh Raghavendra wrote:
> From: Ramuthevar Vadivel Murugan
> <vadivel.muruganx.ramuthevar@linux.intel.com>
> 
> Now that cadence-quadspi has been converted to use spi-mem framework,
> move it under drivers/spi/
> 
> Update license header to match SPI subsystem style
> 
> Signed-off-by: Ramuthevar Vadivel Murugan
> <vadivel.muruganx.ramuthevar@linux.intel.com> Signed-off-by: Vignesh
> Raghavendra <vigneshr@ti.com>
> ---
>  drivers/mtd/spi-nor/controllers/Kconfig            | 11 -----------
>  drivers/mtd/spi-nor/controllers/Makefile           |  1 -
>  drivers/spi/Kconfig                                | 11 +++++++++++
>  drivers/spi/Makefile                               |  1 +
>  .../spi-cadence-quadspi.c}                         | 14 +++++++-------
>  5 files changed, 19 insertions(+), 19 deletions(-)
>  rename drivers/{mtd/spi-nor/controllers/cadence-quadspi.c =>
> spi/spi-cadence-quadspi.c} (99%)

I get a conflict when applying this on top of spi-nor/next.


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

* Re: [PATCH v2 6/6] spi: Move cadence-quadspi driver to drivers/spi/
@ 2020-05-30 14:03     ` Tudor.Ambarus
  0 siblings, 0 replies; 36+ messages in thread
From: Tudor.Ambarus @ 2020-05-30 14:03 UTC (permalink / raw)
  To: vigneshr
  Cc: marex, bbrezillon, dinguyen, simon.k.r.goldschmidt, linux-kernel,
	linux-spi, vadivel.muruganx.ramuthevar, broonie, linux-mtd

On Tuesday, May 26, 2020 12:36:04 PM EEST Vignesh Raghavendra wrote:
> From: Ramuthevar Vadivel Murugan
> <vadivel.muruganx.ramuthevar@linux.intel.com>
> 
> Now that cadence-quadspi has been converted to use spi-mem framework,
> move it under drivers/spi/
> 
> Update license header to match SPI subsystem style
> 
> Signed-off-by: Ramuthevar Vadivel Murugan
> <vadivel.muruganx.ramuthevar@linux.intel.com> Signed-off-by: Vignesh
> Raghavendra <vigneshr@ti.com>
> ---
>  drivers/mtd/spi-nor/controllers/Kconfig            | 11 -----------
>  drivers/mtd/spi-nor/controllers/Makefile           |  1 -
>  drivers/spi/Kconfig                                | 11 +++++++++++
>  drivers/spi/Makefile                               |  1 +
>  .../spi-cadence-quadspi.c}                         | 14 +++++++-------
>  5 files changed, 19 insertions(+), 19 deletions(-)
>  rename drivers/{mtd/spi-nor/controllers/cadence-quadspi.c =>
> spi/spi-cadence-quadspi.c} (99%)

I get a conflict when applying this on top of spi-nor/next.


______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/

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

* Re: [PATCH v2 5/6] mtd: spi-nor: Convert cadence-quadspi to use spi-mem framework
  2020-05-30 13:50     ` Tudor.Ambarus
@ 2020-06-01  4:56       ` Vignesh Raghavendra
  -1 siblings, 0 replies; 36+ messages in thread
From: Vignesh Raghavendra @ 2020-06-01  4:56 UTC (permalink / raw)
  To: Tudor.Ambarus
  Cc: broonie, bbrezillon, vadivel.muruganx.ramuthevar, linux-mtd,
	linux-kernel, linux-spi, simon.k.r.goldschmidt, dinguyen, marex



On 30/05/20 7:20 pm, Tudor.Ambarus@microchip.com wrote:
> Hi, Vignesh,
> 
> On Tuesday, May 26, 2020 12:36:03 PM EEST Vignesh Raghavendra wrote:
>> EXTERNAL EMAIL: Do not click links or open attachments unless you know the
>> content is safe
>>
>> From: Ramuthevar Vadivel Murugan
>> <vadivel.muruganx.ramuthevar@linux.intel.com>
>>
>> Move cadence-quadspi driver to use spi-mem framework. This is required
>> to make the driver support for SPI NAND flashes in future.
>>
>> Driver is feature compliant with existing SPI NOR version.
>>
>> Signed-off-by: Ramuthevar Vadivel Murugan
>> <vadivel.muruganx.ramuthevar@linux.intel.com> Signed-off-by: Vignesh
>> Raghavendra <vigneshr@ti.com>
>> ---
>>  .../mtd/spi-nor/controllers/cadence-quadspi.c | 469 +++++++-----------
>>  1 file changed, 183 insertions(+), 286 deletions(-)
>>
>> diff --git a/drivers/mtd/spi-nor/controllers/cadence-quadspi.c
>> b/drivers/mtd/spi-nor/controllers/cadence-quadspi.c index
>> 608ca657ff7f..c1df4b221889 100644
>> --- a/drivers/mtd/spi-nor/controllers/cadence-quadspi.c
>> +++ b/drivers/mtd/spi-nor/controllers/cadence-quadspi.c
>> @@ -3,6 +3,8 @@
>>   * Driver for Cadence QSPI Controller
>>   *
>>   * Copyright Altera Corporation (C) 2012-2014. All rights reserved.
>> + * Copyright Intel Corporation (C) 2019-2020. All rights reserved.
>> + * Copyright (C) 2020 Texas Instruments Incorporated - http://www.ti.com
>>   */
>>  #include <linux/clk.h>
>>  #include <linux/completion.h>
>> @@ -17,9 +19,6 @@
>>  #include <linux/jiffies.h>
>>  #include <linux/kernel.h>
>>  #include <linux/module.h>
>> -#include <linux/mtd/mtd.h>
>> -#include <linux/mtd/partitions.h>
>> -#include <linux/mtd/spi-nor.h>
>>  #include <linux/of_device.h>
>>  #include <linux/of.h>
>>  #include <linux/platform_device.h>
>> @@ -27,6 +26,7 @@
>>  #include <linux/reset.h>
>>  #include <linux/sched.h>
>>  #include <linux/spi/spi.h>
>> +#include <linux/spi/spi-mem.h>
>>  #include <linux/timer.h>
>>
>>  #define CQSPI_NAME                     "cadence-qspi"
>> @@ -36,16 +36,12 @@
>>  #define CQSPI_NEEDS_WR_DELAY           BIT(0)
>>  #define CQSPI_DISABLE_DAC_MODE         BIT(1)
>>
>> -/* Capabilities mask */
>> -#define CQSPI_BASE_HWCAPS_MASK                                 \
>> -       (SNOR_HWCAPS_READ | SNOR_HWCAPS_READ_FAST |             \
>> -       SNOR_HWCAPS_READ_1_1_2 | SNOR_HWCAPS_READ_1_1_4 |       \
>> -       SNOR_HWCAPS_PP)
>> +/* Capabilities */
>> +#define CQSPI_SUPPORTS_OCTAL           BIT(0)
>>
>>  struct cqspi_st;
>>
>>  struct cqspi_flash_pdata {
>> -       struct spi_nor  nor;
>>         struct cqspi_st *cqspi;
>>         u32             clk_rate;
>>         u32             read_delay;
>> @@ -58,7 +54,6 @@ struct cqspi_flash_pdata {
>>         u8              data_width;
>>         u8              cs;
>>         bool            registered;
> 
> you can drop this, as it is no longer used
> 
>> -       bool            use_direct_mode;
>>  };
>>
>>  struct cqspi_st {
>> @@ -71,7 +66,6 @@ struct cqspi_st {
>>         void __iomem            *ahb_base;
>>         resource_size_t         ahb_size;
>>         struct completion       transfer_complete;
>> -       struct mutex            bus_mutex;
>>
>>         struct dma_chan         *rx_chan;
>>         struct completion       rx_dma_complete;
>> @@ -85,6 +79,7 @@ struct cqspi_st {
>>         bool                    rclk_en;
>>         u32                     trigger_address;
>>         u32                     wr_delay;
>> +       bool                    use_dac_mode;
> 
> is use_dac_mode better than use_direct_mode? If you prefer "dac", maybe you 
> can rename this variable in 2/6

I will just keep "use_direct_mode" as is to minimize churn

> 
>>         struct cqspi_flash_pdata f_pdata[CQSPI_MAX_CHIPSELECT];
>>  };
>>
>> @@ -283,9 +278,8 @@ static irqreturn_t cqspi_irq_handler(int this_irq, void
>> *dev) return IRQ_HANDLED;
>>  }
>>
>> -static unsigned int cqspi_calc_rdreg(struct spi_nor *nor)
>> +static unsigned int cqspi_calc_rdreg(struct cqspi_flash_pdata *f_pdata)
>>  {
>> -       struct cqspi_flash_pdata *f_pdata = nor->priv;
>>         u32 rdreg = 0;
>>
>>         rdreg |= f_pdata->inst_width << CQSPI_REG_RD_INSTR_TYPE_INSTR_LSB;
>> @@ -352,19 +346,21 @@ static int cqspi_exec_flash_cmd(struct cqspi_st
>> *cqspi, unsigned int reg) return cqspi_wait_idle(cqspi);
>>  }
>>
>> -static int cqspi_command_read(struct spi_nor *nor, u8 opcode,
>> -                             u8 *rxbuf, size_t n_rx)
>> +static int cqspi_command_read(struct cqspi_flash_pdata *f_pdata,
>> +                             const struct spi_mem_op *op)
>>  {
>> -       struct cqspi_flash_pdata *f_pdata = nor->priv;
>>         struct cqspi_st *cqspi = f_pdata->cqspi;
>>         void __iomem *reg_base = cqspi->iobase;
>> +       u8 *rxbuf = op->data.buf.in;
>> +       u8 opcode = op->cmd.opcode;
> 
> dedicated variable for opcode is not really needed, it is used only once.

I did this intentionaly in view of 2 byte opcodes being added for Octal
DDR mode

> 
>> +       size_t n_rx = op->data.nbytes;
>>         unsigned int rdreg;
>>         unsigned int reg;
>>         size_t read_len;
>>         int status;
>>
>>         if (!n_rx || n_rx > CQSPI_STIG_DATA_LEN_MAX || !rxbuf) {
>> -               dev_err(nor->dev,
>> +               dev_err(&cqspi->pdev->dev,
>>                         "Invalid input argument, len %zu rxbuf 0x%p\n",
>>                         n_rx, rxbuf);
>>                 return -EINVAL;
>> @@ -372,7 +368,7 @@ static int cqspi_command_read(struct spi_nor *nor, u8
>> opcode,
>>
>>         reg = opcode << CQSPI_REG_CMDCTRL_OPCODE_LSB;
>>
>> -       rdreg = cqspi_calc_rdreg(nor);
>> +       rdreg = cqspi_calc_rdreg(f_pdata);
>>         writel(rdreg, reg_base + CQSPI_REG_RD_INSTR);
>>
>>         reg |= (0x1 << CQSPI_REG_CMDCTRL_RD_EN_LSB);
>> @@ -401,25 +397,35 @@ static int cqspi_command_read(struct spi_nor *nor, u8
>> opcode, return 0;
>>  }
>>
>> -static int cqspi_command_write(struct spi_nor *nor, const u8 opcode,
>> -                              const u8 *txbuf, size_t n_tx)
>> +static int cqspi_command_write(struct cqspi_flash_pdata *f_pdata,
>> +                              const struct spi_mem_op *op)
>>  {
>> -       struct cqspi_flash_pdata *f_pdata = nor->priv;
>>         struct cqspi_st *cqspi = f_pdata->cqspi;
>>         void __iomem *reg_base = cqspi->iobase;
>> +       const u8 opcode = op->cmd.opcode;
> 
> dedicated variable for opcode is not really needed, it is used only once.

Same here...

> 
>> +       const u8 *txbuf = op->data.buf.out;
>> +       size_t n_tx = op->data.nbytes;
>>         unsigned int reg;
>>         unsigned int data;
>>         size_t write_len;
>> -       int ret;
>>
>>         if (n_tx > CQSPI_STIG_DATA_LEN_MAX || (n_tx && !txbuf)) {
>> -               dev_err(nor->dev,
>> +               dev_err(&cqspi->pdev->dev,
>>                         "Invalid input argument, cmdlen %zu txbuf 0x%p\n",
>>                         n_tx, txbuf);
>>                 return -EINVAL;
>>         }
>>
>>         reg = opcode << CQSPI_REG_CMDCTRL_OPCODE_LSB;
>> +
>> +       if (op->addr.nbytes) {
>> +               reg |= (0x1 << CQSPI_REG_CMDCTRL_ADDR_EN_LSB);
>> +               reg |= ((op->addr.nbytes - 1) &
>> CQSPI_REG_CMDCTRL_ADD_BYTES_MASK)
>> +               <<
>> CQSPI_REG_CMDCTRL_ADD_BYTES_LSB;
> 
> you have a 80 chars checkpatch warning here, maybe replace it with smth like
> 	reg |= ((op->addr.nbytes - 1) &
> 	            CQSPI_REG_CMDCTRL_ADD_BYTES_MASK) <<
> 	           CQSPI_REG_CMDCTRL_ADD_BYTES_LSB;
> 

Yes, will fix..

>> +
>> +               writel(op->addr.val, reg_base + CQSPI_REG_CMDADDRESS);
>> +       }
>> +
>>         if (n_tx) {
>>                 reg |= (0x1 << CQSPI_REG_CMDCTRL_WR_EN_LSB);
>>                 reg |= ((n_tx - 1) & CQSPI_REG_CMDCTRL_WR_BYTES_MASK)
>> @@ -437,73 +443,46 @@ static int cqspi_command_write(struct spi_nor *nor,
>> const u8 opcode, writel(data, reg_base + CQSPI_REG_CMDWRITEDATAUPPER); }
>>         }
>> -       ret = cqspi_exec_flash_cmd(cqspi, reg);
>> -       return ret;
>> -}
>> -
>> -static int cqspi_command_write_addr(struct spi_nor *nor,
>> -                                   const u8 opcode, const unsigned int
>> addr) -{
>> -       struct cqspi_flash_pdata *f_pdata = nor->priv;
>> -       struct cqspi_st *cqspi = f_pdata->cqspi;
>> -       void __iomem *reg_base = cqspi->iobase;
>> -       unsigned int reg;
>> -
>> -       reg = opcode << CQSPI_REG_CMDCTRL_OPCODE_LSB;
>> -       reg |= (0x1 << CQSPI_REG_CMDCTRL_ADDR_EN_LSB);
>> -       reg |= ((nor->addr_width - 1) & CQSPI_REG_CMDCTRL_ADD_BYTES_MASK)
>> -               << CQSPI_REG_CMDCTRL_ADD_BYTES_LSB;
>> -
>> -       writel(addr, reg_base + CQSPI_REG_CMDADDRESS);
>>
>>         return cqspi_exec_flash_cmd(cqspi, reg);
>>  }
>>
>> -static int cqspi_read_setup(struct spi_nor *nor)
>> +static int cqspi_read_setup(struct cqspi_flash_pdata *f_pdata,
>> +                           const struct spi_mem_op *op)
>>  {
>> -       struct cqspi_flash_pdata *f_pdata = nor->priv;
>>         struct cqspi_st *cqspi = f_pdata->cqspi;
>>         void __iomem *reg_base = cqspi->iobase;
>>         unsigned int dummy_clk = 0;
>>         unsigned int reg;
>>
>> -       reg = nor->read_opcode << CQSPI_REG_RD_INSTR_OPCODE_LSB;
>> -       reg |= cqspi_calc_rdreg(nor);
>> +       reg = op->cmd.opcode << CQSPI_REG_RD_INSTR_OPCODE_LSB;
>> +       reg |= cqspi_calc_rdreg(f_pdata);
>>
>>         /* Setup dummy clock cycles */
>> -       dummy_clk = nor->read_dummy;
>> +       dummy_clk = op->dummy.nbytes * 8;
>>         if (dummy_clk > CQSPI_DUMMY_CLKS_MAX)
>>                 dummy_clk = CQSPI_DUMMY_CLKS_MAX;
>>
>> -       if (dummy_clk / 8) {
>> -               reg |= (1 << CQSPI_REG_RD_INSTR_MODE_EN_LSB);
>> -               /* Set mode bits high to ensure chip doesn't enter XIP */
>> -               writel(0xFF, reg_base + CQSPI_REG_MODE_BIT);
>> -
>> -               /* Need to subtract the mode byte (8 clocks). */
>> -               if (f_pdata->inst_width != CQSPI_INST_TYPE_QUAD)
>> -                       dummy_clk -= 8;
>> -
>> -               if (dummy_clk)
>> -                       reg |= (dummy_clk & CQSPI_REG_RD_INSTR_DUMMY_MASK)
>> -                              << CQSPI_REG_RD_INSTR_DUMMY_LSB;
>> -       }
>> +       if (dummy_clk / 8)
> 
> if (dummy_clk) should be enough. dummy_clk is either zero, or a multiple of 
> eight, or CQSPI_DUMMY_CLKS_MAX.


Will do.. Was just using the same logic as previous driver.

> 
>> +               reg |= (dummy_clk & CQSPI_REG_RD_INSTR_DUMMY_MASK)
>> +                      << CQSPI_REG_RD_INSTR_DUMMY_LSB;
> 
>>
>>         writel(reg, reg_base + CQSPI_REG_RD_INSTR);
>>
>>         /* Set address width */
>>         reg = readl(reg_base + CQSPI_REG_SIZE);
>>         reg &= ~CQSPI_REG_SIZE_ADDRESS_MASK;
>> -       reg |= (nor->addr_width - 1);
>> +       reg |= (op->addr.nbytes - 1);
>>         writel(reg, reg_base + CQSPI_REG_SIZE);
>>         return 0;
>>  }
>>
>> -static int cqspi_indirect_read_execute(struct spi_nor *nor, u8 *rxbuf,
>> -                                      loff_t from_addr, const size_t n_rx)
>> +static int cqspi_indirect_read_execute(struct cqspi_flash_pdata *f_pdata,
>> +                                      u8 *rxbuf, loff_t from_addr,
>> +                                      const size_t n_rx)
>>  {
>> -       struct cqspi_flash_pdata *f_pdata = nor->priv;
>>         struct cqspi_st *cqspi = f_pdata->cqspi;
>> +       struct device *dev = &cqspi->pdev->dev;
>>         void __iomem *reg_base = cqspi->iobase;
>>         void __iomem *ahb_base = cqspi->ahb_base;
>>         unsigned int remaining = n_rx;
>> @@ -526,13 +505,13 @@ static int cqspi_indirect_read_execute(struct spi_nor
>> *nor, u8 *rxbuf,
>>
>>         while (remaining > 0) {
>>                 if (!wait_for_completion_timeout(&cqspi->transfer_complete,
>> -                               msecs_to_jiffies(CQSPI_READ_TIMEOUT_MS)))
>> +                                               
>> msecs_to_jiffies(CQSPI_READ_TIMEOUT_MS))) ret = -ETIMEDOUT;
>>
>>                 bytes_to_read = cqspi_get_rd_sram_level(cqspi);
>>
>>                 if (ret && bytes_to_read == 0) {
>> -                       dev_err(nor->dev, "Indirect read timeout, no
>> bytes\n"); +                       dev_err(dev, "Indirect read timeout, no
>> bytes\n"); goto failrd;
>>                 }
>>
>> @@ -568,8 +547,7 @@ static int cqspi_indirect_read_execute(struct spi_nor
>> *nor, u8 *rxbuf, ret = cqspi_wait_for_bit(reg_base + CQSPI_REG_INDIRECTRD,
>>                                  CQSPI_REG_INDIRECTRD_DONE_MASK, 0);
>>         if (ret) {
>> -               dev_err(nor->dev,
>> -                       "Indirect read completion error (%i)\n", ret);
>> +               dev_err(dev, "Indirect read completion error (%i)\n", ret);
>>                 goto failrd;
>>         }
>>
>> @@ -591,32 +569,32 @@ static int cqspi_indirect_read_execute(struct spi_nor
>> *nor, u8 *rxbuf, return ret;
>>  }
>>
>> -static int cqspi_write_setup(struct spi_nor *nor)
>> +static int cqspi_write_setup(struct cqspi_flash_pdata *f_pdata,
>> +                            const struct spi_mem_op *op)
>>  {
>>         unsigned int reg;
>> -       struct cqspi_flash_pdata *f_pdata = nor->priv;
>>         struct cqspi_st *cqspi = f_pdata->cqspi;
>>         void __iomem *reg_base = cqspi->iobase;
>>
>>         /* Set opcode. */
>> -       reg = nor->program_opcode << CQSPI_REG_WR_INSTR_OPCODE_LSB;
>> +       reg = op->cmd.opcode << CQSPI_REG_WR_INSTR_OPCODE_LSB;
>>         writel(reg, reg_base + CQSPI_REG_WR_INSTR);
>> -       reg = cqspi_calc_rdreg(nor);
>> +       reg = cqspi_calc_rdreg(f_pdata);
>>         writel(reg, reg_base + CQSPI_REG_RD_INSTR);
>>
>>         reg = readl(reg_base + CQSPI_REG_SIZE);
>>         reg &= ~CQSPI_REG_SIZE_ADDRESS_MASK;
>> -       reg |= (nor->addr_width - 1);
>> +       reg |= (op->addr.nbytes - 1);
>>         writel(reg, reg_base + CQSPI_REG_SIZE);
>>         return 0;
>>  }
>>
>> -static int cqspi_indirect_write_execute(struct spi_nor *nor, loff_t
>> to_addr, -                                       const u8 *txbuf, const
>> size_t n_tx) +static int cqspi_indirect_write_execute(struct
>> cqspi_flash_pdata *f_pdata, +                                       loff_t
>> to_addr, const u8 *txbuf, +                                       const
>> size_t n_tx)
>>  {
>> -       const unsigned int page_size = nor->page_size;
>> -       struct cqspi_flash_pdata *f_pdata = nor->priv;
>>         struct cqspi_st *cqspi = f_pdata->cqspi;
>> +       struct device *dev = &cqspi->pdev->dev;
>>         void __iomem *reg_base = cqspi->iobase;
>>         unsigned int remaining = n_tx;
>>         unsigned int write_bytes;
>> @@ -646,7 +624,7 @@ static int cqspi_indirect_write_execute(struct spi_nor
>> *nor, loff_t to_addr, while (remaining > 0) {
>>                 size_t write_words, mod_bytes;
>>
>> -               write_bytes = remaining > page_size ? page_size : remaining;
>> +               write_bytes = remaining;
>>                 write_words = write_bytes / 4;
>>                 mod_bytes = write_bytes % 4;
>>                 /* Write 4 bytes at a time then single bytes. */
>> @@ -663,8 +641,8 @@ static int cqspi_indirect_write_execute(struct spi_nor
>> *nor, loff_t to_addr, }
>>
>>                 if (!wait_for_completion_timeout(&cqspi->transfer_complete,
>> -                                       msecs_to_jiffies(CQSPI_TIMEOUT_MS)))
>> { -                       dev_err(nor->dev, "Indirect write timeout\n"); + 
>>                                              
>> msecs_to_jiffies(CQSPI_TIMEOUT_MS))) { +                       dev_err(dev,
>> "Indirect write timeout\n");
>>                         ret = -ETIMEDOUT;
>>                         goto failwr;
>>                 }
>> @@ -679,8 +657,7 @@ static int cqspi_indirect_write_execute(struct spi_nor
>> *nor, loff_t to_addr, ret = cqspi_wait_for_bit(reg_base +
>> CQSPI_REG_INDIRECTWR,
>>                                  CQSPI_REG_INDIRECTWR_DONE_MASK, 0);
>>         if (ret) {
>> -               dev_err(nor->dev,
>> -                       "Indirect write completion error (%i)\n", ret);
>> +               dev_err(dev, "Indirect write completion error (%i)\n", ret);
>> goto failwr;
>>         }
>>
>> @@ -704,9 +681,8 @@ static int cqspi_indirect_write_execute(struct spi_nor
>> *nor, loff_t to_addr, return ret;
>>  }
>>
>> -static void cqspi_chipselect(struct spi_nor *nor)
>> +static void cqspi_chipselect(struct cqspi_flash_pdata *f_pdata)
>>  {
>> -       struct cqspi_flash_pdata *f_pdata = nor->priv;
>>         struct cqspi_st *cqspi = f_pdata->cqspi;
>>         void __iomem *reg_base = cqspi->iobase;
>>         unsigned int chip_select = f_pdata->cs;
>> @@ -745,9 +721,8 @@ static unsigned int calculate_ticks_for_ns(const
>> unsigned int ref_clk_hz, return ticks;
>>  }
>>
>> -static void cqspi_delay(struct spi_nor *nor)
>> +static void cqspi_delay(struct cqspi_flash_pdata *f_pdata)
>>  {
>> -       struct cqspi_flash_pdata *f_pdata = nor->priv;
>>         struct cqspi_st *cqspi = f_pdata->cqspi;
>>         void __iomem *iobase = cqspi->iobase;
>>         const unsigned int ref_clk_hz = cqspi->master_ref_clk_hz;
>> @@ -831,11 +806,10 @@ static void cqspi_controller_enable(struct cqspi_st
>> *cqspi, bool enable) writel(reg, reg_base + CQSPI_REG_CONFIG);
>>  }
>>
>> -static void cqspi_configure(struct spi_nor *nor)
>> +static void cqspi_configure(struct cqspi_flash_pdata *f_pdata,
>> +                           unsigned long sclk)
>>  {
>> -       struct cqspi_flash_pdata *f_pdata = nor->priv;
>>         struct cqspi_st *cqspi = f_pdata->cqspi;
>> -       const unsigned int sclk = f_pdata->clk_rate;
>>         int switch_cs = (cqspi->current_cs != f_pdata->cs);
>>         int switch_ck = (cqspi->sclk != sclk);
>>
>> @@ -845,14 +819,14 @@ static void cqspi_configure(struct spi_nor *nor)
>>         /* Switch chip select. */
>>         if (switch_cs) {
>>                 cqspi->current_cs = f_pdata->cs;
>> -               cqspi_chipselect(nor);
>> +               cqspi_chipselect(f_pdata);
>>         }
>>
>>         /* Setup baudrate divisor and delays */
>>         if (switch_ck) {
>>                 cqspi->sclk = sclk;
>>                 cqspi_config_baudrate_div(cqspi);
>> -               cqspi_delay(nor);
>> +               cqspi_delay(f_pdata);
>>                 cqspi_readdata_capture(cqspi, !cqspi->rclk_en,
>>                                        f_pdata->read_delay);
>>         }
>> @@ -861,26 +835,25 @@ static void cqspi_configure(struct spi_nor *nor)
>>                 cqspi_controller_enable(cqspi, 1);
>>  }
>>
>> -static int cqspi_set_protocol(struct spi_nor *nor, const int read)
>> +static int cqspi_set_protocol(struct cqspi_flash_pdata *f_pdata,
>> +                             const struct spi_mem_op *op)
>>  {
>> -       struct cqspi_flash_pdata *f_pdata = nor->priv;
>> -
>>         f_pdata->inst_width = CQSPI_INST_TYPE_SINGLE;
>>         f_pdata->addr_width = CQSPI_INST_TYPE_SINGLE;
>>         f_pdata->data_width = CQSPI_INST_TYPE_SINGLE;
>>
>> -       if (read) {
>> -               switch (nor->read_proto) {
>> -               case SNOR_PROTO_1_1_1:
>> +       if (op->data.dir == SPI_MEM_DATA_IN) {
>> +               switch (op->data.buswidth) {
>> +               case 1:
>>                         f_pdata->data_width = CQSPI_INST_TYPE_SINGLE;
>>                         break;
>> -               case SNOR_PROTO_1_1_2:
>> +               case 2:
>>                         f_pdata->data_width = CQSPI_INST_TYPE_DUAL;
>>                         break;
>> -               case SNOR_PROTO_1_1_4:
>> +               case 4:
>>                         f_pdata->data_width = CQSPI_INST_TYPE_QUAD;
>>                         break;
>> -               case SNOR_PROTO_1_1_8:
>> +               case 8:
>>                         f_pdata->data_width = CQSPI_INST_TYPE_OCTAL;
>>                         break;
>>                 default:
>> @@ -888,36 +861,32 @@ static int cqspi_set_protocol(struct spi_nor *nor,
>> const int read) }
>>         }
>>
>> -       cqspi_configure(nor);
>> -
>>         return 0;
>>  }
>>
>> -static ssize_t cqspi_write(struct spi_nor *nor, loff_t to,
>> -                          size_t len, const u_char *buf)
>> +static ssize_t cqspi_write(struct cqspi_flash_pdata *f_pdata,
>> +                          const struct spi_mem_op *op)
>>  {
>> -       struct cqspi_flash_pdata *f_pdata = nor->priv;
>>         struct cqspi_st *cqspi = f_pdata->cqspi;
>> +       loff_t to = op->addr.val;
>> +       size_t len = op->data.nbytes;
>> +       const u_char *buf = op->data.buf.out;
>>         int ret;
>>
>> -       ret = cqspi_set_protocol(nor, 0);
>> +       ret = cqspi_set_protocol(f_pdata, op);
>>         if (ret)
>>                 return ret;
>>
>> -       ret = cqspi_write_setup(nor);
>> +       ret = cqspi_write_setup(f_pdata, op);
>>         if (ret)
>>                 return ret;
>>
>> -       if (f_pdata->use_direct_mode) {
>> +       if (cqspi->use_dac_mode && ((to + len) <= cqspi->ahb_size)) {
>>                 memcpy_toio(cqspi->ahb_base + to, buf, len);
>> -               ret = cqspi_wait_idle(cqspi);
>> -       } else {
>> -               ret = cqspi_indirect_write_execute(nor, to, buf, len);
>> +               return cqspi_wait_idle(cqspi);
>>         }
>> -       if (ret)
>> -               return ret;
>>
>> -       return len;
>> +       return cqspi_indirect_write_execute(f_pdata, to, buf, len);
>>  }
>>
>>  static void cqspi_rx_dma_callback(void *param)
>> @@ -927,11 +896,11 @@ static void cqspi_rx_dma_callback(void *param)
>>         complete(&cqspi->rx_dma_complete);
>>  }
>>
>> -static int cqspi_direct_read_execute(struct spi_nor *nor, u_char *buf,
>> -                                    loff_t from, size_t len)
>> +static int cqspi_direct_read_execute(struct cqspi_flash_pdata *f_pdata,
>> +                                    u_char *buf, loff_t from, size_t len)
>>  {
>> -       struct cqspi_flash_pdata *f_pdata = nor->priv;
>>         struct cqspi_st *cqspi = f_pdata->cqspi;
>> +       struct device *dev = &cqspi->pdev->dev;
>>         enum dma_ctrl_flags flags = DMA_CTRL_ACK | DMA_PREP_INTERRUPT;
>>         dma_addr_t dma_src = (dma_addr_t)cqspi->mmap_phys_base + from;
>>         int ret = 0;
>> @@ -944,15 +913,15 @@ static int cqspi_direct_read_execute(struct spi_nor
>> *nor, u_char *buf, return 0;
>>         }
>>
>> -       dma_dst = dma_map_single(nor->dev, buf, len, DMA_FROM_DEVICE);
>> -       if (dma_mapping_error(nor->dev, dma_dst)) {
>> -               dev_err(nor->dev, "dma mapping failed\n");
>> +       dma_dst = dma_map_single(dev, buf, len, DMA_FROM_DEVICE);
>> +       if (dma_mapping_error(dev, dma_dst)) {
>> +               dev_err(dev, "dma mapping failed\n");
>>                 return -ENOMEM;
>>         }
>>         tx = dmaengine_prep_dma_memcpy(cqspi->rx_chan, dma_dst, dma_src,
>>                                        len, flags);
>>         if (!tx) {
>> -               dev_err(nor->dev, "device_prep_dma_memcpy error\n");
>> +               dev_err(dev, "device_prep_dma_memcpy error\n");
>>                 ret = -EIO;
>>                 goto err_unmap;
>>         }
>> @@ -964,7 +933,7 @@ static int cqspi_direct_read_execute(struct spi_nor
>> *nor, u_char *buf,
>>
>>         ret = dma_submit_error(cookie);
>>         if (ret) {
>> -               dev_err(nor->dev, "dma_submit_error %d\n", cookie);
>> +               dev_err(dev, "dma_submit_error %d\n", cookie);
>>                 ret = -EIO;
>>                 goto err_unmap;
>>         }
>> @@ -973,99 +942,68 @@ static int cqspi_direct_read_execute(struct spi_nor
>> *nor, u_char *buf, if
>> (!wait_for_completion_timeout(&cqspi->rx_dma_complete,
>>                                          msecs_to_jiffies(len))) {
>>                 dmaengine_terminate_sync(cqspi->rx_chan);
>> -               dev_err(nor->dev, "DMA wait_for_completion_timeout\n");
>> +               dev_err(dev, "DMA wait_for_completion_timeout\n");
>>                 ret = -ETIMEDOUT;
>>                 goto err_unmap;
>>         }
>>
>>  err_unmap:
>> -       dma_unmap_single(nor->dev, dma_dst, len, DMA_FROM_DEVICE);
>> +       dma_unmap_single(dev, dma_dst, len, DMA_FROM_DEVICE);
>>
>>         return ret;
>>  }
>>
>> -static ssize_t cqspi_read(struct spi_nor *nor, loff_t from,
>> -                         size_t len, u_char *buf)
>> -{
>> -       struct cqspi_flash_pdata *f_pdata = nor->priv;
>> -       int ret;
>> -
>> -       ret = cqspi_set_protocol(nor, 1);
>> -       if (ret)
>> -               return ret;
>> -
>> -       ret = cqspi_read_setup(nor);
>> -       if (ret)
>> -               return ret;
>> -
>> -       if (f_pdata->use_direct_mode)
>> -               ret = cqspi_direct_read_execute(nor, buf, from, len);
>> -       else
>> -               ret = cqspi_indirect_read_execute(nor, buf, from, len);
>> -       if (ret)
>> -               return ret;
>> -
>> -       return len;
>> -}
>> -
>> -static int cqspi_erase(struct spi_nor *nor, loff_t offs)
>> +static ssize_t cqspi_read(struct cqspi_flash_pdata *f_pdata,
>> +                         const struct spi_mem_op *op)
>>  {
>> +       struct cqspi_st *cqspi = f_pdata->cqspi;
>> +       loff_t from = op->addr.val;
>> +       size_t len = op->data.nbytes;
>> +       u_char *buf = op->data.buf.in;
>>         int ret;
>>
>> -       ret = cqspi_set_protocol(nor, 0);
>> +       ret = cqspi_set_protocol(f_pdata, op);
>>         if (ret)
>>                 return ret;
>>
>> -       /* Send write enable, then erase commands. */
>> -       ret = nor->controller_ops->write_reg(nor, SPINOR_OP_WREN, NULL, 0);
> 
> Dropping the Write Enable for erases can be done in a separate patch, since it 
> is already done in the SPI NOR core. This would ease the review.
> 

OK...

>> +       ret = cqspi_read_setup(f_pdata, op);
>>         if (ret)
>>                 return ret;
>>
>> -       /* Set up command buffer. */
>> -       ret = cqspi_command_write_addr(nor, nor->erase_opcode, offs);
>> -       if (ret)
>> -               return ret;
>> +       if (cqspi->use_dac_mode && ((from + len) <= cqspi->ahb_size))
>> +               return cqspi_direct_read_execute(f_pdata, buf, from, len);
>>
>> -       return 0;
>> +       return cqspi_indirect_read_execute(f_pdata, buf, from, len);
>>  }
>>
>> -static int cqspi_prep(struct spi_nor *nor)
>> +static int cqspi_mem_process(struct spi_mem *mem, const struct spi_mem_op
>> *op) {
>> -       struct cqspi_flash_pdata *f_pdata = nor->priv;
>> -       struct cqspi_st *cqspi = f_pdata->cqspi;
>> -
>> -       mutex_lock(&cqspi->bus_mutex);
>> -
>> -       return 0;
>> -}
>> +       struct cqspi_st *cqspi = spi_master_get_devdata(mem->spi->master);
>> +       struct cqspi_flash_pdata *f_pdata;
>>
>> -static void cqspi_unprep(struct spi_nor *nor)
>> -{
>> -       struct cqspi_flash_pdata *f_pdata = nor->priv;
>> -       struct cqspi_st *cqspi = f_pdata->cqspi;
>> +       f_pdata = &cqspi->f_pdata[mem->spi->chip_select];
>> +       cqspi_configure(f_pdata, mem->spi->max_speed_hz);
>>
>> -       mutex_unlock(&cqspi->bus_mutex);
>> -}
>> +       if (op->data.dir == SPI_MEM_DATA_IN && op->data.buf.in) {
>> +               if (!op->addr.nbytes)
>> +                       return cqspi_command_read(f_pdata, op);
>>
>> -static int cqspi_read_reg(struct spi_nor *nor, u8 opcode, u8 *buf, size_t
>> len) -{
>> -       int ret;
>> +               return cqspi_read(f_pdata, op);
>> +       }
>>
>> -       ret = cqspi_set_protocol(nor, 0);
>> -       if (!ret)
>> -               ret = cqspi_command_read(nor, opcode, buf, len);
>> +       if (!op->addr.nbytes || !op->data.buf.out)
>> +               return cqspi_command_write(f_pdata, op);
>>
>> -       return ret;
>> +       return cqspi_write(f_pdata, op);
>>  }
>>
>> -static int cqspi_write_reg(struct spi_nor *nor, u8 opcode, const u8 *buf,
>> -                          size_t len)
>> +static int cqspi_exec_mem_op(struct spi_mem *mem, const struct spi_mem_op
>> *op) {
>>         int ret;
>>
>> -       ret = cqspi_set_protocol(nor, 0);
>> -       if (!ret)
>> -               ret = cqspi_command_write(nor, opcode, buf, len);
>> +       ret = cqspi_mem_process(mem, op);
>> +       if (ret)
>> +               dev_err(&mem->spi->dev, "operation failed with %d\n", ret);
>>
>>         return ret;
>>  }
>> @@ -1107,26 +1045,26 @@ static int cqspi_of_get_flash_pdata(struct
>> platform_device *pdev, return 0;
>>  }
>>
>> -static int cqspi_of_get_pdata(struct platform_device *pdev)
>> +static int cqspi_of_get_pdata(struct cqspi_st *cqspi)
>>  {
>> -       struct device_node *np = pdev->dev.of_node;
>> -       struct cqspi_st *cqspi = platform_get_drvdata(pdev);
>> +       struct device *dev = &cqspi->pdev->dev;
>> +       struct device_node *np = dev->of_node;
>>
>>         cqspi->is_decoded_cs = of_property_read_bool(np,
>> "cdns,is-decoded-cs");
>>
>>         if (of_property_read_u32(np, "cdns,fifo-depth", &cqspi->fifo_depth))
>> { -               dev_err(&pdev->dev, "couldn't determine fifo-depth\n"); +
>>               dev_err(dev, "couldn't determine fifo-depth\n");
>>                 return -ENXIO;
>>         }
>>
>>         if (of_property_read_u32(np, "cdns,fifo-width", &cqspi->fifo_width))
>> { -               dev_err(&pdev->dev, "couldn't determine fifo-width\n"); +
>>               dev_err(dev, "couldn't determine fifo-width\n");
>>                 return -ENXIO;
>>         }
>>
>>         if (of_property_read_u32(np, "cdns,trigger-address",
>>                                  &cqspi->trigger_address)) {
>> -               dev_err(&pdev->dev, "couldn't determine trigger-address\n");
>> +               dev_err(dev, "couldn't determine trigger-address\n");
>> return -ENXIO;
>>         }
>>
>> @@ -1169,7 +1107,7 @@ static void cqspi_controller_init(struct cqspi_st
>> *cqspi) cqspi_controller_enable(cqspi, 1);
>>  }
>>
>> -static void cqspi_request_mmap_dma(struct cqspi_st *cqspi)
>> +static int cqspi_request_mmap_dma(struct cqspi_st *cqspi)
>>  {
>>         dma_cap_mask_t mask;
>>
>> @@ -1178,133 +1116,79 @@ static void cqspi_request_mmap_dma(struct cqspi_st
>> *cqspi)
>>
>>         cqspi->rx_chan = dma_request_chan_by_mask(&mask);
>>         if (IS_ERR(cqspi->rx_chan)) {
>> -               dev_err(&cqspi->pdev->dev, "No Rx DMA available\n");
>> +               int ret = PTR_ERR(cqspi->rx_chan);
>> +
>> +               if (ret != -EPROBE_DEFER)
>> +                       dev_err(&cqspi->pdev->dev, "No Rx DMA available\n");
>> cqspi->rx_chan = NULL;
>> -               return;
>> +               return ret;
>>         }
>>         init_completion(&cqspi->rx_dma_complete);
>> +
>> +       return 0;
>>  }
> 
> Can we have the EPROBE_DEFER changes in a dedicated patch?
> 

Ok..

>>
>> -static const struct spi_nor_controller_ops cqspi_controller_ops = {
>> -       .prepare = cqspi_prep,
>> -       .unprepare = cqspi_unprep,
>> -       .read_reg = cqspi_read_reg,
>> -       .write_reg = cqspi_write_reg,
>> -       .read = cqspi_read,
>> -       .write = cqspi_write,
>> -       .erase = cqspi_erase,
>> +static const struct spi_controller_mem_ops cqspi_mem_ops = {
>> +       .exec_op = cqspi_exec_mem_op,
>>  };
>>
>> -static int cqspi_setup_flash(struct cqspi_st *cqspi, struct device_node
>> *np) +static int cqspi_setup_flash(struct cqspi_st *cqspi)
>>  {
>>         struct platform_device *pdev = cqspi->pdev;
>>         struct device *dev = &pdev->dev;
>> -       const struct cqspi_driver_platdata *ddata;
>> -       struct spi_nor_hwcaps hwcaps;
>> +       struct device_node *np = dev->of_node;
>>         struct cqspi_flash_pdata *f_pdata;
>> -       struct spi_nor *nor;
>> -       struct mtd_info *mtd;
>>         unsigned int cs;
>> -       int i, ret;
>> -
>> -       ddata = of_device_get_match_data(dev);
>> -       if (!ddata) {
>> -               dev_err(dev, "Couldn't find driver data\n");
>> -               return -EINVAL;
>> -       }
>> -       hwcaps.mask = ddata->hwcaps_mask;
>>
>>         /* Get flash device data */
>>         for_each_available_child_of_node(dev->of_node, np) {
>> -               ret = of_property_read_u32(np, "reg", &cs);
>> -               if (ret) {
>> +               if (of_property_read_u32(np, "reg", &cs)) {
>>                         dev_err(dev, "Couldn't determine chip select.\n");
>> -                       goto err;
>> +                       continue;
> 
> reg is mandatory, you should keep the behaviour as it was.

Ok..

> 
>>                 }
>>
>>                 if (cs >= CQSPI_MAX_CHIPSELECT) {
>> -                       ret = -EINVAL;
>>                         dev_err(dev, "Chip select %d out of range.\n", cs);
>> -                       goto err;
>> +                       continue;
>>                 }
>>
>>                 f_pdata = &cqspi->f_pdata[cs];
>>                 f_pdata->cqspi = cqspi;
>>                 f_pdata->cs = cs;
>>
>> -               ret = cqspi_of_get_flash_pdata(pdev, f_pdata, np);
>> -               if (ret)
>> -                       goto err;
>> -
>> -               nor = &f_pdata->nor;
>> -               mtd = &nor->mtd;
>> -
>> -               mtd->priv = nor;
>> -
>> -               nor->dev = dev;
>> -               spi_nor_set_flash_node(nor, np);
>> -               nor->priv = f_pdata;
>> -               nor->controller_ops = &cqspi_controller_ops;
>> -
>> -               mtd->name = devm_kasprintf(dev, GFP_KERNEL, "%s.%d",
>> -                                          dev_name(dev), cs);
>> -               if (!mtd->name) {
>> -                       ret = -ENOMEM;
>> -                       goto err;
>> -               }
>> -
>> -               ret = spi_nor_scan(nor, NULL, &hwcaps);
>> -               if (ret)
>> -                       goto err;
>> -
>> -               ret = mtd_device_register(mtd, NULL, 0);
>> -               if (ret)
>> -                       goto err;
>> -
>> -               f_pdata->registered = true;
>> -
>> -               if (mtd->size <= cqspi->ahb_size &&
>> -                   !(ddata->quirks & CQSPI_DISABLE_DAC_MODE)) {
>> -                       f_pdata->use_direct_mode = true;
>> -                       dev_dbg(nor->dev, "using direct mode for %s\n",
>> -                               mtd->name);
>> -
>> -                       if (!cqspi->rx_chan)
>> -                               cqspi_request_mmap_dma(cqspi);
>> -               }
>> +               return cqspi_of_get_flash_pdata(pdev, f_pdata, np);
> 
> drop the return. you now parse just the first discovered flash, whereas before 
> your changes we parsed all the described flashes.
> 

Right, this is a bug, will fix in v3... This should only return on error:
	int ret;

	ret = cqspi_of_get_flash_pdata(pdev, f_pdata, np);
	if (ret)
		return ret;

>>         }
>>
>>         return 0;
>> -
>> -err:
>> -       for (i = 0; i < CQSPI_MAX_CHIPSELECT; i++)
>> -               if (cqspi->f_pdata[i].registered)
>> -                       mtd_device_unregister(&cqspi->f_pdata[i].nor.mtd);
>> -       return ret;
>>  }
>>
>>  static int cqspi_probe(struct platform_device *pdev)
>>  {
>> -       struct device_node *np = pdev->dev.of_node;
>> +       const struct cqspi_driver_platdata *ddata;
>> +       struct reset_control *rstc, *rstc_ocp;
>>         struct device *dev = &pdev->dev;
>> +       struct spi_master *master;
>> +       struct resource *res_ahb;
>>         struct cqspi_st *cqspi;
>>         struct resource *res;
>> -       struct resource *res_ahb;
>> -       struct reset_control *rstc, *rstc_ocp;
>> -       const struct cqspi_driver_platdata *ddata;
>>         int ret;
>>         int irq;
>>
>> -       cqspi = devm_kzalloc(dev, sizeof(*cqspi), GFP_KERNEL);
>> -       if (!cqspi)
>> +       master = spi_alloc_master(&pdev->dev, sizeof(*cqspi));
>> +       if (!master) {
>> +               dev_err(&pdev->dev, "spi_alloc_master failed\n");
>>                 return -ENOMEM;
>> +       }
>> +       master->mode_bits = SPI_RX_QUAD | SPI_RX_DUAL;
>> +       master->mem_ops = &cqspi_mem_ops;
>> +       master->dev.of_node = pdev->dev.of_node;
>> +
>> +       cqspi = spi_master_get_devdata(master);
>>
>> -       mutex_init(&cqspi->bus_mutex);
>>         cqspi->pdev = pdev;
>> -       platform_set_drvdata(pdev, cqspi);
>>
>>         /* Obtain configuration from OF. */
>> -       ret = cqspi_of_get_pdata(pdev);
>> +       ret = cqspi_of_get_pdata(cqspi);
>>         if (ret) {
> 
> spi_controller_put() to not leak memory.
> 

Ah, yes!

Thanks for the review!

Regards
Vignesh

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

* Re: [PATCH v2 5/6] mtd: spi-nor: Convert cadence-quadspi to use spi-mem framework
@ 2020-06-01  4:56       ` Vignesh Raghavendra
  0 siblings, 0 replies; 36+ messages in thread
From: Vignesh Raghavendra @ 2020-06-01  4:56 UTC (permalink / raw)
  To: Tudor.Ambarus
  Cc: marex, bbrezillon, dinguyen, simon.k.r.goldschmidt, linux-kernel,
	linux-spi, vadivel.muruganx.ramuthevar, broonie, linux-mtd



On 30/05/20 7:20 pm, Tudor.Ambarus@microchip.com wrote:
> Hi, Vignesh,
> 
> On Tuesday, May 26, 2020 12:36:03 PM EEST Vignesh Raghavendra wrote:
>> EXTERNAL EMAIL: Do not click links or open attachments unless you know the
>> content is safe
>>
>> From: Ramuthevar Vadivel Murugan
>> <vadivel.muruganx.ramuthevar@linux.intel.com>
>>
>> Move cadence-quadspi driver to use spi-mem framework. This is required
>> to make the driver support for SPI NAND flashes in future.
>>
>> Driver is feature compliant with existing SPI NOR version.
>>
>> Signed-off-by: Ramuthevar Vadivel Murugan
>> <vadivel.muruganx.ramuthevar@linux.intel.com> Signed-off-by: Vignesh
>> Raghavendra <vigneshr@ti.com>
>> ---
>>  .../mtd/spi-nor/controllers/cadence-quadspi.c | 469 +++++++-----------
>>  1 file changed, 183 insertions(+), 286 deletions(-)
>>
>> diff --git a/drivers/mtd/spi-nor/controllers/cadence-quadspi.c
>> b/drivers/mtd/spi-nor/controllers/cadence-quadspi.c index
>> 608ca657ff7f..c1df4b221889 100644
>> --- a/drivers/mtd/spi-nor/controllers/cadence-quadspi.c
>> +++ b/drivers/mtd/spi-nor/controllers/cadence-quadspi.c
>> @@ -3,6 +3,8 @@
>>   * Driver for Cadence QSPI Controller
>>   *
>>   * Copyright Altera Corporation (C) 2012-2014. All rights reserved.
>> + * Copyright Intel Corporation (C) 2019-2020. All rights reserved.
>> + * Copyright (C) 2020 Texas Instruments Incorporated - http://www.ti.com
>>   */
>>  #include <linux/clk.h>
>>  #include <linux/completion.h>
>> @@ -17,9 +19,6 @@
>>  #include <linux/jiffies.h>
>>  #include <linux/kernel.h>
>>  #include <linux/module.h>
>> -#include <linux/mtd/mtd.h>
>> -#include <linux/mtd/partitions.h>
>> -#include <linux/mtd/spi-nor.h>
>>  #include <linux/of_device.h>
>>  #include <linux/of.h>
>>  #include <linux/platform_device.h>
>> @@ -27,6 +26,7 @@
>>  #include <linux/reset.h>
>>  #include <linux/sched.h>
>>  #include <linux/spi/spi.h>
>> +#include <linux/spi/spi-mem.h>
>>  #include <linux/timer.h>
>>
>>  #define CQSPI_NAME                     "cadence-qspi"
>> @@ -36,16 +36,12 @@
>>  #define CQSPI_NEEDS_WR_DELAY           BIT(0)
>>  #define CQSPI_DISABLE_DAC_MODE         BIT(1)
>>
>> -/* Capabilities mask */
>> -#define CQSPI_BASE_HWCAPS_MASK                                 \
>> -       (SNOR_HWCAPS_READ | SNOR_HWCAPS_READ_FAST |             \
>> -       SNOR_HWCAPS_READ_1_1_2 | SNOR_HWCAPS_READ_1_1_4 |       \
>> -       SNOR_HWCAPS_PP)
>> +/* Capabilities */
>> +#define CQSPI_SUPPORTS_OCTAL           BIT(0)
>>
>>  struct cqspi_st;
>>
>>  struct cqspi_flash_pdata {
>> -       struct spi_nor  nor;
>>         struct cqspi_st *cqspi;
>>         u32             clk_rate;
>>         u32             read_delay;
>> @@ -58,7 +54,6 @@ struct cqspi_flash_pdata {
>>         u8              data_width;
>>         u8              cs;
>>         bool            registered;
> 
> you can drop this, as it is no longer used
> 
>> -       bool            use_direct_mode;
>>  };
>>
>>  struct cqspi_st {
>> @@ -71,7 +66,6 @@ struct cqspi_st {
>>         void __iomem            *ahb_base;
>>         resource_size_t         ahb_size;
>>         struct completion       transfer_complete;
>> -       struct mutex            bus_mutex;
>>
>>         struct dma_chan         *rx_chan;
>>         struct completion       rx_dma_complete;
>> @@ -85,6 +79,7 @@ struct cqspi_st {
>>         bool                    rclk_en;
>>         u32                     trigger_address;
>>         u32                     wr_delay;
>> +       bool                    use_dac_mode;
> 
> is use_dac_mode better than use_direct_mode? If you prefer "dac", maybe you 
> can rename this variable in 2/6

I will just keep "use_direct_mode" as is to minimize churn

> 
>>         struct cqspi_flash_pdata f_pdata[CQSPI_MAX_CHIPSELECT];
>>  };
>>
>> @@ -283,9 +278,8 @@ static irqreturn_t cqspi_irq_handler(int this_irq, void
>> *dev) return IRQ_HANDLED;
>>  }
>>
>> -static unsigned int cqspi_calc_rdreg(struct spi_nor *nor)
>> +static unsigned int cqspi_calc_rdreg(struct cqspi_flash_pdata *f_pdata)
>>  {
>> -       struct cqspi_flash_pdata *f_pdata = nor->priv;
>>         u32 rdreg = 0;
>>
>>         rdreg |= f_pdata->inst_width << CQSPI_REG_RD_INSTR_TYPE_INSTR_LSB;
>> @@ -352,19 +346,21 @@ static int cqspi_exec_flash_cmd(struct cqspi_st
>> *cqspi, unsigned int reg) return cqspi_wait_idle(cqspi);
>>  }
>>
>> -static int cqspi_command_read(struct spi_nor *nor, u8 opcode,
>> -                             u8 *rxbuf, size_t n_rx)
>> +static int cqspi_command_read(struct cqspi_flash_pdata *f_pdata,
>> +                             const struct spi_mem_op *op)
>>  {
>> -       struct cqspi_flash_pdata *f_pdata = nor->priv;
>>         struct cqspi_st *cqspi = f_pdata->cqspi;
>>         void __iomem *reg_base = cqspi->iobase;
>> +       u8 *rxbuf = op->data.buf.in;
>> +       u8 opcode = op->cmd.opcode;
> 
> dedicated variable for opcode is not really needed, it is used only once.

I did this intentionaly in view of 2 byte opcodes being added for Octal
DDR mode

> 
>> +       size_t n_rx = op->data.nbytes;
>>         unsigned int rdreg;
>>         unsigned int reg;
>>         size_t read_len;
>>         int status;
>>
>>         if (!n_rx || n_rx > CQSPI_STIG_DATA_LEN_MAX || !rxbuf) {
>> -               dev_err(nor->dev,
>> +               dev_err(&cqspi->pdev->dev,
>>                         "Invalid input argument, len %zu rxbuf 0x%p\n",
>>                         n_rx, rxbuf);
>>                 return -EINVAL;
>> @@ -372,7 +368,7 @@ static int cqspi_command_read(struct spi_nor *nor, u8
>> opcode,
>>
>>         reg = opcode << CQSPI_REG_CMDCTRL_OPCODE_LSB;
>>
>> -       rdreg = cqspi_calc_rdreg(nor);
>> +       rdreg = cqspi_calc_rdreg(f_pdata);
>>         writel(rdreg, reg_base + CQSPI_REG_RD_INSTR);
>>
>>         reg |= (0x1 << CQSPI_REG_CMDCTRL_RD_EN_LSB);
>> @@ -401,25 +397,35 @@ static int cqspi_command_read(struct spi_nor *nor, u8
>> opcode, return 0;
>>  }
>>
>> -static int cqspi_command_write(struct spi_nor *nor, const u8 opcode,
>> -                              const u8 *txbuf, size_t n_tx)
>> +static int cqspi_command_write(struct cqspi_flash_pdata *f_pdata,
>> +                              const struct spi_mem_op *op)
>>  {
>> -       struct cqspi_flash_pdata *f_pdata = nor->priv;
>>         struct cqspi_st *cqspi = f_pdata->cqspi;
>>         void __iomem *reg_base = cqspi->iobase;
>> +       const u8 opcode = op->cmd.opcode;
> 
> dedicated variable for opcode is not really needed, it is used only once.

Same here...

> 
>> +       const u8 *txbuf = op->data.buf.out;
>> +       size_t n_tx = op->data.nbytes;
>>         unsigned int reg;
>>         unsigned int data;
>>         size_t write_len;
>> -       int ret;
>>
>>         if (n_tx > CQSPI_STIG_DATA_LEN_MAX || (n_tx && !txbuf)) {
>> -               dev_err(nor->dev,
>> +               dev_err(&cqspi->pdev->dev,
>>                         "Invalid input argument, cmdlen %zu txbuf 0x%p\n",
>>                         n_tx, txbuf);
>>                 return -EINVAL;
>>         }
>>
>>         reg = opcode << CQSPI_REG_CMDCTRL_OPCODE_LSB;
>> +
>> +       if (op->addr.nbytes) {
>> +               reg |= (0x1 << CQSPI_REG_CMDCTRL_ADDR_EN_LSB);
>> +               reg |= ((op->addr.nbytes - 1) &
>> CQSPI_REG_CMDCTRL_ADD_BYTES_MASK)
>> +               <<
>> CQSPI_REG_CMDCTRL_ADD_BYTES_LSB;
> 
> you have a 80 chars checkpatch warning here, maybe replace it with smth like
> 	reg |= ((op->addr.nbytes - 1) &
> 	            CQSPI_REG_CMDCTRL_ADD_BYTES_MASK) <<
> 	           CQSPI_REG_CMDCTRL_ADD_BYTES_LSB;
> 

Yes, will fix..

>> +
>> +               writel(op->addr.val, reg_base + CQSPI_REG_CMDADDRESS);
>> +       }
>> +
>>         if (n_tx) {
>>                 reg |= (0x1 << CQSPI_REG_CMDCTRL_WR_EN_LSB);
>>                 reg |= ((n_tx - 1) & CQSPI_REG_CMDCTRL_WR_BYTES_MASK)
>> @@ -437,73 +443,46 @@ static int cqspi_command_write(struct spi_nor *nor,
>> const u8 opcode, writel(data, reg_base + CQSPI_REG_CMDWRITEDATAUPPER); }
>>         }
>> -       ret = cqspi_exec_flash_cmd(cqspi, reg);
>> -       return ret;
>> -}
>> -
>> -static int cqspi_command_write_addr(struct spi_nor *nor,
>> -                                   const u8 opcode, const unsigned int
>> addr) -{
>> -       struct cqspi_flash_pdata *f_pdata = nor->priv;
>> -       struct cqspi_st *cqspi = f_pdata->cqspi;
>> -       void __iomem *reg_base = cqspi->iobase;
>> -       unsigned int reg;
>> -
>> -       reg = opcode << CQSPI_REG_CMDCTRL_OPCODE_LSB;
>> -       reg |= (0x1 << CQSPI_REG_CMDCTRL_ADDR_EN_LSB);
>> -       reg |= ((nor->addr_width - 1) & CQSPI_REG_CMDCTRL_ADD_BYTES_MASK)
>> -               << CQSPI_REG_CMDCTRL_ADD_BYTES_LSB;
>> -
>> -       writel(addr, reg_base + CQSPI_REG_CMDADDRESS);
>>
>>         return cqspi_exec_flash_cmd(cqspi, reg);
>>  }
>>
>> -static int cqspi_read_setup(struct spi_nor *nor)
>> +static int cqspi_read_setup(struct cqspi_flash_pdata *f_pdata,
>> +                           const struct spi_mem_op *op)
>>  {
>> -       struct cqspi_flash_pdata *f_pdata = nor->priv;
>>         struct cqspi_st *cqspi = f_pdata->cqspi;
>>         void __iomem *reg_base = cqspi->iobase;
>>         unsigned int dummy_clk = 0;
>>         unsigned int reg;
>>
>> -       reg = nor->read_opcode << CQSPI_REG_RD_INSTR_OPCODE_LSB;
>> -       reg |= cqspi_calc_rdreg(nor);
>> +       reg = op->cmd.opcode << CQSPI_REG_RD_INSTR_OPCODE_LSB;
>> +       reg |= cqspi_calc_rdreg(f_pdata);
>>
>>         /* Setup dummy clock cycles */
>> -       dummy_clk = nor->read_dummy;
>> +       dummy_clk = op->dummy.nbytes * 8;
>>         if (dummy_clk > CQSPI_DUMMY_CLKS_MAX)
>>                 dummy_clk = CQSPI_DUMMY_CLKS_MAX;
>>
>> -       if (dummy_clk / 8) {
>> -               reg |= (1 << CQSPI_REG_RD_INSTR_MODE_EN_LSB);
>> -               /* Set mode bits high to ensure chip doesn't enter XIP */
>> -               writel(0xFF, reg_base + CQSPI_REG_MODE_BIT);
>> -
>> -               /* Need to subtract the mode byte (8 clocks). */
>> -               if (f_pdata->inst_width != CQSPI_INST_TYPE_QUAD)
>> -                       dummy_clk -= 8;
>> -
>> -               if (dummy_clk)
>> -                       reg |= (dummy_clk & CQSPI_REG_RD_INSTR_DUMMY_MASK)
>> -                              << CQSPI_REG_RD_INSTR_DUMMY_LSB;
>> -       }
>> +       if (dummy_clk / 8)
> 
> if (dummy_clk) should be enough. dummy_clk is either zero, or a multiple of 
> eight, or CQSPI_DUMMY_CLKS_MAX.


Will do.. Was just using the same logic as previous driver.

> 
>> +               reg |= (dummy_clk & CQSPI_REG_RD_INSTR_DUMMY_MASK)
>> +                      << CQSPI_REG_RD_INSTR_DUMMY_LSB;
> 
>>
>>         writel(reg, reg_base + CQSPI_REG_RD_INSTR);
>>
>>         /* Set address width */
>>         reg = readl(reg_base + CQSPI_REG_SIZE);
>>         reg &= ~CQSPI_REG_SIZE_ADDRESS_MASK;
>> -       reg |= (nor->addr_width - 1);
>> +       reg |= (op->addr.nbytes - 1);
>>         writel(reg, reg_base + CQSPI_REG_SIZE);
>>         return 0;
>>  }
>>
>> -static int cqspi_indirect_read_execute(struct spi_nor *nor, u8 *rxbuf,
>> -                                      loff_t from_addr, const size_t n_rx)
>> +static int cqspi_indirect_read_execute(struct cqspi_flash_pdata *f_pdata,
>> +                                      u8 *rxbuf, loff_t from_addr,
>> +                                      const size_t n_rx)
>>  {
>> -       struct cqspi_flash_pdata *f_pdata = nor->priv;
>>         struct cqspi_st *cqspi = f_pdata->cqspi;
>> +       struct device *dev = &cqspi->pdev->dev;
>>         void __iomem *reg_base = cqspi->iobase;
>>         void __iomem *ahb_base = cqspi->ahb_base;
>>         unsigned int remaining = n_rx;
>> @@ -526,13 +505,13 @@ static int cqspi_indirect_read_execute(struct spi_nor
>> *nor, u8 *rxbuf,
>>
>>         while (remaining > 0) {
>>                 if (!wait_for_completion_timeout(&cqspi->transfer_complete,
>> -                               msecs_to_jiffies(CQSPI_READ_TIMEOUT_MS)))
>> +                                               
>> msecs_to_jiffies(CQSPI_READ_TIMEOUT_MS))) ret = -ETIMEDOUT;
>>
>>                 bytes_to_read = cqspi_get_rd_sram_level(cqspi);
>>
>>                 if (ret && bytes_to_read == 0) {
>> -                       dev_err(nor->dev, "Indirect read timeout, no
>> bytes\n"); +                       dev_err(dev, "Indirect read timeout, no
>> bytes\n"); goto failrd;
>>                 }
>>
>> @@ -568,8 +547,7 @@ static int cqspi_indirect_read_execute(struct spi_nor
>> *nor, u8 *rxbuf, ret = cqspi_wait_for_bit(reg_base + CQSPI_REG_INDIRECTRD,
>>                                  CQSPI_REG_INDIRECTRD_DONE_MASK, 0);
>>         if (ret) {
>> -               dev_err(nor->dev,
>> -                       "Indirect read completion error (%i)\n", ret);
>> +               dev_err(dev, "Indirect read completion error (%i)\n", ret);
>>                 goto failrd;
>>         }
>>
>> @@ -591,32 +569,32 @@ static int cqspi_indirect_read_execute(struct spi_nor
>> *nor, u8 *rxbuf, return ret;
>>  }
>>
>> -static int cqspi_write_setup(struct spi_nor *nor)
>> +static int cqspi_write_setup(struct cqspi_flash_pdata *f_pdata,
>> +                            const struct spi_mem_op *op)
>>  {
>>         unsigned int reg;
>> -       struct cqspi_flash_pdata *f_pdata = nor->priv;
>>         struct cqspi_st *cqspi = f_pdata->cqspi;
>>         void __iomem *reg_base = cqspi->iobase;
>>
>>         /* Set opcode. */
>> -       reg = nor->program_opcode << CQSPI_REG_WR_INSTR_OPCODE_LSB;
>> +       reg = op->cmd.opcode << CQSPI_REG_WR_INSTR_OPCODE_LSB;
>>         writel(reg, reg_base + CQSPI_REG_WR_INSTR);
>> -       reg = cqspi_calc_rdreg(nor);
>> +       reg = cqspi_calc_rdreg(f_pdata);
>>         writel(reg, reg_base + CQSPI_REG_RD_INSTR);
>>
>>         reg = readl(reg_base + CQSPI_REG_SIZE);
>>         reg &= ~CQSPI_REG_SIZE_ADDRESS_MASK;
>> -       reg |= (nor->addr_width - 1);
>> +       reg |= (op->addr.nbytes - 1);
>>         writel(reg, reg_base + CQSPI_REG_SIZE);
>>         return 0;
>>  }
>>
>> -static int cqspi_indirect_write_execute(struct spi_nor *nor, loff_t
>> to_addr, -                                       const u8 *txbuf, const
>> size_t n_tx) +static int cqspi_indirect_write_execute(struct
>> cqspi_flash_pdata *f_pdata, +                                       loff_t
>> to_addr, const u8 *txbuf, +                                       const
>> size_t n_tx)
>>  {
>> -       const unsigned int page_size = nor->page_size;
>> -       struct cqspi_flash_pdata *f_pdata = nor->priv;
>>         struct cqspi_st *cqspi = f_pdata->cqspi;
>> +       struct device *dev = &cqspi->pdev->dev;
>>         void __iomem *reg_base = cqspi->iobase;
>>         unsigned int remaining = n_tx;
>>         unsigned int write_bytes;
>> @@ -646,7 +624,7 @@ static int cqspi_indirect_write_execute(struct spi_nor
>> *nor, loff_t to_addr, while (remaining > 0) {
>>                 size_t write_words, mod_bytes;
>>
>> -               write_bytes = remaining > page_size ? page_size : remaining;
>> +               write_bytes = remaining;
>>                 write_words = write_bytes / 4;
>>                 mod_bytes = write_bytes % 4;
>>                 /* Write 4 bytes at a time then single bytes. */
>> @@ -663,8 +641,8 @@ static int cqspi_indirect_write_execute(struct spi_nor
>> *nor, loff_t to_addr, }
>>
>>                 if (!wait_for_completion_timeout(&cqspi->transfer_complete,
>> -                                       msecs_to_jiffies(CQSPI_TIMEOUT_MS)))
>> { -                       dev_err(nor->dev, "Indirect write timeout\n"); + 
>>                                              
>> msecs_to_jiffies(CQSPI_TIMEOUT_MS))) { +                       dev_err(dev,
>> "Indirect write timeout\n");
>>                         ret = -ETIMEDOUT;
>>                         goto failwr;
>>                 }
>> @@ -679,8 +657,7 @@ static int cqspi_indirect_write_execute(struct spi_nor
>> *nor, loff_t to_addr, ret = cqspi_wait_for_bit(reg_base +
>> CQSPI_REG_INDIRECTWR,
>>                                  CQSPI_REG_INDIRECTWR_DONE_MASK, 0);
>>         if (ret) {
>> -               dev_err(nor->dev,
>> -                       "Indirect write completion error (%i)\n", ret);
>> +               dev_err(dev, "Indirect write completion error (%i)\n", ret);
>> goto failwr;
>>         }
>>
>> @@ -704,9 +681,8 @@ static int cqspi_indirect_write_execute(struct spi_nor
>> *nor, loff_t to_addr, return ret;
>>  }
>>
>> -static void cqspi_chipselect(struct spi_nor *nor)
>> +static void cqspi_chipselect(struct cqspi_flash_pdata *f_pdata)
>>  {
>> -       struct cqspi_flash_pdata *f_pdata = nor->priv;
>>         struct cqspi_st *cqspi = f_pdata->cqspi;
>>         void __iomem *reg_base = cqspi->iobase;
>>         unsigned int chip_select = f_pdata->cs;
>> @@ -745,9 +721,8 @@ static unsigned int calculate_ticks_for_ns(const
>> unsigned int ref_clk_hz, return ticks;
>>  }
>>
>> -static void cqspi_delay(struct spi_nor *nor)
>> +static void cqspi_delay(struct cqspi_flash_pdata *f_pdata)
>>  {
>> -       struct cqspi_flash_pdata *f_pdata = nor->priv;
>>         struct cqspi_st *cqspi = f_pdata->cqspi;
>>         void __iomem *iobase = cqspi->iobase;
>>         const unsigned int ref_clk_hz = cqspi->master_ref_clk_hz;
>> @@ -831,11 +806,10 @@ static void cqspi_controller_enable(struct cqspi_st
>> *cqspi, bool enable) writel(reg, reg_base + CQSPI_REG_CONFIG);
>>  }
>>
>> -static void cqspi_configure(struct spi_nor *nor)
>> +static void cqspi_configure(struct cqspi_flash_pdata *f_pdata,
>> +                           unsigned long sclk)
>>  {
>> -       struct cqspi_flash_pdata *f_pdata = nor->priv;
>>         struct cqspi_st *cqspi = f_pdata->cqspi;
>> -       const unsigned int sclk = f_pdata->clk_rate;
>>         int switch_cs = (cqspi->current_cs != f_pdata->cs);
>>         int switch_ck = (cqspi->sclk != sclk);
>>
>> @@ -845,14 +819,14 @@ static void cqspi_configure(struct spi_nor *nor)
>>         /* Switch chip select. */
>>         if (switch_cs) {
>>                 cqspi->current_cs = f_pdata->cs;
>> -               cqspi_chipselect(nor);
>> +               cqspi_chipselect(f_pdata);
>>         }
>>
>>         /* Setup baudrate divisor and delays */
>>         if (switch_ck) {
>>                 cqspi->sclk = sclk;
>>                 cqspi_config_baudrate_div(cqspi);
>> -               cqspi_delay(nor);
>> +               cqspi_delay(f_pdata);
>>                 cqspi_readdata_capture(cqspi, !cqspi->rclk_en,
>>                                        f_pdata->read_delay);
>>         }
>> @@ -861,26 +835,25 @@ static void cqspi_configure(struct spi_nor *nor)
>>                 cqspi_controller_enable(cqspi, 1);
>>  }
>>
>> -static int cqspi_set_protocol(struct spi_nor *nor, const int read)
>> +static int cqspi_set_protocol(struct cqspi_flash_pdata *f_pdata,
>> +                             const struct spi_mem_op *op)
>>  {
>> -       struct cqspi_flash_pdata *f_pdata = nor->priv;
>> -
>>         f_pdata->inst_width = CQSPI_INST_TYPE_SINGLE;
>>         f_pdata->addr_width = CQSPI_INST_TYPE_SINGLE;
>>         f_pdata->data_width = CQSPI_INST_TYPE_SINGLE;
>>
>> -       if (read) {
>> -               switch (nor->read_proto) {
>> -               case SNOR_PROTO_1_1_1:
>> +       if (op->data.dir == SPI_MEM_DATA_IN) {
>> +               switch (op->data.buswidth) {
>> +               case 1:
>>                         f_pdata->data_width = CQSPI_INST_TYPE_SINGLE;
>>                         break;
>> -               case SNOR_PROTO_1_1_2:
>> +               case 2:
>>                         f_pdata->data_width = CQSPI_INST_TYPE_DUAL;
>>                         break;
>> -               case SNOR_PROTO_1_1_4:
>> +               case 4:
>>                         f_pdata->data_width = CQSPI_INST_TYPE_QUAD;
>>                         break;
>> -               case SNOR_PROTO_1_1_8:
>> +               case 8:
>>                         f_pdata->data_width = CQSPI_INST_TYPE_OCTAL;
>>                         break;
>>                 default:
>> @@ -888,36 +861,32 @@ static int cqspi_set_protocol(struct spi_nor *nor,
>> const int read) }
>>         }
>>
>> -       cqspi_configure(nor);
>> -
>>         return 0;
>>  }
>>
>> -static ssize_t cqspi_write(struct spi_nor *nor, loff_t to,
>> -                          size_t len, const u_char *buf)
>> +static ssize_t cqspi_write(struct cqspi_flash_pdata *f_pdata,
>> +                          const struct spi_mem_op *op)
>>  {
>> -       struct cqspi_flash_pdata *f_pdata = nor->priv;
>>         struct cqspi_st *cqspi = f_pdata->cqspi;
>> +       loff_t to = op->addr.val;
>> +       size_t len = op->data.nbytes;
>> +       const u_char *buf = op->data.buf.out;
>>         int ret;
>>
>> -       ret = cqspi_set_protocol(nor, 0);
>> +       ret = cqspi_set_protocol(f_pdata, op);
>>         if (ret)
>>                 return ret;
>>
>> -       ret = cqspi_write_setup(nor);
>> +       ret = cqspi_write_setup(f_pdata, op);
>>         if (ret)
>>                 return ret;
>>
>> -       if (f_pdata->use_direct_mode) {
>> +       if (cqspi->use_dac_mode && ((to + len) <= cqspi->ahb_size)) {
>>                 memcpy_toio(cqspi->ahb_base + to, buf, len);
>> -               ret = cqspi_wait_idle(cqspi);
>> -       } else {
>> -               ret = cqspi_indirect_write_execute(nor, to, buf, len);
>> +               return cqspi_wait_idle(cqspi);
>>         }
>> -       if (ret)
>> -               return ret;
>>
>> -       return len;
>> +       return cqspi_indirect_write_execute(f_pdata, to, buf, len);
>>  }
>>
>>  static void cqspi_rx_dma_callback(void *param)
>> @@ -927,11 +896,11 @@ static void cqspi_rx_dma_callback(void *param)
>>         complete(&cqspi->rx_dma_complete);
>>  }
>>
>> -static int cqspi_direct_read_execute(struct spi_nor *nor, u_char *buf,
>> -                                    loff_t from, size_t len)
>> +static int cqspi_direct_read_execute(struct cqspi_flash_pdata *f_pdata,
>> +                                    u_char *buf, loff_t from, size_t len)
>>  {
>> -       struct cqspi_flash_pdata *f_pdata = nor->priv;
>>         struct cqspi_st *cqspi = f_pdata->cqspi;
>> +       struct device *dev = &cqspi->pdev->dev;
>>         enum dma_ctrl_flags flags = DMA_CTRL_ACK | DMA_PREP_INTERRUPT;
>>         dma_addr_t dma_src = (dma_addr_t)cqspi->mmap_phys_base + from;
>>         int ret = 0;
>> @@ -944,15 +913,15 @@ static int cqspi_direct_read_execute(struct spi_nor
>> *nor, u_char *buf, return 0;
>>         }
>>
>> -       dma_dst = dma_map_single(nor->dev, buf, len, DMA_FROM_DEVICE);
>> -       if (dma_mapping_error(nor->dev, dma_dst)) {
>> -               dev_err(nor->dev, "dma mapping failed\n");
>> +       dma_dst = dma_map_single(dev, buf, len, DMA_FROM_DEVICE);
>> +       if (dma_mapping_error(dev, dma_dst)) {
>> +               dev_err(dev, "dma mapping failed\n");
>>                 return -ENOMEM;
>>         }
>>         tx = dmaengine_prep_dma_memcpy(cqspi->rx_chan, dma_dst, dma_src,
>>                                        len, flags);
>>         if (!tx) {
>> -               dev_err(nor->dev, "device_prep_dma_memcpy error\n");
>> +               dev_err(dev, "device_prep_dma_memcpy error\n");
>>                 ret = -EIO;
>>                 goto err_unmap;
>>         }
>> @@ -964,7 +933,7 @@ static int cqspi_direct_read_execute(struct spi_nor
>> *nor, u_char *buf,
>>
>>         ret = dma_submit_error(cookie);
>>         if (ret) {
>> -               dev_err(nor->dev, "dma_submit_error %d\n", cookie);
>> +               dev_err(dev, "dma_submit_error %d\n", cookie);
>>                 ret = -EIO;
>>                 goto err_unmap;
>>         }
>> @@ -973,99 +942,68 @@ static int cqspi_direct_read_execute(struct spi_nor
>> *nor, u_char *buf, if
>> (!wait_for_completion_timeout(&cqspi->rx_dma_complete,
>>                                          msecs_to_jiffies(len))) {
>>                 dmaengine_terminate_sync(cqspi->rx_chan);
>> -               dev_err(nor->dev, "DMA wait_for_completion_timeout\n");
>> +               dev_err(dev, "DMA wait_for_completion_timeout\n");
>>                 ret = -ETIMEDOUT;
>>                 goto err_unmap;
>>         }
>>
>>  err_unmap:
>> -       dma_unmap_single(nor->dev, dma_dst, len, DMA_FROM_DEVICE);
>> +       dma_unmap_single(dev, dma_dst, len, DMA_FROM_DEVICE);
>>
>>         return ret;
>>  }
>>
>> -static ssize_t cqspi_read(struct spi_nor *nor, loff_t from,
>> -                         size_t len, u_char *buf)
>> -{
>> -       struct cqspi_flash_pdata *f_pdata = nor->priv;
>> -       int ret;
>> -
>> -       ret = cqspi_set_protocol(nor, 1);
>> -       if (ret)
>> -               return ret;
>> -
>> -       ret = cqspi_read_setup(nor);
>> -       if (ret)
>> -               return ret;
>> -
>> -       if (f_pdata->use_direct_mode)
>> -               ret = cqspi_direct_read_execute(nor, buf, from, len);
>> -       else
>> -               ret = cqspi_indirect_read_execute(nor, buf, from, len);
>> -       if (ret)
>> -               return ret;
>> -
>> -       return len;
>> -}
>> -
>> -static int cqspi_erase(struct spi_nor *nor, loff_t offs)
>> +static ssize_t cqspi_read(struct cqspi_flash_pdata *f_pdata,
>> +                         const struct spi_mem_op *op)
>>  {
>> +       struct cqspi_st *cqspi = f_pdata->cqspi;
>> +       loff_t from = op->addr.val;
>> +       size_t len = op->data.nbytes;
>> +       u_char *buf = op->data.buf.in;
>>         int ret;
>>
>> -       ret = cqspi_set_protocol(nor, 0);
>> +       ret = cqspi_set_protocol(f_pdata, op);
>>         if (ret)
>>                 return ret;
>>
>> -       /* Send write enable, then erase commands. */
>> -       ret = nor->controller_ops->write_reg(nor, SPINOR_OP_WREN, NULL, 0);
> 
> Dropping the Write Enable for erases can be done in a separate patch, since it 
> is already done in the SPI NOR core. This would ease the review.
> 

OK...

>> +       ret = cqspi_read_setup(f_pdata, op);
>>         if (ret)
>>                 return ret;
>>
>> -       /* Set up command buffer. */
>> -       ret = cqspi_command_write_addr(nor, nor->erase_opcode, offs);
>> -       if (ret)
>> -               return ret;
>> +       if (cqspi->use_dac_mode && ((from + len) <= cqspi->ahb_size))
>> +               return cqspi_direct_read_execute(f_pdata, buf, from, len);
>>
>> -       return 0;
>> +       return cqspi_indirect_read_execute(f_pdata, buf, from, len);
>>  }
>>
>> -static int cqspi_prep(struct spi_nor *nor)
>> +static int cqspi_mem_process(struct spi_mem *mem, const struct spi_mem_op
>> *op) {
>> -       struct cqspi_flash_pdata *f_pdata = nor->priv;
>> -       struct cqspi_st *cqspi = f_pdata->cqspi;
>> -
>> -       mutex_lock(&cqspi->bus_mutex);
>> -
>> -       return 0;
>> -}
>> +       struct cqspi_st *cqspi = spi_master_get_devdata(mem->spi->master);
>> +       struct cqspi_flash_pdata *f_pdata;
>>
>> -static void cqspi_unprep(struct spi_nor *nor)
>> -{
>> -       struct cqspi_flash_pdata *f_pdata = nor->priv;
>> -       struct cqspi_st *cqspi = f_pdata->cqspi;
>> +       f_pdata = &cqspi->f_pdata[mem->spi->chip_select];
>> +       cqspi_configure(f_pdata, mem->spi->max_speed_hz);
>>
>> -       mutex_unlock(&cqspi->bus_mutex);
>> -}
>> +       if (op->data.dir == SPI_MEM_DATA_IN && op->data.buf.in) {
>> +               if (!op->addr.nbytes)
>> +                       return cqspi_command_read(f_pdata, op);
>>
>> -static int cqspi_read_reg(struct spi_nor *nor, u8 opcode, u8 *buf, size_t
>> len) -{
>> -       int ret;
>> +               return cqspi_read(f_pdata, op);
>> +       }
>>
>> -       ret = cqspi_set_protocol(nor, 0);
>> -       if (!ret)
>> -               ret = cqspi_command_read(nor, opcode, buf, len);
>> +       if (!op->addr.nbytes || !op->data.buf.out)
>> +               return cqspi_command_write(f_pdata, op);
>>
>> -       return ret;
>> +       return cqspi_write(f_pdata, op);
>>  }
>>
>> -static int cqspi_write_reg(struct spi_nor *nor, u8 opcode, const u8 *buf,
>> -                          size_t len)
>> +static int cqspi_exec_mem_op(struct spi_mem *mem, const struct spi_mem_op
>> *op) {
>>         int ret;
>>
>> -       ret = cqspi_set_protocol(nor, 0);
>> -       if (!ret)
>> -               ret = cqspi_command_write(nor, opcode, buf, len);
>> +       ret = cqspi_mem_process(mem, op);
>> +       if (ret)
>> +               dev_err(&mem->spi->dev, "operation failed with %d\n", ret);
>>
>>         return ret;
>>  }
>> @@ -1107,26 +1045,26 @@ static int cqspi_of_get_flash_pdata(struct
>> platform_device *pdev, return 0;
>>  }
>>
>> -static int cqspi_of_get_pdata(struct platform_device *pdev)
>> +static int cqspi_of_get_pdata(struct cqspi_st *cqspi)
>>  {
>> -       struct device_node *np = pdev->dev.of_node;
>> -       struct cqspi_st *cqspi = platform_get_drvdata(pdev);
>> +       struct device *dev = &cqspi->pdev->dev;
>> +       struct device_node *np = dev->of_node;
>>
>>         cqspi->is_decoded_cs = of_property_read_bool(np,
>> "cdns,is-decoded-cs");
>>
>>         if (of_property_read_u32(np, "cdns,fifo-depth", &cqspi->fifo_depth))
>> { -               dev_err(&pdev->dev, "couldn't determine fifo-depth\n"); +
>>               dev_err(dev, "couldn't determine fifo-depth\n");
>>                 return -ENXIO;
>>         }
>>
>>         if (of_property_read_u32(np, "cdns,fifo-width", &cqspi->fifo_width))
>> { -               dev_err(&pdev->dev, "couldn't determine fifo-width\n"); +
>>               dev_err(dev, "couldn't determine fifo-width\n");
>>                 return -ENXIO;
>>         }
>>
>>         if (of_property_read_u32(np, "cdns,trigger-address",
>>                                  &cqspi->trigger_address)) {
>> -               dev_err(&pdev->dev, "couldn't determine trigger-address\n");
>> +               dev_err(dev, "couldn't determine trigger-address\n");
>> return -ENXIO;
>>         }
>>
>> @@ -1169,7 +1107,7 @@ static void cqspi_controller_init(struct cqspi_st
>> *cqspi) cqspi_controller_enable(cqspi, 1);
>>  }
>>
>> -static void cqspi_request_mmap_dma(struct cqspi_st *cqspi)
>> +static int cqspi_request_mmap_dma(struct cqspi_st *cqspi)
>>  {
>>         dma_cap_mask_t mask;
>>
>> @@ -1178,133 +1116,79 @@ static void cqspi_request_mmap_dma(struct cqspi_st
>> *cqspi)
>>
>>         cqspi->rx_chan = dma_request_chan_by_mask(&mask);
>>         if (IS_ERR(cqspi->rx_chan)) {
>> -               dev_err(&cqspi->pdev->dev, "No Rx DMA available\n");
>> +               int ret = PTR_ERR(cqspi->rx_chan);
>> +
>> +               if (ret != -EPROBE_DEFER)
>> +                       dev_err(&cqspi->pdev->dev, "No Rx DMA available\n");
>> cqspi->rx_chan = NULL;
>> -               return;
>> +               return ret;
>>         }
>>         init_completion(&cqspi->rx_dma_complete);
>> +
>> +       return 0;
>>  }
> 
> Can we have the EPROBE_DEFER changes in a dedicated patch?
> 

Ok..

>>
>> -static const struct spi_nor_controller_ops cqspi_controller_ops = {
>> -       .prepare = cqspi_prep,
>> -       .unprepare = cqspi_unprep,
>> -       .read_reg = cqspi_read_reg,
>> -       .write_reg = cqspi_write_reg,
>> -       .read = cqspi_read,
>> -       .write = cqspi_write,
>> -       .erase = cqspi_erase,
>> +static const struct spi_controller_mem_ops cqspi_mem_ops = {
>> +       .exec_op = cqspi_exec_mem_op,
>>  };
>>
>> -static int cqspi_setup_flash(struct cqspi_st *cqspi, struct device_node
>> *np) +static int cqspi_setup_flash(struct cqspi_st *cqspi)
>>  {
>>         struct platform_device *pdev = cqspi->pdev;
>>         struct device *dev = &pdev->dev;
>> -       const struct cqspi_driver_platdata *ddata;
>> -       struct spi_nor_hwcaps hwcaps;
>> +       struct device_node *np = dev->of_node;
>>         struct cqspi_flash_pdata *f_pdata;
>> -       struct spi_nor *nor;
>> -       struct mtd_info *mtd;
>>         unsigned int cs;
>> -       int i, ret;
>> -
>> -       ddata = of_device_get_match_data(dev);
>> -       if (!ddata) {
>> -               dev_err(dev, "Couldn't find driver data\n");
>> -               return -EINVAL;
>> -       }
>> -       hwcaps.mask = ddata->hwcaps_mask;
>>
>>         /* Get flash device data */
>>         for_each_available_child_of_node(dev->of_node, np) {
>> -               ret = of_property_read_u32(np, "reg", &cs);
>> -               if (ret) {
>> +               if (of_property_read_u32(np, "reg", &cs)) {
>>                         dev_err(dev, "Couldn't determine chip select.\n");
>> -                       goto err;
>> +                       continue;
> 
> reg is mandatory, you should keep the behaviour as it was.

Ok..

> 
>>                 }
>>
>>                 if (cs >= CQSPI_MAX_CHIPSELECT) {
>> -                       ret = -EINVAL;
>>                         dev_err(dev, "Chip select %d out of range.\n", cs);
>> -                       goto err;
>> +                       continue;
>>                 }
>>
>>                 f_pdata = &cqspi->f_pdata[cs];
>>                 f_pdata->cqspi = cqspi;
>>                 f_pdata->cs = cs;
>>
>> -               ret = cqspi_of_get_flash_pdata(pdev, f_pdata, np);
>> -               if (ret)
>> -                       goto err;
>> -
>> -               nor = &f_pdata->nor;
>> -               mtd = &nor->mtd;
>> -
>> -               mtd->priv = nor;
>> -
>> -               nor->dev = dev;
>> -               spi_nor_set_flash_node(nor, np);
>> -               nor->priv = f_pdata;
>> -               nor->controller_ops = &cqspi_controller_ops;
>> -
>> -               mtd->name = devm_kasprintf(dev, GFP_KERNEL, "%s.%d",
>> -                                          dev_name(dev), cs);
>> -               if (!mtd->name) {
>> -                       ret = -ENOMEM;
>> -                       goto err;
>> -               }
>> -
>> -               ret = spi_nor_scan(nor, NULL, &hwcaps);
>> -               if (ret)
>> -                       goto err;
>> -
>> -               ret = mtd_device_register(mtd, NULL, 0);
>> -               if (ret)
>> -                       goto err;
>> -
>> -               f_pdata->registered = true;
>> -
>> -               if (mtd->size <= cqspi->ahb_size &&
>> -                   !(ddata->quirks & CQSPI_DISABLE_DAC_MODE)) {
>> -                       f_pdata->use_direct_mode = true;
>> -                       dev_dbg(nor->dev, "using direct mode for %s\n",
>> -                               mtd->name);
>> -
>> -                       if (!cqspi->rx_chan)
>> -                               cqspi_request_mmap_dma(cqspi);
>> -               }
>> +               return cqspi_of_get_flash_pdata(pdev, f_pdata, np);
> 
> drop the return. you now parse just the first discovered flash, whereas before 
> your changes we parsed all the described flashes.
> 

Right, this is a bug, will fix in v3... This should only return on error:
	int ret;

	ret = cqspi_of_get_flash_pdata(pdev, f_pdata, np);
	if (ret)
		return ret;

>>         }
>>
>>         return 0;
>> -
>> -err:
>> -       for (i = 0; i < CQSPI_MAX_CHIPSELECT; i++)
>> -               if (cqspi->f_pdata[i].registered)
>> -                       mtd_device_unregister(&cqspi->f_pdata[i].nor.mtd);
>> -       return ret;
>>  }
>>
>>  static int cqspi_probe(struct platform_device *pdev)
>>  {
>> -       struct device_node *np = pdev->dev.of_node;
>> +       const struct cqspi_driver_platdata *ddata;
>> +       struct reset_control *rstc, *rstc_ocp;
>>         struct device *dev = &pdev->dev;
>> +       struct spi_master *master;
>> +       struct resource *res_ahb;
>>         struct cqspi_st *cqspi;
>>         struct resource *res;
>> -       struct resource *res_ahb;
>> -       struct reset_control *rstc, *rstc_ocp;
>> -       const struct cqspi_driver_platdata *ddata;
>>         int ret;
>>         int irq;
>>
>> -       cqspi = devm_kzalloc(dev, sizeof(*cqspi), GFP_KERNEL);
>> -       if (!cqspi)
>> +       master = spi_alloc_master(&pdev->dev, sizeof(*cqspi));
>> +       if (!master) {
>> +               dev_err(&pdev->dev, "spi_alloc_master failed\n");
>>                 return -ENOMEM;
>> +       }
>> +       master->mode_bits = SPI_RX_QUAD | SPI_RX_DUAL;
>> +       master->mem_ops = &cqspi_mem_ops;
>> +       master->dev.of_node = pdev->dev.of_node;
>> +
>> +       cqspi = spi_master_get_devdata(master);
>>
>> -       mutex_init(&cqspi->bus_mutex);
>>         cqspi->pdev = pdev;
>> -       platform_set_drvdata(pdev, cqspi);
>>
>>         /* Obtain configuration from OF. */
>> -       ret = cqspi_of_get_pdata(pdev);
>> +       ret = cqspi_of_get_pdata(cqspi);
>>         if (ret) {
> 
> spi_controller_put() to not leak memory.
> 

Ah, yes!

Thanks for the review!

Regards
Vignesh

______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/

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

* Re: [PATCH v2 0/6] mtd: spi-nor: Move cadence-qaudspi to spi-mem framework
  2020-05-26  9:35 ` Vignesh Raghavendra
@ 2020-06-19 13:28   ` Mark Brown
  -1 siblings, 0 replies; 36+ messages in thread
From: Mark Brown @ 2020-06-19 13:28 UTC (permalink / raw)
  To: Vignesh Raghavendra, Tudor Ambarus
  Cc: dinguyen, Boris Brezillon, linux-spi, Ramuthevar Vadivel Murugan,
	simon.k.r.goldschmidt, linux-kernel, marex, linux-mtd

On Tue, 26 May 2020 15:05:58 +0530, Vignesh Raghavendra wrote:
> This series is a subset of "[PATCH v12 0/4] spi: cadence-quadspi: Add
> support for the Cadence QSPI controller" by Ramuthevar,Vadivel MuruganX
> <vadivel.muruganx.ramuthevar@linux.intel.com> that intended to move
> cadence-quadspi driver to spi-mem framework
> 
> Those patches were trying to accomplish too many things in a single set
> of patches and need to split into smaller patches. This is reduced
> version of above series.
> 
> [...]

Applied to

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

Thanks!

[1/6] mtd: spi-nor: cadence-quadspi: Make driver independent of flash geometry
      commit: 834b4e8d344139ba64cda22099b2b2ef6c9a542d
[2/6] mtd: spi-nor: cadence-quadspi: Provide a way to disable DAC mode
      commit: a99705079a91e6373122bd0ca2fc129b688fc5b3
[3/6] mtd: spi-nor: cadence-quadspi: Don't initialize rx_dma_complete on failure
      commit: 48aae57f0f9f57797772bd462b4d64902b1b4ae1
[4/6] mtd: spi-nor: cadence-quadspi: Fix error path on failure to acquire reset lines
      commit: c61088d1f9932940af780b674f028140eda09a94
[5/6] mtd: spi-nor: Convert cadence-quadspi to use spi-mem framework
      commit: a314f6367787ee1d767df9a2120f17e4511144d0
[6/6] spi: Move cadence-quadspi driver to drivers/spi/
      commit: 31fb632b5d43ca16713095b3a4fe17e3d7331e28

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] 36+ messages in thread

* Re: [PATCH v2 0/6] mtd: spi-nor: Move cadence-qaudspi to spi-mem framework
@ 2020-06-19 13:28   ` Mark Brown
  0 siblings, 0 replies; 36+ messages in thread
From: Mark Brown @ 2020-06-19 13:28 UTC (permalink / raw)
  To: Vignesh Raghavendra, Tudor Ambarus
  Cc: marex, Ramuthevar Vadivel Murugan, simon.k.r.goldschmidt,
	linux-kernel, linux-spi, dinguyen, linux-mtd, Boris Brezillon

On Tue, 26 May 2020 15:05:58 +0530, Vignesh Raghavendra wrote:
> This series is a subset of "[PATCH v12 0/4] spi: cadence-quadspi: Add
> support for the Cadence QSPI controller" by Ramuthevar,Vadivel MuruganX
> <vadivel.muruganx.ramuthevar@linux.intel.com> that intended to move
> cadence-quadspi driver to spi-mem framework
> 
> Those patches were trying to accomplish too many things in a single set
> of patches and need to split into smaller patches. This is reduced
> version of above series.
> 
> [...]

Applied to

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

Thanks!

[1/6] mtd: spi-nor: cadence-quadspi: Make driver independent of flash geometry
      commit: 834b4e8d344139ba64cda22099b2b2ef6c9a542d
[2/6] mtd: spi-nor: cadence-quadspi: Provide a way to disable DAC mode
      commit: a99705079a91e6373122bd0ca2fc129b688fc5b3
[3/6] mtd: spi-nor: cadence-quadspi: Don't initialize rx_dma_complete on failure
      commit: 48aae57f0f9f57797772bd462b4d64902b1b4ae1
[4/6] mtd: spi-nor: cadence-quadspi: Fix error path on failure to acquire reset lines
      commit: c61088d1f9932940af780b674f028140eda09a94
[5/6] mtd: spi-nor: Convert cadence-quadspi to use spi-mem framework
      commit: a314f6367787ee1d767df9a2120f17e4511144d0
[6/6] spi: Move cadence-quadspi driver to drivers/spi/
      commit: 31fb632b5d43ca16713095b3a4fe17e3d7331e28

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

______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/

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

end of thread, other threads:[~2020-06-19 13:28 UTC | newest]

Thread overview: 36+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-05-26  9:35 [PATCH v2 0/6] mtd: spi-nor: Move cadence-qaudspi to spi-mem framework Vignesh Raghavendra
2020-05-26  9:35 ` Vignesh Raghavendra
2020-05-26  9:35 ` [PATCH v2 1/6] mtd: spi-nor: cadence-quadspi: Make driver independent of flash geometry Vignesh Raghavendra
2020-05-26  9:35   ` Vignesh Raghavendra
2020-05-28 11:41   ` Tudor.Ambarus
2020-05-28 11:41     ` Tudor.Ambarus
2020-05-26  9:36 ` [PATCH v2 2/6] mtd: spi-nor: cadence-quadspi: Provide a way to disable DAC mode Vignesh Raghavendra
2020-05-26  9:36   ` Vignesh Raghavendra
2020-05-28 18:41   ` Tudor.Ambarus
2020-05-28 18:41     ` Tudor.Ambarus
2020-05-26  9:36 ` [PATCH v2 3/6] mtd: spi-nor: cadence-quadspi: Don't initialize rx_dma_complete on failure Vignesh Raghavendra
2020-05-26  9:36   ` Vignesh Raghavendra
2020-05-28 18:42   ` Tudor.Ambarus
2020-05-28 18:42     ` Tudor.Ambarus
2020-05-26  9:36 ` [PATCH v2 4/6] mtd: spi-nor: cadence-quadspi: Fix error path on failure to acquire reset lines Vignesh Raghavendra
2020-05-26  9:36   ` Vignesh Raghavendra
2020-05-28 18:46   ` Tudor.Ambarus
2020-05-28 18:46     ` Tudor.Ambarus
2020-05-26  9:36 ` [PATCH v2 5/6] mtd: spi-nor: Convert cadence-quadspi to use spi-mem framework Vignesh Raghavendra
2020-05-26  9:36   ` Vignesh Raghavendra
2020-05-30 13:50   ` Tudor.Ambarus
2020-05-30 13:50     ` Tudor.Ambarus
2020-06-01  4:56     ` Vignesh Raghavendra
2020-06-01  4:56       ` Vignesh Raghavendra
2020-05-26  9:36 ` [PATCH v2 6/6] spi: Move cadence-quadspi driver to drivers/spi/ Vignesh Raghavendra
2020-05-26  9:36   ` Vignesh Raghavendra
2020-05-27 20:58   ` kbuild test robot
2020-05-27 20:58     ` kbuild test robot
2020-05-27 20:58     ` kbuild test robot
2020-05-28  9:54     ` Vignesh Raghavendra
2020-05-28  9:54       ` Vignesh Raghavendra
2020-05-28  9:54       ` Vignesh Raghavendra
2020-05-30 14:03   ` Tudor.Ambarus
2020-05-30 14:03     ` Tudor.Ambarus
2020-06-19 13:28 ` [PATCH v2 0/6] mtd: spi-nor: Move cadence-qaudspi to spi-mem framework Mark Brown
2020-06-19 13:28   ` Mark Brown

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.