All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v4 00/16] OMAP2+ OneNAND driver update
@ 2017-11-11 21:12 ` Ladislav Michl
  0 siblings, 0 replies; 114+ messages in thread
From: Ladislav Michl @ 2017-11-11 21:12 UTC (permalink / raw)
  To: linux-mtd, linux-omap
  Cc: Tony Lindgren, Peter Ujfalusi, Kyungmin Park, Boris Brezillon,
	Roger Quadros

Hi there,

this patch serie updates OMAP2+ OneNAND driver to the present times, making
it fully DT configurable, using libgpio and dmaengine apis.

Please note that unlike previous driver version, which basically ignored
DT specified timings, this one relies on it, so it is important to get
it right in your DT (dumping it from previous kernel version).

In case synchronous timings is requested, it is okay to specify timings
for the slowest chip ever used for you board as it is evetually optimized
after chip probe.

Original driver used DMA only if user specified r/b gpio in platform
data, now DMA is used unconditionally and PIO mode is used as fallback.

In case anyone wants to give it a try, few DT related changes are needed:
- onenand node needs 'ti,omap2-onenand' compatible (for mailine boards this is
  done in patch 2)
- to use R/B pin, rb-gpios needs to be specified (for n900 and n8x0 this is
  done in patch 16, however patch lacks pinmux configuration.

Most notable changes from previous version:
- added dmaengine patches by Peter Ujfalusi
- added dt bindings documentation
- added cleanup patches
- DMA enabled by default

Also note that driver will fail probe OneNAND chip after patch 13 and start
working again after patch 14.

Testing and benchmarking very welcome.

Depends on "memory: omap-gpmc: Make 'bank-width' property optional"
https://patchwork.kernel.org/patch/10043259/

Ladislav Michl (13):
  dt-bindings: mtd: gpmc-onenand: Update properties description
  ARM: dts: OMAP2+: Add compatible property to onenand node
  ARM: dts: omap3-igep: Update onenand node timings
  mtd: onenand: omap2: Remove regulator support
  mtd: onenand: omap2: Remove skip initial unlocking support
  mtd: onenand: omap2: Remove partitioning support from platform data
  mtd: onenand: omap2: Account waiting time as waiting on IO
  mtd: onenand: omap2: Unify OMAP2 and OMAP3 DMA implementation
  mtd: onenand: omap2: Do not make delay for GPIO OMAP3 specific
  memory: omap-gpmc: Refactor OneNAND support
  mtd: onenand: omap2: Configure driver from DT
  ARM: OMAP2+: Remove gpmc-onenand
  ARM: dts: Nokia: Use R/B pin

Peter Ujfalusi (2):
  mtd: onenand: omap2: Simplify the DMA setup for various paths
  mtd: onenand: omap2: Convert to use dmaengine for memcpy

 .../devicetree/bindings/mtd/gpmc-onenand.txt       |   6 +-
 arch/arm/boot/dts/omap2420-n8x0-common.dtsi        |   5 +-
 arch/arm/boot/dts/omap3-igep.dtsi                  |  30 +-
 arch/arm/boot/dts/omap3-n900.dts                   |   2 +
 arch/arm/boot/dts/omap3-n950-n9.dtsi               |   1 +
 arch/arm/boot/dts/omap3430-sdp.dts                 |   1 +
 arch/arm/mach-omap2/Makefile                       |   3 -
 arch/arm/mach-omap2/gpmc-onenand.c                 | 409 ---------------
 drivers/memory/omap-gpmc.c                         | 158 ++++--
 drivers/mtd/onenand/omap2.c                        | 580 ++++++++-------------
 include/linux/omap-gpmc.h                          |  25 +
 include/linux/platform_data/mtd-onenand-omap2.h    |  34 --
 12 files changed, 389 insertions(+), 865 deletions(-)
 delete mode 100644 arch/arm/mach-omap2/gpmc-onenand.c
 delete mode 100644 include/linux/platform_data/mtd-onenand-omap2.h

-- 
2.11.0


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

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

* [PATCH v4 00/16] OMAP2+ OneNAND driver update
@ 2017-11-11 21:12 ` Ladislav Michl
  0 siblings, 0 replies; 114+ messages in thread
From: Ladislav Michl @ 2017-11-11 21:12 UTC (permalink / raw)
  To: linux-mtd, linux-omap
  Cc: Roger Quadros, Tony Lindgren, Peter Ujfalusi, Boris Brezillon,
	Kyungmin Park

Hi there,

this patch serie updates OMAP2+ OneNAND driver to the present times, making
it fully DT configurable, using libgpio and dmaengine apis.

Please note that unlike previous driver version, which basically ignored
DT specified timings, this one relies on it, so it is important to get
it right in your DT (dumping it from previous kernel version).

In case synchronous timings is requested, it is okay to specify timings
for the slowest chip ever used for you board as it is evetually optimized
after chip probe.

Original driver used DMA only if user specified r/b gpio in platform
data, now DMA is used unconditionally and PIO mode is used as fallback.

In case anyone wants to give it a try, few DT related changes are needed:
- onenand node needs 'ti,omap2-onenand' compatible (for mailine boards this is
  done in patch 2)
- to use R/B pin, rb-gpios needs to be specified (for n900 and n8x0 this is
  done in patch 16, however patch lacks pinmux configuration.

Most notable changes from previous version:
- added dmaengine patches by Peter Ujfalusi
- added dt bindings documentation
- added cleanup patches
- DMA enabled by default

Also note that driver will fail probe OneNAND chip after patch 13 and start
working again after patch 14.

Testing and benchmarking very welcome.

Depends on "memory: omap-gpmc: Make 'bank-width' property optional"
https://patchwork.kernel.org/patch/10043259/

Ladislav Michl (13):
  dt-bindings: mtd: gpmc-onenand: Update properties description
  ARM: dts: OMAP2+: Add compatible property to onenand node
  ARM: dts: omap3-igep: Update onenand node timings
  mtd: onenand: omap2: Remove regulator support
  mtd: onenand: omap2: Remove skip initial unlocking support
  mtd: onenand: omap2: Remove partitioning support from platform data
  mtd: onenand: omap2: Account waiting time as waiting on IO
  mtd: onenand: omap2: Unify OMAP2 and OMAP3 DMA implementation
  mtd: onenand: omap2: Do not make delay for GPIO OMAP3 specific
  memory: omap-gpmc: Refactor OneNAND support
  mtd: onenand: omap2: Configure driver from DT
  ARM: OMAP2+: Remove gpmc-onenand
  ARM: dts: Nokia: Use R/B pin

Peter Ujfalusi (2):
  mtd: onenand: omap2: Simplify the DMA setup for various paths
  mtd: onenand: omap2: Convert to use dmaengine for memcpy

 .../devicetree/bindings/mtd/gpmc-onenand.txt       |   6 +-
 arch/arm/boot/dts/omap2420-n8x0-common.dtsi        |   5 +-
 arch/arm/boot/dts/omap3-igep.dtsi                  |  30 +-
 arch/arm/boot/dts/omap3-n900.dts                   |   2 +
 arch/arm/boot/dts/omap3-n950-n9.dtsi               |   1 +
 arch/arm/boot/dts/omap3430-sdp.dts                 |   1 +
 arch/arm/mach-omap2/Makefile                       |   3 -
 arch/arm/mach-omap2/gpmc-onenand.c                 | 409 ---------------
 drivers/memory/omap-gpmc.c                         | 158 ++++--
 drivers/mtd/onenand/omap2.c                        | 580 ++++++++-------------
 include/linux/omap-gpmc.h                          |  25 +
 include/linux/platform_data/mtd-onenand-omap2.h    |  34 --
 12 files changed, 389 insertions(+), 865 deletions(-)
 delete mode 100644 arch/arm/mach-omap2/gpmc-onenand.c
 delete mode 100644 include/linux/platform_data/mtd-onenand-omap2.h

-- 
2.11.0

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

* [PATCH v4 02/16] ARM: dts: OMAP2+: Add compatible property to onenand node
  2017-11-11 21:12 ` Ladislav Michl
@ 2017-11-11 21:17   ` Ladislav Michl
  -1 siblings, 0 replies; 114+ messages in thread
From: Ladislav Michl @ 2017-11-11 21:17 UTC (permalink / raw)
  To: linux-mtd, linux-omap
  Cc: Tony Lindgren, Peter Ujfalusi, Kyungmin Park, Boris Brezillon,
	Roger Quadros

OMAP onenand nodes are missing compatible property, add it.

Signed-off-by: Ladislav Michl <ladis@linux-mips.org>
---
 Changes:
 -v4: new patch

 arch/arm/boot/dts/omap2420-n8x0-common.dtsi | 1 +
 arch/arm/boot/dts/omap3-n900.dts            | 1 +
 arch/arm/boot/dts/omap3-n950-n9.dtsi        | 1 +
 arch/arm/boot/dts/omap3430-sdp.dts          | 1 +
 4 files changed, 4 insertions(+)

diff --git a/arch/arm/boot/dts/omap2420-n8x0-common.dtsi b/arch/arm/boot/dts/omap2420-n8x0-common.dtsi
index 1de80c7886ab..843f6a2f5e29 100644
--- a/arch/arm/boot/dts/omap2420-n8x0-common.dtsi
+++ b/arch/arm/boot/dts/omap2420-n8x0-common.dtsi
@@ -48,6 +48,7 @@
 	onenand@0,0 {
 		#address-cells = <1>;
 		#size-cells = <1>;
+		compatible = "ti,omap2-onenand";
 		reg = <0 0 0x20000>;	/* CS0, offset 0, IO size 128K */
 
 		gpmc,sync-read;
diff --git a/arch/arm/boot/dts/omap3-n900.dts b/arch/arm/boot/dts/omap3-n900.dts
index 4acd32a1c4ef..aa5b1a439564 100644
--- a/arch/arm/boot/dts/omap3-n900.dts
+++ b/arch/arm/boot/dts/omap3-n900.dts
@@ -838,6 +838,7 @@
 	onenand@0,0 {
 		#address-cells = <1>;
 		#size-cells = <1>;
+		compatible = "ti,omap2-onenand";
 		reg = <0 0 0x20000>;	/* CS0, offset 0, IO size 128K */
 
 		gpmc,sync-read;
diff --git a/arch/arm/boot/dts/omap3-n950-n9.dtsi b/arch/arm/boot/dts/omap3-n950-n9.dtsi
index 1b0bd72945f2..cb3c7b2fce52 100644
--- a/arch/arm/boot/dts/omap3-n950-n9.dtsi
+++ b/arch/arm/boot/dts/omap3-n950-n9.dtsi
@@ -367,6 +367,7 @@
 	onenand@0,0 {
 		#address-cells = <1>;
 		#size-cells = <1>;
+		compatible = "ti,omap2-onenand";
 		reg = <0 0 0x20000>;	/* CS0, offset 0, IO size 128K */
 
 		gpmc,sync-read;
diff --git a/arch/arm/boot/dts/omap3430-sdp.dts b/arch/arm/boot/dts/omap3430-sdp.dts
index d50a105c9dc6..ed65795ccc62 100644
--- a/arch/arm/boot/dts/omap3430-sdp.dts
+++ b/arch/arm/boot/dts/omap3430-sdp.dts
@@ -155,6 +155,7 @@
 		linux,mtd-name= "samsung,kfm2g16q2m-deb8";
 		#address-cells = <1>;
 		#size-cells = <1>;
+		compatible = "ti,omap2-onenand";
 		reg = <2 0 0x20000>;	/* CS2, offset 0, IO size 4 */
 
 		gpmc,device-width = <2>;
-- 
2.11.0


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

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

* [PATCH v4 02/16] ARM: dts: OMAP2+: Add compatible property to onenand node
@ 2017-11-11 21:17   ` Ladislav Michl
  0 siblings, 0 replies; 114+ messages in thread
From: Ladislav Michl @ 2017-11-11 21:17 UTC (permalink / raw)
  To: linux-mtd, linux-omap
  Cc: Roger Quadros, Tony Lindgren, Peter Ujfalusi, Boris Brezillon,
	Kyungmin Park

OMAP onenand nodes are missing compatible property, add it.

Signed-off-by: Ladislav Michl <ladis@linux-mips.org>
---
 Changes:
 -v4: new patch

 arch/arm/boot/dts/omap2420-n8x0-common.dtsi | 1 +
 arch/arm/boot/dts/omap3-n900.dts            | 1 +
 arch/arm/boot/dts/omap3-n950-n9.dtsi        | 1 +
 arch/arm/boot/dts/omap3430-sdp.dts          | 1 +
 4 files changed, 4 insertions(+)

diff --git a/arch/arm/boot/dts/omap2420-n8x0-common.dtsi b/arch/arm/boot/dts/omap2420-n8x0-common.dtsi
index 1de80c7886ab..843f6a2f5e29 100644
--- a/arch/arm/boot/dts/omap2420-n8x0-common.dtsi
+++ b/arch/arm/boot/dts/omap2420-n8x0-common.dtsi
@@ -48,6 +48,7 @@
 	onenand@0,0 {
 		#address-cells = <1>;
 		#size-cells = <1>;
+		compatible = "ti,omap2-onenand";
 		reg = <0 0 0x20000>;	/* CS0, offset 0, IO size 128K */
 
 		gpmc,sync-read;
diff --git a/arch/arm/boot/dts/omap3-n900.dts b/arch/arm/boot/dts/omap3-n900.dts
index 4acd32a1c4ef..aa5b1a439564 100644
--- a/arch/arm/boot/dts/omap3-n900.dts
+++ b/arch/arm/boot/dts/omap3-n900.dts
@@ -838,6 +838,7 @@
 	onenand@0,0 {
 		#address-cells = <1>;
 		#size-cells = <1>;
+		compatible = "ti,omap2-onenand";
 		reg = <0 0 0x20000>;	/* CS0, offset 0, IO size 128K */
 
 		gpmc,sync-read;
diff --git a/arch/arm/boot/dts/omap3-n950-n9.dtsi b/arch/arm/boot/dts/omap3-n950-n9.dtsi
index 1b0bd72945f2..cb3c7b2fce52 100644
--- a/arch/arm/boot/dts/omap3-n950-n9.dtsi
+++ b/arch/arm/boot/dts/omap3-n950-n9.dtsi
@@ -367,6 +367,7 @@
 	onenand@0,0 {
 		#address-cells = <1>;
 		#size-cells = <1>;
+		compatible = "ti,omap2-onenand";
 		reg = <0 0 0x20000>;	/* CS0, offset 0, IO size 128K */
 
 		gpmc,sync-read;
diff --git a/arch/arm/boot/dts/omap3430-sdp.dts b/arch/arm/boot/dts/omap3430-sdp.dts
index d50a105c9dc6..ed65795ccc62 100644
--- a/arch/arm/boot/dts/omap3430-sdp.dts
+++ b/arch/arm/boot/dts/omap3430-sdp.dts
@@ -155,6 +155,7 @@
 		linux,mtd-name= "samsung,kfm2g16q2m-deb8";
 		#address-cells = <1>;
 		#size-cells = <1>;
+		compatible = "ti,omap2-onenand";
 		reg = <2 0 0x20000>;	/* CS2, offset 0, IO size 4 */
 
 		gpmc,device-width = <2>;
-- 
2.11.0

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

* [PATCH v4 03/16] ARM: dts: omap3-igep: Update onenand node timings
  2017-11-11 21:12 ` Ladislav Michl
@ 2017-11-11 21:18   ` Ladislav Michl
  -1 siblings, 0 replies; 114+ messages in thread
From: Ladislav Michl @ 2017-11-11 21:18 UTC (permalink / raw)
  To: linux-mtd, linux-omap
  Cc: Tony Lindgren, Peter Ujfalusi, Kyungmin Park, Boris Brezillon,
	Roger Quadros

Update node timings to be compatible with actual chip used -
gpmc_cs_show_timings utilized to dump values.

Signed-off-by: Ladislav Michl <ladis@linux-mips.org>
---
 Changes:
 -v4: new patch

 arch/arm/boot/dts/omap3-igep.dtsi | 30 +++++++++++++++---------------
 1 file changed, 15 insertions(+), 15 deletions(-)

diff --git a/arch/arm/boot/dts/omap3-igep.dtsi b/arch/arm/boot/dts/omap3-igep.dtsi
index 4929ba1cb9d3..1e4b8d5c7572 100644
--- a/arch/arm/boot/dts/omap3-igep.dtsi
+++ b/arch/arm/boot/dts/omap3-igep.dtsi
@@ -144,32 +144,32 @@
 		gpmc,sync-read;
 		gpmc,sync-write;
 		gpmc,burst-length = <16>;
-		gpmc,burst-read;
 		gpmc,burst-wrap;
+		gpmc,burst-read;
 		gpmc,burst-write;
 		gpmc,device-width = <2>; /* GPMC_DEVWIDTH_16BIT */
 		gpmc,mux-add-data = <2>; /* GPMC_MUX_AD */
 		gpmc,cs-on-ns = <0>;
-		gpmc,cs-rd-off-ns = <87>;
-		gpmc,cs-wr-off-ns = <87>;
+		gpmc,cs-rd-off-ns = <96>;
+		gpmc,cs-wr-off-ns = <96>;
 		gpmc,adv-on-ns = <0>;
-		gpmc,adv-rd-off-ns = <10>;
-		gpmc,adv-wr-off-ns = <10>;
-		gpmc,oe-on-ns = <15>;
-		gpmc,oe-off-ns = <87>;
+		gpmc,adv-rd-off-ns = <12>;
+		gpmc,adv-wr-off-ns = <12>;
+		gpmc,oe-on-ns = <18>;
+		gpmc,oe-off-ns = <96>;
 		gpmc,we-on-ns = <0>;
-		gpmc,we-off-ns = <87>;
-		gpmc,rd-cycle-ns = <112>;
-		gpmc,wr-cycle-ns = <112>;
-		gpmc,access-ns = <81>;
-		gpmc,page-burst-access-ns = <15>;
+		gpmc,we-off-ns = <96>;
+		gpmc,rd-cycle-ns = <114>;
+		gpmc,wr-cycle-ns = <114>;
+		gpmc,access-ns = <90>;
+		gpmc,page-burst-access-ns = <12>;
 		gpmc,bus-turnaround-ns = <0>;
 		gpmc,cycle2cycle-delay-ns = <0>;
 		gpmc,wait-monitoring-ns = <0>;
-		gpmc,clk-activation-ns = <5>;
+		gpmc,clk-activation-ns = <6>;
 		gpmc,wr-data-mux-bus-ns = <30>;
-		gpmc,wr-access-ns = <81>;
-		gpmc,sync-clk-ps = <15000>;
+		gpmc,wr-access-ns = <90>;
+		gpmc,sync-clk-ps = <12000>;
 
 		#address-cells = <1>;
 		#size-cells = <1>;
-- 
2.11.0


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

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

* [PATCH v4 03/16] ARM: dts: omap3-igep: Update onenand node timings
@ 2017-11-11 21:18   ` Ladislav Michl
  0 siblings, 0 replies; 114+ messages in thread
From: Ladislav Michl @ 2017-11-11 21:18 UTC (permalink / raw)
  To: linux-mtd, linux-omap
  Cc: Roger Quadros, Tony Lindgren, Peter Ujfalusi, Boris Brezillon,
	Kyungmin Park

Update node timings to be compatible with actual chip used -
gpmc_cs_show_timings utilized to dump values.

Signed-off-by: Ladislav Michl <ladis@linux-mips.org>
---
 Changes:
 -v4: new patch

 arch/arm/boot/dts/omap3-igep.dtsi | 30 +++++++++++++++---------------
 1 file changed, 15 insertions(+), 15 deletions(-)

diff --git a/arch/arm/boot/dts/omap3-igep.dtsi b/arch/arm/boot/dts/omap3-igep.dtsi
index 4929ba1cb9d3..1e4b8d5c7572 100644
--- a/arch/arm/boot/dts/omap3-igep.dtsi
+++ b/arch/arm/boot/dts/omap3-igep.dtsi
@@ -144,32 +144,32 @@
 		gpmc,sync-read;
 		gpmc,sync-write;
 		gpmc,burst-length = <16>;
-		gpmc,burst-read;
 		gpmc,burst-wrap;
+		gpmc,burst-read;
 		gpmc,burst-write;
 		gpmc,device-width = <2>; /* GPMC_DEVWIDTH_16BIT */
 		gpmc,mux-add-data = <2>; /* GPMC_MUX_AD */
 		gpmc,cs-on-ns = <0>;
-		gpmc,cs-rd-off-ns = <87>;
-		gpmc,cs-wr-off-ns = <87>;
+		gpmc,cs-rd-off-ns = <96>;
+		gpmc,cs-wr-off-ns = <96>;
 		gpmc,adv-on-ns = <0>;
-		gpmc,adv-rd-off-ns = <10>;
-		gpmc,adv-wr-off-ns = <10>;
-		gpmc,oe-on-ns = <15>;
-		gpmc,oe-off-ns = <87>;
+		gpmc,adv-rd-off-ns = <12>;
+		gpmc,adv-wr-off-ns = <12>;
+		gpmc,oe-on-ns = <18>;
+		gpmc,oe-off-ns = <96>;
 		gpmc,we-on-ns = <0>;
-		gpmc,we-off-ns = <87>;
-		gpmc,rd-cycle-ns = <112>;
-		gpmc,wr-cycle-ns = <112>;
-		gpmc,access-ns = <81>;
-		gpmc,page-burst-access-ns = <15>;
+		gpmc,we-off-ns = <96>;
+		gpmc,rd-cycle-ns = <114>;
+		gpmc,wr-cycle-ns = <114>;
+		gpmc,access-ns = <90>;
+		gpmc,page-burst-access-ns = <12>;
 		gpmc,bus-turnaround-ns = <0>;
 		gpmc,cycle2cycle-delay-ns = <0>;
 		gpmc,wait-monitoring-ns = <0>;
-		gpmc,clk-activation-ns = <5>;
+		gpmc,clk-activation-ns = <6>;
 		gpmc,wr-data-mux-bus-ns = <30>;
-		gpmc,wr-access-ns = <81>;
-		gpmc,sync-clk-ps = <15000>;
+		gpmc,wr-access-ns = <90>;
+		gpmc,sync-clk-ps = <12000>;
 
 		#address-cells = <1>;
 		#size-cells = <1>;
-- 
2.11.0

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

* [PATCH v4 04/16] mtd: onenand: omap2: Remove regulator support
  2017-11-11 21:12 ` Ladislav Michl
@ 2017-11-11 21:19   ` Ladislav Michl
  -1 siblings, 0 replies; 114+ messages in thread
From: Ladislav Michl @ 2017-11-11 21:19 UTC (permalink / raw)
  To: linux-mtd, linux-omap
  Cc: Tony Lindgren, Peter Ujfalusi, Kyungmin Park, Boris Brezillon,
	Roger Quadros

As no platform data user sets regulator_can_sleep, regulator code is
no-op and can be deleted.

Signed-off-by: Ladislav Michl <ladis@linux-mips.org>
---
 Changes:
 -v2: new patch
 -v3: none
 -v4: none

 drivers/mtd/onenand/omap2.c | 42 +-----------------------------------------
 1 file changed, 1 insertion(+), 41 deletions(-)

diff --git a/drivers/mtd/onenand/omap2.c b/drivers/mtd/onenand/omap2.c
index 24a1388d3031..a03e1fe4aa48 100644
--- a/drivers/mtd/onenand/omap2.c
+++ b/drivers/mtd/onenand/omap2.c
@@ -34,7 +34,6 @@
 #include <linux/dma-mapping.h>
 #include <linux/io.h>
 #include <linux/slab.h>
-#include <linux/regulator/consumer.h>
 #include <linux/gpio.h>
 
 #include <asm/mach/flash.h>
@@ -59,7 +58,6 @@ struct omap2_onenand {
 	int dma_channel;
 	int freq;
 	int (*setup)(void __iomem *base, int *freq_ptr);
-	struct regulator *regulator;
 	u8 flags;
 };
 
@@ -583,30 +581,6 @@ static void omap2_onenand_shutdown(struct platform_device *pdev)
 	memset((__force void *)c->onenand.base, 0, ONENAND_BUFRAM_SIZE);
 }
 
-static int omap2_onenand_enable(struct mtd_info *mtd)
-{
-	int ret;
-	struct omap2_onenand *c = container_of(mtd, struct omap2_onenand, mtd);
-
-	ret = regulator_enable(c->regulator);
-	if (ret != 0)
-		dev_err(&c->pdev->dev, "can't enable regulator\n");
-
-	return ret;
-}
-
-static int omap2_onenand_disable(struct mtd_info *mtd)
-{
-	int ret;
-	struct omap2_onenand *c = container_of(mtd, struct omap2_onenand, mtd);
-
-	ret = regulator_disable(c->regulator);
-	if (ret != 0)
-		dev_err(&c->pdev->dev, "can't disable regulator\n");
-
-	return ret;
-}
-
 static int omap2_onenand_probe(struct platform_device *pdev)
 {
 	struct omap_onenand_platform_data *pdata;
@@ -726,22 +700,11 @@ static int omap2_onenand_probe(struct platform_device *pdev)
 		}
 	}
 
-	if (pdata->regulator_can_sleep) {
-		c->regulator = regulator_get(&pdev->dev, "vonenand");
-		if (IS_ERR(c->regulator)) {
-			dev_err(&pdev->dev,  "Failed to get regulator\n");
-			r = PTR_ERR(c->regulator);
-			goto err_release_dma;
-		}
-		c->onenand.enable = omap2_onenand_enable;
-		c->onenand.disable = omap2_onenand_disable;
-	}
-
 	if (pdata->skip_initial_unlocking)
 		this->options |= ONENAND_SKIP_INITIAL_UNLOCKING;
 
 	if ((r = onenand_scan(&c->mtd, 1)) < 0)
-		goto err_release_regulator;
+		goto err_release_dma;
 
 	r = mtd_device_register(&c->mtd, pdata ? pdata->parts : NULL,
 				pdata ? pdata->nr_parts : 0);
@@ -754,8 +717,6 @@ static int omap2_onenand_probe(struct platform_device *pdev)
 
 err_release_onenand:
 	onenand_release(&c->mtd);
-err_release_regulator:
-	regulator_put(c->regulator);
 err_release_dma:
 	if (c->dma_channel != -1)
 		omap_free_dma(c->dma_channel);
@@ -779,7 +740,6 @@ static int omap2_onenand_remove(struct platform_device *pdev)
 	struct omap2_onenand *c = dev_get_drvdata(&pdev->dev);
 
 	onenand_release(&c->mtd);
-	regulator_put(c->regulator);
 	if (c->dma_channel != -1)
 		omap_free_dma(c->dma_channel);
 	omap2_onenand_shutdown(pdev);
-- 
2.11.0


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

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

* [PATCH v4 04/16] mtd: onenand: omap2: Remove regulator support
@ 2017-11-11 21:19   ` Ladislav Michl
  0 siblings, 0 replies; 114+ messages in thread
From: Ladislav Michl @ 2017-11-11 21:19 UTC (permalink / raw)
  To: linux-mtd, linux-omap
  Cc: Roger Quadros, Tony Lindgren, Peter Ujfalusi, Boris Brezillon,
	Kyungmin Park

As no platform data user sets regulator_can_sleep, regulator code is
no-op and can be deleted.

Signed-off-by: Ladislav Michl <ladis@linux-mips.org>
---
 Changes:
 -v2: new patch
 -v3: none
 -v4: none

 drivers/mtd/onenand/omap2.c | 42 +-----------------------------------------
 1 file changed, 1 insertion(+), 41 deletions(-)

diff --git a/drivers/mtd/onenand/omap2.c b/drivers/mtd/onenand/omap2.c
index 24a1388d3031..a03e1fe4aa48 100644
--- a/drivers/mtd/onenand/omap2.c
+++ b/drivers/mtd/onenand/omap2.c
@@ -34,7 +34,6 @@
 #include <linux/dma-mapping.h>
 #include <linux/io.h>
 #include <linux/slab.h>
-#include <linux/regulator/consumer.h>
 #include <linux/gpio.h>
 
 #include <asm/mach/flash.h>
@@ -59,7 +58,6 @@ struct omap2_onenand {
 	int dma_channel;
 	int freq;
 	int (*setup)(void __iomem *base, int *freq_ptr);
-	struct regulator *regulator;
 	u8 flags;
 };
 
@@ -583,30 +581,6 @@ static void omap2_onenand_shutdown(struct platform_device *pdev)
 	memset((__force void *)c->onenand.base, 0, ONENAND_BUFRAM_SIZE);
 }
 
-static int omap2_onenand_enable(struct mtd_info *mtd)
-{
-	int ret;
-	struct omap2_onenand *c = container_of(mtd, struct omap2_onenand, mtd);
-
-	ret = regulator_enable(c->regulator);
-	if (ret != 0)
-		dev_err(&c->pdev->dev, "can't enable regulator\n");
-
-	return ret;
-}
-
-static int omap2_onenand_disable(struct mtd_info *mtd)
-{
-	int ret;
-	struct omap2_onenand *c = container_of(mtd, struct omap2_onenand, mtd);
-
-	ret = regulator_disable(c->regulator);
-	if (ret != 0)
-		dev_err(&c->pdev->dev, "can't disable regulator\n");
-
-	return ret;
-}
-
 static int omap2_onenand_probe(struct platform_device *pdev)
 {
 	struct omap_onenand_platform_data *pdata;
@@ -726,22 +700,11 @@ static int omap2_onenand_probe(struct platform_device *pdev)
 		}
 	}
 
-	if (pdata->regulator_can_sleep) {
-		c->regulator = regulator_get(&pdev->dev, "vonenand");
-		if (IS_ERR(c->regulator)) {
-			dev_err(&pdev->dev,  "Failed to get regulator\n");
-			r = PTR_ERR(c->regulator);
-			goto err_release_dma;
-		}
-		c->onenand.enable = omap2_onenand_enable;
-		c->onenand.disable = omap2_onenand_disable;
-	}
-
 	if (pdata->skip_initial_unlocking)
 		this->options |= ONENAND_SKIP_INITIAL_UNLOCKING;
 
 	if ((r = onenand_scan(&c->mtd, 1)) < 0)
-		goto err_release_regulator;
+		goto err_release_dma;
 
 	r = mtd_device_register(&c->mtd, pdata ? pdata->parts : NULL,
 				pdata ? pdata->nr_parts : 0);
@@ -754,8 +717,6 @@ static int omap2_onenand_probe(struct platform_device *pdev)
 
 err_release_onenand:
 	onenand_release(&c->mtd);
-err_release_regulator:
-	regulator_put(c->regulator);
 err_release_dma:
 	if (c->dma_channel != -1)
 		omap_free_dma(c->dma_channel);
@@ -779,7 +740,6 @@ static int omap2_onenand_remove(struct platform_device *pdev)
 	struct omap2_onenand *c = dev_get_drvdata(&pdev->dev);
 
 	onenand_release(&c->mtd);
-	regulator_put(c->regulator);
 	if (c->dma_channel != -1)
 		omap_free_dma(c->dma_channel);
 	omap2_onenand_shutdown(pdev);
-- 
2.11.0

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

* [PATCH v4 05/16] mtd: onenand: omap2: Remove skip initial unlocking support
  2017-11-11 21:12 ` Ladislav Michl
@ 2017-11-11 21:19   ` Ladislav Michl
  -1 siblings, 0 replies; 114+ messages in thread
From: Ladislav Michl @ 2017-11-11 21:19 UTC (permalink / raw)
  To: linux-mtd, linux-omap
  Cc: Tony Lindgren, Peter Ujfalusi, Kyungmin Park, Boris Brezillon,
	Roger Quadros

No platform data user sets skip_initial_unlocking, so remove test
for this field.

Signed-off-by: Ladislav Michl <ladis@linux-mips.org>
---
 Changes:
 -v2: new patch
 -v3: none
 -v4: none

 drivers/mtd/onenand/omap2.c | 3 ---
 1 file changed, 3 deletions(-)

diff --git a/drivers/mtd/onenand/omap2.c b/drivers/mtd/onenand/omap2.c
index a03e1fe4aa48..93bd94337b35 100644
--- a/drivers/mtd/onenand/omap2.c
+++ b/drivers/mtd/onenand/omap2.c
@@ -700,9 +700,6 @@ static int omap2_onenand_probe(struct platform_device *pdev)
 		}
 	}
 
-	if (pdata->skip_initial_unlocking)
-		this->options |= ONENAND_SKIP_INITIAL_UNLOCKING;
-
 	if ((r = onenand_scan(&c->mtd, 1)) < 0)
 		goto err_release_dma;
 
-- 
2.11.0


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

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

* [PATCH v4 05/16] mtd: onenand: omap2: Remove skip initial unlocking support
@ 2017-11-11 21:19   ` Ladislav Michl
  0 siblings, 0 replies; 114+ messages in thread
From: Ladislav Michl @ 2017-11-11 21:19 UTC (permalink / raw)
  To: linux-mtd, linux-omap
  Cc: Roger Quadros, Tony Lindgren, Peter Ujfalusi, Boris Brezillon,
	Kyungmin Park

No platform data user sets skip_initial_unlocking, so remove test
for this field.

Signed-off-by: Ladislav Michl <ladis@linux-mips.org>
---
 Changes:
 -v2: new patch
 -v3: none
 -v4: none

 drivers/mtd/onenand/omap2.c | 3 ---
 1 file changed, 3 deletions(-)

diff --git a/drivers/mtd/onenand/omap2.c b/drivers/mtd/onenand/omap2.c
index a03e1fe4aa48..93bd94337b35 100644
--- a/drivers/mtd/onenand/omap2.c
+++ b/drivers/mtd/onenand/omap2.c
@@ -700,9 +700,6 @@ static int omap2_onenand_probe(struct platform_device *pdev)
 		}
 	}
 
-	if (pdata->skip_initial_unlocking)
-		this->options |= ONENAND_SKIP_INITIAL_UNLOCKING;
-
 	if ((r = onenand_scan(&c->mtd, 1)) < 0)
 		goto err_release_dma;
 
-- 
2.11.0

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

* [PATCH v4 06/16] mtd: onenand: omap2: Remove partitioning support from platform data
  2017-11-11 21:12 ` Ladislav Michl
@ 2017-11-11 21:20   ` Ladislav Michl
  -1 siblings, 0 replies; 114+ messages in thread
From: Ladislav Michl @ 2017-11-11 21:20 UTC (permalink / raw)
  To: linux-mtd, linux-omap
  Cc: Tony Lindgren, Peter Ujfalusi, Kyungmin Park, Boris Brezillon,
	Roger Quadros

No platform data user setups partitioning informations, so remove.

Signed-off-by: Ladislav Michl <ladis@linux-mips.org>
---
 Changes:
 -v2: new patch
 -v3: none
 -v4: none

 drivers/mtd/onenand/omap2.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/drivers/mtd/onenand/omap2.c b/drivers/mtd/onenand/omap2.c
index 93bd94337b35..883993bbe40b 100644
--- a/drivers/mtd/onenand/omap2.c
+++ b/drivers/mtd/onenand/omap2.c
@@ -703,8 +703,7 @@ static int omap2_onenand_probe(struct platform_device *pdev)
 	if ((r = onenand_scan(&c->mtd, 1)) < 0)
 		goto err_release_dma;
 
-	r = mtd_device_register(&c->mtd, pdata ? pdata->parts : NULL,
-				pdata ? pdata->nr_parts : 0);
+	r = mtd_device_register(&c->mtd, NULL, 0);
 	if (r)
 		goto err_release_onenand;
 
-- 
2.11.0


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

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

* [PATCH v4 06/16] mtd: onenand: omap2: Remove partitioning support from platform data
@ 2017-11-11 21:20   ` Ladislav Michl
  0 siblings, 0 replies; 114+ messages in thread
From: Ladislav Michl @ 2017-11-11 21:20 UTC (permalink / raw)
  To: linux-mtd, linux-omap
  Cc: Roger Quadros, Tony Lindgren, Peter Ujfalusi, Boris Brezillon,
	Kyungmin Park

No platform data user setups partitioning informations, so remove.

Signed-off-by: Ladislav Michl <ladis@linux-mips.org>
---
 Changes:
 -v2: new patch
 -v3: none
 -v4: none

 drivers/mtd/onenand/omap2.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/drivers/mtd/onenand/omap2.c b/drivers/mtd/onenand/omap2.c
index 93bd94337b35..883993bbe40b 100644
--- a/drivers/mtd/onenand/omap2.c
+++ b/drivers/mtd/onenand/omap2.c
@@ -703,8 +703,7 @@ static int omap2_onenand_probe(struct platform_device *pdev)
 	if ((r = onenand_scan(&c->mtd, 1)) < 0)
 		goto err_release_dma;
 
-	r = mtd_device_register(&c->mtd, pdata ? pdata->parts : NULL,
-				pdata ? pdata->nr_parts : 0);
+	r = mtd_device_register(&c->mtd, NULL, 0);
 	if (r)
 		goto err_release_onenand;
 
-- 
2.11.0

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

* [PATCH v4 07/16] mtd: onenand: omap2: Account waiting time as waiting on IO
  2017-11-11 21:12 ` Ladislav Michl
@ 2017-11-11 21:20   ` Ladislav Michl
  -1 siblings, 0 replies; 114+ messages in thread
From: Ladislav Michl @ 2017-11-11 21:20 UTC (permalink / raw)
  To: linux-mtd, linux-omap
  Cc: Tony Lindgren, Peter Ujfalusi, Kyungmin Park, Boris Brezillon,
	Roger Quadros

Use wait_for_completion_io_timeout, which has an impact on how the
task is accounted in scheduling stats.

Signed-off-by: Ladislav Michl <ladis@linux-mips.org>
---
 Changes:
 -v4: new patch

 drivers/mtd/onenand/omap2.c | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/drivers/mtd/onenand/omap2.c b/drivers/mtd/onenand/omap2.c
index 883993bbe40b..0e7772e16d75 100644
--- a/drivers/mtd/onenand/omap2.c
+++ b/drivers/mtd/onenand/omap2.c
@@ -170,9 +170,8 @@ static int omap2_onenand_wait(struct mtd_info *mtd, int state)
 		if (result == 0) {
 			int retry_cnt = 0;
 retry:
-			result = wait_for_completion_timeout(&c->irq_done,
-						    msecs_to_jiffies(20));
-			if (result == 0) {
+			if (!wait_for_completion_io_timeout(&c->irq_done,
+						msecs_to_jiffies(20))) {
 				/* Timeout after 20ms */
 				ctrl = read_reg(c, ONENAND_REG_CTRL_STATUS);
 				if (ctrl & ONENAND_CTRL_ONGO &&
-- 
2.11.0


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

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

* [PATCH v4 07/16] mtd: onenand: omap2: Account waiting time as waiting on IO
@ 2017-11-11 21:20   ` Ladislav Michl
  0 siblings, 0 replies; 114+ messages in thread
From: Ladislav Michl @ 2017-11-11 21:20 UTC (permalink / raw)
  To: linux-mtd, linux-omap
  Cc: Roger Quadros, Tony Lindgren, Peter Ujfalusi, Boris Brezillon,
	Kyungmin Park

Use wait_for_completion_io_timeout, which has an impact on how the
task is accounted in scheduling stats.

Signed-off-by: Ladislav Michl <ladis@linux-mips.org>
---
 Changes:
 -v4: new patch

 drivers/mtd/onenand/omap2.c | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/drivers/mtd/onenand/omap2.c b/drivers/mtd/onenand/omap2.c
index 883993bbe40b..0e7772e16d75 100644
--- a/drivers/mtd/onenand/omap2.c
+++ b/drivers/mtd/onenand/omap2.c
@@ -170,9 +170,8 @@ static int omap2_onenand_wait(struct mtd_info *mtd, int state)
 		if (result == 0) {
 			int retry_cnt = 0;
 retry:
-			result = wait_for_completion_timeout(&c->irq_done,
-						    msecs_to_jiffies(20));
-			if (result == 0) {
+			if (!wait_for_completion_io_timeout(&c->irq_done,
+						msecs_to_jiffies(20))) {
 				/* Timeout after 20ms */
 				ctrl = read_reg(c, ONENAND_REG_CTRL_STATUS);
 				if (ctrl & ONENAND_CTRL_ONGO &&
-- 
2.11.0

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

* [PATCH v4 08/16] mtd: onenand: omap2: Simplify the DMA setup for various paths
  2017-11-11 21:12 ` Ladislav Michl
@ 2017-11-11 21:21   ` Ladislav Michl
  -1 siblings, 0 replies; 114+ messages in thread
From: Ladislav Michl @ 2017-11-11 21:21 UTC (permalink / raw)
  To: linux-mtd, linux-omap
  Cc: Tony Lindgren, Peter Ujfalusi, Kyungmin Park, Boris Brezillon,
	Roger Quadros

From: Peter Ujfalusi <peter.ujfalusi@ti.com>

We have 4 functions containing almost identical DMA setup code. Create one
function which can set up the DMA for both read and write and use this in
place for the setup code in the driver.
The new function will use wait_for_completion_io_timeout() and it will
figure out the best data_type to be used for the transfer instead of
hardwiring 32 or 16 bit data.

Signed-off-by: Peter Ujfalusi <peter.ujfalusi@ti.com>
Signed-off-by: Ladislav Michl <ladis@linux-mips.org>
---
 Changes:
 -v4: new patch

 drivers/mtd/onenand/omap2.c | 109 ++++++++++++++++++--------------------------
 1 file changed, 45 insertions(+), 64 deletions(-)

diff --git a/drivers/mtd/onenand/omap2.c b/drivers/mtd/onenand/omap2.c
index 0e7772e16d75..d22163271dc9 100644
--- a/drivers/mtd/onenand/omap2.c
+++ b/drivers/mtd/onenand/omap2.c
@@ -288,6 +288,33 @@ static inline int omap2_onenand_bufferram_offset(struct mtd_info *mtd, int area)
 	return 0;
 }
 
+static inline int omap2_onenand_dma_transfer(struct omap2_onenand *c,
+					     dma_addr_t src, dma_addr_t dst,
+					     size_t count)
+{
+	int data_type = __ffs((src | dst | count));
+
+	if (data_type > OMAP_DMA_DATA_TYPE_S32)
+		data_type = OMAP_DMA_DATA_TYPE_S32;
+
+	omap_set_dma_transfer_params(c->dma_channel, data_type,
+				     count / BIT(data_type), 1, 0, 0, 0);
+	omap_set_dma_src_params(c->dma_channel, 0, OMAP_DMA_AMODE_POST_INC,
+				src, 0, 0);
+	omap_set_dma_dest_params(c->dma_channel, 0, OMAP_DMA_AMODE_POST_INC,
+				 dst, 0, 0);
+
+	reinit_completion(&c->dma_done);
+	omap_start_dma(c->dma_channel);
+	if (!wait_for_completion_io_timeout(&c->dma_done,
+					    msecs_to_jiffies(20))) {
+		omap_stop_dma(c->dma_channel);
+		return -ETIMEDOUT;
+	}
+
+	return 0;
+}
+
 #if defined(CONFIG_ARCH_OMAP3) || defined(MULTI_OMAP2)
 
 static int omap3_onenand_read_bufferram(struct mtd_info *mtd, int area,
@@ -298,10 +325,9 @@ static int omap3_onenand_read_bufferram(struct mtd_info *mtd, int area,
 	struct onenand_chip *this = mtd->priv;
 	dma_addr_t dma_src, dma_dst;
 	int bram_offset;
-	unsigned long timeout;
 	void *buf = (void *)buffer;
 	size_t xtra;
-	volatile unsigned *done;
+	int ret;
 
 	bram_offset = omap2_onenand_bufferram_offset(mtd, area) + area + offset;
 	if (bram_offset & 3 || (size_t)buf & 3 || count < 384)
@@ -338,25 +364,10 @@ static int omap3_onenand_read_bufferram(struct mtd_info *mtd, int area,
 		goto out_copy;
 	}
 
-	omap_set_dma_transfer_params(c->dma_channel, OMAP_DMA_DATA_TYPE_S32,
-				     count >> 2, 1, 0, 0, 0);
-	omap_set_dma_src_params(c->dma_channel, 0, OMAP_DMA_AMODE_POST_INC,
-				dma_src, 0, 0);
-	omap_set_dma_dest_params(c->dma_channel, 0, OMAP_DMA_AMODE_POST_INC,
-				 dma_dst, 0, 0);
-
-	reinit_completion(&c->dma_done);
-	omap_start_dma(c->dma_channel);
-
-	timeout = jiffies + msecs_to_jiffies(20);
-	done = &c->dma_done.done;
-	while (time_before(jiffies, timeout))
-		if (*done)
-			break;
-
+	ret = omap2_onenand_dma_transfer(c, dma_src, dma_dst, count);
 	dma_unmap_single(&c->pdev->dev, dma_dst, count, DMA_FROM_DEVICE);
 
-	if (!*done) {
+	if (ret) {
 		dev_err(&c->pdev->dev, "timeout waiting for DMA\n");
 		goto out_copy;
 	}
@@ -376,9 +387,8 @@ static int omap3_onenand_write_bufferram(struct mtd_info *mtd, int area,
 	struct onenand_chip *this = mtd->priv;
 	dma_addr_t dma_src, dma_dst;
 	int bram_offset;
-	unsigned long timeout;
 	void *buf = (void *)buffer;
-	volatile unsigned *done;
+	int ret;
 
 	bram_offset = omap2_onenand_bufferram_offset(mtd, area) + area + offset;
 	if (bram_offset & 3 || (size_t)buf & 3 || count < 384)
@@ -409,25 +419,10 @@ static int omap3_onenand_write_bufferram(struct mtd_info *mtd, int area,
 		return -1;
 	}
 
-	omap_set_dma_transfer_params(c->dma_channel, OMAP_DMA_DATA_TYPE_S32,
-				     count >> 2, 1, 0, 0, 0);
-	omap_set_dma_src_params(c->dma_channel, 0, OMAP_DMA_AMODE_POST_INC,
-				dma_src, 0, 0);
-	omap_set_dma_dest_params(c->dma_channel, 0, OMAP_DMA_AMODE_POST_INC,
-				 dma_dst, 0, 0);
-
-	reinit_completion(&c->dma_done);
-	omap_start_dma(c->dma_channel);
-
-	timeout = jiffies + msecs_to_jiffies(20);
-	done = &c->dma_done.done;
-	while (time_before(jiffies, timeout))
-		if (*done)
-			break;
-
+	ret = omap2_onenand_dma_transfer(c, dma_src, dma_dst, count);
 	dma_unmap_single(&c->pdev->dev, dma_src, count, DMA_TO_DEVICE);
 
-	if (!*done) {
+	if (ret) {
 		dev_err(&c->pdev->dev, "timeout waiting for DMA\n");
 		goto out_copy;
 	}
@@ -466,7 +461,7 @@ static int omap2_onenand_read_bufferram(struct mtd_info *mtd, int area,
 	struct omap2_onenand *c = container_of(mtd, struct omap2_onenand, mtd);
 	struct onenand_chip *this = mtd->priv;
 	dma_addr_t dma_src, dma_dst;
-	int bram_offset;
+	int bram_offset, ret;
 
 	bram_offset = omap2_onenand_bufferram_offset(mtd, area) + area + offset;
 	/* DMA is not used.  Revisit PM requirements before enabling it. */
@@ -488,20 +483,13 @@ static int omap2_onenand_read_bufferram(struct mtd_info *mtd, int area,
 		return -1;
 	}
 
-	omap_set_dma_transfer_params(c->dma_channel, OMAP_DMA_DATA_TYPE_S32,
-				     count / 4, 1, 0, 0, 0);
-	omap_set_dma_src_params(c->dma_channel, 0, OMAP_DMA_AMODE_POST_INC,
-				dma_src, 0, 0);
-	omap_set_dma_dest_params(c->dma_channel, 0, OMAP_DMA_AMODE_POST_INC,
-				 dma_dst, 0, 0);
-
-	reinit_completion(&c->dma_done);
-	omap_start_dma(c->dma_channel);
-	wait_for_completion(&c->dma_done);
-
+	ret = omap2_onenand_dma_transfer(c, dma_src, dma_dst, count);
 	dma_unmap_single(&c->pdev->dev, dma_dst, count, DMA_FROM_DEVICE);
 
-	return 0;
+	if (ret)
+		dev_err(&c->pdev->dev, "timeout waiting for DMA\n");
+
+	return ret;
 }
 
 static int omap2_onenand_write_bufferram(struct mtd_info *mtd, int area,
@@ -511,7 +499,7 @@ static int omap2_onenand_write_bufferram(struct mtd_info *mtd, int area,
 	struct omap2_onenand *c = container_of(mtd, struct omap2_onenand, mtd);
 	struct onenand_chip *this = mtd->priv;
 	dma_addr_t dma_src, dma_dst;
-	int bram_offset;
+	int bram_offset, ret;
 
 	bram_offset = omap2_onenand_bufferram_offset(mtd, area) + area + offset;
 	/* DMA is not used.  Revisit PM requirements before enabling it. */
@@ -533,20 +521,13 @@ static int omap2_onenand_write_bufferram(struct mtd_info *mtd, int area,
 		return -1;
 	}
 
-	omap_set_dma_transfer_params(c->dma_channel, OMAP_DMA_DATA_TYPE_S16,
-				     count / 2, 1, 0, 0, 0);
-	omap_set_dma_src_params(c->dma_channel, 0, OMAP_DMA_AMODE_POST_INC,
-				dma_src, 0, 0);
-	omap_set_dma_dest_params(c->dma_channel, 0, OMAP_DMA_AMODE_POST_INC,
-				 dma_dst, 0, 0);
-
-	reinit_completion(&c->dma_done);
-	omap_start_dma(c->dma_channel);
-	wait_for_completion(&c->dma_done);
-
+	ret = omap2_onenand_dma_transfer(c, dma_src, dma_dst, count);
 	dma_unmap_single(&c->pdev->dev, dma_src, count, DMA_TO_DEVICE);
 
-	return 0;
+	if (ret)
+		dev_err(&c->pdev->dev, "timeout waiting for DMA\n");
+
+	return ret;
 }
 
 #else
-- 
2.11.0


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

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

* [PATCH v4 08/16] mtd: onenand: omap2: Simplify the DMA setup for various paths
@ 2017-11-11 21:21   ` Ladislav Michl
  0 siblings, 0 replies; 114+ messages in thread
From: Ladislav Michl @ 2017-11-11 21:21 UTC (permalink / raw)
  To: linux-mtd, linux-omap
  Cc: Roger Quadros, Tony Lindgren, Peter Ujfalusi, Boris Brezillon,
	Kyungmin Park

From: Peter Ujfalusi <peter.ujfalusi@ti.com>

We have 4 functions containing almost identical DMA setup code. Create one
function which can set up the DMA for both read and write and use this in
place for the setup code in the driver.
The new function will use wait_for_completion_io_timeout() and it will
figure out the best data_type to be used for the transfer instead of
hardwiring 32 or 16 bit data.

Signed-off-by: Peter Ujfalusi <peter.ujfalusi@ti.com>
Signed-off-by: Ladislav Michl <ladis@linux-mips.org>
---
 Changes:
 -v4: new patch

 drivers/mtd/onenand/omap2.c | 109 ++++++++++++++++++--------------------------
 1 file changed, 45 insertions(+), 64 deletions(-)

diff --git a/drivers/mtd/onenand/omap2.c b/drivers/mtd/onenand/omap2.c
index 0e7772e16d75..d22163271dc9 100644
--- a/drivers/mtd/onenand/omap2.c
+++ b/drivers/mtd/onenand/omap2.c
@@ -288,6 +288,33 @@ static inline int omap2_onenand_bufferram_offset(struct mtd_info *mtd, int area)
 	return 0;
 }
 
+static inline int omap2_onenand_dma_transfer(struct omap2_onenand *c,
+					     dma_addr_t src, dma_addr_t dst,
+					     size_t count)
+{
+	int data_type = __ffs((src | dst | count));
+
+	if (data_type > OMAP_DMA_DATA_TYPE_S32)
+		data_type = OMAP_DMA_DATA_TYPE_S32;
+
+	omap_set_dma_transfer_params(c->dma_channel, data_type,
+				     count / BIT(data_type), 1, 0, 0, 0);
+	omap_set_dma_src_params(c->dma_channel, 0, OMAP_DMA_AMODE_POST_INC,
+				src, 0, 0);
+	omap_set_dma_dest_params(c->dma_channel, 0, OMAP_DMA_AMODE_POST_INC,
+				 dst, 0, 0);
+
+	reinit_completion(&c->dma_done);
+	omap_start_dma(c->dma_channel);
+	if (!wait_for_completion_io_timeout(&c->dma_done,
+					    msecs_to_jiffies(20))) {
+		omap_stop_dma(c->dma_channel);
+		return -ETIMEDOUT;
+	}
+
+	return 0;
+}
+
 #if defined(CONFIG_ARCH_OMAP3) || defined(MULTI_OMAP2)
 
 static int omap3_onenand_read_bufferram(struct mtd_info *mtd, int area,
@@ -298,10 +325,9 @@ static int omap3_onenand_read_bufferram(struct mtd_info *mtd, int area,
 	struct onenand_chip *this = mtd->priv;
 	dma_addr_t dma_src, dma_dst;
 	int bram_offset;
-	unsigned long timeout;
 	void *buf = (void *)buffer;
 	size_t xtra;
-	volatile unsigned *done;
+	int ret;
 
 	bram_offset = omap2_onenand_bufferram_offset(mtd, area) + area + offset;
 	if (bram_offset & 3 || (size_t)buf & 3 || count < 384)
@@ -338,25 +364,10 @@ static int omap3_onenand_read_bufferram(struct mtd_info *mtd, int area,
 		goto out_copy;
 	}
 
-	omap_set_dma_transfer_params(c->dma_channel, OMAP_DMA_DATA_TYPE_S32,
-				     count >> 2, 1, 0, 0, 0);
-	omap_set_dma_src_params(c->dma_channel, 0, OMAP_DMA_AMODE_POST_INC,
-				dma_src, 0, 0);
-	omap_set_dma_dest_params(c->dma_channel, 0, OMAP_DMA_AMODE_POST_INC,
-				 dma_dst, 0, 0);
-
-	reinit_completion(&c->dma_done);
-	omap_start_dma(c->dma_channel);
-
-	timeout = jiffies + msecs_to_jiffies(20);
-	done = &c->dma_done.done;
-	while (time_before(jiffies, timeout))
-		if (*done)
-			break;
-
+	ret = omap2_onenand_dma_transfer(c, dma_src, dma_dst, count);
 	dma_unmap_single(&c->pdev->dev, dma_dst, count, DMA_FROM_DEVICE);
 
-	if (!*done) {
+	if (ret) {
 		dev_err(&c->pdev->dev, "timeout waiting for DMA\n");
 		goto out_copy;
 	}
@@ -376,9 +387,8 @@ static int omap3_onenand_write_bufferram(struct mtd_info *mtd, int area,
 	struct onenand_chip *this = mtd->priv;
 	dma_addr_t dma_src, dma_dst;
 	int bram_offset;
-	unsigned long timeout;
 	void *buf = (void *)buffer;
-	volatile unsigned *done;
+	int ret;
 
 	bram_offset = omap2_onenand_bufferram_offset(mtd, area) + area + offset;
 	if (bram_offset & 3 || (size_t)buf & 3 || count < 384)
@@ -409,25 +419,10 @@ static int omap3_onenand_write_bufferram(struct mtd_info *mtd, int area,
 		return -1;
 	}
 
-	omap_set_dma_transfer_params(c->dma_channel, OMAP_DMA_DATA_TYPE_S32,
-				     count >> 2, 1, 0, 0, 0);
-	omap_set_dma_src_params(c->dma_channel, 0, OMAP_DMA_AMODE_POST_INC,
-				dma_src, 0, 0);
-	omap_set_dma_dest_params(c->dma_channel, 0, OMAP_DMA_AMODE_POST_INC,
-				 dma_dst, 0, 0);
-
-	reinit_completion(&c->dma_done);
-	omap_start_dma(c->dma_channel);
-
-	timeout = jiffies + msecs_to_jiffies(20);
-	done = &c->dma_done.done;
-	while (time_before(jiffies, timeout))
-		if (*done)
-			break;
-
+	ret = omap2_onenand_dma_transfer(c, dma_src, dma_dst, count);
 	dma_unmap_single(&c->pdev->dev, dma_src, count, DMA_TO_DEVICE);
 
-	if (!*done) {
+	if (ret) {
 		dev_err(&c->pdev->dev, "timeout waiting for DMA\n");
 		goto out_copy;
 	}
@@ -466,7 +461,7 @@ static int omap2_onenand_read_bufferram(struct mtd_info *mtd, int area,
 	struct omap2_onenand *c = container_of(mtd, struct omap2_onenand, mtd);
 	struct onenand_chip *this = mtd->priv;
 	dma_addr_t dma_src, dma_dst;
-	int bram_offset;
+	int bram_offset, ret;
 
 	bram_offset = omap2_onenand_bufferram_offset(mtd, area) + area + offset;
 	/* DMA is not used.  Revisit PM requirements before enabling it. */
@@ -488,20 +483,13 @@ static int omap2_onenand_read_bufferram(struct mtd_info *mtd, int area,
 		return -1;
 	}
 
-	omap_set_dma_transfer_params(c->dma_channel, OMAP_DMA_DATA_TYPE_S32,
-				     count / 4, 1, 0, 0, 0);
-	omap_set_dma_src_params(c->dma_channel, 0, OMAP_DMA_AMODE_POST_INC,
-				dma_src, 0, 0);
-	omap_set_dma_dest_params(c->dma_channel, 0, OMAP_DMA_AMODE_POST_INC,
-				 dma_dst, 0, 0);
-
-	reinit_completion(&c->dma_done);
-	omap_start_dma(c->dma_channel);
-	wait_for_completion(&c->dma_done);
-
+	ret = omap2_onenand_dma_transfer(c, dma_src, dma_dst, count);
 	dma_unmap_single(&c->pdev->dev, dma_dst, count, DMA_FROM_DEVICE);
 
-	return 0;
+	if (ret)
+		dev_err(&c->pdev->dev, "timeout waiting for DMA\n");
+
+	return ret;
 }
 
 static int omap2_onenand_write_bufferram(struct mtd_info *mtd, int area,
@@ -511,7 +499,7 @@ static int omap2_onenand_write_bufferram(struct mtd_info *mtd, int area,
 	struct omap2_onenand *c = container_of(mtd, struct omap2_onenand, mtd);
 	struct onenand_chip *this = mtd->priv;
 	dma_addr_t dma_src, dma_dst;
-	int bram_offset;
+	int bram_offset, ret;
 
 	bram_offset = omap2_onenand_bufferram_offset(mtd, area) + area + offset;
 	/* DMA is not used.  Revisit PM requirements before enabling it. */
@@ -533,20 +521,13 @@ static int omap2_onenand_write_bufferram(struct mtd_info *mtd, int area,
 		return -1;
 	}
 
-	omap_set_dma_transfer_params(c->dma_channel, OMAP_DMA_DATA_TYPE_S16,
-				     count / 2, 1, 0, 0, 0);
-	omap_set_dma_src_params(c->dma_channel, 0, OMAP_DMA_AMODE_POST_INC,
-				dma_src, 0, 0);
-	omap_set_dma_dest_params(c->dma_channel, 0, OMAP_DMA_AMODE_POST_INC,
-				 dma_dst, 0, 0);
-
-	reinit_completion(&c->dma_done);
-	omap_start_dma(c->dma_channel);
-	wait_for_completion(&c->dma_done);
-
+	ret = omap2_onenand_dma_transfer(c, dma_src, dma_dst, count);
 	dma_unmap_single(&c->pdev->dev, dma_src, count, DMA_TO_DEVICE);
 
-	return 0;
+	if (ret)
+		dev_err(&c->pdev->dev, "timeout waiting for DMA\n");
+
+	return ret;
 }
 
 #else
-- 
2.11.0

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

* [PATCH v4 09/16] mtd: onenand: omap2: Unify OMAP2 and OMAP3 DMA implementation
  2017-11-11 21:12 ` Ladislav Michl
@ 2017-11-11 21:22   ` Ladislav Michl
  -1 siblings, 0 replies; 114+ messages in thread
From: Ladislav Michl @ 2017-11-11 21:22 UTC (permalink / raw)
  To: linux-mtd, linux-omap
  Cc: Tony Lindgren, Peter Ujfalusi, Kyungmin Park, Boris Brezillon,
	Roger Quadros

Since the very first commit (36cd4fb5d277: "[MTD] [OneNAND] Add OMAP2 / OMAP3
OneNAND driver") DMA is disabled for OMAP2. Later fixes thus went only into
OMAP3 specific DMA functions which turned out not to be so OMAP3 specific,
so merge those two implementations.

Signed-off-by: Ladislav Michl <ladis@linux-mips.org>
---
 Changes:
 -v3: new patch
 -v4: rebase on top of Peter's patch

 drivers/mtd/onenand/omap2.c | 129 ++------------------------------------------
 1 file changed, 4 insertions(+), 125 deletions(-)

diff --git a/drivers/mtd/onenand/omap2.c b/drivers/mtd/onenand/omap2.c
index d22163271dc9..36314124488d 100644
--- a/drivers/mtd/onenand/omap2.c
+++ b/drivers/mtd/onenand/omap2.c
@@ -315,9 +315,7 @@ static inline int omap2_onenand_dma_transfer(struct omap2_onenand *c,
 	return 0;
 }
 
-#if defined(CONFIG_ARCH_OMAP3) || defined(MULTI_OMAP2)
-
-static int omap3_onenand_read_bufferram(struct mtd_info *mtd, int area,
+static int omap2_onenand_read_bufferram(struct mtd_info *mtd, int area,
 					unsigned char *buffer, int offset,
 					size_t count)
 {
@@ -379,7 +377,7 @@ static int omap3_onenand_read_bufferram(struct mtd_info *mtd, int area,
 	return 0;
 }
 
-static int omap3_onenand_write_bufferram(struct mtd_info *mtd, int area,
+static int omap2_onenand_write_bufferram(struct mtd_info *mtd, int area,
 					 const unsigned char *buffer,
 					 int offset, size_t count)
 {
@@ -434,120 +432,6 @@ static int omap3_onenand_write_bufferram(struct mtd_info *mtd, int area,
 	return 0;
 }
 
-#else
-
-static int omap3_onenand_read_bufferram(struct mtd_info *mtd, int area,
-					unsigned char *buffer, int offset,
-					size_t count)
-{
-	return -ENOSYS;
-}
-
-static int omap3_onenand_write_bufferram(struct mtd_info *mtd, int area,
-					 const unsigned char *buffer,
-					 int offset, size_t count)
-{
-	return -ENOSYS;
-}
-
-#endif
-
-#if defined(CONFIG_ARCH_OMAP2) || defined(MULTI_OMAP2)
-
-static int omap2_onenand_read_bufferram(struct mtd_info *mtd, int area,
-					unsigned char *buffer, int offset,
-					size_t count)
-{
-	struct omap2_onenand *c = container_of(mtd, struct omap2_onenand, mtd);
-	struct onenand_chip *this = mtd->priv;
-	dma_addr_t dma_src, dma_dst;
-	int bram_offset, ret;
-
-	bram_offset = omap2_onenand_bufferram_offset(mtd, area) + area + offset;
-	/* DMA is not used.  Revisit PM requirements before enabling it. */
-	if (1 || (c->dma_channel < 0) ||
-	    ((void *) buffer >= (void *) high_memory) || (bram_offset & 3) ||
-	    (((unsigned int) buffer) & 3) || (count < 1024) || (count & 3)) {
-		memcpy(buffer, (__force void *)(this->base + bram_offset),
-		       count);
-		return 0;
-	}
-
-	dma_src = c->phys_base + bram_offset;
-	dma_dst = dma_map_single(&c->pdev->dev, buffer, count,
-				 DMA_FROM_DEVICE);
-	if (dma_mapping_error(&c->pdev->dev, dma_dst)) {
-		dev_err(&c->pdev->dev,
-			"Couldn't DMA map a %d byte buffer\n",
-			count);
-		return -1;
-	}
-
-	ret = omap2_onenand_dma_transfer(c, dma_src, dma_dst, count);
-	dma_unmap_single(&c->pdev->dev, dma_dst, count, DMA_FROM_DEVICE);
-
-	if (ret)
-		dev_err(&c->pdev->dev, "timeout waiting for DMA\n");
-
-	return ret;
-}
-
-static int omap2_onenand_write_bufferram(struct mtd_info *mtd, int area,
-					 const unsigned char *buffer,
-					 int offset, size_t count)
-{
-	struct omap2_onenand *c = container_of(mtd, struct omap2_onenand, mtd);
-	struct onenand_chip *this = mtd->priv;
-	dma_addr_t dma_src, dma_dst;
-	int bram_offset, ret;
-
-	bram_offset = omap2_onenand_bufferram_offset(mtd, area) + area + offset;
-	/* DMA is not used.  Revisit PM requirements before enabling it. */
-	if (1 || (c->dma_channel < 0) ||
-	    ((void *) buffer >= (void *) high_memory) || (bram_offset & 3) ||
-	    (((unsigned int) buffer) & 3) || (count < 1024) || (count & 3)) {
-		memcpy((__force void *)(this->base + bram_offset), buffer,
-		       count);
-		return 0;
-	}
-
-	dma_src = dma_map_single(&c->pdev->dev, (void *) buffer, count,
-				 DMA_TO_DEVICE);
-	dma_dst = c->phys_base + bram_offset;
-	if (dma_mapping_error(&c->pdev->dev, dma_src)) {
-		dev_err(&c->pdev->dev,
-			"Couldn't DMA map a %d byte buffer\n",
-			count);
-		return -1;
-	}
-
-	ret = omap2_onenand_dma_transfer(c, dma_src, dma_dst, count);
-	dma_unmap_single(&c->pdev->dev, dma_src, count, DMA_TO_DEVICE);
-
-	if (ret)
-		dev_err(&c->pdev->dev, "timeout waiting for DMA\n");
-
-	return ret;
-}
-
-#else
-
-static int omap2_onenand_read_bufferram(struct mtd_info *mtd, int area,
-					unsigned char *buffer, int offset,
-					size_t count)
-{
-	return -ENOSYS;
-}
-
-static int omap2_onenand_write_bufferram(struct mtd_info *mtd, int area,
-					 const unsigned char *buffer,
-					 int offset, size_t count)
-{
-	return -ENOSYS;
-}
-
-#endif
-
 static struct platform_driver omap2_onenand_driver;
 
 static void omap2_onenand_shutdown(struct platform_device *pdev)
@@ -671,13 +555,8 @@ static int omap2_onenand_probe(struct platform_device *pdev)
 	this = &c->onenand;
 	if (c->dma_channel >= 0) {
 		this->wait = omap2_onenand_wait;
-		if (c->flags & ONENAND_IN_OMAP34XX) {
-			this->read_bufferram = omap3_onenand_read_bufferram;
-			this->write_bufferram = omap3_onenand_write_bufferram;
-		} else {
-			this->read_bufferram = omap2_onenand_read_bufferram;
-			this->write_bufferram = omap2_onenand_write_bufferram;
-		}
+		this->read_bufferram = omap2_onenand_read_bufferram;
+		this->write_bufferram = omap2_onenand_write_bufferram;
 	}
 
 	if ((r = onenand_scan(&c->mtd, 1)) < 0)
-- 
2.11.0


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

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

* [PATCH v4 09/16] mtd: onenand: omap2: Unify OMAP2 and OMAP3 DMA implementation
@ 2017-11-11 21:22   ` Ladislav Michl
  0 siblings, 0 replies; 114+ messages in thread
From: Ladislav Michl @ 2017-11-11 21:22 UTC (permalink / raw)
  To: linux-mtd, linux-omap
  Cc: Roger Quadros, Tony Lindgren, Peter Ujfalusi, Boris Brezillon,
	Kyungmin Park

Since the very first commit (36cd4fb5d277: "[MTD] [OneNAND] Add OMAP2 / OMAP3
OneNAND driver") DMA is disabled for OMAP2. Later fixes thus went only into
OMAP3 specific DMA functions which turned out not to be so OMAP3 specific,
so merge those two implementations.

Signed-off-by: Ladislav Michl <ladis@linux-mips.org>
---
 Changes:
 -v3: new patch
 -v4: rebase on top of Peter's patch

 drivers/mtd/onenand/omap2.c | 129 ++------------------------------------------
 1 file changed, 4 insertions(+), 125 deletions(-)

diff --git a/drivers/mtd/onenand/omap2.c b/drivers/mtd/onenand/omap2.c
index d22163271dc9..36314124488d 100644
--- a/drivers/mtd/onenand/omap2.c
+++ b/drivers/mtd/onenand/omap2.c
@@ -315,9 +315,7 @@ static inline int omap2_onenand_dma_transfer(struct omap2_onenand *c,
 	return 0;
 }
 
-#if defined(CONFIG_ARCH_OMAP3) || defined(MULTI_OMAP2)
-
-static int omap3_onenand_read_bufferram(struct mtd_info *mtd, int area,
+static int omap2_onenand_read_bufferram(struct mtd_info *mtd, int area,
 					unsigned char *buffer, int offset,
 					size_t count)
 {
@@ -379,7 +377,7 @@ static int omap3_onenand_read_bufferram(struct mtd_info *mtd, int area,
 	return 0;
 }
 
-static int omap3_onenand_write_bufferram(struct mtd_info *mtd, int area,
+static int omap2_onenand_write_bufferram(struct mtd_info *mtd, int area,
 					 const unsigned char *buffer,
 					 int offset, size_t count)
 {
@@ -434,120 +432,6 @@ static int omap3_onenand_write_bufferram(struct mtd_info *mtd, int area,
 	return 0;
 }
 
-#else
-
-static int omap3_onenand_read_bufferram(struct mtd_info *mtd, int area,
-					unsigned char *buffer, int offset,
-					size_t count)
-{
-	return -ENOSYS;
-}
-
-static int omap3_onenand_write_bufferram(struct mtd_info *mtd, int area,
-					 const unsigned char *buffer,
-					 int offset, size_t count)
-{
-	return -ENOSYS;
-}
-
-#endif
-
-#if defined(CONFIG_ARCH_OMAP2) || defined(MULTI_OMAP2)
-
-static int omap2_onenand_read_bufferram(struct mtd_info *mtd, int area,
-					unsigned char *buffer, int offset,
-					size_t count)
-{
-	struct omap2_onenand *c = container_of(mtd, struct omap2_onenand, mtd);
-	struct onenand_chip *this = mtd->priv;
-	dma_addr_t dma_src, dma_dst;
-	int bram_offset, ret;
-
-	bram_offset = omap2_onenand_bufferram_offset(mtd, area) + area + offset;
-	/* DMA is not used.  Revisit PM requirements before enabling it. */
-	if (1 || (c->dma_channel < 0) ||
-	    ((void *) buffer >= (void *) high_memory) || (bram_offset & 3) ||
-	    (((unsigned int) buffer) & 3) || (count < 1024) || (count & 3)) {
-		memcpy(buffer, (__force void *)(this->base + bram_offset),
-		       count);
-		return 0;
-	}
-
-	dma_src = c->phys_base + bram_offset;
-	dma_dst = dma_map_single(&c->pdev->dev, buffer, count,
-				 DMA_FROM_DEVICE);
-	if (dma_mapping_error(&c->pdev->dev, dma_dst)) {
-		dev_err(&c->pdev->dev,
-			"Couldn't DMA map a %d byte buffer\n",
-			count);
-		return -1;
-	}
-
-	ret = omap2_onenand_dma_transfer(c, dma_src, dma_dst, count);
-	dma_unmap_single(&c->pdev->dev, dma_dst, count, DMA_FROM_DEVICE);
-
-	if (ret)
-		dev_err(&c->pdev->dev, "timeout waiting for DMA\n");
-
-	return ret;
-}
-
-static int omap2_onenand_write_bufferram(struct mtd_info *mtd, int area,
-					 const unsigned char *buffer,
-					 int offset, size_t count)
-{
-	struct omap2_onenand *c = container_of(mtd, struct omap2_onenand, mtd);
-	struct onenand_chip *this = mtd->priv;
-	dma_addr_t dma_src, dma_dst;
-	int bram_offset, ret;
-
-	bram_offset = omap2_onenand_bufferram_offset(mtd, area) + area + offset;
-	/* DMA is not used.  Revisit PM requirements before enabling it. */
-	if (1 || (c->dma_channel < 0) ||
-	    ((void *) buffer >= (void *) high_memory) || (bram_offset & 3) ||
-	    (((unsigned int) buffer) & 3) || (count < 1024) || (count & 3)) {
-		memcpy((__force void *)(this->base + bram_offset), buffer,
-		       count);
-		return 0;
-	}
-
-	dma_src = dma_map_single(&c->pdev->dev, (void *) buffer, count,
-				 DMA_TO_DEVICE);
-	dma_dst = c->phys_base + bram_offset;
-	if (dma_mapping_error(&c->pdev->dev, dma_src)) {
-		dev_err(&c->pdev->dev,
-			"Couldn't DMA map a %d byte buffer\n",
-			count);
-		return -1;
-	}
-
-	ret = omap2_onenand_dma_transfer(c, dma_src, dma_dst, count);
-	dma_unmap_single(&c->pdev->dev, dma_src, count, DMA_TO_DEVICE);
-
-	if (ret)
-		dev_err(&c->pdev->dev, "timeout waiting for DMA\n");
-
-	return ret;
-}
-
-#else
-
-static int omap2_onenand_read_bufferram(struct mtd_info *mtd, int area,
-					unsigned char *buffer, int offset,
-					size_t count)
-{
-	return -ENOSYS;
-}
-
-static int omap2_onenand_write_bufferram(struct mtd_info *mtd, int area,
-					 const unsigned char *buffer,
-					 int offset, size_t count)
-{
-	return -ENOSYS;
-}
-
-#endif
-
 static struct platform_driver omap2_onenand_driver;
 
 static void omap2_onenand_shutdown(struct platform_device *pdev)
@@ -671,13 +555,8 @@ static int omap2_onenand_probe(struct platform_device *pdev)
 	this = &c->onenand;
 	if (c->dma_channel >= 0) {
 		this->wait = omap2_onenand_wait;
-		if (c->flags & ONENAND_IN_OMAP34XX) {
-			this->read_bufferram = omap3_onenand_read_bufferram;
-			this->write_bufferram = omap3_onenand_write_bufferram;
-		} else {
-			this->read_bufferram = omap2_onenand_read_bufferram;
-			this->write_bufferram = omap2_onenand_write_bufferram;
-		}
+		this->read_bufferram = omap2_onenand_read_bufferram;
+		this->write_bufferram = omap2_onenand_write_bufferram;
 	}
 
 	if ((r = onenand_scan(&c->mtd, 1)) < 0)
-- 
2.11.0

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

* [PATCH v4 10/16] mtd: onenand: omap2: Convert to use dmaengine for memcpy
  2017-11-11 21:12 ` Ladislav Michl
@ 2017-11-11 21:23   ` Ladislav Michl
  -1 siblings, 0 replies; 114+ messages in thread
From: Ladislav Michl @ 2017-11-11 21:23 UTC (permalink / raw)
  To: linux-mtd, linux-omap
  Cc: Tony Lindgren, Peter Ujfalusi, Kyungmin Park, Boris Brezillon,
	Roger Quadros

From: Peter Ujfalusi <peter.ujfalusi@ti.com>

Do not use the legacy and deprecated omap-dma interface for setting up the
memcpy.

Signed-off-by: Peter Ujfalusi <peter.ujfalusi@ti.com>
Signed-off-by: Ladislav Michl <ladis@linux-mips.org>
---
 Changes:
 -v4: new patch

 drivers/mtd/onenand/omap2.c | 80 +++++++++++++++++++++------------------------
 1 file changed, 38 insertions(+), 42 deletions(-)

diff --git a/drivers/mtd/onenand/omap2.c b/drivers/mtd/onenand/omap2.c
index 36314124488d..c9ff67100ef4 100644
--- a/drivers/mtd/onenand/omap2.c
+++ b/drivers/mtd/onenand/omap2.c
@@ -32,6 +32,7 @@
 #include <linux/interrupt.h>
 #include <linux/delay.h>
 #include <linux/dma-mapping.h>
+#include <linux/dmaengine.h>
 #include <linux/io.h>
 #include <linux/slab.h>
 #include <linux/gpio.h>
@@ -39,8 +40,6 @@
 #include <asm/mach/flash.h>
 #include <linux/platform_data/mtd-onenand-omap2.h>
 
-#include <linux/omap-dma.h>
-
 #define DRIVER_NAME "omap2-onenand"
 
 #define ONENAND_BUFRAM_SIZE	(1024 * 5)
@@ -55,17 +54,15 @@ struct omap2_onenand {
 	struct onenand_chip onenand;
 	struct completion irq_done;
 	struct completion dma_done;
-	int dma_channel;
+	struct dma_chan *dma_chan;
 	int freq;
 	int (*setup)(void __iomem *base, int *freq_ptr);
 	u8 flags;
 };
 
-static void omap2_onenand_dma_cb(int lch, u16 ch_status, void *data)
+static void omap2_onenand_dma_complete_func(void *completion)
 {
-	struct omap2_onenand *c = data;
-
-	complete(&c->dma_done);
+	complete(completion);
 }
 
 static irqreturn_t omap2_onenand_interrupt(int irq, void *dev_id)
@@ -292,23 +289,31 @@ static inline int omap2_onenand_dma_transfer(struct omap2_onenand *c,
 					     dma_addr_t src, dma_addr_t dst,
 					     size_t count)
 {
-	int data_type = __ffs((src | dst | count));
+	struct dma_async_tx_descriptor *tx;
+	dma_cookie_t cookie;
 
-	if (data_type > OMAP_DMA_DATA_TYPE_S32)
-		data_type = OMAP_DMA_DATA_TYPE_S32;
-
-	omap_set_dma_transfer_params(c->dma_channel, data_type,
-				     count / BIT(data_type), 1, 0, 0, 0);
-	omap_set_dma_src_params(c->dma_channel, 0, OMAP_DMA_AMODE_POST_INC,
-				src, 0, 0);
-	omap_set_dma_dest_params(c->dma_channel, 0, OMAP_DMA_AMODE_POST_INC,
-				 dst, 0, 0);
+	tx = dmaengine_prep_dma_memcpy(c->dma_chan, dst, src, count, 0);
+	if (!tx) {
+		dev_err(&c->pdev->dev, "Failed to prepare DMA memcpy\n");
+		return -EIO;
+	}
 
 	reinit_completion(&c->dma_done);
-	omap_start_dma(c->dma_channel);
+
+	tx->callback = omap2_onenand_dma_complete_func;
+	tx->callback_param = &c->dma_done;
+
+	cookie = tx->tx_submit(tx);
+	if (dma_submit_error(cookie)) {
+		dev_err(&c->pdev->dev, "Failed to do DMA tx_submit\n");
+		return -EIO;
+	}
+
+	dma_async_issue_pending(c->dma_chan);
+
 	if (!wait_for_completion_io_timeout(&c->dma_done,
 					    msecs_to_jiffies(20))) {
-		omap_stop_dma(c->dma_channel);
+		dmaengine_terminate_sync(c->dma_chan);
 		return -ETIMEDOUT;
 	}
 
@@ -468,8 +473,7 @@ static int omap2_onenand_probe(struct platform_device *pdev)
 	c->flags = pdata->flags;
 	c->gpmc_cs = pdata->cs;
 	c->gpio_irq = pdata->gpio_irq;
-	c->dma_channel = pdata->dma_channel;
-	if (c->dma_channel < 0) {
+	if (pdata->dma_channel < 0) {
 		/* if -1, don't use DMA */
 		c->gpio_irq = 0;
 	}
@@ -521,25 +525,17 @@ static int omap2_onenand_probe(struct platform_device *pdev)
 		goto err_release_gpio;
 	}
 
-	if (c->dma_channel >= 0) {
-		r = omap_request_dma(0, pdev->dev.driver->name,
-				     omap2_onenand_dma_cb, (void *) c,
-				     &c->dma_channel);
-		if (r == 0) {
-			omap_set_dma_write_mode(c->dma_channel,
-						OMAP_DMA_WRITE_NON_POSTED);
-			omap_set_dma_src_data_pack(c->dma_channel, 1);
-			omap_set_dma_src_burst_mode(c->dma_channel,
-						    OMAP_DMA_DATA_BURST_8);
-			omap_set_dma_dest_data_pack(c->dma_channel, 1);
-			omap_set_dma_dest_burst_mode(c->dma_channel,
-						     OMAP_DMA_DATA_BURST_8);
-		} else {
+	if (pdata->dma_channel >= 0) {
+		dma_cap_mask_t mask;
+
+		dma_cap_zero(mask);
+		dma_cap_set(DMA_MEMCPY, mask);
+
+		c->dma_chan = dma_request_channel(mask, NULL, NULL);
+		if (!c->dma_chan)
 			dev_info(&pdev->dev,
 				 "failed to allocate DMA for OneNAND, "
 				 "using PIO instead\n");
-			c->dma_channel = -1;
-		}
 	}
 
 	dev_info(&pdev->dev, "initializing on CS%d, phys base 0x%08lx, virtual "
@@ -553,7 +549,7 @@ static int omap2_onenand_probe(struct platform_device *pdev)
 	mtd_set_of_node(&c->mtd, pdata->of_node);
 
 	this = &c->onenand;
-	if (c->dma_channel >= 0) {
+	if (c->dma_chan) {
 		this->wait = omap2_onenand_wait;
 		this->read_bufferram = omap2_onenand_read_bufferram;
 		this->write_bufferram = omap2_onenand_write_bufferram;
@@ -573,8 +569,8 @@ static int omap2_onenand_probe(struct platform_device *pdev)
 err_release_onenand:
 	onenand_release(&c->mtd);
 err_release_dma:
-	if (c->dma_channel != -1)
-		omap_free_dma(c->dma_channel);
+	if (c->dma_chan)
+		dma_release_channel(c->dma_chan);
 	if (c->gpio_irq)
 		free_irq(gpio_to_irq(c->gpio_irq), c);
 err_release_gpio:
@@ -595,8 +591,8 @@ static int omap2_onenand_remove(struct platform_device *pdev)
 	struct omap2_onenand *c = dev_get_drvdata(&pdev->dev);
 
 	onenand_release(&c->mtd);
-	if (c->dma_channel != -1)
-		omap_free_dma(c->dma_channel);
+	if (c->dma_chan)
+		dma_release_channel(c->dma_chan);
 	omap2_onenand_shutdown(pdev);
 	if (c->gpio_irq) {
 		free_irq(gpio_to_irq(c->gpio_irq), c);
-- 
2.11.0


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

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

* [PATCH v4 10/16] mtd: onenand: omap2: Convert to use dmaengine for memcpy
@ 2017-11-11 21:23   ` Ladislav Michl
  0 siblings, 0 replies; 114+ messages in thread
From: Ladislav Michl @ 2017-11-11 21:23 UTC (permalink / raw)
  To: linux-mtd, linux-omap
  Cc: Roger Quadros, Tony Lindgren, Peter Ujfalusi, Boris Brezillon,
	Kyungmin Park

From: Peter Ujfalusi <peter.ujfalusi@ti.com>

Do not use the legacy and deprecated omap-dma interface for setting up the
memcpy.

Signed-off-by: Peter Ujfalusi <peter.ujfalusi@ti.com>
Signed-off-by: Ladislav Michl <ladis@linux-mips.org>
---
 Changes:
 -v4: new patch

 drivers/mtd/onenand/omap2.c | 80 +++++++++++++++++++++------------------------
 1 file changed, 38 insertions(+), 42 deletions(-)

diff --git a/drivers/mtd/onenand/omap2.c b/drivers/mtd/onenand/omap2.c
index 36314124488d..c9ff67100ef4 100644
--- a/drivers/mtd/onenand/omap2.c
+++ b/drivers/mtd/onenand/omap2.c
@@ -32,6 +32,7 @@
 #include <linux/interrupt.h>
 #include <linux/delay.h>
 #include <linux/dma-mapping.h>
+#include <linux/dmaengine.h>
 #include <linux/io.h>
 #include <linux/slab.h>
 #include <linux/gpio.h>
@@ -39,8 +40,6 @@
 #include <asm/mach/flash.h>
 #include <linux/platform_data/mtd-onenand-omap2.h>
 
-#include <linux/omap-dma.h>
-
 #define DRIVER_NAME "omap2-onenand"
 
 #define ONENAND_BUFRAM_SIZE	(1024 * 5)
@@ -55,17 +54,15 @@ struct omap2_onenand {
 	struct onenand_chip onenand;
 	struct completion irq_done;
 	struct completion dma_done;
-	int dma_channel;
+	struct dma_chan *dma_chan;
 	int freq;
 	int (*setup)(void __iomem *base, int *freq_ptr);
 	u8 flags;
 };
 
-static void omap2_onenand_dma_cb(int lch, u16 ch_status, void *data)
+static void omap2_onenand_dma_complete_func(void *completion)
 {
-	struct omap2_onenand *c = data;
-
-	complete(&c->dma_done);
+	complete(completion);
 }
 
 static irqreturn_t omap2_onenand_interrupt(int irq, void *dev_id)
@@ -292,23 +289,31 @@ static inline int omap2_onenand_dma_transfer(struct omap2_onenand *c,
 					     dma_addr_t src, dma_addr_t dst,
 					     size_t count)
 {
-	int data_type = __ffs((src | dst | count));
+	struct dma_async_tx_descriptor *tx;
+	dma_cookie_t cookie;
 
-	if (data_type > OMAP_DMA_DATA_TYPE_S32)
-		data_type = OMAP_DMA_DATA_TYPE_S32;
-
-	omap_set_dma_transfer_params(c->dma_channel, data_type,
-				     count / BIT(data_type), 1, 0, 0, 0);
-	omap_set_dma_src_params(c->dma_channel, 0, OMAP_DMA_AMODE_POST_INC,
-				src, 0, 0);
-	omap_set_dma_dest_params(c->dma_channel, 0, OMAP_DMA_AMODE_POST_INC,
-				 dst, 0, 0);
+	tx = dmaengine_prep_dma_memcpy(c->dma_chan, dst, src, count, 0);
+	if (!tx) {
+		dev_err(&c->pdev->dev, "Failed to prepare DMA memcpy\n");
+		return -EIO;
+	}
 
 	reinit_completion(&c->dma_done);
-	omap_start_dma(c->dma_channel);
+
+	tx->callback = omap2_onenand_dma_complete_func;
+	tx->callback_param = &c->dma_done;
+
+	cookie = tx->tx_submit(tx);
+	if (dma_submit_error(cookie)) {
+		dev_err(&c->pdev->dev, "Failed to do DMA tx_submit\n");
+		return -EIO;
+	}
+
+	dma_async_issue_pending(c->dma_chan);
+
 	if (!wait_for_completion_io_timeout(&c->dma_done,
 					    msecs_to_jiffies(20))) {
-		omap_stop_dma(c->dma_channel);
+		dmaengine_terminate_sync(c->dma_chan);
 		return -ETIMEDOUT;
 	}
 
@@ -468,8 +473,7 @@ static int omap2_onenand_probe(struct platform_device *pdev)
 	c->flags = pdata->flags;
 	c->gpmc_cs = pdata->cs;
 	c->gpio_irq = pdata->gpio_irq;
-	c->dma_channel = pdata->dma_channel;
-	if (c->dma_channel < 0) {
+	if (pdata->dma_channel < 0) {
 		/* if -1, don't use DMA */
 		c->gpio_irq = 0;
 	}
@@ -521,25 +525,17 @@ static int omap2_onenand_probe(struct platform_device *pdev)
 		goto err_release_gpio;
 	}
 
-	if (c->dma_channel >= 0) {
-		r = omap_request_dma(0, pdev->dev.driver->name,
-				     omap2_onenand_dma_cb, (void *) c,
-				     &c->dma_channel);
-		if (r == 0) {
-			omap_set_dma_write_mode(c->dma_channel,
-						OMAP_DMA_WRITE_NON_POSTED);
-			omap_set_dma_src_data_pack(c->dma_channel, 1);
-			omap_set_dma_src_burst_mode(c->dma_channel,
-						    OMAP_DMA_DATA_BURST_8);
-			omap_set_dma_dest_data_pack(c->dma_channel, 1);
-			omap_set_dma_dest_burst_mode(c->dma_channel,
-						     OMAP_DMA_DATA_BURST_8);
-		} else {
+	if (pdata->dma_channel >= 0) {
+		dma_cap_mask_t mask;
+
+		dma_cap_zero(mask);
+		dma_cap_set(DMA_MEMCPY, mask);
+
+		c->dma_chan = dma_request_channel(mask, NULL, NULL);
+		if (!c->dma_chan)
 			dev_info(&pdev->dev,
 				 "failed to allocate DMA for OneNAND, "
 				 "using PIO instead\n");
-			c->dma_channel = -1;
-		}
 	}
 
 	dev_info(&pdev->dev, "initializing on CS%d, phys base 0x%08lx, virtual "
@@ -553,7 +549,7 @@ static int omap2_onenand_probe(struct platform_device *pdev)
 	mtd_set_of_node(&c->mtd, pdata->of_node);
 
 	this = &c->onenand;
-	if (c->dma_channel >= 0) {
+	if (c->dma_chan) {
 		this->wait = omap2_onenand_wait;
 		this->read_bufferram = omap2_onenand_read_bufferram;
 		this->write_bufferram = omap2_onenand_write_bufferram;
@@ -573,8 +569,8 @@ static int omap2_onenand_probe(struct platform_device *pdev)
 err_release_onenand:
 	onenand_release(&c->mtd);
 err_release_dma:
-	if (c->dma_channel != -1)
-		omap_free_dma(c->dma_channel);
+	if (c->dma_chan)
+		dma_release_channel(c->dma_chan);
 	if (c->gpio_irq)
 		free_irq(gpio_to_irq(c->gpio_irq), c);
 err_release_gpio:
@@ -595,8 +591,8 @@ static int omap2_onenand_remove(struct platform_device *pdev)
 	struct omap2_onenand *c = dev_get_drvdata(&pdev->dev);
 
 	onenand_release(&c->mtd);
-	if (c->dma_channel != -1)
-		omap_free_dma(c->dma_channel);
+	if (c->dma_chan)
+		dma_release_channel(c->dma_chan);
 	omap2_onenand_shutdown(pdev);
 	if (c->gpio_irq) {
 		free_irq(gpio_to_irq(c->gpio_irq), c);
-- 
2.11.0

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

* [PATCH v4 11/16] mtd: onenand: omap2: Do not make delay for GPIO OMAP3 specific
  2017-11-11 21:12 ` Ladislav Michl
@ 2017-11-11 21:24   ` Ladislav Michl
  -1 siblings, 0 replies; 114+ messages in thread
From: Ladislav Michl @ 2017-11-11 21:24 UTC (permalink / raw)
  To: linux-mtd, linux-omap
  Cc: Tony Lindgren, Peter Ujfalusi, Kyungmin Park, Boris Brezillon,
	Roger Quadros

Second commit in driver history (782b7a367d81: "[MTD] [OneNAND] OMAP3:
add delay for GPIO") added quirk for waiting until GPIO line settle.
As DMA was disabled for OMAP2 boards, chances are this problem was
not OMAP3 specific and as it is just one register read, previous
test for SoC type is approximately as expensive as read itself.
Make delay unconditional, which allows removing SoC specific code
alltogether.

Signed-off-by: Ladislav Michl <ladis@linux-mips.org>
---
 Changes:
 -v3: new patch
 -v4: none

 drivers/mtd/onenand/omap2.c | 7 ++-----
 1 file changed, 2 insertions(+), 5 deletions(-)

diff --git a/drivers/mtd/onenand/omap2.c b/drivers/mtd/onenand/omap2.c
index c9ff67100ef4..e4857a41760d 100644
--- a/drivers/mtd/onenand/omap2.c
+++ b/drivers/mtd/onenand/omap2.c
@@ -57,7 +57,6 @@ struct omap2_onenand {
 	struct dma_chan *dma_chan;
 	int freq;
 	int (*setup)(void __iomem *base, int *freq_ptr);
-	u8 flags;
 };
 
 static void omap2_onenand_dma_complete_func(void *completion)
@@ -148,9 +147,8 @@ static int omap2_onenand_wait(struct mtd_info *mtd, int state)
 		if (!(syscfg & ONENAND_SYS_CFG1_IOBE)) {
 			syscfg |= ONENAND_SYS_CFG1_IOBE;
 			write_reg(c, syscfg, ONENAND_REG_SYS_CFG1);
-			if (c->flags & ONENAND_IN_OMAP34XX)
-				/* Add a delay to let GPIO settle */
-				syscfg = read_reg(c, ONENAND_REG_SYS_CFG1);
+			/* Add a delay to let GPIO settle */
+			syscfg = read_reg(c, ONENAND_REG_SYS_CFG1);
 		}
 
 		reinit_completion(&c->irq_done);
@@ -470,7 +468,6 @@ static int omap2_onenand_probe(struct platform_device *pdev)
 
 	init_completion(&c->irq_done);
 	init_completion(&c->dma_done);
-	c->flags = pdata->flags;
 	c->gpmc_cs = pdata->cs;
 	c->gpio_irq = pdata->gpio_irq;
 	if (pdata->dma_channel < 0) {
-- 
2.11.0


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

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

* [PATCH v4 11/16] mtd: onenand: omap2: Do not make delay for GPIO OMAP3 specific
@ 2017-11-11 21:24   ` Ladislav Michl
  0 siblings, 0 replies; 114+ messages in thread
From: Ladislav Michl @ 2017-11-11 21:24 UTC (permalink / raw)
  To: linux-mtd, linux-omap
  Cc: Roger Quadros, Tony Lindgren, Peter Ujfalusi, Boris Brezillon,
	Kyungmin Park

Second commit in driver history (782b7a367d81: "[MTD] [OneNAND] OMAP3:
add delay for GPIO") added quirk for waiting until GPIO line settle.
As DMA was disabled for OMAP2 boards, chances are this problem was
not OMAP3 specific and as it is just one register read, previous
test for SoC type is approximately as expensive as read itself.
Make delay unconditional, which allows removing SoC specific code
alltogether.

Signed-off-by: Ladislav Michl <ladis@linux-mips.org>
---
 Changes:
 -v3: new patch
 -v4: none

 drivers/mtd/onenand/omap2.c | 7 ++-----
 1 file changed, 2 insertions(+), 5 deletions(-)

diff --git a/drivers/mtd/onenand/omap2.c b/drivers/mtd/onenand/omap2.c
index c9ff67100ef4..e4857a41760d 100644
--- a/drivers/mtd/onenand/omap2.c
+++ b/drivers/mtd/onenand/omap2.c
@@ -57,7 +57,6 @@ struct omap2_onenand {
 	struct dma_chan *dma_chan;
 	int freq;
 	int (*setup)(void __iomem *base, int *freq_ptr);
-	u8 flags;
 };
 
 static void omap2_onenand_dma_complete_func(void *completion)
@@ -148,9 +147,8 @@ static int omap2_onenand_wait(struct mtd_info *mtd, int state)
 		if (!(syscfg & ONENAND_SYS_CFG1_IOBE)) {
 			syscfg |= ONENAND_SYS_CFG1_IOBE;
 			write_reg(c, syscfg, ONENAND_REG_SYS_CFG1);
-			if (c->flags & ONENAND_IN_OMAP34XX)
-				/* Add a delay to let GPIO settle */
-				syscfg = read_reg(c, ONENAND_REG_SYS_CFG1);
+			/* Add a delay to let GPIO settle */
+			syscfg = read_reg(c, ONENAND_REG_SYS_CFG1);
 		}
 
 		reinit_completion(&c->irq_done);
@@ -470,7 +468,6 @@ static int omap2_onenand_probe(struct platform_device *pdev)
 
 	init_completion(&c->irq_done);
 	init_completion(&c->dma_done);
-	c->flags = pdata->flags;
 	c->gpmc_cs = pdata->cs;
 	c->gpio_irq = pdata->gpio_irq;
 	if (pdata->dma_channel < 0) {
-- 
2.11.0

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

* [PATCH v4 12/16] mtd: onenand: omap2: Enable DMA by default
  2017-11-11 21:12 ` Ladislav Michl
@ 2017-11-11 21:24   ` Ladislav Michl
  -1 siblings, 0 replies; 114+ messages in thread
From: Ladislav Michl @ 2017-11-11 21:24 UTC (permalink / raw)
  To: linux-mtd, linux-omap
  Cc: Tony Lindgren, Peter Ujfalusi, Kyungmin Park, Boris Brezillon,
	Roger Quadros

DMA and R/B pin are independent on each other. Use DMA by default.

Signed-off-by: Ladislav Michl <ladis@linux-mips.org>
---
 Changes:
 -v4: new patch

 drivers/mtd/onenand/omap2.c | 41 +++++++++++++++++------------------------
 1 file changed, 17 insertions(+), 24 deletions(-)

diff --git a/drivers/mtd/onenand/omap2.c b/drivers/mtd/onenand/omap2.c
index e4857a41760d..62e4ede918c4 100644
--- a/drivers/mtd/onenand/omap2.c
+++ b/drivers/mtd/onenand/omap2.c
@@ -152,17 +152,13 @@ static int omap2_onenand_wait(struct mtd_info *mtd, int state)
 		}
 
 		reinit_completion(&c->irq_done);
-		if (c->gpio_irq) {
-			result = gpio_get_value(c->gpio_irq);
-			if (result == -1) {
-				ctrl = read_reg(c, ONENAND_REG_CTRL_STATUS);
-				intr = read_reg(c, ONENAND_REG_INTERRUPT);
-				wait_err("gpio error", state, ctrl, intr);
-				return -EIO;
-			}
-		} else
-			result = 0;
-		if (result == 0) {
+		result = gpio_get_value(c->gpio_irq);
+		if (result < 0) {
+			ctrl = read_reg(c, ONENAND_REG_CTRL_STATUS);
+			intr = read_reg(c, ONENAND_REG_INTERRUPT);
+			wait_err("gpio error", state, ctrl, intr);
+			return -EIO;
+		} else if (result == 0) {
 			int retry_cnt = 0;
 retry:
 			if (!wait_for_completion_io_timeout(&c->irq_done,
@@ -513,13 +509,15 @@ static int omap2_onenand_probe(struct platform_device *pdev)
 			dev_err(&pdev->dev,  "Failed to request GPIO%d for "
 				"OneNAND\n", c->gpio_irq);
 			goto err_iounmap;
-	}
-	gpio_direction_input(c->gpio_irq);
+		}
+		gpio_direction_input(c->gpio_irq);
+
+		if ((r = request_irq(gpio_to_irq(c->gpio_irq),
+				     omap2_onenand_interrupt, IRQF_TRIGGER_RISING,
+				     pdev->dev.driver->name, c)) < 0)
+			goto err_release_gpio;
 
-	if ((r = request_irq(gpio_to_irq(c->gpio_irq),
-			     omap2_onenand_interrupt, IRQF_TRIGGER_RISING,
-			     pdev->dev.driver->name, c)) < 0)
-		goto err_release_gpio;
+		this->wait = omap2_onenand_wait;
 	}
 
 	if (pdata->dma_channel >= 0) {
@@ -529,15 +527,11 @@ static int omap2_onenand_probe(struct platform_device *pdev)
 		dma_cap_set(DMA_MEMCPY, mask);
 
 		c->dma_chan = dma_request_channel(mask, NULL, NULL);
-		if (!c->dma_chan)
-			dev_info(&pdev->dev,
-				 "failed to allocate DMA for OneNAND, "
-				 "using PIO instead\n");
 	}
 
 	dev_info(&pdev->dev, "initializing on CS%d, phys base 0x%08lx, virtual "
-		 "base %p, freq %d MHz\n", c->gpmc_cs, c->phys_base,
-		 c->onenand.base, c->freq);
+		 "base %p, freq %d MHz, %s mode\n", c->gpmc_cs, c->phys_base,
+		 c->onenand.base, c->freq, c->dma_chan ? "DMA" : "PIO");
 
 	c->pdev = pdev;
 	c->mtd.priv = &c->onenand;
@@ -547,7 +541,6 @@ static int omap2_onenand_probe(struct platform_device *pdev)
 
 	this = &c->onenand;
 	if (c->dma_chan) {
-		this->wait = omap2_onenand_wait;
 		this->read_bufferram = omap2_onenand_read_bufferram;
 		this->write_bufferram = omap2_onenand_write_bufferram;
 	}
-- 
2.11.0


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

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

* [PATCH v4 12/16] mtd: onenand: omap2: Enable DMA by default
@ 2017-11-11 21:24   ` Ladislav Michl
  0 siblings, 0 replies; 114+ messages in thread
From: Ladislav Michl @ 2017-11-11 21:24 UTC (permalink / raw)
  To: linux-mtd, linux-omap
  Cc: Roger Quadros, Tony Lindgren, Peter Ujfalusi, Boris Brezillon,
	Kyungmin Park

DMA and R/B pin are independent on each other. Use DMA by default.

Signed-off-by: Ladislav Michl <ladis@linux-mips.org>
---
 Changes:
 -v4: new patch

 drivers/mtd/onenand/omap2.c | 41 +++++++++++++++++------------------------
 1 file changed, 17 insertions(+), 24 deletions(-)

diff --git a/drivers/mtd/onenand/omap2.c b/drivers/mtd/onenand/omap2.c
index e4857a41760d..62e4ede918c4 100644
--- a/drivers/mtd/onenand/omap2.c
+++ b/drivers/mtd/onenand/omap2.c
@@ -152,17 +152,13 @@ static int omap2_onenand_wait(struct mtd_info *mtd, int state)
 		}
 
 		reinit_completion(&c->irq_done);
-		if (c->gpio_irq) {
-			result = gpio_get_value(c->gpio_irq);
-			if (result == -1) {
-				ctrl = read_reg(c, ONENAND_REG_CTRL_STATUS);
-				intr = read_reg(c, ONENAND_REG_INTERRUPT);
-				wait_err("gpio error", state, ctrl, intr);
-				return -EIO;
-			}
-		} else
-			result = 0;
-		if (result == 0) {
+		result = gpio_get_value(c->gpio_irq);
+		if (result < 0) {
+			ctrl = read_reg(c, ONENAND_REG_CTRL_STATUS);
+			intr = read_reg(c, ONENAND_REG_INTERRUPT);
+			wait_err("gpio error", state, ctrl, intr);
+			return -EIO;
+		} else if (result == 0) {
 			int retry_cnt = 0;
 retry:
 			if (!wait_for_completion_io_timeout(&c->irq_done,
@@ -513,13 +509,15 @@ static int omap2_onenand_probe(struct platform_device *pdev)
 			dev_err(&pdev->dev,  "Failed to request GPIO%d for "
 				"OneNAND\n", c->gpio_irq);
 			goto err_iounmap;
-	}
-	gpio_direction_input(c->gpio_irq);
+		}
+		gpio_direction_input(c->gpio_irq);
+
+		if ((r = request_irq(gpio_to_irq(c->gpio_irq),
+				     omap2_onenand_interrupt, IRQF_TRIGGER_RISING,
+				     pdev->dev.driver->name, c)) < 0)
+			goto err_release_gpio;
 
-	if ((r = request_irq(gpio_to_irq(c->gpio_irq),
-			     omap2_onenand_interrupt, IRQF_TRIGGER_RISING,
-			     pdev->dev.driver->name, c)) < 0)
-		goto err_release_gpio;
+		this->wait = omap2_onenand_wait;
 	}
 
 	if (pdata->dma_channel >= 0) {
@@ -529,15 +527,11 @@ static int omap2_onenand_probe(struct platform_device *pdev)
 		dma_cap_set(DMA_MEMCPY, mask);
 
 		c->dma_chan = dma_request_channel(mask, NULL, NULL);
-		if (!c->dma_chan)
-			dev_info(&pdev->dev,
-				 "failed to allocate DMA for OneNAND, "
-				 "using PIO instead\n");
 	}
 
 	dev_info(&pdev->dev, "initializing on CS%d, phys base 0x%08lx, virtual "
-		 "base %p, freq %d MHz\n", c->gpmc_cs, c->phys_base,
-		 c->onenand.base, c->freq);
+		 "base %p, freq %d MHz, %s mode\n", c->gpmc_cs, c->phys_base,
+		 c->onenand.base, c->freq, c->dma_chan ? "DMA" : "PIO");
 
 	c->pdev = pdev;
 	c->mtd.priv = &c->onenand;
@@ -547,7 +541,6 @@ static int omap2_onenand_probe(struct platform_device *pdev)
 
 	this = &c->onenand;
 	if (c->dma_chan) {
-		this->wait = omap2_onenand_wait;
 		this->read_bufferram = omap2_onenand_read_bufferram;
 		this->write_bufferram = omap2_onenand_write_bufferram;
 	}
-- 
2.11.0

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

* [PATCH v4 13/16] memory: omap-gpmc: Refactor OneNAND support
  2017-11-11 21:12 ` Ladislav Michl
@ 2017-11-11 21:26   ` Ladislav Michl
  -1 siblings, 0 replies; 114+ messages in thread
From: Ladislav Michl @ 2017-11-11 21:26 UTC (permalink / raw)
  To: linux-mtd, linux-omap
  Cc: Tony Lindgren, Peter Ujfalusi, Kyungmin Park, Boris Brezillon,
	Roger Quadros

Use generic probe function to deal with OneNAND node and remove now useless
gpmc_probe_onenand_child function.
Import sync mode timing calculation function from mach-omap2/gpmc-onenand.c
and prepare for MTD driver DTfication.

Signed-off-by: Ladislav Michl <ladis@linux-mips.org>
---
 Changes:
 -v2: add gpmc_omap_onenand_set_timings description
 -v3: none
 -v4: none

 drivers/memory/omap-gpmc.c | 158 +++++++++++++++++++++++++++++++++------------
 include/linux/omap-gpmc.h  |  25 +++++++
 2 files changed, 142 insertions(+), 41 deletions(-)

diff --git a/drivers/memory/omap-gpmc.c b/drivers/memory/omap-gpmc.c
index 0e30ee1c8677..90a66b3f7ae1 100644
--- a/drivers/memory/omap-gpmc.c
+++ b/drivers/memory/omap-gpmc.c
@@ -32,7 +32,6 @@
 #include <linux/pm_runtime.h>
 
 #include <linux/platform_data/mtd-nand-omap2.h>
-#include <linux/platform_data/mtd-onenand-omap2.h>
 
 #include <asm/mach-types.h>
 
@@ -1138,6 +1137,112 @@ struct gpmc_nand_ops *gpmc_omap_get_nand_ops(struct gpmc_nand_regs *reg, int cs)
 }
 EXPORT_SYMBOL_GPL(gpmc_omap_get_nand_ops);
 
+static void gpmc_omap_onenand_calc_sync_timings(struct gpmc_timings *t,
+						struct gpmc_settings *s,
+						int freq, int latency)
+{
+	struct gpmc_device_timings dev_t;
+	const int t_cer  = 15;
+	const int t_avdp = 12;
+	const int t_cez  = 20; /* max of t_cez, t_oez */
+	const int t_wpl  = 40;
+	const int t_wph  = 30;
+	int min_gpmc_clk_period, t_ces, t_avds, t_avdh, t_ach, t_aavdh, t_rdyo;
+
+	switch (freq) {
+	case 104:
+		min_gpmc_clk_period = 9600; /* 104 MHz */
+		t_ces   = 3;
+		t_avds  = 4;
+		t_avdh  = 2;
+		t_ach   = 3;
+		t_aavdh = 6;
+		t_rdyo  = 6;
+		break;
+	case 83:
+		min_gpmc_clk_period = 12000; /* 83 MHz */
+		t_ces   = 5;
+		t_avds  = 4;
+		t_avdh  = 2;
+		t_ach   = 6;
+		t_aavdh = 6;
+		t_rdyo  = 9;
+		break;
+	case 66:
+		min_gpmc_clk_period = 15000; /* 66 MHz */
+		t_ces   = 6;
+		t_avds  = 5;
+		t_avdh  = 2;
+		t_ach   = 6;
+		t_aavdh = 6;
+		t_rdyo  = 11;
+		break;
+	default:
+		min_gpmc_clk_period = 18500; /* 54 MHz */
+		t_ces   = 7;
+		t_avds  = 7;
+		t_avdh  = 7;
+		t_ach   = 9;
+		t_aavdh = 7;
+		t_rdyo  = 15;
+		break;
+	}
+
+	/* Set synchronous read timings */
+	memset(&dev_t, 0, sizeof(dev_t));
+
+	if (!s->sync_write) {
+		dev_t.t_avdp_w = max(t_avdp, t_cer) * 1000;
+		dev_t.t_wpl = t_wpl * 1000;
+		dev_t.t_wph = t_wph * 1000;
+		dev_t.t_aavdh = t_aavdh * 1000;
+	}
+	dev_t.ce_xdelay = true;
+	dev_t.avd_xdelay = true;
+	dev_t.oe_xdelay = true;
+	dev_t.we_xdelay = true;
+	dev_t.clk = min_gpmc_clk_period;
+	dev_t.t_bacc = dev_t.clk;
+	dev_t.t_ces = t_ces * 1000;
+	dev_t.t_avds = t_avds * 1000;
+	dev_t.t_avdh = t_avdh * 1000;
+	dev_t.t_ach = t_ach * 1000;
+	dev_t.cyc_iaa = (latency + 1);
+	dev_t.t_cez_r = t_cez * 1000;
+	dev_t.t_cez_w = dev_t.t_cez_r;
+	dev_t.cyc_aavdh_oe = 1;
+	dev_t.t_rdyo = t_rdyo * 1000 + min_gpmc_clk_period;
+
+	gpmc_calc_timings(t, s, &dev_t);
+}
+
+int gpmc_omap_onenand_set_timings(struct device *dev, int cs, int freq,
+				  int latency,
+				  struct gpmc_onenand_info *info)
+{
+	int ret;
+	struct gpmc_timings gpmc_t;
+	struct gpmc_settings gpmc_s;
+
+	gpmc_read_settings_dt(dev->of_node, &gpmc_s);
+
+	info->sync_read = gpmc_s.sync_read;
+	info->sync_write = gpmc_s.sync_write;
+	info->burst_len = gpmc_s.burst_len;
+
+	if (!gpmc_s.sync_read && !gpmc_s.sync_write)
+		return 0;
+
+	gpmc_omap_onenand_calc_sync_timings(&gpmc_t, &gpmc_s, freq, latency);
+
+	ret = gpmc_cs_program_settings(cs, &gpmc_s);
+	if (ret < 0)
+		return ret;
+
+	return gpmc_cs_set_timings(cs, &gpmc_t, &gpmc_s);
+}
+EXPORT_SYMBOL_GPL(gpmc_omap_onenand_set_timings);
+
 int gpmc_get_client_irq(unsigned irq_config)
 {
 	if (!gpmc_irq_domain) {
@@ -1916,41 +2021,6 @@ static void __maybe_unused gpmc_read_timings_dt(struct device_node *np,
 		of_property_read_bool(np, "gpmc,time-para-granularity");
 }
 
-#if IS_ENABLED(CONFIG_MTD_ONENAND)
-static int gpmc_probe_onenand_child(struct platform_device *pdev,
-				 struct device_node *child)
-{
-	u32 val;
-	struct omap_onenand_platform_data *gpmc_onenand_data;
-
-	if (of_property_read_u32(child, "reg", &val) < 0) {
-		dev_err(&pdev->dev, "%pOF has no 'reg' property\n",
-			child);
-		return -ENODEV;
-	}
-
-	gpmc_onenand_data = devm_kzalloc(&pdev->dev, sizeof(*gpmc_onenand_data),
-					 GFP_KERNEL);
-	if (!gpmc_onenand_data)
-		return -ENOMEM;
-
-	gpmc_onenand_data->cs = val;
-	gpmc_onenand_data->of_node = child;
-	gpmc_onenand_data->dma_channel = -1;
-
-	if (!of_property_read_u32(child, "dma-channel", &val))
-		gpmc_onenand_data->dma_channel = val;
-
-	return gpmc_onenand_init(gpmc_onenand_data);
-}
-#else
-static int gpmc_probe_onenand_child(struct platform_device *pdev,
-				    struct device_node *child)
-{
-	return 0;
-}
-#endif
-
 /**
  * gpmc_probe_generic_child - configures the gpmc for a child device
  * @pdev:	pointer to gpmc platform device
@@ -2053,6 +2123,16 @@ static int gpmc_probe_generic_child(struct platform_device *pdev,
 		}
 	}
 
+	if (of_node_cmp(child->name, "onenand") == 0) {
+		/* Warn about older DT blobs with no compatible property */
+		if (!of_property_read_bool(child, "compatible")) {
+			dev_warn(&pdev->dev,
+				 "Incompatible OneNAND node: missing compatible");
+			ret = -EINVAL;
+			goto err;
+		}
+	}
+
 	if (of_device_is_compatible(child, "ti,omap2-nand")) {
 		/* NAND specific setup */
 		val = 8;
@@ -2189,11 +2269,7 @@ static void gpmc_probe_dt_children(struct platform_device *pdev)
 		if (!child->name)
 			continue;
 
-		if (of_node_cmp(child->name, "onenand") == 0)
-			ret = gpmc_probe_onenand_child(pdev, child);
-		else
-			ret = gpmc_probe_generic_child(pdev, child);
-
+		ret = gpmc_probe_generic_child(pdev, child);
 		if (ret) {
 			dev_err(&pdev->dev, "failed to probe DT child '%s': %d\n",
 				child->name, ret);
diff --git a/include/linux/omap-gpmc.h b/include/linux/omap-gpmc.h
index edfa280c3d56..067bea5e98c4 100644
--- a/include/linux/omap-gpmc.h
+++ b/include/linux/omap-gpmc.h
@@ -25,15 +25,40 @@ struct gpmc_nand_ops {
 
 struct gpmc_nand_regs;
 
+struct gpmc_onenand_info {
+	bool sync_read;
+	bool sync_write;
+	int burst_len;
+};
+
 #if IS_ENABLED(CONFIG_OMAP_GPMC)
 struct gpmc_nand_ops *gpmc_omap_get_nand_ops(struct gpmc_nand_regs *regs,
 					     int cs);
+/**
+ * gpmc_omap_onenand_set_timings - set optimized sync timings.
+ * @cs:      Chip Select Region
+ * @freq:    Chip frequency
+ * @latency: Burst latency cycle count
+ * @info:    Structure describing parameters used
+ */
+int gpmc_omap_onenand_set_timings(struct device *dev, int cs, int freq,
+				  int latency,
+				  struct gpmc_onenand_info *info);
+
 #else
 static inline struct gpmc_nand_ops *gpmc_omap_get_nand_ops(struct gpmc_nand_regs *regs,
 							   int cs)
 {
 	return NULL;
 }
+
+static inline
+int gpmc_omap_onenand_set_timings(struct device *dev, int cs, int freq,
+				  int latency,
+				  struct gpmc_onenand_info *info)
+{
+	return -EINVAL;
+}
 #endif /* CONFIG_OMAP_GPMC */
 
 extern int gpmc_calc_timings(struct gpmc_timings *gpmc_t,
-- 
2.11.0


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

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

* [PATCH v4 13/16] memory: omap-gpmc: Refactor OneNAND support
@ 2017-11-11 21:26   ` Ladislav Michl
  0 siblings, 0 replies; 114+ messages in thread
From: Ladislav Michl @ 2017-11-11 21:26 UTC (permalink / raw)
  To: linux-mtd, linux-omap
  Cc: Roger Quadros, Tony Lindgren, Peter Ujfalusi, Boris Brezillon,
	Kyungmin Park

Use generic probe function to deal with OneNAND node and remove now useless
gpmc_probe_onenand_child function.
Import sync mode timing calculation function from mach-omap2/gpmc-onenand.c
and prepare for MTD driver DTfication.

Signed-off-by: Ladislav Michl <ladis@linux-mips.org>
---
 Changes:
 -v2: add gpmc_omap_onenand_set_timings description
 -v3: none
 -v4: none

 drivers/memory/omap-gpmc.c | 158 +++++++++++++++++++++++++++++++++------------
 include/linux/omap-gpmc.h  |  25 +++++++
 2 files changed, 142 insertions(+), 41 deletions(-)

diff --git a/drivers/memory/omap-gpmc.c b/drivers/memory/omap-gpmc.c
index 0e30ee1c8677..90a66b3f7ae1 100644
--- a/drivers/memory/omap-gpmc.c
+++ b/drivers/memory/omap-gpmc.c
@@ -32,7 +32,6 @@
 #include <linux/pm_runtime.h>
 
 #include <linux/platform_data/mtd-nand-omap2.h>
-#include <linux/platform_data/mtd-onenand-omap2.h>
 
 #include <asm/mach-types.h>
 
@@ -1138,6 +1137,112 @@ struct gpmc_nand_ops *gpmc_omap_get_nand_ops(struct gpmc_nand_regs *reg, int cs)
 }
 EXPORT_SYMBOL_GPL(gpmc_omap_get_nand_ops);
 
+static void gpmc_omap_onenand_calc_sync_timings(struct gpmc_timings *t,
+						struct gpmc_settings *s,
+						int freq, int latency)
+{
+	struct gpmc_device_timings dev_t;
+	const int t_cer  = 15;
+	const int t_avdp = 12;
+	const int t_cez  = 20; /* max of t_cez, t_oez */
+	const int t_wpl  = 40;
+	const int t_wph  = 30;
+	int min_gpmc_clk_period, t_ces, t_avds, t_avdh, t_ach, t_aavdh, t_rdyo;
+
+	switch (freq) {
+	case 104:
+		min_gpmc_clk_period = 9600; /* 104 MHz */
+		t_ces   = 3;
+		t_avds  = 4;
+		t_avdh  = 2;
+		t_ach   = 3;
+		t_aavdh = 6;
+		t_rdyo  = 6;
+		break;
+	case 83:
+		min_gpmc_clk_period = 12000; /* 83 MHz */
+		t_ces   = 5;
+		t_avds  = 4;
+		t_avdh  = 2;
+		t_ach   = 6;
+		t_aavdh = 6;
+		t_rdyo  = 9;
+		break;
+	case 66:
+		min_gpmc_clk_period = 15000; /* 66 MHz */
+		t_ces   = 6;
+		t_avds  = 5;
+		t_avdh  = 2;
+		t_ach   = 6;
+		t_aavdh = 6;
+		t_rdyo  = 11;
+		break;
+	default:
+		min_gpmc_clk_period = 18500; /* 54 MHz */
+		t_ces   = 7;
+		t_avds  = 7;
+		t_avdh  = 7;
+		t_ach   = 9;
+		t_aavdh = 7;
+		t_rdyo  = 15;
+		break;
+	}
+
+	/* Set synchronous read timings */
+	memset(&dev_t, 0, sizeof(dev_t));
+
+	if (!s->sync_write) {
+		dev_t.t_avdp_w = max(t_avdp, t_cer) * 1000;
+		dev_t.t_wpl = t_wpl * 1000;
+		dev_t.t_wph = t_wph * 1000;
+		dev_t.t_aavdh = t_aavdh * 1000;
+	}
+	dev_t.ce_xdelay = true;
+	dev_t.avd_xdelay = true;
+	dev_t.oe_xdelay = true;
+	dev_t.we_xdelay = true;
+	dev_t.clk = min_gpmc_clk_period;
+	dev_t.t_bacc = dev_t.clk;
+	dev_t.t_ces = t_ces * 1000;
+	dev_t.t_avds = t_avds * 1000;
+	dev_t.t_avdh = t_avdh * 1000;
+	dev_t.t_ach = t_ach * 1000;
+	dev_t.cyc_iaa = (latency + 1);
+	dev_t.t_cez_r = t_cez * 1000;
+	dev_t.t_cez_w = dev_t.t_cez_r;
+	dev_t.cyc_aavdh_oe = 1;
+	dev_t.t_rdyo = t_rdyo * 1000 + min_gpmc_clk_period;
+
+	gpmc_calc_timings(t, s, &dev_t);
+}
+
+int gpmc_omap_onenand_set_timings(struct device *dev, int cs, int freq,
+				  int latency,
+				  struct gpmc_onenand_info *info)
+{
+	int ret;
+	struct gpmc_timings gpmc_t;
+	struct gpmc_settings gpmc_s;
+
+	gpmc_read_settings_dt(dev->of_node, &gpmc_s);
+
+	info->sync_read = gpmc_s.sync_read;
+	info->sync_write = gpmc_s.sync_write;
+	info->burst_len = gpmc_s.burst_len;
+
+	if (!gpmc_s.sync_read && !gpmc_s.sync_write)
+		return 0;
+
+	gpmc_omap_onenand_calc_sync_timings(&gpmc_t, &gpmc_s, freq, latency);
+
+	ret = gpmc_cs_program_settings(cs, &gpmc_s);
+	if (ret < 0)
+		return ret;
+
+	return gpmc_cs_set_timings(cs, &gpmc_t, &gpmc_s);
+}
+EXPORT_SYMBOL_GPL(gpmc_omap_onenand_set_timings);
+
 int gpmc_get_client_irq(unsigned irq_config)
 {
 	if (!gpmc_irq_domain) {
@@ -1916,41 +2021,6 @@ static void __maybe_unused gpmc_read_timings_dt(struct device_node *np,
 		of_property_read_bool(np, "gpmc,time-para-granularity");
 }
 
-#if IS_ENABLED(CONFIG_MTD_ONENAND)
-static int gpmc_probe_onenand_child(struct platform_device *pdev,
-				 struct device_node *child)
-{
-	u32 val;
-	struct omap_onenand_platform_data *gpmc_onenand_data;
-
-	if (of_property_read_u32(child, "reg", &val) < 0) {
-		dev_err(&pdev->dev, "%pOF has no 'reg' property\n",
-			child);
-		return -ENODEV;
-	}
-
-	gpmc_onenand_data = devm_kzalloc(&pdev->dev, sizeof(*gpmc_onenand_data),
-					 GFP_KERNEL);
-	if (!gpmc_onenand_data)
-		return -ENOMEM;
-
-	gpmc_onenand_data->cs = val;
-	gpmc_onenand_data->of_node = child;
-	gpmc_onenand_data->dma_channel = -1;
-
-	if (!of_property_read_u32(child, "dma-channel", &val))
-		gpmc_onenand_data->dma_channel = val;
-
-	return gpmc_onenand_init(gpmc_onenand_data);
-}
-#else
-static int gpmc_probe_onenand_child(struct platform_device *pdev,
-				    struct device_node *child)
-{
-	return 0;
-}
-#endif
-
 /**
  * gpmc_probe_generic_child - configures the gpmc for a child device
  * @pdev:	pointer to gpmc platform device
@@ -2053,6 +2123,16 @@ static int gpmc_probe_generic_child(struct platform_device *pdev,
 		}
 	}
 
+	if (of_node_cmp(child->name, "onenand") == 0) {
+		/* Warn about older DT blobs with no compatible property */
+		if (!of_property_read_bool(child, "compatible")) {
+			dev_warn(&pdev->dev,
+				 "Incompatible OneNAND node: missing compatible");
+			ret = -EINVAL;
+			goto err;
+		}
+	}
+
 	if (of_device_is_compatible(child, "ti,omap2-nand")) {
 		/* NAND specific setup */
 		val = 8;
@@ -2189,11 +2269,7 @@ static void gpmc_probe_dt_children(struct platform_device *pdev)
 		if (!child->name)
 			continue;
 
-		if (of_node_cmp(child->name, "onenand") == 0)
-			ret = gpmc_probe_onenand_child(pdev, child);
-		else
-			ret = gpmc_probe_generic_child(pdev, child);
-
+		ret = gpmc_probe_generic_child(pdev, child);
 		if (ret) {
 			dev_err(&pdev->dev, "failed to probe DT child '%s': %d\n",
 				child->name, ret);
diff --git a/include/linux/omap-gpmc.h b/include/linux/omap-gpmc.h
index edfa280c3d56..067bea5e98c4 100644
--- a/include/linux/omap-gpmc.h
+++ b/include/linux/omap-gpmc.h
@@ -25,15 +25,40 @@ struct gpmc_nand_ops {
 
 struct gpmc_nand_regs;
 
+struct gpmc_onenand_info {
+	bool sync_read;
+	bool sync_write;
+	int burst_len;
+};
+
 #if IS_ENABLED(CONFIG_OMAP_GPMC)
 struct gpmc_nand_ops *gpmc_omap_get_nand_ops(struct gpmc_nand_regs *regs,
 					     int cs);
+/**
+ * gpmc_omap_onenand_set_timings - set optimized sync timings.
+ * @cs:      Chip Select Region
+ * @freq:    Chip frequency
+ * @latency: Burst latency cycle count
+ * @info:    Structure describing parameters used
+ */
+int gpmc_omap_onenand_set_timings(struct device *dev, int cs, int freq,
+				  int latency,
+				  struct gpmc_onenand_info *info);
+
 #else
 static inline struct gpmc_nand_ops *gpmc_omap_get_nand_ops(struct gpmc_nand_regs *regs,
 							   int cs)
 {
 	return NULL;
 }
+
+static inline
+int gpmc_omap_onenand_set_timings(struct device *dev, int cs, int freq,
+				  int latency,
+				  struct gpmc_onenand_info *info)
+{
+	return -EINVAL;
+}
 #endif /* CONFIG_OMAP_GPMC */
 
 extern int gpmc_calc_timings(struct gpmc_timings *gpmc_t,
-- 
2.11.0

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

* [PATCH v4 14/16] mtd: onenand: omap2: Configure driver from DT
  2017-11-11 21:12 ` Ladislav Michl
@ 2017-11-11 21:27   ` Ladislav Michl
  -1 siblings, 0 replies; 114+ messages in thread
From: Ladislav Michl @ 2017-11-11 21:27 UTC (permalink / raw)
  To: linux-mtd, linux-omap
  Cc: Tony Lindgren, Peter Ujfalusi, Kyungmin Park, Boris Brezillon,
	Roger Quadros

Move away from platform data configuration and use pure DT approach.

Signed-off-by: Ladislav Michl <ladis@linux-mips.org>
---
 Changes:
 -v2: move cleanups into separate patches
      simplify dma setup
      fix checkpatch error
      print info about otimized timings in sync mode only
 -v3: remove 'ti,omap3-onenand' compatible as it is not needed anymore
 -v4: none

 drivers/mtd/onenand/omap2.c | 264 +++++++++++++++++++++++++++-----------------
 1 file changed, 162 insertions(+), 102 deletions(-)

diff --git a/drivers/mtd/onenand/omap2.c b/drivers/mtd/onenand/omap2.c
index 62e4ede918c4..9ebbbf297993 100644
--- a/drivers/mtd/onenand/omap2.c
+++ b/drivers/mtd/onenand/omap2.c
@@ -28,6 +28,8 @@
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/onenand.h>
 #include <linux/mtd/partitions.h>
+#include <linux/of_device.h>
+#include <linux/omap-gpmc.h>
 #include <linux/platform_device.h>
 #include <linux/interrupt.h>
 #include <linux/delay.h>
@@ -35,10 +37,9 @@
 #include <linux/dmaengine.h>
 #include <linux/io.h>
 #include <linux/slab.h>
-#include <linux/gpio.h>
+#include <linux/gpio/consumer.h>
 
 #include <asm/mach/flash.h>
-#include <linux/platform_data/mtd-onenand-omap2.h>
 
 #define DRIVER_NAME "omap2-onenand"
 
@@ -48,15 +49,12 @@ struct omap2_onenand {
 	struct platform_device *pdev;
 	int gpmc_cs;
 	unsigned long phys_base;
-	unsigned int mem_size;
-	int gpio_irq;
+	struct gpio_desc *ready_gpiod;
 	struct mtd_info mtd;
 	struct onenand_chip onenand;
 	struct completion irq_done;
 	struct completion dma_done;
 	struct dma_chan *dma_chan;
-	int freq;
-	int (*setup)(void __iomem *base, int *freq_ptr);
 };
 
 static void omap2_onenand_dma_complete_func(void *completion)
@@ -84,6 +82,65 @@ static inline void write_reg(struct omap2_onenand *c, unsigned short value,
 	writew(value, c->onenand.base + reg);
 }
 
+static int omap2_onenand_set_cfg(struct omap2_onenand *c,
+				 bool sr, bool sw,
+				 int latency, int burst_len)
+{
+	unsigned short reg = ONENAND_SYS_CFG1_RDY | ONENAND_SYS_CFG1_INT;
+
+	reg |= latency << ONENAND_SYS_CFG1_BRL_SHIFT;
+
+	switch (burst_len) {
+	case 0:		/* continuous */
+		break;
+	case 4:
+		reg |= ONENAND_SYS_CFG1_BL_4;
+		break;
+	case 8:
+		reg |= ONENAND_SYS_CFG1_BL_8;
+		break;
+	case 16:
+		reg |= ONENAND_SYS_CFG1_BL_16;
+		break;
+	case 32:
+		reg |= ONENAND_SYS_CFG1_BL_32;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	if (latency > 5)
+		reg |= ONENAND_SYS_CFG1_HF;
+	if (latency > 7)
+		reg |= ONENAND_SYS_CFG1_VHF;
+	if (sr)
+		reg |= ONENAND_SYS_CFG1_SYNC_READ;
+	if (sw)
+		reg |= ONENAND_SYS_CFG1_SYNC_WRITE;
+
+	write_reg(c, reg, ONENAND_REG_SYS_CFG1);
+
+	return 0;
+}
+
+static int omap2_onenand_get_freq(int ver)
+{
+	switch ((ver >> 4) & 0xf) {
+	case 0:
+		return 40;
+	case 1:
+		return 54;
+	case 2:
+		return 66;
+	case 3:
+		return 83;
+	case 4:
+		return 104;
+	}
+
+	return -EINVAL;
+}
+
 static void wait_err(char *msg, int state, unsigned int ctrl, unsigned int intr)
 {
 	printk(KERN_ERR "onenand_wait: %s! state %d ctrl 0x%04x intr 0x%04x\n",
@@ -152,12 +209,12 @@ static int omap2_onenand_wait(struct mtd_info *mtd, int state)
 		}
 
 		reinit_completion(&c->irq_done);
-		result = gpio_get_value(c->gpio_irq);
+		result = gpiod_get_value(c->ready_gpiod);
 		if (result < 0) {
 			ctrl = read_reg(c, ONENAND_REG_CTRL_STATUS);
 			intr = read_reg(c, ONENAND_REG_INTERRUPT);
 			wait_err("gpio error", state, ctrl, intr);
-			return -EIO;
+			return result;
 		} else if (result == 0) {
 			int retry_cnt = 0;
 retry:
@@ -431,8 +488,6 @@ static int omap2_onenand_write_bufferram(struct mtd_info *mtd, int area,
 	return 0;
 }
 
-static struct platform_driver omap2_onenand_driver;
-
 static void omap2_onenand_shutdown(struct platform_device *pdev)
 {
 	struct omap2_onenand *c = dev_get_drvdata(&pdev->dev);
@@ -446,108 +501,124 @@ static void omap2_onenand_shutdown(struct platform_device *pdev)
 
 static int omap2_onenand_probe(struct platform_device *pdev)
 {
-	struct omap_onenand_platform_data *pdata;
-	struct omap2_onenand *c;
-	struct onenand_chip *this;
-	int r;
+	u32 val;
+	dma_cap_mask_t mask;
+	int freq, latency, r;
+	unsigned int mem_size;
 	struct resource *res;
+	struct omap2_onenand *c;
+	struct gpmc_onenand_info info;
+	struct device *dev = &pdev->dev;
+	struct device_node *np = dev->of_node;
 
-	pdata = dev_get_platdata(&pdev->dev);
-	if (pdata == NULL) {
-		dev_err(&pdev->dev, "platform data missing\n");
-		return -ENODEV;
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!res) {
+		dev_err(dev, "error getting memory resource\n");
+		return -EINVAL;
 	}
 
-	c = kzalloc(sizeof(struct omap2_onenand), GFP_KERNEL);
+	r = of_property_read_u32(np, "reg", &val);
+	if (r) {
+		dev_err(dev, "reg not found in DT\n");
+		return r;
+	}
+
+	c = devm_kzalloc(dev, sizeof(struct omap2_onenand), GFP_KERNEL);
 	if (!c)
 		return -ENOMEM;
 
 	init_completion(&c->irq_done);
 	init_completion(&c->dma_done);
-	c->gpmc_cs = pdata->cs;
-	c->gpio_irq = pdata->gpio_irq;
-	if (pdata->dma_channel < 0) {
-		/* if -1, don't use DMA */
-		c->gpio_irq = 0;
-	}
+	c->gpmc_cs = val;
+	c->phys_base = res->start;
 
-	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	if (res == NULL) {
-		r = -EINVAL;
-		dev_err(&pdev->dev, "error getting memory resource\n");
-		goto err_kfree;
-	}
+	mem_size = resource_size(res);
+	if (!devm_request_mem_region(dev, c->phys_base, mem_size,
+				     dev->driver->name)) {
 
-	c->phys_base = res->start;
-	c->mem_size = resource_size(res);
-
-	if (request_mem_region(c->phys_base, c->mem_size,
-			       pdev->dev.driver->name) == NULL) {
-		dev_err(&pdev->dev, "Cannot reserve memory region at 0x%08lx, size: 0x%x\n",
-						c->phys_base, c->mem_size);
-		r = -EBUSY;
-		goto err_kfree;
-	}
-	c->onenand.base = ioremap(c->phys_base, c->mem_size);
-	if (c->onenand.base == NULL) {
-		r = -ENOMEM;
-		goto err_release_mem_region;
+		dev_err(dev, "Cannot reserve memory region at 0x%08lx, size: 0x%x\n",
+			c->phys_base, mem_size);
+		return -EBUSY;
 	}
 
-	if (pdata->onenand_setup != NULL) {
-		r = pdata->onenand_setup(c->onenand.base, &c->freq);
-		if (r < 0) {
-			dev_err(&pdev->dev, "Onenand platform setup failed: "
-				"%d\n", r);
-			goto err_iounmap;
-		}
-		c->setup = pdata->onenand_setup;
-	}
+	c->onenand.base = devm_ioremap(dev, c->phys_base, mem_size);
+	if (!c->onenand.base)
+		return -ENOMEM;
 
-	if (c->gpio_irq) {
-		if ((r = gpio_request(c->gpio_irq, "OneNAND irq")) < 0) {
-			dev_err(&pdev->dev,  "Failed to request GPIO%d for "
-				"OneNAND\n", c->gpio_irq);
-			goto err_iounmap;
-		}
-		gpio_direction_input(c->gpio_irq);
+	c->ready_gpiod = devm_gpiod_get_optional(dev, "rb", GPIOD_IN);
+	if (IS_ERR(c->ready_gpiod)) {
+		r = PTR_ERR(c->ready_gpiod);
+		/* Just try again if this happens */
+		if (r != -EPROBE_DEFER)
+			dev_err(dev, "error getting gpio: %d\n", r);
+		return r;
+	}
 
-		if ((r = request_irq(gpio_to_irq(c->gpio_irq),
-				     omap2_onenand_interrupt, IRQF_TRIGGER_RISING,
-				     pdev->dev.driver->name, c)) < 0)
-			goto err_release_gpio;
+	if (c->ready_gpiod) {
+		r = devm_request_irq(dev, gpiod_to_irq(c->ready_gpiod),
+				     omap2_onenand_interrupt,
+				     IRQF_TRIGGER_RISING, "OneNAND", c);
+		if (r)
+			return r;
 
-		this->wait = omap2_onenand_wait;
+		c->onenand.wait = omap2_onenand_wait;
 	}
 
-	if (pdata->dma_channel >= 0) {
-		dma_cap_mask_t mask;
-
-		dma_cap_zero(mask);
-		dma_cap_set(DMA_MEMCPY, mask);
+	dma_cap_zero(mask);
+	dma_cap_set(DMA_MEMCPY, mask);
 
-		c->dma_chan = dma_request_channel(mask, NULL, NULL);
+	c->dma_chan = dma_request_channel(mask, NULL, NULL);
+	if (c->dma_chan) {
+		c->onenand.read_bufferram = omap2_onenand_read_bufferram;
+		c->onenand.write_bufferram = omap2_onenand_write_bufferram;
 	}
 
-	dev_info(&pdev->dev, "initializing on CS%d, phys base 0x%08lx, virtual "
-		 "base %p, freq %d MHz, %s mode\n", c->gpmc_cs, c->phys_base,
-		 c->onenand.base, c->freq, c->dma_chan ? "DMA" : "PIO");
-
 	c->pdev = pdev;
 	c->mtd.priv = &c->onenand;
+	c->mtd.dev.parent = dev;
+	mtd_set_of_node(&c->mtd, dev->of_node);
 
-	c->mtd.dev.parent = &pdev->dev;
-	mtd_set_of_node(&c->mtd, pdata->of_node);
-
-	this = &c->onenand;
-	if (c->dma_chan) {
-		this->read_bufferram = omap2_onenand_read_bufferram;
-		this->write_bufferram = omap2_onenand_write_bufferram;
-	}
+	dev_info(dev, "initializing on CS%d (0x%08lx), va %p, %s mode\n",
+		 c->gpmc_cs, c->phys_base, c->onenand.base,
+		 c->dma_chan ? "DMA" : "PIO");
 
 	if ((r = onenand_scan(&c->mtd, 1)) < 0)
 		goto err_release_dma;
 
+	freq = omap2_onenand_get_freq(c->onenand.version_id);
+	if (freq > 0) {
+		switch (freq) {
+		case 104:
+			latency = 7;
+			break;
+		case 83:
+			latency = 6;
+			break;
+		case 66:
+			latency = 5;
+			break;
+		case 56:
+			latency = 4;
+			break;
+		default:	/* 40 MHz or lower */
+			latency = 3;
+			break;
+		}
+
+		r = gpmc_omap_onenand_set_timings(dev, c->gpmc_cs,
+						  freq, latency, &info);
+		if (r)
+			goto err_release_onenand;
+
+		r = omap2_onenand_set_cfg(c, info.sync_read, info.sync_write,
+					  latency, info.burst_len);
+		if (r)
+			goto err_release_onenand;
+
+		if (info.sync_read || info.sync_write)
+			dev_info(dev, "optimized timings for %d MHz\n", freq);
+	}
+
 	r = mtd_device_register(&c->mtd, NULL, 0);
 	if (r)
 		goto err_release_onenand;
@@ -561,17 +632,6 @@ static int omap2_onenand_probe(struct platform_device *pdev)
 err_release_dma:
 	if (c->dma_chan)
 		dma_release_channel(c->dma_chan);
-	if (c->gpio_irq)
-		free_irq(gpio_to_irq(c->gpio_irq), c);
-err_release_gpio:
-	if (c->gpio_irq)
-		gpio_free(c->gpio_irq);
-err_iounmap:
-	iounmap(c->onenand.base);
-err_release_mem_region:
-	release_mem_region(c->phys_base, c->mem_size);
-err_kfree:
-	kfree(c);
 
 	return r;
 }
@@ -584,23 +644,23 @@ static int omap2_onenand_remove(struct platform_device *pdev)
 	if (c->dma_chan)
 		dma_release_channel(c->dma_chan);
 	omap2_onenand_shutdown(pdev);
-	if (c->gpio_irq) {
-		free_irq(gpio_to_irq(c->gpio_irq), c);
-		gpio_free(c->gpio_irq);
-	}
-	iounmap(c->onenand.base);
-	release_mem_region(c->phys_base, c->mem_size);
-	kfree(c);
 
 	return 0;
 }
 
+static const struct of_device_id omap2_onenand_id_table[] = {
+	{ .compatible = "ti,omap2-onenand", },
+	{},
+};
+MODULE_DEVICE_TABLE(of, omap2_onenand_id_table);
+
 static struct platform_driver omap2_onenand_driver = {
 	.probe		= omap2_onenand_probe,
 	.remove		= omap2_onenand_remove,
 	.shutdown	= omap2_onenand_shutdown,
 	.driver		= {
 		.name	= DRIVER_NAME,
+		.of_match_table = omap2_onenand_id_table,
 	},
 };
 
-- 
2.11.0


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

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

* [PATCH v4 14/16] mtd: onenand: omap2: Configure driver from DT
@ 2017-11-11 21:27   ` Ladislav Michl
  0 siblings, 0 replies; 114+ messages in thread
From: Ladislav Michl @ 2017-11-11 21:27 UTC (permalink / raw)
  To: linux-mtd, linux-omap
  Cc: Roger Quadros, Tony Lindgren, Peter Ujfalusi, Boris Brezillon,
	Kyungmin Park

Move away from platform data configuration and use pure DT approach.

Signed-off-by: Ladislav Michl <ladis@linux-mips.org>
---
 Changes:
 -v2: move cleanups into separate patches
      simplify dma setup
      fix checkpatch error
      print info about otimized timings in sync mode only
 -v3: remove 'ti,omap3-onenand' compatible as it is not needed anymore
 -v4: none

 drivers/mtd/onenand/omap2.c | 264 +++++++++++++++++++++++++++-----------------
 1 file changed, 162 insertions(+), 102 deletions(-)

diff --git a/drivers/mtd/onenand/omap2.c b/drivers/mtd/onenand/omap2.c
index 62e4ede918c4..9ebbbf297993 100644
--- a/drivers/mtd/onenand/omap2.c
+++ b/drivers/mtd/onenand/omap2.c
@@ -28,6 +28,8 @@
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/onenand.h>
 #include <linux/mtd/partitions.h>
+#include <linux/of_device.h>
+#include <linux/omap-gpmc.h>
 #include <linux/platform_device.h>
 #include <linux/interrupt.h>
 #include <linux/delay.h>
@@ -35,10 +37,9 @@
 #include <linux/dmaengine.h>
 #include <linux/io.h>
 #include <linux/slab.h>
-#include <linux/gpio.h>
+#include <linux/gpio/consumer.h>
 
 #include <asm/mach/flash.h>
-#include <linux/platform_data/mtd-onenand-omap2.h>
 
 #define DRIVER_NAME "omap2-onenand"
 
@@ -48,15 +49,12 @@ struct omap2_onenand {
 	struct platform_device *pdev;
 	int gpmc_cs;
 	unsigned long phys_base;
-	unsigned int mem_size;
-	int gpio_irq;
+	struct gpio_desc *ready_gpiod;
 	struct mtd_info mtd;
 	struct onenand_chip onenand;
 	struct completion irq_done;
 	struct completion dma_done;
 	struct dma_chan *dma_chan;
-	int freq;
-	int (*setup)(void __iomem *base, int *freq_ptr);
 };
 
 static void omap2_onenand_dma_complete_func(void *completion)
@@ -84,6 +82,65 @@ static inline void write_reg(struct omap2_onenand *c, unsigned short value,
 	writew(value, c->onenand.base + reg);
 }
 
+static int omap2_onenand_set_cfg(struct omap2_onenand *c,
+				 bool sr, bool sw,
+				 int latency, int burst_len)
+{
+	unsigned short reg = ONENAND_SYS_CFG1_RDY | ONENAND_SYS_CFG1_INT;
+
+	reg |= latency << ONENAND_SYS_CFG1_BRL_SHIFT;
+
+	switch (burst_len) {
+	case 0:		/* continuous */
+		break;
+	case 4:
+		reg |= ONENAND_SYS_CFG1_BL_4;
+		break;
+	case 8:
+		reg |= ONENAND_SYS_CFG1_BL_8;
+		break;
+	case 16:
+		reg |= ONENAND_SYS_CFG1_BL_16;
+		break;
+	case 32:
+		reg |= ONENAND_SYS_CFG1_BL_32;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	if (latency > 5)
+		reg |= ONENAND_SYS_CFG1_HF;
+	if (latency > 7)
+		reg |= ONENAND_SYS_CFG1_VHF;
+	if (sr)
+		reg |= ONENAND_SYS_CFG1_SYNC_READ;
+	if (sw)
+		reg |= ONENAND_SYS_CFG1_SYNC_WRITE;
+
+	write_reg(c, reg, ONENAND_REG_SYS_CFG1);
+
+	return 0;
+}
+
+static int omap2_onenand_get_freq(int ver)
+{
+	switch ((ver >> 4) & 0xf) {
+	case 0:
+		return 40;
+	case 1:
+		return 54;
+	case 2:
+		return 66;
+	case 3:
+		return 83;
+	case 4:
+		return 104;
+	}
+
+	return -EINVAL;
+}
+
 static void wait_err(char *msg, int state, unsigned int ctrl, unsigned int intr)
 {
 	printk(KERN_ERR "onenand_wait: %s! state %d ctrl 0x%04x intr 0x%04x\n",
@@ -152,12 +209,12 @@ static int omap2_onenand_wait(struct mtd_info *mtd, int state)
 		}
 
 		reinit_completion(&c->irq_done);
-		result = gpio_get_value(c->gpio_irq);
+		result = gpiod_get_value(c->ready_gpiod);
 		if (result < 0) {
 			ctrl = read_reg(c, ONENAND_REG_CTRL_STATUS);
 			intr = read_reg(c, ONENAND_REG_INTERRUPT);
 			wait_err("gpio error", state, ctrl, intr);
-			return -EIO;
+			return result;
 		} else if (result == 0) {
 			int retry_cnt = 0;
 retry:
@@ -431,8 +488,6 @@ static int omap2_onenand_write_bufferram(struct mtd_info *mtd, int area,
 	return 0;
 }
 
-static struct platform_driver omap2_onenand_driver;
-
 static void omap2_onenand_shutdown(struct platform_device *pdev)
 {
 	struct omap2_onenand *c = dev_get_drvdata(&pdev->dev);
@@ -446,108 +501,124 @@ static void omap2_onenand_shutdown(struct platform_device *pdev)
 
 static int omap2_onenand_probe(struct platform_device *pdev)
 {
-	struct omap_onenand_platform_data *pdata;
-	struct omap2_onenand *c;
-	struct onenand_chip *this;
-	int r;
+	u32 val;
+	dma_cap_mask_t mask;
+	int freq, latency, r;
+	unsigned int mem_size;
 	struct resource *res;
+	struct omap2_onenand *c;
+	struct gpmc_onenand_info info;
+	struct device *dev = &pdev->dev;
+	struct device_node *np = dev->of_node;
 
-	pdata = dev_get_platdata(&pdev->dev);
-	if (pdata == NULL) {
-		dev_err(&pdev->dev, "platform data missing\n");
-		return -ENODEV;
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!res) {
+		dev_err(dev, "error getting memory resource\n");
+		return -EINVAL;
 	}
 
-	c = kzalloc(sizeof(struct omap2_onenand), GFP_KERNEL);
+	r = of_property_read_u32(np, "reg", &val);
+	if (r) {
+		dev_err(dev, "reg not found in DT\n");
+		return r;
+	}
+
+	c = devm_kzalloc(dev, sizeof(struct omap2_onenand), GFP_KERNEL);
 	if (!c)
 		return -ENOMEM;
 
 	init_completion(&c->irq_done);
 	init_completion(&c->dma_done);
-	c->gpmc_cs = pdata->cs;
-	c->gpio_irq = pdata->gpio_irq;
-	if (pdata->dma_channel < 0) {
-		/* if -1, don't use DMA */
-		c->gpio_irq = 0;
-	}
+	c->gpmc_cs = val;
+	c->phys_base = res->start;
 
-	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	if (res == NULL) {
-		r = -EINVAL;
-		dev_err(&pdev->dev, "error getting memory resource\n");
-		goto err_kfree;
-	}
+	mem_size = resource_size(res);
+	if (!devm_request_mem_region(dev, c->phys_base, mem_size,
+				     dev->driver->name)) {
 
-	c->phys_base = res->start;
-	c->mem_size = resource_size(res);
-
-	if (request_mem_region(c->phys_base, c->mem_size,
-			       pdev->dev.driver->name) == NULL) {
-		dev_err(&pdev->dev, "Cannot reserve memory region at 0x%08lx, size: 0x%x\n",
-						c->phys_base, c->mem_size);
-		r = -EBUSY;
-		goto err_kfree;
-	}
-	c->onenand.base = ioremap(c->phys_base, c->mem_size);
-	if (c->onenand.base == NULL) {
-		r = -ENOMEM;
-		goto err_release_mem_region;
+		dev_err(dev, "Cannot reserve memory region at 0x%08lx, size: 0x%x\n",
+			c->phys_base, mem_size);
+		return -EBUSY;
 	}
 
-	if (pdata->onenand_setup != NULL) {
-		r = pdata->onenand_setup(c->onenand.base, &c->freq);
-		if (r < 0) {
-			dev_err(&pdev->dev, "Onenand platform setup failed: "
-				"%d\n", r);
-			goto err_iounmap;
-		}
-		c->setup = pdata->onenand_setup;
-	}
+	c->onenand.base = devm_ioremap(dev, c->phys_base, mem_size);
+	if (!c->onenand.base)
+		return -ENOMEM;
 
-	if (c->gpio_irq) {
-		if ((r = gpio_request(c->gpio_irq, "OneNAND irq")) < 0) {
-			dev_err(&pdev->dev,  "Failed to request GPIO%d for "
-				"OneNAND\n", c->gpio_irq);
-			goto err_iounmap;
-		}
-		gpio_direction_input(c->gpio_irq);
+	c->ready_gpiod = devm_gpiod_get_optional(dev, "rb", GPIOD_IN);
+	if (IS_ERR(c->ready_gpiod)) {
+		r = PTR_ERR(c->ready_gpiod);
+		/* Just try again if this happens */
+		if (r != -EPROBE_DEFER)
+			dev_err(dev, "error getting gpio: %d\n", r);
+		return r;
+	}
 
-		if ((r = request_irq(gpio_to_irq(c->gpio_irq),
-				     omap2_onenand_interrupt, IRQF_TRIGGER_RISING,
-				     pdev->dev.driver->name, c)) < 0)
-			goto err_release_gpio;
+	if (c->ready_gpiod) {
+		r = devm_request_irq(dev, gpiod_to_irq(c->ready_gpiod),
+				     omap2_onenand_interrupt,
+				     IRQF_TRIGGER_RISING, "OneNAND", c);
+		if (r)
+			return r;
 
-		this->wait = omap2_onenand_wait;
+		c->onenand.wait = omap2_onenand_wait;
 	}
 
-	if (pdata->dma_channel >= 0) {
-		dma_cap_mask_t mask;
-
-		dma_cap_zero(mask);
-		dma_cap_set(DMA_MEMCPY, mask);
+	dma_cap_zero(mask);
+	dma_cap_set(DMA_MEMCPY, mask);
 
-		c->dma_chan = dma_request_channel(mask, NULL, NULL);
+	c->dma_chan = dma_request_channel(mask, NULL, NULL);
+	if (c->dma_chan) {
+		c->onenand.read_bufferram = omap2_onenand_read_bufferram;
+		c->onenand.write_bufferram = omap2_onenand_write_bufferram;
 	}
 
-	dev_info(&pdev->dev, "initializing on CS%d, phys base 0x%08lx, virtual "
-		 "base %p, freq %d MHz, %s mode\n", c->gpmc_cs, c->phys_base,
-		 c->onenand.base, c->freq, c->dma_chan ? "DMA" : "PIO");
-
 	c->pdev = pdev;
 	c->mtd.priv = &c->onenand;
+	c->mtd.dev.parent = dev;
+	mtd_set_of_node(&c->mtd, dev->of_node);
 
-	c->mtd.dev.parent = &pdev->dev;
-	mtd_set_of_node(&c->mtd, pdata->of_node);
-
-	this = &c->onenand;
-	if (c->dma_chan) {
-		this->read_bufferram = omap2_onenand_read_bufferram;
-		this->write_bufferram = omap2_onenand_write_bufferram;
-	}
+	dev_info(dev, "initializing on CS%d (0x%08lx), va %p, %s mode\n",
+		 c->gpmc_cs, c->phys_base, c->onenand.base,
+		 c->dma_chan ? "DMA" : "PIO");
 
 	if ((r = onenand_scan(&c->mtd, 1)) < 0)
 		goto err_release_dma;
 
+	freq = omap2_onenand_get_freq(c->onenand.version_id);
+	if (freq > 0) {
+		switch (freq) {
+		case 104:
+			latency = 7;
+			break;
+		case 83:
+			latency = 6;
+			break;
+		case 66:
+			latency = 5;
+			break;
+		case 56:
+			latency = 4;
+			break;
+		default:	/* 40 MHz or lower */
+			latency = 3;
+			break;
+		}
+
+		r = gpmc_omap_onenand_set_timings(dev, c->gpmc_cs,
+						  freq, latency, &info);
+		if (r)
+			goto err_release_onenand;
+
+		r = omap2_onenand_set_cfg(c, info.sync_read, info.sync_write,
+					  latency, info.burst_len);
+		if (r)
+			goto err_release_onenand;
+
+		if (info.sync_read || info.sync_write)
+			dev_info(dev, "optimized timings for %d MHz\n", freq);
+	}
+
 	r = mtd_device_register(&c->mtd, NULL, 0);
 	if (r)
 		goto err_release_onenand;
@@ -561,17 +632,6 @@ static int omap2_onenand_probe(struct platform_device *pdev)
 err_release_dma:
 	if (c->dma_chan)
 		dma_release_channel(c->dma_chan);
-	if (c->gpio_irq)
-		free_irq(gpio_to_irq(c->gpio_irq), c);
-err_release_gpio:
-	if (c->gpio_irq)
-		gpio_free(c->gpio_irq);
-err_iounmap:
-	iounmap(c->onenand.base);
-err_release_mem_region:
-	release_mem_region(c->phys_base, c->mem_size);
-err_kfree:
-	kfree(c);
 
 	return r;
 }
@@ -584,23 +644,23 @@ static int omap2_onenand_remove(struct platform_device *pdev)
 	if (c->dma_chan)
 		dma_release_channel(c->dma_chan);
 	omap2_onenand_shutdown(pdev);
-	if (c->gpio_irq) {
-		free_irq(gpio_to_irq(c->gpio_irq), c);
-		gpio_free(c->gpio_irq);
-	}
-	iounmap(c->onenand.base);
-	release_mem_region(c->phys_base, c->mem_size);
-	kfree(c);
 
 	return 0;
 }
 
+static const struct of_device_id omap2_onenand_id_table[] = {
+	{ .compatible = "ti,omap2-onenand", },
+	{},
+};
+MODULE_DEVICE_TABLE(of, omap2_onenand_id_table);
+
 static struct platform_driver omap2_onenand_driver = {
 	.probe		= omap2_onenand_probe,
 	.remove		= omap2_onenand_remove,
 	.shutdown	= omap2_onenand_shutdown,
 	.driver		= {
 		.name	= DRIVER_NAME,
+		.of_match_table = omap2_onenand_id_table,
 	},
 };
 
-- 
2.11.0

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

* [PATCH v4 15/16] ARM: OMAP2+: Remove gpmc-onenand
  2017-11-11 21:12 ` Ladislav Michl
@ 2017-11-11 21:29   ` Ladislav Michl
  -1 siblings, 0 replies; 114+ messages in thread
From: Ladislav Michl @ 2017-11-11 21:29 UTC (permalink / raw)
  To: linux-mtd, linux-omap
  Cc: Tony Lindgren, Peter Ujfalusi, Kyungmin Park, Boris Brezillon,
	Roger Quadros

As OneNAND driver is now using devicetree gpmc-onenand and its
platform data is unused and can be removed.

Signed-off-by: Ladislav Michl <ladis@linux-mips.org>
---
 Changes:
 -v4: new patch

 arch/arm/mach-omap2/Makefile                    |   3 -
 arch/arm/mach-omap2/gpmc-onenand.c              | 409 ------------------------
 include/linux/platform_data/mtd-onenand-omap2.h |  34 --
 3 files changed, 446 deletions(-)

diff --git a/arch/arm/mach-omap2/Makefile b/arch/arm/mach-omap2/Makefile
index 38f1748a4500..e0306d3df41a 100644
--- a/arch/arm/mach-omap2/Makefile
+++ b/arch/arm/mach-omap2/Makefile
@@ -235,6 +235,3 @@ obj-y					+= $(omap-hsmmc-m) $(omap-hsmmc-y)
 obj-y					+= omap_phy_internal.o
 
 obj-$(CONFIG_MACH_OMAP2_TUSB6010)	+= usb-tusb6010.o
-
-onenand-$(CONFIG_MTD_ONENAND_OMAP2)	:= gpmc-onenand.o
-obj-y					+= $(onenand-m) $(onenand-y)
diff --git a/arch/arm/mach-omap2/gpmc-onenand.c b/arch/arm/mach-omap2/gpmc-onenand.c
deleted file mode 100644
index 2944af820558..000000000000
--- a/arch/arm/mach-omap2/gpmc-onenand.c
+++ /dev/null
@@ -1,409 +0,0 @@
-/*
- * linux/arch/arm/mach-omap2/gpmc-onenand.c
- *
- * Copyright (C) 2006 - 2009 Nokia Corporation
- * Contacts:	Juha Yrjola
- *		Tony Lindgren
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/string.h>
-#include <linux/kernel.h>
-#include <linux/platform_device.h>
-#include <linux/mtd/onenand_regs.h>
-#include <linux/io.h>
-#include <linux/omap-gpmc.h>
-#include <linux/platform_data/mtd-onenand-omap2.h>
-#include <linux/err.h>
-
-#include <asm/mach/flash.h>
-
-#include "soc.h"
-
-#define	ONENAND_IO_SIZE	SZ_128K
-
-#define	ONENAND_FLAG_SYNCREAD	(1 << 0)
-#define	ONENAND_FLAG_SYNCWRITE	(1 << 1)
-#define	ONENAND_FLAG_HF		(1 << 2)
-#define	ONENAND_FLAG_VHF	(1 << 3)
-
-static unsigned onenand_flags;
-static unsigned latency;
-
-static struct omap_onenand_platform_data *gpmc_onenand_data;
-
-static struct resource gpmc_onenand_resource = {
-	.flags		= IORESOURCE_MEM,
-};
-
-static struct platform_device gpmc_onenand_device = {
-	.name		= "omap2-onenand",
-	.id		= -1,
-	.num_resources	= 1,
-	.resource	= &gpmc_onenand_resource,
-};
-
-static struct gpmc_settings onenand_async = {
-	.device_width	= GPMC_DEVWIDTH_16BIT,
-	.mux_add_data	= GPMC_MUX_AD,
-};
-
-static struct gpmc_settings onenand_sync = {
-	.burst_read	= true,
-	.burst_wrap	= true,
-	.burst_len	= GPMC_BURST_16,
-	.device_width	= GPMC_DEVWIDTH_16BIT,
-	.mux_add_data	= GPMC_MUX_AD,
-	.wait_pin	= 0,
-};
-
-static void omap2_onenand_calc_async_timings(struct gpmc_timings *t)
-{
-	struct gpmc_device_timings dev_t;
-	const int t_cer = 15;
-	const int t_avdp = 12;
-	const int t_aavdh = 7;
-	const int t_ce = 76;
-	const int t_aa = 76;
-	const int t_oe = 20;
-	const int t_cez = 20; /* max of t_cez, t_oez */
-	const int t_wpl = 40;
-	const int t_wph = 30;
-
-	memset(&dev_t, 0, sizeof(dev_t));
-
-	dev_t.t_avdp_r = max_t(int, t_avdp, t_cer) * 1000;
-	dev_t.t_avdp_w = dev_t.t_avdp_r;
-	dev_t.t_aavdh = t_aavdh * 1000;
-	dev_t.t_aa = t_aa * 1000;
-	dev_t.t_ce = t_ce * 1000;
-	dev_t.t_oe = t_oe * 1000;
-	dev_t.t_cez_r = t_cez * 1000;
-	dev_t.t_cez_w = dev_t.t_cez_r;
-	dev_t.t_wpl = t_wpl * 1000;
-	dev_t.t_wph = t_wph * 1000;
-
-	gpmc_calc_timings(t, &onenand_async, &dev_t);
-}
-
-static void omap2_onenand_set_async_mode(void __iomem *onenand_base)
-{
-	u32 reg;
-
-	/* Ensure sync read and sync write are disabled */
-	reg = readw(onenand_base + ONENAND_REG_SYS_CFG1);
-	reg &= ~ONENAND_SYS_CFG1_SYNC_READ & ~ONENAND_SYS_CFG1_SYNC_WRITE;
-	writew(reg, onenand_base + ONENAND_REG_SYS_CFG1);
-}
-
-static void set_onenand_cfg(void __iomem *onenand_base)
-{
-	u32 reg = ONENAND_SYS_CFG1_RDY | ONENAND_SYS_CFG1_INT;
-
-	reg |=	(latency << ONENAND_SYS_CFG1_BRL_SHIFT) |
-		ONENAND_SYS_CFG1_BL_16;
-	if (onenand_flags & ONENAND_FLAG_SYNCREAD)
-		reg |= ONENAND_SYS_CFG1_SYNC_READ;
-	else
-		reg &= ~ONENAND_SYS_CFG1_SYNC_READ;
-	if (onenand_flags & ONENAND_FLAG_SYNCWRITE)
-		reg |= ONENAND_SYS_CFG1_SYNC_WRITE;
-	else
-		reg &= ~ONENAND_SYS_CFG1_SYNC_WRITE;
-	if (onenand_flags & ONENAND_FLAG_HF)
-		reg |= ONENAND_SYS_CFG1_HF;
-	else
-		reg &= ~ONENAND_SYS_CFG1_HF;
-	if (onenand_flags & ONENAND_FLAG_VHF)
-		reg |= ONENAND_SYS_CFG1_VHF;
-	else
-		reg &= ~ONENAND_SYS_CFG1_VHF;
-
-	writew(reg, onenand_base + ONENAND_REG_SYS_CFG1);
-}
-
-static int omap2_onenand_get_freq(struct omap_onenand_platform_data *cfg,
-				  void __iomem *onenand_base)
-{
-	u16 ver = readw(onenand_base + ONENAND_REG_VERSION_ID);
-	int freq;
-
-	switch ((ver >> 4) & 0xf) {
-	case 0:
-		freq = 40;
-		break;
-	case 1:
-		freq = 54;
-		break;
-	case 2:
-		freq = 66;
-		break;
-	case 3:
-		freq = 83;
-		break;
-	case 4:
-		freq = 104;
-		break;
-	default:
-		pr_err("onenand rate not detected, bad GPMC async timings?\n");
-		freq = 0;
-	}
-
-	return freq;
-}
-
-static void omap2_onenand_calc_sync_timings(struct gpmc_timings *t,
-					    unsigned int flags,
-					    int freq)
-{
-	struct gpmc_device_timings dev_t;
-	const int t_cer  = 15;
-	const int t_avdp = 12;
-	const int t_cez  = 20; /* max of t_cez, t_oez */
-	const int t_wpl  = 40;
-	const int t_wph  = 30;
-	int min_gpmc_clk_period, t_ces, t_avds, t_avdh, t_ach, t_aavdh, t_rdyo;
-	int div, gpmc_clk_ns;
-
-	if (flags & ONENAND_SYNC_READ)
-		onenand_flags = ONENAND_FLAG_SYNCREAD;
-	else if (flags & ONENAND_SYNC_READWRITE)
-		onenand_flags = ONENAND_FLAG_SYNCREAD | ONENAND_FLAG_SYNCWRITE;
-
-	switch (freq) {
-	case 104:
-		min_gpmc_clk_period = 9600; /* 104 MHz */
-		t_ces   = 3;
-		t_avds  = 4;
-		t_avdh  = 2;
-		t_ach   = 3;
-		t_aavdh = 6;
-		t_rdyo  = 6;
-		break;
-	case 83:
-		min_gpmc_clk_period = 12000; /* 83 MHz */
-		t_ces   = 5;
-		t_avds  = 4;
-		t_avdh  = 2;
-		t_ach   = 6;
-		t_aavdh = 6;
-		t_rdyo  = 9;
-		break;
-	case 66:
-		min_gpmc_clk_period = 15000; /* 66 MHz */
-		t_ces   = 6;
-		t_avds  = 5;
-		t_avdh  = 2;
-		t_ach   = 6;
-		t_aavdh = 6;
-		t_rdyo  = 11;
-		break;
-	default:
-		min_gpmc_clk_period = 18500; /* 54 MHz */
-		t_ces   = 7;
-		t_avds  = 7;
-		t_avdh  = 7;
-		t_ach   = 9;
-		t_aavdh = 7;
-		t_rdyo  = 15;
-		onenand_flags &= ~ONENAND_FLAG_SYNCWRITE;
-		break;
-	}
-
-	div = gpmc_calc_divider(min_gpmc_clk_period);
-	gpmc_clk_ns = gpmc_ticks_to_ns(div);
-	if (gpmc_clk_ns < 15) /* >66MHz */
-		onenand_flags |= ONENAND_FLAG_HF;
-	else
-		onenand_flags &= ~ONENAND_FLAG_HF;
-	if (gpmc_clk_ns < 12) /* >83MHz */
-		onenand_flags |= ONENAND_FLAG_VHF;
-	else
-		onenand_flags &= ~ONENAND_FLAG_VHF;
-	if (onenand_flags & ONENAND_FLAG_VHF)
-		latency = 8;
-	else if (onenand_flags & ONENAND_FLAG_HF)
-		latency = 6;
-	else if (gpmc_clk_ns >= 25) /* 40 MHz*/
-		latency = 3;
-	else
-		latency = 4;
-
-	/* Set synchronous read timings */
-	memset(&dev_t, 0, sizeof(dev_t));
-
-	if (onenand_flags & ONENAND_FLAG_SYNCREAD)
-		onenand_sync.sync_read = true;
-	if (onenand_flags & ONENAND_FLAG_SYNCWRITE) {
-		onenand_sync.sync_write = true;
-		onenand_sync.burst_write = true;
-	} else {
-		dev_t.t_avdp_w = max(t_avdp, t_cer) * 1000;
-		dev_t.t_wpl = t_wpl * 1000;
-		dev_t.t_wph = t_wph * 1000;
-		dev_t.t_aavdh = t_aavdh * 1000;
-	}
-	dev_t.ce_xdelay = true;
-	dev_t.avd_xdelay = true;
-	dev_t.oe_xdelay = true;
-	dev_t.we_xdelay = true;
-	dev_t.clk = min_gpmc_clk_period;
-	dev_t.t_bacc = dev_t.clk;
-	dev_t.t_ces = t_ces * 1000;
-	dev_t.t_avds = t_avds * 1000;
-	dev_t.t_avdh = t_avdh * 1000;
-	dev_t.t_ach = t_ach * 1000;
-	dev_t.cyc_iaa = (latency + 1);
-	dev_t.t_cez_r = t_cez * 1000;
-	dev_t.t_cez_w = dev_t.t_cez_r;
-	dev_t.cyc_aavdh_oe = 1;
-	dev_t.t_rdyo = t_rdyo * 1000 + min_gpmc_clk_period;
-
-	gpmc_calc_timings(t, &onenand_sync, &dev_t);
-}
-
-static int omap2_onenand_setup_async(void __iomem *onenand_base)
-{
-	struct gpmc_timings t;
-	int ret;
-
-	/*
-	 * Note that we need to keep sync_write set for the call to
-	 * omap2_onenand_set_async_mode() to work to detect the onenand
-	 * supported clock rate for the sync timings.
-	 */
-	if (gpmc_onenand_data->of_node) {
-		gpmc_read_settings_dt(gpmc_onenand_data->of_node,
-				      &onenand_async);
-		if (onenand_async.sync_read || onenand_async.sync_write) {
-			if (onenand_async.sync_write)
-				gpmc_onenand_data->flags |=
-					ONENAND_SYNC_READWRITE;
-			else
-				gpmc_onenand_data->flags |= ONENAND_SYNC_READ;
-			onenand_async.sync_read = false;
-		}
-	}
-
-	onenand_async.sync_write = true;
-	omap2_onenand_calc_async_timings(&t);
-
-	ret = gpmc_cs_program_settings(gpmc_onenand_data->cs, &onenand_async);
-	if (ret < 0)
-		return ret;
-
-	ret = gpmc_cs_set_timings(gpmc_onenand_data->cs, &t, &onenand_async);
-	if (ret < 0)
-		return ret;
-
-	omap2_onenand_set_async_mode(onenand_base);
-
-	return 0;
-}
-
-static int omap2_onenand_setup_sync(void __iomem *onenand_base, int *freq_ptr)
-{
-	int ret, freq = *freq_ptr;
-	struct gpmc_timings t;
-
-	if (!freq) {
-		/* Very first call freq is not known */
-		freq = omap2_onenand_get_freq(gpmc_onenand_data, onenand_base);
-		if (!freq)
-			return -ENODEV;
-		set_onenand_cfg(onenand_base);
-	}
-
-	if (gpmc_onenand_data->of_node) {
-		gpmc_read_settings_dt(gpmc_onenand_data->of_node,
-				      &onenand_sync);
-	} else {
-		/*
-		 * FIXME: Appears to be legacy code from initial ONENAND commit.
-		 * Unclear what boards this is for and if this can be removed.
-		 */
-		if (!cpu_is_omap34xx())
-			onenand_sync.wait_on_read = true;
-	}
-
-	omap2_onenand_calc_sync_timings(&t, gpmc_onenand_data->flags, freq);
-
-	ret = gpmc_cs_program_settings(gpmc_onenand_data->cs, &onenand_sync);
-	if (ret < 0)
-		return ret;
-
-	ret = gpmc_cs_set_timings(gpmc_onenand_data->cs, &t, &onenand_sync);
-	if (ret < 0)
-		return ret;
-
-	set_onenand_cfg(onenand_base);
-
-	*freq_ptr = freq;
-
-	return 0;
-}
-
-static int gpmc_onenand_setup(void __iomem *onenand_base, int *freq_ptr)
-{
-	struct device *dev = &gpmc_onenand_device.dev;
-	unsigned l = ONENAND_SYNC_READ | ONENAND_SYNC_READWRITE;
-	int ret;
-
-	ret = omap2_onenand_setup_async(onenand_base);
-	if (ret) {
-		dev_err(dev, "unable to set to async mode\n");
-		return ret;
-	}
-
-	if (!(gpmc_onenand_data->flags & l))
-		return 0;
-
-	ret = omap2_onenand_setup_sync(onenand_base, freq_ptr);
-	if (ret)
-		dev_err(dev, "unable to set to sync mode\n");
-	return ret;
-}
-
-int gpmc_onenand_init(struct omap_onenand_platform_data *_onenand_data)
-{
-	int err;
-	struct device *dev = &gpmc_onenand_device.dev;
-
-	gpmc_onenand_data = _onenand_data;
-	gpmc_onenand_data->onenand_setup = gpmc_onenand_setup;
-	gpmc_onenand_device.dev.platform_data = gpmc_onenand_data;
-
-	if (cpu_is_omap24xx() &&
-			(gpmc_onenand_data->flags & ONENAND_SYNC_READWRITE)) {
-		dev_warn(dev, "OneNAND using only SYNC_READ on 24xx\n");
-		gpmc_onenand_data->flags &= ~ONENAND_SYNC_READWRITE;
-		gpmc_onenand_data->flags |= ONENAND_SYNC_READ;
-	}
-
-	if (cpu_is_omap34xx())
-		gpmc_onenand_data->flags |= ONENAND_IN_OMAP34XX;
-	else
-		gpmc_onenand_data->flags &= ~ONENAND_IN_OMAP34XX;
-
-	err = gpmc_cs_request(gpmc_onenand_data->cs, ONENAND_IO_SIZE,
-				(unsigned long *)&gpmc_onenand_resource.start);
-	if (err < 0) {
-		dev_err(dev, "Cannot request GPMC CS %d, error %d\n",
-			gpmc_onenand_data->cs, err);
-		return err;
-	}
-
-	gpmc_onenand_resource.end = gpmc_onenand_resource.start +
-							ONENAND_IO_SIZE - 1;
-
-	err = platform_device_register(&gpmc_onenand_device);
-	if (err) {
-		dev_err(dev, "Unable to register OneNAND device\n");
-		gpmc_cs_free(gpmc_onenand_data->cs);
-	}
-
-	return err;
-}
diff --git a/include/linux/platform_data/mtd-onenand-omap2.h b/include/linux/platform_data/mtd-onenand-omap2.h
deleted file mode 100644
index 56ff0e6f5ad1..000000000000
--- a/include/linux/platform_data/mtd-onenand-omap2.h
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Copyright (C) 2006 Nokia Corporation
- * Author: Juha Yrjola
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#ifndef	__MTD_ONENAND_OMAP2_H
-#define	__MTD_ONENAND_OMAP2_H
-
-#include <linux/mtd/mtd.h>
-#include <linux/mtd/partitions.h>
-
-#define ONENAND_SYNC_READ	(1 << 0)
-#define ONENAND_SYNC_READWRITE	(1 << 1)
-#define	ONENAND_IN_OMAP34XX	(1 << 2)
-
-struct omap_onenand_platform_data {
-	int			cs;
-	int			gpio_irq;
-	struct mtd_partition	*parts;
-	int			nr_parts;
-	int			(*onenand_setup)(void __iomem *, int *freq_ptr);
-	int			dma_channel;
-	u8			flags;
-	u8			regulator_can_sleep;
-	u8			skip_initial_unlocking;
-
-	/* for passing the partitions */
-	struct device_node	*of_node;
-};
-#endif
-- 
2.11.0


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

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

* [PATCH v4 15/16] ARM: OMAP2+: Remove gpmc-onenand
@ 2017-11-11 21:29   ` Ladislav Michl
  0 siblings, 0 replies; 114+ messages in thread
From: Ladislav Michl @ 2017-11-11 21:29 UTC (permalink / raw)
  To: linux-mtd, linux-omap
  Cc: Roger Quadros, Tony Lindgren, Peter Ujfalusi, Boris Brezillon,
	Kyungmin Park

As OneNAND driver is now using devicetree gpmc-onenand and its
platform data is unused and can be removed.

Signed-off-by: Ladislav Michl <ladis@linux-mips.org>
---
 Changes:
 -v4: new patch

 arch/arm/mach-omap2/Makefile                    |   3 -
 arch/arm/mach-omap2/gpmc-onenand.c              | 409 ------------------------
 include/linux/platform_data/mtd-onenand-omap2.h |  34 --
 3 files changed, 446 deletions(-)

diff --git a/arch/arm/mach-omap2/Makefile b/arch/arm/mach-omap2/Makefile
index 38f1748a4500..e0306d3df41a 100644
--- a/arch/arm/mach-omap2/Makefile
+++ b/arch/arm/mach-omap2/Makefile
@@ -235,6 +235,3 @@ obj-y					+= $(omap-hsmmc-m) $(omap-hsmmc-y)
 obj-y					+= omap_phy_internal.o
 
 obj-$(CONFIG_MACH_OMAP2_TUSB6010)	+= usb-tusb6010.o
-
-onenand-$(CONFIG_MTD_ONENAND_OMAP2)	:= gpmc-onenand.o
-obj-y					+= $(onenand-m) $(onenand-y)
diff --git a/arch/arm/mach-omap2/gpmc-onenand.c b/arch/arm/mach-omap2/gpmc-onenand.c
deleted file mode 100644
index 2944af820558..000000000000
--- a/arch/arm/mach-omap2/gpmc-onenand.c
+++ /dev/null
@@ -1,409 +0,0 @@
-/*
- * linux/arch/arm/mach-omap2/gpmc-onenand.c
- *
- * Copyright (C) 2006 - 2009 Nokia Corporation
- * Contacts:	Juha Yrjola
- *		Tony Lindgren
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/string.h>
-#include <linux/kernel.h>
-#include <linux/platform_device.h>
-#include <linux/mtd/onenand_regs.h>
-#include <linux/io.h>
-#include <linux/omap-gpmc.h>
-#include <linux/platform_data/mtd-onenand-omap2.h>
-#include <linux/err.h>
-
-#include <asm/mach/flash.h>
-
-#include "soc.h"
-
-#define	ONENAND_IO_SIZE	SZ_128K
-
-#define	ONENAND_FLAG_SYNCREAD	(1 << 0)
-#define	ONENAND_FLAG_SYNCWRITE	(1 << 1)
-#define	ONENAND_FLAG_HF		(1 << 2)
-#define	ONENAND_FLAG_VHF	(1 << 3)
-
-static unsigned onenand_flags;
-static unsigned latency;
-
-static struct omap_onenand_platform_data *gpmc_onenand_data;
-
-static struct resource gpmc_onenand_resource = {
-	.flags		= IORESOURCE_MEM,
-};
-
-static struct platform_device gpmc_onenand_device = {
-	.name		= "omap2-onenand",
-	.id		= -1,
-	.num_resources	= 1,
-	.resource	= &gpmc_onenand_resource,
-};
-
-static struct gpmc_settings onenand_async = {
-	.device_width	= GPMC_DEVWIDTH_16BIT,
-	.mux_add_data	= GPMC_MUX_AD,
-};
-
-static struct gpmc_settings onenand_sync = {
-	.burst_read	= true,
-	.burst_wrap	= true,
-	.burst_len	= GPMC_BURST_16,
-	.device_width	= GPMC_DEVWIDTH_16BIT,
-	.mux_add_data	= GPMC_MUX_AD,
-	.wait_pin	= 0,
-};
-
-static void omap2_onenand_calc_async_timings(struct gpmc_timings *t)
-{
-	struct gpmc_device_timings dev_t;
-	const int t_cer = 15;
-	const int t_avdp = 12;
-	const int t_aavdh = 7;
-	const int t_ce = 76;
-	const int t_aa = 76;
-	const int t_oe = 20;
-	const int t_cez = 20; /* max of t_cez, t_oez */
-	const int t_wpl = 40;
-	const int t_wph = 30;
-
-	memset(&dev_t, 0, sizeof(dev_t));
-
-	dev_t.t_avdp_r = max_t(int, t_avdp, t_cer) * 1000;
-	dev_t.t_avdp_w = dev_t.t_avdp_r;
-	dev_t.t_aavdh = t_aavdh * 1000;
-	dev_t.t_aa = t_aa * 1000;
-	dev_t.t_ce = t_ce * 1000;
-	dev_t.t_oe = t_oe * 1000;
-	dev_t.t_cez_r = t_cez * 1000;
-	dev_t.t_cez_w = dev_t.t_cez_r;
-	dev_t.t_wpl = t_wpl * 1000;
-	dev_t.t_wph = t_wph * 1000;
-
-	gpmc_calc_timings(t, &onenand_async, &dev_t);
-}
-
-static void omap2_onenand_set_async_mode(void __iomem *onenand_base)
-{
-	u32 reg;
-
-	/* Ensure sync read and sync write are disabled */
-	reg = readw(onenand_base + ONENAND_REG_SYS_CFG1);
-	reg &= ~ONENAND_SYS_CFG1_SYNC_READ & ~ONENAND_SYS_CFG1_SYNC_WRITE;
-	writew(reg, onenand_base + ONENAND_REG_SYS_CFG1);
-}
-
-static void set_onenand_cfg(void __iomem *onenand_base)
-{
-	u32 reg = ONENAND_SYS_CFG1_RDY | ONENAND_SYS_CFG1_INT;
-
-	reg |=	(latency << ONENAND_SYS_CFG1_BRL_SHIFT) |
-		ONENAND_SYS_CFG1_BL_16;
-	if (onenand_flags & ONENAND_FLAG_SYNCREAD)
-		reg |= ONENAND_SYS_CFG1_SYNC_READ;
-	else
-		reg &= ~ONENAND_SYS_CFG1_SYNC_READ;
-	if (onenand_flags & ONENAND_FLAG_SYNCWRITE)
-		reg |= ONENAND_SYS_CFG1_SYNC_WRITE;
-	else
-		reg &= ~ONENAND_SYS_CFG1_SYNC_WRITE;
-	if (onenand_flags & ONENAND_FLAG_HF)
-		reg |= ONENAND_SYS_CFG1_HF;
-	else
-		reg &= ~ONENAND_SYS_CFG1_HF;
-	if (onenand_flags & ONENAND_FLAG_VHF)
-		reg |= ONENAND_SYS_CFG1_VHF;
-	else
-		reg &= ~ONENAND_SYS_CFG1_VHF;
-
-	writew(reg, onenand_base + ONENAND_REG_SYS_CFG1);
-}
-
-static int omap2_onenand_get_freq(struct omap_onenand_platform_data *cfg,
-				  void __iomem *onenand_base)
-{
-	u16 ver = readw(onenand_base + ONENAND_REG_VERSION_ID);
-	int freq;
-
-	switch ((ver >> 4) & 0xf) {
-	case 0:
-		freq = 40;
-		break;
-	case 1:
-		freq = 54;
-		break;
-	case 2:
-		freq = 66;
-		break;
-	case 3:
-		freq = 83;
-		break;
-	case 4:
-		freq = 104;
-		break;
-	default:
-		pr_err("onenand rate not detected, bad GPMC async timings?\n");
-		freq = 0;
-	}
-
-	return freq;
-}
-
-static void omap2_onenand_calc_sync_timings(struct gpmc_timings *t,
-					    unsigned int flags,
-					    int freq)
-{
-	struct gpmc_device_timings dev_t;
-	const int t_cer  = 15;
-	const int t_avdp = 12;
-	const int t_cez  = 20; /* max of t_cez, t_oez */
-	const int t_wpl  = 40;
-	const int t_wph  = 30;
-	int min_gpmc_clk_period, t_ces, t_avds, t_avdh, t_ach, t_aavdh, t_rdyo;
-	int div, gpmc_clk_ns;
-
-	if (flags & ONENAND_SYNC_READ)
-		onenand_flags = ONENAND_FLAG_SYNCREAD;
-	else if (flags & ONENAND_SYNC_READWRITE)
-		onenand_flags = ONENAND_FLAG_SYNCREAD | ONENAND_FLAG_SYNCWRITE;
-
-	switch (freq) {
-	case 104:
-		min_gpmc_clk_period = 9600; /* 104 MHz */
-		t_ces   = 3;
-		t_avds  = 4;
-		t_avdh  = 2;
-		t_ach   = 3;
-		t_aavdh = 6;
-		t_rdyo  = 6;
-		break;
-	case 83:
-		min_gpmc_clk_period = 12000; /* 83 MHz */
-		t_ces   = 5;
-		t_avds  = 4;
-		t_avdh  = 2;
-		t_ach   = 6;
-		t_aavdh = 6;
-		t_rdyo  = 9;
-		break;
-	case 66:
-		min_gpmc_clk_period = 15000; /* 66 MHz */
-		t_ces   = 6;
-		t_avds  = 5;
-		t_avdh  = 2;
-		t_ach   = 6;
-		t_aavdh = 6;
-		t_rdyo  = 11;
-		break;
-	default:
-		min_gpmc_clk_period = 18500; /* 54 MHz */
-		t_ces   = 7;
-		t_avds  = 7;
-		t_avdh  = 7;
-		t_ach   = 9;
-		t_aavdh = 7;
-		t_rdyo  = 15;
-		onenand_flags &= ~ONENAND_FLAG_SYNCWRITE;
-		break;
-	}
-
-	div = gpmc_calc_divider(min_gpmc_clk_period);
-	gpmc_clk_ns = gpmc_ticks_to_ns(div);
-	if (gpmc_clk_ns < 15) /* >66MHz */
-		onenand_flags |= ONENAND_FLAG_HF;
-	else
-		onenand_flags &= ~ONENAND_FLAG_HF;
-	if (gpmc_clk_ns < 12) /* >83MHz */
-		onenand_flags |= ONENAND_FLAG_VHF;
-	else
-		onenand_flags &= ~ONENAND_FLAG_VHF;
-	if (onenand_flags & ONENAND_FLAG_VHF)
-		latency = 8;
-	else if (onenand_flags & ONENAND_FLAG_HF)
-		latency = 6;
-	else if (gpmc_clk_ns >= 25) /* 40 MHz*/
-		latency = 3;
-	else
-		latency = 4;
-
-	/* Set synchronous read timings */
-	memset(&dev_t, 0, sizeof(dev_t));
-
-	if (onenand_flags & ONENAND_FLAG_SYNCREAD)
-		onenand_sync.sync_read = true;
-	if (onenand_flags & ONENAND_FLAG_SYNCWRITE) {
-		onenand_sync.sync_write = true;
-		onenand_sync.burst_write = true;
-	} else {
-		dev_t.t_avdp_w = max(t_avdp, t_cer) * 1000;
-		dev_t.t_wpl = t_wpl * 1000;
-		dev_t.t_wph = t_wph * 1000;
-		dev_t.t_aavdh = t_aavdh * 1000;
-	}
-	dev_t.ce_xdelay = true;
-	dev_t.avd_xdelay = true;
-	dev_t.oe_xdelay = true;
-	dev_t.we_xdelay = true;
-	dev_t.clk = min_gpmc_clk_period;
-	dev_t.t_bacc = dev_t.clk;
-	dev_t.t_ces = t_ces * 1000;
-	dev_t.t_avds = t_avds * 1000;
-	dev_t.t_avdh = t_avdh * 1000;
-	dev_t.t_ach = t_ach * 1000;
-	dev_t.cyc_iaa = (latency + 1);
-	dev_t.t_cez_r = t_cez * 1000;
-	dev_t.t_cez_w = dev_t.t_cez_r;
-	dev_t.cyc_aavdh_oe = 1;
-	dev_t.t_rdyo = t_rdyo * 1000 + min_gpmc_clk_period;
-
-	gpmc_calc_timings(t, &onenand_sync, &dev_t);
-}
-
-static int omap2_onenand_setup_async(void __iomem *onenand_base)
-{
-	struct gpmc_timings t;
-	int ret;
-
-	/*
-	 * Note that we need to keep sync_write set for the call to
-	 * omap2_onenand_set_async_mode() to work to detect the onenand
-	 * supported clock rate for the sync timings.
-	 */
-	if (gpmc_onenand_data->of_node) {
-		gpmc_read_settings_dt(gpmc_onenand_data->of_node,
-				      &onenand_async);
-		if (onenand_async.sync_read || onenand_async.sync_write) {
-			if (onenand_async.sync_write)
-				gpmc_onenand_data->flags |=
-					ONENAND_SYNC_READWRITE;
-			else
-				gpmc_onenand_data->flags |= ONENAND_SYNC_READ;
-			onenand_async.sync_read = false;
-		}
-	}
-
-	onenand_async.sync_write = true;
-	omap2_onenand_calc_async_timings(&t);
-
-	ret = gpmc_cs_program_settings(gpmc_onenand_data->cs, &onenand_async);
-	if (ret < 0)
-		return ret;
-
-	ret = gpmc_cs_set_timings(gpmc_onenand_data->cs, &t, &onenand_async);
-	if (ret < 0)
-		return ret;
-
-	omap2_onenand_set_async_mode(onenand_base);
-
-	return 0;
-}
-
-static int omap2_onenand_setup_sync(void __iomem *onenand_base, int *freq_ptr)
-{
-	int ret, freq = *freq_ptr;
-	struct gpmc_timings t;
-
-	if (!freq) {
-		/* Very first call freq is not known */
-		freq = omap2_onenand_get_freq(gpmc_onenand_data, onenand_base);
-		if (!freq)
-			return -ENODEV;
-		set_onenand_cfg(onenand_base);
-	}
-
-	if (gpmc_onenand_data->of_node) {
-		gpmc_read_settings_dt(gpmc_onenand_data->of_node,
-				      &onenand_sync);
-	} else {
-		/*
-		 * FIXME: Appears to be legacy code from initial ONENAND commit.
-		 * Unclear what boards this is for and if this can be removed.
-		 */
-		if (!cpu_is_omap34xx())
-			onenand_sync.wait_on_read = true;
-	}
-
-	omap2_onenand_calc_sync_timings(&t, gpmc_onenand_data->flags, freq);
-
-	ret = gpmc_cs_program_settings(gpmc_onenand_data->cs, &onenand_sync);
-	if (ret < 0)
-		return ret;
-
-	ret = gpmc_cs_set_timings(gpmc_onenand_data->cs, &t, &onenand_sync);
-	if (ret < 0)
-		return ret;
-
-	set_onenand_cfg(onenand_base);
-
-	*freq_ptr = freq;
-
-	return 0;
-}
-
-static int gpmc_onenand_setup(void __iomem *onenand_base, int *freq_ptr)
-{
-	struct device *dev = &gpmc_onenand_device.dev;
-	unsigned l = ONENAND_SYNC_READ | ONENAND_SYNC_READWRITE;
-	int ret;
-
-	ret = omap2_onenand_setup_async(onenand_base);
-	if (ret) {
-		dev_err(dev, "unable to set to async mode\n");
-		return ret;
-	}
-
-	if (!(gpmc_onenand_data->flags & l))
-		return 0;
-
-	ret = omap2_onenand_setup_sync(onenand_base, freq_ptr);
-	if (ret)
-		dev_err(dev, "unable to set to sync mode\n");
-	return ret;
-}
-
-int gpmc_onenand_init(struct omap_onenand_platform_data *_onenand_data)
-{
-	int err;
-	struct device *dev = &gpmc_onenand_device.dev;
-
-	gpmc_onenand_data = _onenand_data;
-	gpmc_onenand_data->onenand_setup = gpmc_onenand_setup;
-	gpmc_onenand_device.dev.platform_data = gpmc_onenand_data;
-
-	if (cpu_is_omap24xx() &&
-			(gpmc_onenand_data->flags & ONENAND_SYNC_READWRITE)) {
-		dev_warn(dev, "OneNAND using only SYNC_READ on 24xx\n");
-		gpmc_onenand_data->flags &= ~ONENAND_SYNC_READWRITE;
-		gpmc_onenand_data->flags |= ONENAND_SYNC_READ;
-	}
-
-	if (cpu_is_omap34xx())
-		gpmc_onenand_data->flags |= ONENAND_IN_OMAP34XX;
-	else
-		gpmc_onenand_data->flags &= ~ONENAND_IN_OMAP34XX;
-
-	err = gpmc_cs_request(gpmc_onenand_data->cs, ONENAND_IO_SIZE,
-				(unsigned long *)&gpmc_onenand_resource.start);
-	if (err < 0) {
-		dev_err(dev, "Cannot request GPMC CS %d, error %d\n",
-			gpmc_onenand_data->cs, err);
-		return err;
-	}
-
-	gpmc_onenand_resource.end = gpmc_onenand_resource.start +
-							ONENAND_IO_SIZE - 1;
-
-	err = platform_device_register(&gpmc_onenand_device);
-	if (err) {
-		dev_err(dev, "Unable to register OneNAND device\n");
-		gpmc_cs_free(gpmc_onenand_data->cs);
-	}
-
-	return err;
-}
diff --git a/include/linux/platform_data/mtd-onenand-omap2.h b/include/linux/platform_data/mtd-onenand-omap2.h
deleted file mode 100644
index 56ff0e6f5ad1..000000000000
--- a/include/linux/platform_data/mtd-onenand-omap2.h
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Copyright (C) 2006 Nokia Corporation
- * Author: Juha Yrjola
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#ifndef	__MTD_ONENAND_OMAP2_H
-#define	__MTD_ONENAND_OMAP2_H
-
-#include <linux/mtd/mtd.h>
-#include <linux/mtd/partitions.h>
-
-#define ONENAND_SYNC_READ	(1 << 0)
-#define ONENAND_SYNC_READWRITE	(1 << 1)
-#define	ONENAND_IN_OMAP34XX	(1 << 2)
-
-struct omap_onenand_platform_data {
-	int			cs;
-	int			gpio_irq;
-	struct mtd_partition	*parts;
-	int			nr_parts;
-	int			(*onenand_setup)(void __iomem *, int *freq_ptr);
-	int			dma_channel;
-	u8			flags;
-	u8			regulator_can_sleep;
-	u8			skip_initial_unlocking;
-
-	/* for passing the partitions */
-	struct device_node	*of_node;
-};
-#endif
-- 
2.11.0

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

* [PATCH v4 16/16] ARM: dts: Nokia: Use R/B pin
  2017-11-11 21:12 ` Ladislav Michl
@ 2017-11-11 21:29   ` Ladislav Michl
  -1 siblings, 0 replies; 114+ messages in thread
From: Ladislav Michl @ 2017-11-11 21:29 UTC (permalink / raw)
  To: linux-mtd, linux-omap
  Cc: Tony Lindgren, Peter Ujfalusi, Kyungmin Park, Boris Brezillon,
	Roger Quadros

Enable use of R/B pin. This is just experimental placeholder patch
as it lacks pinmux settings.

Signed-off-by: Ladislav Michl <ladis@linux-mips.org>
---
 Changes:
 -v4: new patch

 arch/arm/boot/dts/omap2420-n8x0-common.dtsi | 4 +---
 arch/arm/boot/dts/omap3-n900.dts            | 1 +
 2 files changed, 2 insertions(+), 3 deletions(-)

diff --git a/arch/arm/boot/dts/omap2420-n8x0-common.dtsi b/arch/arm/boot/dts/omap2420-n8x0-common.dtsi
index 843f6a2f5e29..cfe5d02ea0ed 100644
--- a/arch/arm/boot/dts/omap2420-n8x0-common.dtsi
+++ b/arch/arm/boot/dts/omap2420-n8x0-common.dtsi
@@ -42,14 +42,12 @@
 
 &gpmc {
 	ranges = <0 0 0x04000000 0x1000000>;	/* CS0: 16MB for OneNAND */
-
-	/* gpio-irq for dma: 26 */
-
 	onenand@0,0 {
 		#address-cells = <1>;
 		#size-cells = <1>;
 		compatible = "ti,omap2-onenand";
 		reg = <0 0 0x20000>;	/* CS0, offset 0, IO size 128K */
+		rb-gpios = <&gpio0 26 GPIO_ACTIVE_HIGH>;
 
 		gpmc,sync-read;
 		gpmc,burst-length = <16>;
diff --git a/arch/arm/boot/dts/omap3-n900.dts b/arch/arm/boot/dts/omap3-n900.dts
index aa5b1a439564..718116d9f4ac 100644
--- a/arch/arm/boot/dts/omap3-n900.dts
+++ b/arch/arm/boot/dts/omap3-n900.dts
@@ -840,6 +840,7 @@
 		#size-cells = <1>;
 		compatible = "ti,omap2-onenand";
 		reg = <0 0 0x20000>;	/* CS0, offset 0, IO size 128K */
+		rb-gpios = <&gpio3 1 GPIO_ACTIVE_HIGH>;
 
 		gpmc,sync-read;
 		gpmc,sync-write;
-- 
2.11.0


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

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

* [PATCH v4 16/16] ARM: dts: Nokia: Use R/B pin
@ 2017-11-11 21:29   ` Ladislav Michl
  0 siblings, 0 replies; 114+ messages in thread
From: Ladislav Michl @ 2017-11-11 21:29 UTC (permalink / raw)
  To: linux-mtd, linux-omap
  Cc: Roger Quadros, Tony Lindgren, Peter Ujfalusi, Boris Brezillon,
	Kyungmin Park

Enable use of R/B pin. This is just experimental placeholder patch
as it lacks pinmux settings.

Signed-off-by: Ladislav Michl <ladis@linux-mips.org>
---
 Changes:
 -v4: new patch

 arch/arm/boot/dts/omap2420-n8x0-common.dtsi | 4 +---
 arch/arm/boot/dts/omap3-n900.dts            | 1 +
 2 files changed, 2 insertions(+), 3 deletions(-)

diff --git a/arch/arm/boot/dts/omap2420-n8x0-common.dtsi b/arch/arm/boot/dts/omap2420-n8x0-common.dtsi
index 843f6a2f5e29..cfe5d02ea0ed 100644
--- a/arch/arm/boot/dts/omap2420-n8x0-common.dtsi
+++ b/arch/arm/boot/dts/omap2420-n8x0-common.dtsi
@@ -42,14 +42,12 @@
 
 &gpmc {
 	ranges = <0 0 0x04000000 0x1000000>;	/* CS0: 16MB for OneNAND */
-
-	/* gpio-irq for dma: 26 */
-
 	onenand@0,0 {
 		#address-cells = <1>;
 		#size-cells = <1>;
 		compatible = "ti,omap2-onenand";
 		reg = <0 0 0x20000>;	/* CS0, offset 0, IO size 128K */
+		rb-gpios = <&gpio0 26 GPIO_ACTIVE_HIGH>;
 
 		gpmc,sync-read;
 		gpmc,burst-length = <16>;
diff --git a/arch/arm/boot/dts/omap3-n900.dts b/arch/arm/boot/dts/omap3-n900.dts
index aa5b1a439564..718116d9f4ac 100644
--- a/arch/arm/boot/dts/omap3-n900.dts
+++ b/arch/arm/boot/dts/omap3-n900.dts
@@ -840,6 +840,7 @@
 		#size-cells = <1>;
 		compatible = "ti,omap2-onenand";
 		reg = <0 0 0x20000>;	/* CS0, offset 0, IO size 128K */
+		rb-gpios = <&gpio3 1 GPIO_ACTIVE_HIGH>;
 
 		gpmc,sync-read;
 		gpmc,sync-write;
-- 
2.11.0

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

* Re: [PATCH v4 02/16] ARM: dts: OMAP2+: Add compatible property to onenand node
  2017-11-11 21:17   ` Ladislav Michl
@ 2017-11-14 15:11     ` Roger Quadros
  -1 siblings, 0 replies; 114+ messages in thread
From: Roger Quadros @ 2017-11-14 15:11 UTC (permalink / raw)
  To: Ladislav Michl, linux-mtd, linux-omap
  Cc: Tony Lindgren, Peter Ujfalusi, Kyungmin Park, Boris Brezillon


Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki. Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki

On 11/11/17 23:17, Ladislav Michl wrote:
> OMAP onenand nodes are missing compatible property, add it.
> 
> Signed-off-by: Ladislav Michl <ladis@linux-mips.org>

Acked-by: Roger Quadros <rogerq@ti.com>

How about updating bindings/mtd/gpmc-onenand.txt in a separate patch?

> ---
>  Changes:
>  -v4: new patch
> 
>  arch/arm/boot/dts/omap2420-n8x0-common.dtsi | 1 +
>  arch/arm/boot/dts/omap3-n900.dts            | 1 +
>  arch/arm/boot/dts/omap3-n950-n9.dtsi        | 1 +
>  arch/arm/boot/dts/omap3430-sdp.dts          | 1 +
>  4 files changed, 4 insertions(+)
> 
> diff --git a/arch/arm/boot/dts/omap2420-n8x0-common.dtsi b/arch/arm/boot/dts/omap2420-n8x0-common.dtsi
> index 1de80c7886ab..843f6a2f5e29 100644
> --- a/arch/arm/boot/dts/omap2420-n8x0-common.dtsi
> +++ b/arch/arm/boot/dts/omap2420-n8x0-common.dtsi
> @@ -48,6 +48,7 @@
>  	onenand@0,0 {
>  		#address-cells = <1>;
>  		#size-cells = <1>;
> +		compatible = "ti,omap2-onenand";
>  		reg = <0 0 0x20000>;	/* CS0, offset 0, IO size 128K */
>  
>  		gpmc,sync-read;
> diff --git a/arch/arm/boot/dts/omap3-n900.dts b/arch/arm/boot/dts/omap3-n900.dts
> index 4acd32a1c4ef..aa5b1a439564 100644
> --- a/arch/arm/boot/dts/omap3-n900.dts
> +++ b/arch/arm/boot/dts/omap3-n900.dts
> @@ -838,6 +838,7 @@
>  	onenand@0,0 {
>  		#address-cells = <1>;
>  		#size-cells = <1>;
> +		compatible = "ti,omap2-onenand";
>  		reg = <0 0 0x20000>;	/* CS0, offset 0, IO size 128K */
>  
>  		gpmc,sync-read;
> diff --git a/arch/arm/boot/dts/omap3-n950-n9.dtsi b/arch/arm/boot/dts/omap3-n950-n9.dtsi
> index 1b0bd72945f2..cb3c7b2fce52 100644
> --- a/arch/arm/boot/dts/omap3-n950-n9.dtsi
> +++ b/arch/arm/boot/dts/omap3-n950-n9.dtsi
> @@ -367,6 +367,7 @@
>  	onenand@0,0 {
>  		#address-cells = <1>;
>  		#size-cells = <1>;
> +		compatible = "ti,omap2-onenand";
>  		reg = <0 0 0x20000>;	/* CS0, offset 0, IO size 128K */
>  
>  		gpmc,sync-read;
> diff --git a/arch/arm/boot/dts/omap3430-sdp.dts b/arch/arm/boot/dts/omap3430-sdp.dts
> index d50a105c9dc6..ed65795ccc62 100644
> --- a/arch/arm/boot/dts/omap3430-sdp.dts
> +++ b/arch/arm/boot/dts/omap3430-sdp.dts
> @@ -155,6 +155,7 @@
>  		linux,mtd-name= "samsung,kfm2g16q2m-deb8";
>  		#address-cells = <1>;
>  		#size-cells = <1>;
> +		compatible = "ti,omap2-onenand";
>  		reg = <2 0 0x20000>;	/* CS2, offset 0, IO size 4 */
>  
>  		gpmc,device-width = <2>;
> 

-- 
cheers,
-roger

Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki. Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki


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

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

* Re: [PATCH v4 02/16] ARM: dts: OMAP2+: Add compatible property to onenand node
@ 2017-11-14 15:11     ` Roger Quadros
  0 siblings, 0 replies; 114+ messages in thread
From: Roger Quadros @ 2017-11-14 15:11 UTC (permalink / raw)
  To: Ladislav Michl, linux-mtd, linux-omap
  Cc: Tony Lindgren, Peter Ujfalusi, Boris Brezillon, Kyungmin Park


Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki. Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki

On 11/11/17 23:17, Ladislav Michl wrote:
> OMAP onenand nodes are missing compatible property, add it.
> 
> Signed-off-by: Ladislav Michl <ladis@linux-mips.org>

Acked-by: Roger Quadros <rogerq@ti.com>

How about updating bindings/mtd/gpmc-onenand.txt in a separate patch?

> ---
>  Changes:
>  -v4: new patch
> 
>  arch/arm/boot/dts/omap2420-n8x0-common.dtsi | 1 +
>  arch/arm/boot/dts/omap3-n900.dts            | 1 +
>  arch/arm/boot/dts/omap3-n950-n9.dtsi        | 1 +
>  arch/arm/boot/dts/omap3430-sdp.dts          | 1 +
>  4 files changed, 4 insertions(+)
> 
> diff --git a/arch/arm/boot/dts/omap2420-n8x0-common.dtsi b/arch/arm/boot/dts/omap2420-n8x0-common.dtsi
> index 1de80c7886ab..843f6a2f5e29 100644
> --- a/arch/arm/boot/dts/omap2420-n8x0-common.dtsi
> +++ b/arch/arm/boot/dts/omap2420-n8x0-common.dtsi
> @@ -48,6 +48,7 @@
>  	onenand@0,0 {
>  		#address-cells = <1>;
>  		#size-cells = <1>;
> +		compatible = "ti,omap2-onenand";
>  		reg = <0 0 0x20000>;	/* CS0, offset 0, IO size 128K */
>  
>  		gpmc,sync-read;
> diff --git a/arch/arm/boot/dts/omap3-n900.dts b/arch/arm/boot/dts/omap3-n900.dts
> index 4acd32a1c4ef..aa5b1a439564 100644
> --- a/arch/arm/boot/dts/omap3-n900.dts
> +++ b/arch/arm/boot/dts/omap3-n900.dts
> @@ -838,6 +838,7 @@
>  	onenand@0,0 {
>  		#address-cells = <1>;
>  		#size-cells = <1>;
> +		compatible = "ti,omap2-onenand";
>  		reg = <0 0 0x20000>;	/* CS0, offset 0, IO size 128K */
>  
>  		gpmc,sync-read;
> diff --git a/arch/arm/boot/dts/omap3-n950-n9.dtsi b/arch/arm/boot/dts/omap3-n950-n9.dtsi
> index 1b0bd72945f2..cb3c7b2fce52 100644
> --- a/arch/arm/boot/dts/omap3-n950-n9.dtsi
> +++ b/arch/arm/boot/dts/omap3-n950-n9.dtsi
> @@ -367,6 +367,7 @@
>  	onenand@0,0 {
>  		#address-cells = <1>;
>  		#size-cells = <1>;
> +		compatible = "ti,omap2-onenand";
>  		reg = <0 0 0x20000>;	/* CS0, offset 0, IO size 128K */
>  
>  		gpmc,sync-read;
> diff --git a/arch/arm/boot/dts/omap3430-sdp.dts b/arch/arm/boot/dts/omap3430-sdp.dts
> index d50a105c9dc6..ed65795ccc62 100644
> --- a/arch/arm/boot/dts/omap3430-sdp.dts
> +++ b/arch/arm/boot/dts/omap3430-sdp.dts
> @@ -155,6 +155,7 @@
>  		linux,mtd-name= "samsung,kfm2g16q2m-deb8";
>  		#address-cells = <1>;
>  		#size-cells = <1>;
> +		compatible = "ti,omap2-onenand";
>  		reg = <2 0 0x20000>;	/* CS2, offset 0, IO size 4 */
>  
>  		gpmc,device-width = <2>;
> 

-- 
cheers,
-roger

Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki. Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki

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

* Re: [PATCH v4 03/16] ARM: dts: omap3-igep: Update onenand node timings
  2017-11-11 21:18   ` Ladislav Michl
@ 2017-11-14 15:12     ` Roger Quadros
  -1 siblings, 0 replies; 114+ messages in thread
From: Roger Quadros @ 2017-11-14 15:12 UTC (permalink / raw)
  To: Ladislav Michl, linux-mtd, linux-omap
  Cc: Tony Lindgren, Peter Ujfalusi, Kyungmin Park, Boris Brezillon

On 11/11/17 23:18, Ladislav Michl wrote:
> Update node timings to be compatible with actual chip used -
> gpmc_cs_show_timings utilized to dump values.
> 
> Signed-off-by: Ladislav Michl <ladis@linux-mips.org>

Acked-by: Roger Quadros <rogerq@ti.com>

> ---
>  Changes:
>  -v4: new patch
> 
>  arch/arm/boot/dts/omap3-igep.dtsi | 30 +++++++++++++++---------------
>  1 file changed, 15 insertions(+), 15 deletions(-)
> 
> diff --git a/arch/arm/boot/dts/omap3-igep.dtsi b/arch/arm/boot/dts/omap3-igep.dtsi
> index 4929ba1cb9d3..1e4b8d5c7572 100644
> --- a/arch/arm/boot/dts/omap3-igep.dtsi
> +++ b/arch/arm/boot/dts/omap3-igep.dtsi
> @@ -144,32 +144,32 @@
>  		gpmc,sync-read;
>  		gpmc,sync-write;
>  		gpmc,burst-length = <16>;
> -		gpmc,burst-read;
>  		gpmc,burst-wrap;
> +		gpmc,burst-read;
>  		gpmc,burst-write;
>  		gpmc,device-width = <2>; /* GPMC_DEVWIDTH_16BIT */
>  		gpmc,mux-add-data = <2>; /* GPMC_MUX_AD */
>  		gpmc,cs-on-ns = <0>;
> -		gpmc,cs-rd-off-ns = <87>;
> -		gpmc,cs-wr-off-ns = <87>;
> +		gpmc,cs-rd-off-ns = <96>;
> +		gpmc,cs-wr-off-ns = <96>;
>  		gpmc,adv-on-ns = <0>;
> -		gpmc,adv-rd-off-ns = <10>;
> -		gpmc,adv-wr-off-ns = <10>;
> -		gpmc,oe-on-ns = <15>;
> -		gpmc,oe-off-ns = <87>;
> +		gpmc,adv-rd-off-ns = <12>;
> +		gpmc,adv-wr-off-ns = <12>;
> +		gpmc,oe-on-ns = <18>;
> +		gpmc,oe-off-ns = <96>;
>  		gpmc,we-on-ns = <0>;
> -		gpmc,we-off-ns = <87>;
> -		gpmc,rd-cycle-ns = <112>;
> -		gpmc,wr-cycle-ns = <112>;
> -		gpmc,access-ns = <81>;
> -		gpmc,page-burst-access-ns = <15>;
> +		gpmc,we-off-ns = <96>;
> +		gpmc,rd-cycle-ns = <114>;
> +		gpmc,wr-cycle-ns = <114>;
> +		gpmc,access-ns = <90>;
> +		gpmc,page-burst-access-ns = <12>;
>  		gpmc,bus-turnaround-ns = <0>;
>  		gpmc,cycle2cycle-delay-ns = <0>;
>  		gpmc,wait-monitoring-ns = <0>;
> -		gpmc,clk-activation-ns = <5>;
> +		gpmc,clk-activation-ns = <6>;
>  		gpmc,wr-data-mux-bus-ns = <30>;
> -		gpmc,wr-access-ns = <81>;
> -		gpmc,sync-clk-ps = <15000>;
> +		gpmc,wr-access-ns = <90>;
> +		gpmc,sync-clk-ps = <12000>;
>  
>  		#address-cells = <1>;
>  		#size-cells = <1>;
> 

-- 
cheers,
-roger

Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki. Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki

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

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

* Re: [PATCH v4 03/16] ARM: dts: omap3-igep: Update onenand node timings
@ 2017-11-14 15:12     ` Roger Quadros
  0 siblings, 0 replies; 114+ messages in thread
From: Roger Quadros @ 2017-11-14 15:12 UTC (permalink / raw)
  To: Ladislav Michl, linux-mtd, linux-omap
  Cc: Tony Lindgren, Peter Ujfalusi, Boris Brezillon, Kyungmin Park

On 11/11/17 23:18, Ladislav Michl wrote:
> Update node timings to be compatible with actual chip used -
> gpmc_cs_show_timings utilized to dump values.
> 
> Signed-off-by: Ladislav Michl <ladis@linux-mips.org>

Acked-by: Roger Quadros <rogerq@ti.com>

> ---
>  Changes:
>  -v4: new patch
> 
>  arch/arm/boot/dts/omap3-igep.dtsi | 30 +++++++++++++++---------------
>  1 file changed, 15 insertions(+), 15 deletions(-)
> 
> diff --git a/arch/arm/boot/dts/omap3-igep.dtsi b/arch/arm/boot/dts/omap3-igep.dtsi
> index 4929ba1cb9d3..1e4b8d5c7572 100644
> --- a/arch/arm/boot/dts/omap3-igep.dtsi
> +++ b/arch/arm/boot/dts/omap3-igep.dtsi
> @@ -144,32 +144,32 @@
>  		gpmc,sync-read;
>  		gpmc,sync-write;
>  		gpmc,burst-length = <16>;
> -		gpmc,burst-read;
>  		gpmc,burst-wrap;
> +		gpmc,burst-read;
>  		gpmc,burst-write;
>  		gpmc,device-width = <2>; /* GPMC_DEVWIDTH_16BIT */
>  		gpmc,mux-add-data = <2>; /* GPMC_MUX_AD */
>  		gpmc,cs-on-ns = <0>;
> -		gpmc,cs-rd-off-ns = <87>;
> -		gpmc,cs-wr-off-ns = <87>;
> +		gpmc,cs-rd-off-ns = <96>;
> +		gpmc,cs-wr-off-ns = <96>;
>  		gpmc,adv-on-ns = <0>;
> -		gpmc,adv-rd-off-ns = <10>;
> -		gpmc,adv-wr-off-ns = <10>;
> -		gpmc,oe-on-ns = <15>;
> -		gpmc,oe-off-ns = <87>;
> +		gpmc,adv-rd-off-ns = <12>;
> +		gpmc,adv-wr-off-ns = <12>;
> +		gpmc,oe-on-ns = <18>;
> +		gpmc,oe-off-ns = <96>;
>  		gpmc,we-on-ns = <0>;
> -		gpmc,we-off-ns = <87>;
> -		gpmc,rd-cycle-ns = <112>;
> -		gpmc,wr-cycle-ns = <112>;
> -		gpmc,access-ns = <81>;
> -		gpmc,page-burst-access-ns = <15>;
> +		gpmc,we-off-ns = <96>;
> +		gpmc,rd-cycle-ns = <114>;
> +		gpmc,wr-cycle-ns = <114>;
> +		gpmc,access-ns = <90>;
> +		gpmc,page-burst-access-ns = <12>;
>  		gpmc,bus-turnaround-ns = <0>;
>  		gpmc,cycle2cycle-delay-ns = <0>;
>  		gpmc,wait-monitoring-ns = <0>;
> -		gpmc,clk-activation-ns = <5>;
> +		gpmc,clk-activation-ns = <6>;
>  		gpmc,wr-data-mux-bus-ns = <30>;
> -		gpmc,wr-access-ns = <81>;
> -		gpmc,sync-clk-ps = <15000>;
> +		gpmc,wr-access-ns = <90>;
> +		gpmc,sync-clk-ps = <12000>;
>  
>  		#address-cells = <1>;
>  		#size-cells = <1>;
> 

-- 
cheers,
-roger

Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki. Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki

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

* Re: [PATCH v4 04/16] mtd: onenand: omap2: Remove regulator support
  2017-11-11 21:19   ` Ladislav Michl
@ 2017-11-14 15:13     ` Roger Quadros
  -1 siblings, 0 replies; 114+ messages in thread
From: Roger Quadros @ 2017-11-14 15:13 UTC (permalink / raw)
  To: Ladislav Michl, linux-mtd, linux-omap
  Cc: Tony Lindgren, Peter Ujfalusi, Kyungmin Park, Boris Brezillon

On 11/11/17 23:19, Ladislav Michl wrote:
> As no platform data user sets regulator_can_sleep, regulator code is
> no-op and can be deleted.
> 
> Signed-off-by: Ladislav Michl <ladis@linux-mips.org>

Acked-by: Roger Quadros <rogerq@ti.com>

> ---
>  Changes:
>  -v2: new patch
>  -v3: none
>  -v4: none
> 
>  drivers/mtd/onenand/omap2.c | 42 +-----------------------------------------
>  1 file changed, 1 insertion(+), 41 deletions(-)
> 
> diff --git a/drivers/mtd/onenand/omap2.c b/drivers/mtd/onenand/omap2.c
> index 24a1388d3031..a03e1fe4aa48 100644
> --- a/drivers/mtd/onenand/omap2.c
> +++ b/drivers/mtd/onenand/omap2.c
> @@ -34,7 +34,6 @@
>  #include <linux/dma-mapping.h>
>  #include <linux/io.h>
>  #include <linux/slab.h>
> -#include <linux/regulator/consumer.h>
>  #include <linux/gpio.h>
>  
>  #include <asm/mach/flash.h>
> @@ -59,7 +58,6 @@ struct omap2_onenand {
>  	int dma_channel;
>  	int freq;
>  	int (*setup)(void __iomem *base, int *freq_ptr);
> -	struct regulator *regulator;
>  	u8 flags;
>  };
>  
> @@ -583,30 +581,6 @@ static void omap2_onenand_shutdown(struct platform_device *pdev)
>  	memset((__force void *)c->onenand.base, 0, ONENAND_BUFRAM_SIZE);
>  }
>  
> -static int omap2_onenand_enable(struct mtd_info *mtd)
> -{
> -	int ret;
> -	struct omap2_onenand *c = container_of(mtd, struct omap2_onenand, mtd);
> -
> -	ret = regulator_enable(c->regulator);
> -	if (ret != 0)
> -		dev_err(&c->pdev->dev, "can't enable regulator\n");
> -
> -	return ret;
> -}
> -
> -static int omap2_onenand_disable(struct mtd_info *mtd)
> -{
> -	int ret;
> -	struct omap2_onenand *c = container_of(mtd, struct omap2_onenand, mtd);
> -
> -	ret = regulator_disable(c->regulator);
> -	if (ret != 0)
> -		dev_err(&c->pdev->dev, "can't disable regulator\n");
> -
> -	return ret;
> -}
> -
>  static int omap2_onenand_probe(struct platform_device *pdev)
>  {
>  	struct omap_onenand_platform_data *pdata;
> @@ -726,22 +700,11 @@ static int omap2_onenand_probe(struct platform_device *pdev)
>  		}
>  	}
>  
> -	if (pdata->regulator_can_sleep) {
> -		c->regulator = regulator_get(&pdev->dev, "vonenand");
> -		if (IS_ERR(c->regulator)) {
> -			dev_err(&pdev->dev,  "Failed to get regulator\n");
> -			r = PTR_ERR(c->regulator);
> -			goto err_release_dma;
> -		}
> -		c->onenand.enable = omap2_onenand_enable;
> -		c->onenand.disable = omap2_onenand_disable;
> -	}
> -
>  	if (pdata->skip_initial_unlocking)
>  		this->options |= ONENAND_SKIP_INITIAL_UNLOCKING;
>  
>  	if ((r = onenand_scan(&c->mtd, 1)) < 0)
> -		goto err_release_regulator;
> +		goto err_release_dma;
>  
>  	r = mtd_device_register(&c->mtd, pdata ? pdata->parts : NULL,
>  				pdata ? pdata->nr_parts : 0);
> @@ -754,8 +717,6 @@ static int omap2_onenand_probe(struct platform_device *pdev)
>  
>  err_release_onenand:
>  	onenand_release(&c->mtd);
> -err_release_regulator:
> -	regulator_put(c->regulator);
>  err_release_dma:
>  	if (c->dma_channel != -1)
>  		omap_free_dma(c->dma_channel);
> @@ -779,7 +740,6 @@ static int omap2_onenand_remove(struct platform_device *pdev)
>  	struct omap2_onenand *c = dev_get_drvdata(&pdev->dev);
>  
>  	onenand_release(&c->mtd);
> -	regulator_put(c->regulator);
>  	if (c->dma_channel != -1)
>  		omap_free_dma(c->dma_channel);
>  	omap2_onenand_shutdown(pdev);
> 

-- 
cheers,
-roger

Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki. Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki

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

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

* Re: [PATCH v4 04/16] mtd: onenand: omap2: Remove regulator support
@ 2017-11-14 15:13     ` Roger Quadros
  0 siblings, 0 replies; 114+ messages in thread
From: Roger Quadros @ 2017-11-14 15:13 UTC (permalink / raw)
  To: Ladislav Michl, linux-mtd, linux-omap
  Cc: Tony Lindgren, Peter Ujfalusi, Boris Brezillon, Kyungmin Park

On 11/11/17 23:19, Ladislav Michl wrote:
> As no platform data user sets regulator_can_sleep, regulator code is
> no-op and can be deleted.
> 
> Signed-off-by: Ladislav Michl <ladis@linux-mips.org>

Acked-by: Roger Quadros <rogerq@ti.com>

> ---
>  Changes:
>  -v2: new patch
>  -v3: none
>  -v4: none
> 
>  drivers/mtd/onenand/omap2.c | 42 +-----------------------------------------
>  1 file changed, 1 insertion(+), 41 deletions(-)
> 
> diff --git a/drivers/mtd/onenand/omap2.c b/drivers/mtd/onenand/omap2.c
> index 24a1388d3031..a03e1fe4aa48 100644
> --- a/drivers/mtd/onenand/omap2.c
> +++ b/drivers/mtd/onenand/omap2.c
> @@ -34,7 +34,6 @@
>  #include <linux/dma-mapping.h>
>  #include <linux/io.h>
>  #include <linux/slab.h>
> -#include <linux/regulator/consumer.h>
>  #include <linux/gpio.h>
>  
>  #include <asm/mach/flash.h>
> @@ -59,7 +58,6 @@ struct omap2_onenand {
>  	int dma_channel;
>  	int freq;
>  	int (*setup)(void __iomem *base, int *freq_ptr);
> -	struct regulator *regulator;
>  	u8 flags;
>  };
>  
> @@ -583,30 +581,6 @@ static void omap2_onenand_shutdown(struct platform_device *pdev)
>  	memset((__force void *)c->onenand.base, 0, ONENAND_BUFRAM_SIZE);
>  }
>  
> -static int omap2_onenand_enable(struct mtd_info *mtd)
> -{
> -	int ret;
> -	struct omap2_onenand *c = container_of(mtd, struct omap2_onenand, mtd);
> -
> -	ret = regulator_enable(c->regulator);
> -	if (ret != 0)
> -		dev_err(&c->pdev->dev, "can't enable regulator\n");
> -
> -	return ret;
> -}
> -
> -static int omap2_onenand_disable(struct mtd_info *mtd)
> -{
> -	int ret;
> -	struct omap2_onenand *c = container_of(mtd, struct omap2_onenand, mtd);
> -
> -	ret = regulator_disable(c->regulator);
> -	if (ret != 0)
> -		dev_err(&c->pdev->dev, "can't disable regulator\n");
> -
> -	return ret;
> -}
> -
>  static int omap2_onenand_probe(struct platform_device *pdev)
>  {
>  	struct omap_onenand_platform_data *pdata;
> @@ -726,22 +700,11 @@ static int omap2_onenand_probe(struct platform_device *pdev)
>  		}
>  	}
>  
> -	if (pdata->regulator_can_sleep) {
> -		c->regulator = regulator_get(&pdev->dev, "vonenand");
> -		if (IS_ERR(c->regulator)) {
> -			dev_err(&pdev->dev,  "Failed to get regulator\n");
> -			r = PTR_ERR(c->regulator);
> -			goto err_release_dma;
> -		}
> -		c->onenand.enable = omap2_onenand_enable;
> -		c->onenand.disable = omap2_onenand_disable;
> -	}
> -
>  	if (pdata->skip_initial_unlocking)
>  		this->options |= ONENAND_SKIP_INITIAL_UNLOCKING;
>  
>  	if ((r = onenand_scan(&c->mtd, 1)) < 0)
> -		goto err_release_regulator;
> +		goto err_release_dma;
>  
>  	r = mtd_device_register(&c->mtd, pdata ? pdata->parts : NULL,
>  				pdata ? pdata->nr_parts : 0);
> @@ -754,8 +717,6 @@ static int omap2_onenand_probe(struct platform_device *pdev)
>  
>  err_release_onenand:
>  	onenand_release(&c->mtd);
> -err_release_regulator:
> -	regulator_put(c->regulator);
>  err_release_dma:
>  	if (c->dma_channel != -1)
>  		omap_free_dma(c->dma_channel);
> @@ -779,7 +740,6 @@ static int omap2_onenand_remove(struct platform_device *pdev)
>  	struct omap2_onenand *c = dev_get_drvdata(&pdev->dev);
>  
>  	onenand_release(&c->mtd);
> -	regulator_put(c->regulator);
>  	if (c->dma_channel != -1)
>  		omap_free_dma(c->dma_channel);
>  	omap2_onenand_shutdown(pdev);
> 

-- 
cheers,
-roger

Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki. Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki

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

* Re: [PATCH v4 05/16] mtd: onenand: omap2: Remove skip initial unlocking support
  2017-11-11 21:19   ` Ladislav Michl
@ 2017-11-14 15:14     ` Roger Quadros
  -1 siblings, 0 replies; 114+ messages in thread
From: Roger Quadros @ 2017-11-14 15:14 UTC (permalink / raw)
  To: Ladislav Michl, linux-mtd, linux-omap
  Cc: Tony Lindgren, Peter Ujfalusi, Kyungmin Park, Boris Brezillon

On 11/11/17 23:19, Ladislav Michl wrote:
> No platform data user sets skip_initial_unlocking, so remove test
> for this field.
> 
> Signed-off-by: Ladislav Michl <ladis@linux-mips.org>

Acked-by: Roger Quadros <rogerq@ti.com>

> ---
>  Changes:
>  -v2: new patch
>  -v3: none
>  -v4: none
> 
>  drivers/mtd/onenand/omap2.c | 3 ---
>  1 file changed, 3 deletions(-)
> 
> diff --git a/drivers/mtd/onenand/omap2.c b/drivers/mtd/onenand/omap2.c
> index a03e1fe4aa48..93bd94337b35 100644
> --- a/drivers/mtd/onenand/omap2.c
> +++ b/drivers/mtd/onenand/omap2.c
> @@ -700,9 +700,6 @@ static int omap2_onenand_probe(struct platform_device *pdev)
>  		}
>  	}
>  
> -	if (pdata->skip_initial_unlocking)
> -		this->options |= ONENAND_SKIP_INITIAL_UNLOCKING;
> -
>  	if ((r = onenand_scan(&c->mtd, 1)) < 0)
>  		goto err_release_dma;
>  
> 

-- 
cheers,
-roger

Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki. Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki

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

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

* Re: [PATCH v4 05/16] mtd: onenand: omap2: Remove skip initial unlocking support
@ 2017-11-14 15:14     ` Roger Quadros
  0 siblings, 0 replies; 114+ messages in thread
From: Roger Quadros @ 2017-11-14 15:14 UTC (permalink / raw)
  To: Ladislav Michl, linux-mtd, linux-omap
  Cc: Tony Lindgren, Peter Ujfalusi, Boris Brezillon, Kyungmin Park

On 11/11/17 23:19, Ladislav Michl wrote:
> No platform data user sets skip_initial_unlocking, so remove test
> for this field.
> 
> Signed-off-by: Ladislav Michl <ladis@linux-mips.org>

Acked-by: Roger Quadros <rogerq@ti.com>

> ---
>  Changes:
>  -v2: new patch
>  -v3: none
>  -v4: none
> 
>  drivers/mtd/onenand/omap2.c | 3 ---
>  1 file changed, 3 deletions(-)
> 
> diff --git a/drivers/mtd/onenand/omap2.c b/drivers/mtd/onenand/omap2.c
> index a03e1fe4aa48..93bd94337b35 100644
> --- a/drivers/mtd/onenand/omap2.c
> +++ b/drivers/mtd/onenand/omap2.c
> @@ -700,9 +700,6 @@ static int omap2_onenand_probe(struct platform_device *pdev)
>  		}
>  	}
>  
> -	if (pdata->skip_initial_unlocking)
> -		this->options |= ONENAND_SKIP_INITIAL_UNLOCKING;
> -
>  	if ((r = onenand_scan(&c->mtd, 1)) < 0)
>  		goto err_release_dma;
>  
> 

-- 
cheers,
-roger

Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki. Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki

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

* Re: [PATCH v4 06/16] mtd: onenand: omap2: Remove partitioning support from platform data
  2017-11-11 21:20   ` Ladislav Michl
@ 2017-11-14 15:14     ` Roger Quadros
  -1 siblings, 0 replies; 114+ messages in thread
From: Roger Quadros @ 2017-11-14 15:14 UTC (permalink / raw)
  To: Ladislav Michl, linux-mtd, linux-omap
  Cc: Tony Lindgren, Peter Ujfalusi, Kyungmin Park, Boris Brezillon

On 11/11/17 23:20, Ladislav Michl wrote:
> No platform data user setups partitioning informations, so remove.
> 
> Signed-off-by: Ladislav Michl <ladis@linux-mips.org>

Acked-by: Roger Quadros <rogerq@ti.com>

> ---
>  Changes:
>  -v2: new patch
>  -v3: none
>  -v4: none
> 
>  drivers/mtd/onenand/omap2.c | 3 +--
>  1 file changed, 1 insertion(+), 2 deletions(-)
> 
> diff --git a/drivers/mtd/onenand/omap2.c b/drivers/mtd/onenand/omap2.c
> index 93bd94337b35..883993bbe40b 100644
> --- a/drivers/mtd/onenand/omap2.c
> +++ b/drivers/mtd/onenand/omap2.c
> @@ -703,8 +703,7 @@ static int omap2_onenand_probe(struct platform_device *pdev)
>  	if ((r = onenand_scan(&c->mtd, 1)) < 0)
>  		goto err_release_dma;
>  
> -	r = mtd_device_register(&c->mtd, pdata ? pdata->parts : NULL,
> -				pdata ? pdata->nr_parts : 0);
> +	r = mtd_device_register(&c->mtd, NULL, 0);
>  	if (r)
>  		goto err_release_onenand;
>  
> 

-- 
cheers,
-roger

Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki. Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki

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

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

* Re: [PATCH v4 06/16] mtd: onenand: omap2: Remove partitioning support from platform data
@ 2017-11-14 15:14     ` Roger Quadros
  0 siblings, 0 replies; 114+ messages in thread
From: Roger Quadros @ 2017-11-14 15:14 UTC (permalink / raw)
  To: Ladislav Michl, linux-mtd, linux-omap
  Cc: Tony Lindgren, Peter Ujfalusi, Boris Brezillon, Kyungmin Park

On 11/11/17 23:20, Ladislav Michl wrote:
> No platform data user setups partitioning informations, so remove.
> 
> Signed-off-by: Ladislav Michl <ladis@linux-mips.org>

Acked-by: Roger Quadros <rogerq@ti.com>

> ---
>  Changes:
>  -v2: new patch
>  -v3: none
>  -v4: none
> 
>  drivers/mtd/onenand/omap2.c | 3 +--
>  1 file changed, 1 insertion(+), 2 deletions(-)
> 
> diff --git a/drivers/mtd/onenand/omap2.c b/drivers/mtd/onenand/omap2.c
> index 93bd94337b35..883993bbe40b 100644
> --- a/drivers/mtd/onenand/omap2.c
> +++ b/drivers/mtd/onenand/omap2.c
> @@ -703,8 +703,7 @@ static int omap2_onenand_probe(struct platform_device *pdev)
>  	if ((r = onenand_scan(&c->mtd, 1)) < 0)
>  		goto err_release_dma;
>  
> -	r = mtd_device_register(&c->mtd, pdata ? pdata->parts : NULL,
> -				pdata ? pdata->nr_parts : 0);
> +	r = mtd_device_register(&c->mtd, NULL, 0);
>  	if (r)
>  		goto err_release_onenand;
>  
> 

-- 
cheers,
-roger

Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki. Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki

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

* Re: [PATCH v4 07/16] mtd: onenand: omap2: Account waiting time as waiting on IO
  2017-11-11 21:20   ` Ladislav Michl
@ 2017-11-14 15:18     ` Roger Quadros
  -1 siblings, 0 replies; 114+ messages in thread
From: Roger Quadros @ 2017-11-14 15:18 UTC (permalink / raw)
  To: Ladislav Michl, linux-mtd, linux-omap
  Cc: Tony Lindgren, Peter Ujfalusi, Kyungmin Park, Boris Brezillon

On 11/11/17 23:20, Ladislav Michl wrote:
> Use wait_for_completion_io_timeout, which has an impact on how the
> task is accounted in scheduling stats.
> 
> Signed-off-by: Ladislav Michl <ladis@linux-mips.org>

Acked-by: Roger Quadros <rogerq@ti.com>

> ---
>  Changes:
>  -v4: new patch
> 
>  drivers/mtd/onenand/omap2.c | 5 ++---
>  1 file changed, 2 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/mtd/onenand/omap2.c b/drivers/mtd/onenand/omap2.c
> index 883993bbe40b..0e7772e16d75 100644
> --- a/drivers/mtd/onenand/omap2.c
> +++ b/drivers/mtd/onenand/omap2.c
> @@ -170,9 +170,8 @@ static int omap2_onenand_wait(struct mtd_info *mtd, int state)
>  		if (result == 0) {
>  			int retry_cnt = 0;
>  retry:
> -			result = wait_for_completion_timeout(&c->irq_done,
> -						    msecs_to_jiffies(20));
> -			if (result == 0) {
> +			if (!wait_for_completion_io_timeout(&c->irq_done,
> +						msecs_to_jiffies(20))) {
>  				/* Timeout after 20ms */
>  				ctrl = read_reg(c, ONENAND_REG_CTRL_STATUS);
>  				if (ctrl & ONENAND_CTRL_ONGO &&
> 

-- 
cheers,
-roger

Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki. Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki

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

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

* Re: [PATCH v4 07/16] mtd: onenand: omap2: Account waiting time as waiting on IO
@ 2017-11-14 15:18     ` Roger Quadros
  0 siblings, 0 replies; 114+ messages in thread
From: Roger Quadros @ 2017-11-14 15:18 UTC (permalink / raw)
  To: Ladislav Michl, linux-mtd, linux-omap
  Cc: Tony Lindgren, Peter Ujfalusi, Boris Brezillon, Kyungmin Park

On 11/11/17 23:20, Ladislav Michl wrote:
> Use wait_for_completion_io_timeout, which has an impact on how the
> task is accounted in scheduling stats.
> 
> Signed-off-by: Ladislav Michl <ladis@linux-mips.org>

Acked-by: Roger Quadros <rogerq@ti.com>

> ---
>  Changes:
>  -v4: new patch
> 
>  drivers/mtd/onenand/omap2.c | 5 ++---
>  1 file changed, 2 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/mtd/onenand/omap2.c b/drivers/mtd/onenand/omap2.c
> index 883993bbe40b..0e7772e16d75 100644
> --- a/drivers/mtd/onenand/omap2.c
> +++ b/drivers/mtd/onenand/omap2.c
> @@ -170,9 +170,8 @@ static int omap2_onenand_wait(struct mtd_info *mtd, int state)
>  		if (result == 0) {
>  			int retry_cnt = 0;
>  retry:
> -			result = wait_for_completion_timeout(&c->irq_done,
> -						    msecs_to_jiffies(20));
> -			if (result == 0) {
> +			if (!wait_for_completion_io_timeout(&c->irq_done,
> +						msecs_to_jiffies(20))) {
>  				/* Timeout after 20ms */
>  				ctrl = read_reg(c, ONENAND_REG_CTRL_STATUS);
>  				if (ctrl & ONENAND_CTRL_ONGO &&
> 

-- 
cheers,
-roger

Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki. Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki

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

* Re: [PATCH v4 02/16] ARM: dts: OMAP2+: Add compatible property to onenand node
  2017-11-11 21:17   ` Ladislav Michl
@ 2017-11-14 21:39     ` Tony Lindgren
  -1 siblings, 0 replies; 114+ messages in thread
From: Tony Lindgren @ 2017-11-14 21:39 UTC (permalink / raw)
  To: Ladislav Michl
  Cc: Boris Brezillon, Peter Ujfalusi, Kyungmin Park, linux-mtd,
	linux-omap, Roger Quadros

* Ladislav Michl <ladis@linux-mips.org> [171111 21:19]:
> OMAP onenand nodes are missing compatible property, add it.
> 
> Signed-off-by: Ladislav Michl <ladis@linux-mips.org>

Best to merge this one with the MTD patches, otherwise it will be a
layered mess of merges:

Acked-by: Tony Lindgren <tony@atomide.com>

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

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

* Re: [PATCH v4 02/16] ARM: dts: OMAP2+: Add compatible property to onenand node
@ 2017-11-14 21:39     ` Tony Lindgren
  0 siblings, 0 replies; 114+ messages in thread
From: Tony Lindgren @ 2017-11-14 21:39 UTC (permalink / raw)
  To: Ladislav Michl
  Cc: linux-mtd, linux-omap, Roger Quadros, Peter Ujfalusi,
	Boris Brezillon, Kyungmin Park

* Ladislav Michl <ladis@linux-mips.org> [171111 21:19]:
> OMAP onenand nodes are missing compatible property, add it.
> 
> Signed-off-by: Ladislav Michl <ladis@linux-mips.org>

Best to merge this one with the MTD patches, otherwise it will be a
layered mess of merges:

Acked-by: Tony Lindgren <tony@atomide.com>

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

* Re: [PATCH v4 03/16] ARM: dts: omap3-igep: Update onenand node timings
  2017-11-11 21:18   ` Ladislav Michl
@ 2017-11-14 21:39     ` Tony Lindgren
  -1 siblings, 0 replies; 114+ messages in thread
From: Tony Lindgren @ 2017-11-14 21:39 UTC (permalink / raw)
  To: Ladislav Michl
  Cc: Boris Brezillon, Peter Ujfalusi, Kyungmin Park, linux-mtd,
	linux-omap, Roger Quadros

* Ladislav Michl <ladis@linux-mips.org> [171111 21:20]:
> Update node timings to be compatible with actual chip used -
> gpmc_cs_show_timings utilized to dump values.
> 
> Signed-off-by: Ladislav Michl <ladis@linux-mips.org>

This too:

Acked-by: Tony Lindgren <tony@atomide.com>

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

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

* Re: [PATCH v4 03/16] ARM: dts: omap3-igep: Update onenand node timings
@ 2017-11-14 21:39     ` Tony Lindgren
  0 siblings, 0 replies; 114+ messages in thread
From: Tony Lindgren @ 2017-11-14 21:39 UTC (permalink / raw)
  To: Ladislav Michl
  Cc: linux-mtd, linux-omap, Roger Quadros, Peter Ujfalusi,
	Boris Brezillon, Kyungmin Park

* Ladislav Michl <ladis@linux-mips.org> [171111 21:20]:
> Update node timings to be compatible with actual chip used -
> gpmc_cs_show_timings utilized to dump values.
> 
> Signed-off-by: Ladislav Michl <ladis@linux-mips.org>

This too:

Acked-by: Tony Lindgren <tony@atomide.com>

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

* Re: [PATCH v4 15/16] ARM: OMAP2+: Remove gpmc-onenand
  2017-11-11 21:29   ` Ladislav Michl
@ 2017-11-14 21:41     ` Tony Lindgren
  -1 siblings, 0 replies; 114+ messages in thread
From: Tony Lindgren @ 2017-11-14 21:41 UTC (permalink / raw)
  To: Ladislav Michl
  Cc: Boris Brezillon, Peter Ujfalusi, Kyungmin Park, linux-mtd,
	linux-omap, Roger Quadros

* Ladislav Michl <ladis@linux-mips.org> [171111 21:31]:
> As OneNAND driver is now using devicetree gpmc-onenand and its
> platform data is unused and can be removed.
> 
> Signed-off-by: Ladislav Michl <ladis@linux-mips.org>

And nobody's going to touch this file, so it's safe to merge
also via MTD tree:

Acked-by: Tony Lindgren <tony@atomide.com>

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

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

* Re: [PATCH v4 15/16] ARM: OMAP2+: Remove gpmc-onenand
@ 2017-11-14 21:41     ` Tony Lindgren
  0 siblings, 0 replies; 114+ messages in thread
From: Tony Lindgren @ 2017-11-14 21:41 UTC (permalink / raw)
  To: Ladislav Michl
  Cc: linux-mtd, linux-omap, Roger Quadros, Peter Ujfalusi,
	Boris Brezillon, Kyungmin Park

* Ladislav Michl <ladis@linux-mips.org> [171111 21:31]:
> As OneNAND driver is now using devicetree gpmc-onenand and its
> platform data is unused and can be removed.
> 
> Signed-off-by: Ladislav Michl <ladis@linux-mips.org>

And nobody's going to touch this file, so it's safe to merge
also via MTD tree:

Acked-by: Tony Lindgren <tony@atomide.com>

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

* Re: [PATCH v4 16/16] ARM: dts: Nokia: Use R/B pin
  2017-11-11 21:29   ` Ladislav Michl
@ 2017-11-14 21:42     ` Tony Lindgren
  -1 siblings, 0 replies; 114+ messages in thread
From: Tony Lindgren @ 2017-11-14 21:42 UTC (permalink / raw)
  To: Ladislav Michl
  Cc: Boris Brezillon, Peter Ujfalusi, Kyungmin Park, linux-mtd,
	linux-omap, Roger Quadros

* Ladislav Michl <ladis@linux-mips.org> [171111 21:31]:
> Enable use of R/B pin. This is just experimental placeholder patch
> as it lacks pinmux settings.
> 
> Signed-off-by: Ladislav Michl <ladis@linux-mips.org>
> ---
>  Changes:
>  -v4: new patch
> 
>  arch/arm/boot/dts/omap2420-n8x0-common.dtsi | 4 +---
>  arch/arm/boot/dts/omap3-n900.dts            | 1 +
>  2 files changed, 2 insertions(+), 3 deletions(-)
> 
> diff --git a/arch/arm/boot/dts/omap2420-n8x0-common.dtsi b/arch/arm/boot/dts/omap2420-n8x0-common.dtsi
> index 843f6a2f5e29..cfe5d02ea0ed 100644
> --- a/arch/arm/boot/dts/omap2420-n8x0-common.dtsi
> +++ b/arch/arm/boot/dts/omap2420-n8x0-common.dtsi
> @@ -42,14 +42,12 @@
>  
>  &gpmc {
>  	ranges = <0 0 0x04000000 0x1000000>;	/* CS0: 16MB for OneNAND */
> -
> -	/* gpio-irq for dma: 26 */
> -
>  	onenand@0,0 {
>  		#address-cells = <1>;
>  		#size-cells = <1>;
>  		compatible = "ti,omap2-onenand";
>  		reg = <0 0 0x20000>;	/* CS0, offset 0, IO size 128K */
> +		rb-gpios = <&gpio0 26 GPIO_ACTIVE_HIGH>;
>  
>  		gpmc,sync-read;
>  		gpmc,burst-length = <16>;


This should be then <&gpio1 26 GPIO_ACTIVE_HIGH>, there is no &gpio0. This
will produce a build error too.

> diff --git a/arch/arm/boot/dts/omap3-n900.dts b/arch/arm/boot/dts/omap3-n900.dts
> index aa5b1a439564..718116d9f4ac 100644
> --- a/arch/arm/boot/dts/omap3-n900.dts
> +++ b/arch/arm/boot/dts/omap3-n900.dts
> @@ -840,6 +840,7 @@
>  		#size-cells = <1>;
>  		compatible = "ti,omap2-onenand";
>  		reg = <0 0 0x20000>;	/* CS0, offset 0, IO size 128K */
> +		rb-gpios = <&gpio3 1 GPIO_ACTIVE_HIGH>;
>  
>  		gpmc,sync-read;
>  		gpmc,sync-write;

This worked for me on n900, I'm currently unable to test n8x0.
But might be worth double checking if &gpio3 is correct here?

Regards,

Tony

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

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

* Re: [PATCH v4 16/16] ARM: dts: Nokia: Use R/B pin
@ 2017-11-14 21:42     ` Tony Lindgren
  0 siblings, 0 replies; 114+ messages in thread
From: Tony Lindgren @ 2017-11-14 21:42 UTC (permalink / raw)
  To: Ladislav Michl
  Cc: linux-mtd, linux-omap, Roger Quadros, Peter Ujfalusi,
	Boris Brezillon, Kyungmin Park

* Ladislav Michl <ladis@linux-mips.org> [171111 21:31]:
> Enable use of R/B pin. This is just experimental placeholder patch
> as it lacks pinmux settings.
> 
> Signed-off-by: Ladislav Michl <ladis@linux-mips.org>
> ---
>  Changes:
>  -v4: new patch
> 
>  arch/arm/boot/dts/omap2420-n8x0-common.dtsi | 4 +---
>  arch/arm/boot/dts/omap3-n900.dts            | 1 +
>  2 files changed, 2 insertions(+), 3 deletions(-)
> 
> diff --git a/arch/arm/boot/dts/omap2420-n8x0-common.dtsi b/arch/arm/boot/dts/omap2420-n8x0-common.dtsi
> index 843f6a2f5e29..cfe5d02ea0ed 100644
> --- a/arch/arm/boot/dts/omap2420-n8x0-common.dtsi
> +++ b/arch/arm/boot/dts/omap2420-n8x0-common.dtsi
> @@ -42,14 +42,12 @@
>  
>  &gpmc {
>  	ranges = <0 0 0x04000000 0x1000000>;	/* CS0: 16MB for OneNAND */
> -
> -	/* gpio-irq for dma: 26 */
> -
>  	onenand@0,0 {
>  		#address-cells = <1>;
>  		#size-cells = <1>;
>  		compatible = "ti,omap2-onenand";
>  		reg = <0 0 0x20000>;	/* CS0, offset 0, IO size 128K */
> +		rb-gpios = <&gpio0 26 GPIO_ACTIVE_HIGH>;
>  
>  		gpmc,sync-read;
>  		gpmc,burst-length = <16>;


This should be then <&gpio1 26 GPIO_ACTIVE_HIGH>, there is no &gpio0. This
will produce a build error too.

> diff --git a/arch/arm/boot/dts/omap3-n900.dts b/arch/arm/boot/dts/omap3-n900.dts
> index aa5b1a439564..718116d9f4ac 100644
> --- a/arch/arm/boot/dts/omap3-n900.dts
> +++ b/arch/arm/boot/dts/omap3-n900.dts
> @@ -840,6 +840,7 @@
>  		#size-cells = <1>;
>  		compatible = "ti,omap2-onenand";
>  		reg = <0 0 0x20000>;	/* CS0, offset 0, IO size 128K */
> +		rb-gpios = <&gpio3 1 GPIO_ACTIVE_HIGH>;
>  
>  		gpmc,sync-read;
>  		gpmc,sync-write;

This worked for me on n900, I'm currently unable to test n8x0.
But might be worth double checking if &gpio3 is correct here?

Regards,

Tony

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

* Re: [PATCH v4 00/16] OMAP2+ OneNAND driver update
  2017-11-11 21:12 ` Ladislav Michl
@ 2017-11-14 21:48   ` Tony Lindgren
  -1 siblings, 0 replies; 114+ messages in thread
From: Tony Lindgren @ 2017-11-14 21:48 UTC (permalink / raw)
  To: Ladislav Michl
  Cc: Boris Brezillon, Aaro Koskinen, Peter Ujfalusi, Kyungmin Park,
	linux-mtd, linux-omap, Roger Quadros

Hi,

* Ladislav Michl <ladis@linux-mips.org> [171111 21:13]:
> Hi there,
> 
> this patch serie updates OMAP2+ OneNAND driver to the present times, making
> it fully DT configurable, using libgpio and dmaengine apis.
> 
> Please note that unlike previous driver version, which basically ignored
> DT specified timings, this one relies on it, so it is important to get
> it right in your DT (dumping it from previous kernel version).
> 
> In case synchronous timings is requested, it is okay to specify timings
> for the slowest chip ever used for you board as it is evetually optimized
> after chip probe.
> 
> Original driver used DMA only if user specified r/b gpio in platform
> data, now DMA is used unconditionally and PIO mode is used as fallback.
> 
> In case anyone wants to give it a try, few DT related changes are needed:
> - onenand node needs 'ti,omap2-onenand' compatible (for mailine boards this is
>   done in patch 2)
> - to use R/B pin, rb-gpios needs to be specified (for n900 and n8x0 this is
>   done in patch 16, however patch lacks pinmux configuration.
> 
> Most notable changes from previous version:
> - added dmaengine patches by Peter Ujfalusi
> - added dt bindings documentation
> - added cleanup patches
> - DMA enabled by default
> 
> Also note that driver will fail probe OneNAND chip after patch 13 and start
> working again after patch 14.
> 
> Testing and benchmarking very welcome.
> 
> Depends on "memory: omap-gpmc: Make 'bank-width' property optional"
> https://patchwork.kernel.org/patch/10043259/

Thanks for doing this. I'm adding Aaro to Cc here, maybe he can test
n8x0 as my n800 in my rack is not currently booting.

I've tested this series briefly on n900 by writing a 10MB file to
onenand and comparing it to the original, and it seems to work so
for patches 1 to 15 you can add:

Tested-by: Tony Lindgren <tony@atomide.com>

The last patch has a build error for n8x0, and in general we really
should test this series on n8x0 before merging as the configuration
is a little bit different. So I'd say we need an ack from Aaro there.

I've also acked the mach-omap2 touching patches so when others are
happy this can be merged as a single set via the MTD tree.

Regards,

Tony

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

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

* Re: [PATCH v4 00/16] OMAP2+ OneNAND driver update
@ 2017-11-14 21:48   ` Tony Lindgren
  0 siblings, 0 replies; 114+ messages in thread
From: Tony Lindgren @ 2017-11-14 21:48 UTC (permalink / raw)
  To: Ladislav Michl
  Cc: linux-mtd, linux-omap, Roger Quadros, Peter Ujfalusi,
	Boris Brezillon, Kyungmin Park, Aaro Koskinen

Hi,

* Ladislav Michl <ladis@linux-mips.org> [171111 21:13]:
> Hi there,
> 
> this patch serie updates OMAP2+ OneNAND driver to the present times, making
> it fully DT configurable, using libgpio and dmaengine apis.
> 
> Please note that unlike previous driver version, which basically ignored
> DT specified timings, this one relies on it, so it is important to get
> it right in your DT (dumping it from previous kernel version).
> 
> In case synchronous timings is requested, it is okay to specify timings
> for the slowest chip ever used for you board as it is evetually optimized
> after chip probe.
> 
> Original driver used DMA only if user specified r/b gpio in platform
> data, now DMA is used unconditionally and PIO mode is used as fallback.
> 
> In case anyone wants to give it a try, few DT related changes are needed:
> - onenand node needs 'ti,omap2-onenand' compatible (for mailine boards this is
>   done in patch 2)
> - to use R/B pin, rb-gpios needs to be specified (for n900 and n8x0 this is
>   done in patch 16, however patch lacks pinmux configuration.
> 
> Most notable changes from previous version:
> - added dmaengine patches by Peter Ujfalusi
> - added dt bindings documentation
> - added cleanup patches
> - DMA enabled by default
> 
> Also note that driver will fail probe OneNAND chip after patch 13 and start
> working again after patch 14.
> 
> Testing and benchmarking very welcome.
> 
> Depends on "memory: omap-gpmc: Make 'bank-width' property optional"
> https://patchwork.kernel.org/patch/10043259/

Thanks for doing this. I'm adding Aaro to Cc here, maybe he can test
n8x0 as my n800 in my rack is not currently booting.

I've tested this series briefly on n900 by writing a 10MB file to
onenand and comparing it to the original, and it seems to work so
for patches 1 to 15 you can add:

Tested-by: Tony Lindgren <tony@atomide.com>

The last patch has a build error for n8x0, and in general we really
should test this series on n8x0 before merging as the configuration
is a little bit different. So I'd say we need an ack from Aaro there.

I've also acked the mach-omap2 touching patches so when others are
happy this can be merged as a single set via the MTD tree.

Regards,

Tony

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

* Re: [PATCH v4 16/16] ARM: dts: Nokia: Use R/B pin
  2017-11-14 21:42     ` Tony Lindgren
@ 2017-11-14 22:46       ` Ladislav Michl
  -1 siblings, 0 replies; 114+ messages in thread
From: Ladislav Michl @ 2017-11-14 22:46 UTC (permalink / raw)
  To: Tony Lindgren
  Cc: Boris Brezillon, Aaro Koskinen, Peter Ujfalusi, Kyungmin Park,
	linux-mtd, linux-omap, Roger Quadros

On Tue, Nov 14, 2017 at 01:42:56PM -0800, Tony Lindgren wrote:
> * Ladislav Michl <ladis@linux-mips.org> [171111 21:31]:
> > Enable use of R/B pin. This is just experimental placeholder patch
> > as it lacks pinmux settings.
> > 
> > Signed-off-by: Ladislav Michl <ladis@linux-mips.org>
> > ---
> >  Changes:
> >  -v4: new patch
> > 
> >  arch/arm/boot/dts/omap2420-n8x0-common.dtsi | 4 +---
> >  arch/arm/boot/dts/omap3-n900.dts            | 1 +
> >  2 files changed, 2 insertions(+), 3 deletions(-)
> > 
> > diff --git a/arch/arm/boot/dts/omap2420-n8x0-common.dtsi b/arch/arm/boot/dts/omap2420-n8x0-common.dtsi
> > index 843f6a2f5e29..cfe5d02ea0ed 100644
> > --- a/arch/arm/boot/dts/omap2420-n8x0-common.dtsi
> > +++ b/arch/arm/boot/dts/omap2420-n8x0-common.dtsi
> > @@ -42,14 +42,12 @@
> >  
> >  &gpmc {
> >  	ranges = <0 0 0x04000000 0x1000000>;	/* CS0: 16MB for OneNAND */
> > -
> > -	/* gpio-irq for dma: 26 */
> > -
> >  	onenand@0,0 {
> >  		#address-cells = <1>;
> >  		#size-cells = <1>;
> >  		compatible = "ti,omap2-onenand";
> >  		reg = <0 0 0x20000>;	/* CS0, offset 0, IO size 128K */
> > +		rb-gpios = <&gpio0 26 GPIO_ACTIVE_HIGH>;
> >  
> >  		gpmc,sync-read;
> >  		gpmc,burst-length = <16>;
> 
> 
> This should be then <&gpio1 26 GPIO_ACTIVE_HIGH>, there is no &gpio0. This
> will produce a build error too.

Argh, you're right. Fixed bellow.

> > diff --git a/arch/arm/boot/dts/omap3-n900.dts b/arch/arm/boot/dts/omap3-n900.dts
> > index aa5b1a439564..718116d9f4ac 100644
> > --- a/arch/arm/boot/dts/omap3-n900.dts
> > +++ b/arch/arm/boot/dts/omap3-n900.dts
> > @@ -840,6 +840,7 @@
> >  		#size-cells = <1>;
> >  		compatible = "ti,omap2-onenand";
> >  		reg = <0 0 0x20000>;	/* CS0, offset 0, IO size 128K */
> > +		rb-gpios = <&gpio3 1 GPIO_ACTIVE_HIGH>;
> >  
> >  		gpmc,sync-read;
> >  		gpmc,sync-write;
> 
> This worked for me on n900, I'm currently unable to test n8x0.
> But might be worth double checking if &gpio3 is correct here?

I hope so. This is what original platform data used and what was in 
omap3-n900.dts comment prior to e2c5eb78a3cc. Also see i2c0 node in
omap2420-n8x0-common.dtsi.

Here's quick update, v5 will follow after receiving some more testing.
And of course thanks a lot for testing!

---
 arch/arm/boot/dts/omap2420-n8x0-common.dtsi | 4 +---
 arch/arm/boot/dts/omap3-n900.dts            | 2 +-
 2 files changed, 2 insertions(+), 4 deletions(-)

diff --git a/arch/arm/boot/dts/omap2420-n8x0-common.dtsi b/arch/arm/boot/dts/omap2420-n8x0-common.dtsi
index 843f6a2f5e29..80cbbe0ee844 100644
--- a/arch/arm/boot/dts/omap2420-n8x0-common.dtsi
+++ b/arch/arm/boot/dts/omap2420-n8x0-common.dtsi
@@ -42,14 +42,12 @@
 
 &gpmc {
 	ranges = <0 0 0x04000000 0x1000000>;	/* CS0: 16MB for OneNAND */
-
-	/* gpio-irq for dma: 26 */
-
 	onenand@0,0 {
 		#address-cells = <1>;
 		#size-cells = <1>;
 		compatible = "ti,omap2-onenand";
 		reg = <0 0 0x20000>;	/* CS0, offset 0, IO size 128K */
+		rb-gpios = <&gpio1 26 GPIO_ACTIVE_HIGH>; /* gpio_26 for R/B */
 
 		gpmc,sync-read;
 		gpmc,burst-length = <16>;
diff --git a/arch/arm/boot/dts/omap3-n900.dts b/arch/arm/boot/dts/omap3-n900.dts
index aa5b1a439564..669899fd080b 100644
--- a/arch/arm/boot/dts/omap3-n900.dts
+++ b/arch/arm/boot/dts/omap3-n900.dts
@@ -834,12 +834,12 @@
 	pinctrl-names = "default";
 	pinctrl-0 = <&gpmc_pins>;
 
-	/* sys_ndmareq1 could be used by the driver, not as gpio65 though */
 	onenand@0,0 {
 		#address-cells = <1>;
 		#size-cells = <1>;
 		compatible = "ti,omap2-onenand";
 		reg = <0 0 0x20000>;	/* CS0, offset 0, IO size 128K */
+		rb-gpios = <&gpio3 1 GPIO_ACTIVE_HIGH>;	/* gpio_65 for R/B */
 
 		gpmc,sync-read;
 		gpmc,sync-write;
-- 
2.11.0


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

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

* Re: [PATCH v4 16/16] ARM: dts: Nokia: Use R/B pin
@ 2017-11-14 22:46       ` Ladislav Michl
  0 siblings, 0 replies; 114+ messages in thread
From: Ladislav Michl @ 2017-11-14 22:46 UTC (permalink / raw)
  To: Tony Lindgren
  Cc: linux-mtd, linux-omap, Roger Quadros, Peter Ujfalusi,
	Boris Brezillon, Kyungmin Park, Aaro Koskinen

On Tue, Nov 14, 2017 at 01:42:56PM -0800, Tony Lindgren wrote:
> * Ladislav Michl <ladis@linux-mips.org> [171111 21:31]:
> > Enable use of R/B pin. This is just experimental placeholder patch
> > as it lacks pinmux settings.
> > 
> > Signed-off-by: Ladislav Michl <ladis@linux-mips.org>
> > ---
> >  Changes:
> >  -v4: new patch
> > 
> >  arch/arm/boot/dts/omap2420-n8x0-common.dtsi | 4 +---
> >  arch/arm/boot/dts/omap3-n900.dts            | 1 +
> >  2 files changed, 2 insertions(+), 3 deletions(-)
> > 
> > diff --git a/arch/arm/boot/dts/omap2420-n8x0-common.dtsi b/arch/arm/boot/dts/omap2420-n8x0-common.dtsi
> > index 843f6a2f5e29..cfe5d02ea0ed 100644
> > --- a/arch/arm/boot/dts/omap2420-n8x0-common.dtsi
> > +++ b/arch/arm/boot/dts/omap2420-n8x0-common.dtsi
> > @@ -42,14 +42,12 @@
> >  
> >  &gpmc {
> >  	ranges = <0 0 0x04000000 0x1000000>;	/* CS0: 16MB for OneNAND */
> > -
> > -	/* gpio-irq for dma: 26 */
> > -
> >  	onenand@0,0 {
> >  		#address-cells = <1>;
> >  		#size-cells = <1>;
> >  		compatible = "ti,omap2-onenand";
> >  		reg = <0 0 0x20000>;	/* CS0, offset 0, IO size 128K */
> > +		rb-gpios = <&gpio0 26 GPIO_ACTIVE_HIGH>;
> >  
> >  		gpmc,sync-read;
> >  		gpmc,burst-length = <16>;
> 
> 
> This should be then <&gpio1 26 GPIO_ACTIVE_HIGH>, there is no &gpio0. This
> will produce a build error too.

Argh, you're right. Fixed bellow.

> > diff --git a/arch/arm/boot/dts/omap3-n900.dts b/arch/arm/boot/dts/omap3-n900.dts
> > index aa5b1a439564..718116d9f4ac 100644
> > --- a/arch/arm/boot/dts/omap3-n900.dts
> > +++ b/arch/arm/boot/dts/omap3-n900.dts
> > @@ -840,6 +840,7 @@
> >  		#size-cells = <1>;
> >  		compatible = "ti,omap2-onenand";
> >  		reg = <0 0 0x20000>;	/* CS0, offset 0, IO size 128K */
> > +		rb-gpios = <&gpio3 1 GPIO_ACTIVE_HIGH>;
> >  
> >  		gpmc,sync-read;
> >  		gpmc,sync-write;
> 
> This worked for me on n900, I'm currently unable to test n8x0.
> But might be worth double checking if &gpio3 is correct here?

I hope so. This is what original platform data used and what was in 
omap3-n900.dts comment prior to e2c5eb78a3cc. Also see i2c0 node in
omap2420-n8x0-common.dtsi.

Here's quick update, v5 will follow after receiving some more testing.
And of course thanks a lot for testing!

---
 arch/arm/boot/dts/omap2420-n8x0-common.dtsi | 4 +---
 arch/arm/boot/dts/omap3-n900.dts            | 2 +-
 2 files changed, 2 insertions(+), 4 deletions(-)

diff --git a/arch/arm/boot/dts/omap2420-n8x0-common.dtsi b/arch/arm/boot/dts/omap2420-n8x0-common.dtsi
index 843f6a2f5e29..80cbbe0ee844 100644
--- a/arch/arm/boot/dts/omap2420-n8x0-common.dtsi
+++ b/arch/arm/boot/dts/omap2420-n8x0-common.dtsi
@@ -42,14 +42,12 @@
 
 &gpmc {
 	ranges = <0 0 0x04000000 0x1000000>;	/* CS0: 16MB for OneNAND */
-
-	/* gpio-irq for dma: 26 */
-
 	onenand@0,0 {
 		#address-cells = <1>;
 		#size-cells = <1>;
 		compatible = "ti,omap2-onenand";
 		reg = <0 0 0x20000>;	/* CS0, offset 0, IO size 128K */
+		rb-gpios = <&gpio1 26 GPIO_ACTIVE_HIGH>; /* gpio_26 for R/B */
 
 		gpmc,sync-read;
 		gpmc,burst-length = <16>;
diff --git a/arch/arm/boot/dts/omap3-n900.dts b/arch/arm/boot/dts/omap3-n900.dts
index aa5b1a439564..669899fd080b 100644
--- a/arch/arm/boot/dts/omap3-n900.dts
+++ b/arch/arm/boot/dts/omap3-n900.dts
@@ -834,12 +834,12 @@
 	pinctrl-names = "default";
 	pinctrl-0 = <&gpmc_pins>;
 
-	/* sys_ndmareq1 could be used by the driver, not as gpio65 though */
 	onenand@0,0 {
 		#address-cells = <1>;
 		#size-cells = <1>;
 		compatible = "ti,omap2-onenand";
 		reg = <0 0 0x20000>;	/* CS0, offset 0, IO size 128K */
+		rb-gpios = <&gpio3 1 GPIO_ACTIVE_HIGH>;	/* gpio_65 for R/B */
 
 		gpmc,sync-read;
 		gpmc,sync-write;
-- 
2.11.0

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

* Re: [PATCH v4 00/16] OMAP2+ OneNAND driver update
  2017-11-14 21:48   ` Tony Lindgren
@ 2017-11-14 22:53     ` Ladislav Michl
  -1 siblings, 0 replies; 114+ messages in thread
From: Ladislav Michl @ 2017-11-14 22:53 UTC (permalink / raw)
  To: Tony Lindgren
  Cc: Boris Brezillon, Aaro Koskinen, Peter Ujfalusi, Kyungmin Park,
	linux-mtd, linux-omap, Roger Quadros

On Tue, Nov 14, 2017 at 01:48:53PM -0800, Tony Lindgren wrote:
> Hi,
> 
> * Ladislav Michl <ladis@linux-mips.org> [171111 21:13]:
> > Hi there,
> > 
> > this patch serie updates OMAP2+ OneNAND driver to the present times, making
> > it fully DT configurable, using libgpio and dmaengine apis.
> > 
> > Please note that unlike previous driver version, which basically ignored
> > DT specified timings, this one relies on it, so it is important to get
> > it right in your DT (dumping it from previous kernel version).
> > 
> > In case synchronous timings is requested, it is okay to specify timings
> > for the slowest chip ever used for you board as it is evetually optimized
> > after chip probe.
> > 
> > Original driver used DMA only if user specified r/b gpio in platform
> > data, now DMA is used unconditionally and PIO mode is used as fallback.
> > 
> > In case anyone wants to give it a try, few DT related changes are needed:
> > - onenand node needs 'ti,omap2-onenand' compatible (for mailine boards this is
> >   done in patch 2)
> > - to use R/B pin, rb-gpios needs to be specified (for n900 and n8x0 this is
> >   done in patch 16, however patch lacks pinmux configuration.
> > 
> > Most notable changes from previous version:
> > - added dmaengine patches by Peter Ujfalusi
> > - added dt bindings documentation
> > - added cleanup patches
> > - DMA enabled by default
> > 
> > Also note that driver will fail probe OneNAND chip after patch 13 and start
> > working again after patch 14.
> > 
> > Testing and benchmarking very welcome.
> > 
> > Depends on "memory: omap-gpmc: Make 'bank-width' property optional"
> > https://patchwork.kernel.org/patch/10043259/
> 
> Thanks for doing this. I'm adding Aaro to Cc here, maybe he can test
> n8x0 as my n800 in my rack is not currently booting.
> 
> I've tested this series briefly on n900 by writing a 10MB file to
> onenand and comparing it to the original, and it seems to work so
> for patches 1 to 15 you can add:
> 
> Tested-by: Tony Lindgren <tony@atomide.com>
> 
> The last patch has a build error for n8x0, and in general we really
> should test this series on n8x0 before merging as the configuration
> is a little bit different. So I'd say we need an ack from Aaro there.

Just sent a quick update on that one.

> I've also acked the mach-omap2 touching patches so when others are
> happy this can be merged as a single set via the MTD tree.

While it is running for a few days on IGEPv2 boards in DMA mode without
issues, I'm still unsure whenever we should leave DMA enabled by default.
On the other side, it _was_ used on n900, but disabled later with device
tree introducion. So n8x0 is to be verified. I'll happily leave that
decision to others :-)

Best regards,
	ladis

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

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

* Re: [PATCH v4 00/16] OMAP2+ OneNAND driver update
@ 2017-11-14 22:53     ` Ladislav Michl
  0 siblings, 0 replies; 114+ messages in thread
From: Ladislav Michl @ 2017-11-14 22:53 UTC (permalink / raw)
  To: Tony Lindgren
  Cc: linux-mtd, linux-omap, Roger Quadros, Peter Ujfalusi,
	Boris Brezillon, Kyungmin Park, Aaro Koskinen

On Tue, Nov 14, 2017 at 01:48:53PM -0800, Tony Lindgren wrote:
> Hi,
> 
> * Ladislav Michl <ladis@linux-mips.org> [171111 21:13]:
> > Hi there,
> > 
> > this patch serie updates OMAP2+ OneNAND driver to the present times, making
> > it fully DT configurable, using libgpio and dmaengine apis.
> > 
> > Please note that unlike previous driver version, which basically ignored
> > DT specified timings, this one relies on it, so it is important to get
> > it right in your DT (dumping it from previous kernel version).
> > 
> > In case synchronous timings is requested, it is okay to specify timings
> > for the slowest chip ever used for you board as it is evetually optimized
> > after chip probe.
> > 
> > Original driver used DMA only if user specified r/b gpio in platform
> > data, now DMA is used unconditionally and PIO mode is used as fallback.
> > 
> > In case anyone wants to give it a try, few DT related changes are needed:
> > - onenand node needs 'ti,omap2-onenand' compatible (for mailine boards this is
> >   done in patch 2)
> > - to use R/B pin, rb-gpios needs to be specified (for n900 and n8x0 this is
> >   done in patch 16, however patch lacks pinmux configuration.
> > 
> > Most notable changes from previous version:
> > - added dmaengine patches by Peter Ujfalusi
> > - added dt bindings documentation
> > - added cleanup patches
> > - DMA enabled by default
> > 
> > Also note that driver will fail probe OneNAND chip after patch 13 and start
> > working again after patch 14.
> > 
> > Testing and benchmarking very welcome.
> > 
> > Depends on "memory: omap-gpmc: Make 'bank-width' property optional"
> > https://patchwork.kernel.org/patch/10043259/
> 
> Thanks for doing this. I'm adding Aaro to Cc here, maybe he can test
> n8x0 as my n800 in my rack is not currently booting.
> 
> I've tested this series briefly on n900 by writing a 10MB file to
> onenand and comparing it to the original, and it seems to work so
> for patches 1 to 15 you can add:
> 
> Tested-by: Tony Lindgren <tony@atomide.com>
> 
> The last patch has a build error for n8x0, and in general we really
> should test this series on n8x0 before merging as the configuration
> is a little bit different. So I'd say we need an ack from Aaro there.

Just sent a quick update on that one.

> I've also acked the mach-omap2 touching patches so when others are
> happy this can be merged as a single set via the MTD tree.

While it is running for a few days on IGEPv2 boards in DMA mode without
issues, I'm still unsure whenever we should leave DMA enabled by default.
On the other side, it _was_ used on n900, but disabled later with device
tree introducion. So n8x0 is to be verified. I'll happily leave that
decision to others :-)

Best regards,
	ladis

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

* Re: [PATCH v4 02/16] ARM: dts: OMAP2+: Add compatible property to onenand node
  2017-11-14 15:11     ` Roger Quadros
@ 2017-11-14 23:01       ` Ladislav Michl
  -1 siblings, 0 replies; 114+ messages in thread
From: Ladislav Michl @ 2017-11-14 23:01 UTC (permalink / raw)
  To: Roger Quadros
  Cc: Boris Brezillon, Tony Lindgren, Peter Ujfalusi, Kyungmin Park,
	linux-mtd, linux-omap

On Tue, Nov 14, 2017 at 05:11:47PM +0200, Roger Quadros wrote:
> Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki. Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki

Oops? ^

> On 11/11/17 23:17, Ladislav Michl wrote:
> > OMAP onenand nodes are missing compatible property, add it.
> > 
> > Signed-off-by: Ladislav Michl <ladis@linux-mips.org>
> 
> Acked-by: Roger Quadros <rogerq@ti.com>
> 
> How about updating bindings/mtd/gpmc-onenand.txt in a separate patch?

Already done, but I messed up sending, so you do not see first patch as reply
to cover letter. I'm sorry for that.

	ladis

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

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

* Re: [PATCH v4 02/16] ARM: dts: OMAP2+: Add compatible property to onenand node
@ 2017-11-14 23:01       ` Ladislav Michl
  0 siblings, 0 replies; 114+ messages in thread
From: Ladislav Michl @ 2017-11-14 23:01 UTC (permalink / raw)
  To: Roger Quadros
  Cc: linux-mtd, linux-omap, Tony Lindgren, Peter Ujfalusi,
	Boris Brezillon, Kyungmin Park

On Tue, Nov 14, 2017 at 05:11:47PM +0200, Roger Quadros wrote:
> Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki. Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki

Oops? ^

> On 11/11/17 23:17, Ladislav Michl wrote:
> > OMAP onenand nodes are missing compatible property, add it.
> > 
> > Signed-off-by: Ladislav Michl <ladis@linux-mips.org>
> 
> Acked-by: Roger Quadros <rogerq@ti.com>
> 
> How about updating bindings/mtd/gpmc-onenand.txt in a separate patch?

Already done, but I messed up sending, so you do not see first patch as reply
to cover letter. I'm sorry for that.

	ladis

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

* Re: [PATCH v4 00/16] OMAP2+ OneNAND driver update
  2017-11-11 21:12 ` Ladislav Michl
@ 2017-11-15  8:10   ` Peter Ujfalusi
  -1 siblings, 0 replies; 114+ messages in thread
From: Peter Ujfalusi @ 2017-11-15  8:10 UTC (permalink / raw)
  To: Ladislav Michl, linux-mtd, linux-omap
  Cc: Tony Lindgren, Boris Brezillon, Kyungmin Park, Roger Quadros



On 2017-11-11 23:12, Ladislav Michl wrote:
> Hi there,
> 
> this patch serie updates OMAP2+ OneNAND driver to the present times, making
> it fully DT configurable, using libgpio and dmaengine apis.
> 
> Please note that unlike previous driver version, which basically ignored
> DT specified timings, this one relies on it, so it is important to get
> it right in your DT (dumping it from previous kernel version).
> 
> In case synchronous timings is requested, it is okay to specify timings
> for the slowest chip ever used for you board as it is evetually optimized
> after chip probe.
> 
> Original driver used DMA only if user specified r/b gpio in platform
> data, now DMA is used unconditionally and PIO mode is used as fallback.
> 
> In case anyone wants to give it a try, few DT related changes are needed:
> - onenand node needs 'ti,omap2-onenand' compatible (for mailine boards this is
>   done in patch 2)
> - to use R/B pin, rb-gpios needs to be specified (for n900 and n8x0 this is
>   done in patch 16, however patch lacks pinmux configuration.
> 
> Most notable changes from previous version:
> - added dmaengine patches by Peter Ujfalusi
> - added dt bindings documentation
> - added cleanup patches
> - DMA enabled by default
> 
> Also note that driver will fail probe OneNAND chip after patch 13 and start
> working again after patch 14.

Thanks for the hard work!
to all:
Reviewed-by: Peter Ujfalusi <peter.ujfalusi@ti.com>

> 
> Testing and benchmarking very welcome.
> 
> Depends on "memory: omap-gpmc: Make 'bank-width' property optional"
> https://patchwork.kernel.org/patch/10043259/
> 
> Ladislav Michl (13):
>   dt-bindings: mtd: gpmc-onenand: Update properties description
>   ARM: dts: OMAP2+: Add compatible property to onenand node
>   ARM: dts: omap3-igep: Update onenand node timings
>   mtd: onenand: omap2: Remove regulator support
>   mtd: onenand: omap2: Remove skip initial unlocking support
>   mtd: onenand: omap2: Remove partitioning support from platform data
>   mtd: onenand: omap2: Account waiting time as waiting on IO
>   mtd: onenand: omap2: Unify OMAP2 and OMAP3 DMA implementation
>   mtd: onenand: omap2: Do not make delay for GPIO OMAP3 specific
>   memory: omap-gpmc: Refactor OneNAND support
>   mtd: onenand: omap2: Configure driver from DT
>   ARM: OMAP2+: Remove gpmc-onenand
>   ARM: dts: Nokia: Use R/B pin
> 
> Peter Ujfalusi (2):
>   mtd: onenand: omap2: Simplify the DMA setup for various paths
>   mtd: onenand: omap2: Convert to use dmaengine for memcpy
> 
>  .../devicetree/bindings/mtd/gpmc-onenand.txt       |   6 +-
>  arch/arm/boot/dts/omap2420-n8x0-common.dtsi        |   5 +-
>  arch/arm/boot/dts/omap3-igep.dtsi                  |  30 +-
>  arch/arm/boot/dts/omap3-n900.dts                   |   2 +
>  arch/arm/boot/dts/omap3-n950-n9.dtsi               |   1 +
>  arch/arm/boot/dts/omap3430-sdp.dts                 |   1 +
>  arch/arm/mach-omap2/Makefile                       |   3 -
>  arch/arm/mach-omap2/gpmc-onenand.c                 | 409 ---------------
>  drivers/memory/omap-gpmc.c                         | 158 ++++--
>  drivers/mtd/onenand/omap2.c                        | 580 ++++++++-------------
>  include/linux/omap-gpmc.h                          |  25 +
>  include/linux/platform_data/mtd-onenand-omap2.h    |  34 --
>  12 files changed, 389 insertions(+), 865 deletions(-)
>  delete mode 100644 arch/arm/mach-omap2/gpmc-onenand.c
>  delete mode 100644 include/linux/platform_data/mtd-onenand-omap2.h
> 

- Péter

Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki.
Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki

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

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

* Re: [PATCH v4 00/16] OMAP2+ OneNAND driver update
@ 2017-11-15  8:10   ` Peter Ujfalusi
  0 siblings, 0 replies; 114+ messages in thread
From: Peter Ujfalusi @ 2017-11-15  8:10 UTC (permalink / raw)
  To: Ladislav Michl, linux-mtd, linux-omap
  Cc: Roger Quadros, Tony Lindgren, Boris Brezillon, Kyungmin Park



On 2017-11-11 23:12, Ladislav Michl wrote:
> Hi there,
> 
> this patch serie updates OMAP2+ OneNAND driver to the present times, making
> it fully DT configurable, using libgpio and dmaengine apis.
> 
> Please note that unlike previous driver version, which basically ignored
> DT specified timings, this one relies on it, so it is important to get
> it right in your DT (dumping it from previous kernel version).
> 
> In case synchronous timings is requested, it is okay to specify timings
> for the slowest chip ever used for you board as it is evetually optimized
> after chip probe.
> 
> Original driver used DMA only if user specified r/b gpio in platform
> data, now DMA is used unconditionally and PIO mode is used as fallback.
> 
> In case anyone wants to give it a try, few DT related changes are needed:
> - onenand node needs 'ti,omap2-onenand' compatible (for mailine boards this is
>   done in patch 2)
> - to use R/B pin, rb-gpios needs to be specified (for n900 and n8x0 this is
>   done in patch 16, however patch lacks pinmux configuration.
> 
> Most notable changes from previous version:
> - added dmaengine patches by Peter Ujfalusi
> - added dt bindings documentation
> - added cleanup patches
> - DMA enabled by default
> 
> Also note that driver will fail probe OneNAND chip after patch 13 and start
> working again after patch 14.

Thanks for the hard work!
to all:
Reviewed-by: Peter Ujfalusi <peter.ujfalusi@ti.com>

> 
> Testing and benchmarking very welcome.
> 
> Depends on "memory: omap-gpmc: Make 'bank-width' property optional"
> https://patchwork.kernel.org/patch/10043259/
> 
> Ladislav Michl (13):
>   dt-bindings: mtd: gpmc-onenand: Update properties description
>   ARM: dts: OMAP2+: Add compatible property to onenand node
>   ARM: dts: omap3-igep: Update onenand node timings
>   mtd: onenand: omap2: Remove regulator support
>   mtd: onenand: omap2: Remove skip initial unlocking support
>   mtd: onenand: omap2: Remove partitioning support from platform data
>   mtd: onenand: omap2: Account waiting time as waiting on IO
>   mtd: onenand: omap2: Unify OMAP2 and OMAP3 DMA implementation
>   mtd: onenand: omap2: Do not make delay for GPIO OMAP3 specific
>   memory: omap-gpmc: Refactor OneNAND support
>   mtd: onenand: omap2: Configure driver from DT
>   ARM: OMAP2+: Remove gpmc-onenand
>   ARM: dts: Nokia: Use R/B pin
> 
> Peter Ujfalusi (2):
>   mtd: onenand: omap2: Simplify the DMA setup for various paths
>   mtd: onenand: omap2: Convert to use dmaengine for memcpy
> 
>  .../devicetree/bindings/mtd/gpmc-onenand.txt       |   6 +-
>  arch/arm/boot/dts/omap2420-n8x0-common.dtsi        |   5 +-
>  arch/arm/boot/dts/omap3-igep.dtsi                  |  30 +-
>  arch/arm/boot/dts/omap3-n900.dts                   |   2 +
>  arch/arm/boot/dts/omap3-n950-n9.dtsi               |   1 +
>  arch/arm/boot/dts/omap3430-sdp.dts                 |   1 +
>  arch/arm/mach-omap2/Makefile                       |   3 -
>  arch/arm/mach-omap2/gpmc-onenand.c                 | 409 ---------------
>  drivers/memory/omap-gpmc.c                         | 158 ++++--
>  drivers/mtd/onenand/omap2.c                        | 580 ++++++++-------------
>  include/linux/omap-gpmc.h                          |  25 +
>  include/linux/platform_data/mtd-onenand-omap2.h    |  34 --
>  12 files changed, 389 insertions(+), 865 deletions(-)
>  delete mode 100644 arch/arm/mach-omap2/gpmc-onenand.c
>  delete mode 100644 include/linux/platform_data/mtd-onenand-omap2.h
> 

- Péter

Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki.
Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki

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

* Re: [PATCH v4 08/16] mtd: onenand: omap2: Simplify the DMA setup for various paths
  2017-11-11 21:21   ` Ladislav Michl
@ 2017-11-15  8:35     ` Roger Quadros
  -1 siblings, 0 replies; 114+ messages in thread
From: Roger Quadros @ 2017-11-15  8:35 UTC (permalink / raw)
  To: Ladislav Michl, linux-mtd, linux-omap
  Cc: Tony Lindgren, Peter Ujfalusi, Kyungmin Park, Boris Brezillon

On 11/11/17 23:21, Ladislav Michl wrote:
> From: Peter Ujfalusi <peter.ujfalusi@ti.com>
> 
> We have 4 functions containing almost identical DMA setup code. Create one
> function which can set up the DMA for both read and write and use this in
> place for the setup code in the driver.
> The new function will use wait_for_completion_io_timeout() and it will
> figure out the best data_type to be used for the transfer instead of
> hardwiring 32 or 16 bit data.
> 
> Signed-off-by: Peter Ujfalusi <peter.ujfalusi@ti.com>
> Signed-off-by: Ladislav Michl <ladis@linux-mips.org>

Acked-by: Roger Quadros <rogerq@ti.com>

> ---
>  Changes:
>  -v4: new patch
> 
>  drivers/mtd/onenand/omap2.c | 109 ++++++++++++++++++--------------------------
>  1 file changed, 45 insertions(+), 64 deletions(-)
> 
> diff --git a/drivers/mtd/onenand/omap2.c b/drivers/mtd/onenand/omap2.c
> index 0e7772e16d75..d22163271dc9 100644
> --- a/drivers/mtd/onenand/omap2.c
> +++ b/drivers/mtd/onenand/omap2.c
> @@ -288,6 +288,33 @@ static inline int omap2_onenand_bufferram_offset(struct mtd_info *mtd, int area)
>  	return 0;
>  }
>  
> +static inline int omap2_onenand_dma_transfer(struct omap2_onenand *c,
> +					     dma_addr_t src, dma_addr_t dst,
> +					     size_t count)
> +{
> +	int data_type = __ffs((src | dst | count));
> +
> +	if (data_type > OMAP_DMA_DATA_TYPE_S32)
> +		data_type = OMAP_DMA_DATA_TYPE_S32;
> +
> +	omap_set_dma_transfer_params(c->dma_channel, data_type,
> +				     count / BIT(data_type), 1, 0, 0, 0);
> +	omap_set_dma_src_params(c->dma_channel, 0, OMAP_DMA_AMODE_POST_INC,
> +				src, 0, 0);
> +	omap_set_dma_dest_params(c->dma_channel, 0, OMAP_DMA_AMODE_POST_INC,
> +				 dst, 0, 0);
> +
> +	reinit_completion(&c->dma_done);
> +	omap_start_dma(c->dma_channel);
> +	if (!wait_for_completion_io_timeout(&c->dma_done,
> +					    msecs_to_jiffies(20))) {
> +		omap_stop_dma(c->dma_channel);
> +		return -ETIMEDOUT;
> +	}
> +
> +	return 0;
> +}
> +
>  #if defined(CONFIG_ARCH_OMAP3) || defined(MULTI_OMAP2)
>  
>  static int omap3_onenand_read_bufferram(struct mtd_info *mtd, int area,
> @@ -298,10 +325,9 @@ static int omap3_onenand_read_bufferram(struct mtd_info *mtd, int area,
>  	struct onenand_chip *this = mtd->priv;
>  	dma_addr_t dma_src, dma_dst;
>  	int bram_offset;
> -	unsigned long timeout;
>  	void *buf = (void *)buffer;
>  	size_t xtra;
> -	volatile unsigned *done;
> +	int ret;
>  
>  	bram_offset = omap2_onenand_bufferram_offset(mtd, area) + area + offset;
>  	if (bram_offset & 3 || (size_t)buf & 3 || count < 384)
> @@ -338,25 +364,10 @@ static int omap3_onenand_read_bufferram(struct mtd_info *mtd, int area,
>  		goto out_copy;
>  	}
>  
> -	omap_set_dma_transfer_params(c->dma_channel, OMAP_DMA_DATA_TYPE_S32,
> -				     count >> 2, 1, 0, 0, 0);
> -	omap_set_dma_src_params(c->dma_channel, 0, OMAP_DMA_AMODE_POST_INC,
> -				dma_src, 0, 0);
> -	omap_set_dma_dest_params(c->dma_channel, 0, OMAP_DMA_AMODE_POST_INC,
> -				 dma_dst, 0, 0);
> -
> -	reinit_completion(&c->dma_done);
> -	omap_start_dma(c->dma_channel);
> -
> -	timeout = jiffies + msecs_to_jiffies(20);
> -	done = &c->dma_done.done;
> -	while (time_before(jiffies, timeout))
> -		if (*done)
> -			break;
> -
> +	ret = omap2_onenand_dma_transfer(c, dma_src, dma_dst, count);
>  	dma_unmap_single(&c->pdev->dev, dma_dst, count, DMA_FROM_DEVICE);
>  
> -	if (!*done) {
> +	if (ret) {
>  		dev_err(&c->pdev->dev, "timeout waiting for DMA\n");
>  		goto out_copy;
>  	}
> @@ -376,9 +387,8 @@ static int omap3_onenand_write_bufferram(struct mtd_info *mtd, int area,
>  	struct onenand_chip *this = mtd->priv;
>  	dma_addr_t dma_src, dma_dst;
>  	int bram_offset;
> -	unsigned long timeout;
>  	void *buf = (void *)buffer;
> -	volatile unsigned *done;
> +	int ret;
>  
>  	bram_offset = omap2_onenand_bufferram_offset(mtd, area) + area + offset;
>  	if (bram_offset & 3 || (size_t)buf & 3 || count < 384)
> @@ -409,25 +419,10 @@ static int omap3_onenand_write_bufferram(struct mtd_info *mtd, int area,
>  		return -1;
>  	}
>  
> -	omap_set_dma_transfer_params(c->dma_channel, OMAP_DMA_DATA_TYPE_S32,
> -				     count >> 2, 1, 0, 0, 0);
> -	omap_set_dma_src_params(c->dma_channel, 0, OMAP_DMA_AMODE_POST_INC,
> -				dma_src, 0, 0);
> -	omap_set_dma_dest_params(c->dma_channel, 0, OMAP_DMA_AMODE_POST_INC,
> -				 dma_dst, 0, 0);
> -
> -	reinit_completion(&c->dma_done);
> -	omap_start_dma(c->dma_channel);
> -
> -	timeout = jiffies + msecs_to_jiffies(20);
> -	done = &c->dma_done.done;
> -	while (time_before(jiffies, timeout))
> -		if (*done)
> -			break;
> -
> +	ret = omap2_onenand_dma_transfer(c, dma_src, dma_dst, count);
>  	dma_unmap_single(&c->pdev->dev, dma_src, count, DMA_TO_DEVICE);
>  
> -	if (!*done) {
> +	if (ret) {
>  		dev_err(&c->pdev->dev, "timeout waiting for DMA\n");
>  		goto out_copy;
>  	}
> @@ -466,7 +461,7 @@ static int omap2_onenand_read_bufferram(struct mtd_info *mtd, int area,
>  	struct omap2_onenand *c = container_of(mtd, struct omap2_onenand, mtd);
>  	struct onenand_chip *this = mtd->priv;
>  	dma_addr_t dma_src, dma_dst;
> -	int bram_offset;
> +	int bram_offset, ret;
>  
>  	bram_offset = omap2_onenand_bufferram_offset(mtd, area) + area + offset;
>  	/* DMA is not used.  Revisit PM requirements before enabling it. */
> @@ -488,20 +483,13 @@ static int omap2_onenand_read_bufferram(struct mtd_info *mtd, int area,
>  		return -1;
>  	}
>  
> -	omap_set_dma_transfer_params(c->dma_channel, OMAP_DMA_DATA_TYPE_S32,
> -				     count / 4, 1, 0, 0, 0);
> -	omap_set_dma_src_params(c->dma_channel, 0, OMAP_DMA_AMODE_POST_INC,
> -				dma_src, 0, 0);
> -	omap_set_dma_dest_params(c->dma_channel, 0, OMAP_DMA_AMODE_POST_INC,
> -				 dma_dst, 0, 0);
> -
> -	reinit_completion(&c->dma_done);
> -	omap_start_dma(c->dma_channel);
> -	wait_for_completion(&c->dma_done);
> -
> +	ret = omap2_onenand_dma_transfer(c, dma_src, dma_dst, count);
>  	dma_unmap_single(&c->pdev->dev, dma_dst, count, DMA_FROM_DEVICE);
>  
> -	return 0;
> +	if (ret)
> +		dev_err(&c->pdev->dev, "timeout waiting for DMA\n");
> +
> +	return ret;
>  }
>  
>  static int omap2_onenand_write_bufferram(struct mtd_info *mtd, int area,
> @@ -511,7 +499,7 @@ static int omap2_onenand_write_bufferram(struct mtd_info *mtd, int area,
>  	struct omap2_onenand *c = container_of(mtd, struct omap2_onenand, mtd);
>  	struct onenand_chip *this = mtd->priv;
>  	dma_addr_t dma_src, dma_dst;
> -	int bram_offset;
> +	int bram_offset, ret;
>  
>  	bram_offset = omap2_onenand_bufferram_offset(mtd, area) + area + offset;
>  	/* DMA is not used.  Revisit PM requirements before enabling it. */
> @@ -533,20 +521,13 @@ static int omap2_onenand_write_bufferram(struct mtd_info *mtd, int area,
>  		return -1;
>  	}
>  
> -	omap_set_dma_transfer_params(c->dma_channel, OMAP_DMA_DATA_TYPE_S16,
> -				     count / 2, 1, 0, 0, 0);
> -	omap_set_dma_src_params(c->dma_channel, 0, OMAP_DMA_AMODE_POST_INC,
> -				dma_src, 0, 0);
> -	omap_set_dma_dest_params(c->dma_channel, 0, OMAP_DMA_AMODE_POST_INC,
> -				 dma_dst, 0, 0);
> -
> -	reinit_completion(&c->dma_done);
> -	omap_start_dma(c->dma_channel);
> -	wait_for_completion(&c->dma_done);
> -
> +	ret = omap2_onenand_dma_transfer(c, dma_src, dma_dst, count);
>  	dma_unmap_single(&c->pdev->dev, dma_src, count, DMA_TO_DEVICE);
>  
> -	return 0;
> +	if (ret)
> +		dev_err(&c->pdev->dev, "timeout waiting for DMA\n");
> +
> +	return ret;
>  }
>  
>  #else
> 

-- 
cheers,
-roger

Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki. Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki

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

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

* Re: [PATCH v4 08/16] mtd: onenand: omap2: Simplify the DMA setup for various paths
@ 2017-11-15  8:35     ` Roger Quadros
  0 siblings, 0 replies; 114+ messages in thread
From: Roger Quadros @ 2017-11-15  8:35 UTC (permalink / raw)
  To: Ladislav Michl, linux-mtd, linux-omap
  Cc: Tony Lindgren, Peter Ujfalusi, Boris Brezillon, Kyungmin Park

On 11/11/17 23:21, Ladislav Michl wrote:
> From: Peter Ujfalusi <peter.ujfalusi@ti.com>
> 
> We have 4 functions containing almost identical DMA setup code. Create one
> function which can set up the DMA for both read and write and use this in
> place for the setup code in the driver.
> The new function will use wait_for_completion_io_timeout() and it will
> figure out the best data_type to be used for the transfer instead of
> hardwiring 32 or 16 bit data.
> 
> Signed-off-by: Peter Ujfalusi <peter.ujfalusi@ti.com>
> Signed-off-by: Ladislav Michl <ladis@linux-mips.org>

Acked-by: Roger Quadros <rogerq@ti.com>

> ---
>  Changes:
>  -v4: new patch
> 
>  drivers/mtd/onenand/omap2.c | 109 ++++++++++++++++++--------------------------
>  1 file changed, 45 insertions(+), 64 deletions(-)
> 
> diff --git a/drivers/mtd/onenand/omap2.c b/drivers/mtd/onenand/omap2.c
> index 0e7772e16d75..d22163271dc9 100644
> --- a/drivers/mtd/onenand/omap2.c
> +++ b/drivers/mtd/onenand/omap2.c
> @@ -288,6 +288,33 @@ static inline int omap2_onenand_bufferram_offset(struct mtd_info *mtd, int area)
>  	return 0;
>  }
>  
> +static inline int omap2_onenand_dma_transfer(struct omap2_onenand *c,
> +					     dma_addr_t src, dma_addr_t dst,
> +					     size_t count)
> +{
> +	int data_type = __ffs((src | dst | count));
> +
> +	if (data_type > OMAP_DMA_DATA_TYPE_S32)
> +		data_type = OMAP_DMA_DATA_TYPE_S32;
> +
> +	omap_set_dma_transfer_params(c->dma_channel, data_type,
> +				     count / BIT(data_type), 1, 0, 0, 0);
> +	omap_set_dma_src_params(c->dma_channel, 0, OMAP_DMA_AMODE_POST_INC,
> +				src, 0, 0);
> +	omap_set_dma_dest_params(c->dma_channel, 0, OMAP_DMA_AMODE_POST_INC,
> +				 dst, 0, 0);
> +
> +	reinit_completion(&c->dma_done);
> +	omap_start_dma(c->dma_channel);
> +	if (!wait_for_completion_io_timeout(&c->dma_done,
> +					    msecs_to_jiffies(20))) {
> +		omap_stop_dma(c->dma_channel);
> +		return -ETIMEDOUT;
> +	}
> +
> +	return 0;
> +}
> +
>  #if defined(CONFIG_ARCH_OMAP3) || defined(MULTI_OMAP2)
>  
>  static int omap3_onenand_read_bufferram(struct mtd_info *mtd, int area,
> @@ -298,10 +325,9 @@ static int omap3_onenand_read_bufferram(struct mtd_info *mtd, int area,
>  	struct onenand_chip *this = mtd->priv;
>  	dma_addr_t dma_src, dma_dst;
>  	int bram_offset;
> -	unsigned long timeout;
>  	void *buf = (void *)buffer;
>  	size_t xtra;
> -	volatile unsigned *done;
> +	int ret;
>  
>  	bram_offset = omap2_onenand_bufferram_offset(mtd, area) + area + offset;
>  	if (bram_offset & 3 || (size_t)buf & 3 || count < 384)
> @@ -338,25 +364,10 @@ static int omap3_onenand_read_bufferram(struct mtd_info *mtd, int area,
>  		goto out_copy;
>  	}
>  
> -	omap_set_dma_transfer_params(c->dma_channel, OMAP_DMA_DATA_TYPE_S32,
> -				     count >> 2, 1, 0, 0, 0);
> -	omap_set_dma_src_params(c->dma_channel, 0, OMAP_DMA_AMODE_POST_INC,
> -				dma_src, 0, 0);
> -	omap_set_dma_dest_params(c->dma_channel, 0, OMAP_DMA_AMODE_POST_INC,
> -				 dma_dst, 0, 0);
> -
> -	reinit_completion(&c->dma_done);
> -	omap_start_dma(c->dma_channel);
> -
> -	timeout = jiffies + msecs_to_jiffies(20);
> -	done = &c->dma_done.done;
> -	while (time_before(jiffies, timeout))
> -		if (*done)
> -			break;
> -
> +	ret = omap2_onenand_dma_transfer(c, dma_src, dma_dst, count);
>  	dma_unmap_single(&c->pdev->dev, dma_dst, count, DMA_FROM_DEVICE);
>  
> -	if (!*done) {
> +	if (ret) {
>  		dev_err(&c->pdev->dev, "timeout waiting for DMA\n");
>  		goto out_copy;
>  	}
> @@ -376,9 +387,8 @@ static int omap3_onenand_write_bufferram(struct mtd_info *mtd, int area,
>  	struct onenand_chip *this = mtd->priv;
>  	dma_addr_t dma_src, dma_dst;
>  	int bram_offset;
> -	unsigned long timeout;
>  	void *buf = (void *)buffer;
> -	volatile unsigned *done;
> +	int ret;
>  
>  	bram_offset = omap2_onenand_bufferram_offset(mtd, area) + area + offset;
>  	if (bram_offset & 3 || (size_t)buf & 3 || count < 384)
> @@ -409,25 +419,10 @@ static int omap3_onenand_write_bufferram(struct mtd_info *mtd, int area,
>  		return -1;
>  	}
>  
> -	omap_set_dma_transfer_params(c->dma_channel, OMAP_DMA_DATA_TYPE_S32,
> -				     count >> 2, 1, 0, 0, 0);
> -	omap_set_dma_src_params(c->dma_channel, 0, OMAP_DMA_AMODE_POST_INC,
> -				dma_src, 0, 0);
> -	omap_set_dma_dest_params(c->dma_channel, 0, OMAP_DMA_AMODE_POST_INC,
> -				 dma_dst, 0, 0);
> -
> -	reinit_completion(&c->dma_done);
> -	omap_start_dma(c->dma_channel);
> -
> -	timeout = jiffies + msecs_to_jiffies(20);
> -	done = &c->dma_done.done;
> -	while (time_before(jiffies, timeout))
> -		if (*done)
> -			break;
> -
> +	ret = omap2_onenand_dma_transfer(c, dma_src, dma_dst, count);
>  	dma_unmap_single(&c->pdev->dev, dma_src, count, DMA_TO_DEVICE);
>  
> -	if (!*done) {
> +	if (ret) {
>  		dev_err(&c->pdev->dev, "timeout waiting for DMA\n");
>  		goto out_copy;
>  	}
> @@ -466,7 +461,7 @@ static int omap2_onenand_read_bufferram(struct mtd_info *mtd, int area,
>  	struct omap2_onenand *c = container_of(mtd, struct omap2_onenand, mtd);
>  	struct onenand_chip *this = mtd->priv;
>  	dma_addr_t dma_src, dma_dst;
> -	int bram_offset;
> +	int bram_offset, ret;
>  
>  	bram_offset = omap2_onenand_bufferram_offset(mtd, area) + area + offset;
>  	/* DMA is not used.  Revisit PM requirements before enabling it. */
> @@ -488,20 +483,13 @@ static int omap2_onenand_read_bufferram(struct mtd_info *mtd, int area,
>  		return -1;
>  	}
>  
> -	omap_set_dma_transfer_params(c->dma_channel, OMAP_DMA_DATA_TYPE_S32,
> -				     count / 4, 1, 0, 0, 0);
> -	omap_set_dma_src_params(c->dma_channel, 0, OMAP_DMA_AMODE_POST_INC,
> -				dma_src, 0, 0);
> -	omap_set_dma_dest_params(c->dma_channel, 0, OMAP_DMA_AMODE_POST_INC,
> -				 dma_dst, 0, 0);
> -
> -	reinit_completion(&c->dma_done);
> -	omap_start_dma(c->dma_channel);
> -	wait_for_completion(&c->dma_done);
> -
> +	ret = omap2_onenand_dma_transfer(c, dma_src, dma_dst, count);
>  	dma_unmap_single(&c->pdev->dev, dma_dst, count, DMA_FROM_DEVICE);
>  
> -	return 0;
> +	if (ret)
> +		dev_err(&c->pdev->dev, "timeout waiting for DMA\n");
> +
> +	return ret;
>  }
>  
>  static int omap2_onenand_write_bufferram(struct mtd_info *mtd, int area,
> @@ -511,7 +499,7 @@ static int omap2_onenand_write_bufferram(struct mtd_info *mtd, int area,
>  	struct omap2_onenand *c = container_of(mtd, struct omap2_onenand, mtd);
>  	struct onenand_chip *this = mtd->priv;
>  	dma_addr_t dma_src, dma_dst;
> -	int bram_offset;
> +	int bram_offset, ret;
>  
>  	bram_offset = omap2_onenand_bufferram_offset(mtd, area) + area + offset;
>  	/* DMA is not used.  Revisit PM requirements before enabling it. */
> @@ -533,20 +521,13 @@ static int omap2_onenand_write_bufferram(struct mtd_info *mtd, int area,
>  		return -1;
>  	}
>  
> -	omap_set_dma_transfer_params(c->dma_channel, OMAP_DMA_DATA_TYPE_S16,
> -				     count / 2, 1, 0, 0, 0);
> -	omap_set_dma_src_params(c->dma_channel, 0, OMAP_DMA_AMODE_POST_INC,
> -				dma_src, 0, 0);
> -	omap_set_dma_dest_params(c->dma_channel, 0, OMAP_DMA_AMODE_POST_INC,
> -				 dma_dst, 0, 0);
> -
> -	reinit_completion(&c->dma_done);
> -	omap_start_dma(c->dma_channel);
> -	wait_for_completion(&c->dma_done);
> -
> +	ret = omap2_onenand_dma_transfer(c, dma_src, dma_dst, count);
>  	dma_unmap_single(&c->pdev->dev, dma_src, count, DMA_TO_DEVICE);
>  
> -	return 0;
> +	if (ret)
> +		dev_err(&c->pdev->dev, "timeout waiting for DMA\n");
> +
> +	return ret;
>  }
>  
>  #else
> 

-- 
cheers,
-roger

Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki. Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki

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

* Re: [PATCH v4 09/16] mtd: onenand: omap2: Unify OMAP2 and OMAP3 DMA implementation
  2017-11-11 21:22   ` Ladislav Michl
@ 2017-11-15  8:38     ` Roger Quadros
  -1 siblings, 0 replies; 114+ messages in thread
From: Roger Quadros @ 2017-11-15  8:38 UTC (permalink / raw)
  To: Ladislav Michl, linux-mtd, linux-omap
  Cc: Tony Lindgren, Peter Ujfalusi, Kyungmin Park, Boris Brezillon

On 11/11/17 23:22, Ladislav Michl wrote:
> Since the very first commit (36cd4fb5d277: "[MTD] [OneNAND] Add OMAP2 / OMAP3
> OneNAND driver") DMA is disabled for OMAP2. Later fixes thus went only into
> OMAP3 specific DMA functions which turned out not to be so OMAP3 specific,
> so merge those two implementations.
> 
> Signed-off-by: Ladislav Michl <ladis@linux-mips.org>

Acked-by: Roger Quadros <rogerq@ti.com>

> ---
>  Changes:
>  -v3: new patch
>  -v4: rebase on top of Peter's patch
> 
>  drivers/mtd/onenand/omap2.c | 129 ++------------------------------------------
>  1 file changed, 4 insertions(+), 125 deletions(-)
> 
> diff --git a/drivers/mtd/onenand/omap2.c b/drivers/mtd/onenand/omap2.c
> index d22163271dc9..36314124488d 100644
> --- a/drivers/mtd/onenand/omap2.c
> +++ b/drivers/mtd/onenand/omap2.c
> @@ -315,9 +315,7 @@ static inline int omap2_onenand_dma_transfer(struct omap2_onenand *c,
>  	return 0;
>  }
>  
> -#if defined(CONFIG_ARCH_OMAP3) || defined(MULTI_OMAP2)
> -
> -static int omap3_onenand_read_bufferram(struct mtd_info *mtd, int area,
> +static int omap2_onenand_read_bufferram(struct mtd_info *mtd, int area,
>  					unsigned char *buffer, int offset,
>  					size_t count)
>  {
> @@ -379,7 +377,7 @@ static int omap3_onenand_read_bufferram(struct mtd_info *mtd, int area,
>  	return 0;
>  }
>  
> -static int omap3_onenand_write_bufferram(struct mtd_info *mtd, int area,
> +static int omap2_onenand_write_bufferram(struct mtd_info *mtd, int area,
>  					 const unsigned char *buffer,
>  					 int offset, size_t count)
>  {
> @@ -434,120 +432,6 @@ static int omap3_onenand_write_bufferram(struct mtd_info *mtd, int area,
>  	return 0;
>  }
>  
> -#else
> -
> -static int omap3_onenand_read_bufferram(struct mtd_info *mtd, int area,
> -					unsigned char *buffer, int offset,
> -					size_t count)
> -{
> -	return -ENOSYS;
> -}
> -
> -static int omap3_onenand_write_bufferram(struct mtd_info *mtd, int area,
> -					 const unsigned char *buffer,
> -					 int offset, size_t count)
> -{
> -	return -ENOSYS;
> -}
> -
> -#endif
> -
> -#if defined(CONFIG_ARCH_OMAP2) || defined(MULTI_OMAP2)
> -
> -static int omap2_onenand_read_bufferram(struct mtd_info *mtd, int area,
> -					unsigned char *buffer, int offset,
> -					size_t count)
> -{
> -	struct omap2_onenand *c = container_of(mtd, struct omap2_onenand, mtd);
> -	struct onenand_chip *this = mtd->priv;
> -	dma_addr_t dma_src, dma_dst;
> -	int bram_offset, ret;
> -
> -	bram_offset = omap2_onenand_bufferram_offset(mtd, area) + area + offset;
> -	/* DMA is not used.  Revisit PM requirements before enabling it. */
> -	if (1 || (c->dma_channel < 0) ||
> -	    ((void *) buffer >= (void *) high_memory) || (bram_offset & 3) ||
> -	    (((unsigned int) buffer) & 3) || (count < 1024) || (count & 3)) {
> -		memcpy(buffer, (__force void *)(this->base + bram_offset),
> -		       count);
> -		return 0;
> -	}
> -
> -	dma_src = c->phys_base + bram_offset;
> -	dma_dst = dma_map_single(&c->pdev->dev, buffer, count,
> -				 DMA_FROM_DEVICE);
> -	if (dma_mapping_error(&c->pdev->dev, dma_dst)) {
> -		dev_err(&c->pdev->dev,
> -			"Couldn't DMA map a %d byte buffer\n",
> -			count);
> -		return -1;
> -	}
> -
> -	ret = omap2_onenand_dma_transfer(c, dma_src, dma_dst, count);
> -	dma_unmap_single(&c->pdev->dev, dma_dst, count, DMA_FROM_DEVICE);
> -
> -	if (ret)
> -		dev_err(&c->pdev->dev, "timeout waiting for DMA\n");
> -
> -	return ret;
> -}
> -
> -static int omap2_onenand_write_bufferram(struct mtd_info *mtd, int area,
> -					 const unsigned char *buffer,
> -					 int offset, size_t count)
> -{
> -	struct omap2_onenand *c = container_of(mtd, struct omap2_onenand, mtd);
> -	struct onenand_chip *this = mtd->priv;
> -	dma_addr_t dma_src, dma_dst;
> -	int bram_offset, ret;
> -
> -	bram_offset = omap2_onenand_bufferram_offset(mtd, area) + area + offset;
> -	/* DMA is not used.  Revisit PM requirements before enabling it. */
> -	if (1 || (c->dma_channel < 0) ||
> -	    ((void *) buffer >= (void *) high_memory) || (bram_offset & 3) ||
> -	    (((unsigned int) buffer) & 3) || (count < 1024) || (count & 3)) {
> -		memcpy((__force void *)(this->base + bram_offset), buffer,
> -		       count);
> -		return 0;
> -	}
> -
> -	dma_src = dma_map_single(&c->pdev->dev, (void *) buffer, count,
> -				 DMA_TO_DEVICE);
> -	dma_dst = c->phys_base + bram_offset;
> -	if (dma_mapping_error(&c->pdev->dev, dma_src)) {
> -		dev_err(&c->pdev->dev,
> -			"Couldn't DMA map a %d byte buffer\n",
> -			count);
> -		return -1;
> -	}
> -
> -	ret = omap2_onenand_dma_transfer(c, dma_src, dma_dst, count);
> -	dma_unmap_single(&c->pdev->dev, dma_src, count, DMA_TO_DEVICE);
> -
> -	if (ret)
> -		dev_err(&c->pdev->dev, "timeout waiting for DMA\n");
> -
> -	return ret;
> -}
> -
> -#else
> -
> -static int omap2_onenand_read_bufferram(struct mtd_info *mtd, int area,
> -					unsigned char *buffer, int offset,
> -					size_t count)
> -{
> -	return -ENOSYS;
> -}
> -
> -static int omap2_onenand_write_bufferram(struct mtd_info *mtd, int area,
> -					 const unsigned char *buffer,
> -					 int offset, size_t count)
> -{
> -	return -ENOSYS;
> -}
> -
> -#endif
> -
>  static struct platform_driver omap2_onenand_driver;
>  
>  static void omap2_onenand_shutdown(struct platform_device *pdev)
> @@ -671,13 +555,8 @@ static int omap2_onenand_probe(struct platform_device *pdev)
>  	this = &c->onenand;
>  	if (c->dma_channel >= 0) {
>  		this->wait = omap2_onenand_wait;
> -		if (c->flags & ONENAND_IN_OMAP34XX) {
> -			this->read_bufferram = omap3_onenand_read_bufferram;
> -			this->write_bufferram = omap3_onenand_write_bufferram;
> -		} else {
> -			this->read_bufferram = omap2_onenand_read_bufferram;
> -			this->write_bufferram = omap2_onenand_write_bufferram;
> -		}
> +		this->read_bufferram = omap2_onenand_read_bufferram;
> +		this->write_bufferram = omap2_onenand_write_bufferram;
>  	}
>  
>  	if ((r = onenand_scan(&c->mtd, 1)) < 0)
> 

-- 
cheers,
-roger

Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki. Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki

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

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

* Re: [PATCH v4 09/16] mtd: onenand: omap2: Unify OMAP2 and OMAP3 DMA implementation
@ 2017-11-15  8:38     ` Roger Quadros
  0 siblings, 0 replies; 114+ messages in thread
From: Roger Quadros @ 2017-11-15  8:38 UTC (permalink / raw)
  To: Ladislav Michl, linux-mtd, linux-omap
  Cc: Tony Lindgren, Peter Ujfalusi, Boris Brezillon, Kyungmin Park

On 11/11/17 23:22, Ladislav Michl wrote:
> Since the very first commit (36cd4fb5d277: "[MTD] [OneNAND] Add OMAP2 / OMAP3
> OneNAND driver") DMA is disabled for OMAP2. Later fixes thus went only into
> OMAP3 specific DMA functions which turned out not to be so OMAP3 specific,
> so merge those two implementations.
> 
> Signed-off-by: Ladislav Michl <ladis@linux-mips.org>

Acked-by: Roger Quadros <rogerq@ti.com>

> ---
>  Changes:
>  -v3: new patch
>  -v4: rebase on top of Peter's patch
> 
>  drivers/mtd/onenand/omap2.c | 129 ++------------------------------------------
>  1 file changed, 4 insertions(+), 125 deletions(-)
> 
> diff --git a/drivers/mtd/onenand/omap2.c b/drivers/mtd/onenand/omap2.c
> index d22163271dc9..36314124488d 100644
> --- a/drivers/mtd/onenand/omap2.c
> +++ b/drivers/mtd/onenand/omap2.c
> @@ -315,9 +315,7 @@ static inline int omap2_onenand_dma_transfer(struct omap2_onenand *c,
>  	return 0;
>  }
>  
> -#if defined(CONFIG_ARCH_OMAP3) || defined(MULTI_OMAP2)
> -
> -static int omap3_onenand_read_bufferram(struct mtd_info *mtd, int area,
> +static int omap2_onenand_read_bufferram(struct mtd_info *mtd, int area,
>  					unsigned char *buffer, int offset,
>  					size_t count)
>  {
> @@ -379,7 +377,7 @@ static int omap3_onenand_read_bufferram(struct mtd_info *mtd, int area,
>  	return 0;
>  }
>  
> -static int omap3_onenand_write_bufferram(struct mtd_info *mtd, int area,
> +static int omap2_onenand_write_bufferram(struct mtd_info *mtd, int area,
>  					 const unsigned char *buffer,
>  					 int offset, size_t count)
>  {
> @@ -434,120 +432,6 @@ static int omap3_onenand_write_bufferram(struct mtd_info *mtd, int area,
>  	return 0;
>  }
>  
> -#else
> -
> -static int omap3_onenand_read_bufferram(struct mtd_info *mtd, int area,
> -					unsigned char *buffer, int offset,
> -					size_t count)
> -{
> -	return -ENOSYS;
> -}
> -
> -static int omap3_onenand_write_bufferram(struct mtd_info *mtd, int area,
> -					 const unsigned char *buffer,
> -					 int offset, size_t count)
> -{
> -	return -ENOSYS;
> -}
> -
> -#endif
> -
> -#if defined(CONFIG_ARCH_OMAP2) || defined(MULTI_OMAP2)
> -
> -static int omap2_onenand_read_bufferram(struct mtd_info *mtd, int area,
> -					unsigned char *buffer, int offset,
> -					size_t count)
> -{
> -	struct omap2_onenand *c = container_of(mtd, struct omap2_onenand, mtd);
> -	struct onenand_chip *this = mtd->priv;
> -	dma_addr_t dma_src, dma_dst;
> -	int bram_offset, ret;
> -
> -	bram_offset = omap2_onenand_bufferram_offset(mtd, area) + area + offset;
> -	/* DMA is not used.  Revisit PM requirements before enabling it. */
> -	if (1 || (c->dma_channel < 0) ||
> -	    ((void *) buffer >= (void *) high_memory) || (bram_offset & 3) ||
> -	    (((unsigned int) buffer) & 3) || (count < 1024) || (count & 3)) {
> -		memcpy(buffer, (__force void *)(this->base + bram_offset),
> -		       count);
> -		return 0;
> -	}
> -
> -	dma_src = c->phys_base + bram_offset;
> -	dma_dst = dma_map_single(&c->pdev->dev, buffer, count,
> -				 DMA_FROM_DEVICE);
> -	if (dma_mapping_error(&c->pdev->dev, dma_dst)) {
> -		dev_err(&c->pdev->dev,
> -			"Couldn't DMA map a %d byte buffer\n",
> -			count);
> -		return -1;
> -	}
> -
> -	ret = omap2_onenand_dma_transfer(c, dma_src, dma_dst, count);
> -	dma_unmap_single(&c->pdev->dev, dma_dst, count, DMA_FROM_DEVICE);
> -
> -	if (ret)
> -		dev_err(&c->pdev->dev, "timeout waiting for DMA\n");
> -
> -	return ret;
> -}
> -
> -static int omap2_onenand_write_bufferram(struct mtd_info *mtd, int area,
> -					 const unsigned char *buffer,
> -					 int offset, size_t count)
> -{
> -	struct omap2_onenand *c = container_of(mtd, struct omap2_onenand, mtd);
> -	struct onenand_chip *this = mtd->priv;
> -	dma_addr_t dma_src, dma_dst;
> -	int bram_offset, ret;
> -
> -	bram_offset = omap2_onenand_bufferram_offset(mtd, area) + area + offset;
> -	/* DMA is not used.  Revisit PM requirements before enabling it. */
> -	if (1 || (c->dma_channel < 0) ||
> -	    ((void *) buffer >= (void *) high_memory) || (bram_offset & 3) ||
> -	    (((unsigned int) buffer) & 3) || (count < 1024) || (count & 3)) {
> -		memcpy((__force void *)(this->base + bram_offset), buffer,
> -		       count);
> -		return 0;
> -	}
> -
> -	dma_src = dma_map_single(&c->pdev->dev, (void *) buffer, count,
> -				 DMA_TO_DEVICE);
> -	dma_dst = c->phys_base + bram_offset;
> -	if (dma_mapping_error(&c->pdev->dev, dma_src)) {
> -		dev_err(&c->pdev->dev,
> -			"Couldn't DMA map a %d byte buffer\n",
> -			count);
> -		return -1;
> -	}
> -
> -	ret = omap2_onenand_dma_transfer(c, dma_src, dma_dst, count);
> -	dma_unmap_single(&c->pdev->dev, dma_src, count, DMA_TO_DEVICE);
> -
> -	if (ret)
> -		dev_err(&c->pdev->dev, "timeout waiting for DMA\n");
> -
> -	return ret;
> -}
> -
> -#else
> -
> -static int omap2_onenand_read_bufferram(struct mtd_info *mtd, int area,
> -					unsigned char *buffer, int offset,
> -					size_t count)
> -{
> -	return -ENOSYS;
> -}
> -
> -static int omap2_onenand_write_bufferram(struct mtd_info *mtd, int area,
> -					 const unsigned char *buffer,
> -					 int offset, size_t count)
> -{
> -	return -ENOSYS;
> -}
> -
> -#endif
> -
>  static struct platform_driver omap2_onenand_driver;
>  
>  static void omap2_onenand_shutdown(struct platform_device *pdev)
> @@ -671,13 +555,8 @@ static int omap2_onenand_probe(struct platform_device *pdev)
>  	this = &c->onenand;
>  	if (c->dma_channel >= 0) {
>  		this->wait = omap2_onenand_wait;
> -		if (c->flags & ONENAND_IN_OMAP34XX) {
> -			this->read_bufferram = omap3_onenand_read_bufferram;
> -			this->write_bufferram = omap3_onenand_write_bufferram;
> -		} else {
> -			this->read_bufferram = omap2_onenand_read_bufferram;
> -			this->write_bufferram = omap2_onenand_write_bufferram;
> -		}
> +		this->read_bufferram = omap2_onenand_read_bufferram;
> +		this->write_bufferram = omap2_onenand_write_bufferram;
>  	}
>  
>  	if ((r = onenand_scan(&c->mtd, 1)) < 0)
> 

-- 
cheers,
-roger

Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki. Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki

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

* Re: [PATCH v4 10/16] mtd: onenand: omap2: Convert to use dmaengine for memcpy
  2017-11-11 21:23   ` Ladislav Michl
@ 2017-11-15  8:57     ` Roger Quadros
  -1 siblings, 0 replies; 114+ messages in thread
From: Roger Quadros @ 2017-11-15  8:57 UTC (permalink / raw)
  To: Ladislav Michl, linux-mtd, linux-omap
  Cc: Tony Lindgren, Peter Ujfalusi, Kyungmin Park, Boris Brezillon

On 11/11/17 23:23, Ladislav Michl wrote:
> From: Peter Ujfalusi <peter.ujfalusi@ti.com>
> 
> Do not use the legacy and deprecated omap-dma interface for setting up the
> memcpy.
> 
> Signed-off-by: Peter Ujfalusi <peter.ujfalusi@ti.com>
> Signed-off-by: Ladislav Michl <ladis@linux-mips.org>

Acked-by: Roger Quadros <rogerq@ti.com>

Please see one comment below.

> ---
>  Changes:
>  -v4: new patch
> 
>  drivers/mtd/onenand/omap2.c | 80 +++++++++++++++++++++------------------------
>  1 file changed, 38 insertions(+), 42 deletions(-)
> 
> diff --git a/drivers/mtd/onenand/omap2.c b/drivers/mtd/onenand/omap2.c
> index 36314124488d..c9ff67100ef4 100644
> --- a/drivers/mtd/onenand/omap2.c
> +++ b/drivers/mtd/onenand/omap2.c
> @@ -32,6 +32,7 @@
>  #include <linux/interrupt.h>
>  #include <linux/delay.h>
>  #include <linux/dma-mapping.h>
> +#include <linux/dmaengine.h>
>  #include <linux/io.h>
>  #include <linux/slab.h>
>  #include <linux/gpio.h>
> @@ -39,8 +40,6 @@
>  #include <asm/mach/flash.h>
>  #include <linux/platform_data/mtd-onenand-omap2.h>
>  
> -#include <linux/omap-dma.h>
> -
>  #define DRIVER_NAME "omap2-onenand"
>  
>  #define ONENAND_BUFRAM_SIZE	(1024 * 5)
> @@ -55,17 +54,15 @@ struct omap2_onenand {
>  	struct onenand_chip onenand;
>  	struct completion irq_done;
>  	struct completion dma_done;
> -	int dma_channel;
> +	struct dma_chan *dma_chan;
>  	int freq;
>  	int (*setup)(void __iomem *base, int *freq_ptr);
>  	u8 flags;
>  };
>  
> -static void omap2_onenand_dma_cb(int lch, u16 ch_status, void *data)
> +static void omap2_onenand_dma_complete_func(void *completion)
>  {
> -	struct omap2_onenand *c = data;
> -
> -	complete(&c->dma_done);
> +	complete(completion);
>  }
>  
>  static irqreturn_t omap2_onenand_interrupt(int irq, void *dev_id)
> @@ -292,23 +289,31 @@ static inline int omap2_onenand_dma_transfer(struct omap2_onenand *c,
>  					     dma_addr_t src, dma_addr_t dst,
>  					     size_t count)
>  {
> -	int data_type = __ffs((src | dst | count));
> +	struct dma_async_tx_descriptor *tx;
> +	dma_cookie_t cookie;
>  
> -	if (data_type > OMAP_DMA_DATA_TYPE_S32)
> -		data_type = OMAP_DMA_DATA_TYPE_S32;
> -
> -	omap_set_dma_transfer_params(c->dma_channel, data_type,
> -				     count / BIT(data_type), 1, 0, 0, 0);
> -	omap_set_dma_src_params(c->dma_channel, 0, OMAP_DMA_AMODE_POST_INC,
> -				src, 0, 0);
> -	omap_set_dma_dest_params(c->dma_channel, 0, OMAP_DMA_AMODE_POST_INC,
> -				 dst, 0, 0);
> +	tx = dmaengine_prep_dma_memcpy(c->dma_chan, dst, src, count, 0);
> +	if (!tx) {
> +		dev_err(&c->pdev->dev, "Failed to prepare DMA memcpy\n");
> +		return -EIO;
> +	}
>  
>  	reinit_completion(&c->dma_done);
> -	omap_start_dma(c->dma_channel);
> +
> +	tx->callback = omap2_onenand_dma_complete_func;
> +	tx->callback_param = &c->dma_done;
> +
> +	cookie = tx->tx_submit(tx);
> +	if (dma_submit_error(cookie)) {
> +		dev_err(&c->pdev->dev, "Failed to do DMA tx_submit\n");
> +		return -EIO;
> +	}
> +
> +	dma_async_issue_pending(c->dma_chan);
> +
>  	if (!wait_for_completion_io_timeout(&c->dma_done,
>  					    msecs_to_jiffies(20))) {
> -		omap_stop_dma(c->dma_channel);
> +		dmaengine_terminate_sync(c->dma_chan);
>  		return -ETIMEDOUT;
>  	}
>  
> @@ -468,8 +473,7 @@ static int omap2_onenand_probe(struct platform_device *pdev)
>  	c->flags = pdata->flags;
>  	c->gpmc_cs = pdata->cs;
>  	c->gpio_irq = pdata->gpio_irq;
> -	c->dma_channel = pdata->dma_channel;
> -	if (c->dma_channel < 0) {
> +	if (pdata->dma_channel < 0) {
>  		/* if -1, don't use DMA */
>  		c->gpio_irq = 0;

Why are we ignoring gpio_irq if DMA channel is not available?
The wait mechanism could still benefit from the Interrupt even with no DMA right?

We could fix this in a separate patch of course.

>  	}
> @@ -521,25 +525,17 @@ static int omap2_onenand_probe(struct platform_device *pdev)
>  		goto err_release_gpio;
>  	}
>  
> -	if (c->dma_channel >= 0) {
> -		r = omap_request_dma(0, pdev->dev.driver->name,
> -				     omap2_onenand_dma_cb, (void *) c,
> -				     &c->dma_channel);
> -		if (r == 0) {
> -			omap_set_dma_write_mode(c->dma_channel,
> -						OMAP_DMA_WRITE_NON_POSTED);
> -			omap_set_dma_src_data_pack(c->dma_channel, 1);
> -			omap_set_dma_src_burst_mode(c->dma_channel,
> -						    OMAP_DMA_DATA_BURST_8);
> -			omap_set_dma_dest_data_pack(c->dma_channel, 1);
> -			omap_set_dma_dest_burst_mode(c->dma_channel,
> -						     OMAP_DMA_DATA_BURST_8);
> -		} else {
> +	if (pdata->dma_channel >= 0) {
> +		dma_cap_mask_t mask;
> +
> +		dma_cap_zero(mask);
> +		dma_cap_set(DMA_MEMCPY, mask);
> +
> +		c->dma_chan = dma_request_channel(mask, NULL, NULL);
> +		if (!c->dma_chan)
>  			dev_info(&pdev->dev,
>  				 "failed to allocate DMA for OneNAND, "
>  				 "using PIO instead\n");
> -			c->dma_channel = -1;
> -		}
>  	}
>  
>  	dev_info(&pdev->dev, "initializing on CS%d, phys base 0x%08lx, virtual "
> @@ -553,7 +549,7 @@ static int omap2_onenand_probe(struct platform_device *pdev)
>  	mtd_set_of_node(&c->mtd, pdata->of_node);
>  
>  	this = &c->onenand;
> -	if (c->dma_channel >= 0) {
> +	if (c->dma_chan) {
>  		this->wait = omap2_onenand_wait;
>  		this->read_bufferram = omap2_onenand_read_bufferram;
>  		this->write_bufferram = omap2_onenand_write_bufferram;
> @@ -573,8 +569,8 @@ static int omap2_onenand_probe(struct platform_device *pdev)
>  err_release_onenand:
>  	onenand_release(&c->mtd);
>  err_release_dma:
> -	if (c->dma_channel != -1)
> -		omap_free_dma(c->dma_channel);
> +	if (c->dma_chan)
> +		dma_release_channel(c->dma_chan);
>  	if (c->gpio_irq)
>  		free_irq(gpio_to_irq(c->gpio_irq), c);
>  err_release_gpio:
> @@ -595,8 +591,8 @@ static int omap2_onenand_remove(struct platform_device *pdev)
>  	struct omap2_onenand *c = dev_get_drvdata(&pdev->dev);
>  
>  	onenand_release(&c->mtd);
> -	if (c->dma_channel != -1)
> -		omap_free_dma(c->dma_channel);
> +	if (c->dma_chan)
> +		dma_release_channel(c->dma_chan);
>  	omap2_onenand_shutdown(pdev);
>  	if (c->gpio_irq) {
>  		free_irq(gpio_to_irq(c->gpio_irq), c);
> 

-- 
cheers,
-roger

Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki. Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki

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

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

* Re: [PATCH v4 10/16] mtd: onenand: omap2: Convert to use dmaengine for memcpy
@ 2017-11-15  8:57     ` Roger Quadros
  0 siblings, 0 replies; 114+ messages in thread
From: Roger Quadros @ 2017-11-15  8:57 UTC (permalink / raw)
  To: Ladislav Michl, linux-mtd, linux-omap
  Cc: Tony Lindgren, Peter Ujfalusi, Boris Brezillon, Kyungmin Park

On 11/11/17 23:23, Ladislav Michl wrote:
> From: Peter Ujfalusi <peter.ujfalusi@ti.com>
> 
> Do not use the legacy and deprecated omap-dma interface for setting up the
> memcpy.
> 
> Signed-off-by: Peter Ujfalusi <peter.ujfalusi@ti.com>
> Signed-off-by: Ladislav Michl <ladis@linux-mips.org>

Acked-by: Roger Quadros <rogerq@ti.com>

Please see one comment below.

> ---
>  Changes:
>  -v4: new patch
> 
>  drivers/mtd/onenand/omap2.c | 80 +++++++++++++++++++++------------------------
>  1 file changed, 38 insertions(+), 42 deletions(-)
> 
> diff --git a/drivers/mtd/onenand/omap2.c b/drivers/mtd/onenand/omap2.c
> index 36314124488d..c9ff67100ef4 100644
> --- a/drivers/mtd/onenand/omap2.c
> +++ b/drivers/mtd/onenand/omap2.c
> @@ -32,6 +32,7 @@
>  #include <linux/interrupt.h>
>  #include <linux/delay.h>
>  #include <linux/dma-mapping.h>
> +#include <linux/dmaengine.h>
>  #include <linux/io.h>
>  #include <linux/slab.h>
>  #include <linux/gpio.h>
> @@ -39,8 +40,6 @@
>  #include <asm/mach/flash.h>
>  #include <linux/platform_data/mtd-onenand-omap2.h>
>  
> -#include <linux/omap-dma.h>
> -
>  #define DRIVER_NAME "omap2-onenand"
>  
>  #define ONENAND_BUFRAM_SIZE	(1024 * 5)
> @@ -55,17 +54,15 @@ struct omap2_onenand {
>  	struct onenand_chip onenand;
>  	struct completion irq_done;
>  	struct completion dma_done;
> -	int dma_channel;
> +	struct dma_chan *dma_chan;
>  	int freq;
>  	int (*setup)(void __iomem *base, int *freq_ptr);
>  	u8 flags;
>  };
>  
> -static void omap2_onenand_dma_cb(int lch, u16 ch_status, void *data)
> +static void omap2_onenand_dma_complete_func(void *completion)
>  {
> -	struct omap2_onenand *c = data;
> -
> -	complete(&c->dma_done);
> +	complete(completion);
>  }
>  
>  static irqreturn_t omap2_onenand_interrupt(int irq, void *dev_id)
> @@ -292,23 +289,31 @@ static inline int omap2_onenand_dma_transfer(struct omap2_onenand *c,
>  					     dma_addr_t src, dma_addr_t dst,
>  					     size_t count)
>  {
> -	int data_type = __ffs((src | dst | count));
> +	struct dma_async_tx_descriptor *tx;
> +	dma_cookie_t cookie;
>  
> -	if (data_type > OMAP_DMA_DATA_TYPE_S32)
> -		data_type = OMAP_DMA_DATA_TYPE_S32;
> -
> -	omap_set_dma_transfer_params(c->dma_channel, data_type,
> -				     count / BIT(data_type), 1, 0, 0, 0);
> -	omap_set_dma_src_params(c->dma_channel, 0, OMAP_DMA_AMODE_POST_INC,
> -				src, 0, 0);
> -	omap_set_dma_dest_params(c->dma_channel, 0, OMAP_DMA_AMODE_POST_INC,
> -				 dst, 0, 0);
> +	tx = dmaengine_prep_dma_memcpy(c->dma_chan, dst, src, count, 0);
> +	if (!tx) {
> +		dev_err(&c->pdev->dev, "Failed to prepare DMA memcpy\n");
> +		return -EIO;
> +	}
>  
>  	reinit_completion(&c->dma_done);
> -	omap_start_dma(c->dma_channel);
> +
> +	tx->callback = omap2_onenand_dma_complete_func;
> +	tx->callback_param = &c->dma_done;
> +
> +	cookie = tx->tx_submit(tx);
> +	if (dma_submit_error(cookie)) {
> +		dev_err(&c->pdev->dev, "Failed to do DMA tx_submit\n");
> +		return -EIO;
> +	}
> +
> +	dma_async_issue_pending(c->dma_chan);
> +
>  	if (!wait_for_completion_io_timeout(&c->dma_done,
>  					    msecs_to_jiffies(20))) {
> -		omap_stop_dma(c->dma_channel);
> +		dmaengine_terminate_sync(c->dma_chan);
>  		return -ETIMEDOUT;
>  	}
>  
> @@ -468,8 +473,7 @@ static int omap2_onenand_probe(struct platform_device *pdev)
>  	c->flags = pdata->flags;
>  	c->gpmc_cs = pdata->cs;
>  	c->gpio_irq = pdata->gpio_irq;
> -	c->dma_channel = pdata->dma_channel;
> -	if (c->dma_channel < 0) {
> +	if (pdata->dma_channel < 0) {
>  		/* if -1, don't use DMA */
>  		c->gpio_irq = 0;

Why are we ignoring gpio_irq if DMA channel is not available?
The wait mechanism could still benefit from the Interrupt even with no DMA right?

We could fix this in a separate patch of course.

>  	}
> @@ -521,25 +525,17 @@ static int omap2_onenand_probe(struct platform_device *pdev)
>  		goto err_release_gpio;
>  	}
>  
> -	if (c->dma_channel >= 0) {
> -		r = omap_request_dma(0, pdev->dev.driver->name,
> -				     omap2_onenand_dma_cb, (void *) c,
> -				     &c->dma_channel);
> -		if (r == 0) {
> -			omap_set_dma_write_mode(c->dma_channel,
> -						OMAP_DMA_WRITE_NON_POSTED);
> -			omap_set_dma_src_data_pack(c->dma_channel, 1);
> -			omap_set_dma_src_burst_mode(c->dma_channel,
> -						    OMAP_DMA_DATA_BURST_8);
> -			omap_set_dma_dest_data_pack(c->dma_channel, 1);
> -			omap_set_dma_dest_burst_mode(c->dma_channel,
> -						     OMAP_DMA_DATA_BURST_8);
> -		} else {
> +	if (pdata->dma_channel >= 0) {
> +		dma_cap_mask_t mask;
> +
> +		dma_cap_zero(mask);
> +		dma_cap_set(DMA_MEMCPY, mask);
> +
> +		c->dma_chan = dma_request_channel(mask, NULL, NULL);
> +		if (!c->dma_chan)
>  			dev_info(&pdev->dev,
>  				 "failed to allocate DMA for OneNAND, "
>  				 "using PIO instead\n");
> -			c->dma_channel = -1;
> -		}
>  	}
>  
>  	dev_info(&pdev->dev, "initializing on CS%d, phys base 0x%08lx, virtual "
> @@ -553,7 +549,7 @@ static int omap2_onenand_probe(struct platform_device *pdev)
>  	mtd_set_of_node(&c->mtd, pdata->of_node);
>  
>  	this = &c->onenand;
> -	if (c->dma_channel >= 0) {
> +	if (c->dma_chan) {
>  		this->wait = omap2_onenand_wait;
>  		this->read_bufferram = omap2_onenand_read_bufferram;
>  		this->write_bufferram = omap2_onenand_write_bufferram;
> @@ -573,8 +569,8 @@ static int omap2_onenand_probe(struct platform_device *pdev)
>  err_release_onenand:
>  	onenand_release(&c->mtd);
>  err_release_dma:
> -	if (c->dma_channel != -1)
> -		omap_free_dma(c->dma_channel);
> +	if (c->dma_chan)
> +		dma_release_channel(c->dma_chan);
>  	if (c->gpio_irq)
>  		free_irq(gpio_to_irq(c->gpio_irq), c);
>  err_release_gpio:
> @@ -595,8 +591,8 @@ static int omap2_onenand_remove(struct platform_device *pdev)
>  	struct omap2_onenand *c = dev_get_drvdata(&pdev->dev);
>  
>  	onenand_release(&c->mtd);
> -	if (c->dma_channel != -1)
> -		omap_free_dma(c->dma_channel);
> +	if (c->dma_chan)
> +		dma_release_channel(c->dma_chan);
>  	omap2_onenand_shutdown(pdev);
>  	if (c->gpio_irq) {
>  		free_irq(gpio_to_irq(c->gpio_irq), c);
> 

-- 
cheers,
-roger

Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki. Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki

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

* Re: [PATCH v4 11/16] mtd: onenand: omap2: Do not make delay for GPIO OMAP3 specific
  2017-11-11 21:24   ` Ladislav Michl
@ 2017-11-15  9:31     ` Roger Quadros
  -1 siblings, 0 replies; 114+ messages in thread
From: Roger Quadros @ 2017-11-15  9:31 UTC (permalink / raw)
  To: Ladislav Michl, linux-mtd, linux-omap
  Cc: Tony Lindgren, Peter Ujfalusi, Kyungmin Park, Boris Brezillon

On 11/11/17 23:24, Ladislav Michl wrote:
> Second commit in driver history (782b7a367d81: "[MTD] [OneNAND] OMAP3:
> add delay for GPIO") added quirk for waiting until GPIO line settle.
> As DMA was disabled for OMAP2 boards, chances are this problem was
> not OMAP3 specific and as it is just one register read, previous
> test for SoC type is approximately as expensive as read itself.
> Make delay unconditional, which allows removing SoC specific code
> alltogether.
> 
> Signed-off-by: Ladislav Michl <ladis@linux-mips.org>

Acked-by: Roger Quadros <rogerq@ti.com>

> ---
>  Changes:
>  -v3: new patch
>  -v4: none
> 
>  drivers/mtd/onenand/omap2.c | 7 ++-----
>  1 file changed, 2 insertions(+), 5 deletions(-)
> 
> diff --git a/drivers/mtd/onenand/omap2.c b/drivers/mtd/onenand/omap2.c
> index c9ff67100ef4..e4857a41760d 100644
> --- a/drivers/mtd/onenand/omap2.c
> +++ b/drivers/mtd/onenand/omap2.c
> @@ -57,7 +57,6 @@ struct omap2_onenand {
>  	struct dma_chan *dma_chan;
>  	int freq;
>  	int (*setup)(void __iomem *base, int *freq_ptr);
> -	u8 flags;
>  };
>  
>  static void omap2_onenand_dma_complete_func(void *completion)
> @@ -148,9 +147,8 @@ static int omap2_onenand_wait(struct mtd_info *mtd, int state)
>  		if (!(syscfg & ONENAND_SYS_CFG1_IOBE)) {
>  			syscfg |= ONENAND_SYS_CFG1_IOBE;
>  			write_reg(c, syscfg, ONENAND_REG_SYS_CFG1);
> -			if (c->flags & ONENAND_IN_OMAP34XX)
> -				/* Add a delay to let GPIO settle */
> -				syscfg = read_reg(c, ONENAND_REG_SYS_CFG1);
> +			/* Add a delay to let GPIO settle */
> +			syscfg = read_reg(c, ONENAND_REG_SYS_CFG1);
>  		}
>  
>  		reinit_completion(&c->irq_done);
> @@ -470,7 +468,6 @@ static int omap2_onenand_probe(struct platform_device *pdev)
>  
>  	init_completion(&c->irq_done);
>  	init_completion(&c->dma_done);
> -	c->flags = pdata->flags;
>  	c->gpmc_cs = pdata->cs;
>  	c->gpio_irq = pdata->gpio_irq;
>  	if (pdata->dma_channel < 0) {
> 

-- 
cheers,
-roger

Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki. Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki

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

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

* Re: [PATCH v4 11/16] mtd: onenand: omap2: Do not make delay for GPIO OMAP3 specific
@ 2017-11-15  9:31     ` Roger Quadros
  0 siblings, 0 replies; 114+ messages in thread
From: Roger Quadros @ 2017-11-15  9:31 UTC (permalink / raw)
  To: Ladislav Michl, linux-mtd, linux-omap
  Cc: Tony Lindgren, Peter Ujfalusi, Boris Brezillon, Kyungmin Park

On 11/11/17 23:24, Ladislav Michl wrote:
> Second commit in driver history (782b7a367d81: "[MTD] [OneNAND] OMAP3:
> add delay for GPIO") added quirk for waiting until GPIO line settle.
> As DMA was disabled for OMAP2 boards, chances are this problem was
> not OMAP3 specific and as it is just one register read, previous
> test for SoC type is approximately as expensive as read itself.
> Make delay unconditional, which allows removing SoC specific code
> alltogether.
> 
> Signed-off-by: Ladislav Michl <ladis@linux-mips.org>

Acked-by: Roger Quadros <rogerq@ti.com>

> ---
>  Changes:
>  -v3: new patch
>  -v4: none
> 
>  drivers/mtd/onenand/omap2.c | 7 ++-----
>  1 file changed, 2 insertions(+), 5 deletions(-)
> 
> diff --git a/drivers/mtd/onenand/omap2.c b/drivers/mtd/onenand/omap2.c
> index c9ff67100ef4..e4857a41760d 100644
> --- a/drivers/mtd/onenand/omap2.c
> +++ b/drivers/mtd/onenand/omap2.c
> @@ -57,7 +57,6 @@ struct omap2_onenand {
>  	struct dma_chan *dma_chan;
>  	int freq;
>  	int (*setup)(void __iomem *base, int *freq_ptr);
> -	u8 flags;
>  };
>  
>  static void omap2_onenand_dma_complete_func(void *completion)
> @@ -148,9 +147,8 @@ static int omap2_onenand_wait(struct mtd_info *mtd, int state)
>  		if (!(syscfg & ONENAND_SYS_CFG1_IOBE)) {
>  			syscfg |= ONENAND_SYS_CFG1_IOBE;
>  			write_reg(c, syscfg, ONENAND_REG_SYS_CFG1);
> -			if (c->flags & ONENAND_IN_OMAP34XX)
> -				/* Add a delay to let GPIO settle */
> -				syscfg = read_reg(c, ONENAND_REG_SYS_CFG1);
> +			/* Add a delay to let GPIO settle */
> +			syscfg = read_reg(c, ONENAND_REG_SYS_CFG1);
>  		}
>  
>  		reinit_completion(&c->irq_done);
> @@ -470,7 +468,6 @@ static int omap2_onenand_probe(struct platform_device *pdev)
>  
>  	init_completion(&c->irq_done);
>  	init_completion(&c->dma_done);
> -	c->flags = pdata->flags;
>  	c->gpmc_cs = pdata->cs;
>  	c->gpio_irq = pdata->gpio_irq;
>  	if (pdata->dma_channel < 0) {
> 

-- 
cheers,
-roger

Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki. Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki

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

* Re: [PATCH v4 10/16] mtd: onenand: omap2: Convert to use dmaengine for memcpy
  2017-11-15  8:57     ` Roger Quadros
@ 2017-11-15  9:32       ` Ladislav Michl
  -1 siblings, 0 replies; 114+ messages in thread
From: Ladislav Michl @ 2017-11-15  9:32 UTC (permalink / raw)
  To: Roger Quadros
  Cc: Boris Brezillon, Tony Lindgren, Peter Ujfalusi, Kyungmin Park,
	linux-mtd, linux-omap

On Wed, Nov 15, 2017 at 10:57:20AM +0200, Roger Quadros wrote:
> On 11/11/17 23:23, Ladislav Michl wrote:
> > From: Peter Ujfalusi <peter.ujfalusi@ti.com>
> > 
> > Do not use the legacy and deprecated omap-dma interface for setting up the
> > memcpy.
> > 
> > Signed-off-by: Peter Ujfalusi <peter.ujfalusi@ti.com>
> > Signed-off-by: Ladislav Michl <ladis@linux-mips.org>
> 
> Acked-by: Roger Quadros <rogerq@ti.com>
> 
> Please see one comment below.
> 
> > ---
> >  Changes:
> >  -v4: new patch
> > 
> >  drivers/mtd/onenand/omap2.c | 80 +++++++++++++++++++++------------------------
> >  1 file changed, 38 insertions(+), 42 deletions(-)
> > 
> > diff --git a/drivers/mtd/onenand/omap2.c b/drivers/mtd/onenand/omap2.c
> > index 36314124488d..c9ff67100ef4 100644
> > --- a/drivers/mtd/onenand/omap2.c
> > +++ b/drivers/mtd/onenand/omap2.c
> > @@ -32,6 +32,7 @@
> >  #include <linux/interrupt.h>
> >  #include <linux/delay.h>
> >  #include <linux/dma-mapping.h>
> > +#include <linux/dmaengine.h>
> >  #include <linux/io.h>
> >  #include <linux/slab.h>
> >  #include <linux/gpio.h>
> > @@ -39,8 +40,6 @@
> >  #include <asm/mach/flash.h>
> >  #include <linux/platform_data/mtd-onenand-omap2.h>
> >  
> > -#include <linux/omap-dma.h>
> > -
> >  #define DRIVER_NAME "omap2-onenand"
> >  
> >  #define ONENAND_BUFRAM_SIZE	(1024 * 5)
> > @@ -55,17 +54,15 @@ struct omap2_onenand {
> >  	struct onenand_chip onenand;
> >  	struct completion irq_done;
> >  	struct completion dma_done;
> > -	int dma_channel;
> > +	struct dma_chan *dma_chan;
> >  	int freq;
> >  	int (*setup)(void __iomem *base, int *freq_ptr);
> >  	u8 flags;
> >  };
> >  
> > -static void omap2_onenand_dma_cb(int lch, u16 ch_status, void *data)
> > +static void omap2_onenand_dma_complete_func(void *completion)
> >  {
> > -	struct omap2_onenand *c = data;
> > -
> > -	complete(&c->dma_done);
> > +	complete(completion);
> >  }
> >  
> >  static irqreturn_t omap2_onenand_interrupt(int irq, void *dev_id)
> > @@ -292,23 +289,31 @@ static inline int omap2_onenand_dma_transfer(struct omap2_onenand *c,
> >  					     dma_addr_t src, dma_addr_t dst,
> >  					     size_t count)
> >  {
> > -	int data_type = __ffs((src | dst | count));
> > +	struct dma_async_tx_descriptor *tx;
> > +	dma_cookie_t cookie;
> >  
> > -	if (data_type > OMAP_DMA_DATA_TYPE_S32)
> > -		data_type = OMAP_DMA_DATA_TYPE_S32;
> > -
> > -	omap_set_dma_transfer_params(c->dma_channel, data_type,
> > -				     count / BIT(data_type), 1, 0, 0, 0);
> > -	omap_set_dma_src_params(c->dma_channel, 0, OMAP_DMA_AMODE_POST_INC,
> > -				src, 0, 0);
> > -	omap_set_dma_dest_params(c->dma_channel, 0, OMAP_DMA_AMODE_POST_INC,
> > -				 dst, 0, 0);
> > +	tx = dmaengine_prep_dma_memcpy(c->dma_chan, dst, src, count, 0);
> > +	if (!tx) {
> > +		dev_err(&c->pdev->dev, "Failed to prepare DMA memcpy\n");
> > +		return -EIO;
> > +	}
> >  
> >  	reinit_completion(&c->dma_done);
> > -	omap_start_dma(c->dma_channel);
> > +
> > +	tx->callback = omap2_onenand_dma_complete_func;
> > +	tx->callback_param = &c->dma_done;
> > +
> > +	cookie = tx->tx_submit(tx);
> > +	if (dma_submit_error(cookie)) {
> > +		dev_err(&c->pdev->dev, "Failed to do DMA tx_submit\n");
> > +		return -EIO;
> > +	}
> > +
> > +	dma_async_issue_pending(c->dma_chan);
> > +
> >  	if (!wait_for_completion_io_timeout(&c->dma_done,
> >  					    msecs_to_jiffies(20))) {
> > -		omap_stop_dma(c->dma_channel);
> > +		dmaengine_terminate_sync(c->dma_chan);
> >  		return -ETIMEDOUT;
> >  	}
> >  
> > @@ -468,8 +473,7 @@ static int omap2_onenand_probe(struct platform_device *pdev)
> >  	c->flags = pdata->flags;
> >  	c->gpmc_cs = pdata->cs;
> >  	c->gpio_irq = pdata->gpio_irq;
> > -	c->dma_channel = pdata->dma_channel;
> > -	if (c->dma_channel < 0) {
> > +	if (pdata->dma_channel < 0) {
> >  		/* if -1, don't use DMA */
> >  		c->gpio_irq = 0;
> 
> Why are we ignoring gpio_irq if DMA channel is not available?
> The wait mechanism could still benefit from the Interrupt even with no DMA right?

That's what original driver does and logic is preserved here.

> We could fix this in a separate patch of course.

And indeed we did. See "mtd: onenand: omap2: Enable DMA by default" (*) and
"mtd: onenand: omap2: Configure driver from DT".

(*) Now looking at that patch is should be renamed, as enabling DMA still depends
on pdata->dma_chan. It is enabled unconditionally in later patch. Will fix.

> >  	}
> > @@ -521,25 +525,17 @@ static int omap2_onenand_probe(struct platform_device *pdev)
> >  		goto err_release_gpio;
> >  	}
> >  
> > -	if (c->dma_channel >= 0) {
> > -		r = omap_request_dma(0, pdev->dev.driver->name,
> > -				     omap2_onenand_dma_cb, (void *) c,
> > -				     &c->dma_channel);
> > -		if (r == 0) {
> > -			omap_set_dma_write_mode(c->dma_channel,
> > -						OMAP_DMA_WRITE_NON_POSTED);
> > -			omap_set_dma_src_data_pack(c->dma_channel, 1);
> > -			omap_set_dma_src_burst_mode(c->dma_channel,
> > -						    OMAP_DMA_DATA_BURST_8);
> > -			omap_set_dma_dest_data_pack(c->dma_channel, 1);
> > -			omap_set_dma_dest_burst_mode(c->dma_channel,
> > -						     OMAP_DMA_DATA_BURST_8);
> > -		} else {
> > +	if (pdata->dma_channel >= 0) {
> > +		dma_cap_mask_t mask;
> > +
> > +		dma_cap_zero(mask);
> > +		dma_cap_set(DMA_MEMCPY, mask);
> > +
> > +		c->dma_chan = dma_request_channel(mask, NULL, NULL);
> > +		if (!c->dma_chan)
> >  			dev_info(&pdev->dev,
> >  				 "failed to allocate DMA for OneNAND, "
> >  				 "using PIO instead\n");
> > -			c->dma_channel = -1;
> > -		}
> >  	}
> >  
> >  	dev_info(&pdev->dev, "initializing on CS%d, phys base 0x%08lx, virtual "
> > @@ -553,7 +549,7 @@ static int omap2_onenand_probe(struct platform_device *pdev)
> >  	mtd_set_of_node(&c->mtd, pdata->of_node);
> >  
> >  	this = &c->onenand;
> > -	if (c->dma_channel >= 0) {
> > +	if (c->dma_chan) {
> >  		this->wait = omap2_onenand_wait;
> >  		this->read_bufferram = omap2_onenand_read_bufferram;
> >  		this->write_bufferram = omap2_onenand_write_bufferram;
> > @@ -573,8 +569,8 @@ static int omap2_onenand_probe(struct platform_device *pdev)
> >  err_release_onenand:
> >  	onenand_release(&c->mtd);
> >  err_release_dma:
> > -	if (c->dma_channel != -1)
> > -		omap_free_dma(c->dma_channel);
> > +	if (c->dma_chan)
> > +		dma_release_channel(c->dma_chan);
> >  	if (c->gpio_irq)
> >  		free_irq(gpio_to_irq(c->gpio_irq), c);
> >  err_release_gpio:
> > @@ -595,8 +591,8 @@ static int omap2_onenand_remove(struct platform_device *pdev)
> >  	struct omap2_onenand *c = dev_get_drvdata(&pdev->dev);
> >  
> >  	onenand_release(&c->mtd);
> > -	if (c->dma_channel != -1)
> > -		omap_free_dma(c->dma_channel);
> > +	if (c->dma_chan)
> > +		dma_release_channel(c->dma_chan);
> >  	omap2_onenand_shutdown(pdev);
> >  	if (c->gpio_irq) {
> >  		free_irq(gpio_to_irq(c->gpio_irq), c);
> > 
> 
> -- 
> cheers,
> -roger
> 
> Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki. Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki

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

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

* Re: [PATCH v4 10/16] mtd: onenand: omap2: Convert to use dmaengine for memcpy
@ 2017-11-15  9:32       ` Ladislav Michl
  0 siblings, 0 replies; 114+ messages in thread
From: Ladislav Michl @ 2017-11-15  9:32 UTC (permalink / raw)
  To: Roger Quadros
  Cc: linux-mtd, linux-omap, Tony Lindgren, Peter Ujfalusi,
	Boris Brezillon, Kyungmin Park

On Wed, Nov 15, 2017 at 10:57:20AM +0200, Roger Quadros wrote:
> On 11/11/17 23:23, Ladislav Michl wrote:
> > From: Peter Ujfalusi <peter.ujfalusi@ti.com>
> > 
> > Do not use the legacy and deprecated omap-dma interface for setting up the
> > memcpy.
> > 
> > Signed-off-by: Peter Ujfalusi <peter.ujfalusi@ti.com>
> > Signed-off-by: Ladislav Michl <ladis@linux-mips.org>
> 
> Acked-by: Roger Quadros <rogerq@ti.com>
> 
> Please see one comment below.
> 
> > ---
> >  Changes:
> >  -v4: new patch
> > 
> >  drivers/mtd/onenand/omap2.c | 80 +++++++++++++++++++++------------------------
> >  1 file changed, 38 insertions(+), 42 deletions(-)
> > 
> > diff --git a/drivers/mtd/onenand/omap2.c b/drivers/mtd/onenand/omap2.c
> > index 36314124488d..c9ff67100ef4 100644
> > --- a/drivers/mtd/onenand/omap2.c
> > +++ b/drivers/mtd/onenand/omap2.c
> > @@ -32,6 +32,7 @@
> >  #include <linux/interrupt.h>
> >  #include <linux/delay.h>
> >  #include <linux/dma-mapping.h>
> > +#include <linux/dmaengine.h>
> >  #include <linux/io.h>
> >  #include <linux/slab.h>
> >  #include <linux/gpio.h>
> > @@ -39,8 +40,6 @@
> >  #include <asm/mach/flash.h>
> >  #include <linux/platform_data/mtd-onenand-omap2.h>
> >  
> > -#include <linux/omap-dma.h>
> > -
> >  #define DRIVER_NAME "omap2-onenand"
> >  
> >  #define ONENAND_BUFRAM_SIZE	(1024 * 5)
> > @@ -55,17 +54,15 @@ struct omap2_onenand {
> >  	struct onenand_chip onenand;
> >  	struct completion irq_done;
> >  	struct completion dma_done;
> > -	int dma_channel;
> > +	struct dma_chan *dma_chan;
> >  	int freq;
> >  	int (*setup)(void __iomem *base, int *freq_ptr);
> >  	u8 flags;
> >  };
> >  
> > -static void omap2_onenand_dma_cb(int lch, u16 ch_status, void *data)
> > +static void omap2_onenand_dma_complete_func(void *completion)
> >  {
> > -	struct omap2_onenand *c = data;
> > -
> > -	complete(&c->dma_done);
> > +	complete(completion);
> >  }
> >  
> >  static irqreturn_t omap2_onenand_interrupt(int irq, void *dev_id)
> > @@ -292,23 +289,31 @@ static inline int omap2_onenand_dma_transfer(struct omap2_onenand *c,
> >  					     dma_addr_t src, dma_addr_t dst,
> >  					     size_t count)
> >  {
> > -	int data_type = __ffs((src | dst | count));
> > +	struct dma_async_tx_descriptor *tx;
> > +	dma_cookie_t cookie;
> >  
> > -	if (data_type > OMAP_DMA_DATA_TYPE_S32)
> > -		data_type = OMAP_DMA_DATA_TYPE_S32;
> > -
> > -	omap_set_dma_transfer_params(c->dma_channel, data_type,
> > -				     count / BIT(data_type), 1, 0, 0, 0);
> > -	omap_set_dma_src_params(c->dma_channel, 0, OMAP_DMA_AMODE_POST_INC,
> > -				src, 0, 0);
> > -	omap_set_dma_dest_params(c->dma_channel, 0, OMAP_DMA_AMODE_POST_INC,
> > -				 dst, 0, 0);
> > +	tx = dmaengine_prep_dma_memcpy(c->dma_chan, dst, src, count, 0);
> > +	if (!tx) {
> > +		dev_err(&c->pdev->dev, "Failed to prepare DMA memcpy\n");
> > +		return -EIO;
> > +	}
> >  
> >  	reinit_completion(&c->dma_done);
> > -	omap_start_dma(c->dma_channel);
> > +
> > +	tx->callback = omap2_onenand_dma_complete_func;
> > +	tx->callback_param = &c->dma_done;
> > +
> > +	cookie = tx->tx_submit(tx);
> > +	if (dma_submit_error(cookie)) {
> > +		dev_err(&c->pdev->dev, "Failed to do DMA tx_submit\n");
> > +		return -EIO;
> > +	}
> > +
> > +	dma_async_issue_pending(c->dma_chan);
> > +
> >  	if (!wait_for_completion_io_timeout(&c->dma_done,
> >  					    msecs_to_jiffies(20))) {
> > -		omap_stop_dma(c->dma_channel);
> > +		dmaengine_terminate_sync(c->dma_chan);
> >  		return -ETIMEDOUT;
> >  	}
> >  
> > @@ -468,8 +473,7 @@ static int omap2_onenand_probe(struct platform_device *pdev)
> >  	c->flags = pdata->flags;
> >  	c->gpmc_cs = pdata->cs;
> >  	c->gpio_irq = pdata->gpio_irq;
> > -	c->dma_channel = pdata->dma_channel;
> > -	if (c->dma_channel < 0) {
> > +	if (pdata->dma_channel < 0) {
> >  		/* if -1, don't use DMA */
> >  		c->gpio_irq = 0;
> 
> Why are we ignoring gpio_irq if DMA channel is not available?
> The wait mechanism could still benefit from the Interrupt even with no DMA right?

That's what original driver does and logic is preserved here.

> We could fix this in a separate patch of course.

And indeed we did. See "mtd: onenand: omap2: Enable DMA by default" (*) and
"mtd: onenand: omap2: Configure driver from DT".

(*) Now looking at that patch is should be renamed, as enabling DMA still depends
on pdata->dma_chan. It is enabled unconditionally in later patch. Will fix.

> >  	}
> > @@ -521,25 +525,17 @@ static int omap2_onenand_probe(struct platform_device *pdev)
> >  		goto err_release_gpio;
> >  	}
> >  
> > -	if (c->dma_channel >= 0) {
> > -		r = omap_request_dma(0, pdev->dev.driver->name,
> > -				     omap2_onenand_dma_cb, (void *) c,
> > -				     &c->dma_channel);
> > -		if (r == 0) {
> > -			omap_set_dma_write_mode(c->dma_channel,
> > -						OMAP_DMA_WRITE_NON_POSTED);
> > -			omap_set_dma_src_data_pack(c->dma_channel, 1);
> > -			omap_set_dma_src_burst_mode(c->dma_channel,
> > -						    OMAP_DMA_DATA_BURST_8);
> > -			omap_set_dma_dest_data_pack(c->dma_channel, 1);
> > -			omap_set_dma_dest_burst_mode(c->dma_channel,
> > -						     OMAP_DMA_DATA_BURST_8);
> > -		} else {
> > +	if (pdata->dma_channel >= 0) {
> > +		dma_cap_mask_t mask;
> > +
> > +		dma_cap_zero(mask);
> > +		dma_cap_set(DMA_MEMCPY, mask);
> > +
> > +		c->dma_chan = dma_request_channel(mask, NULL, NULL);
> > +		if (!c->dma_chan)
> >  			dev_info(&pdev->dev,
> >  				 "failed to allocate DMA for OneNAND, "
> >  				 "using PIO instead\n");
> > -			c->dma_channel = -1;
> > -		}
> >  	}
> >  
> >  	dev_info(&pdev->dev, "initializing on CS%d, phys base 0x%08lx, virtual "
> > @@ -553,7 +549,7 @@ static int omap2_onenand_probe(struct platform_device *pdev)
> >  	mtd_set_of_node(&c->mtd, pdata->of_node);
> >  
> >  	this = &c->onenand;
> > -	if (c->dma_channel >= 0) {
> > +	if (c->dma_chan) {
> >  		this->wait = omap2_onenand_wait;
> >  		this->read_bufferram = omap2_onenand_read_bufferram;
> >  		this->write_bufferram = omap2_onenand_write_bufferram;
> > @@ -573,8 +569,8 @@ static int omap2_onenand_probe(struct platform_device *pdev)
> >  err_release_onenand:
> >  	onenand_release(&c->mtd);
> >  err_release_dma:
> > -	if (c->dma_channel != -1)
> > -		omap_free_dma(c->dma_channel);
> > +	if (c->dma_chan)
> > +		dma_release_channel(c->dma_chan);
> >  	if (c->gpio_irq)
> >  		free_irq(gpio_to_irq(c->gpio_irq), c);
> >  err_release_gpio:
> > @@ -595,8 +591,8 @@ static int omap2_onenand_remove(struct platform_device *pdev)
> >  	struct omap2_onenand *c = dev_get_drvdata(&pdev->dev);
> >  
> >  	onenand_release(&c->mtd);
> > -	if (c->dma_channel != -1)
> > -		omap_free_dma(c->dma_channel);
> > +	if (c->dma_chan)
> > +		dma_release_channel(c->dma_chan);
> >  	omap2_onenand_shutdown(pdev);
> >  	if (c->gpio_irq) {
> >  		free_irq(gpio_to_irq(c->gpio_irq), c);
> > 
> 
> -- 
> cheers,
> -roger
> 
> Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki. Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki

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

* Re: [PATCH v4 12/16] mtd: onenand: omap2: Enable DMA by default
  2017-11-11 21:24   ` Ladislav Michl
@ 2017-11-15 10:08     ` Roger Quadros
  -1 siblings, 0 replies; 114+ messages in thread
From: Roger Quadros @ 2017-11-15 10:08 UTC (permalink / raw)
  To: Ladislav Michl, linux-mtd, linux-omap
  Cc: Tony Lindgren, Peter Ujfalusi, Kyungmin Park, Boris Brezillon

Hi,

On 11/11/17 23:24, Ladislav Michl wrote:
> DMA and R/B pin are independent on each other. Use DMA by default.

Is there a R/B pin on Onenand? It looks more like it has a RDY pin and
an INT pin (which is used for command completion interrupt).

I think the subject and message are a bit misleading.

It should be something like

mtd: onenand: omap2: decouple DMA enabling from INT pin availability

INT pin (gpio_irq) is not really needed for DMA but only for notification
when a command that needs wait has completed. We can still have DMA
even without gpio_irq available.

> 
> Signed-off-by: Ladislav Michl <ladis@linux-mips.org>
> ---
>  Changes:
>  -v4: new patch
> 
>  drivers/mtd/onenand/omap2.c | 41 +++++++++++++++++------------------------
>  1 file changed, 17 insertions(+), 24 deletions(-)
> 
> diff --git a/drivers/mtd/onenand/omap2.c b/drivers/mtd/onenand/omap2.c
> index e4857a41760d..62e4ede918c4 100644
> --- a/drivers/mtd/onenand/omap2.c
> +++ b/drivers/mtd/onenand/omap2.c
> @@ -152,17 +152,13 @@ static int omap2_onenand_wait(struct mtd_info *mtd, int state)
>  		}
>  
>  		reinit_completion(&c->irq_done);
> -		if (c->gpio_irq) {
> -			result = gpio_get_value(c->gpio_irq);
> -			if (result == -1) {
> -				ctrl = read_reg(c, ONENAND_REG_CTRL_STATUS);
> -				intr = read_reg(c, ONENAND_REG_INTERRUPT);
> -				wait_err("gpio error", state, ctrl, intr);
> -				return -EIO;
> -			}
> -		} else
> -			result = 0;
> -		if (result == 0) {
> +		result = gpio_get_value(c->gpio_irq);
> +		if (result < 0) {
> +			ctrl = read_reg(c, ONENAND_REG_CTRL_STATUS);
> +			intr = read_reg(c, ONENAND_REG_INTERRUPT);
> +			wait_err("gpio error", state, ctrl, intr);
> +			return -EIO;
> +		} else if (result == 0) {
>  			int retry_cnt = 0;
>  retry:
>  			if (!wait_for_completion_io_timeout(&c->irq_done,
> @@ -513,13 +509,15 @@ static int omap2_onenand_probe(struct platform_device *pdev)

We need to get rid if this code from probe.

        if (pdata->dma_channel < 0) {
                /* if -1, don't use DMA */
                c->gpio_irq = 0;
        }

>  			dev_err(&pdev->dev,  "Failed to request GPIO%d for "
>  				"OneNAND\n", c->gpio_irq);
>  			goto err_iounmap;
> -	}
> -	gpio_direction_input(c->gpio_irq);
> +		}
> +		gpio_direction_input(c->gpio_irq);
> +
> +		if ((r = request_irq(gpio_to_irq(c->gpio_irq),
> +				     omap2_onenand_interrupt, IRQF_TRIGGER_RISING,
> +				     pdev->dev.driver->name, c)) < 0)
> +			goto err_release_gpio;
>  
> -	if ((r = request_irq(gpio_to_irq(c->gpio_irq),
> -			     omap2_onenand_interrupt, IRQF_TRIGGER_RISING,
> -			     pdev->dev.driver->name, c)) < 0)
> -		goto err_release_gpio;
> +		this->wait = omap2_onenand_wait;
>  	}
>  
>  	if (pdata->dma_channel >= 0) {
> @@ -529,15 +527,11 @@ static int omap2_onenand_probe(struct platform_device *pdev)
>  		dma_cap_set(DMA_MEMCPY, mask);
>  
>  		c->dma_chan = dma_request_channel(mask, NULL, NULL);
> -		if (!c->dma_chan)
> -			dev_info(&pdev->dev,
> -				 "failed to allocate DMA for OneNAND, "
> -				 "using PIO instead\n");

Why get rid of the print message? Instead we could choose to error out completely
if a DMA channel was provided and we couldn't get it.

>  	}
>  
>  	dev_info(&pdev->dev, "initializing on CS%d, phys base 0x%08lx, virtual "
> -		 "base %p, freq %d MHz\n", c->gpmc_cs, c->phys_base,
> -		 c->onenand.base, c->freq);
> +		 "base %p, freq %d MHz, %s mode\n", c->gpmc_cs, c->phys_base,
> +		 c->onenand.base, c->freq, c->dma_chan ? "DMA" : "PIO");
>  
>  	c->pdev = pdev;
>  	c->mtd.priv = &c->onenand;
> @@ -547,7 +541,6 @@ static int omap2_onenand_probe(struct platform_device *pdev)
>  
>  	this = &c->onenand;
>  	if (c->dma_chan) {
> -		this->wait = omap2_onenand_wait;
>  		this->read_bufferram = omap2_onenand_read_bufferram;
>  		this->write_bufferram = omap2_onenand_write_bufferram;
>  	}
> 

-- 
cheers,
-roger

Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki. Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki

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

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

* Re: [PATCH v4 12/16] mtd: onenand: omap2: Enable DMA by default
@ 2017-11-15 10:08     ` Roger Quadros
  0 siblings, 0 replies; 114+ messages in thread
From: Roger Quadros @ 2017-11-15 10:08 UTC (permalink / raw)
  To: Ladislav Michl, linux-mtd, linux-omap
  Cc: Tony Lindgren, Peter Ujfalusi, Boris Brezillon, Kyungmin Park

Hi,

On 11/11/17 23:24, Ladislav Michl wrote:
> DMA and R/B pin are independent on each other. Use DMA by default.

Is there a R/B pin on Onenand? It looks more like it has a RDY pin and
an INT pin (which is used for command completion interrupt).

I think the subject and message are a bit misleading.

It should be something like

mtd: onenand: omap2: decouple DMA enabling from INT pin availability

INT pin (gpio_irq) is not really needed for DMA but only for notification
when a command that needs wait has completed. We can still have DMA
even without gpio_irq available.

> 
> Signed-off-by: Ladislav Michl <ladis@linux-mips.org>
> ---
>  Changes:
>  -v4: new patch
> 
>  drivers/mtd/onenand/omap2.c | 41 +++++++++++++++++------------------------
>  1 file changed, 17 insertions(+), 24 deletions(-)
> 
> diff --git a/drivers/mtd/onenand/omap2.c b/drivers/mtd/onenand/omap2.c
> index e4857a41760d..62e4ede918c4 100644
> --- a/drivers/mtd/onenand/omap2.c
> +++ b/drivers/mtd/onenand/omap2.c
> @@ -152,17 +152,13 @@ static int omap2_onenand_wait(struct mtd_info *mtd, int state)
>  		}
>  
>  		reinit_completion(&c->irq_done);
> -		if (c->gpio_irq) {
> -			result = gpio_get_value(c->gpio_irq);
> -			if (result == -1) {
> -				ctrl = read_reg(c, ONENAND_REG_CTRL_STATUS);
> -				intr = read_reg(c, ONENAND_REG_INTERRUPT);
> -				wait_err("gpio error", state, ctrl, intr);
> -				return -EIO;
> -			}
> -		} else
> -			result = 0;
> -		if (result == 0) {
> +		result = gpio_get_value(c->gpio_irq);
> +		if (result < 0) {
> +			ctrl = read_reg(c, ONENAND_REG_CTRL_STATUS);
> +			intr = read_reg(c, ONENAND_REG_INTERRUPT);
> +			wait_err("gpio error", state, ctrl, intr);
> +			return -EIO;
> +		} else if (result == 0) {
>  			int retry_cnt = 0;
>  retry:
>  			if (!wait_for_completion_io_timeout(&c->irq_done,
> @@ -513,13 +509,15 @@ static int omap2_onenand_probe(struct platform_device *pdev)

We need to get rid if this code from probe.

        if (pdata->dma_channel < 0) {
                /* if -1, don't use DMA */
                c->gpio_irq = 0;
        }

>  			dev_err(&pdev->dev,  "Failed to request GPIO%d for "
>  				"OneNAND\n", c->gpio_irq);
>  			goto err_iounmap;
> -	}
> -	gpio_direction_input(c->gpio_irq);
> +		}
> +		gpio_direction_input(c->gpio_irq);
> +
> +		if ((r = request_irq(gpio_to_irq(c->gpio_irq),
> +				     omap2_onenand_interrupt, IRQF_TRIGGER_RISING,
> +				     pdev->dev.driver->name, c)) < 0)
> +			goto err_release_gpio;
>  
> -	if ((r = request_irq(gpio_to_irq(c->gpio_irq),
> -			     omap2_onenand_interrupt, IRQF_TRIGGER_RISING,
> -			     pdev->dev.driver->name, c)) < 0)
> -		goto err_release_gpio;
> +		this->wait = omap2_onenand_wait;
>  	}
>  
>  	if (pdata->dma_channel >= 0) {
> @@ -529,15 +527,11 @@ static int omap2_onenand_probe(struct platform_device *pdev)
>  		dma_cap_set(DMA_MEMCPY, mask);
>  
>  		c->dma_chan = dma_request_channel(mask, NULL, NULL);
> -		if (!c->dma_chan)
> -			dev_info(&pdev->dev,
> -				 "failed to allocate DMA for OneNAND, "
> -				 "using PIO instead\n");

Why get rid of the print message? Instead we could choose to error out completely
if a DMA channel was provided and we couldn't get it.

>  	}
>  
>  	dev_info(&pdev->dev, "initializing on CS%d, phys base 0x%08lx, virtual "
> -		 "base %p, freq %d MHz\n", c->gpmc_cs, c->phys_base,
> -		 c->onenand.base, c->freq);
> +		 "base %p, freq %d MHz, %s mode\n", c->gpmc_cs, c->phys_base,
> +		 c->onenand.base, c->freq, c->dma_chan ? "DMA" : "PIO");
>  
>  	c->pdev = pdev;
>  	c->mtd.priv = &c->onenand;
> @@ -547,7 +541,6 @@ static int omap2_onenand_probe(struct platform_device *pdev)
>  
>  	this = &c->onenand;
>  	if (c->dma_chan) {
> -		this->wait = omap2_onenand_wait;
>  		this->read_bufferram = omap2_onenand_read_bufferram;
>  		this->write_bufferram = omap2_onenand_write_bufferram;
>  	}
> 

-- 
cheers,
-roger

Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki. Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki

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

* Re: [PATCH v4 13/16] memory: omap-gpmc: Refactor OneNAND support
  2017-11-11 21:26   ` Ladislav Michl
@ 2017-11-15 10:13     ` Roger Quadros
  -1 siblings, 0 replies; 114+ messages in thread
From: Roger Quadros @ 2017-11-15 10:13 UTC (permalink / raw)
  To: Ladislav Michl, linux-mtd, linux-omap
  Cc: Tony Lindgren, Peter Ujfalusi, Kyungmin Park, Boris Brezillon

On 11/11/17 23:26, Ladislav Michl wrote:
> Use generic probe function to deal with OneNAND node and remove now useless
> gpmc_probe_onenand_child function.
> Import sync mode timing calculation function from mach-omap2/gpmc-onenand.c
> and prepare for MTD driver DTfication.
> 
> Signed-off-by: Ladislav Michl <ladis@linux-mips.org>
> ---
>  Changes:
>  -v2: add gpmc_omap_onenand_set_timings description
>  -v3: none
>  -v4: none
> 
>  drivers/memory/omap-gpmc.c | 158 +++++++++++++++++++++++++++++++++------------
>  include/linux/omap-gpmc.h  |  25 +++++++
>  2 files changed, 142 insertions(+), 41 deletions(-)
> 
> diff --git a/drivers/memory/omap-gpmc.c b/drivers/memory/omap-gpmc.c
> index 0e30ee1c8677..90a66b3f7ae1 100644
> --- a/drivers/memory/omap-gpmc.c
> +++ b/drivers/memory/omap-gpmc.c
> @@ -32,7 +32,6 @@
>  #include <linux/pm_runtime.h>
>  
>  #include <linux/platform_data/mtd-nand-omap2.h>
> -#include <linux/platform_data/mtd-onenand-omap2.h>
>  
>  #include <asm/mach-types.h>
>  
> @@ -1138,6 +1137,112 @@ struct gpmc_nand_ops *gpmc_omap_get_nand_ops(struct gpmc_nand_regs *reg, int cs)
>  }
>  EXPORT_SYMBOL_GPL(gpmc_omap_get_nand_ops);
>  
> +static void gpmc_omap_onenand_calc_sync_timings(struct gpmc_timings *t,
> +						struct gpmc_settings *s,
> +						int freq, int latency)
> +{
> +	struct gpmc_device_timings dev_t;
> +	const int t_cer  = 15;
> +	const int t_avdp = 12;
> +	const int t_cez  = 20; /* max of t_cez, t_oez */
> +	const int t_wpl  = 40;
> +	const int t_wph  = 30;
> +	int min_gpmc_clk_period, t_ces, t_avds, t_avdh, t_ach, t_aavdh, t_rdyo;
> +
> +	switch (freq) {
> +	case 104:
> +		min_gpmc_clk_period = 9600; /* 104 MHz */
> +		t_ces   = 3;
> +		t_avds  = 4;
> +		t_avdh  = 2;
> +		t_ach   = 3;
> +		t_aavdh = 6;
> +		t_rdyo  = 6;
> +		break;
> +	case 83:
> +		min_gpmc_clk_period = 12000; /* 83 MHz */
> +		t_ces   = 5;
> +		t_avds  = 4;
> +		t_avdh  = 2;
> +		t_ach   = 6;
> +		t_aavdh = 6;
> +		t_rdyo  = 9;
> +		break;
> +	case 66:
> +		min_gpmc_clk_period = 15000; /* 66 MHz */
> +		t_ces   = 6;
> +		t_avds  = 5;
> +		t_avdh  = 2;
> +		t_ach   = 6;
> +		t_aavdh = 6;
> +		t_rdyo  = 11;
> +		break;
> +	default:
> +		min_gpmc_clk_period = 18500; /* 54 MHz */
> +		t_ces   = 7;
> +		t_avds  = 7;
> +		t_avdh  = 7;
> +		t_ach   = 9;
> +		t_aavdh = 7;
> +		t_rdyo  = 15;
> +		break;
> +	}
> +
> +	/* Set synchronous read timings */
> +	memset(&dev_t, 0, sizeof(dev_t));
> +
> +	if (!s->sync_write) {
> +		dev_t.t_avdp_w = max(t_avdp, t_cer) * 1000;
> +		dev_t.t_wpl = t_wpl * 1000;
> +		dev_t.t_wph = t_wph * 1000;
> +		dev_t.t_aavdh = t_aavdh * 1000;
> +	}
> +	dev_t.ce_xdelay = true;
> +	dev_t.avd_xdelay = true;
> +	dev_t.oe_xdelay = true;
> +	dev_t.we_xdelay = true;
> +	dev_t.clk = min_gpmc_clk_period;
> +	dev_t.t_bacc = dev_t.clk;
> +	dev_t.t_ces = t_ces * 1000;
> +	dev_t.t_avds = t_avds * 1000;
> +	dev_t.t_avdh = t_avdh * 1000;
> +	dev_t.t_ach = t_ach * 1000;
> +	dev_t.cyc_iaa = (latency + 1);
> +	dev_t.t_cez_r = t_cez * 1000;
> +	dev_t.t_cez_w = dev_t.t_cez_r;
> +	dev_t.cyc_aavdh_oe = 1;
> +	dev_t.t_rdyo = t_rdyo * 1000 + min_gpmc_clk_period;
> +
> +	gpmc_calc_timings(t, s, &dev_t);
> +}
> +
> +int gpmc_omap_onenand_set_timings(struct device *dev, int cs, int freq,
> +				  int latency,
> +				  struct gpmc_onenand_info *info)
> +{
> +	int ret;
> +	struct gpmc_timings gpmc_t;
> +	struct gpmc_settings gpmc_s;
> +
> +	gpmc_read_settings_dt(dev->of_node, &gpmc_s);
> +
> +	info->sync_read = gpmc_s.sync_read;
> +	info->sync_write = gpmc_s.sync_write;
> +	info->burst_len = gpmc_s.burst_len;
> +
> +	if (!gpmc_s.sync_read && !gpmc_s.sync_write)
> +		return 0;
> +
> +	gpmc_omap_onenand_calc_sync_timings(&gpmc_t, &gpmc_s, freq, latency);
> +
> +	ret = gpmc_cs_program_settings(cs, &gpmc_s);
> +	if (ret < 0)
> +		return ret;
> +
> +	return gpmc_cs_set_timings(cs, &gpmc_t, &gpmc_s);
> +}
> +EXPORT_SYMBOL_GPL(gpmc_omap_onenand_set_timings);
> +
>  int gpmc_get_client_irq(unsigned irq_config)
>  {
>  	if (!gpmc_irq_domain) {
> @@ -1916,41 +2021,6 @@ static void __maybe_unused gpmc_read_timings_dt(struct device_node *np,
>  		of_property_read_bool(np, "gpmc,time-para-granularity");
>  }
>  
> -#if IS_ENABLED(CONFIG_MTD_ONENAND)
> -static int gpmc_probe_onenand_child(struct platform_device *pdev,
> -				 struct device_node *child)
> -{
> -	u32 val;
> -	struct omap_onenand_platform_data *gpmc_onenand_data;
> -
> -	if (of_property_read_u32(child, "reg", &val) < 0) {
> -		dev_err(&pdev->dev, "%pOF has no 'reg' property\n",
> -			child);
> -		return -ENODEV;
> -	}
> -
> -	gpmc_onenand_data = devm_kzalloc(&pdev->dev, sizeof(*gpmc_onenand_data),
> -					 GFP_KERNEL);
> -	if (!gpmc_onenand_data)
> -		return -ENOMEM;
> -
> -	gpmc_onenand_data->cs = val;
> -	gpmc_onenand_data->of_node = child;
> -	gpmc_onenand_data->dma_channel = -1;
> -
> -	if (!of_property_read_u32(child, "dma-channel", &val))
> -		gpmc_onenand_data->dma_channel = val;
> -
> -	return gpmc_onenand_init(gpmc_onenand_data);
> -}
> -#else
> -static int gpmc_probe_onenand_child(struct platform_device *pdev,
> -				    struct device_node *child)
> -{
> -	return 0;
> -}
> -#endif
> -
>  /**
>   * gpmc_probe_generic_child - configures the gpmc for a child device
>   * @pdev:	pointer to gpmc platform device
> @@ -2053,6 +2123,16 @@ static int gpmc_probe_generic_child(struct platform_device *pdev,
>  		}
>  	}
>  
> +	if (of_node_cmp(child->name, "onenand") == 0) {
> +		/* Warn about older DT blobs with no compatible property */
> +		if (!of_property_read_bool(child, "compatible")) {
> +			dev_warn(&pdev->dev,
> +				 "Incompatible OneNAND node: missing compatible");
> +			ret = -EINVAL;
> +			goto err;
> +		}
> +	}
> +
>  	if (of_device_is_compatible(child, "ti,omap2-nand")) {
>  		/* NAND specific setup */
>  		val = 8;
> @@ -2189,11 +2269,7 @@ static void gpmc_probe_dt_children(struct platform_device *pdev)
>  		if (!child->name)
>  			continue;
>  
> -		if (of_node_cmp(child->name, "onenand") == 0)
> -			ret = gpmc_probe_onenand_child(pdev, child);
> -		else
> -			ret = gpmc_probe_generic_child(pdev, child);
> -
> +		ret = gpmc_probe_generic_child(pdev, child);
>  		if (ret) {
>  			dev_err(&pdev->dev, "failed to probe DT child '%s': %d\n",
>  				child->name, ret);
> diff --git a/include/linux/omap-gpmc.h b/include/linux/omap-gpmc.h
> index edfa280c3d56..067bea5e98c4 100644
> --- a/include/linux/omap-gpmc.h
> +++ b/include/linux/omap-gpmc.h
> @@ -25,15 +25,40 @@ struct gpmc_nand_ops {
>  
>  struct gpmc_nand_regs;
>  
> +struct gpmc_onenand_info {
> +	bool sync_read;
> +	bool sync_write;
> +	int burst_len;
> +};
> +
>  #if IS_ENABLED(CONFIG_OMAP_GPMC)
>  struct gpmc_nand_ops *gpmc_omap_get_nand_ops(struct gpmc_nand_regs *regs,
>  					     int cs);
> +/**
> + * gpmc_omap_onenand_set_timings - set optimized sync timings.
> + * @cs:      Chip Select Region
> + * @freq:    Chip frequency
> + * @latency: Burst latency cycle count
> + * @info:    Structure describing parameters used

How about adding some description? e.g.

sets optimized timings for the provided @cs region based on
provided @freq and @latency. Updates the @info structure based on
the GPMC settings.

> + */
> +int gpmc_omap_onenand_set_timings(struct device *dev, int cs, int freq,
> +				  int latency,
> +				  struct gpmc_onenand_info *info);
> +
>  #else
>  static inline struct gpmc_nand_ops *gpmc_omap_get_nand_ops(struct gpmc_nand_regs *regs,
>  							   int cs)
>  {
>  	return NULL;
>  }
> +
> +static inline
> +int gpmc_omap_onenand_set_timings(struct device *dev, int cs, int freq,
> +				  int latency,
> +				  struct gpmc_onenand_info *info)
> +{
> +	return -EINVAL;
> +}
>  #endif /* CONFIG_OMAP_GPMC */
>  
>  extern int gpmc_calc_timings(struct gpmc_timings *gpmc_t,
> 

-- 
cheers,
-roger

Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki. Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki

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

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

* Re: [PATCH v4 13/16] memory: omap-gpmc: Refactor OneNAND support
@ 2017-11-15 10:13     ` Roger Quadros
  0 siblings, 0 replies; 114+ messages in thread
From: Roger Quadros @ 2017-11-15 10:13 UTC (permalink / raw)
  To: Ladislav Michl, linux-mtd, linux-omap
  Cc: Tony Lindgren, Peter Ujfalusi, Boris Brezillon, Kyungmin Park

On 11/11/17 23:26, Ladislav Michl wrote:
> Use generic probe function to deal with OneNAND node and remove now useless
> gpmc_probe_onenand_child function.
> Import sync mode timing calculation function from mach-omap2/gpmc-onenand.c
> and prepare for MTD driver DTfication.
> 
> Signed-off-by: Ladislav Michl <ladis@linux-mips.org>
> ---
>  Changes:
>  -v2: add gpmc_omap_onenand_set_timings description
>  -v3: none
>  -v4: none
> 
>  drivers/memory/omap-gpmc.c | 158 +++++++++++++++++++++++++++++++++------------
>  include/linux/omap-gpmc.h  |  25 +++++++
>  2 files changed, 142 insertions(+), 41 deletions(-)
> 
> diff --git a/drivers/memory/omap-gpmc.c b/drivers/memory/omap-gpmc.c
> index 0e30ee1c8677..90a66b3f7ae1 100644
> --- a/drivers/memory/omap-gpmc.c
> +++ b/drivers/memory/omap-gpmc.c
> @@ -32,7 +32,6 @@
>  #include <linux/pm_runtime.h>
>  
>  #include <linux/platform_data/mtd-nand-omap2.h>
> -#include <linux/platform_data/mtd-onenand-omap2.h>
>  
>  #include <asm/mach-types.h>
>  
> @@ -1138,6 +1137,112 @@ struct gpmc_nand_ops *gpmc_omap_get_nand_ops(struct gpmc_nand_regs *reg, int cs)
>  }
>  EXPORT_SYMBOL_GPL(gpmc_omap_get_nand_ops);
>  
> +static void gpmc_omap_onenand_calc_sync_timings(struct gpmc_timings *t,
> +						struct gpmc_settings *s,
> +						int freq, int latency)
> +{
> +	struct gpmc_device_timings dev_t;
> +	const int t_cer  = 15;
> +	const int t_avdp = 12;
> +	const int t_cez  = 20; /* max of t_cez, t_oez */
> +	const int t_wpl  = 40;
> +	const int t_wph  = 30;
> +	int min_gpmc_clk_period, t_ces, t_avds, t_avdh, t_ach, t_aavdh, t_rdyo;
> +
> +	switch (freq) {
> +	case 104:
> +		min_gpmc_clk_period = 9600; /* 104 MHz */
> +		t_ces   = 3;
> +		t_avds  = 4;
> +		t_avdh  = 2;
> +		t_ach   = 3;
> +		t_aavdh = 6;
> +		t_rdyo  = 6;
> +		break;
> +	case 83:
> +		min_gpmc_clk_period = 12000; /* 83 MHz */
> +		t_ces   = 5;
> +		t_avds  = 4;
> +		t_avdh  = 2;
> +		t_ach   = 6;
> +		t_aavdh = 6;
> +		t_rdyo  = 9;
> +		break;
> +	case 66:
> +		min_gpmc_clk_period = 15000; /* 66 MHz */
> +		t_ces   = 6;
> +		t_avds  = 5;
> +		t_avdh  = 2;
> +		t_ach   = 6;
> +		t_aavdh = 6;
> +		t_rdyo  = 11;
> +		break;
> +	default:
> +		min_gpmc_clk_period = 18500; /* 54 MHz */
> +		t_ces   = 7;
> +		t_avds  = 7;
> +		t_avdh  = 7;
> +		t_ach   = 9;
> +		t_aavdh = 7;
> +		t_rdyo  = 15;
> +		break;
> +	}
> +
> +	/* Set synchronous read timings */
> +	memset(&dev_t, 0, sizeof(dev_t));
> +
> +	if (!s->sync_write) {
> +		dev_t.t_avdp_w = max(t_avdp, t_cer) * 1000;
> +		dev_t.t_wpl = t_wpl * 1000;
> +		dev_t.t_wph = t_wph * 1000;
> +		dev_t.t_aavdh = t_aavdh * 1000;
> +	}
> +	dev_t.ce_xdelay = true;
> +	dev_t.avd_xdelay = true;
> +	dev_t.oe_xdelay = true;
> +	dev_t.we_xdelay = true;
> +	dev_t.clk = min_gpmc_clk_period;
> +	dev_t.t_bacc = dev_t.clk;
> +	dev_t.t_ces = t_ces * 1000;
> +	dev_t.t_avds = t_avds * 1000;
> +	dev_t.t_avdh = t_avdh * 1000;
> +	dev_t.t_ach = t_ach * 1000;
> +	dev_t.cyc_iaa = (latency + 1);
> +	dev_t.t_cez_r = t_cez * 1000;
> +	dev_t.t_cez_w = dev_t.t_cez_r;
> +	dev_t.cyc_aavdh_oe = 1;
> +	dev_t.t_rdyo = t_rdyo * 1000 + min_gpmc_clk_period;
> +
> +	gpmc_calc_timings(t, s, &dev_t);
> +}
> +
> +int gpmc_omap_onenand_set_timings(struct device *dev, int cs, int freq,
> +				  int latency,
> +				  struct gpmc_onenand_info *info)
> +{
> +	int ret;
> +	struct gpmc_timings gpmc_t;
> +	struct gpmc_settings gpmc_s;
> +
> +	gpmc_read_settings_dt(dev->of_node, &gpmc_s);
> +
> +	info->sync_read = gpmc_s.sync_read;
> +	info->sync_write = gpmc_s.sync_write;
> +	info->burst_len = gpmc_s.burst_len;
> +
> +	if (!gpmc_s.sync_read && !gpmc_s.sync_write)
> +		return 0;
> +
> +	gpmc_omap_onenand_calc_sync_timings(&gpmc_t, &gpmc_s, freq, latency);
> +
> +	ret = gpmc_cs_program_settings(cs, &gpmc_s);
> +	if (ret < 0)
> +		return ret;
> +
> +	return gpmc_cs_set_timings(cs, &gpmc_t, &gpmc_s);
> +}
> +EXPORT_SYMBOL_GPL(gpmc_omap_onenand_set_timings);
> +
>  int gpmc_get_client_irq(unsigned irq_config)
>  {
>  	if (!gpmc_irq_domain) {
> @@ -1916,41 +2021,6 @@ static void __maybe_unused gpmc_read_timings_dt(struct device_node *np,
>  		of_property_read_bool(np, "gpmc,time-para-granularity");
>  }
>  
> -#if IS_ENABLED(CONFIG_MTD_ONENAND)
> -static int gpmc_probe_onenand_child(struct platform_device *pdev,
> -				 struct device_node *child)
> -{
> -	u32 val;
> -	struct omap_onenand_platform_data *gpmc_onenand_data;
> -
> -	if (of_property_read_u32(child, "reg", &val) < 0) {
> -		dev_err(&pdev->dev, "%pOF has no 'reg' property\n",
> -			child);
> -		return -ENODEV;
> -	}
> -
> -	gpmc_onenand_data = devm_kzalloc(&pdev->dev, sizeof(*gpmc_onenand_data),
> -					 GFP_KERNEL);
> -	if (!gpmc_onenand_data)
> -		return -ENOMEM;
> -
> -	gpmc_onenand_data->cs = val;
> -	gpmc_onenand_data->of_node = child;
> -	gpmc_onenand_data->dma_channel = -1;
> -
> -	if (!of_property_read_u32(child, "dma-channel", &val))
> -		gpmc_onenand_data->dma_channel = val;
> -
> -	return gpmc_onenand_init(gpmc_onenand_data);
> -}
> -#else
> -static int gpmc_probe_onenand_child(struct platform_device *pdev,
> -				    struct device_node *child)
> -{
> -	return 0;
> -}
> -#endif
> -
>  /**
>   * gpmc_probe_generic_child - configures the gpmc for a child device
>   * @pdev:	pointer to gpmc platform device
> @@ -2053,6 +2123,16 @@ static int gpmc_probe_generic_child(struct platform_device *pdev,
>  		}
>  	}
>  
> +	if (of_node_cmp(child->name, "onenand") == 0) {
> +		/* Warn about older DT blobs with no compatible property */
> +		if (!of_property_read_bool(child, "compatible")) {
> +			dev_warn(&pdev->dev,
> +				 "Incompatible OneNAND node: missing compatible");
> +			ret = -EINVAL;
> +			goto err;
> +		}
> +	}
> +
>  	if (of_device_is_compatible(child, "ti,omap2-nand")) {
>  		/* NAND specific setup */
>  		val = 8;
> @@ -2189,11 +2269,7 @@ static void gpmc_probe_dt_children(struct platform_device *pdev)
>  		if (!child->name)
>  			continue;
>  
> -		if (of_node_cmp(child->name, "onenand") == 0)
> -			ret = gpmc_probe_onenand_child(pdev, child);
> -		else
> -			ret = gpmc_probe_generic_child(pdev, child);
> -
> +		ret = gpmc_probe_generic_child(pdev, child);
>  		if (ret) {
>  			dev_err(&pdev->dev, "failed to probe DT child '%s': %d\n",
>  				child->name, ret);
> diff --git a/include/linux/omap-gpmc.h b/include/linux/omap-gpmc.h
> index edfa280c3d56..067bea5e98c4 100644
> --- a/include/linux/omap-gpmc.h
> +++ b/include/linux/omap-gpmc.h
> @@ -25,15 +25,40 @@ struct gpmc_nand_ops {
>  
>  struct gpmc_nand_regs;
>  
> +struct gpmc_onenand_info {
> +	bool sync_read;
> +	bool sync_write;
> +	int burst_len;
> +};
> +
>  #if IS_ENABLED(CONFIG_OMAP_GPMC)
>  struct gpmc_nand_ops *gpmc_omap_get_nand_ops(struct gpmc_nand_regs *regs,
>  					     int cs);
> +/**
> + * gpmc_omap_onenand_set_timings - set optimized sync timings.
> + * @cs:      Chip Select Region
> + * @freq:    Chip frequency
> + * @latency: Burst latency cycle count
> + * @info:    Structure describing parameters used

How about adding some description? e.g.

sets optimized timings for the provided @cs region based on
provided @freq and @latency. Updates the @info structure based on
the GPMC settings.

> + */
> +int gpmc_omap_onenand_set_timings(struct device *dev, int cs, int freq,
> +				  int latency,
> +				  struct gpmc_onenand_info *info);
> +
>  #else
>  static inline struct gpmc_nand_ops *gpmc_omap_get_nand_ops(struct gpmc_nand_regs *regs,
>  							   int cs)
>  {
>  	return NULL;
>  }
> +
> +static inline
> +int gpmc_omap_onenand_set_timings(struct device *dev, int cs, int freq,
> +				  int latency,
> +				  struct gpmc_onenand_info *info)
> +{
> +	return -EINVAL;
> +}
>  #endif /* CONFIG_OMAP_GPMC */
>  
>  extern int gpmc_calc_timings(struct gpmc_timings *gpmc_t,
> 

-- 
cheers,
-roger

Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki. Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki

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

* Re: [PATCH v4 12/16] mtd: onenand: omap2: Enable DMA by default
  2017-11-15 10:08     ` Roger Quadros
@ 2017-11-15 10:32       ` Ladislav Michl
  -1 siblings, 0 replies; 114+ messages in thread
From: Ladislav Michl @ 2017-11-15 10:32 UTC (permalink / raw)
  To: Roger Quadros
  Cc: Boris Brezillon, Tony Lindgren, Peter Ujfalusi, Kyungmin Park,
	linux-mtd, linux-omap

On Wed, Nov 15, 2017 at 12:08:05PM +0200, Roger Quadros wrote:
> Hi,
> 
> On 11/11/17 23:24, Ladislav Michl wrote:
> > DMA and R/B pin are independent on each other. Use DMA by default.
> 
> Is there a R/B pin on Onenand? It looks more like it has a RDY pin and
> an INT pin (which is used for command completion interrupt).

(See also my previous answer) Yes, there's RDY and INT pin. I tried to use
the same scheme as NAND is using, but perhaps it doesn't fit too well here.
Therefore I'm proposing to keep INT pin name and use int-gpios in DT
bindings. Suggestions?

> I think the subject and message are a bit misleading.
> 
> It should be something like
> 
> mtd: onenand: omap2: decouple DMA enabling from INT pin availability
> 
> INT pin (gpio_irq) is not really needed for DMA but only for notification
> when a command that needs wait has completed. We can still have DMA
> even without gpio_irq available.

Thanks, that's definitely better :-)

> > Signed-off-by: Ladislav Michl <ladis@linux-mips.org>
> > ---
> >  Changes:
> >  -v4: new patch
> > 
> >  drivers/mtd/onenand/omap2.c | 41 +++++++++++++++++------------------------
> >  1 file changed, 17 insertions(+), 24 deletions(-)
> > 
> > diff --git a/drivers/mtd/onenand/omap2.c b/drivers/mtd/onenand/omap2.c
> > index e4857a41760d..62e4ede918c4 100644
> > --- a/drivers/mtd/onenand/omap2.c
> > +++ b/drivers/mtd/onenand/omap2.c
> > @@ -152,17 +152,13 @@ static int omap2_onenand_wait(struct mtd_info *mtd, int state)
> >  		}
> >  
> >  		reinit_completion(&c->irq_done);
> > -		if (c->gpio_irq) {
> > -			result = gpio_get_value(c->gpio_irq);
> > -			if (result == -1) {
> > -				ctrl = read_reg(c, ONENAND_REG_CTRL_STATUS);
> > -				intr = read_reg(c, ONENAND_REG_INTERRUPT);
> > -				wait_err("gpio error", state, ctrl, intr);
> > -				return -EIO;
> > -			}
> > -		} else
> > -			result = 0;
> > -		if (result == 0) {
> > +		result = gpio_get_value(c->gpio_irq);
> > +		if (result < 0) {
> > +			ctrl = read_reg(c, ONENAND_REG_CTRL_STATUS);
> > +			intr = read_reg(c, ONENAND_REG_INTERRUPT);
> > +			wait_err("gpio error", state, ctrl, intr);
> > +			return -EIO;
> > +		} else if (result == 0) {
> >  			int retry_cnt = 0;
> >  retry:
> >  			if (!wait_for_completion_io_timeout(&c->irq_done,
> > @@ -513,13 +509,15 @@ static int omap2_onenand_probe(struct platform_device *pdev)
> 
> We need to get rid if this code from probe.
> 
>         if (pdata->dma_channel < 0) {
>                 /* if -1, don't use DMA */
>                 c->gpio_irq = 0;
>         }

Yes. I overlooked it when shuffling with patches. In ended in later patch, but it
really belongs here. Will fix.

> >  			dev_err(&pdev->dev,  "Failed to request GPIO%d for "
> >  				"OneNAND\n", c->gpio_irq);
> >  			goto err_iounmap;
> > -	}
> > -	gpio_direction_input(c->gpio_irq);
> > +		}
> > +		gpio_direction_input(c->gpio_irq);
> > +
> > +		if ((r = request_irq(gpio_to_irq(c->gpio_irq),
> > +				     omap2_onenand_interrupt, IRQF_TRIGGER_RISING,
> > +				     pdev->dev.driver->name, c)) < 0)
> > +			goto err_release_gpio;
> >  
> > -	if ((r = request_irq(gpio_to_irq(c->gpio_irq),
> > -			     omap2_onenand_interrupt, IRQF_TRIGGER_RISING,
> > -			     pdev->dev.driver->name, c)) < 0)
> > -		goto err_release_gpio;
> > +		this->wait = omap2_onenand_wait;
> >  	}
> >  
> >  	if (pdata->dma_channel >= 0) {
> > @@ -529,15 +527,11 @@ static int omap2_onenand_probe(struct platform_device *pdev)
> >  		dma_cap_set(DMA_MEMCPY, mask);
> >  
> >  		c->dma_chan = dma_request_channel(mask, NULL, NULL);
> > -		if (!c->dma_chan)
> > -			dev_info(&pdev->dev,
> > -				 "failed to allocate DMA for OneNAND, "
> > -				 "using PIO instead\n");
> 
> Why get rid of the print message? Instead we could choose to error out completely
> if a DMA channel was provided and we couldn't get it.

The point is that without pdata->dma_channel condition above, DMA is always
enabled and it seems too strict to me to fail, when driver can continue to work.

> >  	}
> >  
> >  	dev_info(&pdev->dev, "initializing on CS%d, phys base 0x%08lx, virtual "
> > -		 "base %p, freq %d MHz\n", c->gpmc_cs, c->phys_base,
> > -		 c->onenand.base, c->freq);
> > +		 "base %p, freq %d MHz, %s mode\n", c->gpmc_cs, c->phys_base,
> > +		 c->onenand.base, c->freq, c->dma_chan ? "DMA" : "PIO");

See here ^. We just merely print message driver is running in PIO mode.

> >  	c->pdev = pdev;
> >  	c->mtd.priv = &c->onenand;
> > @@ -547,7 +541,6 @@ static int omap2_onenand_probe(struct platform_device *pdev)
> >  
> >  	this = &c->onenand;
> >  	if (c->dma_chan) {
> > -		this->wait = omap2_onenand_wait;
> >  		this->read_bufferram = omap2_onenand_read_bufferram;
> >  		this->write_bufferram = omap2_onenand_write_bufferram;
> >  	}
> > 
> 
> -- 
> cheers,
> -roger
> 
> Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki. Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki

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

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

* Re: [PATCH v4 12/16] mtd: onenand: omap2: Enable DMA by default
@ 2017-11-15 10:32       ` Ladislav Michl
  0 siblings, 0 replies; 114+ messages in thread
From: Ladislav Michl @ 2017-11-15 10:32 UTC (permalink / raw)
  To: Roger Quadros
  Cc: linux-mtd, linux-omap, Tony Lindgren, Peter Ujfalusi,
	Boris Brezillon, Kyungmin Park

On Wed, Nov 15, 2017 at 12:08:05PM +0200, Roger Quadros wrote:
> Hi,
> 
> On 11/11/17 23:24, Ladislav Michl wrote:
> > DMA and R/B pin are independent on each other. Use DMA by default.
> 
> Is there a R/B pin on Onenand? It looks more like it has a RDY pin and
> an INT pin (which is used for command completion interrupt).

(See also my previous answer) Yes, there's RDY and INT pin. I tried to use
the same scheme as NAND is using, but perhaps it doesn't fit too well here.
Therefore I'm proposing to keep INT pin name and use int-gpios in DT
bindings. Suggestions?

> I think the subject and message are a bit misleading.
> 
> It should be something like
> 
> mtd: onenand: omap2: decouple DMA enabling from INT pin availability
> 
> INT pin (gpio_irq) is not really needed for DMA but only for notification
> when a command that needs wait has completed. We can still have DMA
> even without gpio_irq available.

Thanks, that's definitely better :-)

> > Signed-off-by: Ladislav Michl <ladis@linux-mips.org>
> > ---
> >  Changes:
> >  -v4: new patch
> > 
> >  drivers/mtd/onenand/omap2.c | 41 +++++++++++++++++------------------------
> >  1 file changed, 17 insertions(+), 24 deletions(-)
> > 
> > diff --git a/drivers/mtd/onenand/omap2.c b/drivers/mtd/onenand/omap2.c
> > index e4857a41760d..62e4ede918c4 100644
> > --- a/drivers/mtd/onenand/omap2.c
> > +++ b/drivers/mtd/onenand/omap2.c
> > @@ -152,17 +152,13 @@ static int omap2_onenand_wait(struct mtd_info *mtd, int state)
> >  		}
> >  
> >  		reinit_completion(&c->irq_done);
> > -		if (c->gpio_irq) {
> > -			result = gpio_get_value(c->gpio_irq);
> > -			if (result == -1) {
> > -				ctrl = read_reg(c, ONENAND_REG_CTRL_STATUS);
> > -				intr = read_reg(c, ONENAND_REG_INTERRUPT);
> > -				wait_err("gpio error", state, ctrl, intr);
> > -				return -EIO;
> > -			}
> > -		} else
> > -			result = 0;
> > -		if (result == 0) {
> > +		result = gpio_get_value(c->gpio_irq);
> > +		if (result < 0) {
> > +			ctrl = read_reg(c, ONENAND_REG_CTRL_STATUS);
> > +			intr = read_reg(c, ONENAND_REG_INTERRUPT);
> > +			wait_err("gpio error", state, ctrl, intr);
> > +			return -EIO;
> > +		} else if (result == 0) {
> >  			int retry_cnt = 0;
> >  retry:
> >  			if (!wait_for_completion_io_timeout(&c->irq_done,
> > @@ -513,13 +509,15 @@ static int omap2_onenand_probe(struct platform_device *pdev)
> 
> We need to get rid if this code from probe.
> 
>         if (pdata->dma_channel < 0) {
>                 /* if -1, don't use DMA */
>                 c->gpio_irq = 0;
>         }

Yes. I overlooked it when shuffling with patches. In ended in later patch, but it
really belongs here. Will fix.

> >  			dev_err(&pdev->dev,  "Failed to request GPIO%d for "
> >  				"OneNAND\n", c->gpio_irq);
> >  			goto err_iounmap;
> > -	}
> > -	gpio_direction_input(c->gpio_irq);
> > +		}
> > +		gpio_direction_input(c->gpio_irq);
> > +
> > +		if ((r = request_irq(gpio_to_irq(c->gpio_irq),
> > +				     omap2_onenand_interrupt, IRQF_TRIGGER_RISING,
> > +				     pdev->dev.driver->name, c)) < 0)
> > +			goto err_release_gpio;
> >  
> > -	if ((r = request_irq(gpio_to_irq(c->gpio_irq),
> > -			     omap2_onenand_interrupt, IRQF_TRIGGER_RISING,
> > -			     pdev->dev.driver->name, c)) < 0)
> > -		goto err_release_gpio;
> > +		this->wait = omap2_onenand_wait;
> >  	}
> >  
> >  	if (pdata->dma_channel >= 0) {
> > @@ -529,15 +527,11 @@ static int omap2_onenand_probe(struct platform_device *pdev)
> >  		dma_cap_set(DMA_MEMCPY, mask);
> >  
> >  		c->dma_chan = dma_request_channel(mask, NULL, NULL);
> > -		if (!c->dma_chan)
> > -			dev_info(&pdev->dev,
> > -				 "failed to allocate DMA for OneNAND, "
> > -				 "using PIO instead\n");
> 
> Why get rid of the print message? Instead we could choose to error out completely
> if a DMA channel was provided and we couldn't get it.

The point is that without pdata->dma_channel condition above, DMA is always
enabled and it seems too strict to me to fail, when driver can continue to work.

> >  	}
> >  
> >  	dev_info(&pdev->dev, "initializing on CS%d, phys base 0x%08lx, virtual "
> > -		 "base %p, freq %d MHz\n", c->gpmc_cs, c->phys_base,
> > -		 c->onenand.base, c->freq);
> > +		 "base %p, freq %d MHz, %s mode\n", c->gpmc_cs, c->phys_base,
> > +		 c->onenand.base, c->freq, c->dma_chan ? "DMA" : "PIO");

See here ^. We just merely print message driver is running in PIO mode.

> >  	c->pdev = pdev;
> >  	c->mtd.priv = &c->onenand;
> > @@ -547,7 +541,6 @@ static int omap2_onenand_probe(struct platform_device *pdev)
> >  
> >  	this = &c->onenand;
> >  	if (c->dma_chan) {
> > -		this->wait = omap2_onenand_wait;
> >  		this->read_bufferram = omap2_onenand_read_bufferram;
> >  		this->write_bufferram = omap2_onenand_write_bufferram;
> >  	}
> > 
> 
> -- 
> cheers,
> -roger
> 
> Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki. Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki

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

* Re: [PATCH v4 13/16] memory: omap-gpmc: Refactor OneNAND support
  2017-11-15 10:13     ` Roger Quadros
@ 2017-11-15 10:37       ` Ladislav Michl
  -1 siblings, 0 replies; 114+ messages in thread
From: Ladislav Michl @ 2017-11-15 10:37 UTC (permalink / raw)
  To: Roger Quadros
  Cc: Boris Brezillon, Tony Lindgren, Peter Ujfalusi, Kyungmin Park,
	linux-mtd, linux-omap

On Wed, Nov 15, 2017 at 12:13:56PM +0200, Roger Quadros wrote:
> On 11/11/17 23:26, Ladislav Michl wrote:
[snip]
> > +/**
> > + * gpmc_omap_onenand_set_timings - set optimized sync timings.
> > + * @cs:      Chip Select Region
> > + * @freq:    Chip frequency
> > + * @latency: Burst latency cycle count
> > + * @info:    Structure describing parameters used
> 
> How about adding some description? e.g.
> 
> sets optimized timings for the provided @cs region based on
> provided @freq and @latency. Updates the @info structure based on
> the GPMC settings.

Added to v5, thank you.

Side question: u-boot has patman to deal with patch changelog. Is there
something similar or even better for linux? For the time being I setup
patman...

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

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

* Re: [PATCH v4 13/16] memory: omap-gpmc: Refactor OneNAND support
@ 2017-11-15 10:37       ` Ladislav Michl
  0 siblings, 0 replies; 114+ messages in thread
From: Ladislav Michl @ 2017-11-15 10:37 UTC (permalink / raw)
  To: Roger Quadros
  Cc: linux-mtd, linux-omap, Tony Lindgren, Peter Ujfalusi,
	Boris Brezillon, Kyungmin Park

On Wed, Nov 15, 2017 at 12:13:56PM +0200, Roger Quadros wrote:
> On 11/11/17 23:26, Ladislav Michl wrote:
[snip]
> > +/**
> > + * gpmc_omap_onenand_set_timings - set optimized sync timings.
> > + * @cs:      Chip Select Region
> > + * @freq:    Chip frequency
> > + * @latency: Burst latency cycle count
> > + * @info:    Structure describing parameters used
> 
> How about adding some description? e.g.
> 
> sets optimized timings for the provided @cs region based on
> provided @freq and @latency. Updates the @info structure based on
> the GPMC settings.

Added to v5, thank you.

Side question: u-boot has patman to deal with patch changelog. Is there
something similar or even better for linux? For the time being I setup
patman...

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

* Re: [PATCH v4 14/16] mtd: onenand: omap2: Configure driver from DT
  2017-11-11 21:27   ` Ladislav Michl
@ 2017-11-15 10:40     ` Roger Quadros
  -1 siblings, 0 replies; 114+ messages in thread
From: Roger Quadros @ 2017-11-15 10:40 UTC (permalink / raw)
  To: Ladislav Michl, linux-mtd, linux-omap
  Cc: Tony Lindgren, Peter Ujfalusi, Kyungmin Park, Boris Brezillon

On 11/11/17 23:27, Ladislav Michl wrote:
> Move away from platform data configuration and use pure DT approach.
> 
> Signed-off-by: Ladislav Michl <ladis@linux-mips.org>
> ---
>  Changes:
>  -v2: move cleanups into separate patches
>       simplify dma setup
>       fix checkpatch error
>       print info about otimized timings in sync mode only
>  -v3: remove 'ti,omap3-onenand' compatible as it is not needed anymore
>  -v4: none
> 
>  drivers/mtd/onenand/omap2.c | 264 +++++++++++++++++++++++++++-----------------
>  1 file changed, 162 insertions(+), 102 deletions(-)
> 
> diff --git a/drivers/mtd/onenand/omap2.c b/drivers/mtd/onenand/omap2.c
> index 62e4ede918c4..9ebbbf297993 100644
> --- a/drivers/mtd/onenand/omap2.c
> +++ b/drivers/mtd/onenand/omap2.c
> @@ -28,6 +28,8 @@
>  #include <linux/mtd/mtd.h>
>  #include <linux/mtd/onenand.h>
>  #include <linux/mtd/partitions.h>
> +#include <linux/of_device.h>
> +#include <linux/omap-gpmc.h>
>  #include <linux/platform_device.h>
>  #include <linux/interrupt.h>
>  #include <linux/delay.h>
> @@ -35,10 +37,9 @@
>  #include <linux/dmaengine.h>
>  #include <linux/io.h>
>  #include <linux/slab.h>
> -#include <linux/gpio.h>
> +#include <linux/gpio/consumer.h>
>  
>  #include <asm/mach/flash.h>
> -#include <linux/platform_data/mtd-onenand-omap2.h>
>  
>  #define DRIVER_NAME "omap2-onenand"
>  
> @@ -48,15 +49,12 @@ struct omap2_onenand {
>  	struct platform_device *pdev;
>  	int gpmc_cs;
>  	unsigned long phys_base;
> -	unsigned int mem_size;
> -	int gpio_irq;
> +	struct gpio_desc *ready_gpiod;

Is this the RDY pin or the INT pin?
If it is the INT pin then I'd keep the name as int_gpiod.

>  	struct mtd_info mtd;
>  	struct onenand_chip onenand;
>  	struct completion irq_done;
>  	struct completion dma_done;
>  	struct dma_chan *dma_chan;
> -	int freq;
> -	int (*setup)(void __iomem *base, int *freq_ptr);
>  };
>  
>  static void omap2_onenand_dma_complete_func(void *completion)
> @@ -84,6 +82,65 @@ static inline void write_reg(struct omap2_onenand *c, unsigned short value,
>  	writew(value, c->onenand.base + reg);
>  }
>  
> +static int omap2_onenand_set_cfg(struct omap2_onenand *c,
> +				 bool sr, bool sw,
> +				 int latency, int burst_len)
> +{
> +	unsigned short reg = ONENAND_SYS_CFG1_RDY | ONENAND_SYS_CFG1_INT;
> +
> +	reg |= latency << ONENAND_SYS_CFG1_BRL_SHIFT;
> +
> +	switch (burst_len) {
> +	case 0:		/* continuous */
> +		break;
> +	case 4:
> +		reg |= ONENAND_SYS_CFG1_BL_4;
> +		break;
> +	case 8:
> +		reg |= ONENAND_SYS_CFG1_BL_8;
> +		break;
> +	case 16:
> +		reg |= ONENAND_SYS_CFG1_BL_16;
> +		break;
> +	case 32:
> +		reg |= ONENAND_SYS_CFG1_BL_32;
> +		break;
> +	default:
> +		return -EINVAL;
> +	}
> +
> +	if (latency > 5)
> +		reg |= ONENAND_SYS_CFG1_HF;
> +	if (latency > 7)
> +		reg |= ONENAND_SYS_CFG1_VHF;
> +	if (sr)
> +		reg |= ONENAND_SYS_CFG1_SYNC_READ;
> +	if (sw)
> +		reg |= ONENAND_SYS_CFG1_SYNC_WRITE;
> +
> +	write_reg(c, reg, ONENAND_REG_SYS_CFG1);
> +
> +	return 0;
> +}
> +
> +static int omap2_onenand_get_freq(int ver)
> +{
> +	switch ((ver >> 4) & 0xf) {
> +	case 0:
> +		return 40;
> +	case 1:
> +		return 54;
> +	case 2:
> +		return 66;
> +	case 3:
> +		return 83;
> +	case 4:
> +		return 104;
> +	}
> +
> +	return -EINVAL;
> +}
> +
>  static void wait_err(char *msg, int state, unsigned int ctrl, unsigned int intr)
>  {
>  	printk(KERN_ERR "onenand_wait: %s! state %d ctrl 0x%04x intr 0x%04x\n",
> @@ -152,12 +209,12 @@ static int omap2_onenand_wait(struct mtd_info *mtd, int state)
>  		}
>  
>  		reinit_completion(&c->irq_done);
> -		result = gpio_get_value(c->gpio_irq);
> +		result = gpiod_get_value(c->ready_gpiod);
>  		if (result < 0) {
>  			ctrl = read_reg(c, ONENAND_REG_CTRL_STATUS);
>  			intr = read_reg(c, ONENAND_REG_INTERRUPT);
>  			wait_err("gpio error", state, ctrl, intr);
> -			return -EIO;
> +			return result;
>  		} else if (result == 0) {
>  			int retry_cnt = 0;
>  retry:
> @@ -431,8 +488,6 @@ static int omap2_onenand_write_bufferram(struct mtd_info *mtd, int area,
>  	return 0;
>  }
>  
> -static struct platform_driver omap2_onenand_driver;
> -
>  static void omap2_onenand_shutdown(struct platform_device *pdev)
>  {
>  	struct omap2_onenand *c = dev_get_drvdata(&pdev->dev);
> @@ -446,108 +501,124 @@ static void omap2_onenand_shutdown(struct platform_device *pdev)
>  
>  static int omap2_onenand_probe(struct platform_device *pdev)
>  {
> -	struct omap_onenand_platform_data *pdata;
> -	struct omap2_onenand *c;
> -	struct onenand_chip *this;
> -	int r;
> +	u32 val;
> +	dma_cap_mask_t mask;
> +	int freq, latency, r;
> +	unsigned int mem_size;
>  	struct resource *res;
> +	struct omap2_onenand *c;
> +	struct gpmc_onenand_info info;
> +	struct device *dev = &pdev->dev;
> +	struct device_node *np = dev->of_node;
>  
> -	pdata = dev_get_platdata(&pdev->dev);
> -	if (pdata == NULL) {
> -		dev_err(&pdev->dev, "platform data missing\n");
> -		return -ENODEV;
> +	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> +	if (!res) {
> +		dev_err(dev, "error getting memory resource\n");
> +		return -EINVAL;
>  	}
>  
> -	c = kzalloc(sizeof(struct omap2_onenand), GFP_KERNEL);

We should error out if np is NULL before beginning to read DT properties?

> +	r = of_property_read_u32(np, "reg", &val);
> +	if (r) {
> +		dev_err(dev, "reg not found in DT\n");
> +		return r;
> +	}
> +
> +	c = devm_kzalloc(dev, sizeof(struct omap2_onenand), GFP_KERNEL);
>  	if (!c)
>  		return -ENOMEM;
>  
>  	init_completion(&c->irq_done);
>  	init_completion(&c->dma_done);
> -	c->gpmc_cs = pdata->cs;
> -	c->gpio_irq = pdata->gpio_irq;
> -	if (pdata->dma_channel < 0) {
> -		/* if -1, don't use DMA */
> -		c->gpio_irq = 0;
> -	}
> +	c->gpmc_cs = val;
> +	c->phys_base = res->start;

Above 2 lines could be moved to just after where val and res is found respectively.

>  
> -	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> -	if (res == NULL) {
> -		r = -EINVAL;
> -		dev_err(&pdev->dev, "error getting memory resource\n");
> -		goto err_kfree;
> -	}
> +	mem_size = resource_size(res);
> +	if (!devm_request_mem_region(dev, c->phys_base, mem_size,
> +				     dev->driver->name)) {
>  
> -	c->phys_base = res->start;
> -	c->mem_size = resource_size(res);
> -
> -	if (request_mem_region(c->phys_base, c->mem_size,
> -			       pdev->dev.driver->name) == NULL) {
> -		dev_err(&pdev->dev, "Cannot reserve memory region at 0x%08lx, size: 0x%x\n",
> -						c->phys_base, c->mem_size);
> -		r = -EBUSY;
> -		goto err_kfree;
> -	}
> -	c->onenand.base = ioremap(c->phys_base, c->mem_size);
> -	if (c->onenand.base == NULL) {
> -		r = -ENOMEM;
> -		goto err_release_mem_region;
> +		dev_err(dev, "Cannot reserve memory region at 0x%08lx, size: 0x%x\n",
> +			c->phys_base, mem_size);
> +		return -EBUSY;
>  	}
>  
> -	if (pdata->onenand_setup != NULL) {
> -		r = pdata->onenand_setup(c->onenand.base, &c->freq);
> -		if (r < 0) {
> -			dev_err(&pdev->dev, "Onenand platform setup failed: "
> -				"%d\n", r);
> -			goto err_iounmap;
> -		}
> -		c->setup = pdata->onenand_setup;
> -	}
> +	c->onenand.base = devm_ioremap(dev, c->phys_base, mem_size);
> +	if (!c->onenand.base)
> +		return -ENOMEM;

How about doing request and ioremap in one shot?

	c->onenand.base = devm_ioremap_resource(&pdev->dev, res);
	if (IS_ERR(base))
		return PTR_ERR(base);

>  
> -	if (c->gpio_irq) {
> -		if ((r = gpio_request(c->gpio_irq, "OneNAND irq")) < 0) {
> -			dev_err(&pdev->dev,  "Failed to request GPIO%d for "
> -				"OneNAND\n", c->gpio_irq);
> -			goto err_iounmap;
> -		}
> -		gpio_direction_input(c->gpio_irq);
> +	c->ready_gpiod = devm_gpiod_get_optional(dev, "rb", GPIOD_IN);

I'd keep the name "onenand int" if it is the INT pin.

> +	if (IS_ERR(c->ready_gpiod)) {
> +		r = PTR_ERR(c->ready_gpiod);
> +		/* Just try again if this happens */
> +		if (r != -EPROBE_DEFER)
> +			dev_err(dev, "error getting gpio: %d\n", r);
> +		return r;
> +	}
>  
> -		if ((r = request_irq(gpio_to_irq(c->gpio_irq),
> -				     omap2_onenand_interrupt, IRQF_TRIGGER_RISING,
> -				     pdev->dev.driver->name, c)) < 0)
> -			goto err_release_gpio;
> +	if (c->ready_gpiod) {
> +		r = devm_request_irq(dev, gpiod_to_irq(c->ready_gpiod),
> +				     omap2_onenand_interrupt,
> +				     IRQF_TRIGGER_RISING, "OneNAND", c);

"onenand" to be consistent with onenand_base.c?

> +		if (r)
> +			return r;
>  
> -		this->wait = omap2_onenand_wait;
> +		c->onenand.wait = omap2_onenand_wait;
>  	}
>  
> -	if (pdata->dma_channel >= 0) {
> -		dma_cap_mask_t mask;
> -
> -		dma_cap_zero(mask);
> -		dma_cap_set(DMA_MEMCPY, mask);
> +	dma_cap_zero(mask);
> +	dma_cap_set(DMA_MEMCPY, mask);
>  
> -		c->dma_chan = dma_request_channel(mask, NULL, NULL);
> +	c->dma_chan = dma_request_channel(mask, NULL, NULL);
> +	if (c->dma_chan) {
> +		c->onenand.read_bufferram = omap2_onenand_read_bufferram;
> +		c->onenand.write_bufferram = omap2_onenand_write_bufferram;
>  	}
>  
> -	dev_info(&pdev->dev, "initializing on CS%d, phys base 0x%08lx, virtual "
> -		 "base %p, freq %d MHz, %s mode\n", c->gpmc_cs, c->phys_base,
> -		 c->onenand.base, c->freq, c->dma_chan ? "DMA" : "PIO");
> -
>  	c->pdev = pdev;
>  	c->mtd.priv = &c->onenand;
> +	c->mtd.dev.parent = dev;
> +	mtd_set_of_node(&c->mtd, dev->of_node);
>  
> -	c->mtd.dev.parent = &pdev->dev;
> -	mtd_set_of_node(&c->mtd, pdata->of_node);
> -
> -	this = &c->onenand;
> -	if (c->dma_chan) {
> -		this->read_bufferram = omap2_onenand_read_bufferram;
> -		this->write_bufferram = omap2_onenand_write_bufferram;
> -	}
> +	dev_info(dev, "initializing on CS%d (0x%08lx), va %p, %s mode\n",
> +		 c->gpmc_cs, c->phys_base, c->onenand.base,
> +		 c->dma_chan ? "DMA" : "PIO");
>  
>  	if ((r = onenand_scan(&c->mtd, 1)) < 0)
>  		goto err_release_dma;
>  
> +	freq = omap2_onenand_get_freq(c->onenand.version_id);
> +	if (freq > 0) {
> +		switch (freq) {
> +		case 104:
> +			latency = 7;
> +			break;
> +		case 83:
> +			latency = 6;
> +			break;
> +		case 66:
> +			latency = 5;
> +			break;
> +		case 56:
> +			latency = 4;
> +			break;
> +		default:	/* 40 MHz or lower */
> +			latency = 3;
> +			break;
> +		}
> +
> +		r = gpmc_omap_onenand_set_timings(dev, c->gpmc_cs,
> +						  freq, latency, &info);
> +		if (r)
> +			goto err_release_onenand;
> +
> +		r = omap2_onenand_set_cfg(c, info.sync_read, info.sync_write,
> +					  latency, info.burst_len);
> +		if (r)
> +			goto err_release_onenand;
> +
> +		if (info.sync_read || info.sync_write)
> +			dev_info(dev, "optimized timings for %d MHz\n", freq);
> +	}
> +
>  	r = mtd_device_register(&c->mtd, NULL, 0);
>  	if (r)
>  		goto err_release_onenand;
> @@ -561,17 +632,6 @@ static int omap2_onenand_probe(struct platform_device *pdev)
>  err_release_dma:
>  	if (c->dma_chan)
>  		dma_release_channel(c->dma_chan);
> -	if (c->gpio_irq)
> -		free_irq(gpio_to_irq(c->gpio_irq), c);
> -err_release_gpio:
> -	if (c->gpio_irq)
> -		gpio_free(c->gpio_irq);
> -err_iounmap:
> -	iounmap(c->onenand.base);
> -err_release_mem_region:
> -	release_mem_region(c->phys_base, c->mem_size);
> -err_kfree:
> -	kfree(c);
>  
>  	return r;
>  }
> @@ -584,23 +644,23 @@ static int omap2_onenand_remove(struct platform_device *pdev)
>  	if (c->dma_chan)
>  		dma_release_channel(c->dma_chan);
>  	omap2_onenand_shutdown(pdev);
> -	if (c->gpio_irq) {
> -		free_irq(gpio_to_irq(c->gpio_irq), c);
> -		gpio_free(c->gpio_irq);
> -	}
> -	iounmap(c->onenand.base);
> -	release_mem_region(c->phys_base, c->mem_size);
> -	kfree(c);
>  
>  	return 0;
>  }
>  
> +static const struct of_device_id omap2_onenand_id_table[] = {
> +	{ .compatible = "ti,omap2-onenand", },
> +	{},
> +};
> +MODULE_DEVICE_TABLE(of, omap2_onenand_id_table);
> +
>  static struct platform_driver omap2_onenand_driver = {
>  	.probe		= omap2_onenand_probe,
>  	.remove		= omap2_onenand_remove,
>  	.shutdown	= omap2_onenand_shutdown,
>  	.driver		= {
>  		.name	= DRIVER_NAME,
> +		.of_match_table = omap2_onenand_id_table,
>  	},
>  };
>  
> 

-- 
cheers,
-roger

Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki. Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki

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

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

* Re: [PATCH v4 14/16] mtd: onenand: omap2: Configure driver from DT
@ 2017-11-15 10:40     ` Roger Quadros
  0 siblings, 0 replies; 114+ messages in thread
From: Roger Quadros @ 2017-11-15 10:40 UTC (permalink / raw)
  To: Ladislav Michl, linux-mtd, linux-omap
  Cc: Tony Lindgren, Peter Ujfalusi, Boris Brezillon, Kyungmin Park

On 11/11/17 23:27, Ladislav Michl wrote:
> Move away from platform data configuration and use pure DT approach.
> 
> Signed-off-by: Ladislav Michl <ladis@linux-mips.org>
> ---
>  Changes:
>  -v2: move cleanups into separate patches
>       simplify dma setup
>       fix checkpatch error
>       print info about otimized timings in sync mode only
>  -v3: remove 'ti,omap3-onenand' compatible as it is not needed anymore
>  -v4: none
> 
>  drivers/mtd/onenand/omap2.c | 264 +++++++++++++++++++++++++++-----------------
>  1 file changed, 162 insertions(+), 102 deletions(-)
> 
> diff --git a/drivers/mtd/onenand/omap2.c b/drivers/mtd/onenand/omap2.c
> index 62e4ede918c4..9ebbbf297993 100644
> --- a/drivers/mtd/onenand/omap2.c
> +++ b/drivers/mtd/onenand/omap2.c
> @@ -28,6 +28,8 @@
>  #include <linux/mtd/mtd.h>
>  #include <linux/mtd/onenand.h>
>  #include <linux/mtd/partitions.h>
> +#include <linux/of_device.h>
> +#include <linux/omap-gpmc.h>
>  #include <linux/platform_device.h>
>  #include <linux/interrupt.h>
>  #include <linux/delay.h>
> @@ -35,10 +37,9 @@
>  #include <linux/dmaengine.h>
>  #include <linux/io.h>
>  #include <linux/slab.h>
> -#include <linux/gpio.h>
> +#include <linux/gpio/consumer.h>
>  
>  #include <asm/mach/flash.h>
> -#include <linux/platform_data/mtd-onenand-omap2.h>
>  
>  #define DRIVER_NAME "omap2-onenand"
>  
> @@ -48,15 +49,12 @@ struct omap2_onenand {
>  	struct platform_device *pdev;
>  	int gpmc_cs;
>  	unsigned long phys_base;
> -	unsigned int mem_size;
> -	int gpio_irq;
> +	struct gpio_desc *ready_gpiod;

Is this the RDY pin or the INT pin?
If it is the INT pin then I'd keep the name as int_gpiod.

>  	struct mtd_info mtd;
>  	struct onenand_chip onenand;
>  	struct completion irq_done;
>  	struct completion dma_done;
>  	struct dma_chan *dma_chan;
> -	int freq;
> -	int (*setup)(void __iomem *base, int *freq_ptr);
>  };
>  
>  static void omap2_onenand_dma_complete_func(void *completion)
> @@ -84,6 +82,65 @@ static inline void write_reg(struct omap2_onenand *c, unsigned short value,
>  	writew(value, c->onenand.base + reg);
>  }
>  
> +static int omap2_onenand_set_cfg(struct omap2_onenand *c,
> +				 bool sr, bool sw,
> +				 int latency, int burst_len)
> +{
> +	unsigned short reg = ONENAND_SYS_CFG1_RDY | ONENAND_SYS_CFG1_INT;
> +
> +	reg |= latency << ONENAND_SYS_CFG1_BRL_SHIFT;
> +
> +	switch (burst_len) {
> +	case 0:		/* continuous */
> +		break;
> +	case 4:
> +		reg |= ONENAND_SYS_CFG1_BL_4;
> +		break;
> +	case 8:
> +		reg |= ONENAND_SYS_CFG1_BL_8;
> +		break;
> +	case 16:
> +		reg |= ONENAND_SYS_CFG1_BL_16;
> +		break;
> +	case 32:
> +		reg |= ONENAND_SYS_CFG1_BL_32;
> +		break;
> +	default:
> +		return -EINVAL;
> +	}
> +
> +	if (latency > 5)
> +		reg |= ONENAND_SYS_CFG1_HF;
> +	if (latency > 7)
> +		reg |= ONENAND_SYS_CFG1_VHF;
> +	if (sr)
> +		reg |= ONENAND_SYS_CFG1_SYNC_READ;
> +	if (sw)
> +		reg |= ONENAND_SYS_CFG1_SYNC_WRITE;
> +
> +	write_reg(c, reg, ONENAND_REG_SYS_CFG1);
> +
> +	return 0;
> +}
> +
> +static int omap2_onenand_get_freq(int ver)
> +{
> +	switch ((ver >> 4) & 0xf) {
> +	case 0:
> +		return 40;
> +	case 1:
> +		return 54;
> +	case 2:
> +		return 66;
> +	case 3:
> +		return 83;
> +	case 4:
> +		return 104;
> +	}
> +
> +	return -EINVAL;
> +}
> +
>  static void wait_err(char *msg, int state, unsigned int ctrl, unsigned int intr)
>  {
>  	printk(KERN_ERR "onenand_wait: %s! state %d ctrl 0x%04x intr 0x%04x\n",
> @@ -152,12 +209,12 @@ static int omap2_onenand_wait(struct mtd_info *mtd, int state)
>  		}
>  
>  		reinit_completion(&c->irq_done);
> -		result = gpio_get_value(c->gpio_irq);
> +		result = gpiod_get_value(c->ready_gpiod);
>  		if (result < 0) {
>  			ctrl = read_reg(c, ONENAND_REG_CTRL_STATUS);
>  			intr = read_reg(c, ONENAND_REG_INTERRUPT);
>  			wait_err("gpio error", state, ctrl, intr);
> -			return -EIO;
> +			return result;
>  		} else if (result == 0) {
>  			int retry_cnt = 0;
>  retry:
> @@ -431,8 +488,6 @@ static int omap2_onenand_write_bufferram(struct mtd_info *mtd, int area,
>  	return 0;
>  }
>  
> -static struct platform_driver omap2_onenand_driver;
> -
>  static void omap2_onenand_shutdown(struct platform_device *pdev)
>  {
>  	struct omap2_onenand *c = dev_get_drvdata(&pdev->dev);
> @@ -446,108 +501,124 @@ static void omap2_onenand_shutdown(struct platform_device *pdev)
>  
>  static int omap2_onenand_probe(struct platform_device *pdev)
>  {
> -	struct omap_onenand_platform_data *pdata;
> -	struct omap2_onenand *c;
> -	struct onenand_chip *this;
> -	int r;
> +	u32 val;
> +	dma_cap_mask_t mask;
> +	int freq, latency, r;
> +	unsigned int mem_size;
>  	struct resource *res;
> +	struct omap2_onenand *c;
> +	struct gpmc_onenand_info info;
> +	struct device *dev = &pdev->dev;
> +	struct device_node *np = dev->of_node;
>  
> -	pdata = dev_get_platdata(&pdev->dev);
> -	if (pdata == NULL) {
> -		dev_err(&pdev->dev, "platform data missing\n");
> -		return -ENODEV;
> +	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> +	if (!res) {
> +		dev_err(dev, "error getting memory resource\n");
> +		return -EINVAL;
>  	}
>  
> -	c = kzalloc(sizeof(struct omap2_onenand), GFP_KERNEL);

We should error out if np is NULL before beginning to read DT properties?

> +	r = of_property_read_u32(np, "reg", &val);
> +	if (r) {
> +		dev_err(dev, "reg not found in DT\n");
> +		return r;
> +	}
> +
> +	c = devm_kzalloc(dev, sizeof(struct omap2_onenand), GFP_KERNEL);
>  	if (!c)
>  		return -ENOMEM;
>  
>  	init_completion(&c->irq_done);
>  	init_completion(&c->dma_done);
> -	c->gpmc_cs = pdata->cs;
> -	c->gpio_irq = pdata->gpio_irq;
> -	if (pdata->dma_channel < 0) {
> -		/* if -1, don't use DMA */
> -		c->gpio_irq = 0;
> -	}
> +	c->gpmc_cs = val;
> +	c->phys_base = res->start;

Above 2 lines could be moved to just after where val and res is found respectively.

>  
> -	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> -	if (res == NULL) {
> -		r = -EINVAL;
> -		dev_err(&pdev->dev, "error getting memory resource\n");
> -		goto err_kfree;
> -	}
> +	mem_size = resource_size(res);
> +	if (!devm_request_mem_region(dev, c->phys_base, mem_size,
> +				     dev->driver->name)) {
>  
> -	c->phys_base = res->start;
> -	c->mem_size = resource_size(res);
> -
> -	if (request_mem_region(c->phys_base, c->mem_size,
> -			       pdev->dev.driver->name) == NULL) {
> -		dev_err(&pdev->dev, "Cannot reserve memory region at 0x%08lx, size: 0x%x\n",
> -						c->phys_base, c->mem_size);
> -		r = -EBUSY;
> -		goto err_kfree;
> -	}
> -	c->onenand.base = ioremap(c->phys_base, c->mem_size);
> -	if (c->onenand.base == NULL) {
> -		r = -ENOMEM;
> -		goto err_release_mem_region;
> +		dev_err(dev, "Cannot reserve memory region at 0x%08lx, size: 0x%x\n",
> +			c->phys_base, mem_size);
> +		return -EBUSY;
>  	}
>  
> -	if (pdata->onenand_setup != NULL) {
> -		r = pdata->onenand_setup(c->onenand.base, &c->freq);
> -		if (r < 0) {
> -			dev_err(&pdev->dev, "Onenand platform setup failed: "
> -				"%d\n", r);
> -			goto err_iounmap;
> -		}
> -		c->setup = pdata->onenand_setup;
> -	}
> +	c->onenand.base = devm_ioremap(dev, c->phys_base, mem_size);
> +	if (!c->onenand.base)
> +		return -ENOMEM;

How about doing request and ioremap in one shot?

	c->onenand.base = devm_ioremap_resource(&pdev->dev, res);
	if (IS_ERR(base))
		return PTR_ERR(base);

>  
> -	if (c->gpio_irq) {
> -		if ((r = gpio_request(c->gpio_irq, "OneNAND irq")) < 0) {
> -			dev_err(&pdev->dev,  "Failed to request GPIO%d for "
> -				"OneNAND\n", c->gpio_irq);
> -			goto err_iounmap;
> -		}
> -		gpio_direction_input(c->gpio_irq);
> +	c->ready_gpiod = devm_gpiod_get_optional(dev, "rb", GPIOD_IN);

I'd keep the name "onenand int" if it is the INT pin.

> +	if (IS_ERR(c->ready_gpiod)) {
> +		r = PTR_ERR(c->ready_gpiod);
> +		/* Just try again if this happens */
> +		if (r != -EPROBE_DEFER)
> +			dev_err(dev, "error getting gpio: %d\n", r);
> +		return r;
> +	}
>  
> -		if ((r = request_irq(gpio_to_irq(c->gpio_irq),
> -				     omap2_onenand_interrupt, IRQF_TRIGGER_RISING,
> -				     pdev->dev.driver->name, c)) < 0)
> -			goto err_release_gpio;
> +	if (c->ready_gpiod) {
> +		r = devm_request_irq(dev, gpiod_to_irq(c->ready_gpiod),
> +				     omap2_onenand_interrupt,
> +				     IRQF_TRIGGER_RISING, "OneNAND", c);

"onenand" to be consistent with onenand_base.c?

> +		if (r)
> +			return r;
>  
> -		this->wait = omap2_onenand_wait;
> +		c->onenand.wait = omap2_onenand_wait;
>  	}
>  
> -	if (pdata->dma_channel >= 0) {
> -		dma_cap_mask_t mask;
> -
> -		dma_cap_zero(mask);
> -		dma_cap_set(DMA_MEMCPY, mask);
> +	dma_cap_zero(mask);
> +	dma_cap_set(DMA_MEMCPY, mask);
>  
> -		c->dma_chan = dma_request_channel(mask, NULL, NULL);
> +	c->dma_chan = dma_request_channel(mask, NULL, NULL);
> +	if (c->dma_chan) {
> +		c->onenand.read_bufferram = omap2_onenand_read_bufferram;
> +		c->onenand.write_bufferram = omap2_onenand_write_bufferram;
>  	}
>  
> -	dev_info(&pdev->dev, "initializing on CS%d, phys base 0x%08lx, virtual "
> -		 "base %p, freq %d MHz, %s mode\n", c->gpmc_cs, c->phys_base,
> -		 c->onenand.base, c->freq, c->dma_chan ? "DMA" : "PIO");
> -
>  	c->pdev = pdev;
>  	c->mtd.priv = &c->onenand;
> +	c->mtd.dev.parent = dev;
> +	mtd_set_of_node(&c->mtd, dev->of_node);
>  
> -	c->mtd.dev.parent = &pdev->dev;
> -	mtd_set_of_node(&c->mtd, pdata->of_node);
> -
> -	this = &c->onenand;
> -	if (c->dma_chan) {
> -		this->read_bufferram = omap2_onenand_read_bufferram;
> -		this->write_bufferram = omap2_onenand_write_bufferram;
> -	}
> +	dev_info(dev, "initializing on CS%d (0x%08lx), va %p, %s mode\n",
> +		 c->gpmc_cs, c->phys_base, c->onenand.base,
> +		 c->dma_chan ? "DMA" : "PIO");
>  
>  	if ((r = onenand_scan(&c->mtd, 1)) < 0)
>  		goto err_release_dma;
>  
> +	freq = omap2_onenand_get_freq(c->onenand.version_id);
> +	if (freq > 0) {
> +		switch (freq) {
> +		case 104:
> +			latency = 7;
> +			break;
> +		case 83:
> +			latency = 6;
> +			break;
> +		case 66:
> +			latency = 5;
> +			break;
> +		case 56:
> +			latency = 4;
> +			break;
> +		default:	/* 40 MHz or lower */
> +			latency = 3;
> +			break;
> +		}
> +
> +		r = gpmc_omap_onenand_set_timings(dev, c->gpmc_cs,
> +						  freq, latency, &info);
> +		if (r)
> +			goto err_release_onenand;
> +
> +		r = omap2_onenand_set_cfg(c, info.sync_read, info.sync_write,
> +					  latency, info.burst_len);
> +		if (r)
> +			goto err_release_onenand;
> +
> +		if (info.sync_read || info.sync_write)
> +			dev_info(dev, "optimized timings for %d MHz\n", freq);
> +	}
> +
>  	r = mtd_device_register(&c->mtd, NULL, 0);
>  	if (r)
>  		goto err_release_onenand;
> @@ -561,17 +632,6 @@ static int omap2_onenand_probe(struct platform_device *pdev)
>  err_release_dma:
>  	if (c->dma_chan)
>  		dma_release_channel(c->dma_chan);
> -	if (c->gpio_irq)
> -		free_irq(gpio_to_irq(c->gpio_irq), c);
> -err_release_gpio:
> -	if (c->gpio_irq)
> -		gpio_free(c->gpio_irq);
> -err_iounmap:
> -	iounmap(c->onenand.base);
> -err_release_mem_region:
> -	release_mem_region(c->phys_base, c->mem_size);
> -err_kfree:
> -	kfree(c);
>  
>  	return r;
>  }
> @@ -584,23 +644,23 @@ static int omap2_onenand_remove(struct platform_device *pdev)
>  	if (c->dma_chan)
>  		dma_release_channel(c->dma_chan);
>  	omap2_onenand_shutdown(pdev);
> -	if (c->gpio_irq) {
> -		free_irq(gpio_to_irq(c->gpio_irq), c);
> -		gpio_free(c->gpio_irq);
> -	}
> -	iounmap(c->onenand.base);
> -	release_mem_region(c->phys_base, c->mem_size);
> -	kfree(c);
>  
>  	return 0;
>  }
>  
> +static const struct of_device_id omap2_onenand_id_table[] = {
> +	{ .compatible = "ti,omap2-onenand", },
> +	{},
> +};
> +MODULE_DEVICE_TABLE(of, omap2_onenand_id_table);
> +
>  static struct platform_driver omap2_onenand_driver = {
>  	.probe		= omap2_onenand_probe,
>  	.remove		= omap2_onenand_remove,
>  	.shutdown	= omap2_onenand_shutdown,
>  	.driver		= {
>  		.name	= DRIVER_NAME,
> +		.of_match_table = omap2_onenand_id_table,
>  	},
>  };
>  
> 

-- 
cheers,
-roger

Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki. Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki

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

* Re: [PATCH v4 12/16] mtd: onenand: omap2: Enable DMA by default
  2017-11-15 10:32       ` Ladislav Michl
@ 2017-11-15 10:43         ` Roger Quadros
  -1 siblings, 0 replies; 114+ messages in thread
From: Roger Quadros @ 2017-11-15 10:43 UTC (permalink / raw)
  To: Ladislav Michl
  Cc: Boris Brezillon, Tony Lindgren, Peter Ujfalusi, Kyungmin Park,
	linux-mtd, linux-omap

On 15/11/17 12:32, Ladislav Michl wrote:
> On Wed, Nov 15, 2017 at 12:08:05PM +0200, Roger Quadros wrote:
>> Hi,
>>
>> On 11/11/17 23:24, Ladislav Michl wrote:
>>> DMA and R/B pin are independent on each other. Use DMA by default.
>>
>> Is there a R/B pin on Onenand? It looks more like it has a RDY pin and
>> an INT pin (which is used for command completion interrupt).
> 
> (See also my previous answer) Yes, there's RDY and INT pin. I tried to use
> the same scheme as NAND is using, but perhaps it doesn't fit too well here.
> Therefore I'm proposing to keep INT pin name and use int-gpios in DT
> bindings. Suggestions?
> 
>> I think the subject and message are a bit misleading.
>>
>> It should be something like
>>
>> mtd: onenand: omap2: decouple DMA enabling from INT pin availability
>>
>> INT pin (gpio_irq) is not really needed for DMA but only for notification
>> when a command that needs wait has completed. We can still have DMA
>> even without gpio_irq available.
> 
> Thanks, that's definitely better :-)
> 
>>> Signed-off-by: Ladislav Michl <ladis@linux-mips.org>
>>> ---
>>>  Changes:
>>>  -v4: new patch
>>>
>>>  drivers/mtd/onenand/omap2.c | 41 +++++++++++++++++------------------------
>>>  1 file changed, 17 insertions(+), 24 deletions(-)
>>>
>>> diff --git a/drivers/mtd/onenand/omap2.c b/drivers/mtd/onenand/omap2.c
>>> index e4857a41760d..62e4ede918c4 100644
>>> --- a/drivers/mtd/onenand/omap2.c
>>> +++ b/drivers/mtd/onenand/omap2.c
>>> @@ -152,17 +152,13 @@ static int omap2_onenand_wait(struct mtd_info *mtd, int state)
>>>  		}
>>>  
>>>  		reinit_completion(&c->irq_done);
>>> -		if (c->gpio_irq) {
>>> -			result = gpio_get_value(c->gpio_irq);
>>> -			if (result == -1) {
>>> -				ctrl = read_reg(c, ONENAND_REG_CTRL_STATUS);
>>> -				intr = read_reg(c, ONENAND_REG_INTERRUPT);
>>> -				wait_err("gpio error", state, ctrl, intr);
>>> -				return -EIO;
>>> -			}
>>> -		} else
>>> -			result = 0;
>>> -		if (result == 0) {
>>> +		result = gpio_get_value(c->gpio_irq);
>>> +		if (result < 0) {
>>> +			ctrl = read_reg(c, ONENAND_REG_CTRL_STATUS);
>>> +			intr = read_reg(c, ONENAND_REG_INTERRUPT);
>>> +			wait_err("gpio error", state, ctrl, intr);
>>> +			return -EIO;
>>> +		} else if (result == 0) {
>>>  			int retry_cnt = 0;
>>>  retry:
>>>  			if (!wait_for_completion_io_timeout(&c->irq_done,
>>> @@ -513,13 +509,15 @@ static int omap2_onenand_probe(struct platform_device *pdev)
>>
>> We need to get rid if this code from probe.
>>
>>         if (pdata->dma_channel < 0) {
>>                 /* if -1, don't use DMA */
>>                 c->gpio_irq = 0;
>>         }
> 
> Yes. I overlooked it when shuffling with patches. In ended in later patch, but it
> really belongs here. Will fix.
> 
>>>  			dev_err(&pdev->dev,  "Failed to request GPIO%d for "
>>>  				"OneNAND\n", c->gpio_irq);
>>>  			goto err_iounmap;
>>> -	}
>>> -	gpio_direction_input(c->gpio_irq);
>>> +		}
>>> +		gpio_direction_input(c->gpio_irq);
>>> +
>>> +		if ((r = request_irq(gpio_to_irq(c->gpio_irq),
>>> +				     omap2_onenand_interrupt, IRQF_TRIGGER_RISING,
>>> +				     pdev->dev.driver->name, c)) < 0)
>>> +			goto err_release_gpio;
>>>  
>>> -	if ((r = request_irq(gpio_to_irq(c->gpio_irq),
>>> -			     omap2_onenand_interrupt, IRQF_TRIGGER_RISING,
>>> -			     pdev->dev.driver->name, c)) < 0)
>>> -		goto err_release_gpio;
>>> +		this->wait = omap2_onenand_wait;
>>>  	}
>>>  
>>>  	if (pdata->dma_channel >= 0) {
>>> @@ -529,15 +527,11 @@ static int omap2_onenand_probe(struct platform_device *pdev)
>>>  		dma_cap_set(DMA_MEMCPY, mask);
>>>  
>>>  		c->dma_chan = dma_request_channel(mask, NULL, NULL);
>>> -		if (!c->dma_chan)
>>> -			dev_info(&pdev->dev,
>>> -				 "failed to allocate DMA for OneNAND, "
>>> -				 "using PIO instead\n");
>>
>> Why get rid of the print message? Instead we could choose to error out completely
>> if a DMA channel was provided and we couldn't get it.
> 
> The point is that without pdata->dma_channel condition above, DMA is always
> enabled and it seems too strict to me to fail, when driver can continue to work.

OK. fair enough.

> 
>>>  	}
>>>  
>>>  	dev_info(&pdev->dev, "initializing on CS%d, phys base 0x%08lx, virtual "
>>> -		 "base %p, freq %d MHz\n", c->gpmc_cs, c->phys_base,
>>> -		 c->onenand.base, c->freq);
>>> +		 "base %p, freq %d MHz, %s mode\n", c->gpmc_cs, c->phys_base,
>>> +		 c->onenand.base, c->freq, c->dma_chan ? "DMA" : "PIO");
> 
> See here ^. We just merely print message driver is running in PIO mode.
> 
>>>  	c->pdev = pdev;
>>>  	c->mtd.priv = &c->onenand;
>>> @@ -547,7 +541,6 @@ static int omap2_onenand_probe(struct platform_device *pdev)
>>>  
>>>  	this = &c->onenand;
>>>  	if (c->dma_chan) {
>>> -		this->wait = omap2_onenand_wait;
>>>  		this->read_bufferram = omap2_onenand_read_bufferram;
>>>  		this->write_bufferram = omap2_onenand_write_bufferram;
>>>  	}
>>>
>>
>> -- 
>> cheers,
>> -roger
>>
>> Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki. Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki

-- 
cheers,
-roger

Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki. Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki

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

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

* Re: [PATCH v4 12/16] mtd: onenand: omap2: Enable DMA by default
@ 2017-11-15 10:43         ` Roger Quadros
  0 siblings, 0 replies; 114+ messages in thread
From: Roger Quadros @ 2017-11-15 10:43 UTC (permalink / raw)
  To: Ladislav Michl
  Cc: linux-mtd, linux-omap, Tony Lindgren, Peter Ujfalusi,
	Boris Brezillon, Kyungmin Park

On 15/11/17 12:32, Ladislav Michl wrote:
> On Wed, Nov 15, 2017 at 12:08:05PM +0200, Roger Quadros wrote:
>> Hi,
>>
>> On 11/11/17 23:24, Ladislav Michl wrote:
>>> DMA and R/B pin are independent on each other. Use DMA by default.
>>
>> Is there a R/B pin on Onenand? It looks more like it has a RDY pin and
>> an INT pin (which is used for command completion interrupt).
> 
> (See also my previous answer) Yes, there's RDY and INT pin. I tried to use
> the same scheme as NAND is using, but perhaps it doesn't fit too well here.
> Therefore I'm proposing to keep INT pin name and use int-gpios in DT
> bindings. Suggestions?
> 
>> I think the subject and message are a bit misleading.
>>
>> It should be something like
>>
>> mtd: onenand: omap2: decouple DMA enabling from INT pin availability
>>
>> INT pin (gpio_irq) is not really needed for DMA but only for notification
>> when a command that needs wait has completed. We can still have DMA
>> even without gpio_irq available.
> 
> Thanks, that's definitely better :-)
> 
>>> Signed-off-by: Ladislav Michl <ladis@linux-mips.org>
>>> ---
>>>  Changes:
>>>  -v4: new patch
>>>
>>>  drivers/mtd/onenand/omap2.c | 41 +++++++++++++++++------------------------
>>>  1 file changed, 17 insertions(+), 24 deletions(-)
>>>
>>> diff --git a/drivers/mtd/onenand/omap2.c b/drivers/mtd/onenand/omap2.c
>>> index e4857a41760d..62e4ede918c4 100644
>>> --- a/drivers/mtd/onenand/omap2.c
>>> +++ b/drivers/mtd/onenand/omap2.c
>>> @@ -152,17 +152,13 @@ static int omap2_onenand_wait(struct mtd_info *mtd, int state)
>>>  		}
>>>  
>>>  		reinit_completion(&c->irq_done);
>>> -		if (c->gpio_irq) {
>>> -			result = gpio_get_value(c->gpio_irq);
>>> -			if (result == -1) {
>>> -				ctrl = read_reg(c, ONENAND_REG_CTRL_STATUS);
>>> -				intr = read_reg(c, ONENAND_REG_INTERRUPT);
>>> -				wait_err("gpio error", state, ctrl, intr);
>>> -				return -EIO;
>>> -			}
>>> -		} else
>>> -			result = 0;
>>> -		if (result == 0) {
>>> +		result = gpio_get_value(c->gpio_irq);
>>> +		if (result < 0) {
>>> +			ctrl = read_reg(c, ONENAND_REG_CTRL_STATUS);
>>> +			intr = read_reg(c, ONENAND_REG_INTERRUPT);
>>> +			wait_err("gpio error", state, ctrl, intr);
>>> +			return -EIO;
>>> +		} else if (result == 0) {
>>>  			int retry_cnt = 0;
>>>  retry:
>>>  			if (!wait_for_completion_io_timeout(&c->irq_done,
>>> @@ -513,13 +509,15 @@ static int omap2_onenand_probe(struct platform_device *pdev)
>>
>> We need to get rid if this code from probe.
>>
>>         if (pdata->dma_channel < 0) {
>>                 /* if -1, don't use DMA */
>>                 c->gpio_irq = 0;
>>         }
> 
> Yes. I overlooked it when shuffling with patches. In ended in later patch, but it
> really belongs here. Will fix.
> 
>>>  			dev_err(&pdev->dev,  "Failed to request GPIO%d for "
>>>  				"OneNAND\n", c->gpio_irq);
>>>  			goto err_iounmap;
>>> -	}
>>> -	gpio_direction_input(c->gpio_irq);
>>> +		}
>>> +		gpio_direction_input(c->gpio_irq);
>>> +
>>> +		if ((r = request_irq(gpio_to_irq(c->gpio_irq),
>>> +				     omap2_onenand_interrupt, IRQF_TRIGGER_RISING,
>>> +				     pdev->dev.driver->name, c)) < 0)
>>> +			goto err_release_gpio;
>>>  
>>> -	if ((r = request_irq(gpio_to_irq(c->gpio_irq),
>>> -			     omap2_onenand_interrupt, IRQF_TRIGGER_RISING,
>>> -			     pdev->dev.driver->name, c)) < 0)
>>> -		goto err_release_gpio;
>>> +		this->wait = omap2_onenand_wait;
>>>  	}
>>>  
>>>  	if (pdata->dma_channel >= 0) {
>>> @@ -529,15 +527,11 @@ static int omap2_onenand_probe(struct platform_device *pdev)
>>>  		dma_cap_set(DMA_MEMCPY, mask);
>>>  
>>>  		c->dma_chan = dma_request_channel(mask, NULL, NULL);
>>> -		if (!c->dma_chan)
>>> -			dev_info(&pdev->dev,
>>> -				 "failed to allocate DMA for OneNAND, "
>>> -				 "using PIO instead\n");
>>
>> Why get rid of the print message? Instead we could choose to error out completely
>> if a DMA channel was provided and we couldn't get it.
> 
> The point is that without pdata->dma_channel condition above, DMA is always
> enabled and it seems too strict to me to fail, when driver can continue to work.

OK. fair enough.

> 
>>>  	}
>>>  
>>>  	dev_info(&pdev->dev, "initializing on CS%d, phys base 0x%08lx, virtual "
>>> -		 "base %p, freq %d MHz\n", c->gpmc_cs, c->phys_base,
>>> -		 c->onenand.base, c->freq);
>>> +		 "base %p, freq %d MHz, %s mode\n", c->gpmc_cs, c->phys_base,
>>> +		 c->onenand.base, c->freq, c->dma_chan ? "DMA" : "PIO");
> 
> See here ^. We just merely print message driver is running in PIO mode.
> 
>>>  	c->pdev = pdev;
>>>  	c->mtd.priv = &c->onenand;
>>> @@ -547,7 +541,6 @@ static int omap2_onenand_probe(struct platform_device *pdev)
>>>  
>>>  	this = &c->onenand;
>>>  	if (c->dma_chan) {
>>> -		this->wait = omap2_onenand_wait;
>>>  		this->read_bufferram = omap2_onenand_read_bufferram;
>>>  		this->write_bufferram = omap2_onenand_write_bufferram;
>>>  	}
>>>
>>
>> -- 
>> cheers,
>> -roger
>>
>> Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki. Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki

-- 
cheers,
-roger

Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki. Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki

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

* Re: [PATCH v4 12/16] mtd: onenand: omap2: Enable DMA by default
  2017-11-15 10:32       ` Ladislav Michl
@ 2017-11-15 10:44         ` Roger Quadros
  -1 siblings, 0 replies; 114+ messages in thread
From: Roger Quadros @ 2017-11-15 10:44 UTC (permalink / raw)
  To: Ladislav Michl
  Cc: Boris Brezillon, Tony Lindgren, Peter Ujfalusi, Kyungmin Park,
	linux-mtd, linux-omap

On 15/11/17 12:32, Ladislav Michl wrote:
> On Wed, Nov 15, 2017 at 12:08:05PM +0200, Roger Quadros wrote:
>> Hi,
>>
>> On 11/11/17 23:24, Ladislav Michl wrote:
>>> DMA and R/B pin are independent on each other. Use DMA by default.
>>
>> Is there a R/B pin on Onenand? It looks more like it has a RDY pin and
>> an INT pin (which is used for command completion interrupt).
> 
> (See also my previous answer) Yes, there's RDY and INT pin. I tried to use
> the same scheme as NAND is using, but perhaps it doesn't fit too well here.
> Therefore I'm proposing to keep INT pin name and use int-gpios in DT
> bindings. Suggestions?

Yes, I think that is better too.

-- 
cheers,
-roger

Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki. Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki

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

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

* Re: [PATCH v4 12/16] mtd: onenand: omap2: Enable DMA by default
@ 2017-11-15 10:44         ` Roger Quadros
  0 siblings, 0 replies; 114+ messages in thread
From: Roger Quadros @ 2017-11-15 10:44 UTC (permalink / raw)
  To: Ladislav Michl
  Cc: linux-mtd, linux-omap, Tony Lindgren, Peter Ujfalusi,
	Boris Brezillon, Kyungmin Park

On 15/11/17 12:32, Ladislav Michl wrote:
> On Wed, Nov 15, 2017 at 12:08:05PM +0200, Roger Quadros wrote:
>> Hi,
>>
>> On 11/11/17 23:24, Ladislav Michl wrote:
>>> DMA and R/B pin are independent on each other. Use DMA by default.
>>
>> Is there a R/B pin on Onenand? It looks more like it has a RDY pin and
>> an INT pin (which is used for command completion interrupt).
> 
> (See also my previous answer) Yes, there's RDY and INT pin. I tried to use
> the same scheme as NAND is using, but perhaps it doesn't fit too well here.
> Therefore I'm proposing to keep INT pin name and use int-gpios in DT
> bindings. Suggestions?

Yes, I think that is better too.

-- 
cheers,
-roger

Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki. Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki

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

* Re: [PATCH v4 15/16] ARM: OMAP2+: Remove gpmc-onenand
  2017-11-11 21:29   ` Ladislav Michl
@ 2017-11-15 10:46     ` Roger Quadros
  -1 siblings, 0 replies; 114+ messages in thread
From: Roger Quadros @ 2017-11-15 10:46 UTC (permalink / raw)
  To: Ladislav Michl, linux-mtd, linux-omap
  Cc: Tony Lindgren, Peter Ujfalusi, Kyungmin Park, Boris Brezillon

On 11/11/17 23:29, Ladislav Michl wrote:
> As OneNAND driver is now using devicetree gpmc-onenand and its
> platform data is unused and can be removed.
> 
> Signed-off-by: Ladislav Michl <ladis@linux-mips.org>

Acked-by: Roger Quadros <rogerq@ti.com>

-- 
cheers,
-roger

Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki. Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki

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

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

* Re: [PATCH v4 15/16] ARM: OMAP2+: Remove gpmc-onenand
@ 2017-11-15 10:46     ` Roger Quadros
  0 siblings, 0 replies; 114+ messages in thread
From: Roger Quadros @ 2017-11-15 10:46 UTC (permalink / raw)
  To: Ladislav Michl, linux-mtd, linux-omap
  Cc: Tony Lindgren, Peter Ujfalusi, Boris Brezillon, Kyungmin Park

On 11/11/17 23:29, Ladislav Michl wrote:
> As OneNAND driver is now using devicetree gpmc-onenand and its
> platform data is unused and can be removed.
> 
> Signed-off-by: Ladislav Michl <ladis@linux-mips.org>

Acked-by: Roger Quadros <rogerq@ti.com>

-- 
cheers,
-roger

Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki. Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki

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

* Re: [PATCH v4 14/16] mtd: onenand: omap2: Configure driver from DT
  2017-11-15 10:40     ` Roger Quadros
@ 2017-11-15 10:53       ` Ladislav Michl
  -1 siblings, 0 replies; 114+ messages in thread
From: Ladislav Michl @ 2017-11-15 10:53 UTC (permalink / raw)
  To: Roger Quadros
  Cc: Boris Brezillon, Tony Lindgren, Peter Ujfalusi, Kyungmin Park,
	linux-mtd, linux-omap

On Wed, Nov 15, 2017 at 12:40:14PM +0200, Roger Quadros wrote:
> On 11/11/17 23:27, Ladislav Michl wrote:
> > Move away from platform data configuration and use pure DT approach.
> > 
> > Signed-off-by: Ladislav Michl <ladis@linux-mips.org>
> > ---
> >  Changes:
> >  -v2: move cleanups into separate patches
> >       simplify dma setup
> >       fix checkpatch error
> >       print info about otimized timings in sync mode only
> >  -v3: remove 'ti,omap3-onenand' compatible as it is not needed anymore
> >  -v4: none
> > 
> >  drivers/mtd/onenand/omap2.c | 264 +++++++++++++++++++++++++++-----------------
> >  1 file changed, 162 insertions(+), 102 deletions(-)
> > 
> > diff --git a/drivers/mtd/onenand/omap2.c b/drivers/mtd/onenand/omap2.c
> > index 62e4ede918c4..9ebbbf297993 100644
> > --- a/drivers/mtd/onenand/omap2.c
> > +++ b/drivers/mtd/onenand/omap2.c
> > @@ -28,6 +28,8 @@
> >  #include <linux/mtd/mtd.h>
> >  #include <linux/mtd/onenand.h>
> >  #include <linux/mtd/partitions.h>
> > +#include <linux/of_device.h>
> > +#include <linux/omap-gpmc.h>
> >  #include <linux/platform_device.h>
> >  #include <linux/interrupt.h>
> >  #include <linux/delay.h>
> > @@ -35,10 +37,9 @@
> >  #include <linux/dmaengine.h>
> >  #include <linux/io.h>
> >  #include <linux/slab.h>
> > -#include <linux/gpio.h>
> > +#include <linux/gpio/consumer.h>
> >  
> >  #include <asm/mach/flash.h>
> > -#include <linux/platform_data/mtd-onenand-omap2.h>
> >  
> >  #define DRIVER_NAME "omap2-onenand"
> >  
> > @@ -48,15 +49,12 @@ struct omap2_onenand {
> >  	struct platform_device *pdev;
> >  	int gpmc_cs;
> >  	unsigned long phys_base;
> > -	unsigned int mem_size;
> > -	int gpio_irq;
> > +	struct gpio_desc *ready_gpiod;
> 
> Is this the RDY pin or the INT pin?
> If it is the INT pin then I'd keep the name as int_gpiod.

It is INT pin, so I'll use int_gpiod. Also shall we use int-gpios
DT bindings then? Note, there can be two DPP devices in one die.

> >  	struct mtd_info mtd;
> >  	struct onenand_chip onenand;
> >  	struct completion irq_done;
> >  	struct completion dma_done;
> >  	struct dma_chan *dma_chan;
> > -	int freq;
> > -	int (*setup)(void __iomem *base, int *freq_ptr);
> >  };
> >  
> >  static void omap2_onenand_dma_complete_func(void *completion)
> > @@ -84,6 +82,65 @@ static inline void write_reg(struct omap2_onenand *c, unsigned short value,
> >  	writew(value, c->onenand.base + reg);
> >  }
> >  
> > +static int omap2_onenand_set_cfg(struct omap2_onenand *c,
> > +				 bool sr, bool sw,
> > +				 int latency, int burst_len)
> > +{
> > +	unsigned short reg = ONENAND_SYS_CFG1_RDY | ONENAND_SYS_CFG1_INT;
> > +
> > +	reg |= latency << ONENAND_SYS_CFG1_BRL_SHIFT;
> > +
> > +	switch (burst_len) {
> > +	case 0:		/* continuous */
> > +		break;
> > +	case 4:
> > +		reg |= ONENAND_SYS_CFG1_BL_4;
> > +		break;
> > +	case 8:
> > +		reg |= ONENAND_SYS_CFG1_BL_8;
> > +		break;
> > +	case 16:
> > +		reg |= ONENAND_SYS_CFG1_BL_16;
> > +		break;
> > +	case 32:
> > +		reg |= ONENAND_SYS_CFG1_BL_32;
> > +		break;
> > +	default:
> > +		return -EINVAL;
> > +	}
> > +
> > +	if (latency > 5)
> > +		reg |= ONENAND_SYS_CFG1_HF;
> > +	if (latency > 7)
> > +		reg |= ONENAND_SYS_CFG1_VHF;
> > +	if (sr)
> > +		reg |= ONENAND_SYS_CFG1_SYNC_READ;
> > +	if (sw)
> > +		reg |= ONENAND_SYS_CFG1_SYNC_WRITE;
> > +
> > +	write_reg(c, reg, ONENAND_REG_SYS_CFG1);
> > +
> > +	return 0;
> > +}
> > +
> > +static int omap2_onenand_get_freq(int ver)
> > +{
> > +	switch ((ver >> 4) & 0xf) {
> > +	case 0:
> > +		return 40;
> > +	case 1:
> > +		return 54;
> > +	case 2:
> > +		return 66;
> > +	case 3:
> > +		return 83;
> > +	case 4:
> > +		return 104;
> > +	}
> > +
> > +	return -EINVAL;
> > +}
> > +
> >  static void wait_err(char *msg, int state, unsigned int ctrl, unsigned int intr)
> >  {
> >  	printk(KERN_ERR "onenand_wait: %s! state %d ctrl 0x%04x intr 0x%04x\n",
> > @@ -152,12 +209,12 @@ static int omap2_onenand_wait(struct mtd_info *mtd, int state)
> >  		}
> >  
> >  		reinit_completion(&c->irq_done);
> > -		result = gpio_get_value(c->gpio_irq);
> > +		result = gpiod_get_value(c->ready_gpiod);
> >  		if (result < 0) {
> >  			ctrl = read_reg(c, ONENAND_REG_CTRL_STATUS);
> >  			intr = read_reg(c, ONENAND_REG_INTERRUPT);
> >  			wait_err("gpio error", state, ctrl, intr);
> > -			return -EIO;
> > +			return result;
> >  		} else if (result == 0) {
> >  			int retry_cnt = 0;
> >  retry:
> > @@ -431,8 +488,6 @@ static int omap2_onenand_write_bufferram(struct mtd_info *mtd, int area,
> >  	return 0;
> >  }
> >  
> > -static struct platform_driver omap2_onenand_driver;
> > -
> >  static void omap2_onenand_shutdown(struct platform_device *pdev)
> >  {
> >  	struct omap2_onenand *c = dev_get_drvdata(&pdev->dev);
> > @@ -446,108 +501,124 @@ static void omap2_onenand_shutdown(struct platform_device *pdev)
> >  
> >  static int omap2_onenand_probe(struct platform_device *pdev)
> >  {
> > -	struct omap_onenand_platform_data *pdata;
> > -	struct omap2_onenand *c;
> > -	struct onenand_chip *this;
> > -	int r;
> > +	u32 val;
> > +	dma_cap_mask_t mask;
> > +	int freq, latency, r;
> > +	unsigned int mem_size;
> >  	struct resource *res;
> > +	struct omap2_onenand *c;
> > +	struct gpmc_onenand_info info;
> > +	struct device *dev = &pdev->dev;
> > +	struct device_node *np = dev->of_node;
> >  
> > -	pdata = dev_get_platdata(&pdev->dev);
> > -	if (pdata == NULL) {
> > -		dev_err(&pdev->dev, "platform data missing\n");
> > -		return -ENODEV;
> > +	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> > +	if (!res) {
> > +		dev_err(dev, "error getting memory resource\n");
> > +		return -EINVAL;
> >  	}
> >  
> > -	c = kzalloc(sizeof(struct omap2_onenand), GFP_KERNEL);
> 
> We should error out if np is NULL before beginning to read DT properties?

of_property_read_u32 will fail then, so I do not think it is worth adding
explicit test for NULL here.

> > +	r = of_property_read_u32(np, "reg", &val);
> > +	if (r) {
> > +		dev_err(dev, "reg not found in DT\n");
> > +		return r;
> > +	}
> > +
> > +	c = devm_kzalloc(dev, sizeof(struct omap2_onenand), GFP_KERNEL);
> >  	if (!c)
> >  		return -ENOMEM;
> >  
> >  	init_completion(&c->irq_done);
> >  	init_completion(&c->dma_done);
> > -	c->gpmc_cs = pdata->cs;
> > -	c->gpio_irq = pdata->gpio_irq;
> > -	if (pdata->dma_channel < 0) {
> > -		/* if -1, don't use DMA */
> > -		c->gpio_irq = 0;
> > -	}
> > +	c->gpmc_cs = val;
> > +	c->phys_base = res->start;
> 
> Above 2 lines could be moved to just after where val and res is found respectively.

Nope, we do not have 'c' allocated at that time.

> > -	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> > -	if (res == NULL) {
> > -		r = -EINVAL;
> > -		dev_err(&pdev->dev, "error getting memory resource\n");
> > -		goto err_kfree;
> > -	}
> > +	mem_size = resource_size(res);
> > +	if (!devm_request_mem_region(dev, c->phys_base, mem_size,
> > +				     dev->driver->name)) {
> >  
> > -	c->phys_base = res->start;
> > -	c->mem_size = resource_size(res);
> > -
> > -	if (request_mem_region(c->phys_base, c->mem_size,
> > -			       pdev->dev.driver->name) == NULL) {
> > -		dev_err(&pdev->dev, "Cannot reserve memory region at 0x%08lx, size: 0x%x\n",
> > -						c->phys_base, c->mem_size);
> > -		r = -EBUSY;
> > -		goto err_kfree;
> > -	}
> > -	c->onenand.base = ioremap(c->phys_base, c->mem_size);
> > -	if (c->onenand.base == NULL) {
> > -		r = -ENOMEM;
> > -		goto err_release_mem_region;
> > +		dev_err(dev, "Cannot reserve memory region at 0x%08lx, size: 0x%x\n",
> > +			c->phys_base, mem_size);
> > +		return -EBUSY;
> >  	}
> >  
> > -	if (pdata->onenand_setup != NULL) {
> > -		r = pdata->onenand_setup(c->onenand.base, &c->freq);
> > -		if (r < 0) {
> > -			dev_err(&pdev->dev, "Onenand platform setup failed: "
> > -				"%d\n", r);
> > -			goto err_iounmap;
> > -		}
> > -		c->setup = pdata->onenand_setup;
> > -	}
> > +	c->onenand.base = devm_ioremap(dev, c->phys_base, mem_size);
> > +	if (!c->onenand.base)
> > +		return -ENOMEM;
> 
> How about doing request and ioremap in one shot?
> 
> 	c->onenand.base = devm_ioremap_resource(&pdev->dev, res);
> 	if (IS_ERR(base))
> 		return PTR_ERR(base);

Good idea..

> >  
> > -	if (c->gpio_irq) {
> > -		if ((r = gpio_request(c->gpio_irq, "OneNAND irq")) < 0) {
> > -			dev_err(&pdev->dev,  "Failed to request GPIO%d for "
> > -				"OneNAND\n", c->gpio_irq);
> > -			goto err_iounmap;
> > -		}
> > -		gpio_direction_input(c->gpio_irq);
> > +	c->ready_gpiod = devm_gpiod_get_optional(dev, "rb", GPIOD_IN);
> 
> I'd keep the name "onenand int" if it is the INT pin.

Ok.

> > +	if (IS_ERR(c->ready_gpiod)) {
> > +		r = PTR_ERR(c->ready_gpiod);
> > +		/* Just try again if this happens */
> > +		if (r != -EPROBE_DEFER)
> > +			dev_err(dev, "error getting gpio: %d\n", r);
> > +		return r;
> > +	}
> >  
> > -		if ((r = request_irq(gpio_to_irq(c->gpio_irq),
> > -				     omap2_onenand_interrupt, IRQF_TRIGGER_RISING,
> > -				     pdev->dev.driver->name, c)) < 0)
> > -			goto err_release_gpio;
> > +	if (c->ready_gpiod) {
> > +		r = devm_request_irq(dev, gpiod_to_irq(c->ready_gpiod),
> > +				     omap2_onenand_interrupt,
> > +				     IRQF_TRIGGER_RISING, "OneNAND", c);
> 
> "onenand" to be consistent with onenand_base.c?

Ok.

> > +		if (r)
> > +			return r;
> >  
> > -		this->wait = omap2_onenand_wait;
> > +		c->onenand.wait = omap2_onenand_wait;
> >  	}
> >  
> > -	if (pdata->dma_channel >= 0) {
> > -		dma_cap_mask_t mask;
> > -
> > -		dma_cap_zero(mask);
> > -		dma_cap_set(DMA_MEMCPY, mask);
> > +	dma_cap_zero(mask);
> > +	dma_cap_set(DMA_MEMCPY, mask);
> >  
> > -		c->dma_chan = dma_request_channel(mask, NULL, NULL);
> > +	c->dma_chan = dma_request_channel(mask, NULL, NULL);
> > +	if (c->dma_chan) {
> > +		c->onenand.read_bufferram = omap2_onenand_read_bufferram;
> > +		c->onenand.write_bufferram = omap2_onenand_write_bufferram;
> >  	}
> >  
> > -	dev_info(&pdev->dev, "initializing on CS%d, phys base 0x%08lx, virtual "
> > -		 "base %p, freq %d MHz, %s mode\n", c->gpmc_cs, c->phys_base,
> > -		 c->onenand.base, c->freq, c->dma_chan ? "DMA" : "PIO");
> > -
> >  	c->pdev = pdev;
> >  	c->mtd.priv = &c->onenand;
> > +	c->mtd.dev.parent = dev;
> > +	mtd_set_of_node(&c->mtd, dev->of_node);
> >  
> > -	c->mtd.dev.parent = &pdev->dev;
> > -	mtd_set_of_node(&c->mtd, pdata->of_node);
> > -
> > -	this = &c->onenand;
> > -	if (c->dma_chan) {
> > -		this->read_bufferram = omap2_onenand_read_bufferram;
> > -		this->write_bufferram = omap2_onenand_write_bufferram;
> > -	}
> > +	dev_info(dev, "initializing on CS%d (0x%08lx), va %p, %s mode\n",
> > +		 c->gpmc_cs, c->phys_base, c->onenand.base,
> > +		 c->dma_chan ? "DMA" : "PIO");
> >  
> >  	if ((r = onenand_scan(&c->mtd, 1)) < 0)
> >  		goto err_release_dma;
> >  
> > +	freq = omap2_onenand_get_freq(c->onenand.version_id);
> > +	if (freq > 0) {
> > +		switch (freq) {
> > +		case 104:
> > +			latency = 7;
> > +			break;
> > +		case 83:
> > +			latency = 6;
> > +			break;
> > +		case 66:
> > +			latency = 5;
> > +			break;
> > +		case 56:
> > +			latency = 4;
> > +			break;
> > +		default:	/* 40 MHz or lower */
> > +			latency = 3;
> > +			break;
> > +		}
> > +
> > +		r = gpmc_omap_onenand_set_timings(dev, c->gpmc_cs,
> > +						  freq, latency, &info);
> > +		if (r)
> > +			goto err_release_onenand;
> > +
> > +		r = omap2_onenand_set_cfg(c, info.sync_read, info.sync_write,
> > +					  latency, info.burst_len);
> > +		if (r)
> > +			goto err_release_onenand;
> > +
> > +		if (info.sync_read || info.sync_write)
> > +			dev_info(dev, "optimized timings for %d MHz\n", freq);
> > +	}
> > +
> >  	r = mtd_device_register(&c->mtd, NULL, 0);
> >  	if (r)
> >  		goto err_release_onenand;
> > @@ -561,17 +632,6 @@ static int omap2_onenand_probe(struct platform_device *pdev)
> >  err_release_dma:
> >  	if (c->dma_chan)
> >  		dma_release_channel(c->dma_chan);
> > -	if (c->gpio_irq)
> > -		free_irq(gpio_to_irq(c->gpio_irq), c);
> > -err_release_gpio:
> > -	if (c->gpio_irq)
> > -		gpio_free(c->gpio_irq);
> > -err_iounmap:
> > -	iounmap(c->onenand.base);
> > -err_release_mem_region:
> > -	release_mem_region(c->phys_base, c->mem_size);
> > -err_kfree:
> > -	kfree(c);
> >  
> >  	return r;
> >  }
> > @@ -584,23 +644,23 @@ static int omap2_onenand_remove(struct platform_device *pdev)
> >  	if (c->dma_chan)
> >  		dma_release_channel(c->dma_chan);
> >  	omap2_onenand_shutdown(pdev);
> > -	if (c->gpio_irq) {
> > -		free_irq(gpio_to_irq(c->gpio_irq), c);
> > -		gpio_free(c->gpio_irq);
> > -	}
> > -	iounmap(c->onenand.base);
> > -	release_mem_region(c->phys_base, c->mem_size);
> > -	kfree(c);
> >  
> >  	return 0;
> >  }
> >  
> > +static const struct of_device_id omap2_onenand_id_table[] = {
> > +	{ .compatible = "ti,omap2-onenand", },
> > +	{},
> > +};
> > +MODULE_DEVICE_TABLE(of, omap2_onenand_id_table);
> > +
> >  static struct platform_driver omap2_onenand_driver = {
> >  	.probe		= omap2_onenand_probe,
> >  	.remove		= omap2_onenand_remove,
> >  	.shutdown	= omap2_onenand_shutdown,
> >  	.driver		= {
> >  		.name	= DRIVER_NAME,
> > +		.of_match_table = omap2_onenand_id_table,
> >  	},
> >  };
> >  
> > 
> 
> -- 
> cheers,
> -roger
> 
> Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki. Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki

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

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

* Re: [PATCH v4 14/16] mtd: onenand: omap2: Configure driver from DT
@ 2017-11-15 10:53       ` Ladislav Michl
  0 siblings, 0 replies; 114+ messages in thread
From: Ladislav Michl @ 2017-11-15 10:53 UTC (permalink / raw)
  To: Roger Quadros
  Cc: linux-mtd, linux-omap, Tony Lindgren, Peter Ujfalusi,
	Boris Brezillon, Kyungmin Park

On Wed, Nov 15, 2017 at 12:40:14PM +0200, Roger Quadros wrote:
> On 11/11/17 23:27, Ladislav Michl wrote:
> > Move away from platform data configuration and use pure DT approach.
> > 
> > Signed-off-by: Ladislav Michl <ladis@linux-mips.org>
> > ---
> >  Changes:
> >  -v2: move cleanups into separate patches
> >       simplify dma setup
> >       fix checkpatch error
> >       print info about otimized timings in sync mode only
> >  -v3: remove 'ti,omap3-onenand' compatible as it is not needed anymore
> >  -v4: none
> > 
> >  drivers/mtd/onenand/omap2.c | 264 +++++++++++++++++++++++++++-----------------
> >  1 file changed, 162 insertions(+), 102 deletions(-)
> > 
> > diff --git a/drivers/mtd/onenand/omap2.c b/drivers/mtd/onenand/omap2.c
> > index 62e4ede918c4..9ebbbf297993 100644
> > --- a/drivers/mtd/onenand/omap2.c
> > +++ b/drivers/mtd/onenand/omap2.c
> > @@ -28,6 +28,8 @@
> >  #include <linux/mtd/mtd.h>
> >  #include <linux/mtd/onenand.h>
> >  #include <linux/mtd/partitions.h>
> > +#include <linux/of_device.h>
> > +#include <linux/omap-gpmc.h>
> >  #include <linux/platform_device.h>
> >  #include <linux/interrupt.h>
> >  #include <linux/delay.h>
> > @@ -35,10 +37,9 @@
> >  #include <linux/dmaengine.h>
> >  #include <linux/io.h>
> >  #include <linux/slab.h>
> > -#include <linux/gpio.h>
> > +#include <linux/gpio/consumer.h>
> >  
> >  #include <asm/mach/flash.h>
> > -#include <linux/platform_data/mtd-onenand-omap2.h>
> >  
> >  #define DRIVER_NAME "omap2-onenand"
> >  
> > @@ -48,15 +49,12 @@ struct omap2_onenand {
> >  	struct platform_device *pdev;
> >  	int gpmc_cs;
> >  	unsigned long phys_base;
> > -	unsigned int mem_size;
> > -	int gpio_irq;
> > +	struct gpio_desc *ready_gpiod;
> 
> Is this the RDY pin or the INT pin?
> If it is the INT pin then I'd keep the name as int_gpiod.

It is INT pin, so I'll use int_gpiod. Also shall we use int-gpios
DT bindings then? Note, there can be two DPP devices in one die.

> >  	struct mtd_info mtd;
> >  	struct onenand_chip onenand;
> >  	struct completion irq_done;
> >  	struct completion dma_done;
> >  	struct dma_chan *dma_chan;
> > -	int freq;
> > -	int (*setup)(void __iomem *base, int *freq_ptr);
> >  };
> >  
> >  static void omap2_onenand_dma_complete_func(void *completion)
> > @@ -84,6 +82,65 @@ static inline void write_reg(struct omap2_onenand *c, unsigned short value,
> >  	writew(value, c->onenand.base + reg);
> >  }
> >  
> > +static int omap2_onenand_set_cfg(struct omap2_onenand *c,
> > +				 bool sr, bool sw,
> > +				 int latency, int burst_len)
> > +{
> > +	unsigned short reg = ONENAND_SYS_CFG1_RDY | ONENAND_SYS_CFG1_INT;
> > +
> > +	reg |= latency << ONENAND_SYS_CFG1_BRL_SHIFT;
> > +
> > +	switch (burst_len) {
> > +	case 0:		/* continuous */
> > +		break;
> > +	case 4:
> > +		reg |= ONENAND_SYS_CFG1_BL_4;
> > +		break;
> > +	case 8:
> > +		reg |= ONENAND_SYS_CFG1_BL_8;
> > +		break;
> > +	case 16:
> > +		reg |= ONENAND_SYS_CFG1_BL_16;
> > +		break;
> > +	case 32:
> > +		reg |= ONENAND_SYS_CFG1_BL_32;
> > +		break;
> > +	default:
> > +		return -EINVAL;
> > +	}
> > +
> > +	if (latency > 5)
> > +		reg |= ONENAND_SYS_CFG1_HF;
> > +	if (latency > 7)
> > +		reg |= ONENAND_SYS_CFG1_VHF;
> > +	if (sr)
> > +		reg |= ONENAND_SYS_CFG1_SYNC_READ;
> > +	if (sw)
> > +		reg |= ONENAND_SYS_CFG1_SYNC_WRITE;
> > +
> > +	write_reg(c, reg, ONENAND_REG_SYS_CFG1);
> > +
> > +	return 0;
> > +}
> > +
> > +static int omap2_onenand_get_freq(int ver)
> > +{
> > +	switch ((ver >> 4) & 0xf) {
> > +	case 0:
> > +		return 40;
> > +	case 1:
> > +		return 54;
> > +	case 2:
> > +		return 66;
> > +	case 3:
> > +		return 83;
> > +	case 4:
> > +		return 104;
> > +	}
> > +
> > +	return -EINVAL;
> > +}
> > +
> >  static void wait_err(char *msg, int state, unsigned int ctrl, unsigned int intr)
> >  {
> >  	printk(KERN_ERR "onenand_wait: %s! state %d ctrl 0x%04x intr 0x%04x\n",
> > @@ -152,12 +209,12 @@ static int omap2_onenand_wait(struct mtd_info *mtd, int state)
> >  		}
> >  
> >  		reinit_completion(&c->irq_done);
> > -		result = gpio_get_value(c->gpio_irq);
> > +		result = gpiod_get_value(c->ready_gpiod);
> >  		if (result < 0) {
> >  			ctrl = read_reg(c, ONENAND_REG_CTRL_STATUS);
> >  			intr = read_reg(c, ONENAND_REG_INTERRUPT);
> >  			wait_err("gpio error", state, ctrl, intr);
> > -			return -EIO;
> > +			return result;
> >  		} else if (result == 0) {
> >  			int retry_cnt = 0;
> >  retry:
> > @@ -431,8 +488,6 @@ static int omap2_onenand_write_bufferram(struct mtd_info *mtd, int area,
> >  	return 0;
> >  }
> >  
> > -static struct platform_driver omap2_onenand_driver;
> > -
> >  static void omap2_onenand_shutdown(struct platform_device *pdev)
> >  {
> >  	struct omap2_onenand *c = dev_get_drvdata(&pdev->dev);
> > @@ -446,108 +501,124 @@ static void omap2_onenand_shutdown(struct platform_device *pdev)
> >  
> >  static int omap2_onenand_probe(struct platform_device *pdev)
> >  {
> > -	struct omap_onenand_platform_data *pdata;
> > -	struct omap2_onenand *c;
> > -	struct onenand_chip *this;
> > -	int r;
> > +	u32 val;
> > +	dma_cap_mask_t mask;
> > +	int freq, latency, r;
> > +	unsigned int mem_size;
> >  	struct resource *res;
> > +	struct omap2_onenand *c;
> > +	struct gpmc_onenand_info info;
> > +	struct device *dev = &pdev->dev;
> > +	struct device_node *np = dev->of_node;
> >  
> > -	pdata = dev_get_platdata(&pdev->dev);
> > -	if (pdata == NULL) {
> > -		dev_err(&pdev->dev, "platform data missing\n");
> > -		return -ENODEV;
> > +	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> > +	if (!res) {
> > +		dev_err(dev, "error getting memory resource\n");
> > +		return -EINVAL;
> >  	}
> >  
> > -	c = kzalloc(sizeof(struct omap2_onenand), GFP_KERNEL);
> 
> We should error out if np is NULL before beginning to read DT properties?

of_property_read_u32 will fail then, so I do not think it is worth adding
explicit test for NULL here.

> > +	r = of_property_read_u32(np, "reg", &val);
> > +	if (r) {
> > +		dev_err(dev, "reg not found in DT\n");
> > +		return r;
> > +	}
> > +
> > +	c = devm_kzalloc(dev, sizeof(struct omap2_onenand), GFP_KERNEL);
> >  	if (!c)
> >  		return -ENOMEM;
> >  
> >  	init_completion(&c->irq_done);
> >  	init_completion(&c->dma_done);
> > -	c->gpmc_cs = pdata->cs;
> > -	c->gpio_irq = pdata->gpio_irq;
> > -	if (pdata->dma_channel < 0) {
> > -		/* if -1, don't use DMA */
> > -		c->gpio_irq = 0;
> > -	}
> > +	c->gpmc_cs = val;
> > +	c->phys_base = res->start;
> 
> Above 2 lines could be moved to just after where val and res is found respectively.

Nope, we do not have 'c' allocated at that time.

> > -	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> > -	if (res == NULL) {
> > -		r = -EINVAL;
> > -		dev_err(&pdev->dev, "error getting memory resource\n");
> > -		goto err_kfree;
> > -	}
> > +	mem_size = resource_size(res);
> > +	if (!devm_request_mem_region(dev, c->phys_base, mem_size,
> > +				     dev->driver->name)) {
> >  
> > -	c->phys_base = res->start;
> > -	c->mem_size = resource_size(res);
> > -
> > -	if (request_mem_region(c->phys_base, c->mem_size,
> > -			       pdev->dev.driver->name) == NULL) {
> > -		dev_err(&pdev->dev, "Cannot reserve memory region at 0x%08lx, size: 0x%x\n",
> > -						c->phys_base, c->mem_size);
> > -		r = -EBUSY;
> > -		goto err_kfree;
> > -	}
> > -	c->onenand.base = ioremap(c->phys_base, c->mem_size);
> > -	if (c->onenand.base == NULL) {
> > -		r = -ENOMEM;
> > -		goto err_release_mem_region;
> > +		dev_err(dev, "Cannot reserve memory region at 0x%08lx, size: 0x%x\n",
> > +			c->phys_base, mem_size);
> > +		return -EBUSY;
> >  	}
> >  
> > -	if (pdata->onenand_setup != NULL) {
> > -		r = pdata->onenand_setup(c->onenand.base, &c->freq);
> > -		if (r < 0) {
> > -			dev_err(&pdev->dev, "Onenand platform setup failed: "
> > -				"%d\n", r);
> > -			goto err_iounmap;
> > -		}
> > -		c->setup = pdata->onenand_setup;
> > -	}
> > +	c->onenand.base = devm_ioremap(dev, c->phys_base, mem_size);
> > +	if (!c->onenand.base)
> > +		return -ENOMEM;
> 
> How about doing request and ioremap in one shot?
> 
> 	c->onenand.base = devm_ioremap_resource(&pdev->dev, res);
> 	if (IS_ERR(base))
> 		return PTR_ERR(base);

Good idea..

> >  
> > -	if (c->gpio_irq) {
> > -		if ((r = gpio_request(c->gpio_irq, "OneNAND irq")) < 0) {
> > -			dev_err(&pdev->dev,  "Failed to request GPIO%d for "
> > -				"OneNAND\n", c->gpio_irq);
> > -			goto err_iounmap;
> > -		}
> > -		gpio_direction_input(c->gpio_irq);
> > +	c->ready_gpiod = devm_gpiod_get_optional(dev, "rb", GPIOD_IN);
> 
> I'd keep the name "onenand int" if it is the INT pin.

Ok.

> > +	if (IS_ERR(c->ready_gpiod)) {
> > +		r = PTR_ERR(c->ready_gpiod);
> > +		/* Just try again if this happens */
> > +		if (r != -EPROBE_DEFER)
> > +			dev_err(dev, "error getting gpio: %d\n", r);
> > +		return r;
> > +	}
> >  
> > -		if ((r = request_irq(gpio_to_irq(c->gpio_irq),
> > -				     omap2_onenand_interrupt, IRQF_TRIGGER_RISING,
> > -				     pdev->dev.driver->name, c)) < 0)
> > -			goto err_release_gpio;
> > +	if (c->ready_gpiod) {
> > +		r = devm_request_irq(dev, gpiod_to_irq(c->ready_gpiod),
> > +				     omap2_onenand_interrupt,
> > +				     IRQF_TRIGGER_RISING, "OneNAND", c);
> 
> "onenand" to be consistent with onenand_base.c?

Ok.

> > +		if (r)
> > +			return r;
> >  
> > -		this->wait = omap2_onenand_wait;
> > +		c->onenand.wait = omap2_onenand_wait;
> >  	}
> >  
> > -	if (pdata->dma_channel >= 0) {
> > -		dma_cap_mask_t mask;
> > -
> > -		dma_cap_zero(mask);
> > -		dma_cap_set(DMA_MEMCPY, mask);
> > +	dma_cap_zero(mask);
> > +	dma_cap_set(DMA_MEMCPY, mask);
> >  
> > -		c->dma_chan = dma_request_channel(mask, NULL, NULL);
> > +	c->dma_chan = dma_request_channel(mask, NULL, NULL);
> > +	if (c->dma_chan) {
> > +		c->onenand.read_bufferram = omap2_onenand_read_bufferram;
> > +		c->onenand.write_bufferram = omap2_onenand_write_bufferram;
> >  	}
> >  
> > -	dev_info(&pdev->dev, "initializing on CS%d, phys base 0x%08lx, virtual "
> > -		 "base %p, freq %d MHz, %s mode\n", c->gpmc_cs, c->phys_base,
> > -		 c->onenand.base, c->freq, c->dma_chan ? "DMA" : "PIO");
> > -
> >  	c->pdev = pdev;
> >  	c->mtd.priv = &c->onenand;
> > +	c->mtd.dev.parent = dev;
> > +	mtd_set_of_node(&c->mtd, dev->of_node);
> >  
> > -	c->mtd.dev.parent = &pdev->dev;
> > -	mtd_set_of_node(&c->mtd, pdata->of_node);
> > -
> > -	this = &c->onenand;
> > -	if (c->dma_chan) {
> > -		this->read_bufferram = omap2_onenand_read_bufferram;
> > -		this->write_bufferram = omap2_onenand_write_bufferram;
> > -	}
> > +	dev_info(dev, "initializing on CS%d (0x%08lx), va %p, %s mode\n",
> > +		 c->gpmc_cs, c->phys_base, c->onenand.base,
> > +		 c->dma_chan ? "DMA" : "PIO");
> >  
> >  	if ((r = onenand_scan(&c->mtd, 1)) < 0)
> >  		goto err_release_dma;
> >  
> > +	freq = omap2_onenand_get_freq(c->onenand.version_id);
> > +	if (freq > 0) {
> > +		switch (freq) {
> > +		case 104:
> > +			latency = 7;
> > +			break;
> > +		case 83:
> > +			latency = 6;
> > +			break;
> > +		case 66:
> > +			latency = 5;
> > +			break;
> > +		case 56:
> > +			latency = 4;
> > +			break;
> > +		default:	/* 40 MHz or lower */
> > +			latency = 3;
> > +			break;
> > +		}
> > +
> > +		r = gpmc_omap_onenand_set_timings(dev, c->gpmc_cs,
> > +						  freq, latency, &info);
> > +		if (r)
> > +			goto err_release_onenand;
> > +
> > +		r = omap2_onenand_set_cfg(c, info.sync_read, info.sync_write,
> > +					  latency, info.burst_len);
> > +		if (r)
> > +			goto err_release_onenand;
> > +
> > +		if (info.sync_read || info.sync_write)
> > +			dev_info(dev, "optimized timings for %d MHz\n", freq);
> > +	}
> > +
> >  	r = mtd_device_register(&c->mtd, NULL, 0);
> >  	if (r)
> >  		goto err_release_onenand;
> > @@ -561,17 +632,6 @@ static int omap2_onenand_probe(struct platform_device *pdev)
> >  err_release_dma:
> >  	if (c->dma_chan)
> >  		dma_release_channel(c->dma_chan);
> > -	if (c->gpio_irq)
> > -		free_irq(gpio_to_irq(c->gpio_irq), c);
> > -err_release_gpio:
> > -	if (c->gpio_irq)
> > -		gpio_free(c->gpio_irq);
> > -err_iounmap:
> > -	iounmap(c->onenand.base);
> > -err_release_mem_region:
> > -	release_mem_region(c->phys_base, c->mem_size);
> > -err_kfree:
> > -	kfree(c);
> >  
> >  	return r;
> >  }
> > @@ -584,23 +644,23 @@ static int omap2_onenand_remove(struct platform_device *pdev)
> >  	if (c->dma_chan)
> >  		dma_release_channel(c->dma_chan);
> >  	omap2_onenand_shutdown(pdev);
> > -	if (c->gpio_irq) {
> > -		free_irq(gpio_to_irq(c->gpio_irq), c);
> > -		gpio_free(c->gpio_irq);
> > -	}
> > -	iounmap(c->onenand.base);
> > -	release_mem_region(c->phys_base, c->mem_size);
> > -	kfree(c);
> >  
> >  	return 0;
> >  }
> >  
> > +static const struct of_device_id omap2_onenand_id_table[] = {
> > +	{ .compatible = "ti,omap2-onenand", },
> > +	{},
> > +};
> > +MODULE_DEVICE_TABLE(of, omap2_onenand_id_table);
> > +
> >  static struct platform_driver omap2_onenand_driver = {
> >  	.probe		= omap2_onenand_probe,
> >  	.remove		= omap2_onenand_remove,
> >  	.shutdown	= omap2_onenand_shutdown,
> >  	.driver		= {
> >  		.name	= DRIVER_NAME,
> > +		.of_match_table = omap2_onenand_id_table,
> >  	},
> >  };
> >  
> > 
> 
> -- 
> cheers,
> -roger
> 
> Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki. Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki

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

* Re: [PATCH v4 14/16] mtd: onenand: omap2: Configure driver from DT
  2017-11-15 10:53       ` Ladislav Michl
@ 2017-11-15 11:04         ` Roger Quadros
  -1 siblings, 0 replies; 114+ messages in thread
From: Roger Quadros @ 2017-11-15 11:04 UTC (permalink / raw)
  To: Ladislav Michl
  Cc: Boris Brezillon, Tony Lindgren, Peter Ujfalusi, Kyungmin Park,
	linux-mtd, linux-omap

On 15/11/17 12:53, Ladislav Michl wrote:
> On Wed, Nov 15, 2017 at 12:40:14PM +0200, Roger Quadros wrote:
>> On 11/11/17 23:27, Ladislav Michl wrote:
>>> Move away from platform data configuration and use pure DT approach.
>>>
>>> Signed-off-by: Ladislav Michl <ladis@linux-mips.org>
>>> ---
>>>  Changes:
>>>  -v2: move cleanups into separate patches
>>>       simplify dma setup
>>>       fix checkpatch error
>>>       print info about otimized timings in sync mode only
>>>  -v3: remove 'ti,omap3-onenand' compatible as it is not needed anymore
>>>  -v4: none
>>>
>>>  drivers/mtd/onenand/omap2.c | 264 +++++++++++++++++++++++++++-----------------
>>>  1 file changed, 162 insertions(+), 102 deletions(-)
>>>
>>> diff --git a/drivers/mtd/onenand/omap2.c b/drivers/mtd/onenand/omap2.c
>>> index 62e4ede918c4..9ebbbf297993 100644
>>> --- a/drivers/mtd/onenand/omap2.c
>>> +++ b/drivers/mtd/onenand/omap2.c
>>> @@ -28,6 +28,8 @@
>>>  #include <linux/mtd/mtd.h>
>>>  #include <linux/mtd/onenand.h>
>>>  #include <linux/mtd/partitions.h>
>>> +#include <linux/of_device.h>
>>> +#include <linux/omap-gpmc.h>
>>>  #include <linux/platform_device.h>
>>>  #include <linux/interrupt.h>
>>>  #include <linux/delay.h>
>>> @@ -35,10 +37,9 @@
>>>  #include <linux/dmaengine.h>
>>>  #include <linux/io.h>
>>>  #include <linux/slab.h>
>>> -#include <linux/gpio.h>
>>> +#include <linux/gpio/consumer.h>
>>>  
>>>  #include <asm/mach/flash.h>
>>> -#include <linux/platform_data/mtd-onenand-omap2.h>
>>>  
>>>  #define DRIVER_NAME "omap2-onenand"
>>>  
>>> @@ -48,15 +49,12 @@ struct omap2_onenand {
>>>  	struct platform_device *pdev;
>>>  	int gpmc_cs;
>>>  	unsigned long phys_base;
>>> -	unsigned int mem_size;
>>> -	int gpio_irq;
>>> +	struct gpio_desc *ready_gpiod;
>>
>> Is this the RDY pin or the INT pin?
>> If it is the INT pin then I'd keep the name as int_gpiod.
> 
> It is INT pin, so I'll use int_gpiod. Also shall we use int-gpios
> DT bindings then? Note, there can be two DPP devices in one die.

Yes int-gpios is better.
We'll leave the more than one devices case to be implemented whenever
someone has a real device.

> 
>>>  	struct mtd_info mtd;
>>>  	struct onenand_chip onenand;
>>>  	struct completion irq_done;
>>>  	struct completion dma_done;
>>>  	struct dma_chan *dma_chan;
>>> -	int freq;
>>> -	int (*setup)(void __iomem *base, int *freq_ptr);
>>>  };
>>>  
>>>  static void omap2_onenand_dma_complete_func(void *completion)
>>> @@ -84,6 +82,65 @@ static inline void write_reg(struct omap2_onenand *c, unsigned short value,
>>>  	writew(value, c->onenand.base + reg);
>>>  }
>>>  
>>> +static int omap2_onenand_set_cfg(struct omap2_onenand *c,
>>> +				 bool sr, bool sw,
>>> +				 int latency, int burst_len)
>>> +{
>>> +	unsigned short reg = ONENAND_SYS_CFG1_RDY | ONENAND_SYS_CFG1_INT;
>>> +
>>> +	reg |= latency << ONENAND_SYS_CFG1_BRL_SHIFT;
>>> +
>>> +	switch (burst_len) {
>>> +	case 0:		/* continuous */
>>> +		break;
>>> +	case 4:
>>> +		reg |= ONENAND_SYS_CFG1_BL_4;
>>> +		break;
>>> +	case 8:
>>> +		reg |= ONENAND_SYS_CFG1_BL_8;
>>> +		break;
>>> +	case 16:
>>> +		reg |= ONENAND_SYS_CFG1_BL_16;
>>> +		break;
>>> +	case 32:
>>> +		reg |= ONENAND_SYS_CFG1_BL_32;
>>> +		break;
>>> +	default:
>>> +		return -EINVAL;
>>> +	}
>>> +
>>> +	if (latency > 5)
>>> +		reg |= ONENAND_SYS_CFG1_HF;
>>> +	if (latency > 7)
>>> +		reg |= ONENAND_SYS_CFG1_VHF;
>>> +	if (sr)
>>> +		reg |= ONENAND_SYS_CFG1_SYNC_READ;
>>> +	if (sw)
>>> +		reg |= ONENAND_SYS_CFG1_SYNC_WRITE;
>>> +
>>> +	write_reg(c, reg, ONENAND_REG_SYS_CFG1);
>>> +
>>> +	return 0;
>>> +}
>>> +
>>> +static int omap2_onenand_get_freq(int ver)
>>> +{
>>> +	switch ((ver >> 4) & 0xf) {
>>> +	case 0:
>>> +		return 40;
>>> +	case 1:
>>> +		return 54;
>>> +	case 2:
>>> +		return 66;
>>> +	case 3:
>>> +		return 83;
>>> +	case 4:
>>> +		return 104;
>>> +	}
>>> +
>>> +	return -EINVAL;
>>> +}
>>> +
>>>  static void wait_err(char *msg, int state, unsigned int ctrl, unsigned int intr)
>>>  {
>>>  	printk(KERN_ERR "onenand_wait: %s! state %d ctrl 0x%04x intr 0x%04x\n",
>>> @@ -152,12 +209,12 @@ static int omap2_onenand_wait(struct mtd_info *mtd, int state)
>>>  		}
>>>  
>>>  		reinit_completion(&c->irq_done);
>>> -		result = gpio_get_value(c->gpio_irq);
>>> +		result = gpiod_get_value(c->ready_gpiod);
>>>  		if (result < 0) {
>>>  			ctrl = read_reg(c, ONENAND_REG_CTRL_STATUS);
>>>  			intr = read_reg(c, ONENAND_REG_INTERRUPT);
>>>  			wait_err("gpio error", state, ctrl, intr);
>>> -			return -EIO;
>>> +			return result;
>>>  		} else if (result == 0) {
>>>  			int retry_cnt = 0;
>>>  retry:
>>> @@ -431,8 +488,6 @@ static int omap2_onenand_write_bufferram(struct mtd_info *mtd, int area,
>>>  	return 0;
>>>  }
>>>  
>>> -static struct platform_driver omap2_onenand_driver;
>>> -
>>>  static void omap2_onenand_shutdown(struct platform_device *pdev)
>>>  {
>>>  	struct omap2_onenand *c = dev_get_drvdata(&pdev->dev);
>>> @@ -446,108 +501,124 @@ static void omap2_onenand_shutdown(struct platform_device *pdev)
>>>  
>>>  static int omap2_onenand_probe(struct platform_device *pdev)
>>>  {
>>> -	struct omap_onenand_platform_data *pdata;
>>> -	struct omap2_onenand *c;
>>> -	struct onenand_chip *this;
>>> -	int r;
>>> +	u32 val;
>>> +	dma_cap_mask_t mask;
>>> +	int freq, latency, r;
>>> +	unsigned int mem_size;
>>>  	struct resource *res;
>>> +	struct omap2_onenand *c;
>>> +	struct gpmc_onenand_info info;
>>> +	struct device *dev = &pdev->dev;
>>> +	struct device_node *np = dev->of_node;
>>>  
>>> -	pdata = dev_get_platdata(&pdev->dev);
>>> -	if (pdata == NULL) {
>>> -		dev_err(&pdev->dev, "platform data missing\n");
>>> -		return -ENODEV;
>>> +	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
>>> +	if (!res) {
>>> +		dev_err(dev, "error getting memory resource\n");
>>> +		return -EINVAL;
>>>  	}
>>>  
>>> -	c = kzalloc(sizeof(struct omap2_onenand), GFP_KERNEL);
>>
>> We should error out if np is NULL before beginning to read DT properties?
> 
> of_property_read_u32 will fail then, so I do not think it is worth adding
> explicit test for NULL here.
> 

But the error message would be wrong in that case.
I'm trying to tackle the case where driver was probed using legacy methods
where device tree/node isn't present.

>>> +	r = of_property_read_u32(np, "reg", &val);
>>> +	if (r) {
>>> +		dev_err(dev, "reg not found in DT\n");
>>> +		return r;
>>> +	}
>>> +
>>> +	c = devm_kzalloc(dev, sizeof(struct omap2_onenand), GFP_KERNEL);
>>>  	if (!c)
>>>  		return -ENOMEM;
>>>  
>>>  	init_completion(&c->irq_done);
>>>  	init_completion(&c->dma_done);
>>> -	c->gpmc_cs = pdata->cs;
>>> -	c->gpio_irq = pdata->gpio_irq;
>>> -	if (pdata->dma_channel < 0) {
>>> -		/* if -1, don't use DMA */
>>> -		c->gpio_irq = 0;
>>> -	}
>>> +	c->gpmc_cs = val;
>>> +	c->phys_base = res->start;
>>
>> Above 2 lines could be moved to just after where val and res is found respectively.
> 
> Nope, we do not have 'c' allocated at that time.
> 
indeed. silly me :)

>>> -	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);

<snip>

-- 
cheers,
-roger

Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki. Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki

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

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

* Re: [PATCH v4 14/16] mtd: onenand: omap2: Configure driver from DT
@ 2017-11-15 11:04         ` Roger Quadros
  0 siblings, 0 replies; 114+ messages in thread
From: Roger Quadros @ 2017-11-15 11:04 UTC (permalink / raw)
  To: Ladislav Michl
  Cc: linux-mtd, linux-omap, Tony Lindgren, Peter Ujfalusi,
	Boris Brezillon, Kyungmin Park

On 15/11/17 12:53, Ladislav Michl wrote:
> On Wed, Nov 15, 2017 at 12:40:14PM +0200, Roger Quadros wrote:
>> On 11/11/17 23:27, Ladislav Michl wrote:
>>> Move away from platform data configuration and use pure DT approach.
>>>
>>> Signed-off-by: Ladislav Michl <ladis@linux-mips.org>
>>> ---
>>>  Changes:
>>>  -v2: move cleanups into separate patches
>>>       simplify dma setup
>>>       fix checkpatch error
>>>       print info about otimized timings in sync mode only
>>>  -v3: remove 'ti,omap3-onenand' compatible as it is not needed anymore
>>>  -v4: none
>>>
>>>  drivers/mtd/onenand/omap2.c | 264 +++++++++++++++++++++++++++-----------------
>>>  1 file changed, 162 insertions(+), 102 deletions(-)
>>>
>>> diff --git a/drivers/mtd/onenand/omap2.c b/drivers/mtd/onenand/omap2.c
>>> index 62e4ede918c4..9ebbbf297993 100644
>>> --- a/drivers/mtd/onenand/omap2.c
>>> +++ b/drivers/mtd/onenand/omap2.c
>>> @@ -28,6 +28,8 @@
>>>  #include <linux/mtd/mtd.h>
>>>  #include <linux/mtd/onenand.h>
>>>  #include <linux/mtd/partitions.h>
>>> +#include <linux/of_device.h>
>>> +#include <linux/omap-gpmc.h>
>>>  #include <linux/platform_device.h>
>>>  #include <linux/interrupt.h>
>>>  #include <linux/delay.h>
>>> @@ -35,10 +37,9 @@
>>>  #include <linux/dmaengine.h>
>>>  #include <linux/io.h>
>>>  #include <linux/slab.h>
>>> -#include <linux/gpio.h>
>>> +#include <linux/gpio/consumer.h>
>>>  
>>>  #include <asm/mach/flash.h>
>>> -#include <linux/platform_data/mtd-onenand-omap2.h>
>>>  
>>>  #define DRIVER_NAME "omap2-onenand"
>>>  
>>> @@ -48,15 +49,12 @@ struct omap2_onenand {
>>>  	struct platform_device *pdev;
>>>  	int gpmc_cs;
>>>  	unsigned long phys_base;
>>> -	unsigned int mem_size;
>>> -	int gpio_irq;
>>> +	struct gpio_desc *ready_gpiod;
>>
>> Is this the RDY pin or the INT pin?
>> If it is the INT pin then I'd keep the name as int_gpiod.
> 
> It is INT pin, so I'll use int_gpiod. Also shall we use int-gpios
> DT bindings then? Note, there can be two DPP devices in one die.

Yes int-gpios is better.
We'll leave the more than one devices case to be implemented whenever
someone has a real device.

> 
>>>  	struct mtd_info mtd;
>>>  	struct onenand_chip onenand;
>>>  	struct completion irq_done;
>>>  	struct completion dma_done;
>>>  	struct dma_chan *dma_chan;
>>> -	int freq;
>>> -	int (*setup)(void __iomem *base, int *freq_ptr);
>>>  };
>>>  
>>>  static void omap2_onenand_dma_complete_func(void *completion)
>>> @@ -84,6 +82,65 @@ static inline void write_reg(struct omap2_onenand *c, unsigned short value,
>>>  	writew(value, c->onenand.base + reg);
>>>  }
>>>  
>>> +static int omap2_onenand_set_cfg(struct omap2_onenand *c,
>>> +				 bool sr, bool sw,
>>> +				 int latency, int burst_len)
>>> +{
>>> +	unsigned short reg = ONENAND_SYS_CFG1_RDY | ONENAND_SYS_CFG1_INT;
>>> +
>>> +	reg |= latency << ONENAND_SYS_CFG1_BRL_SHIFT;
>>> +
>>> +	switch (burst_len) {
>>> +	case 0:		/* continuous */
>>> +		break;
>>> +	case 4:
>>> +		reg |= ONENAND_SYS_CFG1_BL_4;
>>> +		break;
>>> +	case 8:
>>> +		reg |= ONENAND_SYS_CFG1_BL_8;
>>> +		break;
>>> +	case 16:
>>> +		reg |= ONENAND_SYS_CFG1_BL_16;
>>> +		break;
>>> +	case 32:
>>> +		reg |= ONENAND_SYS_CFG1_BL_32;
>>> +		break;
>>> +	default:
>>> +		return -EINVAL;
>>> +	}
>>> +
>>> +	if (latency > 5)
>>> +		reg |= ONENAND_SYS_CFG1_HF;
>>> +	if (latency > 7)
>>> +		reg |= ONENAND_SYS_CFG1_VHF;
>>> +	if (sr)
>>> +		reg |= ONENAND_SYS_CFG1_SYNC_READ;
>>> +	if (sw)
>>> +		reg |= ONENAND_SYS_CFG1_SYNC_WRITE;
>>> +
>>> +	write_reg(c, reg, ONENAND_REG_SYS_CFG1);
>>> +
>>> +	return 0;
>>> +}
>>> +
>>> +static int omap2_onenand_get_freq(int ver)
>>> +{
>>> +	switch ((ver >> 4) & 0xf) {
>>> +	case 0:
>>> +		return 40;
>>> +	case 1:
>>> +		return 54;
>>> +	case 2:
>>> +		return 66;
>>> +	case 3:
>>> +		return 83;
>>> +	case 4:
>>> +		return 104;
>>> +	}
>>> +
>>> +	return -EINVAL;
>>> +}
>>> +
>>>  static void wait_err(char *msg, int state, unsigned int ctrl, unsigned int intr)
>>>  {
>>>  	printk(KERN_ERR "onenand_wait: %s! state %d ctrl 0x%04x intr 0x%04x\n",
>>> @@ -152,12 +209,12 @@ static int omap2_onenand_wait(struct mtd_info *mtd, int state)
>>>  		}
>>>  
>>>  		reinit_completion(&c->irq_done);
>>> -		result = gpio_get_value(c->gpio_irq);
>>> +		result = gpiod_get_value(c->ready_gpiod);
>>>  		if (result < 0) {
>>>  			ctrl = read_reg(c, ONENAND_REG_CTRL_STATUS);
>>>  			intr = read_reg(c, ONENAND_REG_INTERRUPT);
>>>  			wait_err("gpio error", state, ctrl, intr);
>>> -			return -EIO;
>>> +			return result;
>>>  		} else if (result == 0) {
>>>  			int retry_cnt = 0;
>>>  retry:
>>> @@ -431,8 +488,6 @@ static int omap2_onenand_write_bufferram(struct mtd_info *mtd, int area,
>>>  	return 0;
>>>  }
>>>  
>>> -static struct platform_driver omap2_onenand_driver;
>>> -
>>>  static void omap2_onenand_shutdown(struct platform_device *pdev)
>>>  {
>>>  	struct omap2_onenand *c = dev_get_drvdata(&pdev->dev);
>>> @@ -446,108 +501,124 @@ static void omap2_onenand_shutdown(struct platform_device *pdev)
>>>  
>>>  static int omap2_onenand_probe(struct platform_device *pdev)
>>>  {
>>> -	struct omap_onenand_platform_data *pdata;
>>> -	struct omap2_onenand *c;
>>> -	struct onenand_chip *this;
>>> -	int r;
>>> +	u32 val;
>>> +	dma_cap_mask_t mask;
>>> +	int freq, latency, r;
>>> +	unsigned int mem_size;
>>>  	struct resource *res;
>>> +	struct omap2_onenand *c;
>>> +	struct gpmc_onenand_info info;
>>> +	struct device *dev = &pdev->dev;
>>> +	struct device_node *np = dev->of_node;
>>>  
>>> -	pdata = dev_get_platdata(&pdev->dev);
>>> -	if (pdata == NULL) {
>>> -		dev_err(&pdev->dev, "platform data missing\n");
>>> -		return -ENODEV;
>>> +	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
>>> +	if (!res) {
>>> +		dev_err(dev, "error getting memory resource\n");
>>> +		return -EINVAL;
>>>  	}
>>>  
>>> -	c = kzalloc(sizeof(struct omap2_onenand), GFP_KERNEL);
>>
>> We should error out if np is NULL before beginning to read DT properties?
> 
> of_property_read_u32 will fail then, so I do not think it is worth adding
> explicit test for NULL here.
> 

But the error message would be wrong in that case.
I'm trying to tackle the case where driver was probed using legacy methods
where device tree/node isn't present.

>>> +	r = of_property_read_u32(np, "reg", &val);
>>> +	if (r) {
>>> +		dev_err(dev, "reg not found in DT\n");
>>> +		return r;
>>> +	}
>>> +
>>> +	c = devm_kzalloc(dev, sizeof(struct omap2_onenand), GFP_KERNEL);
>>>  	if (!c)
>>>  		return -ENOMEM;
>>>  
>>>  	init_completion(&c->irq_done);
>>>  	init_completion(&c->dma_done);
>>> -	c->gpmc_cs = pdata->cs;
>>> -	c->gpio_irq = pdata->gpio_irq;
>>> -	if (pdata->dma_channel < 0) {
>>> -		/* if -1, don't use DMA */
>>> -		c->gpio_irq = 0;
>>> -	}
>>> +	c->gpmc_cs = val;
>>> +	c->phys_base = res->start;
>>
>> Above 2 lines could be moved to just after where val and res is found respectively.
> 
> Nope, we do not have 'c' allocated at that time.
> 
indeed. silly me :)

>>> -	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);

<snip>

-- 
cheers,
-roger

Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki. Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki

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

* Re: [PATCH v4 14/16] mtd: onenand: omap2: Configure driver from DT
  2017-11-15 11:04         ` Roger Quadros
@ 2017-11-15 11:20           ` Ladislav Michl
  -1 siblings, 0 replies; 114+ messages in thread
From: Ladislav Michl @ 2017-11-15 11:20 UTC (permalink / raw)
  To: Roger Quadros
  Cc: Boris Brezillon, Tony Lindgren, Peter Ujfalusi, Kyungmin Park,
	linux-mtd, linux-omap

On Wed, Nov 15, 2017 at 01:04:22PM +0200, Roger Quadros wrote:
> On 15/11/17 12:53, Ladislav Michl wrote:
[snip]
> > of_property_read_u32 will fail then, so I do not think it is worth adding
> > explicit test for NULL here.
> > 
> 
> But the error message would be wrong in that case.
> I'm trying to tackle the case where driver was probed using legacy methods
> where device tree/node isn't present.

But how could we ever get there in that case? platform_device_register is
removed just one patch later.

Of course we should add:
depends on (OF && GPIOLIB) || COMPILE_TEST
to the Kconfig

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

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

* Re: [PATCH v4 14/16] mtd: onenand: omap2: Configure driver from DT
@ 2017-11-15 11:20           ` Ladislav Michl
  0 siblings, 0 replies; 114+ messages in thread
From: Ladislav Michl @ 2017-11-15 11:20 UTC (permalink / raw)
  To: Roger Quadros
  Cc: linux-mtd, linux-omap, Tony Lindgren, Peter Ujfalusi,
	Boris Brezillon, Kyungmin Park

On Wed, Nov 15, 2017 at 01:04:22PM +0200, Roger Quadros wrote:
> On 15/11/17 12:53, Ladislav Michl wrote:
[snip]
> > of_property_read_u32 will fail then, so I do not think it is worth adding
> > explicit test for NULL here.
> > 
> 
> But the error message would be wrong in that case.
> I'm trying to tackle the case where driver was probed using legacy methods
> where device tree/node isn't present.

But how could we ever get there in that case? platform_device_register is
removed just one patch later.

Of course we should add:
depends on (OF && GPIOLIB) || COMPILE_TEST
to the Kconfig

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

* Re: [PATCH v4 04/16] mtd: onenand: omap2: Remove regulator support
  2017-11-11 21:19   ` Ladislav Michl
@ 2017-11-15 14:15     ` Sebastian Reichel
  -1 siblings, 0 replies; 114+ messages in thread
From: Sebastian Reichel @ 2017-11-15 14:15 UTC (permalink / raw)
  To: Ladislav Michl
  Cc: Boris Brezillon, Tony Lindgren, Peter Ujfalusi, Kyungmin Park,
	linux-mtd, linux-omap, Roger Quadros


[-- Attachment #1.1: Type: text/plain, Size: 3684 bytes --]

Hi,

On Sat, Nov 11, 2017 at 10:19:08PM +0100, Ladislav Michl wrote:
> As no platform data user sets regulator_can_sleep, regulator code is
> no-op and can be deleted.
> 
> Signed-off-by: Ladislav Michl <ladis@linux-mips.org>
> ---

Reviewed-by: Sebastian Reichel <sebastian.reichel@collabora.co.uk>

-- Sebastian

>  Changes:
>  -v2: new patch
>  -v3: none
>  -v4: none
> 
>  drivers/mtd/onenand/omap2.c | 42 +-----------------------------------------
>  1 file changed, 1 insertion(+), 41 deletions(-)
> 
> diff --git a/drivers/mtd/onenand/omap2.c b/drivers/mtd/onenand/omap2.c
> index 24a1388d3031..a03e1fe4aa48 100644
> --- a/drivers/mtd/onenand/omap2.c
> +++ b/drivers/mtd/onenand/omap2.c
> @@ -34,7 +34,6 @@
>  #include <linux/dma-mapping.h>
>  #include <linux/io.h>
>  #include <linux/slab.h>
> -#include <linux/regulator/consumer.h>
>  #include <linux/gpio.h>
>  
>  #include <asm/mach/flash.h>
> @@ -59,7 +58,6 @@ struct omap2_onenand {
>  	int dma_channel;
>  	int freq;
>  	int (*setup)(void __iomem *base, int *freq_ptr);
> -	struct regulator *regulator;
>  	u8 flags;
>  };
>  
> @@ -583,30 +581,6 @@ static void omap2_onenand_shutdown(struct platform_device *pdev)
>  	memset((__force void *)c->onenand.base, 0, ONENAND_BUFRAM_SIZE);
>  }
>  
> -static int omap2_onenand_enable(struct mtd_info *mtd)
> -{
> -	int ret;
> -	struct omap2_onenand *c = container_of(mtd, struct omap2_onenand, mtd);
> -
> -	ret = regulator_enable(c->regulator);
> -	if (ret != 0)
> -		dev_err(&c->pdev->dev, "can't enable regulator\n");
> -
> -	return ret;
> -}
> -
> -static int omap2_onenand_disable(struct mtd_info *mtd)
> -{
> -	int ret;
> -	struct omap2_onenand *c = container_of(mtd, struct omap2_onenand, mtd);
> -
> -	ret = regulator_disable(c->regulator);
> -	if (ret != 0)
> -		dev_err(&c->pdev->dev, "can't disable regulator\n");
> -
> -	return ret;
> -}
> -
>  static int omap2_onenand_probe(struct platform_device *pdev)
>  {
>  	struct omap_onenand_platform_data *pdata;
> @@ -726,22 +700,11 @@ static int omap2_onenand_probe(struct platform_device *pdev)
>  		}
>  	}
>  
> -	if (pdata->regulator_can_sleep) {
> -		c->regulator = regulator_get(&pdev->dev, "vonenand");
> -		if (IS_ERR(c->regulator)) {
> -			dev_err(&pdev->dev,  "Failed to get regulator\n");
> -			r = PTR_ERR(c->regulator);
> -			goto err_release_dma;
> -		}
> -		c->onenand.enable = omap2_onenand_enable;
> -		c->onenand.disable = omap2_onenand_disable;
> -	}
> -
>  	if (pdata->skip_initial_unlocking)
>  		this->options |= ONENAND_SKIP_INITIAL_UNLOCKING;
>  
>  	if ((r = onenand_scan(&c->mtd, 1)) < 0)
> -		goto err_release_regulator;
> +		goto err_release_dma;
>  
>  	r = mtd_device_register(&c->mtd, pdata ? pdata->parts : NULL,
>  				pdata ? pdata->nr_parts : 0);
> @@ -754,8 +717,6 @@ static int omap2_onenand_probe(struct platform_device *pdev)
>  
>  err_release_onenand:
>  	onenand_release(&c->mtd);
> -err_release_regulator:
> -	regulator_put(c->regulator);
>  err_release_dma:
>  	if (c->dma_channel != -1)
>  		omap_free_dma(c->dma_channel);
> @@ -779,7 +740,6 @@ static int omap2_onenand_remove(struct platform_device *pdev)
>  	struct omap2_onenand *c = dev_get_drvdata(&pdev->dev);
>  
>  	onenand_release(&c->mtd);
> -	regulator_put(c->regulator);
>  	if (c->dma_channel != -1)
>  		omap_free_dma(c->dma_channel);
>  	omap2_onenand_shutdown(pdev);
> -- 
> 2.11.0
> 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-omap" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

[-- Attachment #1.2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

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

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

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

* Re: [PATCH v4 04/16] mtd: onenand: omap2: Remove regulator support
@ 2017-11-15 14:15     ` Sebastian Reichel
  0 siblings, 0 replies; 114+ messages in thread
From: Sebastian Reichel @ 2017-11-15 14:15 UTC (permalink / raw)
  To: Ladislav Michl
  Cc: linux-mtd, linux-omap, Roger Quadros, Tony Lindgren,
	Peter Ujfalusi, Boris Brezillon, Kyungmin Park

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

Hi,

On Sat, Nov 11, 2017 at 10:19:08PM +0100, Ladislav Michl wrote:
> As no platform data user sets regulator_can_sleep, regulator code is
> no-op and can be deleted.
> 
> Signed-off-by: Ladislav Michl <ladis@linux-mips.org>
> ---

Reviewed-by: Sebastian Reichel <sebastian.reichel@collabora.co.uk>

-- Sebastian

>  Changes:
>  -v2: new patch
>  -v3: none
>  -v4: none
> 
>  drivers/mtd/onenand/omap2.c | 42 +-----------------------------------------
>  1 file changed, 1 insertion(+), 41 deletions(-)
> 
> diff --git a/drivers/mtd/onenand/omap2.c b/drivers/mtd/onenand/omap2.c
> index 24a1388d3031..a03e1fe4aa48 100644
> --- a/drivers/mtd/onenand/omap2.c
> +++ b/drivers/mtd/onenand/omap2.c
> @@ -34,7 +34,6 @@
>  #include <linux/dma-mapping.h>
>  #include <linux/io.h>
>  #include <linux/slab.h>
> -#include <linux/regulator/consumer.h>
>  #include <linux/gpio.h>
>  
>  #include <asm/mach/flash.h>
> @@ -59,7 +58,6 @@ struct omap2_onenand {
>  	int dma_channel;
>  	int freq;
>  	int (*setup)(void __iomem *base, int *freq_ptr);
> -	struct regulator *regulator;
>  	u8 flags;
>  };
>  
> @@ -583,30 +581,6 @@ static void omap2_onenand_shutdown(struct platform_device *pdev)
>  	memset((__force void *)c->onenand.base, 0, ONENAND_BUFRAM_SIZE);
>  }
>  
> -static int omap2_onenand_enable(struct mtd_info *mtd)
> -{
> -	int ret;
> -	struct omap2_onenand *c = container_of(mtd, struct omap2_onenand, mtd);
> -
> -	ret = regulator_enable(c->regulator);
> -	if (ret != 0)
> -		dev_err(&c->pdev->dev, "can't enable regulator\n");
> -
> -	return ret;
> -}
> -
> -static int omap2_onenand_disable(struct mtd_info *mtd)
> -{
> -	int ret;
> -	struct omap2_onenand *c = container_of(mtd, struct omap2_onenand, mtd);
> -
> -	ret = regulator_disable(c->regulator);
> -	if (ret != 0)
> -		dev_err(&c->pdev->dev, "can't disable regulator\n");
> -
> -	return ret;
> -}
> -
>  static int omap2_onenand_probe(struct platform_device *pdev)
>  {
>  	struct omap_onenand_platform_data *pdata;
> @@ -726,22 +700,11 @@ static int omap2_onenand_probe(struct platform_device *pdev)
>  		}
>  	}
>  
> -	if (pdata->regulator_can_sleep) {
> -		c->regulator = regulator_get(&pdev->dev, "vonenand");
> -		if (IS_ERR(c->regulator)) {
> -			dev_err(&pdev->dev,  "Failed to get regulator\n");
> -			r = PTR_ERR(c->regulator);
> -			goto err_release_dma;
> -		}
> -		c->onenand.enable = omap2_onenand_enable;
> -		c->onenand.disable = omap2_onenand_disable;
> -	}
> -
>  	if (pdata->skip_initial_unlocking)
>  		this->options |= ONENAND_SKIP_INITIAL_UNLOCKING;
>  
>  	if ((r = onenand_scan(&c->mtd, 1)) < 0)
> -		goto err_release_regulator;
> +		goto err_release_dma;
>  
>  	r = mtd_device_register(&c->mtd, pdata ? pdata->parts : NULL,
>  				pdata ? pdata->nr_parts : 0);
> @@ -754,8 +717,6 @@ static int omap2_onenand_probe(struct platform_device *pdev)
>  
>  err_release_onenand:
>  	onenand_release(&c->mtd);
> -err_release_regulator:
> -	regulator_put(c->regulator);
>  err_release_dma:
>  	if (c->dma_channel != -1)
>  		omap_free_dma(c->dma_channel);
> @@ -779,7 +740,6 @@ static int omap2_onenand_remove(struct platform_device *pdev)
>  	struct omap2_onenand *c = dev_get_drvdata(&pdev->dev);
>  
>  	onenand_release(&c->mtd);
> -	regulator_put(c->regulator);
>  	if (c->dma_channel != -1)
>  		omap_free_dma(c->dma_channel);
>  	omap2_onenand_shutdown(pdev);
> -- 
> 2.11.0
> 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-omap" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

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

* Re: [PATCH v4 05/16] mtd: onenand: omap2: Remove skip initial unlocking support
  2017-11-11 21:19   ` Ladislav Michl
@ 2017-11-15 14:16     ` Sebastian Reichel
  -1 siblings, 0 replies; 114+ messages in thread
From: Sebastian Reichel @ 2017-11-15 14:16 UTC (permalink / raw)
  To: Ladislav Michl
  Cc: Boris Brezillon, Tony Lindgren, Peter Ujfalusi, Kyungmin Park,
	linux-mtd, linux-omap, Roger Quadros


[-- Attachment #1.1: Type: text/plain, Size: 1158 bytes --]

Hi,

On Sat, Nov 11, 2017 at 10:19:42PM +0100, Ladislav Michl wrote:
> No platform data user sets skip_initial_unlocking, so remove test
> for this field.
> 
> Signed-off-by: Ladislav Michl <ladis@linux-mips.org>
> ---

Reviewed-by: Sebastian Reichel <sebastian.reichel@collabora.co.uk>

-- Sebastian

>  Changes:
>  -v2: new patch
>  -v3: none
>  -v4: none
> 
>  drivers/mtd/onenand/omap2.c | 3 ---
>  1 file changed, 3 deletions(-)
> 
> diff --git a/drivers/mtd/onenand/omap2.c b/drivers/mtd/onenand/omap2.c
> index a03e1fe4aa48..93bd94337b35 100644
> --- a/drivers/mtd/onenand/omap2.c
> +++ b/drivers/mtd/onenand/omap2.c
> @@ -700,9 +700,6 @@ static int omap2_onenand_probe(struct platform_device *pdev)
>  		}
>  	}
>  
> -	if (pdata->skip_initial_unlocking)
> -		this->options |= ONENAND_SKIP_INITIAL_UNLOCKING;
> -
>  	if ((r = onenand_scan(&c->mtd, 1)) < 0)
>  		goto err_release_dma;
>  
> -- 
> 2.11.0
> 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-omap" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

[-- Attachment #1.2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

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

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

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

* Re: [PATCH v4 05/16] mtd: onenand: omap2: Remove skip initial unlocking support
@ 2017-11-15 14:16     ` Sebastian Reichel
  0 siblings, 0 replies; 114+ messages in thread
From: Sebastian Reichel @ 2017-11-15 14:16 UTC (permalink / raw)
  To: Ladislav Michl
  Cc: linux-mtd, linux-omap, Roger Quadros, Tony Lindgren,
	Peter Ujfalusi, Boris Brezillon, Kyungmin Park

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

Hi,

On Sat, Nov 11, 2017 at 10:19:42PM +0100, Ladislav Michl wrote:
> No platform data user sets skip_initial_unlocking, so remove test
> for this field.
> 
> Signed-off-by: Ladislav Michl <ladis@linux-mips.org>
> ---

Reviewed-by: Sebastian Reichel <sebastian.reichel@collabora.co.uk>

-- Sebastian

>  Changes:
>  -v2: new patch
>  -v3: none
>  -v4: none
> 
>  drivers/mtd/onenand/omap2.c | 3 ---
>  1 file changed, 3 deletions(-)
> 
> diff --git a/drivers/mtd/onenand/omap2.c b/drivers/mtd/onenand/omap2.c
> index a03e1fe4aa48..93bd94337b35 100644
> --- a/drivers/mtd/onenand/omap2.c
> +++ b/drivers/mtd/onenand/omap2.c
> @@ -700,9 +700,6 @@ static int omap2_onenand_probe(struct platform_device *pdev)
>  		}
>  	}
>  
> -	if (pdata->skip_initial_unlocking)
> -		this->options |= ONENAND_SKIP_INITIAL_UNLOCKING;
> -
>  	if ((r = onenand_scan(&c->mtd, 1)) < 0)
>  		goto err_release_dma;
>  
> -- 
> 2.11.0
> 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-omap" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

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

* Re: [PATCH v4 14/16] mtd: onenand: omap2: Configure driver from DT
  2017-11-15 11:20           ` Ladislav Michl
@ 2017-11-15 14:41             ` Roger Quadros
  -1 siblings, 0 replies; 114+ messages in thread
From: Roger Quadros @ 2017-11-15 14:41 UTC (permalink / raw)
  To: Ladislav Michl
  Cc: Boris Brezillon, Tony Lindgren, Peter Ujfalusi, Kyungmin Park,
	linux-mtd, linux-omap

On 15/11/17 13:20, Ladislav Michl wrote:
> On Wed, Nov 15, 2017 at 01:04:22PM +0200, Roger Quadros wrote:
>> On 15/11/17 12:53, Ladislav Michl wrote:
> [snip]
>>> of_property_read_u32 will fail then, so I do not think it is worth adding
>>> explicit test for NULL here.
>>>
>>
>> But the error message would be wrong in that case.
>> I'm trying to tackle the case where driver was probed using legacy methods
>> where device tree/node isn't present.
> 
> But how could we ever get there in that case? platform_device_register is
> removed just one patch later.
> 
> Of course we should add:
> depends on (OF && GPIOLIB) || COMPILE_TEST
> to the Kconfig
> 

OK.

-- 
cheers,
-roger

Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki. Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki

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

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

* Re: [PATCH v4 14/16] mtd: onenand: omap2: Configure driver from DT
@ 2017-11-15 14:41             ` Roger Quadros
  0 siblings, 0 replies; 114+ messages in thread
From: Roger Quadros @ 2017-11-15 14:41 UTC (permalink / raw)
  To: Ladislav Michl
  Cc: linux-mtd, linux-omap, Tony Lindgren, Peter Ujfalusi,
	Boris Brezillon, Kyungmin Park

On 15/11/17 13:20, Ladislav Michl wrote:
> On Wed, Nov 15, 2017 at 01:04:22PM +0200, Roger Quadros wrote:
>> On 15/11/17 12:53, Ladislav Michl wrote:
> [snip]
>>> of_property_read_u32 will fail then, so I do not think it is worth adding
>>> explicit test for NULL here.
>>>
>>
>> But the error message would be wrong in that case.
>> I'm trying to tackle the case where driver was probed using legacy methods
>> where device tree/node isn't present.
> 
> But how could we ever get there in that case? platform_device_register is
> removed just one patch later.
> 
> Of course we should add:
> depends on (OF && GPIOLIB) || COMPILE_TEST
> to the Kconfig
> 

OK.

-- 
cheers,
-roger

Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki. Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki

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

* Re: [PATCH v4 06/16] mtd: onenand: omap2: Remove partitioning support from platform data
  2017-11-11 21:20   ` Ladislav Michl
@ 2017-11-15 14:57     ` Sebastian Reichel
  -1 siblings, 0 replies; 114+ messages in thread
From: Sebastian Reichel @ 2017-11-15 14:57 UTC (permalink / raw)
  To: Ladislav Michl
  Cc: Boris Brezillon, Tony Lindgren, Peter Ujfalusi, Kyungmin Park,
	linux-mtd, linux-omap, Roger Quadros


[-- Attachment #1.1: Type: text/plain, Size: 1238 bytes --]

Hi,

On Sat, Nov 11, 2017 at 10:20:20PM +0100, Ladislav Michl wrote:
> No platform data user setups partitioning informations, so remove.
> 
> Signed-off-by: Ladislav Michl <ladis@linux-mips.org>
> ---

Reviewed-by: Sebastian Reichel <sebastian.reichel@collabora.co.uk>

-- Sebastian

>  Changes:
>  -v2: new patch
>  -v3: none
>  -v4: none
> 
>  drivers/mtd/onenand/omap2.c | 3 +--
>  1 file changed, 1 insertion(+), 2 deletions(-)
> 
> diff --git a/drivers/mtd/onenand/omap2.c b/drivers/mtd/onenand/omap2.c
> index 93bd94337b35..883993bbe40b 100644
> --- a/drivers/mtd/onenand/omap2.c
> +++ b/drivers/mtd/onenand/omap2.c
> @@ -703,8 +703,7 @@ static int omap2_onenand_probe(struct platform_device *pdev)
>  	if ((r = onenand_scan(&c->mtd, 1)) < 0)
>  		goto err_release_dma;
>  
> -	r = mtd_device_register(&c->mtd, pdata ? pdata->parts : NULL,
> -				pdata ? pdata->nr_parts : 0);
> +	r = mtd_device_register(&c->mtd, NULL, 0);
>  	if (r)
>  		goto err_release_onenand;
>  
> -- 
> 2.11.0
> 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-omap" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

[-- Attachment #1.2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

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

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

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

* Re: [PATCH v4 06/16] mtd: onenand: omap2: Remove partitioning support from platform data
@ 2017-11-15 14:57     ` Sebastian Reichel
  0 siblings, 0 replies; 114+ messages in thread
From: Sebastian Reichel @ 2017-11-15 14:57 UTC (permalink / raw)
  To: Ladislav Michl
  Cc: linux-mtd, linux-omap, Roger Quadros, Tony Lindgren,
	Peter Ujfalusi, Boris Brezillon, Kyungmin Park

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

Hi,

On Sat, Nov 11, 2017 at 10:20:20PM +0100, Ladislav Michl wrote:
> No platform data user setups partitioning informations, so remove.
> 
> Signed-off-by: Ladislav Michl <ladis@linux-mips.org>
> ---

Reviewed-by: Sebastian Reichel <sebastian.reichel@collabora.co.uk>

-- Sebastian

>  Changes:
>  -v2: new patch
>  -v3: none
>  -v4: none
> 
>  drivers/mtd/onenand/omap2.c | 3 +--
>  1 file changed, 1 insertion(+), 2 deletions(-)
> 
> diff --git a/drivers/mtd/onenand/omap2.c b/drivers/mtd/onenand/omap2.c
> index 93bd94337b35..883993bbe40b 100644
> --- a/drivers/mtd/onenand/omap2.c
> +++ b/drivers/mtd/onenand/omap2.c
> @@ -703,8 +703,7 @@ static int omap2_onenand_probe(struct platform_device *pdev)
>  	if ((r = onenand_scan(&c->mtd, 1)) < 0)
>  		goto err_release_dma;
>  
> -	r = mtd_device_register(&c->mtd, pdata ? pdata->parts : NULL,
> -				pdata ? pdata->nr_parts : 0);
> +	r = mtd_device_register(&c->mtd, NULL, 0);
>  	if (r)
>  		goto err_release_onenand;
>  
> -- 
> 2.11.0
> 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-omap" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

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

* Re: [PATCH v4 07/16] mtd: onenand: omap2: Account waiting time as waiting on IO
  2017-11-11 21:20   ` Ladislav Michl
@ 2017-11-15 15:00     ` Sebastian Reichel
  -1 siblings, 0 replies; 114+ messages in thread
From: Sebastian Reichel @ 2017-11-15 15:00 UTC (permalink / raw)
  To: Ladislav Michl
  Cc: Boris Brezillon, Tony Lindgren, Peter Ujfalusi, Kyungmin Park,
	linux-mtd, linux-omap, Roger Quadros


[-- Attachment #1.1: Type: text/plain, Size: 1378 bytes --]

Hi,

On Sat, Nov 11, 2017 at 10:20:58PM +0100, Ladislav Michl wrote:
> Use wait_for_completion_io_timeout, which has an impact on how the
> task is accounted in scheduling stats.
> 
> Signed-off-by: Ladislav Michl <ladis@linux-mips.org>
> ---

Reviewed-by: Sebastian Reichel <sebastian.reichel@collabora.co.uk>

-- Sebastian

>  Changes:
>  -v4: new patch
> 
>  drivers/mtd/onenand/omap2.c | 5 ++---
>  1 file changed, 2 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/mtd/onenand/omap2.c b/drivers/mtd/onenand/omap2.c
> index 883993bbe40b..0e7772e16d75 100644
> --- a/drivers/mtd/onenand/omap2.c
> +++ b/drivers/mtd/onenand/omap2.c
> @@ -170,9 +170,8 @@ static int omap2_onenand_wait(struct mtd_info *mtd, int state)
>  		if (result == 0) {
>  			int retry_cnt = 0;
>  retry:
> -			result = wait_for_completion_timeout(&c->irq_done,
> -						    msecs_to_jiffies(20));
> -			if (result == 0) {
> +			if (!wait_for_completion_io_timeout(&c->irq_done,
> +						msecs_to_jiffies(20))) {
>  				/* Timeout after 20ms */
>  				ctrl = read_reg(c, ONENAND_REG_CTRL_STATUS);
>  				if (ctrl & ONENAND_CTRL_ONGO &&
> -- 
> 2.11.0
> 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-omap" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

[-- Attachment #1.2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

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

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

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

* Re: [PATCH v4 07/16] mtd: onenand: omap2: Account waiting time as waiting on IO
@ 2017-11-15 15:00     ` Sebastian Reichel
  0 siblings, 0 replies; 114+ messages in thread
From: Sebastian Reichel @ 2017-11-15 15:00 UTC (permalink / raw)
  To: Ladislav Michl
  Cc: linux-mtd, linux-omap, Roger Quadros, Tony Lindgren,
	Peter Ujfalusi, Boris Brezillon, Kyungmin Park

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

Hi,

On Sat, Nov 11, 2017 at 10:20:58PM +0100, Ladislav Michl wrote:
> Use wait_for_completion_io_timeout, which has an impact on how the
> task is accounted in scheduling stats.
> 
> Signed-off-by: Ladislav Michl <ladis@linux-mips.org>
> ---

Reviewed-by: Sebastian Reichel <sebastian.reichel@collabora.co.uk>

-- Sebastian

>  Changes:
>  -v4: new patch
> 
>  drivers/mtd/onenand/omap2.c | 5 ++---
>  1 file changed, 2 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/mtd/onenand/omap2.c b/drivers/mtd/onenand/omap2.c
> index 883993bbe40b..0e7772e16d75 100644
> --- a/drivers/mtd/onenand/omap2.c
> +++ b/drivers/mtd/onenand/omap2.c
> @@ -170,9 +170,8 @@ static int omap2_onenand_wait(struct mtd_info *mtd, int state)
>  		if (result == 0) {
>  			int retry_cnt = 0;
>  retry:
> -			result = wait_for_completion_timeout(&c->irq_done,
> -						    msecs_to_jiffies(20));
> -			if (result == 0) {
> +			if (!wait_for_completion_io_timeout(&c->irq_done,
> +						msecs_to_jiffies(20))) {
>  				/* Timeout after 20ms */
>  				ctrl = read_reg(c, ONENAND_REG_CTRL_STATUS);
>  				if (ctrl & ONENAND_CTRL_ONGO &&
> -- 
> 2.11.0
> 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-omap" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

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

* Re: [PATCH v4 08/16] mtd: onenand: omap2: Simplify the DMA setup for various paths
  2017-11-11 21:21   ` Ladislav Michl
@ 2017-11-15 15:05     ` Sebastian Reichel
  -1 siblings, 0 replies; 114+ messages in thread
From: Sebastian Reichel @ 2017-11-15 15:05 UTC (permalink / raw)
  To: Ladislav Michl
  Cc: Boris Brezillon, Tony Lindgren, Peter Ujfalusi, Kyungmin Park,
	linux-mtd, linux-omap, Roger Quadros


[-- Attachment #1.1: Type: text/plain, Size: 7883 bytes --]

Hi,

On Sat, Nov 11, 2017 at 10:21:53PM +0100, Ladislav Michl wrote:
> From: Peter Ujfalusi <peter.ujfalusi@ti.com>
> 
> We have 4 functions containing almost identical DMA setup code. Create one
> function which can set up the DMA for both read and write and use this in
> place for the setup code in the driver.
> The new function will use wait_for_completion_io_timeout() and it will
> figure out the best data_type to be used for the transfer instead of
> hardwiring 32 or 16 bit data.
> 
> Signed-off-by: Peter Ujfalusi <peter.ujfalusi@ti.com>
> Signed-off-by: Ladislav Michl <ladis@linux-mips.org>
> ---

Reviewed-by: Sebastian Reichel <sebastian.reichel@collabora.co.uk>

-- Sebastian

>  Changes:
>  -v4: new patch
> 
>  drivers/mtd/onenand/omap2.c | 109 ++++++++++++++++++--------------------------
>  1 file changed, 45 insertions(+), 64 deletions(-)
> 
> diff --git a/drivers/mtd/onenand/omap2.c b/drivers/mtd/onenand/omap2.c
> index 0e7772e16d75..d22163271dc9 100644
> --- a/drivers/mtd/onenand/omap2.c
> +++ b/drivers/mtd/onenand/omap2.c
> @@ -288,6 +288,33 @@ static inline int omap2_onenand_bufferram_offset(struct mtd_info *mtd, int area)
>  	return 0;
>  }
>  
> +static inline int omap2_onenand_dma_transfer(struct omap2_onenand *c,
> +					     dma_addr_t src, dma_addr_t dst,
> +					     size_t count)
> +{
> +	int data_type = __ffs((src | dst | count));
> +
> +	if (data_type > OMAP_DMA_DATA_TYPE_S32)
> +		data_type = OMAP_DMA_DATA_TYPE_S32;
> +
> +	omap_set_dma_transfer_params(c->dma_channel, data_type,
> +				     count / BIT(data_type), 1, 0, 0, 0);
> +	omap_set_dma_src_params(c->dma_channel, 0, OMAP_DMA_AMODE_POST_INC,
> +				src, 0, 0);
> +	omap_set_dma_dest_params(c->dma_channel, 0, OMAP_DMA_AMODE_POST_INC,
> +				 dst, 0, 0);
> +
> +	reinit_completion(&c->dma_done);
> +	omap_start_dma(c->dma_channel);
> +	if (!wait_for_completion_io_timeout(&c->dma_done,
> +					    msecs_to_jiffies(20))) {
> +		omap_stop_dma(c->dma_channel);
> +		return -ETIMEDOUT;
> +	}
> +
> +	return 0;
> +}
> +
>  #if defined(CONFIG_ARCH_OMAP3) || defined(MULTI_OMAP2)
>  
>  static int omap3_onenand_read_bufferram(struct mtd_info *mtd, int area,
> @@ -298,10 +325,9 @@ static int omap3_onenand_read_bufferram(struct mtd_info *mtd, int area,
>  	struct onenand_chip *this = mtd->priv;
>  	dma_addr_t dma_src, dma_dst;
>  	int bram_offset;
> -	unsigned long timeout;
>  	void *buf = (void *)buffer;
>  	size_t xtra;
> -	volatile unsigned *done;
> +	int ret;
>  
>  	bram_offset = omap2_onenand_bufferram_offset(mtd, area) + area + offset;
>  	if (bram_offset & 3 || (size_t)buf & 3 || count < 384)
> @@ -338,25 +364,10 @@ static int omap3_onenand_read_bufferram(struct mtd_info *mtd, int area,
>  		goto out_copy;
>  	}
>  
> -	omap_set_dma_transfer_params(c->dma_channel, OMAP_DMA_DATA_TYPE_S32,
> -				     count >> 2, 1, 0, 0, 0);
> -	omap_set_dma_src_params(c->dma_channel, 0, OMAP_DMA_AMODE_POST_INC,
> -				dma_src, 0, 0);
> -	omap_set_dma_dest_params(c->dma_channel, 0, OMAP_DMA_AMODE_POST_INC,
> -				 dma_dst, 0, 0);
> -
> -	reinit_completion(&c->dma_done);
> -	omap_start_dma(c->dma_channel);
> -
> -	timeout = jiffies + msecs_to_jiffies(20);
> -	done = &c->dma_done.done;
> -	while (time_before(jiffies, timeout))
> -		if (*done)
> -			break;
> -
> +	ret = omap2_onenand_dma_transfer(c, dma_src, dma_dst, count);
>  	dma_unmap_single(&c->pdev->dev, dma_dst, count, DMA_FROM_DEVICE);
>  
> -	if (!*done) {
> +	if (ret) {
>  		dev_err(&c->pdev->dev, "timeout waiting for DMA\n");
>  		goto out_copy;
>  	}
> @@ -376,9 +387,8 @@ static int omap3_onenand_write_bufferram(struct mtd_info *mtd, int area,
>  	struct onenand_chip *this = mtd->priv;
>  	dma_addr_t dma_src, dma_dst;
>  	int bram_offset;
> -	unsigned long timeout;
>  	void *buf = (void *)buffer;
> -	volatile unsigned *done;
> +	int ret;
>  
>  	bram_offset = omap2_onenand_bufferram_offset(mtd, area) + area + offset;
>  	if (bram_offset & 3 || (size_t)buf & 3 || count < 384)
> @@ -409,25 +419,10 @@ static int omap3_onenand_write_bufferram(struct mtd_info *mtd, int area,
>  		return -1;
>  	}
>  
> -	omap_set_dma_transfer_params(c->dma_channel, OMAP_DMA_DATA_TYPE_S32,
> -				     count >> 2, 1, 0, 0, 0);
> -	omap_set_dma_src_params(c->dma_channel, 0, OMAP_DMA_AMODE_POST_INC,
> -				dma_src, 0, 0);
> -	omap_set_dma_dest_params(c->dma_channel, 0, OMAP_DMA_AMODE_POST_INC,
> -				 dma_dst, 0, 0);
> -
> -	reinit_completion(&c->dma_done);
> -	omap_start_dma(c->dma_channel);
> -
> -	timeout = jiffies + msecs_to_jiffies(20);
> -	done = &c->dma_done.done;
> -	while (time_before(jiffies, timeout))
> -		if (*done)
> -			break;
> -
> +	ret = omap2_onenand_dma_transfer(c, dma_src, dma_dst, count);
>  	dma_unmap_single(&c->pdev->dev, dma_src, count, DMA_TO_DEVICE);
>  
> -	if (!*done) {
> +	if (ret) {
>  		dev_err(&c->pdev->dev, "timeout waiting for DMA\n");
>  		goto out_copy;
>  	}
> @@ -466,7 +461,7 @@ static int omap2_onenand_read_bufferram(struct mtd_info *mtd, int area,
>  	struct omap2_onenand *c = container_of(mtd, struct omap2_onenand, mtd);
>  	struct onenand_chip *this = mtd->priv;
>  	dma_addr_t dma_src, dma_dst;
> -	int bram_offset;
> +	int bram_offset, ret;
>  
>  	bram_offset = omap2_onenand_bufferram_offset(mtd, area) + area + offset;
>  	/* DMA is not used.  Revisit PM requirements before enabling it. */
> @@ -488,20 +483,13 @@ static int omap2_onenand_read_bufferram(struct mtd_info *mtd, int area,
>  		return -1;
>  	}
>  
> -	omap_set_dma_transfer_params(c->dma_channel, OMAP_DMA_DATA_TYPE_S32,
> -				     count / 4, 1, 0, 0, 0);
> -	omap_set_dma_src_params(c->dma_channel, 0, OMAP_DMA_AMODE_POST_INC,
> -				dma_src, 0, 0);
> -	omap_set_dma_dest_params(c->dma_channel, 0, OMAP_DMA_AMODE_POST_INC,
> -				 dma_dst, 0, 0);
> -
> -	reinit_completion(&c->dma_done);
> -	omap_start_dma(c->dma_channel);
> -	wait_for_completion(&c->dma_done);
> -
> +	ret = omap2_onenand_dma_transfer(c, dma_src, dma_dst, count);
>  	dma_unmap_single(&c->pdev->dev, dma_dst, count, DMA_FROM_DEVICE);
>  
> -	return 0;
> +	if (ret)
> +		dev_err(&c->pdev->dev, "timeout waiting for DMA\n");
> +
> +	return ret;
>  }
>  
>  static int omap2_onenand_write_bufferram(struct mtd_info *mtd, int area,
> @@ -511,7 +499,7 @@ static int omap2_onenand_write_bufferram(struct mtd_info *mtd, int area,
>  	struct omap2_onenand *c = container_of(mtd, struct omap2_onenand, mtd);
>  	struct onenand_chip *this = mtd->priv;
>  	dma_addr_t dma_src, dma_dst;
> -	int bram_offset;
> +	int bram_offset, ret;
>  
>  	bram_offset = omap2_onenand_bufferram_offset(mtd, area) + area + offset;
>  	/* DMA is not used.  Revisit PM requirements before enabling it. */
> @@ -533,20 +521,13 @@ static int omap2_onenand_write_bufferram(struct mtd_info *mtd, int area,
>  		return -1;
>  	}
>  
> -	omap_set_dma_transfer_params(c->dma_channel, OMAP_DMA_DATA_TYPE_S16,
> -				     count / 2, 1, 0, 0, 0);
> -	omap_set_dma_src_params(c->dma_channel, 0, OMAP_DMA_AMODE_POST_INC,
> -				dma_src, 0, 0);
> -	omap_set_dma_dest_params(c->dma_channel, 0, OMAP_DMA_AMODE_POST_INC,
> -				 dma_dst, 0, 0);
> -
> -	reinit_completion(&c->dma_done);
> -	omap_start_dma(c->dma_channel);
> -	wait_for_completion(&c->dma_done);
> -
> +	ret = omap2_onenand_dma_transfer(c, dma_src, dma_dst, count);
>  	dma_unmap_single(&c->pdev->dev, dma_src, count, DMA_TO_DEVICE);
>  
> -	return 0;
> +	if (ret)
> +		dev_err(&c->pdev->dev, "timeout waiting for DMA\n");
> +
> +	return ret;
>  }
>  
>  #else
> -- 
> 2.11.0
> 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-omap" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

[-- Attachment #1.2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

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

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

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

* Re: [PATCH v4 08/16] mtd: onenand: omap2: Simplify the DMA setup for various paths
@ 2017-11-15 15:05     ` Sebastian Reichel
  0 siblings, 0 replies; 114+ messages in thread
From: Sebastian Reichel @ 2017-11-15 15:05 UTC (permalink / raw)
  To: Ladislav Michl
  Cc: linux-mtd, linux-omap, Roger Quadros, Tony Lindgren,
	Peter Ujfalusi, Boris Brezillon, Kyungmin Park

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

Hi,

On Sat, Nov 11, 2017 at 10:21:53PM +0100, Ladislav Michl wrote:
> From: Peter Ujfalusi <peter.ujfalusi@ti.com>
> 
> We have 4 functions containing almost identical DMA setup code. Create one
> function which can set up the DMA for both read and write and use this in
> place for the setup code in the driver.
> The new function will use wait_for_completion_io_timeout() and it will
> figure out the best data_type to be used for the transfer instead of
> hardwiring 32 or 16 bit data.
> 
> Signed-off-by: Peter Ujfalusi <peter.ujfalusi@ti.com>
> Signed-off-by: Ladislav Michl <ladis@linux-mips.org>
> ---

Reviewed-by: Sebastian Reichel <sebastian.reichel@collabora.co.uk>

-- Sebastian

>  Changes:
>  -v4: new patch
> 
>  drivers/mtd/onenand/omap2.c | 109 ++++++++++++++++++--------------------------
>  1 file changed, 45 insertions(+), 64 deletions(-)
> 
> diff --git a/drivers/mtd/onenand/omap2.c b/drivers/mtd/onenand/omap2.c
> index 0e7772e16d75..d22163271dc9 100644
> --- a/drivers/mtd/onenand/omap2.c
> +++ b/drivers/mtd/onenand/omap2.c
> @@ -288,6 +288,33 @@ static inline int omap2_onenand_bufferram_offset(struct mtd_info *mtd, int area)
>  	return 0;
>  }
>  
> +static inline int omap2_onenand_dma_transfer(struct omap2_onenand *c,
> +					     dma_addr_t src, dma_addr_t dst,
> +					     size_t count)
> +{
> +	int data_type = __ffs((src | dst | count));
> +
> +	if (data_type > OMAP_DMA_DATA_TYPE_S32)
> +		data_type = OMAP_DMA_DATA_TYPE_S32;
> +
> +	omap_set_dma_transfer_params(c->dma_channel, data_type,
> +				     count / BIT(data_type), 1, 0, 0, 0);
> +	omap_set_dma_src_params(c->dma_channel, 0, OMAP_DMA_AMODE_POST_INC,
> +				src, 0, 0);
> +	omap_set_dma_dest_params(c->dma_channel, 0, OMAP_DMA_AMODE_POST_INC,
> +				 dst, 0, 0);
> +
> +	reinit_completion(&c->dma_done);
> +	omap_start_dma(c->dma_channel);
> +	if (!wait_for_completion_io_timeout(&c->dma_done,
> +					    msecs_to_jiffies(20))) {
> +		omap_stop_dma(c->dma_channel);
> +		return -ETIMEDOUT;
> +	}
> +
> +	return 0;
> +}
> +
>  #if defined(CONFIG_ARCH_OMAP3) || defined(MULTI_OMAP2)
>  
>  static int omap3_onenand_read_bufferram(struct mtd_info *mtd, int area,
> @@ -298,10 +325,9 @@ static int omap3_onenand_read_bufferram(struct mtd_info *mtd, int area,
>  	struct onenand_chip *this = mtd->priv;
>  	dma_addr_t dma_src, dma_dst;
>  	int bram_offset;
> -	unsigned long timeout;
>  	void *buf = (void *)buffer;
>  	size_t xtra;
> -	volatile unsigned *done;
> +	int ret;
>  
>  	bram_offset = omap2_onenand_bufferram_offset(mtd, area) + area + offset;
>  	if (bram_offset & 3 || (size_t)buf & 3 || count < 384)
> @@ -338,25 +364,10 @@ static int omap3_onenand_read_bufferram(struct mtd_info *mtd, int area,
>  		goto out_copy;
>  	}
>  
> -	omap_set_dma_transfer_params(c->dma_channel, OMAP_DMA_DATA_TYPE_S32,
> -				     count >> 2, 1, 0, 0, 0);
> -	omap_set_dma_src_params(c->dma_channel, 0, OMAP_DMA_AMODE_POST_INC,
> -				dma_src, 0, 0);
> -	omap_set_dma_dest_params(c->dma_channel, 0, OMAP_DMA_AMODE_POST_INC,
> -				 dma_dst, 0, 0);
> -
> -	reinit_completion(&c->dma_done);
> -	omap_start_dma(c->dma_channel);
> -
> -	timeout = jiffies + msecs_to_jiffies(20);
> -	done = &c->dma_done.done;
> -	while (time_before(jiffies, timeout))
> -		if (*done)
> -			break;
> -
> +	ret = omap2_onenand_dma_transfer(c, dma_src, dma_dst, count);
>  	dma_unmap_single(&c->pdev->dev, dma_dst, count, DMA_FROM_DEVICE);
>  
> -	if (!*done) {
> +	if (ret) {
>  		dev_err(&c->pdev->dev, "timeout waiting for DMA\n");
>  		goto out_copy;
>  	}
> @@ -376,9 +387,8 @@ static int omap3_onenand_write_bufferram(struct mtd_info *mtd, int area,
>  	struct onenand_chip *this = mtd->priv;
>  	dma_addr_t dma_src, dma_dst;
>  	int bram_offset;
> -	unsigned long timeout;
>  	void *buf = (void *)buffer;
> -	volatile unsigned *done;
> +	int ret;
>  
>  	bram_offset = omap2_onenand_bufferram_offset(mtd, area) + area + offset;
>  	if (bram_offset & 3 || (size_t)buf & 3 || count < 384)
> @@ -409,25 +419,10 @@ static int omap3_onenand_write_bufferram(struct mtd_info *mtd, int area,
>  		return -1;
>  	}
>  
> -	omap_set_dma_transfer_params(c->dma_channel, OMAP_DMA_DATA_TYPE_S32,
> -				     count >> 2, 1, 0, 0, 0);
> -	omap_set_dma_src_params(c->dma_channel, 0, OMAP_DMA_AMODE_POST_INC,
> -				dma_src, 0, 0);
> -	omap_set_dma_dest_params(c->dma_channel, 0, OMAP_DMA_AMODE_POST_INC,
> -				 dma_dst, 0, 0);
> -
> -	reinit_completion(&c->dma_done);
> -	omap_start_dma(c->dma_channel);
> -
> -	timeout = jiffies + msecs_to_jiffies(20);
> -	done = &c->dma_done.done;
> -	while (time_before(jiffies, timeout))
> -		if (*done)
> -			break;
> -
> +	ret = omap2_onenand_dma_transfer(c, dma_src, dma_dst, count);
>  	dma_unmap_single(&c->pdev->dev, dma_src, count, DMA_TO_DEVICE);
>  
> -	if (!*done) {
> +	if (ret) {
>  		dev_err(&c->pdev->dev, "timeout waiting for DMA\n");
>  		goto out_copy;
>  	}
> @@ -466,7 +461,7 @@ static int omap2_onenand_read_bufferram(struct mtd_info *mtd, int area,
>  	struct omap2_onenand *c = container_of(mtd, struct omap2_onenand, mtd);
>  	struct onenand_chip *this = mtd->priv;
>  	dma_addr_t dma_src, dma_dst;
> -	int bram_offset;
> +	int bram_offset, ret;
>  
>  	bram_offset = omap2_onenand_bufferram_offset(mtd, area) + area + offset;
>  	/* DMA is not used.  Revisit PM requirements before enabling it. */
> @@ -488,20 +483,13 @@ static int omap2_onenand_read_bufferram(struct mtd_info *mtd, int area,
>  		return -1;
>  	}
>  
> -	omap_set_dma_transfer_params(c->dma_channel, OMAP_DMA_DATA_TYPE_S32,
> -				     count / 4, 1, 0, 0, 0);
> -	omap_set_dma_src_params(c->dma_channel, 0, OMAP_DMA_AMODE_POST_INC,
> -				dma_src, 0, 0);
> -	omap_set_dma_dest_params(c->dma_channel, 0, OMAP_DMA_AMODE_POST_INC,
> -				 dma_dst, 0, 0);
> -
> -	reinit_completion(&c->dma_done);
> -	omap_start_dma(c->dma_channel);
> -	wait_for_completion(&c->dma_done);
> -
> +	ret = omap2_onenand_dma_transfer(c, dma_src, dma_dst, count);
>  	dma_unmap_single(&c->pdev->dev, dma_dst, count, DMA_FROM_DEVICE);
>  
> -	return 0;
> +	if (ret)
> +		dev_err(&c->pdev->dev, "timeout waiting for DMA\n");
> +
> +	return ret;
>  }
>  
>  static int omap2_onenand_write_bufferram(struct mtd_info *mtd, int area,
> @@ -511,7 +499,7 @@ static int omap2_onenand_write_bufferram(struct mtd_info *mtd, int area,
>  	struct omap2_onenand *c = container_of(mtd, struct omap2_onenand, mtd);
>  	struct onenand_chip *this = mtd->priv;
>  	dma_addr_t dma_src, dma_dst;
> -	int bram_offset;
> +	int bram_offset, ret;
>  
>  	bram_offset = omap2_onenand_bufferram_offset(mtd, area) + area + offset;
>  	/* DMA is not used.  Revisit PM requirements before enabling it. */
> @@ -533,20 +521,13 @@ static int omap2_onenand_write_bufferram(struct mtd_info *mtd, int area,
>  		return -1;
>  	}
>  
> -	omap_set_dma_transfer_params(c->dma_channel, OMAP_DMA_DATA_TYPE_S16,
> -				     count / 2, 1, 0, 0, 0);
> -	omap_set_dma_src_params(c->dma_channel, 0, OMAP_DMA_AMODE_POST_INC,
> -				dma_src, 0, 0);
> -	omap_set_dma_dest_params(c->dma_channel, 0, OMAP_DMA_AMODE_POST_INC,
> -				 dma_dst, 0, 0);
> -
> -	reinit_completion(&c->dma_done);
> -	omap_start_dma(c->dma_channel);
> -	wait_for_completion(&c->dma_done);
> -
> +	ret = omap2_onenand_dma_transfer(c, dma_src, dma_dst, count);
>  	dma_unmap_single(&c->pdev->dev, dma_src, count, DMA_TO_DEVICE);
>  
> -	return 0;
> +	if (ret)
> +		dev_err(&c->pdev->dev, "timeout waiting for DMA\n");
> +
> +	return ret;
>  }
>  
>  #else
> -- 
> 2.11.0
> 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-omap" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

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

* Re: [PATCH v4 09/16] mtd: onenand: omap2: Unify OMAP2 and OMAP3 DMA implementation
  2017-11-11 21:22   ` Ladislav Michl
@ 2017-11-15 15:07     ` Sebastian Reichel
  -1 siblings, 0 replies; 114+ messages in thread
From: Sebastian Reichel @ 2017-11-15 15:07 UTC (permalink / raw)
  To: Ladislav Michl
  Cc: Boris Brezillon, Tony Lindgren, Peter Ujfalusi, Kyungmin Park,
	linux-mtd, linux-omap, Roger Quadros


[-- Attachment #1.1: Type: text/plain, Size: 6390 bytes --]

Hi,

On Sat, Nov 11, 2017 at 10:22:44PM +0100, Ladislav Michl wrote:
> Since the very first commit (36cd4fb5d277: "[MTD] [OneNAND] Add OMAP2 / OMAP3
> OneNAND driver") DMA is disabled for OMAP2. Later fixes thus went only into
> OMAP3 specific DMA functions which turned out not to be so OMAP3 specific,
> so merge those two implementations.
> 
> Signed-off-by: Ladislav Michl <ladis@linux-mips.org>

Reviewed-by: Sebastian Reichel <sebastian.reichel@collabora.co.uk>

-- Sebastian

> ---
>  Changes:
>  -v3: new patch
>  -v4: rebase on top of Peter's patch
> 
>  drivers/mtd/onenand/omap2.c | 129 ++------------------------------------------
>  1 file changed, 4 insertions(+), 125 deletions(-)
> 
> diff --git a/drivers/mtd/onenand/omap2.c b/drivers/mtd/onenand/omap2.c
> index d22163271dc9..36314124488d 100644
> --- a/drivers/mtd/onenand/omap2.c
> +++ b/drivers/mtd/onenand/omap2.c
> @@ -315,9 +315,7 @@ static inline int omap2_onenand_dma_transfer(struct omap2_onenand *c,
>  	return 0;
>  }
>  
> -#if defined(CONFIG_ARCH_OMAP3) || defined(MULTI_OMAP2)
> -
> -static int omap3_onenand_read_bufferram(struct mtd_info *mtd, int area,
> +static int omap2_onenand_read_bufferram(struct mtd_info *mtd, int area,
>  					unsigned char *buffer, int offset,
>  					size_t count)
>  {
> @@ -379,7 +377,7 @@ static int omap3_onenand_read_bufferram(struct mtd_info *mtd, int area,
>  	return 0;
>  }
>  
> -static int omap3_onenand_write_bufferram(struct mtd_info *mtd, int area,
> +static int omap2_onenand_write_bufferram(struct mtd_info *mtd, int area,
>  					 const unsigned char *buffer,
>  					 int offset, size_t count)
>  {
> @@ -434,120 +432,6 @@ static int omap3_onenand_write_bufferram(struct mtd_info *mtd, int area,
>  	return 0;
>  }
>  
> -#else
> -
> -static int omap3_onenand_read_bufferram(struct mtd_info *mtd, int area,
> -					unsigned char *buffer, int offset,
> -					size_t count)
> -{
> -	return -ENOSYS;
> -}
> -
> -static int omap3_onenand_write_bufferram(struct mtd_info *mtd, int area,
> -					 const unsigned char *buffer,
> -					 int offset, size_t count)
> -{
> -	return -ENOSYS;
> -}
> -
> -#endif
> -
> -#if defined(CONFIG_ARCH_OMAP2) || defined(MULTI_OMAP2)
> -
> -static int omap2_onenand_read_bufferram(struct mtd_info *mtd, int area,
> -					unsigned char *buffer, int offset,
> -					size_t count)
> -{
> -	struct omap2_onenand *c = container_of(mtd, struct omap2_onenand, mtd);
> -	struct onenand_chip *this = mtd->priv;
> -	dma_addr_t dma_src, dma_dst;
> -	int bram_offset, ret;
> -
> -	bram_offset = omap2_onenand_bufferram_offset(mtd, area) + area + offset;
> -	/* DMA is not used.  Revisit PM requirements before enabling it. */
> -	if (1 || (c->dma_channel < 0) ||
> -	    ((void *) buffer >= (void *) high_memory) || (bram_offset & 3) ||
> -	    (((unsigned int) buffer) & 3) || (count < 1024) || (count & 3)) {
> -		memcpy(buffer, (__force void *)(this->base + bram_offset),
> -		       count);
> -		return 0;
> -	}
> -
> -	dma_src = c->phys_base + bram_offset;
> -	dma_dst = dma_map_single(&c->pdev->dev, buffer, count,
> -				 DMA_FROM_DEVICE);
> -	if (dma_mapping_error(&c->pdev->dev, dma_dst)) {
> -		dev_err(&c->pdev->dev,
> -			"Couldn't DMA map a %d byte buffer\n",
> -			count);
> -		return -1;
> -	}
> -
> -	ret = omap2_onenand_dma_transfer(c, dma_src, dma_dst, count);
> -	dma_unmap_single(&c->pdev->dev, dma_dst, count, DMA_FROM_DEVICE);
> -
> -	if (ret)
> -		dev_err(&c->pdev->dev, "timeout waiting for DMA\n");
> -
> -	return ret;
> -}
> -
> -static int omap2_onenand_write_bufferram(struct mtd_info *mtd, int area,
> -					 const unsigned char *buffer,
> -					 int offset, size_t count)
> -{
> -	struct omap2_onenand *c = container_of(mtd, struct omap2_onenand, mtd);
> -	struct onenand_chip *this = mtd->priv;
> -	dma_addr_t dma_src, dma_dst;
> -	int bram_offset, ret;
> -
> -	bram_offset = omap2_onenand_bufferram_offset(mtd, area) + area + offset;
> -	/* DMA is not used.  Revisit PM requirements before enabling it. */
> -	if (1 || (c->dma_channel < 0) ||
> -	    ((void *) buffer >= (void *) high_memory) || (bram_offset & 3) ||
> -	    (((unsigned int) buffer) & 3) || (count < 1024) || (count & 3)) {
> -		memcpy((__force void *)(this->base + bram_offset), buffer,
> -		       count);
> -		return 0;
> -	}
> -
> -	dma_src = dma_map_single(&c->pdev->dev, (void *) buffer, count,
> -				 DMA_TO_DEVICE);
> -	dma_dst = c->phys_base + bram_offset;
> -	if (dma_mapping_error(&c->pdev->dev, dma_src)) {
> -		dev_err(&c->pdev->dev,
> -			"Couldn't DMA map a %d byte buffer\n",
> -			count);
> -		return -1;
> -	}
> -
> -	ret = omap2_onenand_dma_transfer(c, dma_src, dma_dst, count);
> -	dma_unmap_single(&c->pdev->dev, dma_src, count, DMA_TO_DEVICE);
> -
> -	if (ret)
> -		dev_err(&c->pdev->dev, "timeout waiting for DMA\n");
> -
> -	return ret;
> -}
> -
> -#else
> -
> -static int omap2_onenand_read_bufferram(struct mtd_info *mtd, int area,
> -					unsigned char *buffer, int offset,
> -					size_t count)
> -{
> -	return -ENOSYS;
> -}
> -
> -static int omap2_onenand_write_bufferram(struct mtd_info *mtd, int area,
> -					 const unsigned char *buffer,
> -					 int offset, size_t count)
> -{
> -	return -ENOSYS;
> -}
> -
> -#endif
> -
>  static struct platform_driver omap2_onenand_driver;
>  
>  static void omap2_onenand_shutdown(struct platform_device *pdev)
> @@ -671,13 +555,8 @@ static int omap2_onenand_probe(struct platform_device *pdev)
>  	this = &c->onenand;
>  	if (c->dma_channel >= 0) {
>  		this->wait = omap2_onenand_wait;
> -		if (c->flags & ONENAND_IN_OMAP34XX) {
> -			this->read_bufferram = omap3_onenand_read_bufferram;
> -			this->write_bufferram = omap3_onenand_write_bufferram;
> -		} else {
> -			this->read_bufferram = omap2_onenand_read_bufferram;
> -			this->write_bufferram = omap2_onenand_write_bufferram;
> -		}
> +		this->read_bufferram = omap2_onenand_read_bufferram;
> +		this->write_bufferram = omap2_onenand_write_bufferram;
>  	}
>  
>  	if ((r = onenand_scan(&c->mtd, 1)) < 0)
> -- 
> 2.11.0
> 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-omap" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

[-- Attachment #1.2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

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

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

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

* Re: [PATCH v4 09/16] mtd: onenand: omap2: Unify OMAP2 and OMAP3 DMA implementation
@ 2017-11-15 15:07     ` Sebastian Reichel
  0 siblings, 0 replies; 114+ messages in thread
From: Sebastian Reichel @ 2017-11-15 15:07 UTC (permalink / raw)
  To: Ladislav Michl
  Cc: linux-mtd, linux-omap, Roger Quadros, Tony Lindgren,
	Peter Ujfalusi, Boris Brezillon, Kyungmin Park

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

Hi,

On Sat, Nov 11, 2017 at 10:22:44PM +0100, Ladislav Michl wrote:
> Since the very first commit (36cd4fb5d277: "[MTD] [OneNAND] Add OMAP2 / OMAP3
> OneNAND driver") DMA is disabled for OMAP2. Later fixes thus went only into
> OMAP3 specific DMA functions which turned out not to be so OMAP3 specific,
> so merge those two implementations.
> 
> Signed-off-by: Ladislav Michl <ladis@linux-mips.org>

Reviewed-by: Sebastian Reichel <sebastian.reichel@collabora.co.uk>

-- Sebastian

> ---
>  Changes:
>  -v3: new patch
>  -v4: rebase on top of Peter's patch
> 
>  drivers/mtd/onenand/omap2.c | 129 ++------------------------------------------
>  1 file changed, 4 insertions(+), 125 deletions(-)
> 
> diff --git a/drivers/mtd/onenand/omap2.c b/drivers/mtd/onenand/omap2.c
> index d22163271dc9..36314124488d 100644
> --- a/drivers/mtd/onenand/omap2.c
> +++ b/drivers/mtd/onenand/omap2.c
> @@ -315,9 +315,7 @@ static inline int omap2_onenand_dma_transfer(struct omap2_onenand *c,
>  	return 0;
>  }
>  
> -#if defined(CONFIG_ARCH_OMAP3) || defined(MULTI_OMAP2)
> -
> -static int omap3_onenand_read_bufferram(struct mtd_info *mtd, int area,
> +static int omap2_onenand_read_bufferram(struct mtd_info *mtd, int area,
>  					unsigned char *buffer, int offset,
>  					size_t count)
>  {
> @@ -379,7 +377,7 @@ static int omap3_onenand_read_bufferram(struct mtd_info *mtd, int area,
>  	return 0;
>  }
>  
> -static int omap3_onenand_write_bufferram(struct mtd_info *mtd, int area,
> +static int omap2_onenand_write_bufferram(struct mtd_info *mtd, int area,
>  					 const unsigned char *buffer,
>  					 int offset, size_t count)
>  {
> @@ -434,120 +432,6 @@ static int omap3_onenand_write_bufferram(struct mtd_info *mtd, int area,
>  	return 0;
>  }
>  
> -#else
> -
> -static int omap3_onenand_read_bufferram(struct mtd_info *mtd, int area,
> -					unsigned char *buffer, int offset,
> -					size_t count)
> -{
> -	return -ENOSYS;
> -}
> -
> -static int omap3_onenand_write_bufferram(struct mtd_info *mtd, int area,
> -					 const unsigned char *buffer,
> -					 int offset, size_t count)
> -{
> -	return -ENOSYS;
> -}
> -
> -#endif
> -
> -#if defined(CONFIG_ARCH_OMAP2) || defined(MULTI_OMAP2)
> -
> -static int omap2_onenand_read_bufferram(struct mtd_info *mtd, int area,
> -					unsigned char *buffer, int offset,
> -					size_t count)
> -{
> -	struct omap2_onenand *c = container_of(mtd, struct omap2_onenand, mtd);
> -	struct onenand_chip *this = mtd->priv;
> -	dma_addr_t dma_src, dma_dst;
> -	int bram_offset, ret;
> -
> -	bram_offset = omap2_onenand_bufferram_offset(mtd, area) + area + offset;
> -	/* DMA is not used.  Revisit PM requirements before enabling it. */
> -	if (1 || (c->dma_channel < 0) ||
> -	    ((void *) buffer >= (void *) high_memory) || (bram_offset & 3) ||
> -	    (((unsigned int) buffer) & 3) || (count < 1024) || (count & 3)) {
> -		memcpy(buffer, (__force void *)(this->base + bram_offset),
> -		       count);
> -		return 0;
> -	}
> -
> -	dma_src = c->phys_base + bram_offset;
> -	dma_dst = dma_map_single(&c->pdev->dev, buffer, count,
> -				 DMA_FROM_DEVICE);
> -	if (dma_mapping_error(&c->pdev->dev, dma_dst)) {
> -		dev_err(&c->pdev->dev,
> -			"Couldn't DMA map a %d byte buffer\n",
> -			count);
> -		return -1;
> -	}
> -
> -	ret = omap2_onenand_dma_transfer(c, dma_src, dma_dst, count);
> -	dma_unmap_single(&c->pdev->dev, dma_dst, count, DMA_FROM_DEVICE);
> -
> -	if (ret)
> -		dev_err(&c->pdev->dev, "timeout waiting for DMA\n");
> -
> -	return ret;
> -}
> -
> -static int omap2_onenand_write_bufferram(struct mtd_info *mtd, int area,
> -					 const unsigned char *buffer,
> -					 int offset, size_t count)
> -{
> -	struct omap2_onenand *c = container_of(mtd, struct omap2_onenand, mtd);
> -	struct onenand_chip *this = mtd->priv;
> -	dma_addr_t dma_src, dma_dst;
> -	int bram_offset, ret;
> -
> -	bram_offset = omap2_onenand_bufferram_offset(mtd, area) + area + offset;
> -	/* DMA is not used.  Revisit PM requirements before enabling it. */
> -	if (1 || (c->dma_channel < 0) ||
> -	    ((void *) buffer >= (void *) high_memory) || (bram_offset & 3) ||
> -	    (((unsigned int) buffer) & 3) || (count < 1024) || (count & 3)) {
> -		memcpy((__force void *)(this->base + bram_offset), buffer,
> -		       count);
> -		return 0;
> -	}
> -
> -	dma_src = dma_map_single(&c->pdev->dev, (void *) buffer, count,
> -				 DMA_TO_DEVICE);
> -	dma_dst = c->phys_base + bram_offset;
> -	if (dma_mapping_error(&c->pdev->dev, dma_src)) {
> -		dev_err(&c->pdev->dev,
> -			"Couldn't DMA map a %d byte buffer\n",
> -			count);
> -		return -1;
> -	}
> -
> -	ret = omap2_onenand_dma_transfer(c, dma_src, dma_dst, count);
> -	dma_unmap_single(&c->pdev->dev, dma_src, count, DMA_TO_DEVICE);
> -
> -	if (ret)
> -		dev_err(&c->pdev->dev, "timeout waiting for DMA\n");
> -
> -	return ret;
> -}
> -
> -#else
> -
> -static int omap2_onenand_read_bufferram(struct mtd_info *mtd, int area,
> -					unsigned char *buffer, int offset,
> -					size_t count)
> -{
> -	return -ENOSYS;
> -}
> -
> -static int omap2_onenand_write_bufferram(struct mtd_info *mtd, int area,
> -					 const unsigned char *buffer,
> -					 int offset, size_t count)
> -{
> -	return -ENOSYS;
> -}
> -
> -#endif
> -
>  static struct platform_driver omap2_onenand_driver;
>  
>  static void omap2_onenand_shutdown(struct platform_device *pdev)
> @@ -671,13 +555,8 @@ static int omap2_onenand_probe(struct platform_device *pdev)
>  	this = &c->onenand;
>  	if (c->dma_channel >= 0) {
>  		this->wait = omap2_onenand_wait;
> -		if (c->flags & ONENAND_IN_OMAP34XX) {
> -			this->read_bufferram = omap3_onenand_read_bufferram;
> -			this->write_bufferram = omap3_onenand_write_bufferram;
> -		} else {
> -			this->read_bufferram = omap2_onenand_read_bufferram;
> -			this->write_bufferram = omap2_onenand_write_bufferram;
> -		}
> +		this->read_bufferram = omap2_onenand_read_bufferram;
> +		this->write_bufferram = omap2_onenand_write_bufferram;
>  	}
>  
>  	if ((r = onenand_scan(&c->mtd, 1)) < 0)
> -- 
> 2.11.0
> 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-omap" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

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

* Re: [PATCH v4 10/16] mtd: onenand: omap2: Convert to use dmaengine for memcpy
  2017-11-11 21:23   ` Ladislav Michl
@ 2017-11-15 15:19     ` Sebastian Reichel
  -1 siblings, 0 replies; 114+ messages in thread
From: Sebastian Reichel @ 2017-11-15 15:19 UTC (permalink / raw)
  To: Ladislav Michl
  Cc: Boris Brezillon, Tony Lindgren, Peter Ujfalusi, Kyungmin Park,
	linux-mtd, linux-omap, Roger Quadros


[-- Attachment #1.1: Type: text/plain, Size: 6255 bytes --]

Hi,

On Sat, Nov 11, 2017 at 10:23:31PM +0100, Ladislav Michl wrote:
> From: Peter Ujfalusi <peter.ujfalusi@ti.com>
> 
> Do not use the legacy and deprecated omap-dma interface for setting up the
> memcpy.
> 
> Signed-off-by: Peter Ujfalusi <peter.ujfalusi@ti.com>
> Signed-off-by: Ladislav Michl <ladis@linux-mips.org>
> ---

Reviewed-by: Sebastian Reichel <sebastian.reichel@collabora.co.uk>

-- Sebastian

>  Changes:
>  -v4: new patch
> 
>  drivers/mtd/onenand/omap2.c | 80 +++++++++++++++++++++------------------------
>  1 file changed, 38 insertions(+), 42 deletions(-)
> 
> diff --git a/drivers/mtd/onenand/omap2.c b/drivers/mtd/onenand/omap2.c
> index 36314124488d..c9ff67100ef4 100644
> --- a/drivers/mtd/onenand/omap2.c
> +++ b/drivers/mtd/onenand/omap2.c
> @@ -32,6 +32,7 @@
>  #include <linux/interrupt.h>
>  #include <linux/delay.h>
>  #include <linux/dma-mapping.h>
> +#include <linux/dmaengine.h>
>  #include <linux/io.h>
>  #include <linux/slab.h>
>  #include <linux/gpio.h>
> @@ -39,8 +40,6 @@
>  #include <asm/mach/flash.h>
>  #include <linux/platform_data/mtd-onenand-omap2.h>
>  
> -#include <linux/omap-dma.h>
> -
>  #define DRIVER_NAME "omap2-onenand"
>  
>  #define ONENAND_BUFRAM_SIZE	(1024 * 5)
> @@ -55,17 +54,15 @@ struct omap2_onenand {
>  	struct onenand_chip onenand;
>  	struct completion irq_done;
>  	struct completion dma_done;
> -	int dma_channel;
> +	struct dma_chan *dma_chan;
>  	int freq;
>  	int (*setup)(void __iomem *base, int *freq_ptr);
>  	u8 flags;
>  };
>  
> -static void omap2_onenand_dma_cb(int lch, u16 ch_status, void *data)
> +static void omap2_onenand_dma_complete_func(void *completion)
>  {
> -	struct omap2_onenand *c = data;
> -
> -	complete(&c->dma_done);
> +	complete(completion);
>  }
>  
>  static irqreturn_t omap2_onenand_interrupt(int irq, void *dev_id)
> @@ -292,23 +289,31 @@ static inline int omap2_onenand_dma_transfer(struct omap2_onenand *c,
>  					     dma_addr_t src, dma_addr_t dst,
>  					     size_t count)
>  {
> -	int data_type = __ffs((src | dst | count));
> +	struct dma_async_tx_descriptor *tx;
> +	dma_cookie_t cookie;
>  
> -	if (data_type > OMAP_DMA_DATA_TYPE_S32)
> -		data_type = OMAP_DMA_DATA_TYPE_S32;
> -
> -	omap_set_dma_transfer_params(c->dma_channel, data_type,
> -				     count / BIT(data_type), 1, 0, 0, 0);
> -	omap_set_dma_src_params(c->dma_channel, 0, OMAP_DMA_AMODE_POST_INC,
> -				src, 0, 0);
> -	omap_set_dma_dest_params(c->dma_channel, 0, OMAP_DMA_AMODE_POST_INC,
> -				 dst, 0, 0);
> +	tx = dmaengine_prep_dma_memcpy(c->dma_chan, dst, src, count, 0);
> +	if (!tx) {
> +		dev_err(&c->pdev->dev, "Failed to prepare DMA memcpy\n");
> +		return -EIO;
> +	}
>  
>  	reinit_completion(&c->dma_done);
> -	omap_start_dma(c->dma_channel);
> +
> +	tx->callback = omap2_onenand_dma_complete_func;
> +	tx->callback_param = &c->dma_done;
> +
> +	cookie = tx->tx_submit(tx);
> +	if (dma_submit_error(cookie)) {
> +		dev_err(&c->pdev->dev, "Failed to do DMA tx_submit\n");
> +		return -EIO;
> +	}
> +
> +	dma_async_issue_pending(c->dma_chan);
> +
>  	if (!wait_for_completion_io_timeout(&c->dma_done,
>  					    msecs_to_jiffies(20))) {
> -		omap_stop_dma(c->dma_channel);
> +		dmaengine_terminate_sync(c->dma_chan);
>  		return -ETIMEDOUT;
>  	}
>  
> @@ -468,8 +473,7 @@ static int omap2_onenand_probe(struct platform_device *pdev)
>  	c->flags = pdata->flags;
>  	c->gpmc_cs = pdata->cs;
>  	c->gpio_irq = pdata->gpio_irq;
> -	c->dma_channel = pdata->dma_channel;
> -	if (c->dma_channel < 0) {
> +	if (pdata->dma_channel < 0) {
>  		/* if -1, don't use DMA */
>  		c->gpio_irq = 0;
>  	}
> @@ -521,25 +525,17 @@ static int omap2_onenand_probe(struct platform_device *pdev)
>  		goto err_release_gpio;
>  	}
>  
> -	if (c->dma_channel >= 0) {
> -		r = omap_request_dma(0, pdev->dev.driver->name,
> -				     omap2_onenand_dma_cb, (void *) c,
> -				     &c->dma_channel);
> -		if (r == 0) {
> -			omap_set_dma_write_mode(c->dma_channel,
> -						OMAP_DMA_WRITE_NON_POSTED);
> -			omap_set_dma_src_data_pack(c->dma_channel, 1);
> -			omap_set_dma_src_burst_mode(c->dma_channel,
> -						    OMAP_DMA_DATA_BURST_8);
> -			omap_set_dma_dest_data_pack(c->dma_channel, 1);
> -			omap_set_dma_dest_burst_mode(c->dma_channel,
> -						     OMAP_DMA_DATA_BURST_8);
> -		} else {
> +	if (pdata->dma_channel >= 0) {
> +		dma_cap_mask_t mask;
> +
> +		dma_cap_zero(mask);
> +		dma_cap_set(DMA_MEMCPY, mask);
> +
> +		c->dma_chan = dma_request_channel(mask, NULL, NULL);
> +		if (!c->dma_chan)
>  			dev_info(&pdev->dev,
>  				 "failed to allocate DMA for OneNAND, "
>  				 "using PIO instead\n");
> -			c->dma_channel = -1;
> -		}
>  	}
>  
>  	dev_info(&pdev->dev, "initializing on CS%d, phys base 0x%08lx, virtual "
> @@ -553,7 +549,7 @@ static int omap2_onenand_probe(struct platform_device *pdev)
>  	mtd_set_of_node(&c->mtd, pdata->of_node);
>  
>  	this = &c->onenand;
> -	if (c->dma_channel >= 0) {
> +	if (c->dma_chan) {
>  		this->wait = omap2_onenand_wait;
>  		this->read_bufferram = omap2_onenand_read_bufferram;
>  		this->write_bufferram = omap2_onenand_write_bufferram;
> @@ -573,8 +569,8 @@ static int omap2_onenand_probe(struct platform_device *pdev)
>  err_release_onenand:
>  	onenand_release(&c->mtd);
>  err_release_dma:
> -	if (c->dma_channel != -1)
> -		omap_free_dma(c->dma_channel);
> +	if (c->dma_chan)
> +		dma_release_channel(c->dma_chan);
>  	if (c->gpio_irq)
>  		free_irq(gpio_to_irq(c->gpio_irq), c);
>  err_release_gpio:
> @@ -595,8 +591,8 @@ static int omap2_onenand_remove(struct platform_device *pdev)
>  	struct omap2_onenand *c = dev_get_drvdata(&pdev->dev);
>  
>  	onenand_release(&c->mtd);
> -	if (c->dma_channel != -1)
> -		omap_free_dma(c->dma_channel);
> +	if (c->dma_chan)
> +		dma_release_channel(c->dma_chan);
>  	omap2_onenand_shutdown(pdev);
>  	if (c->gpio_irq) {
>  		free_irq(gpio_to_irq(c->gpio_irq), c);
> -- 
> 2.11.0
> 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-omap" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

[-- Attachment #1.2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

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

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

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

* Re: [PATCH v4 10/16] mtd: onenand: omap2: Convert to use dmaengine for memcpy
@ 2017-11-15 15:19     ` Sebastian Reichel
  0 siblings, 0 replies; 114+ messages in thread
From: Sebastian Reichel @ 2017-11-15 15:19 UTC (permalink / raw)
  To: Ladislav Michl
  Cc: linux-mtd, linux-omap, Roger Quadros, Tony Lindgren,
	Peter Ujfalusi, Boris Brezillon, Kyungmin Park

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

Hi,

On Sat, Nov 11, 2017 at 10:23:31PM +0100, Ladislav Michl wrote:
> From: Peter Ujfalusi <peter.ujfalusi@ti.com>
> 
> Do not use the legacy and deprecated omap-dma interface for setting up the
> memcpy.
> 
> Signed-off-by: Peter Ujfalusi <peter.ujfalusi@ti.com>
> Signed-off-by: Ladislav Michl <ladis@linux-mips.org>
> ---

Reviewed-by: Sebastian Reichel <sebastian.reichel@collabora.co.uk>

-- Sebastian

>  Changes:
>  -v4: new patch
> 
>  drivers/mtd/onenand/omap2.c | 80 +++++++++++++++++++++------------------------
>  1 file changed, 38 insertions(+), 42 deletions(-)
> 
> diff --git a/drivers/mtd/onenand/omap2.c b/drivers/mtd/onenand/omap2.c
> index 36314124488d..c9ff67100ef4 100644
> --- a/drivers/mtd/onenand/omap2.c
> +++ b/drivers/mtd/onenand/omap2.c
> @@ -32,6 +32,7 @@
>  #include <linux/interrupt.h>
>  #include <linux/delay.h>
>  #include <linux/dma-mapping.h>
> +#include <linux/dmaengine.h>
>  #include <linux/io.h>
>  #include <linux/slab.h>
>  #include <linux/gpio.h>
> @@ -39,8 +40,6 @@
>  #include <asm/mach/flash.h>
>  #include <linux/platform_data/mtd-onenand-omap2.h>
>  
> -#include <linux/omap-dma.h>
> -
>  #define DRIVER_NAME "omap2-onenand"
>  
>  #define ONENAND_BUFRAM_SIZE	(1024 * 5)
> @@ -55,17 +54,15 @@ struct omap2_onenand {
>  	struct onenand_chip onenand;
>  	struct completion irq_done;
>  	struct completion dma_done;
> -	int dma_channel;
> +	struct dma_chan *dma_chan;
>  	int freq;
>  	int (*setup)(void __iomem *base, int *freq_ptr);
>  	u8 flags;
>  };
>  
> -static void omap2_onenand_dma_cb(int lch, u16 ch_status, void *data)
> +static void omap2_onenand_dma_complete_func(void *completion)
>  {
> -	struct omap2_onenand *c = data;
> -
> -	complete(&c->dma_done);
> +	complete(completion);
>  }
>  
>  static irqreturn_t omap2_onenand_interrupt(int irq, void *dev_id)
> @@ -292,23 +289,31 @@ static inline int omap2_onenand_dma_transfer(struct omap2_onenand *c,
>  					     dma_addr_t src, dma_addr_t dst,
>  					     size_t count)
>  {
> -	int data_type = __ffs((src | dst | count));
> +	struct dma_async_tx_descriptor *tx;
> +	dma_cookie_t cookie;
>  
> -	if (data_type > OMAP_DMA_DATA_TYPE_S32)
> -		data_type = OMAP_DMA_DATA_TYPE_S32;
> -
> -	omap_set_dma_transfer_params(c->dma_channel, data_type,
> -				     count / BIT(data_type), 1, 0, 0, 0);
> -	omap_set_dma_src_params(c->dma_channel, 0, OMAP_DMA_AMODE_POST_INC,
> -				src, 0, 0);
> -	omap_set_dma_dest_params(c->dma_channel, 0, OMAP_DMA_AMODE_POST_INC,
> -				 dst, 0, 0);
> +	tx = dmaengine_prep_dma_memcpy(c->dma_chan, dst, src, count, 0);
> +	if (!tx) {
> +		dev_err(&c->pdev->dev, "Failed to prepare DMA memcpy\n");
> +		return -EIO;
> +	}
>  
>  	reinit_completion(&c->dma_done);
> -	omap_start_dma(c->dma_channel);
> +
> +	tx->callback = omap2_onenand_dma_complete_func;
> +	tx->callback_param = &c->dma_done;
> +
> +	cookie = tx->tx_submit(tx);
> +	if (dma_submit_error(cookie)) {
> +		dev_err(&c->pdev->dev, "Failed to do DMA tx_submit\n");
> +		return -EIO;
> +	}
> +
> +	dma_async_issue_pending(c->dma_chan);
> +
>  	if (!wait_for_completion_io_timeout(&c->dma_done,
>  					    msecs_to_jiffies(20))) {
> -		omap_stop_dma(c->dma_channel);
> +		dmaengine_terminate_sync(c->dma_chan);
>  		return -ETIMEDOUT;
>  	}
>  
> @@ -468,8 +473,7 @@ static int omap2_onenand_probe(struct platform_device *pdev)
>  	c->flags = pdata->flags;
>  	c->gpmc_cs = pdata->cs;
>  	c->gpio_irq = pdata->gpio_irq;
> -	c->dma_channel = pdata->dma_channel;
> -	if (c->dma_channel < 0) {
> +	if (pdata->dma_channel < 0) {
>  		/* if -1, don't use DMA */
>  		c->gpio_irq = 0;
>  	}
> @@ -521,25 +525,17 @@ static int omap2_onenand_probe(struct platform_device *pdev)
>  		goto err_release_gpio;
>  	}
>  
> -	if (c->dma_channel >= 0) {
> -		r = omap_request_dma(0, pdev->dev.driver->name,
> -				     omap2_onenand_dma_cb, (void *) c,
> -				     &c->dma_channel);
> -		if (r == 0) {
> -			omap_set_dma_write_mode(c->dma_channel,
> -						OMAP_DMA_WRITE_NON_POSTED);
> -			omap_set_dma_src_data_pack(c->dma_channel, 1);
> -			omap_set_dma_src_burst_mode(c->dma_channel,
> -						    OMAP_DMA_DATA_BURST_8);
> -			omap_set_dma_dest_data_pack(c->dma_channel, 1);
> -			omap_set_dma_dest_burst_mode(c->dma_channel,
> -						     OMAP_DMA_DATA_BURST_8);
> -		} else {
> +	if (pdata->dma_channel >= 0) {
> +		dma_cap_mask_t mask;
> +
> +		dma_cap_zero(mask);
> +		dma_cap_set(DMA_MEMCPY, mask);
> +
> +		c->dma_chan = dma_request_channel(mask, NULL, NULL);
> +		if (!c->dma_chan)
>  			dev_info(&pdev->dev,
>  				 "failed to allocate DMA for OneNAND, "
>  				 "using PIO instead\n");
> -			c->dma_channel = -1;
> -		}
>  	}
>  
>  	dev_info(&pdev->dev, "initializing on CS%d, phys base 0x%08lx, virtual "
> @@ -553,7 +549,7 @@ static int omap2_onenand_probe(struct platform_device *pdev)
>  	mtd_set_of_node(&c->mtd, pdata->of_node);
>  
>  	this = &c->onenand;
> -	if (c->dma_channel >= 0) {
> +	if (c->dma_chan) {
>  		this->wait = omap2_onenand_wait;
>  		this->read_bufferram = omap2_onenand_read_bufferram;
>  		this->write_bufferram = omap2_onenand_write_bufferram;
> @@ -573,8 +569,8 @@ static int omap2_onenand_probe(struct platform_device *pdev)
>  err_release_onenand:
>  	onenand_release(&c->mtd);
>  err_release_dma:
> -	if (c->dma_channel != -1)
> -		omap_free_dma(c->dma_channel);
> +	if (c->dma_chan)
> +		dma_release_channel(c->dma_chan);
>  	if (c->gpio_irq)
>  		free_irq(gpio_to_irq(c->gpio_irq), c);
>  err_release_gpio:
> @@ -595,8 +591,8 @@ static int omap2_onenand_remove(struct platform_device *pdev)
>  	struct omap2_onenand *c = dev_get_drvdata(&pdev->dev);
>  
>  	onenand_release(&c->mtd);
> -	if (c->dma_channel != -1)
> -		omap_free_dma(c->dma_channel);
> +	if (c->dma_chan)
> +		dma_release_channel(c->dma_chan);
>  	omap2_onenand_shutdown(pdev);
>  	if (c->gpio_irq) {
>  		free_irq(gpio_to_irq(c->gpio_irq), c);
> -- 
> 2.11.0
> 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-omap" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

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

* Re: [PATCH v4 11/16] mtd: onenand: omap2: Do not make delay for GPIO OMAP3 specific
  2017-11-11 21:24   ` Ladislav Michl
@ 2017-11-15 15:20     ` Sebastian Reichel
  -1 siblings, 0 replies; 114+ messages in thread
From: Sebastian Reichel @ 2017-11-15 15:20 UTC (permalink / raw)
  To: Ladislav Michl
  Cc: Boris Brezillon, Tony Lindgren, Peter Ujfalusi, Kyungmin Park,
	linux-mtd, linux-omap, Roger Quadros


[-- Attachment #1.1: Type: text/plain, Size: 2271 bytes --]

Hi,

On Sat, Nov 11, 2017 at 10:24:06PM +0100, Ladislav Michl wrote:
> Second commit in driver history (782b7a367d81: "[MTD] [OneNAND] OMAP3:
> add delay for GPIO") added quirk for waiting until GPIO line settle.
> As DMA was disabled for OMAP2 boards, chances are this problem was
> not OMAP3 specific and as it is just one register read, previous
> test for SoC type is approximately as expensive as read itself.
> Make delay unconditional, which allows removing SoC specific code
> alltogether.
> 
> Signed-off-by: Ladislav Michl <ladis@linux-mips.org>

Reviewed-by: Sebastian Reichel <sebastian.reichel@collabora.co.uk>

-- Sebastian

> ---
>  Changes:
>  -v3: new patch
>  -v4: none
> 
>  drivers/mtd/onenand/omap2.c | 7 ++-----
>  1 file changed, 2 insertions(+), 5 deletions(-)
> 
> diff --git a/drivers/mtd/onenand/omap2.c b/drivers/mtd/onenand/omap2.c
> index c9ff67100ef4..e4857a41760d 100644
> --- a/drivers/mtd/onenand/omap2.c
> +++ b/drivers/mtd/onenand/omap2.c
> @@ -57,7 +57,6 @@ struct omap2_onenand {
>  	struct dma_chan *dma_chan;
>  	int freq;
>  	int (*setup)(void __iomem *base, int *freq_ptr);
> -	u8 flags;
>  };
>  
>  static void omap2_onenand_dma_complete_func(void *completion)
> @@ -148,9 +147,8 @@ static int omap2_onenand_wait(struct mtd_info *mtd, int state)
>  		if (!(syscfg & ONENAND_SYS_CFG1_IOBE)) {
>  			syscfg |= ONENAND_SYS_CFG1_IOBE;
>  			write_reg(c, syscfg, ONENAND_REG_SYS_CFG1);
> -			if (c->flags & ONENAND_IN_OMAP34XX)
> -				/* Add a delay to let GPIO settle */
> -				syscfg = read_reg(c, ONENAND_REG_SYS_CFG1);
> +			/* Add a delay to let GPIO settle */
> +			syscfg = read_reg(c, ONENAND_REG_SYS_CFG1);
>  		}
>  
>  		reinit_completion(&c->irq_done);
> @@ -470,7 +468,6 @@ static int omap2_onenand_probe(struct platform_device *pdev)
>  
>  	init_completion(&c->irq_done);
>  	init_completion(&c->dma_done);
> -	c->flags = pdata->flags;
>  	c->gpmc_cs = pdata->cs;
>  	c->gpio_irq = pdata->gpio_irq;
>  	if (pdata->dma_channel < 0) {
> -- 
> 2.11.0
> 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-omap" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

[-- Attachment #1.2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

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

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

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

* Re: [PATCH v4 11/16] mtd: onenand: omap2: Do not make delay for GPIO OMAP3 specific
@ 2017-11-15 15:20     ` Sebastian Reichel
  0 siblings, 0 replies; 114+ messages in thread
From: Sebastian Reichel @ 2017-11-15 15:20 UTC (permalink / raw)
  To: Ladislav Michl
  Cc: linux-mtd, linux-omap, Roger Quadros, Tony Lindgren,
	Peter Ujfalusi, Boris Brezillon, Kyungmin Park

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

Hi,

On Sat, Nov 11, 2017 at 10:24:06PM +0100, Ladislav Michl wrote:
> Second commit in driver history (782b7a367d81: "[MTD] [OneNAND] OMAP3:
> add delay for GPIO") added quirk for waiting until GPIO line settle.
> As DMA was disabled for OMAP2 boards, chances are this problem was
> not OMAP3 specific and as it is just one register read, previous
> test for SoC type is approximately as expensive as read itself.
> Make delay unconditional, which allows removing SoC specific code
> alltogether.
> 
> Signed-off-by: Ladislav Michl <ladis@linux-mips.org>

Reviewed-by: Sebastian Reichel <sebastian.reichel@collabora.co.uk>

-- Sebastian

> ---
>  Changes:
>  -v3: new patch
>  -v4: none
> 
>  drivers/mtd/onenand/omap2.c | 7 ++-----
>  1 file changed, 2 insertions(+), 5 deletions(-)
> 
> diff --git a/drivers/mtd/onenand/omap2.c b/drivers/mtd/onenand/omap2.c
> index c9ff67100ef4..e4857a41760d 100644
> --- a/drivers/mtd/onenand/omap2.c
> +++ b/drivers/mtd/onenand/omap2.c
> @@ -57,7 +57,6 @@ struct omap2_onenand {
>  	struct dma_chan *dma_chan;
>  	int freq;
>  	int (*setup)(void __iomem *base, int *freq_ptr);
> -	u8 flags;
>  };
>  
>  static void omap2_onenand_dma_complete_func(void *completion)
> @@ -148,9 +147,8 @@ static int omap2_onenand_wait(struct mtd_info *mtd, int state)
>  		if (!(syscfg & ONENAND_SYS_CFG1_IOBE)) {
>  			syscfg |= ONENAND_SYS_CFG1_IOBE;
>  			write_reg(c, syscfg, ONENAND_REG_SYS_CFG1);
> -			if (c->flags & ONENAND_IN_OMAP34XX)
> -				/* Add a delay to let GPIO settle */
> -				syscfg = read_reg(c, ONENAND_REG_SYS_CFG1);
> +			/* Add a delay to let GPIO settle */
> +			syscfg = read_reg(c, ONENAND_REG_SYS_CFG1);
>  		}
>  
>  		reinit_completion(&c->irq_done);
> @@ -470,7 +468,6 @@ static int omap2_onenand_probe(struct platform_device *pdev)
>  
>  	init_completion(&c->irq_done);
>  	init_completion(&c->dma_done);
> -	c->flags = pdata->flags;
>  	c->gpmc_cs = pdata->cs;
>  	c->gpio_irq = pdata->gpio_irq;
>  	if (pdata->dma_channel < 0) {
> -- 
> 2.11.0
> 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-omap" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

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

* Re: [PATCH v4 12/16] mtd: onenand: omap2: Enable DMA by default
  2017-11-15 10:43         ` Roger Quadros
@ 2017-11-27 18:21           ` Ladislav Michl
  -1 siblings, 0 replies; 114+ messages in thread
From: Ladislav Michl @ 2017-11-27 18:21 UTC (permalink / raw)
  To: Roger Quadros
  Cc: Boris Brezillon, Tony Lindgren, Peter Ujfalusi, Kyungmin Park,
	linux-mtd, linux-omap

Hi,

On Wed, Nov 15, 2017 at 12:43:19PM +0200, Roger Quadros wrote:
> On 15/11/17 12:32, Ladislav Michl wrote:
> > On Wed, Nov 15, 2017 at 12:08:05PM +0200, Roger Quadros wrote:
> >> Hi,
> >>
> >> On 11/11/17 23:24, Ladislav Michl wrote:
> >>> @@ -529,15 +527,11 @@ static int omap2_onenand_probe(struct platform_device *pdev)
> >>>  		dma_cap_set(DMA_MEMCPY, mask);
> >>>  
> >>>  		c->dma_chan = dma_request_channel(mask, NULL, NULL);
> >>> -		if (!c->dma_chan)
> >>> -			dev_info(&pdev->dev,
> >>> -				 "failed to allocate DMA for OneNAND, "
> >>> -				 "using PIO instead\n");
> >>
> >> Why get rid of the print message? Instead we could choose to error out completely
> >> if a DMA channel was provided and we couldn't get it.
> > 
> > The point is that without pdata->dma_channel condition above, DMA is always
> > enabled and it seems too strict to me to fail, when driver can continue to work.
> 
> OK. fair enough.

Just FYI, tested 4.15-rc1 and got this:
[    0.168701] omap_hwmod: dma: no dt node
[    0.292968] omap_device: omap_dma_system: build failed (-22)
[    0.292968] omap2_system_dma_init_dev: Can't build omap_device for omap_dma_system:dma.
[    0.411590] onenand_check_lock_status: block = 2048, wp status = 0x2
[    0.777435] omap_hsmmc 4809c000.mmc: RX DMA channel request failed
[    0.787841] omap_hsmmc 4809c000.mmc: RX DMA channel request failed
[    4.959228] omap_hsmmc 4809c000.mmc: RX DMA channel request failed
[    5.077667] omap_hsmmc 4809c000.mmc: RX DMA channel request failed
[    5.187011] omap_hsmmc 4809c000.mmc: RX DMA channel request failed
[    5.288726] omap_hsmmc 4809c000.mmc: RX DMA channel request failed
[    5.426971] omap_hsmmc 4809c000.mmc: RX DMA channel request failed
[    5.987457] omap_hsmmc 4809c000.mmc: RX DMA channel request failed
[    6.098937] omap_hsmmc 4809c000.mmc: RX DMA channel request failed
[    6.243530] omap_hsmmc 4809c000.mmc: RX DMA channel request failed
[    6.311950] omap_hsmmc 4809c000.mmc: RX DMA channel request failed
[    6.355957] omap-sham 480c3000.sham: initialization failed.
[    6.397247] omap-aes 480c5000.aes: Unable to request in DMA channel
[    6.403869] omap-aes 480c5000.aes: initialization failed.
[    6.614807] omap-sham 480c3000.sham: initialization failed.
[    6.621551] omap-aes 480c5000.aes: Unable to request in DMA channel
[    6.628234] omap-aes 480c5000.aes: initialization failed.
[    6.793853] omap_hsmmc 4809c000.mmc: RX DMA channel request failed
[    7.176910] omap-sham 480c3000.sham: initialization failed.
[    7.183563] omap-aes 480c5000.aes: Unable to request in DMA channel
[    7.190246] omap-aes 480c5000.aes: initialization failed.
[    7.417022] omap_hsmmc 4809c000.mmc: RX DMA channel request failed
[    7.629211] omap-sham 480c3000.sham: initialization failed.
[    7.635986] omap-aes 480c5000.aes: Unable to request in DMA channel
[    7.642578] omap-aes 480c5000.aes: initialization failed.
[    7.854522] omap_hsmmc 4809c000.mmc: RX DMA channel request failed
[    7.938964] omap-sham 480c3000.sham: initialization failed.
[    7.945617] omap-aes 480c5000.aes: Unable to request in DMA channel
[    7.952331] omap-aes 480c5000.aes: initialization failed.
[    8.142791] omap_hsmmc 4809c000.mmc: RX DMA channel request failed

Above error seems to be caused by missing DT changes merged during -rc1
(Which DT related brokeness is allowed and which not is still mystery
to me).

Anyway, driver can deal with that pretty well:
omap2-onenand 30000000.onenand: initializing on CS0 (0x30000000), va e0080000, PIO mode
...and oprerates normally (unlike mmc, sound, etc.)

Best regards,
	ladis

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

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

* Re: [PATCH v4 12/16] mtd: onenand: omap2: Enable DMA by default
@ 2017-11-27 18:21           ` Ladislav Michl
  0 siblings, 0 replies; 114+ messages in thread
From: Ladislav Michl @ 2017-11-27 18:21 UTC (permalink / raw)
  To: Roger Quadros
  Cc: linux-mtd, linux-omap, Tony Lindgren, Peter Ujfalusi,
	Boris Brezillon, Kyungmin Park

Hi,

On Wed, Nov 15, 2017 at 12:43:19PM +0200, Roger Quadros wrote:
> On 15/11/17 12:32, Ladislav Michl wrote:
> > On Wed, Nov 15, 2017 at 12:08:05PM +0200, Roger Quadros wrote:
> >> Hi,
> >>
> >> On 11/11/17 23:24, Ladislav Michl wrote:
> >>> @@ -529,15 +527,11 @@ static int omap2_onenand_probe(struct platform_device *pdev)
> >>>  		dma_cap_set(DMA_MEMCPY, mask);
> >>>  
> >>>  		c->dma_chan = dma_request_channel(mask, NULL, NULL);
> >>> -		if (!c->dma_chan)
> >>> -			dev_info(&pdev->dev,
> >>> -				 "failed to allocate DMA for OneNAND, "
> >>> -				 "using PIO instead\n");
> >>
> >> Why get rid of the print message? Instead we could choose to error out completely
> >> if a DMA channel was provided and we couldn't get it.
> > 
> > The point is that without pdata->dma_channel condition above, DMA is always
> > enabled and it seems too strict to me to fail, when driver can continue to work.
> 
> OK. fair enough.

Just FYI, tested 4.15-rc1 and got this:
[    0.168701] omap_hwmod: dma: no dt node
[    0.292968] omap_device: omap_dma_system: build failed (-22)
[    0.292968] omap2_system_dma_init_dev: Can't build omap_device for omap_dma_system:dma.
[    0.411590] onenand_check_lock_status: block = 2048, wp status = 0x2
[    0.777435] omap_hsmmc 4809c000.mmc: RX DMA channel request failed
[    0.787841] omap_hsmmc 4809c000.mmc: RX DMA channel request failed
[    4.959228] omap_hsmmc 4809c000.mmc: RX DMA channel request failed
[    5.077667] omap_hsmmc 4809c000.mmc: RX DMA channel request failed
[    5.187011] omap_hsmmc 4809c000.mmc: RX DMA channel request failed
[    5.288726] omap_hsmmc 4809c000.mmc: RX DMA channel request failed
[    5.426971] omap_hsmmc 4809c000.mmc: RX DMA channel request failed
[    5.987457] omap_hsmmc 4809c000.mmc: RX DMA channel request failed
[    6.098937] omap_hsmmc 4809c000.mmc: RX DMA channel request failed
[    6.243530] omap_hsmmc 4809c000.mmc: RX DMA channel request failed
[    6.311950] omap_hsmmc 4809c000.mmc: RX DMA channel request failed
[    6.355957] omap-sham 480c3000.sham: initialization failed.
[    6.397247] omap-aes 480c5000.aes: Unable to request in DMA channel
[    6.403869] omap-aes 480c5000.aes: initialization failed.
[    6.614807] omap-sham 480c3000.sham: initialization failed.
[    6.621551] omap-aes 480c5000.aes: Unable to request in DMA channel
[    6.628234] omap-aes 480c5000.aes: initialization failed.
[    6.793853] omap_hsmmc 4809c000.mmc: RX DMA channel request failed
[    7.176910] omap-sham 480c3000.sham: initialization failed.
[    7.183563] omap-aes 480c5000.aes: Unable to request in DMA channel
[    7.190246] omap-aes 480c5000.aes: initialization failed.
[    7.417022] omap_hsmmc 4809c000.mmc: RX DMA channel request failed
[    7.629211] omap-sham 480c3000.sham: initialization failed.
[    7.635986] omap-aes 480c5000.aes: Unable to request in DMA channel
[    7.642578] omap-aes 480c5000.aes: initialization failed.
[    7.854522] omap_hsmmc 4809c000.mmc: RX DMA channel request failed
[    7.938964] omap-sham 480c3000.sham: initialization failed.
[    7.945617] omap-aes 480c5000.aes: Unable to request in DMA channel
[    7.952331] omap-aes 480c5000.aes: initialization failed.
[    8.142791] omap_hsmmc 4809c000.mmc: RX DMA channel request failed

Above error seems to be caused by missing DT changes merged during -rc1
(Which DT related brokeness is allowed and which not is still mystery
to me).

Anyway, driver can deal with that pretty well:
omap2-onenand 30000000.onenand: initializing on CS0 (0x30000000), va e0080000, PIO mode
...and oprerates normally (unlike mmc, sound, etc.)

Best regards,
	ladis

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

end of thread, other threads:[~2017-11-27 18:22 UTC | newest]

Thread overview: 114+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-11-11 21:12 [PATCH v4 00/16] OMAP2+ OneNAND driver update Ladislav Michl
2017-11-11 21:12 ` Ladislav Michl
2017-11-11 21:17 ` [PATCH v4 02/16] ARM: dts: OMAP2+: Add compatible property to onenand node Ladislav Michl
2017-11-11 21:17   ` Ladislav Michl
2017-11-14 15:11   ` Roger Quadros
2017-11-14 15:11     ` Roger Quadros
2017-11-14 23:01     ` Ladislav Michl
2017-11-14 23:01       ` Ladislav Michl
2017-11-14 21:39   ` Tony Lindgren
2017-11-14 21:39     ` Tony Lindgren
2017-11-11 21:18 ` [PATCH v4 03/16] ARM: dts: omap3-igep: Update onenand node timings Ladislav Michl
2017-11-11 21:18   ` Ladislav Michl
2017-11-14 15:12   ` Roger Quadros
2017-11-14 15:12     ` Roger Quadros
2017-11-14 21:39   ` Tony Lindgren
2017-11-14 21:39     ` Tony Lindgren
2017-11-11 21:19 ` [PATCH v4 04/16] mtd: onenand: omap2: Remove regulator support Ladislav Michl
2017-11-11 21:19   ` Ladislav Michl
2017-11-14 15:13   ` Roger Quadros
2017-11-14 15:13     ` Roger Quadros
2017-11-15 14:15   ` Sebastian Reichel
2017-11-15 14:15     ` Sebastian Reichel
2017-11-11 21:19 ` [PATCH v4 05/16] mtd: onenand: omap2: Remove skip initial unlocking support Ladislav Michl
2017-11-11 21:19   ` Ladislav Michl
2017-11-14 15:14   ` Roger Quadros
2017-11-14 15:14     ` Roger Quadros
2017-11-15 14:16   ` Sebastian Reichel
2017-11-15 14:16     ` Sebastian Reichel
2017-11-11 21:20 ` [PATCH v4 06/16] mtd: onenand: omap2: Remove partitioning support from platform data Ladislav Michl
2017-11-11 21:20   ` Ladislav Michl
2017-11-14 15:14   ` Roger Quadros
2017-11-14 15:14     ` Roger Quadros
2017-11-15 14:57   ` Sebastian Reichel
2017-11-15 14:57     ` Sebastian Reichel
2017-11-11 21:20 ` [PATCH v4 07/16] mtd: onenand: omap2: Account waiting time as waiting on IO Ladislav Michl
2017-11-11 21:20   ` Ladislav Michl
2017-11-14 15:18   ` Roger Quadros
2017-11-14 15:18     ` Roger Quadros
2017-11-15 15:00   ` Sebastian Reichel
2017-11-15 15:00     ` Sebastian Reichel
2017-11-11 21:21 ` [PATCH v4 08/16] mtd: onenand: omap2: Simplify the DMA setup for various paths Ladislav Michl
2017-11-11 21:21   ` Ladislav Michl
2017-11-15  8:35   ` Roger Quadros
2017-11-15  8:35     ` Roger Quadros
2017-11-15 15:05   ` Sebastian Reichel
2017-11-15 15:05     ` Sebastian Reichel
2017-11-11 21:22 ` [PATCH v4 09/16] mtd: onenand: omap2: Unify OMAP2 and OMAP3 DMA implementation Ladislav Michl
2017-11-11 21:22   ` Ladislav Michl
2017-11-15  8:38   ` Roger Quadros
2017-11-15  8:38     ` Roger Quadros
2017-11-15 15:07   ` Sebastian Reichel
2017-11-15 15:07     ` Sebastian Reichel
2017-11-11 21:23 ` [PATCH v4 10/16] mtd: onenand: omap2: Convert to use dmaengine for memcpy Ladislav Michl
2017-11-11 21:23   ` Ladislav Michl
2017-11-15  8:57   ` Roger Quadros
2017-11-15  8:57     ` Roger Quadros
2017-11-15  9:32     ` Ladislav Michl
2017-11-15  9:32       ` Ladislav Michl
2017-11-15 15:19   ` Sebastian Reichel
2017-11-15 15:19     ` Sebastian Reichel
2017-11-11 21:24 ` [PATCH v4 11/16] mtd: onenand: omap2: Do not make delay for GPIO OMAP3 specific Ladislav Michl
2017-11-11 21:24   ` Ladislav Michl
2017-11-15  9:31   ` Roger Quadros
2017-11-15  9:31     ` Roger Quadros
2017-11-15 15:20   ` Sebastian Reichel
2017-11-15 15:20     ` Sebastian Reichel
2017-11-11 21:24 ` [PATCH v4 12/16] mtd: onenand: omap2: Enable DMA by default Ladislav Michl
2017-11-11 21:24   ` Ladislav Michl
2017-11-15 10:08   ` Roger Quadros
2017-11-15 10:08     ` Roger Quadros
2017-11-15 10:32     ` Ladislav Michl
2017-11-15 10:32       ` Ladislav Michl
2017-11-15 10:43       ` Roger Quadros
2017-11-15 10:43         ` Roger Quadros
2017-11-27 18:21         ` Ladislav Michl
2017-11-27 18:21           ` Ladislav Michl
2017-11-15 10:44       ` Roger Quadros
2017-11-15 10:44         ` Roger Quadros
2017-11-11 21:26 ` [PATCH v4 13/16] memory: omap-gpmc: Refactor OneNAND support Ladislav Michl
2017-11-11 21:26   ` Ladislav Michl
2017-11-15 10:13   ` Roger Quadros
2017-11-15 10:13     ` Roger Quadros
2017-11-15 10:37     ` Ladislav Michl
2017-11-15 10:37       ` Ladislav Michl
2017-11-11 21:27 ` [PATCH v4 14/16] mtd: onenand: omap2: Configure driver from DT Ladislav Michl
2017-11-11 21:27   ` Ladislav Michl
2017-11-15 10:40   ` Roger Quadros
2017-11-15 10:40     ` Roger Quadros
2017-11-15 10:53     ` Ladislav Michl
2017-11-15 10:53       ` Ladislav Michl
2017-11-15 11:04       ` Roger Quadros
2017-11-15 11:04         ` Roger Quadros
2017-11-15 11:20         ` Ladislav Michl
2017-11-15 11:20           ` Ladislav Michl
2017-11-15 14:41           ` Roger Quadros
2017-11-15 14:41             ` Roger Quadros
2017-11-11 21:29 ` [PATCH v4 15/16] ARM: OMAP2+: Remove gpmc-onenand Ladislav Michl
2017-11-11 21:29   ` Ladislav Michl
2017-11-14 21:41   ` Tony Lindgren
2017-11-14 21:41     ` Tony Lindgren
2017-11-15 10:46   ` Roger Quadros
2017-11-15 10:46     ` Roger Quadros
2017-11-11 21:29 ` [PATCH v4 16/16] ARM: dts: Nokia: Use R/B pin Ladislav Michl
2017-11-11 21:29   ` Ladislav Michl
2017-11-14 21:42   ` Tony Lindgren
2017-11-14 21:42     ` Tony Lindgren
2017-11-14 22:46     ` Ladislav Michl
2017-11-14 22:46       ` Ladislav Michl
2017-11-14 21:48 ` [PATCH v4 00/16] OMAP2+ OneNAND driver update Tony Lindgren
2017-11-14 21:48   ` Tony Lindgren
2017-11-14 22:53   ` Ladislav Michl
2017-11-14 22:53     ` Ladislav Michl
2017-11-15  8:10 ` Peter Ujfalusi
2017-11-15  8:10   ` Peter Ujfalusi

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.