Skip to contentSkip to conversation

memory: omap-gpmc: mtd: nand: Support GPMC NAND on non-OMAP platforms

PATCH Superseded Roger Quadros 6 participants 56 messages Feb 19, 2016 – Mar 17, 2016

Subsystems (9)

v5 of 6 Superseded Latest is v6 →

lore
Share & tools
lore
#0 lore raw

v5 cover memory: omap-gpmc: mtd: nand: Support GPMC NAND on non-OMAP platforms

Hi,

@Tony
Patches 15 and 24 are new and will need your review.
I've modified patch 22 to include the new am335x boards introduced since v4.4.

Patches are based on top of omap-for-v4.6/dt so that the DT changes apply cleanly.

@Brian
If you can Ack the MTD related changes we can push the series (excluding DT patches) to an immutable branch and you can then pull it into l2-mtd.git

Patches tested on:
dra-evm, am437x-gp-evm, beagleboard-c4, beagleboard-c4-legacyboot

Changelog:
v5:
-changed ready/busy# GPIO DT binding from "ready-gpio" to "rb-gpios". -use irqdomain for gpmc NAND interrupts: fifoevent and termcount

v4:
-Warn if using older incompatible DT i.e. compatible property not present in nand node.
-Applied Tony's patch to fix broken ethernet on torpedo.

v3:
-Fixed and tested NAND using legacy boot on omap3-beagle. -Support rising and falling edge interrupts on WAITpins. -Update DT node of all gpmc users.

Patches summary:

We do a couple of things in this series which result in cleaner device tree implementation, faster perfomance and multi-platform support. As an added bonus we get to use the GPMC_WAIT pins as GPI/Interrupts.

- Establish a custom interface between NAND and GPMC driver. This is needed because all of the NAND registers sit in the GPMC register space.

- Clean up device tree support so that omap-gpmc IP and the omap2 NAND driver can be used on non-OMAP platforms. e.g. Keystone.

- Implement GPIOCHIP for the GPMC WAITPINS. SoCs can contain
2 to 4 of these and most of them would be unused otherwise. It also allows a cleaner implementation of NAND Ready pin status for the NAND driver.

- Implement GPMC IRQ domain to proivde the 2 NAND events and GPMC WAITPIN edge interrupts.

- Implement GPIOlib based NAND ready pin checking for OMAP NAND driver. On dra7-evm, Read speed increases from 13768 KiB/ to 17246 KiB/s. Write speed was unchanged at 7123 KiB/s.

This series is available at
[email protected]:rogerq/linux.git
in branch
for-v4.6/gpmc-v5

--
cheers,
-roger

Roger Quadros (26):
ARM: OMAP2+: gpmc: Add platform data
ARM: OMAP2+: gpmc: Add gpmc timings and settings to platform data
memory: omap-gpmc: Introduce GPMC to NAND interface
mtd: nand: omap2: Use gpmc_omap_get_nand_ops() to get NAND registers
memory: omap-gpmc: Add GPMC-NAND ops to get writebufferempty status
mtd: nand: omap2: Switch to using GPMC-NAND ops for writebuffer empty
check
memory: omap-gpmc: Implement IRQ domain for NAND IRQs
mtd: nand: omap: Copy platform data parameters to omap_nand_info data
mtd: nand: omap: Clean up device tree support
mtd: nand: omap: Update DT binding documentation
memory: omap-gpmc: Prevent mapping into 1st 16MB
memory: omap-gpmc: Move device tree binding to correct location
memory: omap-gpmc: Support general purpose input for WAITPINs
memory: omap-gpmc: Reserve WAITPIN if needed for WAIT monitoring
memory: omap-gpmc: Support WAIT pin edge interrupts
memory: omap-gpmc: Prevent GPMC_STATUS from being accessed via
gpmc_regs
mtd: nand: omap2: Implement NAND ready using gpiolib
ARM: dts: dra7: Fix NAND device nodes.
ARM: dts: dra7x-evm: Provide NAND ready pin
ARM: dts: am437x: Fix NAND device nodes
ARM: dts: am437x: Provide NAND ready pin
ARM: dts: am335x: Fix NAND device nodes
ARM: dts: am335x: Provide NAND ready pin
ARM: dts: dm814x: Fix gpmc and NAND node
ARM: dts: dm816x: Fix gpmc and NAND node
ARM: dts: omap3: Fix gpmc and NAND nodes

 Documentation/devicetree/bindings/bus/ti-gpmc.txt  | 130 ----
 .../bindings/memory-controllers/omap-gpmc.txt      | 141 +++++
 .../devicetree/bindings/mtd/gpmc-nand.txt          |  19 +-
 arch/arm/boot/dts/am335x-baltos-ir5221.dts         |  10 +-
 arch/arm/boot/dts/am335x-chilisom.dtsi             |   9 +-
 arch/arm/boot/dts/am335x-cm-t335.dts               |  10 +-
 arch/arm/boot/dts/am335x-evm.dts                   |   8 +-
 arch/arm/boot/dts/am335x-igep0033.dtsi             |   9 +-
 arch/arm/boot/dts/am335x-phycore-som.dtsi          |   9 +-
 arch/arm/boot/dts/am33xx.dtsi                      |   4 +
 arch/arm/boot/dts/am4372.dtsi                      |   4 +
 arch/arm/boot/dts/am437x-cm-t43.dts                |   7 +-
 arch/arm/boot/dts/am437x-gp-evm.dts                |   9 +-
 arch/arm/boot/dts/am43x-epos-evm.dts               |   9 +-
 arch/arm/boot/dts/dm8148-evm.dts                   |   8 +-
 arch/arm/boot/dts/dm814x.dtsi                      |   4 +
 arch/arm/boot/dts/dm8168-evm.dts                   |   8 +-
 arch/arm/boot/dts/dm816x.dtsi                      |   4 +
 arch/arm/boot/dts/dra62x-j5eco-evm.dts             |   8 +-
 arch/arm/boot/dts/dra7-evm.dts                     |   7 +-
 arch/arm/boot/dts/dra7.dtsi                        |   4 +
 arch/arm/boot/dts/dra72-evm.dts                    |   7 +-
 arch/arm/boot/dts/logicpd-torpedo-37xx-devkit.dts  |   3 +-
 arch/arm/boot/dts/logicpd-torpedo-som.dtsi         |   8 +-
 arch/arm/boot/dts/omap3-beagle.dts                 |   5 +-
 arch/arm/boot/dts/omap3-cm-t3x.dtsi                |   6 +-
 arch/arm/boot/dts/omap3-devkit8000-common.dtsi     |   4 +
 arch/arm/boot/dts/omap3-evm-37xx.dts               |   8 +-
 arch/arm/boot/dts/omap3-gta04.dtsi                 |   4 +
 arch/arm/boot/dts/omap3-igep.dtsi                  |   6 +-
 arch/arm/boot/dts/omap3-igep0020-common.dtsi       |   4 +-
 arch/arm/boot/dts/omap3-igep0030-common.dtsi       |   4 +
 arch/arm/boot/dts/omap3-ldp.dts                    |  10 +-
 arch/arm/boot/dts/omap3-lilly-a83x.dtsi            |   6 +-
 arch/arm/boot/dts/omap3-overo-base.dtsi            |   6 +-
 arch/arm/boot/dts/omap3-pandora-common.dtsi        |   4 +
 arch/arm/boot/dts/omap3-tao3530.dtsi               |   6 +-
 arch/arm/boot/dts/omap3.dtsi                       |   4 +
 arch/arm/boot/dts/omap3430-sdp.dts                 |   6 +-
 arch/arm/mach-omap2/gpmc-nand.c                    |   7 +-
 drivers/memory/Kconfig                             |   1 +
 drivers/memory/omap-gpmc.c                         | 653 +++++++++++++--------
 drivers/mtd/nand/omap2.c                           | 193 ++++--
 include/linux/omap-gpmc.h                          | 177 ++----
 include/linux/platform_data/gpmc-omap.h            | 167 ++++++
 include/linux/platform_data/mtd-nand-omap2.h       |  12 +-
 46 files changed, 1121 insertions(+), 611 deletions(-)
 delete mode 100644 Documentation/devicetree/bindings/bus/ti-gpmc.txt
 create mode 100644 Documentation/devicetree/bindings/memory-controllers/omap-gpmc.txt
 create mode 100644 include/linux/platform_data/gpmc-omap.h
Signature · 1 line
2.1.4
#1 lore raw

PATCH v5 1/26 ARM: OMAP2+: gpmc: Add platform data

Add a platform data structure for GPMC. It contains all the necessary platform information that needs to be passed from platform init code to GPMC driver.

---
 include/linux/omap-gpmc.h               |  3 +--
 include/linux/platform_data/gpmc-omap.h | 30 ++++++++++++++++++++++++++++++
 2 files changed, 31 insertions(+), 2 deletions(-)
 create mode 100644 include/linux/platform_data/gpmc-omap.h
include/linux/omap-gpmc.h +1 -2
index 7dee0014..5c79190 100644
@@ -7,8 +7,7 @@
  *  option) any later version.
  */
 
-/* Maximum Number of Chip Selects */
-#define GPMC_CS_NUM		8
+#include <linux/platform_data/gpmc-omap.h>
 
 #define GPMC_CONFIG_WP		0x00000005
 
include/linux/platform_data/gpmc-omap.h new file +30 -0
new file mode 100644
index 0000000..d32d9de
@@ -0,0 +1,30 @@
+/*
+ * OMAP GPMC Platform data
+ *
+ * Copyright (C) 2014 Texas Instruments, Inc. - http://www.ti.com
+ *	Roger Quadros <[email protected]>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ */
+
+#ifndef _GPMC_OMAP_H_
+#define _GPMC_OMAP_H_
+
+/* Maximum Number of Chip Selects */
+#define GPMC_CS_NUM		8
+
+/* Data for each chip select */
+struct gpmc_omap_cs_data {
+	bool valid;			/* data is valid */
+	bool is_nand;			/* device within this CS is NAND */
+	struct platform_device *pdev;	/* device within this CS region */
+	unsigned pdata_size;
+};
+
+struct gpmc_omap_platform_data {
+	struct gpmc_omap_cs_data cs[GPMC_CS_NUM];
+};
+
+#endif /* _GPMC_OMAP_H */
Signature · 6 lines
2.1.4


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

PATCH v5 2/26 ARM: OMAP2+: gpmc: Add gpmc timings and settings to platform data

In reply to Roger Quadros

Add device_timings, gpmc_timings and gpmc_setting to gpmc platform data.

---
 include/linux/omap-gpmc.h               | 134 -------------------------------
 include/linux/platform_data/gpmc-omap.h | 137 ++++++++++++++++++++++++++++++++
 2 files changed, 137 insertions(+), 134 deletions(-)
include/linux/omap-gpmc.h +0 -134
index 5c79190..2dcef1c 100644
@@ -14,140 +14,6 @@
 #define GPMC_IRQ_FIFOEVENTENABLE	0x01
 #define GPMC_IRQ_COUNT_EVENT		0x02
 
-#define GPMC_BURST_4			4	/* 4 word burst */
-#define GPMC_BURST_8			8	/* 8 word burst */
-#define GPMC_BURST_16			16	/* 16 word burst */
-#define GPMC_DEVWIDTH_8BIT		1	/* 8-bit device width */
-#define GPMC_DEVWIDTH_16BIT		2	/* 16-bit device width */
-#define GPMC_MUX_AAD			1	/* Addr-Addr-Data multiplex */
-#define GPMC_MUX_AD			2	/* Addr-Data multiplex */
-
-/* bool type time settings */
-struct gpmc_bool_timings {
-	bool cycle2cyclediffcsen;
-	bool cycle2cyclesamecsen;
-	bool we_extra_delay;
-	bool oe_extra_delay;
-	bool adv_extra_delay;
-	bool cs_extra_delay;
-	bool time_para_granularity;
-};
-
-/*
- * Note that all values in this struct are in nanoseconds except sync_clk
- * (which is in picoseconds), while the register values are in gpmc_fck cycles.
- */
-struct gpmc_timings {
-	/* Minimum clock period for synchronous mode (in picoseconds) */
-	u32 sync_clk;
-
-	/* Chip-select signal timings corresponding to GPMC_CS_CONFIG2 */
-	u32 cs_on;		/* Assertion time */
-	u32 cs_rd_off;		/* Read deassertion time */
-	u32 cs_wr_off;		/* Write deassertion time */
-
-	/* ADV signal timings corresponding to GPMC_CONFIG3 */
-	u32 adv_on;		/* Assertion time */
-	u32 adv_rd_off;		/* Read deassertion time */
-	u32 adv_wr_off;		/* Write deassertion time */
-
-	/* WE signals timings corresponding to GPMC_CONFIG4 */
-	u32 we_on;		/* WE assertion time */
-	u32 we_off;		/* WE deassertion time */
-
-	/* OE signals timings corresponding to GPMC_CONFIG4 */
-	u32 oe_on;		/* OE assertion time */
-	u32 oe_off;		/* OE deassertion time */
-
-	/* Access time and cycle time timings corresponding to GPMC_CONFIG5 */
-	u32 page_burst_access;	/* Multiple access word delay */
-	u32 access;		/* Start-cycle to first data valid delay */
-	u32 rd_cycle;		/* Total read cycle time */
-	u32 wr_cycle;		/* Total write cycle time */
-
-	u32 bus_turnaround;
-	u32 cycle2cycle_delay;
-
-	u32 wait_monitoring;
-	u32 clk_activation;
-
-	/* The following are only on OMAP3430 */
-	u32 wr_access;		/* WRACCESSTIME */
-	u32 wr_data_mux_bus;	/* WRDATAONADMUXBUS */
-
-	struct gpmc_bool_timings bool_timings;
-};
-
-/* Device timings in picoseconds */
-struct gpmc_device_timings {
-	u32 t_ceasu;	/* address setup to CS valid */
-	u32 t_avdasu;	/* address setup to ADV valid */
-	/* XXX: try to combine t_avdp_r & t_avdp_w. Issue is
-	 * of tusb using these timings even for sync whilst
-	 * ideally for adv_rd/(wr)_off it should have considered
-	 * t_avdh instead. This indirectly necessitates r/w
-	 * variations of t_avdp as it is possible to have one
-	 * sync & other async
-	 */
-	u32 t_avdp_r;	/* ADV low time (what about t_cer ?) */
-	u32 t_avdp_w;
-	u32 t_aavdh;	/* address hold time */
-	u32 t_oeasu;	/* address setup to OE valid */
-	u32 t_aa;	/* access time from ADV assertion */
-	u32 t_iaa;	/* initial access time */
-	u32 t_oe;	/* access time from OE assertion */
-	u32 t_ce;	/* access time from CS asertion */
-	u32 t_rd_cycle;	/* read cycle time */
-	u32 t_cez_r;	/* read CS deassertion to high Z */
-	u32 t_cez_w;	/* write CS deassertion to high Z */
-	u32 t_oez;	/* OE deassertion to high Z */
-	u32 t_weasu;	/* address setup to WE valid */
-	u32 t_wpl;	/* write assertion time */
-	u32 t_wph;	/* write deassertion time */
-	u32 t_wr_cycle;	/* write cycle time */
-
-	u32 clk;
-	u32 t_bacc;	/* burst access valid clock to output delay */
-	u32 t_ces;	/* CS setup time to clk */
-	u32 t_avds;	/* ADV setup time to clk */
-	u32 t_avdh;	/* ADV hold time from clk */
-	u32 t_ach;	/* address hold time from clk */
-	u32 t_rdyo;	/* clk to ready valid */
-
-	u32 t_ce_rdyz;	/* XXX: description ?, or use t_cez instead */
-	u32 t_ce_avd;	/* CS on to ADV on delay */
-
-	/* XXX: check the possibility of combining
-	 * cyc_aavhd_oe & cyc_aavdh_we
-	 */
-	u8 cyc_aavdh_oe;/* read address hold time in cycles */
-	u8 cyc_aavdh_we;/* write address hold time in cycles */
-	u8 cyc_oe;	/* access time from OE assertion in cycles */
-	u8 cyc_wpl;	/* write deassertion time in cycles */
-	u32 cyc_iaa;	/* initial access time in cycles */
-
-	/* extra delays */
-	bool ce_xdelay;
-	bool avd_xdelay;
-	bool oe_xdelay;
-	bool we_xdelay;
-};
-
-struct gpmc_settings {
-	bool burst_wrap;	/* enables wrap bursting */
-	bool burst_read;	/* enables read page/burst mode */
-	bool burst_write;	/* enables write page/burst mode */
-	bool device_nand;	/* device is NAND */
-	bool sync_read;		/* enables synchronous reads */
-	bool sync_write;	/* enables synchronous writes */
-	bool wait_on_read;	/* monitor wait on reads */
-	bool wait_on_write;	/* monitor wait on writes */
-	u32 burst_len;		/* page/burst length */
-	u32 device_width;	/* device bus width (8 or 16 bit) */
-	u32 mux_add_data;	/* multiplex address & data */
-	u32 wait_pin;		/* wait-pin to be used */
-};
-
 extern int gpmc_calc_timings(struct gpmc_timings *gpmc_t,
 			     struct gpmc_settings *gpmc_s,
 			     struct gpmc_device_timings *dev_t);
include/linux/platform_data/gpmc-omap.h +137 -0

147 lines not on this page · raw message

Signature · 6 lines
2.1.4


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

PATCH v5 3/26 memory: omap-gpmc: Introduce GPMC to NAND interface

In reply to Roger Quadros

The OMAP GPMC module has certain registers dedicated for NAND access and some NAND bits mixed with other GPMC functionality.

For the NAND dedicated registers we have the struct gpmc_nand_regs.

The NAND driver needs to access NAND specific bits from the following non-dedicated registers
1) FIFOEVENT and TERMCOUNT from GPMC_IRQENABLE and GPMC_IRQSTATUS
2) EMPTYWRITEBUFFERSTATUS from GPMC_STATUS

For accessing these bits we introduce the struct gpmc_nand_ops.

Rename the gpmc_update_nand_reg() API to gpmc_omap_get_nand_ops() and make it return the gpmc_nand_ops along with updating the gpmc_nand_regs. This API will be called by the OMAP NAND driver to access the necessary bits in GPMC register space.

---
 drivers/memory/omap-gpmc.c | 21 ++++++++++++++++++++
 include/linux/omap-gpmc.h  | 49 ++++++++++++++++++++++++++++++++++++++++++++--
 2 files changed, 68 insertions(+), 2 deletions(-)
drivers/memory/omap-gpmc.c +21 -0
index 6515dfc..c2f7320 100644
@@ -1098,6 +1098,27 @@ void gpmc_update_nand_reg(struct gpmc_nand_regs *reg, int cs)
 	}
 }
 
+static struct gpmc_nand_ops nand_ops;
+
+/**
+ * gpmc_omap_get_nand_ops - Get the GPMC NAND interface
+ * @regs: the GPMC NAND register map exclusive for NAND use.
+ * @cs: GPMC chip select number on which the NAND sits. The
+ *      register map returned will be specific to this chip select.
+ *
+ * Returns NULL on error e.g. invalid cs.
+ */
+struct gpmc_nand_ops *gpmc_omap_get_nand_ops(struct gpmc_nand_regs *reg, int cs)
+{
+	if (cs >= gpmc_cs_num)
+		return NULL;
+
+	gpmc_update_nand_reg(reg, cs);
+
+	return &nand_ops;
+}
+EXPORT_SYMBOL_GPL(gpmc_omap_get_nand_ops);
+
 int gpmc_get_client_irq(unsigned irq_config)
 {
 	int i;
include/linux/omap-gpmc.h +47 -2

61 lines not on this page · raw message

Signature · 6 lines
2.1.4


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

Re: [PATCH v5 03/26] memory: omap-gpmc: Introduce GPMC to NAND interface

Hi Roger,

Quoted 71 lines · Roger Quadros

The OMAP GPMC module has certain registers dedicated for NAND access and some NAND bits mixed with other GPMC functionality.

For the NAND dedicated registers we have the struct gpmc_nand_regs.

The NAND driver needs to access NAND specific bits from the following non-dedicated registers
1) FIFOEVENT and TERMCOUNT from GPMC_IRQENABLE and GPMC_IRQSTATUS
2) EMPTYWRITEBUFFERSTATUS from GPMC_STATUS

For accessing these bits we introduce the struct gpmc_nand_ops.

Rename the gpmc_update_nand_reg() API to gpmc_omap_get_nand_ops() and make it return the gpmc_nand_ops along with updating the gpmc_nand_regs. This API will be called by the OMAP NAND driver to access the necessary bits in GPMC register space.

---
 drivers/memory/omap-gpmc.c | 21 ++++++++++++++++++++
 include/linux/omap-gpmc.h  | 49 ++++++++++++++++++++++++++++++++++++++++++++--
 2 files changed, 68 insertions(+), 2 deletions(-)
drivers/memory/omap-gpmc.c +21 -0
index 6515dfc..c2f7320 100644
@@ -1098,6 +1098,27 @@ void gpmc_update_nand_reg(struct gpmc_nand_regs *reg, int cs)
 	}
 }
 
+static struct gpmc_nand_ops nand_ops;
+
+/**
+ * gpmc_omap_get_nand_ops - Get the GPMC NAND interface
+ * @regs: the GPMC NAND register map exclusive for NAND use.
+ * @cs: GPMC chip select number on which the NAND sits. The
+ *      register map returned will be specific to this chip select.
+ *
+ * Returns NULL on error e.g. invalid cs.
+ */
+struct gpmc_nand_ops *gpmc_omap_get_nand_ops(struct gpmc_nand_regs *reg, int cs)
+{
+	if (cs >= gpmc_cs_num)
+		return NULL;
+
+	gpmc_update_nand_reg(reg, cs);
+
+	return &nand_ops;
+}
+EXPORT_SYMBOL_GPL(gpmc_omap_get_nand_ops);
+
 int gpmc_get_client_irq(unsigned irq_config)
 {
 	int i;
include/linux/omap-gpmc.h +8 -0
index 2dcef1c..7de9f9b 100644
@@ -14,14 +14,59 @@
 #define GPMC_IRQ_FIFOEVENTENABLE	0x01
 #define GPMC_IRQ_COUNT_EVENT		0x02
 
+enum gpmc_nand_irq {
+	GPMC_NAND_IRQ_FIFOEVENT = 0,
+	GPMC_NAND_IRQ_TERMCOUNT,
+};
+
+/**
+ * gpmc_nand_ops - Interface between NAND and GPMC
+ * @nand_irq_enable: enable the requested GPMC NAND interrupt event.

include/linux/omap-gpmc.h line 34

Quoted 10 lines
include/linux/omap-gpmc.h +10 -0
+ * @nand_irq_disable: disable the requested GPMC NAND interrupt event.
+ * @nand_irq_clear: clears the GPMC NAND interrupt event status.
+ * @nand_irq_status: get the NAND interrupt event status.
+ * @nand_write_buffer_empty: get the NAND write buffer empty status.
+ */
+struct gpmc_nand_ops {
+	int (*nand_irq_enable)(enum gpmc_nand_irq irq);
+	int (*nand_irq_disable)(enum gpmc_nand_irq irq);
+	void (*nand_irq_clear)(enum gpmc_nand_irq irq);
+	u32 (*nand_irq_status)(void);

^^ These 4 aren't being used in this revision?

Quoted 15 lines
include/linux/omap-gpmc.h +15 -0
+	bool (*nand_writebuffer_empty)(void);
+};
+
+struct gpmc_nand_regs;
+
+#if IS_ENABLED(CONFIG_OMAP_GPMC)
+struct gpmc_nand_ops *gpmc_omap_get_nand_ops(struct gpmc_nand_regs *regs,
+					     int cs);
+#else
+static inline gpmc_nand_ops *gpmc_omap_get_nand_ops(struct gpmc_nand_regs *regs,
+						    int cs)
+{
+	return NULL;
+}
+#endif /* CONFIG_OMAP_GPMC */

include/linux/omap-gpmc.h line 59

Quoted 10 lines
include/linux/omap-gpmc.h +10 -0
+
+/*--------------------------------*/
+
+/* deprecated APIs */
+#if IS_ENABLED(CONFIG_OMAP_GPMC)
+void gpmc_update_nand_reg(struct gpmc_nand_regs *reg, int cs);
+#else
+static inline void gpmc_update_nand_reg(struct gpmc_nand_regs *reg, int cs)
+{
+	reg = NULL;

What are you trying to do here? 'reg' is local, so the assignment is pointless.

include/linux/omap-gpmc.h line 61

Quoted 2 lines
include/linux/omap-gpmc.h +2 -0
+}
+#endif /* CONFIG_OMAP_GPMC */

Brian

#5 lore raw

Re: [PATCH v5 03/26] memory: omap-gpmc: Introduce GPMC to NAND interface

Hi Brian,

Quoted 78 lines · Brian Norris

Hi Roger,

Quoted 75 lines · Roger Quadros

The OMAP GPMC module has certain registers dedicated for NAND access and some NAND bits mixed with other GPMC functionality.

For the NAND dedicated registers we have the struct gpmc_nand_regs.

The NAND driver needs to access NAND specific bits from the following non-dedicated registers
1) FIFOEVENT and TERMCOUNT from GPMC_IRQENABLE and GPMC_IRQSTATUS
2) EMPTYWRITEBUFFERSTATUS from GPMC_STATUS

For accessing these bits we introduce the struct gpmc_nand_ops.

Rename the gpmc_update_nand_reg() API to gpmc_omap_get_nand_ops() and make it return the gpmc_nand_ops along with updating the gpmc_nand_regs. This API will be called by the OMAP NAND driver to access the necessary bits in GPMC register space.

---
 drivers/memory/omap-gpmc.c | 21 ++++++++++++++++++++
 include/linux/omap-gpmc.h  | 49 ++++++++++++++++++++++++++++++++++++++++++++--
 2 files changed, 68 insertions(+), 2 deletions(-)
drivers/memory/omap-gpmc.c +21 -0
index 6515dfc..c2f7320 100644
@@ -1098,6 +1098,27 @@ void gpmc_update_nand_reg(struct gpmc_nand_regs *reg, int cs)
 	}
 }
 
+static struct gpmc_nand_ops nand_ops;
+
+/**
+ * gpmc_omap_get_nand_ops - Get the GPMC NAND interface
+ * @regs: the GPMC NAND register map exclusive for NAND use.
+ * @cs: GPMC chip select number on which the NAND sits. The
+ *      register map returned will be specific to this chip select.
+ *
+ * Returns NULL on error e.g. invalid cs.
+ */
+struct gpmc_nand_ops *gpmc_omap_get_nand_ops(struct gpmc_nand_regs *reg, int cs)
+{
+	if (cs >= gpmc_cs_num)
+		return NULL;
+
+	gpmc_update_nand_reg(reg, cs);
+
+	return &nand_ops;
+}
+EXPORT_SYMBOL_GPL(gpmc_omap_get_nand_ops);
+
 int gpmc_get_client_irq(unsigned irq_config)
 {
 	int i;
include/linux/omap-gpmc.h +12 -0
index 2dcef1c..7de9f9b 100644
@@ -14,14 +14,59 @@
 #define GPMC_IRQ_FIFOEVENTENABLE	0x01
 #define GPMC_IRQ_COUNT_EVENT		0x02
 
+enum gpmc_nand_irq {
+	GPMC_NAND_IRQ_FIFOEVENT = 0,
+	GPMC_NAND_IRQ_TERMCOUNT,
+};
+
+/**
+ * gpmc_nand_ops - Interface between NAND and GPMC
+ * @nand_irq_enable: enable the requested GPMC NAND interrupt event.
+ * @nand_irq_disable: disable the requested GPMC NAND interrupt event.
+ * @nand_irq_clear: clears the GPMC NAND interrupt event status.
+ * @nand_irq_status: get the NAND interrupt event status.
+ * @nand_write_buffer_empty: get the NAND write buffer empty status.
Quoted 8 lines

include/linux/omap-gpmc.h line 34

Quoted 6 lines
include/linux/omap-gpmc.h +6 -0
+ */
+struct gpmc_nand_ops {
+	int (*nand_irq_enable)(enum gpmc_nand_irq irq);
+	int (*nand_irq_disable)(enum gpmc_nand_irq irq);
+	void (*nand_irq_clear)(enum gpmc_nand_irq irq);
+	u32 (*nand_irq_status)(void);

^^ These 4 aren't being used in this revision?

Right. I'll remove them.

Quoted 21 lines
Quoted 21 lines
include/linux/omap-gpmc.h +20 -0
+	bool (*nand_writebuffer_empty)(void);
+};
+
+struct gpmc_nand_regs;
+
+#if IS_ENABLED(CONFIG_OMAP_GPMC)
+struct gpmc_nand_ops *gpmc_omap_get_nand_ops(struct gpmc_nand_regs *regs,
+					     int cs);
+#else
+static inline gpmc_nand_ops *gpmc_omap_get_nand_ops(struct gpmc_nand_regs *regs,
+						    int cs)
+{
+	return NULL;
+}
+#endif /* CONFIG_OMAP_GPMC */
+
+/*--------------------------------*/
+
+/* deprecated APIs */
+#if IS_ENABLED(CONFIG_OMAP_GPMC)
Quoted 8 lines

include/linux/omap-gpmc.h line 59

Quoted 5 lines
include/linux/omap-gpmc.h +5 -0
+void gpmc_update_nand_reg(struct gpmc_nand_regs *reg, int cs);
+#else
+static inline void gpmc_update_nand_reg(struct gpmc_nand_regs *reg, int cs)
+{
+	reg = NULL;

What are you trying to do here? 'reg' is local, so the assignment is pointless.

Indeed this is pointless. I'll remove this line.
I'll also add a patch in the end to get rid of this API as there are no more users to it.

Quoted 4 lines

include/linux/omap-gpmc.h line 61

Quoted 3 lines
include/linux/omap-gpmc.h +2 -0
+}
+#endif /* CONFIG_OMAP_GPMC */

cheers,
-roger
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html

#6 lore raw

PATCH v5 4/26 mtd: nand: omap2: Use gpmc_omap_get_nand_ops() to get NAND registers

In reply to Roger Quadros

Deprecate nand register passing via platform data and use gpmc_omap_get_nand_ops() instead.

---
 arch/arm/mach-omap2/gpmc-nand.c              | 2 --
 drivers/mtd/nand/omap2.c                     | 9 ++++++++-
 include/linux/platform_data/mtd-nand-omap2.h | 4 +++-
 3 files changed, 11 insertions(+), 4 deletions(-)
arch/arm/mach-omap2/gpmc-nand.c +0 -2
index 72918c4..04e6998 100644
@@ -121,8 +121,6 @@ int gpmc_nand_init(struct omap_nand_platform_data *gpmc_nand_data,
 	if (err < 0)
 		goto out_free_cs;
 
-	gpmc_update_nand_reg(&gpmc_nand_data->reg, gpmc_nand_data->cs);
-
 	if (!gpmc_hwecc_bch_capable(gpmc_nand_data->ecc_opt)) {
 		pr_err("omap2-nand: Unsupported NAND ECC scheme selected\n");
 		err = -EINVAL;
drivers/mtd/nand/omap2.c +8 -1
index c553f78..eb18c04 100644
@@ -28,6 +28,7 @@
 #include <linux/mtd/nand_bch.h>
 #include <linux/platform_data/elm.h>
 
+#include <linux/omap-gpmc.h>
 #include <linux/platform_data/mtd-nand-omap2.h>
 
 #define	DRIVER_NAME	"omap2-nand"
@@ -168,7 +169,9 @@ struct omap_nand_info {
 	} iomode;
 	u_char				*buf;
 	int					buf_len;
+	/* Interface to GPMC */
 	struct gpmc_nand_regs		reg;
+	struct gpmc_nand_ops		*ops;
 	/* generated at runtime depending on ECC algorithm and layout selected */
 	struct nand_ecclayout		oobinfo;
 	/* fields specific for BCHx_HW ECC scheme */
@@ -1665,9 +1668,13 @@ static int omap_nand_probe(struct platform_device *pdev)
 
 	platform_set_drvdata(pdev, info);
 
+	info->ops = gpmc_omap_get_nand_ops(&info->reg, info->gpmc_cs);
+	if (!info->ops) {
+		dev_err(&pdev->dev, "Failed to get GPMC->NAND interface\n");
+		return -ENODEV;
+	}
 	info->pdev		= pdev;
 	info->gpmc_cs		= pdata->cs;
-	info->reg		= pdata->reg;
 	info->of_node		= pdata->of_node;
 	info->ecc_opt		= pdata->ecc_opt;
 	nand_chip		= &info->nand;
include/linux/platform_data/mtd-nand-omap2.h +3 -1
index 090bbab..a067f58 100644
@@ -75,10 +75,12 @@ struct omap_nand_platform_data {
 	enum nand_io		xfer_type;
 	int			devsize;
 	enum omap_ecc           ecc_opt;
-	struct gpmc_nand_regs	reg;
 
 	/* for passing the partitions */
 	struct device_node	*of_node;
 	struct device_node	*elm_of_node;
+
+	/* deprecated */
+	struct gpmc_nand_regs	reg;
 };
 #endif
Signature · 6 lines
2.1.4


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

PATCH v5 5/26 memory: omap-gpmc: Add GPMC-NAND ops to get writebufferempty status

In reply to Roger Quadros

This is needed by OMAP NAND driver to poll the empty status of the writebuffer.

---
 drivers/memory/omap-gpmc.c | 14 +++++++++++++-
 1 file changed, 13 insertions(+), 1 deletion(-)
drivers/memory/omap-gpmc.c +13 -1
index c2f7320..695be32 100644
@@ -81,6 +81,8 @@
 
 #define GPMC_CONFIG_LIMITEDADDRESS		BIT(1)
 
+#define GPMC_STATUS_EMPTYWRITEBUFFERSTATUS	BIT(0)
+
 #define	GPMC_CONFIG2_CSEXTRADELAY		BIT(7)
 #define	GPMC_CONFIG3_ADVEXTRADELAY		BIT(7)
 #define	GPMC_CONFIG4_OEEXTRADELAY		BIT(7)
@@ -1098,7 +1100,17 @@ void gpmc_update_nand_reg(struct gpmc_nand_regs *reg, int cs)
 	}
 }
 
-static struct gpmc_nand_ops nand_ops;
+static bool gpmc_nand_writebuffer_empty(void)
+{
+	if (gpmc_read_reg(GPMC_STATUS) & GPMC_STATUS_EMPTYWRITEBUFFERSTATUS)
+		return true;
+
+	return false;
+}
+
+static struct gpmc_nand_ops nand_ops = {
+	.nand_writebuffer_empty = gpmc_nand_writebuffer_empty,
+};
 
 /**
  * gpmc_omap_get_nand_ops - Get the GPMC NAND interface
Signature · 6 lines
2.1.4


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

PATCH v5 6/26 mtd: nand: omap2: Switch to using GPMC-NAND ops for writebuffer empty check

In reply to Roger Quadros

Instead of accessing the gpmc_status register directly start using the gpmc_nand_ops->nand_writebuffer_empty() helper to check write buffer empty status.

---
 drivers/mtd/nand/omap2.c | 10 ++++------
 1 file changed, 4 insertions(+), 6 deletions(-)
drivers/mtd/nand/omap2.c +4 -6
index eb18c04..088ff62 100644
@@ -291,14 +291,13 @@ static void omap_write_buf8(struct mtd_info *mtd, const u_char *buf, int len)
 {
 	struct omap_nand_info *info = mtd_to_omap(mtd);
 	u_char *p = (u_char *)buf;
-	u32	status = 0;
+	bool status;
 
 	while (len--) {
 		iowrite8(*p++, info->nand.IO_ADDR_W);
 		/* wait until buffer is available for write */
 		do {
-			status = readl(info->reg.gpmc_status) &
-					STATUS_BUFF_EMPTY;
+			status = info->ops->nand_writebuffer_empty();
 		} while (!status);
 	}
 }
@@ -326,7 +325,7 @@ static void omap_write_buf16(struct mtd_info *mtd, const u_char * buf, int len)
 {
 	struct omap_nand_info *info = mtd_to_omap(mtd);
 	u16 *p = (u16 *) buf;
-	u32	status = 0;
+	bool status;
 	/* FIXME try bursts of writesw() or DMA ... */
 	len >>= 1;
 
@@ -334,8 +333,7 @@ static void omap_write_buf16(struct mtd_info *mtd, const u_char * buf, int len)
 		iowrite16(*p++, info->nand.IO_ADDR_W);
 		/* wait until buffer is available for write */
 		do {
-			status = readl(info->reg.gpmc_status) &
-					STATUS_BUFF_EMPTY;
+			status = info->ops->nand_writebuffer_empty();
 		} while (!status);
 	}
 }
Signature · 1 line
2.1.4
#9 lore raw

PATCH v5 7/26 memory: omap-gpmc: Implement IRQ domain for NAND IRQs

In reply to Roger Quadros

GPMC provides 2 interrupts for NAND use. i.e. fifoevent and termcount. Use IRQ domain for this. NAND device tree node can then
get the necessary interrupts by using gpmc as the interrupt parent.

Legacy boot uses gpmc_get_client_irq to get the NAND interrupts from the GPMC IRQ domain.
Get rid of custom bitmasks and use IRQ domain for that as well.

---
 drivers/memory/omap-gpmc.c | 246 ++++++++++++++++++++++++---------------------
 include/linux/omap-gpmc.h  |   5 +-
 2 files changed, 136 insertions(+), 115 deletions(-)
drivers/memory/omap-gpmc.c +133 -113
index 695be32..d75f417 100644
@@ -22,6 +22,7 @@
 #include <linux/io.h>
 #include <linux/module.h>
 #include <linux/interrupt.h>
+#include <linux/irqdomain.h>
 #include <linux/platform_device.h>
 #include <linux/of.h>
 #include <linux/of_address.h>
@@ -127,7 +128,6 @@
 #define GPMC_CONFIG_RDY_BSY	0x00000001
 #define GPMC_CONFIG_DEV_SIZE	0x00000002
 #define GPMC_CONFIG_DEV_TYPE	0x00000003
-#define GPMC_SET_IRQ_STATUS	0x00000004
 
 #define GPMC_CONFIG1_WRAPBURST_SUPP     (1 << 31)
 #define GPMC_CONFIG1_READMULTIPLE_SUPP  (1 << 30)
@@ -176,8 +176,6 @@
 #define GPMC_CONFIG_WRITEPROTECT	0x00000010
 #define WR_RD_PIN_MONITORING		0x00600000
 
-#define GPMC_ENABLE_IRQ		0x0000000d
-
 /* ECC commands */
 #define GPMC_ECC_READ		0 /* Reset Hardware ECC for read */
 #define GPMC_ECC_WRITE		1 /* Reset Hardware ECC for write */
@@ -201,11 +199,6 @@ struct gpmc_cs_data {
 	struct resource mem;
 };
 
-struct gpmc_client_irq	{
-	unsigned		irq;
-	u32			bitmask;
-};
-
 /* Structure to save gpmc cs context */
 struct gpmc_cs_config {
 	u32 config1;
@@ -233,9 +226,13 @@ struct omap3_gpmc_regs {
 	struct gpmc_cs_config cs_context[GPMC_CS_NUM];
 };
 
-static struct gpmc_client_irq gpmc_client_irq[GPMC_NR_IRQ];
-static struct irq_chip gpmc_irq_chip;
-static int gpmc_irq_start;
+struct gpmc_device {
+	struct device *dev;
+	int irq;
+	struct irq_chip irq_chip;
+};
+
+static struct irq_domain *gpmc_irq_domain;
 
 static struct resource	gpmc_mem_root;
 static struct gpmc_cs_data gpmc_cs[GPMC_CS_NUM];
@@ -243,8 +240,6 @@ static DEFINE_SPINLOCK(gpmc_mem_lock);
 /* Define chip-selects as reserved by default until probe completes */
 static unsigned int gpmc_cs_num = GPMC_CS_NUM;
 static unsigned int gpmc_nr_waitpins;
-static struct device *gpmc_dev;
-static int gpmc_irq;
 static resource_size_t phys_base, mem_size;
 static unsigned gpmc_capability;
 static void __iomem *gpmc_base;
@@ -1036,14 +1031,6 @@ int gpmc_configure(int cmd, int wval)
 	u32 regval;
 
 	switch (cmd) {
-	case GPMC_ENABLE_IRQ:
-		gpmc_write_reg(GPMC_IRQENABLE, wval);
-		break;
-
-	case GPMC_SET_IRQ_STATUS:
-		gpmc_write_reg(GPMC_IRQSTATUS, wval);
-		break;
-
 	case GPMC_CONFIG_WP:
 		regval = gpmc_read_reg(GPMC_CONFIG);
 		if (wval)
@@ -1133,85 +1120,97 @@ EXPORT_SYMBOL_GPL(gpmc_omap_get_nand_ops);
 
 int gpmc_get_client_irq(unsigned irq_config)
 {
-	int i;
-
-	if (hweight32(irq_config) > 1)
+	if (!gpmc_irq_domain) {
+		pr_warn("%s called before GPMC IRQ domain available\n",
+		__func__);
 		return 0;
+	}
 
-	for (i = 0; i < GPMC_NR_IRQ; i++)
-		if (gpmc_client_irq[i].bitmask & irq_config)
-			return gpmc_client_irq[i].irq;
+	if (irq_config >= GPMC_NR_IRQ)
+		return 0;
 
-	return 0;
+	return irq_create_mapping(gpmc_irq_domain, irq_config);
 }
 
-static int gpmc_irq_endis(unsigned irq, bool endis)
+static int gpmc_irq_endis(unsigned long hwirq, bool endis)
 {
-	int i;
 	u32 regval;
 
-	for (i = 0; i < GPMC_NR_IRQ; i++)
-		if (irq == gpmc_client_irq[i].irq) {
-			regval = gpmc_read_reg(GPMC_IRQENABLE);
-			if (endis)
-				regval |= gpmc_client_irq[i].bitmask;
-			else
-				regval &= ~gpmc_client_irq[i].bitmask;
-			gpmc_write_reg(GPMC_IRQENABLE, regval);
-			break;
-		}
+	regval = gpmc_read_reg(GPMC_IRQENABLE);
+	if (endis)
+		regval |= BIT(hwirq);
+	else
+		regval &= ~BIT(hwirq);
+	gpmc_write_reg(GPMC_IRQENABLE, regval);
 
 	return 0;
 }
 
 static void gpmc_irq_disable(struct irq_data *p)
 {
-	gpmc_irq_endis(p->irq, false);
+	gpmc_irq_endis(p->hwirq, false);
 }
 
 static void gpmc_irq_enable(struct irq_data *p)
 {
-	gpmc_irq_endis(p->irq, true);
+	gpmc_irq_endis(p->hwirq, true);
 }
 
 static void gpmc_irq_noop(struct irq_data *data) { }
 
 static unsigned int gpmc_irq_noop_ret(struct irq_data *data) { return 0; }
 
-static int gpmc_setup_irq(void)
+static int gpmc_irq_map(struct irq_domain *d, unsigned int virq,
+			irq_hw_number_t hw)
 {
-	int i;
+	struct gpmc_device *gpmc = d->host_data;
+
+	irq_set_chip_data(virq, gpmc);
+	irq_set_chip_and_handler(virq, &gpmc->irq_chip, handle_simple_irq);
+	irq_modify_status(virq, IRQ_NOREQUEST, IRQ_NOAUTOEN);
+
+	return 0;
+}
+
+static const struct irq_domain_ops gpmc_irq_domain_ops = {
+	.map    = gpmc_irq_map,
+	.xlate  = irq_domain_xlate_twocell,
+};
+
+static irqreturn_t gpmc_handle_irq(int irq, void *data)
+{
+	int hwirq, virq;
 	u32 regval;
+	struct gpmc_device *gpmc = data;
 
-	if (!gpmc_irq)
-		return -EINVAL;
+	regval = gpmc_read_reg(GPMC_IRQSTATUS);
 
-	gpmc_irq_start = irq_alloc_descs(-1, 0, GPMC_NR_IRQ, 0);
-	if (gpmc_irq_start < 0) {
-		pr_err("irq_alloc_descs failed\n");
-		return gpmc_irq_start;
-	}
+	if (!regval)
+		return IRQ_NONE;
 
-	gpmc_irq_chip.name = "gpmc";
-	gpmc_irq_chip.irq_startup = gpmc_irq_noop_ret;
-	gpmc_irq_chip.irq_enable = gpmc_irq_enable;
-	gpmc_irq_chip.irq_disable = gpmc_irq_disable;
-	gpmc_irq_chip.irq_shutdown = gpmc_irq_noop;
-	gpmc_irq_chip.irq_ack = gpmc_irq_noop;
-	gpmc_irq_chip.irq_mask = gpmc_irq_noop;
-	gpmc_irq_chip.irq_unmask = gpmc_irq_noop;
-
-	gpmc_client_irq[0].bitmask = GPMC_IRQ_FIFOEVENTENABLE;
-	gpmc_client_irq[1].bitmask = GPMC_IRQ_COUNT_EVENT;
-
-	for (i = 0; i < GPMC_NR_IRQ; i++) {
-		gpmc_client_irq[i].irq = gpmc_irq_start + i;
-		irq_set_chip_and_handler(gpmc_client_irq[i].irq,
-					&gpmc_irq_chip, handle_simple_irq);
-		irq_modify_status(gpmc_client_irq[i].irq, IRQ_NOREQUEST,
-				  IRQ_NOAUTOEN);
+	for (hwirq = 0; hwirq < GPMC_NR_IRQ; hwirq++) {
+		if (regval & BIT(hwirq)) {
+			virq = irq_find_mapping(gpmc_irq_domain, hwirq);
+			if (!virq) {
+				dev_warn(gpmc->dev,
+					 "spurious irq detected hwirq %d, virq %d\n",
+					 hwirq, virq);
+			}
+
+			generic_handle_irq(virq);
+		}
 	}
 
+	gpmc_write_reg(GPMC_IRQSTATUS, regval);
+
+	return IRQ_HANDLED;
+}
+
+static int gpmc_setup_irq(struct gpmc_device *gpmc)
+{
+	u32 regval;
+	int rc;
+
 	/* Disable interrupts */
 	gpmc_write_reg(GPMC_IRQENABLE, 0);
 
@@ -1219,22 +1218,46 @@ static int gpmc_setup_irq(void)
 	regval = gpmc_read_reg(GPMC_IRQSTATUS);
 	gpmc_write_reg(GPMC_IRQSTATUS, regval);
 
-	return request_irq(gpmc_irq, gpmc_handle_irq, 0, "gpmc", NULL);
+	gpmc->irq_chip.name = "gpmc";
+	gpmc->irq_chip.irq_startup = gpmc_irq_noop_ret;
+	gpmc->irq_chip.irq_enable = gpmc_irq_enable;
+	gpmc->irq_chip.irq_disable = gpmc_irq_disable;
+	gpmc->irq_chip.irq_shutdown = gpmc_irq_noop;
+	gpmc->irq_chip.irq_ack = gpmc_irq_noop;
+	gpmc->irq_chip.irq_mask = gpmc_irq_noop;
+	gpmc->irq_chip.irq_unmask = gpmc_irq_noop;
+
+	gpmc_irq_domain = irq_domain_add_linear(gpmc->dev->of_node,
+						GPMC_NR_IRQ,
+						&gpmc_irq_domain_ops,
+						gpmc);
+	if (!gpmc_irq_domain) {
+		dev_err(gpmc->dev, "IRQ domain add failed\n");
+		return -ENODEV;
+	}
+
+	rc = request_irq(gpmc->irq, gpmc_handle_irq, 0, "gpmc", gpmc);
+	if (rc) {
+		dev_err(gpmc->dev, "failed to request irq %d: %d\n",
+			gpmc->irq, rc);
+		irq_domain_remove(gpmc_irq_domain);
+		gpmc_irq_domain = NULL;
+	}
+
+	return rc;
 }
 
-static int gpmc_free_irq(void)
+static int gpmc_free_irq(struct gpmc_device *gpmc)
 {
-	int i;
+	int hwirq;
 
-	if (gpmc_irq)
-		free_irq(gpmc_irq, NULL);
+	free_irq(gpmc->irq, gpmc);
 
-	for (i = 0; i < GPMC_NR_IRQ; i++) {
-		irq_set_handler(gpmc_client_irq[i].irq, NULL);
-		irq_set_chip(gpmc_client_irq[i].irq, &no_irq_chip);
-	}
+	for (hwirq = 0; hwirq < GPMC_NR_IRQ; hwirq++)
+		irq_dispose_mapping(irq_find_mapping(gpmc_irq_domain, hwirq));
 
-	irq_free_descs(gpmc_irq_start, GPMC_NR_IRQ);
+	irq_domain_remove(gpmc_irq_domain);
+	gpmc_irq_domain = NULL;
 
 	return 0;
 }
@@ -2124,6 +2147,14 @@ static int gpmc_probe(struct platform_device *pdev)
 	int rc;
 	u32 l;
 	struct resource *res;
+	struct gpmc_device *gpmc;
+
+	gpmc = devm_kzalloc(&pdev->dev, sizeof(*gpmc), GFP_KERNEL);
+	if (!gpmc)
+		return -ENOMEM;
+
+	gpmc->dev = &pdev->dev;
+	platform_set_drvdata(pdev, gpmc);
 
 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	if (res == NULL)
@@ -2137,15 +2168,16 @@ static int gpmc_probe(struct platform_device *pdev)
 		return PTR_ERR(gpmc_base);
 
 	res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
-	if (res == NULL)
-		dev_warn(&pdev->dev, "Failed to get resource: irq\n");
-	else
-		gpmc_irq = res->start;
+	if (!res) {
+		dev_err(&pdev->dev, "Failed to get resource: irq\n");
+		return -ENOENT;
+	}
+
+	gpmc->irq = res->start;
 
 	gpmc_l3_clk = devm_clk_get(&pdev->dev, "fck");
 	if (IS_ERR(gpmc_l3_clk)) {
 		dev_err(&pdev->dev, "Failed to get GPMC fck\n");
-		gpmc_irq = 0;
 		return PTR_ERR(gpmc_l3_clk);
 	}
 
@@ -2157,8 +2189,6 @@ static int gpmc_probe(struct platform_device *pdev)
 	pm_runtime_enable(&pdev->dev);
 	pm_runtime_get_sync(&pdev->dev);
 
-	gpmc_dev = &pdev->dev;
-
 	l = gpmc_read_reg(GPMC_REVISION);
 
 	/*
@@ -2177,13 +2207,16 @@ static int gpmc_probe(struct platform_device *pdev)
 		gpmc_capability = GPMC_HAS_WR_ACCESS | GPMC_HAS_WR_DATA_MUX_BUS;
 	if (GPMC_REVISION_MAJOR(l) > 0x5)
 		gpmc_capability |= GPMC_HAS_MUX_AAD;
-	dev_info(gpmc_dev, "GPMC revision %d.%d\n", GPMC_REVISION_MAJOR(l),
+	dev_info(gpmc->dev, "GPMC revision %d.%d\n", GPMC_REVISION_MAJOR(l),
 		 GPMC_REVISION_MINOR(l));
 
 	gpmc_mem_init();
 
-	if (gpmc_setup_irq() < 0)
-		dev_warn(gpmc_dev, "gpmc_setup_irq failed\n");
+	rc = gpmc_setup_irq(gpmc);
+	if (rc) {
+		dev_err(gpmc->dev, "gpmc_setup_irq failed\n");
+		goto fail;
+	}
 
 	if (!pdev->dev.of_node) {
 		gpmc_cs_num	 = GPMC_CS_NUM;
@@ -2192,21 +2225,27 @@ static int gpmc_probe(struct platform_device *pdev)
 
 	rc = gpmc_probe_dt(pdev);
 	if (rc < 0) {
-		pm_runtime_put_sync(&pdev->dev);
-		dev_err(gpmc_dev, "failed to probe DT parameters\n");
-		return rc;
+		dev_err(gpmc->dev, "failed to probe DT parameters\n");
+		gpmc_free_irq(gpmc);
+		goto fail;
 	}
 
 	return 0;
+
+fail:
+	pm_runtime_put_sync(&pdev->dev);
+	return rc;
 }
 
 static int gpmc_remove(struct platform_device *pdev)
 {
-	gpmc_free_irq();
+	struct gpmc_device *gpmc = platform_get_drvdata(pdev);
+
+	gpmc_free_irq(gpmc);
 	gpmc_mem_exit();
 	pm_runtime_put_sync(&pdev->dev);
 	pm_runtime_disable(&pdev->dev);
-	gpmc_dev = NULL;
+
 	return 0;
 }
 
@@ -2252,25 +2291,6 @@ static __exit void gpmc_exit(void)
 postcore_initcall(gpmc_init);
 module_exit(gpmc_exit);
 
-static irqreturn_t gpmc_handle_irq(int irq, void *dev)
-{
-	int i;
-	u32 regval;
-
-	regval = gpmc_read_reg(GPMC_IRQSTATUS);
-
-	if (!regval)
-		return IRQ_NONE;
-
-	for (i = 0; i < GPMC_NR_IRQ; i++)
-		if (regval & gpmc_client_irq[i].bitmask)
-			generic_handle_irq(gpmc_client_irq[i].irq);
-
-	gpmc_write_reg(GPMC_IRQSTATUS, regval);
-
-	return IRQ_HANDLED;
-}
-
 static struct omap3_gpmc_regs gpmc_context;
 
 void omap3_gpmc_save_context(void)
include/linux/omap-gpmc.h +3 -2
index 7de9f9b..f660e17 100644
@@ -11,8 +11,9 @@
 
 #define GPMC_CONFIG_WP		0x00000005
 
-#define GPMC_IRQ_FIFOEVENTENABLE	0x01
-#define GPMC_IRQ_COUNT_EVENT		0x02
+/* IRQ numbers in GPMC IRQ domain for legacy boot use */
+#define GPMC_IRQ_FIFOEVENTENABLE	0
+#define GPMC_IRQ_COUNT_EVENT		1
 
 enum gpmc_nand_irq {
 	GPMC_NAND_IRQ_FIFOEVENT = 0,
Signature · 6 lines
2.1.4


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

PATCH v5 8/26 mtd: nand: omap: Copy platform data parameters to omap_nand_info data

In reply to Roger Quadros

Copy all the platform data parameters to the driver's local data structure 'omap_nand_info' and use it in the entire driver. This will make it easer for device tree migration.

---
 drivers/mtd/nand/omap2.c | 26 ++++++++++++++++++--------
 1 file changed, 18 insertions(+), 8 deletions(-)
drivers/mtd/nand/omap2.c +18 -8
index 088ff62..9e99199 100644
@@ -152,13 +152,17 @@ static struct nand_hw_control omap_gpmc_controller = {
 };
 
 struct omap_nand_info {
-	struct omap_nand_platform_data	*pdata;
 	struct nand_chip		nand;
 	struct platform_device		*pdev;
 
 	int				gpmc_cs;
-	unsigned long			phys_base;
+	bool				dev_ready;
+	enum nand_io			xfer_type;
+	int				devsize;
 	enum omap_ecc			ecc_opt;
+	struct device_node		*elm_of_node;
+
+	unsigned long			phys_base;
 	struct completion		comp;
 	struct dma_chan			*dma;
 	int				gpmc_irq_fifo;
@@ -1631,7 +1635,7 @@ static bool omap2_nand_ecc_check(struct omap_nand_info *info,
 			"CONFIG_MTD_NAND_OMAP_BCH not enabled\n");
 		return false;
 	}
-	if (ecc_needs_elm && !is_elm_present(info, pdata->elm_of_node)) {
+	if (ecc_needs_elm && !is_elm_present(info, info->elm_of_node)) {
 		dev_err(&info->pdev->dev, "ELM not available\n");
 		return false;
 	}
@@ -1675,6 +1679,11 @@ static int omap_nand_probe(struct platform_device *pdev)
 	info->gpmc_cs		= pdata->cs;
 	info->of_node		= pdata->of_node;
 	info->ecc_opt		= pdata->ecc_opt;
+	info->dev_ready	= pdata->dev_ready;
+	info->xfer_type = pdata->xfer_type;
+	info->devsize = pdata->devsize;
+	info->elm_of_node = pdata->elm_of_node;
+
 	nand_chip		= &info->nand;
 	mtd			= nand_to_mtd(nand_chip);
 	mtd->dev.parent		= &pdev->dev;
@@ -1700,7 +1709,7 @@ static int omap_nand_probe(struct platform_device *pdev)
 	 * chip delay which is slightly more than tR (AC Timing) of the NAND
 	 * device and read status register until you get a failure or success
 	 */
-	if (pdata->dev_ready) {
+	if (info->dev_ready) {
 		nand_chip->dev_ready = omap_dev_ready;
 		nand_chip->chip_delay = 0;
 	} else {
@@ -1714,15 +1723,16 @@ static int omap_nand_probe(struct platform_device *pdev)
 		nand_chip->options |= NAND_SKIP_BBTSCAN;
 
 	/* scan NAND device connected to chip controller */
-	nand_chip->options |= pdata->devsize & NAND_BUSWIDTH_16;
+	nand_chip->options |= info->devsize & NAND_BUSWIDTH_16;
 	if (nand_scan_ident(mtd, 1, NULL)) {
-		dev_err(&info->pdev->dev, "scan failed, may be bus-width mismatch\n");
+		dev_err(&info->pdev->dev,
+			"scan failed, may be bus-width mismatch\n");
 		err = -ENXIO;
 		goto return_error;
 	}
 
 	/* re-populate low-level callbacks based on xfer modes */
-	switch (pdata->xfer_type) {
+	switch (info->xfer_type) {
 	case NAND_OMAP_PREFETCH_POLLED:
 		nand_chip->read_buf   = omap_read_buf_pref;
 		nand_chip->write_buf  = omap_write_buf_pref;
@@ -1802,7 +1812,7 @@ static int omap_nand_probe(struct platform_device *pdev)
 
 	default:
 		dev_err(&pdev->dev,
-			"xfer_type(%d) not supported!\n", pdata->xfer_type);
+			"xfer_type(%d) not supported!\n", info->xfer_type);
 		err = -EINVAL;
 		goto return_error;
 	}
Signature · 6 lines
2.1.4


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

PATCH v5 9/26 mtd: nand: omap: Clean up device tree support

In reply to Roger Quadros

Move NAND specific device tree parsing to NAND driver.

The NAND controller node must have a compatible id, register space resource and interrupt resource.

---
 arch/arm/mach-omap2/gpmc-nand.c              |   5 +-
 drivers/memory/omap-gpmc.c                   | 143 +++++++--------------------
 drivers/mtd/nand/omap2.c                     | 133 +++++++++++++++++++++----
 include/linux/platform_data/mtd-nand-omap2.h |   3 +-
 4 files changed, 152 insertions(+), 132 deletions(-)
arch/arm/mach-omap2/gpmc-nand.c +1 -4
index 04e6998..f6ac027 100644
@@ -97,10 +97,7 @@ int gpmc_nand_init(struct omap_nand_platform_data *gpmc_nand_data,
 	gpmc_nand_res[2].start = gpmc_get_client_irq(GPMC_IRQ_COUNT_EVENT);
 
 	memset(&s, 0, sizeof(struct gpmc_settings));
-	if (gpmc_nand_data->of_node)
-		gpmc_read_settings_dt(gpmc_nand_data->of_node, &s);
-	else
-		gpmc_set_legacy(gpmc_nand_data, &s);
+	gpmc_set_legacy(gpmc_nand_data, &s);
 
 	s.device_nand = true;
 
drivers/memory/omap-gpmc.c +37 -106

167 lines not on this page · raw message

drivers/mtd/nand/omap2.c +113 -20

203 lines not on this page · raw message

include/linux/platform_data/mtd-nand-omap2.h +1 -2
index a067f58..ff27e5a 100644
@@ -76,11 +76,10 @@ struct omap_nand_platform_data {
 	int			devsize;
 	enum omap_ecc           ecc_opt;
 
-	/* for passing the partitions */
-	struct device_node	*of_node;
 	struct device_node	*elm_of_node;
 
 	/* deprecated */
 	struct gpmc_nand_regs	reg;
+	struct device_node	*of_node;
 };
 #endif
Signature · 6 lines
2.1.4


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

Re: [PATCH v5 09/26] mtd: nand: omap: Clean up device tree support

A couple of sparse warnings.

Quoted 17 lines · Roger Quadros

Move NAND specific device tree parsing to NAND driver.

The NAND controller node must have a compatible id, register space resource and interrupt resource.

---
 arch/arm/mach-omap2/gpmc-nand.c              |   5 +-
 drivers/memory/omap-gpmc.c                   | 143 +++++++--------------------
 drivers/mtd/nand/omap2.c                     | 133 +++++++++++++++++++++----
 include/linux/platform_data/mtd-nand-omap2.h |   3 +-
 4 files changed, 152 insertions(+), 132 deletions(-)
arch/arm/mach-omap2/gpmc-nand.c +0 -0
index 04e6998..f6ac027 100644

[...]

arch/arm/mach-omap2/gpmc-nand.c static int gpmc_probe_generic_child(struct platform_device *pdev, · line 1944

Quoted 10 lines
arch/arm/mach-omap2/gpmc-nand.c +3 -3
@@ -2039,9 +1939,42 @@ static int gpmc_probe_generic_child(struct platform_device *pdev,
 		goto err;
 	}
 
-	ret = of_property_read_u32(child, "bank-width", &gpmc_s.device_width);
-	if (ret < 0)
-		goto err;
+	if (of_node_cmp(child->name, "nand") == 0) {
+		/* NAND specific setup */
+		u32 val;

drivers/memory/omap-gpmc.c:1952:13: originally declared here [sparse] drivers/memory/omap-gpmc.c:2029:21: warning: symbol 'val' shadows an earlier one [sparse]

Quoted 9 lines
arch/arm/mach-omap2/gpmc-nand.c +9 -0
+
+		/* Warn about older DT blobs with no compatible property */
+		if (!of_property_read_bool(child, "compatible")) {
+			dev_warn(&pdev->dev,
+				 "Incompatible NAND node: missing compatible");
+			ret = -EINVAL;
+			goto err;
+		}
+

[...]

Quoted 4 lines
drivers/mtd/nand/omap2.c +0 -0
index 9e99199..0a637c4 100644

[...]

drivers/mtd/nand/omap2.c static bool omap2_nand_ecc_check(struct omap_nand_info *info, · line 1662

Quoted 8 lines
drivers/mtd/nand/omap2.c +8 -0
+static int omap_get_dt_info(struct device *dev, struct omap_nand_info *info)
+{
+	struct device_node *child = dev->of_node;
+	int i;
+	const char *s;
+
+	/* In old bindings, CS num is embedded in reg property */
+	if (of_property_read_u32(child, "reg", &info->gpmc_cs) < 0) {

Sparse doesn't like this one:

drivers/mtd/nand/omap2.c:1660:49: warning: incorrect type in argument 3 (different signedness) [sparse]
drivers/mtd/nand/omap2.c:1660:49: expected unsigned int [usertype] *out_value [sparse]
drivers/mtd/nand/omap2.c:1660:49: got int *<noident> [sparse]

drivers/mtd/nand/omap2.c static bool omap2_nand_ecc_check(struct omap_nand_info *info, · line 1666

Quoted 4 lines
drivers/mtd/nand/omap2.c +4 -0
+		dev_err(dev, "reg not found in DT\n");
+		return -EINVAL;
+	}
+

[...]

Brian

#13 lore raw

Re: [PATCH v5 09/26] mtd: nand: omap: Clean up device tree support

Quoted 27 lines · Brian Norris

A couple of sparse warnings.

Quoted 17 lines · Roger Quadros

Move NAND specific device tree parsing to NAND driver.

The NAND controller node must have a compatible id, register space resource and interrupt resource.

---
 arch/arm/mach-omap2/gpmc-nand.c              |   5 +-
 drivers/memory/omap-gpmc.c                   | 143 +++++++--------------------
 drivers/mtd/nand/omap2.c                     | 133 +++++++++++++++++++++----
 include/linux/platform_data/mtd-nand-omap2.h |   3 +-
 4 files changed, 152 insertions(+), 132 deletions(-)
arch/arm/mach-omap2/gpmc-nand.c +0 -0
index 04e6998..f6ac027 100644

[...]

Quoted 4 lines
arch/arm/mach-omap2/gpmc-nand.c +0 -0
@@ -2039,9 +1939,42 @@ static int gpmc_probe_generic_child(struct platform_device *pdev,
 		goto err;
 	}
 
Quoted 9 lines

arch/arm/mach-omap2/gpmc-nand.c static int gpmc_probe_generic_child(struct platform_device *pdev, · line 1944

Quoted 6 lines
arch/arm/mach-omap2/gpmc-nand.c +3 -3
-	ret = of_property_read_u32(child, "bank-width", &gpmc_s.device_width);
-	if (ret < 0)
-		goto err;
+	if (of_node_cmp(child->name, "nand") == 0) {
+		/* NAND specific setup */
+		u32 val;

drivers/memory/omap-gpmc.c:1952:13: originally declared here [sparse] drivers/memory/omap-gpmc.c:2029:21: warning: symbol 'val' shadows an earlier one [sparse]

I'll get rid of this duplicate val.

Quoted 31 lines
Quoted 10 lines
arch/arm/mach-omap2/gpmc-nand.c +9 -0
+
+		/* Warn about older DT blobs with no compatible property */
+		if (!of_property_read_bool(child, "compatible")) {
+			dev_warn(&pdev->dev,
+				 "Incompatible NAND node: missing compatible");
+			ret = -EINVAL;
+			goto err;
+		}
+

[...]

Quoted 4 lines
drivers/mtd/nand/omap2.c +0 -0
index 9e99199..0a637c4 100644

[...]

drivers/mtd/nand/omap2.c static bool omap2_nand_ecc_check(struct omap_nand_info *info, · line 1662

Quoted 8 lines
drivers/mtd/nand/omap2.c +8 -0
+static int omap_get_dt_info(struct device *dev, struct omap_nand_info *info)
+{
+	struct device_node *child = dev->of_node;
+	int i;
+	const char *s;
+
+	/* In old bindings, CS num is embedded in reg property */
+	if (of_property_read_u32(child, "reg", &info->gpmc_cs) < 0) {

Sparse doesn't like this one:

Quoted 3 lines

drivers/mtd/nand/omap2.c:1660:49: warning: incorrect type in argument 3 (different signedness) [sparse]
drivers/mtd/nand/omap2.c:1660:49: expected unsigned int [usertype] *out_value [sparse]
drivers/mtd/nand/omap2.c:1660:49: got int *<noident> [sparse]

I'll use a temporary unsigned int variable instead.

Quoted 8 lines
Quoted 5 lines
drivers/mtd/nand/omap2.c +4 -0
+		dev_err(dev, "reg not found in DT\n");
+		return -EINVAL;
+	}
+

[...]

cheers,
-roger
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html

#14 lore raw

Re: [PATCH v5 09/26] mtd: nand: omap: Clean up device tree support

In reply to Roger Quadros

Sorry, another small thing I noticed.

Quoted 7 lines · Roger Quadros

Move NAND specific device tree parsing to NAND driver.

The NAND controller node must have a compatible id, register space resource and interrupt resource.

---

[...]

Quoted 13 lines
drivers/mtd/nand/omap2.c +1 -0
index 9e99199..0a637c4 100644
@@ -24,6 +24,7 @@
 #include <linux/slab.h>
 #include <linux/of.h>
 #include <linux/of_device.h>
+#include <linux/of_mtd.h>
 
 #include <linux/mtd/nand_bch.h>
 #include <linux/platform_data/elm.h>

drivers/mtd/nand/omap2.c struct omap_nand_info { · line 180

Quoted 3 lines
drivers/mtd/nand/omap2.c +0 -0
@@ -177,10 +178,11 @@ struct omap_nand_info {
 	struct gpmc_nand_regs		reg;
 	struct gpmc_nand_ops		*ops;
 	/* generated at runtime depending on ECC algorithm and layout selected */

^^^ I don't think that comment describes the following line. You probably meant to delete this one?

drivers/mtd/nand/omap2.c struct omap_nand_info { · line 188

Quoted 9 lines
drivers/mtd/nand/omap2.c +2 -1
+	bool				flash_bbt;
+	/* generated at runtime depending on ECC algorithm and layout */
 	struct nand_ecclayout		oobinfo;
 	/* fields specific for BCHx_HW ECC scheme */
 	struct device			*elm_dev;
-	struct device_node		*of_node;
 };
 
 static inline struct omap_nand_info *mtd_to_omap(struct mtd_info *mtd)

[...]

Brian
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html

#15 lore raw

Re: [PATCH v5 09/26] mtd: nand: omap: Clean up device tree support

Quoted 22 lines · Brian Norris

Sorry, another small thing I noticed.

Quoted 7 lines · Roger Quadros

Move NAND specific device tree parsing to NAND driver.

The NAND controller node must have a compatible id, register space resource and interrupt resource.

---

[...]

Quoted 10 lines
drivers/mtd/nand/omap2.c +1 -0
index 9e99199..0a637c4 100644
@@ -24,6 +24,7 @@
 #include <linux/slab.h>
 #include <linux/of.h>
 #include <linux/of_device.h>
+#include <linux/of_mtd.h>
 
Quoted 9 lines

drivers/mtd/nand/omap2.c struct omap_nand_info { · line 180

Quoted 6 lines
drivers/mtd/nand/omap2.c +0 -0
 #include <linux/mtd/nand_bch.h>
 #include <linux/platform_data/elm.h>
@@ -177,10 +178,11 @@ struct omap_nand_info {
 	struct gpmc_nand_regs		reg;
 	struct gpmc_nand_ops		*ops;
 	/* generated at runtime depending on ECC algorithm and layout selected */

^^^ I don't think that comment describes the following line. You probably meant to delete this one?

Yes. I'll remove that. Was my bad on cherry-pick conflict resolution.

Quoted 9 lines
Quoted 9 lines
drivers/mtd/nand/omap2.c +2 -1
+	bool				flash_bbt;
+	/* generated at runtime depending on ECC algorithm and layout */
 	struct nand_ecclayout		oobinfo;
 	/* fields specific for BCHx_HW ECC scheme */
 	struct device			*elm_dev;
-	struct device_node		*of_node;
 };
 
Quoted 4 lines
Quoted 1 line
drivers/mtd/nand/omap2.c +0 -0
 static inline struct omap_nand_info *mtd_to_omap(struct mtd_info *mtd)

[...]

cheers,
-roger
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html

#16 lore raw

PATCH v5 10/26 mtd: nand: omap: Update DT binding documentation

In reply to Roger Quadros

Add compatible id and interrupts. The NAND interrupts are provided by the GPMC controller node.

---
 Documentation/devicetree/bindings/mtd/gpmc-nand.txt | 17 +++++++++++++----
 1 file changed, 13 insertions(+), 4 deletions(-)
Documentation/devicetree/bindings/mtd/gpmc-nand.txt +13 -4
index fb733c4..810b87b 100644
@@ -13,7 +13,11 @@ Documentation/devicetree/bindings/mtd/nand.txt
 
 Required properties:
 
- - reg:		The CS line the peripheral is connected to
+ - compatible:	"ti,omap2-nand"
+ - reg:		range id (CS number), base offset and length of the
+		NAND I/O space
+ - interrupt-parent: must point to gpmc node
+ - interrupts:	Two interrupt specifiers, one for fifoevent, one for termcount.
 
 Optional properties:
 
@@ -55,20 +59,25 @@ Example for an AM33xx board:
 	gpmc: gpmc@50000000 {
 		compatible = "ti,am3352-gpmc";
 		ti,hwmods = "gpmc";
-		reg = <0x50000000 0x1000000>;
+		reg = <0x50000000 0x36c>;
 		interrupts = <100>;
 		gpmc,num-cs = <8>;
 		gpmc,num-waitpins = <2>;
 		#address-cells = <2>;
 		#size-cells = <1>;
-		ranges = <0 0 0x08000000 0x2000>;	/* CS0: NAND */
+		ranges = <0 0 0x08000000 0x1000000>;	/* CS0 space, 16MB */
 		elm_id = <&elm>;
 
 		nand@0,0 {
-			reg = <0 0 0>; /* CS0, offset 0 */
+			compatible = "ti,omap2-nand";
+			reg = <0 0 4>;		/* CS0, offset 0, NAND I/O window 4 */
+			interrupt-parent = <&gpmc>;
+			interrupts = <0 IRQ_TYPE_NONE>, <1 IRQ_TYPE NONE>;
 			nand-bus-width = <16>;
 			ti,nand-ecc-opt = "bch8";
 			ti,nand-xfer-type = "polled";
+			interrupt-parent = <&gpmc>;
+			interrupts = <0>, <1>;
 
 			gpmc,sync-clk-ps = <0>;
 			gpmc,cs-on-ns = <0>;
Signature · 1 line
2.1.4
maintainer
#17 lore raw

Re: [PATCH v5 10/26] mtd: nand: omap: Update DT binding documentation

Quoted 2 lines · Roger Quadros

Add compatible id and interrupts. The NAND interrupts are provided by the GPMC controller node.

This doesn't look like a backwards compatible change.

Quoted 32 lines
---
 Documentation/devicetree/bindings/mtd/gpmc-nand.txt | 17 +++++++++++++----
 1 file changed, 13 insertions(+), 4 deletions(-)
Documentation/devicetree/bindings/mtd/gpmc-nand.txt +6 -2
index fb733c4..810b87b 100644
@@ -13,7 +13,11 @@ Documentation/devicetree/bindings/mtd/nand.txt
 
 Required properties:
 
- - reg:		The CS line the peripheral is connected to
+ - compatible:	"ti,omap2-nand"
+ - reg:		range id (CS number), base offset and length of the
+		NAND I/O space
+ - interrupt-parent: must point to gpmc node
+ - interrupts:	Two interrupt specifiers, one for fifoevent, one for termcount.
 
 Optional properties:
 
@@ -55,20 +59,25 @@ Example for an AM33xx board:
 	gpmc: gpmc@50000000 {
 		compatible = "ti,am3352-gpmc";
 		ti,hwmods = "gpmc";
-		reg = <0x50000000 0x1000000>;
+		reg = <0x50000000 0x36c>;
 		interrupts = <100>;
 		gpmc,num-cs = <8>;
 		gpmc,num-waitpins = <2>;
 		#address-cells = <2>;

Documentation/devicetree/bindings/mtd/gpmc-nand.txt Example for an AM33xx board: · line 74

Quoted 10 lines
Documentation/devicetree/bindings/mtd/gpmc-nand.txt +4 -2
 		#size-cells = <1>;
-		ranges = <0 0 0x08000000 0x2000>;	/* CS0: NAND */
+		ranges = <0 0 0x08000000 0x1000000>;	/* CS0 space, 16MB */
 		elm_id = <&elm>;
 
 		nand@0,0 {
-			reg = <0 0 0>; /* CS0, offset 0 */
+			compatible = "ti,omap2-nand";
+			reg = <0 0 4>;		/* CS0, offset 0, NAND I/O window 4 */
+			interrupt-parent = <&gpmc>;

gpmc also needs an interrupt-controller property.

Documentation/devicetree/bindings/mtd/gpmc-nand.txt Example for an AM33xx board: · line 80

Quoted 6 lines
Documentation/devicetree/bindings/mtd/gpmc-nand.txt +3 -0
+			interrupts = <0 IRQ_TYPE_NONE>, <1 IRQ_TYPE NONE>;
 			nand-bus-width = <16>;
 			ti,nand-ecc-opt = "bch8";
 			ti,nand-xfer-type = "polled";
+			interrupt-parent = <&gpmc>;
+			interrupts = <0>, <1>;

Twice?

Quoted 10 lines
Documentation/devicetree/bindings/mtd/gpmc-nand.txt +0 -0
 			gpmc,sync-clk-ps = <0>;
 			gpmc,cs-on-ns = <0>;
Signature · 6 lines
2.1.4

--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
#18 lore raw

Re: [PATCH v5 10/26] mtd: nand: omap: Update DT binding documentation

Quoted 5 lines · Rob Herring
Quoted 2 lines · Roger Quadros

Add compatible id and interrupts. The NAND interrupts are provided by the GPMC controller node.

This doesn't look like a backwards compatible change.

The existing OMAP NAND DT implementation doesn't even need a compatible id in its DT node and so we are not intending to keep it backward compatible.

We are placing a warning instead if we encounter an old style NAND node.

Quoted 39 lines
Quoted 39 lines
---
 Documentation/devicetree/bindings/mtd/gpmc-nand.txt | 17 +++++++++++++----
 1 file changed, 13 insertions(+), 4 deletions(-)
Documentation/devicetree/bindings/mtd/gpmc-nand.txt +7 -3
index fb733c4..810b87b 100644
@@ -13,7 +13,11 @@ Documentation/devicetree/bindings/mtd/nand.txt
 
 Required properties:
 
- - reg:		The CS line the peripheral is connected to
+ - compatible:	"ti,omap2-nand"
+ - reg:		range id (CS number), base offset and length of the
+		NAND I/O space
+ - interrupt-parent: must point to gpmc node
+ - interrupts:	Two interrupt specifiers, one for fifoevent, one for termcount.
 
 Optional properties:
 
@@ -55,20 +59,25 @@ Example for an AM33xx board:
 	gpmc: gpmc@50000000 {
 		compatible = "ti,am3352-gpmc";
 		ti,hwmods = "gpmc";
-		reg = <0x50000000 0x1000000>;
+		reg = <0x50000000 0x36c>;
 		interrupts = <100>;
 		gpmc,num-cs = <8>;
 		gpmc,num-waitpins = <2>;
 		#address-cells = <2>;
 		#size-cells = <1>;
-		ranges = <0 0 0x08000000 0x2000>;	/* CS0: NAND */
+		ranges = <0 0 0x08000000 0x1000000>;	/* CS0 space, 16MB */
 		elm_id = <&elm>;
 
Quoted 7 lines

Documentation/devicetree/bindings/mtd/gpmc-nand.txt Example for an AM33xx board: · line 74

Quoted 5 lines
Documentation/devicetree/bindings/mtd/gpmc-nand.txt +3 -1
 		nand@0,0 {
-			reg = <0 0 0>; /* CS0, offset 0 */
+			compatible = "ti,omap2-nand";
+			reg = <0 0 4>;		/* CS0, offset 0, NAND I/O window 4 */
+			interrupt-parent = <&gpmc>;

gpmc also needs an interrupt-controller property.

Yes. will fix.

Quoted 9 lines

Documentation/devicetree/bindings/mtd/gpmc-nand.txt Example for an AM33xx board: · line 80

Quoted 7 lines
Documentation/devicetree/bindings/mtd/gpmc-nand.txt +3 -0
+			interrupts = <0 IRQ_TYPE_NONE>, <1 IRQ_TYPE NONE>;
 			nand-bus-width = <16>;
 			ti,nand-ecc-opt = "bch8";
 			ti,nand-xfer-type = "polled";
+			interrupt-parent = <&gpmc>;
+			interrupts = <0>, <1>;

Twice?

oops. will remove this.

Quoted 7 lines
Quoted 7 lines
Documentation/devicetree/bindings/mtd/gpmc-nand.txt +0 -0
 			gpmc,sync-clk-ps = <0>;
 			gpmc,cs-on-ns = <0>;
Signature · 1 line
2.1.4

cheers,
-roger
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html

#19 lore raw

Re: [PATCH v5 10/26] mtd: nand: omap: Update DT binding documentation

In reply to Roger Quadros
Quoted 13 lines · Roger Quadros

Add compatible id and interrupts. The NAND interrupts are provided by the GPMC controller node.

---
 Documentation/devicetree/bindings/mtd/gpmc-nand.txt | 17 +++++++++++++----
 1 file changed, 13 insertions(+), 4 deletions(-)
Documentation/devicetree/bindings/mtd/gpmc-nand.txt +0 -0
index fb733c4..810b87b 100644

Documentation/devicetree/bindings/mtd/gpmc-nand.txt Documentation/devicetree/bindings/mtd/nand.txt · line 18

Quoted 7 lines
Documentation/devicetree/bindings/mtd/gpmc-nand.txt +3 -1
@@ -13,7 +13,11 @@ Documentation/devicetree/bindings/mtd/nand.txt
 
 Required properties:
 
- - reg:		The CS line the peripheral is connected to
+ - compatible:	"ti,omap2-nand"
+ - reg:		range id (CS number), base offset and length of the
+		NAND I/O space

Is it normal to mix types of addressing in a single 'reg' property? Is your code working for anything besides CS==0?

Brian

Quoted 37 lines
Documentation/devicetree/bindings/mtd/gpmc-nand.txt +10 -3
+ - interrupt-parent: must point to gpmc node
+ - interrupts:	Two interrupt specifiers, one for fifoevent, one for termcount.
 
 Optional properties:
 
@@ -55,20 +59,25 @@ Example for an AM33xx board:
 	gpmc: gpmc@50000000 {
 		compatible = "ti,am3352-gpmc";
 		ti,hwmods = "gpmc";
-		reg = <0x50000000 0x1000000>;
+		reg = <0x50000000 0x36c>;
 		interrupts = <100>;
 		gpmc,num-cs = <8>;
 		gpmc,num-waitpins = <2>;
 		#address-cells = <2>;
 		#size-cells = <1>;
-		ranges = <0 0 0x08000000 0x2000>;	/* CS0: NAND */
+		ranges = <0 0 0x08000000 0x1000000>;	/* CS0 space, 16MB */
 		elm_id = <&elm>;
 
 		nand@0,0 {
-			reg = <0 0 0>; /* CS0, offset 0 */
+			compatible = "ti,omap2-nand";
+			reg = <0 0 4>;		/* CS0, offset 0, NAND I/O window 4 */
+			interrupt-parent = <&gpmc>;
+			interrupts = <0 IRQ_TYPE_NONE>, <1 IRQ_TYPE NONE>;
 			nand-bus-width = <16>;
 			ti,nand-ecc-opt = "bch8";
 			ti,nand-xfer-type = "polled";
+			interrupt-parent = <&gpmc>;
+			interrupts = <0>, <1>;
 
 			gpmc,sync-clk-ps = <0>;
 			gpmc,cs-on-ns = <0>;
Signature · 1 line
2.1.4

--
To unsubscribe from this list: send the line "unsubscribe devicetree" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html

#20 lore raw

Re: [PATCH v5 10/26] mtd: nand: omap: Update DT binding documentation

Quoted 17 lines · Brian Norris
Quoted 16 lines · Roger Quadros

Add compatible id and interrupts. The NAND interrupts are provided by the GPMC controller node.

---
 Documentation/devicetree/bindings/mtd/gpmc-nand.txt | 17 +++++++++++++----
 1 file changed, 13 insertions(+), 4 deletions(-)
Documentation/devicetree/bindings/mtd/gpmc-nand.txt +0 -0
index fb733c4..810b87b 100644
@@ -13,7 +13,11 @@ Documentation/devicetree/bindings/mtd/nand.txt
 
 Required properties:
 
Quoted 7 lines

Documentation/devicetree/bindings/mtd/gpmc-nand.txt Documentation/devicetree/bindings/mtd/nand.txt · line 18

Quoted 4 lines
Documentation/devicetree/bindings/mtd/gpmc-nand.txt +3 -1
- - reg:		The CS line the peripheral is connected to
+ - compatible:	"ti,omap2-nand"
+ - reg:		range id (CS number), base offset and length of the
+		NAND I/O space

Is it normal to mix types of addressing in a single 'reg' property? Is your code working for anything besides CS==0?

Yes we're using non zero CS on different omap platforms.
I haven't changed the behaviour of the reg property in this series. Just updated the documentation.

I didn't understand what you meant by mixing type of addressing.

This usage is exactly as mentioned here
http://devicetree.org/Device_Tree_Usage#Ranges_.28Address_Translation.29

cheers,
-roger

Quoted 38 lines
Quoted 38 lines
Documentation/devicetree/bindings/mtd/gpmc-nand.txt +10 -3
+ - interrupt-parent: must point to gpmc node
+ - interrupts:	Two interrupt specifiers, one for fifoevent, one for termcount.
 
 Optional properties:
 
@@ -55,20 +59,25 @@ Example for an AM33xx board:
 	gpmc: gpmc@50000000 {
 		compatible = "ti,am3352-gpmc";
 		ti,hwmods = "gpmc";
-		reg = <0x50000000 0x1000000>;
+		reg = <0x50000000 0x36c>;
 		interrupts = <100>;
 		gpmc,num-cs = <8>;
 		gpmc,num-waitpins = <2>;
 		#address-cells = <2>;
 		#size-cells = <1>;
-		ranges = <0 0 0x08000000 0x2000>;	/* CS0: NAND */
+		ranges = <0 0 0x08000000 0x1000000>;	/* CS0 space, 16MB */
 		elm_id = <&elm>;
 
 		nand@0,0 {
-			reg = <0 0 0>; /* CS0, offset 0 */
+			compatible = "ti,omap2-nand";
+			reg = <0 0 4>;		/* CS0, offset 0, NAND I/O window 4 */
+			interrupt-parent = <&gpmc>;
+			interrupts = <0 IRQ_TYPE_NONE>, <1 IRQ_TYPE NONE>;
 			nand-bus-width = <16>;
 			ti,nand-ecc-opt = "bch8";
 			ti,nand-xfer-type = "polled";
+			interrupt-parent = <&gpmc>;
+			interrupts = <0>, <1>;
 
 			gpmc,sync-clk-ps = <0>;
 			gpmc,cs-on-ns = <0>;
Signature · 1 line
2.1.4
#21 lore raw

Re: [PATCH v5 10/26] mtd: nand: omap: Update DT binding documentation

Quoted 11 lines · Roger Quadros
Quoted 2 lines · Brian Norris

Is it normal to mix types of addressing in a single 'reg' property? Is your code working for anything besides CS==0?

Yes we're using non zero CS on different omap platforms.
I haven't changed the behaviour of the reg property in this series. Just updated the documentation.

I didn't understand what you meant by mixing type of addressing.

This usage is exactly as mentioned here
http://devicetree.org/Device_Tree_Usage#Ranges_.28Address_Translation.29

I think I was just misunderstanding the use of the reg, *-cells, and ranges properties here. Thanks for the pointer.

Brian
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html

#22 lore raw

PATCH v6 10/26 mtd: nand: omap: Update DT binding documentation

In reply to Roger Quadros

Add compatible id and interrupts. The NAND interrupts are provided by the GPMC controller node.

---
 Documentation/devicetree/bindings/mtd/gpmc-nand.txt | 17 +++++++++++++----
 1 file changed, 13 insertions(+), 4 deletions(-)
Documentation/devicetree/bindings/mtd/gpmc-nand.txt +13 -4
index fb733c4..ff3215d2 100644
@@ -13,7 +13,11 @@ Documentation/devicetree/bindings/mtd/nand.txt
 
 Required properties:
 
- - reg:		The CS line the peripheral is connected to
+ - compatible:	"ti,omap2-nand"
+ - reg:		range id (CS number), base offset and length of the
+		NAND I/O space
+ - interrupt-parent: must point to gpmc node
+ - interrupts:	Two interrupt specifiers, one for fifoevent, one for termcount.
 
 Optional properties:
 
@@ -55,17 +59,22 @@ Example for an AM33xx board:
 	gpmc: gpmc@50000000 {
 		compatible = "ti,am3352-gpmc";
 		ti,hwmods = "gpmc";
-		reg = <0x50000000 0x1000000>;
+		reg = <0x50000000 0x36c>;
 		interrupts = <100>;
 		gpmc,num-cs = <8>;
 		gpmc,num-waitpins = <2>;
 		#address-cells = <2>;
 		#size-cells = <1>;
-		ranges = <0 0 0x08000000 0x2000>;	/* CS0: NAND */
+		ranges = <0 0 0x08000000 0x1000000>;	/* CS0 space, 16MB */
 		elm_id = <&elm>;
+		interrupt-controller;
+		#interrupt-cells = <2>;
 
 		nand@0,0 {
-			reg = <0 0 0>; /* CS0, offset 0 */
+			compatible = "ti,omap2-nand";
+			reg = <0 0 4>;		/* CS0, offset 0, NAND I/O window 4 */
+			interrupt-parent = <&gpmc>;
+			interrupts = <0 IRQ_TYPE_NONE>, <1 IRQ_TYPE NONE>;
 			nand-bus-width = <16>;
 			ti,nand-ecc-opt = "bch8";
 			ti,nand-xfer-type = "polled";
Signature · 7 lines
2.5.0


--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
maintainer Acked-by on v6 10/26
#23 lore raw

Re: [PATCH v6 10/26] mtd: nand: omap: Update DT binding documentation

Quoted 7 lines · Roger Quadros

Add compatible id and interrupts. The NAND interrupts are provided by the GPMC controller node.

---
 Documentation/devicetree/bindings/mtd/gpmc-nand.txt | 17 +++++++++++++----
 1 file changed, 13 insertions(+), 4 deletions(-)

--
To unsubscribe from this list: send the line "unsubscribe devicetree" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html

#24 lore raw

PATCH v5 11/26 memory: omap-gpmc: Prevent mapping into 1st 16MB

In reply to Roger Quadros

We have been preventing mapping GPMC children in the first 1MB but really it has to be the first 16MB as the minimum GPMC partition size is 16MB.

Also print an error message if CS mapping fails due to DT requesting address outside the GPMC map.

---
 drivers/memory/omap-gpmc.c | 24 ++++++++++++++++++------
 1 file changed, 18 insertions(+), 6 deletions(-)
drivers/memory/omap-gpmc.c +18 -6
index 13b900e..6c8d85e 100644
@@ -94,6 +94,14 @@
 #define GPMC_CS_SIZE		0x30
 #define	GPMC_BCH_SIZE		0x10
 
+/*
+ * The first 1MB of GPMC address space is typically mapped to
+ * the internal ROM. Never allocate the first page, to
+ * facilitate bug detection; even if we didn't boot from ROM.
+ * As GPMC minimum partition size is 16MB we can only start from
+ * there.
+ */
+#define GPMC_MEM_START		0x1000000
 #define GPMC_MEM_END		0x3FFFFFFF
 
 #define GPMC_CHUNK_SHIFT	24		/* 16 MB */
@@ -1277,12 +1285,7 @@ static void gpmc_mem_init(void)
 {
 	int cs;
 
-	/*
-	 * The first 1MB of GPMC address space is typically mapped to
-	 * the internal ROM. Never allocate the first page, to
-	 * facilitate bug detection; even if we didn't boot from ROM.
-	 */
-	gpmc_mem_root.start = SZ_1M;
+	gpmc_mem_root.start = GPMC_MEM_START;
 	gpmc_mem_root.end = GPMC_MEM_END;
 
 	/* Reserve all regions that has been set up by bootloader */
@@ -1936,6 +1939,15 @@ static int gpmc_probe_generic_child(struct platform_device *pdev,
 	if (ret < 0) {
 		dev_err(&pdev->dev, "cannot remap GPMC CS %d to %pa\n",
 			cs, &res.start);
+		if (res.start < GPMC_MEM_START) {
+			dev_info(&pdev->dev,
+				 "GPMC CS %d start cannot be lesser than 0x%x\n",
+				 cs, GPMC_MEM_START);
+		} else if (res.end > GPMC_MEM_END) {
+			dev_info(&pdev->dev,
+				 "GPMC CS %d end cannot be greater than 0x%x\n",
+				 cs, GPMC_MEM_END);
+		}
 		goto err;
 	}
 
Signature · 1 line
2.1.4
#25 lore raw

PATCH v5 12/26 memory: omap-gpmc: Move device tree binding to correct location

In reply to Roger Quadros

omap-gpmc.c is a memory controller so move the binding to the right place.

---
 Documentation/devicetree/bindings/bus/ti-gpmc.txt  | 130 ---------------------
 .../bindings/memory-controllers/omap-gpmc.txt      | 130 +++++++++++++++++++++
 2 files changed, 130 insertions(+), 130 deletions(-)
 delete mode 100644 Documentation/devicetree/bindings/bus/ti-gpmc.txt
 create mode 100644 Documentation/devicetree/bindings/memory-controllers/omap-gpmc.txt
Documentation/devicetree/bindings/bus/ti-gpmc.txt deleted +0 -130
deleted file mode 100644
index 704be93..0000000
@@ -1,130 +0,0 @@
-Device tree bindings for OMAP general purpose memory controllers (GPMC)
-
-The actual devices are instantiated from the child nodes of a GPMC node.
-
-Required properties:
-
- - compatible:		Should be set to one of the following:
-
-			ti,omap2420-gpmc (omap2420)
-			ti,omap2430-gpmc (omap2430)
-			ti,omap3430-gpmc (omap3430 & omap3630)
-			ti,omap4430-gpmc (omap4430 & omap4460 & omap543x)
-			ti,am3352-gpmc   (am335x devices)
-
- - reg:			A resource specifier for the register space
-			(see the example below)
- - ti,hwmods:		Should be set to "ti,gpmc" until the DT transition is
-			completed.
- - #address-cells:	Must be set to 2 to allow memory address translation
- - #size-cells:		Must be set to 1 to allow CS address passing
- - gpmc,num-cs:		The maximum number of chip-select lines that controller
-			can support.
- - gpmc,num-waitpins:	The maximum number of wait pins that controller can
-			support.
- - ranges:		Must be set up to reflect the memory layout with four
-			integer values for each chip-select line in use:
-
-			   <cs-number> 0 <physical address of mapping> <size>
-
-			Currently, calculated values derived from the contents
-			of the per-CS register GPMC_CONFIG7 (as set up by the
-			bootloader) are used for the physical address decoding.
-			As this will change in the future, filling correct
-			values here is a requirement.
-
-Timing properties for child nodes. All are optional and default to 0.
-
- - gpmc,sync-clk-ps:	Minimum clock period for synchronous mode, in picoseconds
-
- Chip-select signal timings (in nanoseconds) corresponding to GPMC_CONFIG2:
- - gpmc,cs-on-ns:	Assertion time
- - gpmc,cs-rd-off-ns:	Read deassertion time
- - gpmc,cs-wr-off-ns:	Write deassertion time
-
- ADV signal timings (in nanoseconds) corresponding to GPMC_CONFIG3:
- - gpmc,adv-on-ns:	Assertion time
- - gpmc,adv-rd-off-ns:	Read deassertion time
- - gpmc,adv-wr-off-ns:	Write deassertion time
-
- WE signals timings (in nanoseconds) corresponding to GPMC_CONFIG4:
- - gpmc,we-on-ns	Assertion time
- - gpmc,we-off-ns:	Deassertion time
-
- OE signals timings (in nanoseconds) corresponding to GPMC_CONFIG4:
- - gpmc,oe-on-ns:	Assertion time
- - gpmc,oe-off-ns:	Deassertion time
-
- Access time and cycle time timings (in nanoseconds) corresponding to
- GPMC_CONFIG5:
- - gpmc,page-burst-access-ns: 	Multiple access word delay
- - gpmc,access-ns:		Start-cycle to first data valid delay
- - gpmc,rd-cycle-ns:		Total read cycle time
- - gpmc,wr-cycle-ns:		Total write cycle time
- - gpmc,bus-turnaround-ns:	Turn-around time between successive accesses
- - gpmc,cycle2cycle-delay-ns:	Delay between chip-select pulses
- - gpmc,clk-activation-ns: 	GPMC clock activation time
- - gpmc,wait-monitoring-ns:	Start of wait monitoring with regard to valid
-				data
-
-Boolean timing parameters. If property is present parameter enabled and
-disabled if omitted:
- - gpmc,adv-extra-delay:	ADV signal is delayed by half GPMC clock
- - gpmc,cs-extra-delay:		CS signal is delayed by half GPMC clock
- - gpmc,cycle2cycle-diffcsen:	Add "cycle2cycle-delay" between successive
-				accesses to a different CS
- - gpmc,cycle2cycle-samecsen:	Add "cycle2cycle-delay" between successive
-				accesses to the same CS
- - gpmc,oe-extra-delay:		OE signal is delayed by half GPMC clock
- - gpmc,we-extra-delay:		WE signal is delayed by half GPMC clock
- - gpmc,time-para-granularity:	Multiply all access times by 2
-
-The following are only applicable to OMAP3+ and AM335x:
- - gpmc,wr-access-ns:		In synchronous write mode, for single or
-				burst accesses, defines the number of
-				GPMC_FCLK cycles from start access time
-				to the GPMC_CLK rising edge used by the
-				memory device for the first data capture.
- - gpmc,wr-data-mux-bus-ns:	In address-data multiplex mode, specifies
-				the time when the first data is driven on
-				the address-data bus.
-
-GPMC chip-select settings properties for child nodes. All are optional.
-
-- gpmc,burst-length	Page/burst length. Must be 4, 8 or 16.
-- gpmc,burst-wrap	Enables wrap bursting
-- gpmc,burst-read	Enables read page/burst mode
-- gpmc,burst-write	Enables write page/burst mode
-- gpmc,device-width	Total width of device(s) connected to a GPMC
-			chip-select in bytes. The GPMC supports 8-bit
-			and 16-bit devices and so this property must be
-			1 or 2.
-- gpmc,mux-add-data	Address and data multiplexing configuration.
-			Valid values are 1 for address-address-data
-			multiplexing mode and 2 for address-data
-			multiplexing mode.
-- gpmc,sync-read	Enables synchronous read. Defaults to asynchronous
-			is this is not set.
-- gpmc,sync-write	Enables synchronous writes. Defaults to asynchronous
-			is this is not set.
-- gpmc,wait-pin		Wait-pin used by client. Must be less than
-			"gpmc,num-waitpins".
-- gpmc,wait-on-read	Enables wait monitoring on reads.
-- gpmc,wait-on-write	Enables wait monitoring on writes.
-
-Example for an AM33xx board:
-
-	gpmc: gpmc@50000000 {
-		compatible = "ti,am3352-gpmc";
-		ti,hwmods = "gpmc";
-		reg = <0x50000000 0x2000>;
-		interrupts = <100>;
-
-		gpmc,num-cs = <8>;
-		gpmc,num-waitpins = <2>;
-		#address-cells = <2>;
-		#size-cells = <1>;
-		ranges = <0 0 0x08000000 0x10000000>; /* CS0 @addr 0x8000000, size 0x10000000 */
-
-		/* child nodes go here */
-	};
Documentation/devicetree/bindings/memory-controllers/omap-gpmc.txt new file +130 -0

130 lines not on this page · raw message

Signature · 1 line
2.1.4
maintainer Acked-by on v5 12/26
#26 lore raw

Re: [PATCH v5 12/26] memory: omap-gpmc: Move device tree binding to correct location

Quoted 7 lines · Roger Quadros

omap-gpmc.c is a memory controller so move the binding to the right place.

---
 Documentation/devicetree/bindings/bus/ti-gpmc.txt  | 130 ---------------------
 .../bindings/memory-controllers/omap-gpmc.txt      | 130 +++++++++++++++++++++

am335x is not an OMAP, so wasn't ti-gpmc a better name?

Quoted 3 lines
 2 files changed, 130 insertions(+), 130 deletions(-)
 delete mode 100644 Documentation/devicetree/bindings/bus/ti-gpmc.txt
 create mode 100644 Documentation/devicetree/bindings/memory-controllers/omap-gpmc.txt

Next time, use the git format-patch -M option.

#27 lore raw

Re: [PATCH v5 12/26] memory: omap-gpmc: Move device tree binding to correct location

Quoted 10 lines · Rob Herring
Quoted 7 lines · Roger Quadros

omap-gpmc.c is a memory controller so move the binding to the right place.

---
 Documentation/devicetree/bindings/bus/ti-gpmc.txt  | 130 ---------------------
 .../bindings/memory-controllers/omap-gpmc.txt      | 130 +++++++++++++++++++++

am335x is not an OMAP, so wasn't ti-gpmc a better name?

The driver is named drivers/memory/omap-gpmc.c.

Quoted 6 lines
Quoted 4 lines
 2 files changed, 130 insertions(+), 130 deletions(-)
 delete mode 100644 Documentation/devicetree/bindings/bus/ti-gpmc.txt
 create mode 100644 Documentation/devicetree/bindings/memory-controllers/omap-gpmc.txt

Next time, use the git format-patch -M option.

Indeed.

Quoted 3 lines

Thanks.

cheers,
-roger

#28 lore raw

PATCH v5 13/26 memory: omap-gpmc: Support general purpose input for WAITPINs

In reply to Roger Quadros

OMAPs can have 2 to 4 WAITPINs that can be used as general purpose input if not used for memory wait state insertion.

The first user will be the OMAP NAND chip to get the NAND read/busy status using gpiolib.

---
 .../bindings/memory-controllers/omap-gpmc.txt      |   3 +
 drivers/memory/Kconfig                             |   1 +
 drivers/memory/omap-gpmc.c                         | 115 ++++++++++++++++++---
 3 files changed, 107 insertions(+), 12 deletions(-)
Documentation/devicetree/bindings/memory-controllers/omap-gpmc.txt +3 -0
index 704be93..8113a52 100644
@@ -32,6 +32,9 @@ Required properties:
 			bootloader) are used for the physical address decoding.
 			As this will change in the future, filling correct
 			values here is a requirement.
+ - gpio-controller:	The GPMC driver implements a GPIO controller for the
+			GPMC WAIT pins that can be used as general purpose inputs.
+			0 maps to GPMC_WAIT0 pin.
 
 Timing properties for child nodes. All are optional and default to 0.
 
drivers/memory/Kconfig +1 -0
index 6f31546..bca24c6 100644
@@ -51,6 +51,7 @@ config TI_EMIF
 
 config OMAP_GPMC
 	bool
+	select GPIOLIB
 	help
 	  This driver is for the General Purpose Memory Controller (GPMC)
 	  present on Texas Instruments SoCs (e.g. OMAP2+). GPMC allows
drivers/memory/omap-gpmc.c +103 -12

184 lines not on this page · raw message

Signature · 1 line
2.1.4
#29 lore raw

Re: [PATCH v5 13/26] memory: omap-gpmc: Support general purpose input for WAITPINs

Hi Roger,

Quoted 5 lines · On Fri, 19 Feb 2016 23:15:35 +0200 Roger Quadros <[email protected]> wrote:

OMAPs can have 2 to 4 WAITPINs that can be used as general purpose input if not used for memory wait state insertion.

The first user will be the OMAP NAND chip to get the NAND read/busy status using gpiolib.

Just a comment on this approach. Why do you need to exposed native R/B pins as GPIOs? I mean, other NAND controllers are supporting R/B detection using dedicated logic, and they do not exposed those pins a plain GPIOs. Have you considered adding another property (rb-native ?) to deal with this case instead of emulating a GPIO controller? Side note: I added an rb-gpios property in my sunxi-nand DT binding because in some cases, the board design forces us to use a plain GPIO.

Anyway, I realize I'm quite late to review this, and I don't want to delay even more the inclusion of those patches, so I leave the decision to the MTD and TI maintainers.

Best Regards,

Boris

Quoted 231 lines
---
 .../bindings/memory-controllers/omap-gpmc.txt      |   3 +
 drivers/memory/Kconfig                             |   1 +
 drivers/memory/omap-gpmc.c                         | 115 ++++++++++++++++++---
 3 files changed, 107 insertions(+), 12 deletions(-)
Documentation/devicetree/bindings/memory-controllers/omap-gpmc.txt +3 -0
index 704be93..8113a52 100644
@@ -32,6 +32,9 @@ Required properties:
 			bootloader) are used for the physical address decoding.
 			As this will change in the future, filling correct
 			values here is a requirement.
+ - gpio-controller:	The GPMC driver implements a GPIO controller for the
+			GPMC WAIT pins that can be used as general purpose inputs.
+			0 maps to GPMC_WAIT0 pin.
 
 Timing properties for child nodes. All are optional and default to 0.
 
drivers/memory/Kconfig +1 -0
index 6f31546..bca24c6 100644
@@ -51,6 +51,7 @@ config TI_EMIF
 
 config OMAP_GPMC
 	bool
+	select GPIOLIB
 	help
 	  This driver is for the General Purpose Memory Controller (GPMC)
 	  present on Texas Instruments SoCs (e.g. OMAP2+). GPMC allows
drivers/memory/omap-gpmc.c +103 -12
index 6c8d85e..f67e5695 100644
@@ -21,6 +21,7 @@
 #include <linux/spinlock.h>
 #include <linux/io.h>
 #include <linux/module.h>
+#include <linux/gpio/driver.h>
 #include <linux/interrupt.h>
 #include <linux/irqdomain.h>
 #include <linux/platform_device.h>
@@ -237,6 +238,7 @@ struct gpmc_device {
 	struct device *dev;
 	int irq;
 	struct irq_chip irq_chip;
+	struct gpio_chip gpio_chip;
 };
 
 static struct irq_domain *gpmc_irq_domain;
@@ -2034,10 +2036,69 @@ err:
 	return ret;
 }
 
+static int gpmc_gpio_get_direction(struct gpio_chip *chip, unsigned offset)
+{
+	return 1;	/* we're input only */
+}
+
+static int gpmc_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
+{
+	return 0;	/* we're input only */
+}
+
+static int gpmc_gpio_direction_output(struct gpio_chip *chip, unsigned offset,
+				      int value)
+{
+	return -EINVAL;	/* we're input only */
+}
+
+static void gpmc_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
+{
+}
+
+static int gpmc_gpio_get(struct gpio_chip *chip, unsigned offset)
+{
+	u32 reg;
+
+	offset += 8;
+
+	reg = gpmc_read_reg(GPMC_STATUS) & BIT(offset);
+
+	return !!reg;
+}
+
+static int gpmc_gpio_init(struct gpmc_device *gpmc)
+{
+	int ret;
+
+	gpmc->gpio_chip.parent = gpmc->dev;
+	gpmc->gpio_chip.owner = THIS_MODULE;
+	gpmc->gpio_chip.label = DEVICE_NAME;
+	gpmc->gpio_chip.ngpio = gpmc_nr_waitpins;
+	gpmc->gpio_chip.get_direction = gpmc_gpio_get_direction;
+	gpmc->gpio_chip.direction_input = gpmc_gpio_direction_input;
+	gpmc->gpio_chip.direction_output = gpmc_gpio_direction_output;
+	gpmc->gpio_chip.set = gpmc_gpio_set;
+	gpmc->gpio_chip.get = gpmc_gpio_get;
+	gpmc->gpio_chip.base = -1;
+
+	ret = gpiochip_add(&gpmc->gpio_chip);
+	if (ret < 0) {
+		dev_err(gpmc->dev, "could not register gpio chip: %d\n", ret);
+		return ret;
+	}
+
+	return 0;
+}
+
+static void gpmc_gpio_exit(struct gpmc_device *gpmc)
+{
+	gpiochip_remove(&gpmc->gpio_chip);
+}
+
 static int gpmc_probe_dt(struct platform_device *pdev)
 {
 	int ret;
-	struct device_node *child;
 	const struct of_device_id *of_id =
 		of_match_device(gpmc_dt_ids, &pdev->dev);
 
@@ -2065,6 +2126,14 @@ static int gpmc_probe_dt(struct platform_device *pdev)
 		return ret;
 	}
 
+	return 0;
+}
+
+static int gpmc_probe_dt_children(struct platform_device *pdev)
+{
+	int ret;
+	struct device_node *child;
+
 	for_each_available_child_of_node(pdev->dev.of_node, child) {
 
 		if (!child->name)
@@ -2074,6 +2143,9 @@ static int gpmc_probe_dt(struct platform_device *pdev)
 			ret = gpmc_probe_onenand_child(pdev, child);
 		else
 			ret = gpmc_probe_generic_child(pdev, child);
+
+		if (ret)
+			return ret;
 	}
 
 	return 0;
@@ -2083,6 +2155,11 @@ static int gpmc_probe_dt(struct platform_device *pdev)
 {
 	return 0;
 }
+
+static int gpmc_probe_dt_children(struct platform_device *pdev)
+{
+	return 0;
+}
 #endif
 
 static int gpmc_probe(struct platform_device *pdev)
@@ -2129,6 +2206,15 @@ static int gpmc_probe(struct platform_device *pdev)
 		return -EINVAL;
 	}
 
+	if (pdev->dev.of_node) {
+		rc = gpmc_probe_dt(pdev);
+		if (rc)
+			return rc;
+	} else {
+		gpmc_cs_num = GPMC_CS_NUM;
+		gpmc_nr_waitpins = GPMC_NR_WAITPINS;
+	}
+
 	pm_runtime_enable(&pdev->dev);
 	pm_runtime_get_sync(&pdev->dev);
 
@@ -2154,29 +2240,33 @@ static int gpmc_probe(struct platform_device *pdev)
 		 GPMC_REVISION_MINOR(l));
 
 	gpmc_mem_init();
+	rc = gpmc_gpio_init(gpmc);
+	if (rc)
+		goto gpio_init_failed;
 
 	rc = gpmc_setup_irq(gpmc);
 	if (rc) {
 		dev_err(gpmc->dev, "gpmc_setup_irq failed\n");
-		goto fail;
+		goto setup_irq_failed;
 	}
 
-	if (!pdev->dev.of_node) {
-		gpmc_cs_num	 = GPMC_CS_NUM;
-		gpmc_nr_waitpins = GPMC_NR_WAITPINS;
-	}
-
-	rc = gpmc_probe_dt(pdev);
+	rc = gpmc_probe_dt_children(pdev);
 	if (rc < 0) {
-		dev_err(gpmc->dev, "failed to probe DT parameters\n");
-		gpmc_free_irq(gpmc);
-		goto fail;
+		dev_err(gpmc->dev, "failed to probe DT children\n");
+		goto dt_children_failed;
 	}
 
 	return 0;
 
-fail:
+dt_children_failed:
+	gpmc_free_irq(gpmc);
+setup_irq_failed:
+	gpmc_gpio_exit(gpmc);
+gpio_init_failed:
+	gpmc_mem_exit();
 	pm_runtime_put_sync(&pdev->dev);
+	pm_runtime_disable(&pdev->dev);
+
 	return rc;
 }
 
@@ -2185,6 +2275,7 @@ static int gpmc_remove(struct platform_device *pdev)
 	struct gpmc_device *gpmc = platform_get_drvdata(pdev);
 
 	gpmc_free_irq(gpmc);
+	gpmc_gpio_exit(gpmc);
 	gpmc_mem_exit();
 	pm_runtime_put_sync(&pdev->dev);
 	pm_runtime_disable(&pdev->dev);
Signature · 3 lines
Boris Brezillon, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com
#30 lore raw

Re: [PATCH v5 13/26] memory: omap-gpmc: Support general purpose input for WAITPINs

Quoted 8 lines · On Mon, 7 Mar 2016 10:34:40 +0100 Boris Brezillon…

Hi Roger,

Quoted 3 lines · On Fri, 19 Feb 2016 23:15:35 +0200 Roger Quadros…

OMAPs can have 2 to 4 WAITPINs that can be used as general purpose input if not used for memory wait state insertion.

Quoted 7 lines
Quoted 2 lines

The first user will be the OMAP NAND chip to get the NAND read/busy status using gpiolib.

Just a comment on this approach. Why do you need to exposed native R/B pins as GPIOs? I mean, other NAND controllers are supporting R/B detection using dedicated logic, and they do not exposed those pins a plain GPIOs. Have you considered adding another property (rb-native ?)

Just had a look at the sunxi-nand binding, and we chose "allwinner,rb" for this native RB logic. So "ti,rb" would be the equivalent for the gpmc driver.

Signature · 7 lines
Boris Brezillon, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
#31 lore raw

Re: [PATCH v5 13/26] memory: omap-gpmc: Support general purpose input for WAITPINs

In reply to Boris Brezillon

Hi Boris,

Quoted 11 lines · Boris Brezillon

Hi Roger,

Quoted 5 lines · On Fri, 19 Feb 2016 23:15:35 +0200 Roger Quadros…

OMAPs can have 2 to 4 WAITPINs that can be used as general purpose input if not used for memory wait state insertion.

The first user will be the OMAP NAND chip to get the NAND read/busy status using gpiolib.

Quoted 7 lines

Just a comment on this approach. Why do you need to exposed native R/B pins as GPIOs? I mean, other NAND controllers are supporting R/B detection using dedicated logic, and they do not exposed those pins a plain GPIOs. Have you considered adding another property (rb-native ?) to deal with this case instead of emulating a GPIO controller? Side note: I added an rb-gpios property in my sunxi-nand DT binding because in some cases, the board design forces us to use a plain GPIO.

OMAPs can have more than one WAITpins which can be used in multiple ways
- wait state insertion
- general purpose input
- edge detect interrupt

It is not automatically tied to NAND read/busy# mechanism and needs software to get the read/busy# state.
The register to get WAIT pin status is not situated in the NAND controller register space but in the parent GPMC controller space.

So we've modelled the WAIT pins as irqchip and gpiochip and users can use them as they want.

cheers,
-roger

Quoted 232 lines

Anyway, I realize I'm quite late to review this, and I don't want to delay even more the inclusion of those patches, so I leave the decision to the MTD and TI maintainers.

Best Regards,

Boris

Quoted 223 lines
---
 .../bindings/memory-controllers/omap-gpmc.txt      |   3 +
 drivers/memory/Kconfig                             |   1 +
 drivers/memory/omap-gpmc.c                         | 115 ++++++++++++++++++---
 3 files changed, 107 insertions(+), 12 deletions(-)
Documentation/devicetree/bindings/memory-controllers/omap-gpmc.txt +3 -0
index 704be93..8113a52 100644
@@ -32,6 +32,9 @@ Required properties:
 			bootloader) are used for the physical address decoding.
 			As this will change in the future, filling correct
 			values here is a requirement.
+ - gpio-controller:	The GPMC driver implements a GPIO controller for the
+			GPMC WAIT pins that can be used as general purpose inputs.
+			0 maps to GPMC_WAIT0 pin.
 
 Timing properties for child nodes. All are optional and default to 0.
 
drivers/memory/Kconfig +1 -0
index 6f31546..bca24c6 100644
@@ -51,6 +51,7 @@ config TI_EMIF
 
 config OMAP_GPMC
 	bool
+	select GPIOLIB
 	help
 	  This driver is for the General Purpose Memory Controller (GPMC)
 	  present on Texas Instruments SoCs (e.g. OMAP2+). GPMC allows
drivers/memory/omap-gpmc.c +102 -12
index 6c8d85e..f67e5695 100644
@@ -21,6 +21,7 @@
 #include <linux/spinlock.h>
 #include <linux/io.h>
 #include <linux/module.h>
+#include <linux/gpio/driver.h>
 #include <linux/interrupt.h>
 #include <linux/irqdomain.h>
 #include <linux/platform_device.h>
@@ -237,6 +238,7 @@ struct gpmc_device {
 	struct device *dev;
 	int irq;
 	struct irq_chip irq_chip;
+	struct gpio_chip gpio_chip;
 };
 
 static struct irq_domain *gpmc_irq_domain;
@@ -2034,10 +2036,69 @@ err:
 	return ret;
 }
 
+static int gpmc_gpio_get_direction(struct gpio_chip *chip, unsigned offset)
+{
+	return 1;	/* we're input only */
+}
+
+static int gpmc_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
+{
+	return 0;	/* we're input only */
+}
+
+static int gpmc_gpio_direction_output(struct gpio_chip *chip, unsigned offset,
+				      int value)
+{
+	return -EINVAL;	/* we're input only */
+}
+
+static void gpmc_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
+{
+}
+
+static int gpmc_gpio_get(struct gpio_chip *chip, unsigned offset)
+{
+	u32 reg;
+
+	offset += 8;
+
+	reg = gpmc_read_reg(GPMC_STATUS) & BIT(offset);
+
+	return !!reg;
+}
+
+static int gpmc_gpio_init(struct gpmc_device *gpmc)
+{
+	int ret;
+
+	gpmc->gpio_chip.parent = gpmc->dev;
+	gpmc->gpio_chip.owner = THIS_MODULE;
+	gpmc->gpio_chip.label = DEVICE_NAME;
+	gpmc->gpio_chip.ngpio = gpmc_nr_waitpins;
+	gpmc->gpio_chip.get_direction = gpmc_gpio_get_direction;
+	gpmc->gpio_chip.direction_input = gpmc_gpio_direction_input;
+	gpmc->gpio_chip.direction_output = gpmc_gpio_direction_output;
+	gpmc->gpio_chip.set = gpmc_gpio_set;
+	gpmc->gpio_chip.get = gpmc_gpio_get;
+	gpmc->gpio_chip.base = -1;
+
+	ret = gpiochip_add(&gpmc->gpio_chip);
+	if (ret < 0) {
+		dev_err(gpmc->dev, "could not register gpio chip: %d\n", ret);
+		return ret;
+	}
+
+	return 0;
+}
+
+static void gpmc_gpio_exit(struct gpmc_device *gpmc)
+{
+	gpiochip_remove(&gpmc->gpio_chip);
+}
+
 static int gpmc_probe_dt(struct platform_device *pdev)
 {
 	int ret;
-	struct device_node *child;
 	const struct of_device_id *of_id =
 		of_match_device(gpmc_dt_ids, &pdev->dev);
 
@@ -2065,6 +2126,14 @@ static int gpmc_probe_dt(struct platform_device *pdev)
 		return ret;
 	}
 
+	return 0;
+}
+
+static int gpmc_probe_dt_children(struct platform_device *pdev)
+{
+	int ret;
+	struct device_node *child;
+
 	for_each_available_child_of_node(pdev->dev.of_node, child) {
 
 		if (!child->name)
@@ -2074,6 +2143,9 @@ static int gpmc_probe_dt(struct platform_device *pdev)
 			ret = gpmc_probe_onenand_child(pdev, child);
 		else
 			ret = gpmc_probe_generic_child(pdev, child);
+
+		if (ret)
+			return ret;
 	}
 
 	return 0;
@@ -2083,6 +2155,11 @@ static int gpmc_probe_dt(struct platform_device *pdev)
 {
 	return 0;
 }
+
+static int gpmc_probe_dt_children(struct platform_device *pdev)
+{
+	return 0;
+}
 #endif
 
 static int gpmc_probe(struct platform_device *pdev)
@@ -2129,6 +2206,15 @@ static int gpmc_probe(struct platform_device *pdev)
 		return -EINVAL;
 	}
 
+	if (pdev->dev.of_node) {
+		rc = gpmc_probe_dt(pdev);
+		if (rc)
+			return rc;
+	} else {
+		gpmc_cs_num = GPMC_CS_NUM;
+		gpmc_nr_waitpins = GPMC_NR_WAITPINS;
+	}
+
 	pm_runtime_enable(&pdev->dev);
 	pm_runtime_get_sync(&pdev->dev);
 
@@ -2154,29 +2240,33 @@ static int gpmc_probe(struct platform_device *pdev)
 		 GPMC_REVISION_MINOR(l));
 
 	gpmc_mem_init();
+	rc = gpmc_gpio_init(gpmc);
+	if (rc)
+		goto gpio_init_failed;
 
 	rc = gpmc_setup_irq(gpmc);
 	if (rc) {
 		dev_err(gpmc->dev, "gpmc_setup_irq failed\n");
-		goto fail;
+		goto setup_irq_failed;
 	}
 
-	if (!pdev->dev.of_node) {
-		gpmc_cs_num	 = GPMC_CS_NUM;
-		gpmc_nr_waitpins = GPMC_NR_WAITPINS;
-	}
-
-	rc = gpmc_probe_dt(pdev);
+	rc = gpmc_probe_dt_children(pdev);
 	if (rc < 0) {
-		dev_err(gpmc->dev, "failed to probe DT parameters\n");
-		gpmc_free_irq(gpmc);
-		goto fail;
+		dev_err(gpmc->dev, "failed to probe DT children\n");
+		goto dt_children_failed;
 	}
 
 	return 0;
 
-fail:
+dt_children_failed:
+	gpmc_free_irq(gpmc);
+setup_irq_failed:
+	gpmc_gpio_exit(gpmc);
+gpio_init_failed:
+	gpmc_mem_exit();
 	pm_runtime_put_sync(&pdev->dev);
+	pm_runtime_disable(&pdev->dev);
+
 	return rc;
 }
 
Quoted 11 lines

drivers/memory/omap-gpmc.c static int gpmc_remove(struct platform_device *pdev) · line 2281

Quoted 8 lines
drivers/memory/omap-gpmc.c +1 -0
@@ -2185,6 +2275,7 @@ static int gpmc_remove(struct platform_device *pdev)
 	struct gpmc_device *gpmc = platform_get_drvdata(pdev);
 
 	gpmc_free_irq(gpmc);
+	gpmc_gpio_exit(gpmc);
 	gpmc_mem_exit();
 	pm_runtime_put_sync(&pdev->dev);
 	pm_runtime_disable(&pdev->dev);

--
To unsubscribe from this list: send the line "unsubscribe devicetree" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html

#32 lore raw

Re: [PATCH v5 13/26] memory: omap-gpmc: Support general purpose input for WAITPINs

Quoted 27 lines · On Mon, 7 Mar 2016 12:02:02 +0200 Roger Quadros…

Hi Boris,

Quoted 11 lines · Boris Brezillon

Hi Roger,

Quoted 5 lines · On Fri, 19 Feb 2016 23:15:35 +0200 Roger Quadros…

OMAPs can have 2 to 4 WAITPINs that can be used as general purpose input if not used for memory wait state insertion.

The first user will be the OMAP NAND chip to get the NAND read/busy status using gpiolib.

Quoted 7 lines

Just a comment on this approach. Why do you need to exposed native R/B pins as GPIOs? I mean, other NAND controllers are supporting R/B detection using dedicated logic, and they do not exposed those pins a plain GPIOs. Have you considered adding another property (rb-native ?) to deal with this case instead of emulating a GPIO controller? Side note: I added an rb-gpios property in my sunxi-nand DT binding because in some cases, the board design forces us to use a plain GPIO.

OMAPs can have more than one WAITpins which can be used in multiple ways
- wait state insertion
- general purpose input
- edge detect interrupt

Quoted 7 lines

It is not automatically tied to NAND read/busy# mechanism and needs software to get the read/busy# state.
The register to get WAIT pin status is not situated in the NAND controller register space but in the parent GPMC controller space.

So we've modelled the WAIT pins as irqchip and gpiochip and users can use them as they want.

Okay. Thanks for the detailed explanation.

Signature · 7 lines
Boris Brezillon, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
#33 lore raw

PATCH v5 14/26 memory: omap-gpmc: Reserve WAITPIN if needed for WAIT monitoring

In reply to Roger Quadros

If the device attached to GPMC wants to use the WAIT pin for WAIT monitoring then we reserve it internally for exclusive use.

---
 drivers/memory/omap-gpmc.c | 24 ++++++++++++++++++++++--
 1 file changed, 22 insertions(+), 2 deletions(-)
drivers/memory/omap-gpmc.c +22 -2
index f67e5695..af2d57f 100644
@@ -1881,6 +1881,8 @@ static int gpmc_probe_generic_child(struct platform_device *pdev,
 	const char *name;
 	int ret, cs;
 	u32 val;
+	struct gpio_desc *waitpin_desc = NULL;
+	struct gpmc_device *gpmc = platform_get_drvdata(pdev);
 
 	if (of_property_read_u32(child, "reg", &cs) < 0) {
 		dev_err(&pdev->dev, "%s has no 'reg' property\n",
@@ -1990,16 +1992,30 @@ static int gpmc_probe_generic_child(struct platform_device *pdev,
 			goto err;
 	}
 
+	/* Reserve wait pin if it is required and valid */
+	if (gpmc_s.wait_on_read || gpmc_s.wait_on_write) {
+		unsigned wait_pin = gpmc_s.wait_pin;
+
+		waitpin_desc = gpiochip_request_own_desc(&gpmc->gpio_chip,
+							 wait_pin, "WAITPIN");
+		if (IS_ERR(waitpin_desc)) {
+			dev_err(&pdev->dev, "invalid wait-pin: %d\n", wait_pin);
+			ret = PTR_ERR(waitpin_desc);
+			goto err;
+		}
+	}
+
 	gpmc_cs_show_timings(cs, "before gpmc_cs_program_settings");
+
 	ret = gpmc_cs_program_settings(cs, &gpmc_s);
 	if (ret < 0)
-		goto err;
+		goto err_cs;
 
 	ret = gpmc_cs_set_timings(cs, &gpmc_t, &gpmc_s);
 	if (ret) {
 		dev_err(&pdev->dev, "failed to set gpmc timings for: %s\n",
 			child->name);
-		goto err;
+		goto err_cs;
 	}
 
 	/* Clear limited address i.e. enable A26-A11 */
@@ -2030,6 +2046,10 @@ err_child_fail:
 	dev_err(&pdev->dev, "failed to create gpmc child %s\n", child->name);
 	ret = -ENODEV;
 
+err_cs:
+	if (waitpin_desc)
+		gpiochip_free_own_desc(waitpin_desc);
+
 err:
 	gpmc_cs_free(cs);
 
Signature · 6 lines
2.1.4


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

PATCH v5 15/26 memory: omap-gpmc: Support WAIT pin edge interrupts

In reply to Roger Quadros

OMAPs can have 2 to 4 WAITPINs that can be used as edge triggered interrupts if not used for memory wait state insertion.

Support these interrupts via the gpmc IRQ domain.

The gpmc IRQ domain interrupt map is:

0 - NAND_fifoevent
1 - NAND_termcount
2 - GPMC_WAIT0 edge
3 - GPMC_WAIT1 edge, and so on

---
 .../bindings/memory-controllers/omap-gpmc.txt      |   8 ++
 drivers/memory/omap-gpmc.c                         | 106 +++++++++++++++++----
 2 files changed, 96 insertions(+), 18 deletions(-)
Documentation/devicetree/bindings/memory-controllers/omap-gpmc.txt +8 -0
index 8113a52..f64b29c 100644
@@ -35,6 +35,14 @@ Required properties:
  - gpio-controller:	The GPMC driver implements a GPIO controller for the
 			GPMC WAIT pins that can be used as general purpose inputs.
 			0 maps to GPMC_WAIT0 pin.
+ - interrupt-controller: The GPMC driver implements and interrupt controller for
+			the NAND events "fifoevent" and "termcount" plus the
+			rising/falling edges on the GPMC_WAIT pins.
+			The interrupt number mapping is as follows
+			0 - NAND_fifoevent
+			1 - NAND_termcount
+			2 - GPMC_WAIT0 pin edge
+			3 - GPMC_WAIT1 pin edge, and so on.
 
 Timing properties for child nodes. All are optional and default to 0.
 
drivers/memory/omap-gpmc.c +88 -18

178 lines not on this page · raw message

Signature · 6 lines
2.1.4


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

PATCH v5 16/26 memory: omap-gpmc: Prevent GPMC_STATUS from being accessed via gpmc_regs

In reply to Roger Quadros

GPMC_STATUS register is private to the GPMC module and must not be accessed directly by NAND driver through the gpmc_regs.

They must use gpmc_omap_get_nand_ops() instead.

---
 drivers/memory/omap-gpmc.c                   | 2 +-
 include/linux/platform_data/mtd-nand-omap2.h | 3 ++-
 2 files changed, 3 insertions(+), 2 deletions(-)
drivers/memory/omap-gpmc.c +1 -1
index d958fb6..76ce9fe 100644
@@ -1061,7 +1061,7 @@ void gpmc_update_nand_reg(struct gpmc_nand_regs *reg, int cs)
 {
 	int i;
 
-	reg->gpmc_status = gpmc_base + GPMC_STATUS;
+	reg->gpmc_status = NULL;	/* deprecated */
 	reg->gpmc_nand_command = gpmc_base + GPMC_CS0_OFFSET +
 				GPMC_CS_NAND_COMMAND + GPMC_CS_SIZE * cs;
 	reg->gpmc_nand_address = gpmc_base + GPMC_CS0_OFFSET +
include/linux/platform_data/mtd-nand-omap2.h +2 -1
index ff27e5a..7f6de53 100644
@@ -45,7 +45,6 @@ enum omap_ecc {
 };
 
 struct gpmc_nand_regs {
-	void __iomem	*gpmc_status;
 	void __iomem	*gpmc_nand_command;
 	void __iomem	*gpmc_nand_address;
 	void __iomem	*gpmc_nand_data;
@@ -64,6 +63,8 @@ struct gpmc_nand_regs {
 	void __iomem	*gpmc_bch_result4[GPMC_BCH_NUM_REMAINDER];
 	void __iomem	*gpmc_bch_result5[GPMC_BCH_NUM_REMAINDER];
 	void __iomem	*gpmc_bch_result6[GPMC_BCH_NUM_REMAINDER];
+	/* Deprecated. Do not use */
+	void __iomem	*gpmc_status;
 };
 
 struct omap_nand_platform_data {
Signature · 1 line
2.1.4
#36 lore raw

PATCH v5 17/26 mtd: nand: omap2: Implement NAND ready using gpiolib

In reply to Roger Quadros

The GPMC WAIT pin status are now available over gpiolib. Update the omap_dev_ready() function to use gpio instead of directly accessing GPMC register space.

---
 .../devicetree/bindings/mtd/gpmc-nand.txt          |  2 ++
 drivers/mtd/nand/omap2.c                           | 29 ++++++++++++++--------
 include/linux/platform_data/mtd-nand-omap2.h       |  2 +-
 3 files changed, 21 insertions(+), 12 deletions(-)
Documentation/devicetree/bindings/mtd/gpmc-nand.txt +2 -0
index 810b87b..256bb86 100644
@@ -48,6 +48,7 @@ Optional properties:
 		locating ECC errors for BCHx algorithms. SoC devices which have
 		ELM hardware engines should specify this device node in .dtsi
 		Using ELM for ECC error correction frees some CPU cycles.
+ - rb-gpios:	GPIO specifier for the ready/busy# pin.
 
 For inline partition table parsing (optional):
 
@@ -78,6 +79,7 @@ Example for an AM33xx board:
 			ti,nand-xfer-type = "polled";
 			interrupt-parent = <&gpmc>;
 			interrupts = <0>, <1>;
+			rb-gpios = <&gpmc 0 GPIO_ACTIVE_HIGH>; /* gpmc_wait0 */
 
 			gpmc,sync-clk-ps = <0>;
 			gpmc,cs-on-ns = <0>;
drivers/mtd/nand/omap2.c +18 -11
index 0a637c4..e7939f1 100644
@@ -12,6 +12,7 @@
 #include <linux/dmaengine.h>
 #include <linux/dma-mapping.h>
 #include <linux/delay.h>
+#include <linux/gpio/consumer.h>
 #include <linux/module.h>
 #include <linux/interrupt.h>
 #include <linux/jiffies.h>
@@ -183,6 +184,8 @@ struct omap_nand_info {
 	struct nand_ecclayout		oobinfo;
 	/* fields specific for BCHx_HW ECC scheme */
 	struct device			*elm_dev;
+	/* NAND ready gpio */
+	struct gpio_desc		*ready_gpiod;
 };
 
 static inline struct omap_nand_info *mtd_to_omap(struct mtd_info *mtd)
@@ -1024,21 +1027,16 @@ static int omap_wait(struct mtd_info *mtd, struct nand_chip *chip)
 }
 
 /**
- * omap_dev_ready - calls the platform specific dev_ready function
+ * omap_dev_ready - checks the NAND Ready GPIO line
  * @mtd: MTD device structure
+ *
+ * Returns true if ready and false if busy.
  */
 static int omap_dev_ready(struct mtd_info *mtd)
 {
-	unsigned int val = 0;
 	struct omap_nand_info *info = mtd_to_omap(mtd);
 
-	val = readl(info->reg.gpmc_status);
-
-	if ((val & 0x100) == 0x100) {
-		return 1;
-	} else {
-		return 0;
-	}
+	return gpiod_get_value(info->ready_gpiod);
 }
 
 /**
@@ -1754,7 +1752,9 @@ static int omap_nand_probe(struct platform_device *pdev)
 		info->gpmc_cs = pdata->cs;
 		info->reg = pdata->reg;
 		info->ecc_opt = pdata->ecc_opt;
-		info->dev_ready	= pdata->dev_ready;
+		if (pdata->dev_ready)
+			dev_info(&pdev->dev, "pdata->dev_ready is deprecated\n");
+
 		info->xfer_type = pdata->xfer_type;
 		info->devsize = pdata->devsize;
 		info->elm_of_node = pdata->elm_of_node;
@@ -1786,6 +1786,13 @@ static int omap_nand_probe(struct platform_device *pdev)
 	nand_chip->IO_ADDR_W = nand_chip->IO_ADDR_R;
 	nand_chip->cmd_ctrl  = omap_hwcontrol;
 
+	info->ready_gpiod = devm_gpiod_get_optional(&pdev->dev, "rb",
+						    GPIOD_IN);
+	if (IS_ERR(info->ready_gpiod)) {
+		dev_err(dev, "failed to get ready gpio\n");
+		return PTR_ERR(info->ready_gpiod);
+	}
+
 	/*
 	 * If RDY/BSY line is connected to OMAP then use the omap ready
 	 * function and the generic nand_wait function which reads the status
@@ -1793,7 +1800,7 @@ static int omap_nand_probe(struct platform_device *pdev)
 	 * chip delay which is slightly more than tR (AC Timing) of the NAND
 	 * device and read status register until you get a failure or success
 	 */
-	if (info->dev_ready) {
+	if (info->ready_gpiod) {
 		nand_chip->dev_ready = omap_dev_ready;
 		nand_chip->chip_delay = 0;
 	} else {
include/linux/platform_data/mtd-nand-omap2.h +1 -1
index 7f6de53..17d57a1 100644
@@ -71,7 +71,6 @@ struct omap_nand_platform_data {
 	int			cs;
 	struct mtd_partition	*parts;
 	int			nr_parts;
-	bool			dev_ready;
 	bool			flash_bbt;
 	enum nand_io		xfer_type;
 	int			devsize;
@@ -82,5 +81,6 @@ struct omap_nand_platform_data {
 	/* deprecated */
 	struct gpmc_nand_regs	reg;
 	struct device_node	*of_node;
+	bool			dev_ready;
 };
 #endif
Signature · 1 line
2.1.4
#37 lore raw

Re: [PATCH v5 17/26] mtd: nand: omap2: Implement NAND ready using gpiolib

+ Boris

Quoted 16 lines · Roger Quadros

The GPMC WAIT pin status are now available over gpiolib. Update the omap_dev_ready() function to use gpio instead of directly accessing GPMC register space.

---
 .../devicetree/bindings/mtd/gpmc-nand.txt          |  2 ++
 drivers/mtd/nand/omap2.c                           | 29 ++++++++++++++--------
 include/linux/platform_data/mtd-nand-omap2.h       |  2 +-
 3 files changed, 21 insertions(+), 12 deletions(-)
Documentation/devicetree/bindings/mtd/gpmc-nand.txt +0 -0
index 810b87b..256bb86 100644

Documentation/devicetree/bindings/mtd/gpmc-nand.txt Optional properties: · line 51

Quoted 4 lines
Documentation/devicetree/bindings/mtd/gpmc-nand.txt +1 -0
@@ -48,6 +48,7 @@ Optional properties:
 		locating ECC errors for BCHx algorithms. SoC devices which have
 		ELM hardware engines should specify this device node in .dtsi
 		Using ELM for ECC error correction frees some CPU cycles.
+ - rb-gpios:	GPIO specifier for the ready/busy# pin.

^^ Looks better, I think.

Brian

Quoted 114 lines
Documentation/devicetree/bindings/mtd/gpmc-nand.txt +1 -0
 For inline partition table parsing (optional):
 
@@ -78,6 +79,7 @@ Example for an AM33xx board:
 			ti,nand-xfer-type = "polled";
 			interrupt-parent = <&gpmc>;
 			interrupts = <0>, <1>;
+			rb-gpios = <&gpmc 0 GPIO_ACTIVE_HIGH>; /* gpmc_wait0 */
 
 			gpmc,sync-clk-ps = <0>;
 			gpmc,cs-on-ns = <0>;
drivers/mtd/nand/omap2.c +18 -11
index 0a637c4..e7939f1 100644
@@ -12,6 +12,7 @@
 #include <linux/dmaengine.h>
 #include <linux/dma-mapping.h>
 #include <linux/delay.h>
+#include <linux/gpio/consumer.h>
 #include <linux/module.h>
 #include <linux/interrupt.h>
 #include <linux/jiffies.h>
@@ -183,6 +184,8 @@ struct omap_nand_info {
 	struct nand_ecclayout		oobinfo;
 	/* fields specific for BCHx_HW ECC scheme */
 	struct device			*elm_dev;
+	/* NAND ready gpio */
+	struct gpio_desc		*ready_gpiod;
 };
 
 static inline struct omap_nand_info *mtd_to_omap(struct mtd_info *mtd)
@@ -1024,21 +1027,16 @@ static int omap_wait(struct mtd_info *mtd, struct nand_chip *chip)
 }
 
 /**
- * omap_dev_ready - calls the platform specific dev_ready function
+ * omap_dev_ready - checks the NAND Ready GPIO line
  * @mtd: MTD device structure
+ *
+ * Returns true if ready and false if busy.
  */
 static int omap_dev_ready(struct mtd_info *mtd)
 {
-	unsigned int val = 0;
 	struct omap_nand_info *info = mtd_to_omap(mtd);
 
-	val = readl(info->reg.gpmc_status);
-
-	if ((val & 0x100) == 0x100) {
-		return 1;
-	} else {
-		return 0;
-	}
+	return gpiod_get_value(info->ready_gpiod);
 }
 
 /**
@@ -1754,7 +1752,9 @@ static int omap_nand_probe(struct platform_device *pdev)
 		info->gpmc_cs = pdata->cs;
 		info->reg = pdata->reg;
 		info->ecc_opt = pdata->ecc_opt;
-		info->dev_ready	= pdata->dev_ready;
+		if (pdata->dev_ready)
+			dev_info(&pdev->dev, "pdata->dev_ready is deprecated\n");
+
 		info->xfer_type = pdata->xfer_type;
 		info->devsize = pdata->devsize;
 		info->elm_of_node = pdata->elm_of_node;
@@ -1786,6 +1786,13 @@ static int omap_nand_probe(struct platform_device *pdev)
 	nand_chip->IO_ADDR_W = nand_chip->IO_ADDR_R;
 	nand_chip->cmd_ctrl  = omap_hwcontrol;
 
+	info->ready_gpiod = devm_gpiod_get_optional(&pdev->dev, "rb",
+						    GPIOD_IN);
+	if (IS_ERR(info->ready_gpiod)) {
+		dev_err(dev, "failed to get ready gpio\n");
+		return PTR_ERR(info->ready_gpiod);
+	}
+
 	/*
 	 * If RDY/BSY line is connected to OMAP then use the omap ready
 	 * function and the generic nand_wait function which reads the status
@@ -1793,7 +1800,7 @@ static int omap_nand_probe(struct platform_device *pdev)
 	 * chip delay which is slightly more than tR (AC Timing) of the NAND
 	 * device and read status register until you get a failure or success
 	 */
-	if (info->dev_ready) {
+	if (info->ready_gpiod) {
 		nand_chip->dev_ready = omap_dev_ready;
 		nand_chip->chip_delay = 0;
 	} else {
include/linux/platform_data/mtd-nand-omap2.h +1 -1
index 7f6de53..17d57a1 100644
@@ -71,7 +71,6 @@ struct omap_nand_platform_data {
 	int			cs;
 	struct mtd_partition	*parts;
 	int			nr_parts;
-	bool			dev_ready;
 	bool			flash_bbt;
 	enum nand_io		xfer_type;
 	int			devsize;
@@ -82,5 +81,6 @@ struct omap_nand_platform_data {
 	/* deprecated */
 	struct gpmc_nand_regs	reg;
 	struct device_node	*of_node;
+	bool			dev_ready;
 };
 #endif
Signature · 1 line
2.1.4

--
To unsubscribe from this list: send the line "unsubscribe devicetree" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html

#38 lore raw

Re: [PATCH v5 17/26] mtd: nand: omap2: Implement NAND ready using gpiolib

+ Boris

Quoted 134 lines · Brian Norris

+ Boris

Quoted 16 lines · Roger Quadros

The GPMC WAIT pin status are now available over gpiolib. Update the omap_dev_ready() function to use gpio instead of directly accessing GPMC register space.

---
 .../devicetree/bindings/mtd/gpmc-nand.txt          |  2 ++
 drivers/mtd/nand/omap2.c                           | 29 ++++++++++++++--------
 include/linux/platform_data/mtd-nand-omap2.h       |  2 +-
 3 files changed, 21 insertions(+), 12 deletions(-)
Documentation/devicetree/bindings/mtd/gpmc-nand.txt +0 -0
index 810b87b..256bb86 100644

Documentation/devicetree/bindings/mtd/gpmc-nand.txt Optional properties: · line 51

Quoted 4 lines
Documentation/devicetree/bindings/mtd/gpmc-nand.txt +1 -0
@@ -48,6 +48,7 @@ Optional properties:
 		locating ECC errors for BCHx algorithms. SoC devices which have
 		ELM hardware engines should specify this device node in .dtsi
 		Using ELM for ECC error correction frees some CPU cycles.
+ - rb-gpios:	GPIO specifier for the ready/busy# pin.

^^ Looks better, I think.

Brian

Quoted 106 lines
Documentation/devicetree/bindings/mtd/gpmc-nand.txt +1 -0
 For inline partition table parsing (optional):
 
@@ -78,6 +79,7 @@ Example for an AM33xx board:
 			ti,nand-xfer-type = "polled";
 			interrupt-parent = <&gpmc>;
 			interrupts = <0>, <1>;
+			rb-gpios = <&gpmc 0 GPIO_ACTIVE_HIGH>; /* gpmc_wait0 */
 
 			gpmc,sync-clk-ps = <0>;
 			gpmc,cs-on-ns = <0>;
drivers/mtd/nand/omap2.c +18 -11
index 0a637c4..e7939f1 100644
@@ -12,6 +12,7 @@
 #include <linux/dmaengine.h>
 #include <linux/dma-mapping.h>
 #include <linux/delay.h>
+#include <linux/gpio/consumer.h>
 #include <linux/module.h>
 #include <linux/interrupt.h>
 #include <linux/jiffies.h>
@@ -183,6 +184,8 @@ struct omap_nand_info {
 	struct nand_ecclayout		oobinfo;
 	/* fields specific for BCHx_HW ECC scheme */
 	struct device			*elm_dev;
+	/* NAND ready gpio */
+	struct gpio_desc		*ready_gpiod;
 };
 
 static inline struct omap_nand_info *mtd_to_omap(struct mtd_info *mtd)
@@ -1024,21 +1027,16 @@ static int omap_wait(struct mtd_info *mtd, struct nand_chip *chip)
 }
 
 /**
- * omap_dev_ready - calls the platform specific dev_ready function
+ * omap_dev_ready - checks the NAND Ready GPIO line
  * @mtd: MTD device structure
+ *
+ * Returns true if ready and false if busy.
  */
 static int omap_dev_ready(struct mtd_info *mtd)
 {
-	unsigned int val = 0;
 	struct omap_nand_info *info = mtd_to_omap(mtd);
 
-	val = readl(info->reg.gpmc_status);
-
-	if ((val & 0x100) == 0x100) {
-		return 1;
-	} else {
-		return 0;
-	}
+	return gpiod_get_value(info->ready_gpiod);
 }
 
 /**
@@ -1754,7 +1752,9 @@ static int omap_nand_probe(struct platform_device *pdev)
 		info->gpmc_cs = pdata->cs;
 		info->reg = pdata->reg;
 		info->ecc_opt = pdata->ecc_opt;
-		info->dev_ready	= pdata->dev_ready;
+		if (pdata->dev_ready)
+			dev_info(&pdev->dev, "pdata->dev_ready is deprecated\n");
+
 		info->xfer_type = pdata->xfer_type;
 		info->devsize = pdata->devsize;
 		info->elm_of_node = pdata->elm_of_node;
@@ -1786,6 +1786,13 @@ static int omap_nand_probe(struct platform_device *pdev)
 	nand_chip->IO_ADDR_W = nand_chip->IO_ADDR_R;
 	nand_chip->cmd_ctrl  = omap_hwcontrol;
 
+	info->ready_gpiod = devm_gpiod_get_optional(&pdev->dev, "rb",
+						    GPIOD_IN);
+	if (IS_ERR(info->ready_gpiod)) {
+		dev_err(dev, "failed to get ready gpio\n");
+		return PTR_ERR(info->ready_gpiod);
+	}
+
 	/*
 	 * If RDY/BSY line is connected to OMAP then use the omap ready
 	 * function and the generic nand_wait function which reads the status
@@ -1793,7 +1800,7 @@ static int omap_nand_probe(struct platform_device *pdev)
 	 * chip delay which is slightly more than tR (AC Timing) of the NAND
 	 * device and read status register until you get a failure or success
 	 */
-	if (info->dev_ready) {
+	if (info->ready_gpiod) {
 		nand_chip->dev_ready = omap_dev_ready;
 		nand_chip->chip_delay = 0;
 	} else {
include/linux/platform_data/mtd-nand-omap2.h +0 -1
index 7f6de53..17d57a1 100644
@@ -71,7 +71,6 @@ struct omap_nand_platform_data {
 	int			cs;
 	struct mtd_partition	*parts;
 	int			nr_parts;
-	bool			dev_ready;
 	bool			flash_bbt;
 	enum nand_io		xfer_type;
 	int			devsize;
@@ -82,5 +81,6 @@ struct omap_nand_platform_data {
 	/* deprecated */
Quoted 8 lines
Quoted 8 lines
include/linux/platform_data/mtd-nand-omap2.h +1 -0
 	struct gpmc_nand_regs	reg;
 	struct device_node	*of_node;
+	bool			dev_ready;
 };
 #endif
Signature · 1 line
2.1.4

--
To unsubscribe from this list: send the line "unsubscribe devicetree" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html

Acked-by on v5 17/26
#39 lore raw

Re: [PATCH v5 17/26] mtd: nand: omap2: Implement NAND ready using gpiolib

In reply to Roger Quadros
Quoted 5 lines · On Fri, 19 Feb 2016 23:15:39 +0200 Roger Quadros…

The GPMC WAIT pin status are now available over gpiolib. Update the omap_dev_ready() function to use gpio instead of directly accessing GPMC register space.

Quoted 126 lines
---
 .../devicetree/bindings/mtd/gpmc-nand.txt          |  2 ++
 drivers/mtd/nand/omap2.c                           | 29 ++++++++++++++--------
 include/linux/platform_data/mtd-nand-omap2.h       |  2 +-
 3 files changed, 21 insertions(+), 12 deletions(-)
Documentation/devicetree/bindings/mtd/gpmc-nand.txt +2 -0
index 810b87b..256bb86 100644
@@ -48,6 +48,7 @@ Optional properties:
 		locating ECC errors for BCHx algorithms. SoC devices which have
 		ELM hardware engines should specify this device node in .dtsi
 		Using ELM for ECC error correction frees some CPU cycles.
+ - rb-gpios:	GPIO specifier for the ready/busy# pin.
 
 For inline partition table parsing (optional):
 
@@ -78,6 +79,7 @@ Example for an AM33xx board:
 			ti,nand-xfer-type = "polled";
 			interrupt-parent = <&gpmc>;
 			interrupts = <0>, <1>;
+			rb-gpios = <&gpmc 0 GPIO_ACTIVE_HIGH>; /* gpmc_wait0 */
 
 			gpmc,sync-clk-ps = <0>;
 			gpmc,cs-on-ns = <0>;
drivers/mtd/nand/omap2.c +18 -11
index 0a637c4..e7939f1 100644
@@ -12,6 +12,7 @@
 #include <linux/dmaengine.h>
 #include <linux/dma-mapping.h>
 #include <linux/delay.h>
+#include <linux/gpio/consumer.h>
 #include <linux/module.h>
 #include <linux/interrupt.h>
 #include <linux/jiffies.h>
@@ -183,6 +184,8 @@ struct omap_nand_info {
 	struct nand_ecclayout		oobinfo;
 	/* fields specific for BCHx_HW ECC scheme */
 	struct device			*elm_dev;
+	/* NAND ready gpio */
+	struct gpio_desc		*ready_gpiod;
 };
 
 static inline struct omap_nand_info *mtd_to_omap(struct mtd_info *mtd)
@@ -1024,21 +1027,16 @@ static int omap_wait(struct mtd_info *mtd, struct nand_chip *chip)
 }
 
 /**
- * omap_dev_ready - calls the platform specific dev_ready function
+ * omap_dev_ready - checks the NAND Ready GPIO line
  * @mtd: MTD device structure
+ *
+ * Returns true if ready and false if busy.
  */
 static int omap_dev_ready(struct mtd_info *mtd)
 {
-	unsigned int val = 0;
 	struct omap_nand_info *info = mtd_to_omap(mtd);
 
-	val = readl(info->reg.gpmc_status);
-
-	if ((val & 0x100) == 0x100) {
-		return 1;
-	} else {
-		return 0;
-	}
+	return gpiod_get_value(info->ready_gpiod);
 }
 
 /**
@@ -1754,7 +1752,9 @@ static int omap_nand_probe(struct platform_device *pdev)
 		info->gpmc_cs = pdata->cs;
 		info->reg = pdata->reg;
 		info->ecc_opt = pdata->ecc_opt;
-		info->dev_ready	= pdata->dev_ready;
+		if (pdata->dev_ready)
+			dev_info(&pdev->dev, "pdata->dev_ready is deprecated\n");
+
 		info->xfer_type = pdata->xfer_type;
 		info->devsize = pdata->devsize;
 		info->elm_of_node = pdata->elm_of_node;
@@ -1786,6 +1786,13 @@ static int omap_nand_probe(struct platform_device *pdev)
 	nand_chip->IO_ADDR_W = nand_chip->IO_ADDR_R;
 	nand_chip->cmd_ctrl  = omap_hwcontrol;
 
+	info->ready_gpiod = devm_gpiod_get_optional(&pdev->dev, "rb",
+						    GPIOD_IN);
+	if (IS_ERR(info->ready_gpiod)) {
+		dev_err(dev, "failed to get ready gpio\n");
+		return PTR_ERR(info->ready_gpiod);
+	}
+
 	/*
 	 * If RDY/BSY line is connected to OMAP then use the omap ready
 	 * function and the generic nand_wait function which reads the status
@@ -1793,7 +1800,7 @@ static int omap_nand_probe(struct platform_device *pdev)
 	 * chip delay which is slightly more than tR (AC Timing) of the NAND
 	 * device and read status register until you get a failure or success
 	 */
-	if (info->dev_ready) {
+	if (info->ready_gpiod) {
 		nand_chip->dev_ready = omap_dev_ready;
 		nand_chip->chip_delay = 0;
 	} else {
include/linux/platform_data/mtd-nand-omap2.h +1 -1
index 7f6de53..17d57a1 100644
@@ -71,7 +71,6 @@ struct omap_nand_platform_data {
 	int			cs;
 	struct mtd_partition	*parts;
 	int			nr_parts;
-	bool			dev_ready;
 	bool			flash_bbt;
 	enum nand_io		xfer_type;
 	int			devsize;
@@ -82,5 +81,6 @@ struct omap_nand_platform_data {
 	/* deprecated */
 	struct gpmc_nand_regs	reg;
 	struct device_node	*of_node;
+	bool			dev_ready;
 };
 #endif
Signature · 7 lines
Boris Brezillon, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
#40 lore raw

PATCH v5 18/26 ARM: dts: dra7: Fix NAND device nodes.

In reply to Roger Quadros

Add compatible id, GPMC register resource and interrupt resource to NAND controller nodes.

The GPMC driver now implements gpiochip and irqchip so enable gpio-controller and interrupt-controller properties.

With this the interrupt parent of NAND node changes so fix it accordingly.

---
 arch/arm/boot/dts/dra7-evm.dts  | 6 +++++-
 arch/arm/boot/dts/dra7.dtsi     | 4 ++++
 arch/arm/boot/dts/dra72-evm.dts | 6 +++++-
 3 files changed, 14 insertions(+), 2 deletions(-)
arch/arm/boot/dts/dra7-evm.dts +5 -1
index cfc24e5..28ae95e 100644
@@ -741,9 +741,13 @@
 	status = "okay";
 	pinctrl-names = "default";
 	pinctrl-0 = <&nand_flash_x16>;
-	ranges = <0 0 0 0x01000000>;	/* minimum GPMC partition = 16MB */
+	ranges = <0 0 0x08000000 0x01000000>;	/* minimum GPMC partition = 16MB */
 	nand@0,0 {
+		compatible = "ti,omap2-nand";
 		reg = <0 0 4>;		/* device IO registers */
+		interrupt-parent = <&gpmc>;
+		interrupts = <0 IRQ_TYPE_NONE>, /* fifoevent */
+			     <1 IRQ_TYPE_NONE>; /* termcount */
 		ti,nand-ecc-opt = "bch8";
 		ti,elm-id = <&elm>;
 		nand-bus-width = <16>;
arch/arm/boot/dts/dra7.dtsi +4 -0
index 8ea153a..1ac3ffdb 100644
@@ -1402,6 +1402,10 @@
 			gpmc,num-waitpins = <2>;
 			#address-cells = <2>;
 			#size-cells = <1>;
+			gpio-controller;
+			#gpio-cells = <2>;
+			interrupt-controller;
+			#interrupt-cells = <2>;
 			status = "disabled";
 		};
 
arch/arm/boot/dts/dra72-evm.dts +5 -1
index 00b1200..6cf211b 100644
@@ -492,13 +492,17 @@
 	status = "okay";
 	pinctrl-names = "default";
 	pinctrl-0 = <&nand_default>;
-	ranges = <0 0 0 0x01000000>;	/* minimum GPMC partition = 16MB */
+	ranges = <0 0 0x08000000 0x01000000>;	/* minimum GPMC partition = 16MB */
 	nand@0,0 {
 		/* To use NAND, DIP switch SW5 must be set like so:
 		 * SW5.1 (NAND_SELn) = ON (LOW)
 		 * SW5.9 (GPMC_WPN) = OFF (HIGH)
 		 */
+		compatible = "ti,omap2-nand";
 		reg = <0 0 4>;		/* device IO registers */
+		interrupt-parent = <&gpmc>;
+		interrupts = <0 IRQ_TYPE_NONE>, /* fifoevent */
+			     <1 IRQ_TYPE_NONE>;	/* termcount */
 		ti,nand-ecc-opt = "bch8";
 		ti,elm-id = <&elm>;
 		nand-bus-width = <16>;
Signature · 1 line
2.1.4
#41 lore raw

PATCH v5 19/26 ARM: dts: dra7x-evm: Provide NAND ready pin

In reply to Roger Quadros

On these boards NAND ready pin status is avilable over GPMC_WAIT0 pin.

Read speed increases from 13768 KiB/ to 17246 KiB/s. Write speed was unchanged at 7123 KiB/s. Measured using mtd_speedtest.ko.

---
 arch/arm/boot/dts/dra7-evm.dts  | 1 +
 arch/arm/boot/dts/dra72-evm.dts | 1 +
 2 files changed, 2 insertions(+)
arch/arm/boot/dts/dra7-evm.dts +1 -0
index 28ae95e..36053ba 100644
@@ -748,6 +748,7 @@
 		interrupt-parent = <&gpmc>;
 		interrupts = <0 IRQ_TYPE_NONE>, /* fifoevent */
 			     <1 IRQ_TYPE_NONE>; /* termcount */
+		rb-gpios = <&gpmc 0 GPIO_ACTIVE_HIGH>; /* gpmc_wait0 pin */
 		ti,nand-ecc-opt = "bch8";
 		ti,elm-id = <&elm>;
 		nand-bus-width = <16>;
arch/arm/boot/dts/dra72-evm.dts +1 -0
index 6cf211b..75d4ec5 100644
@@ -503,6 +503,7 @@
 		interrupt-parent = <&gpmc>;
 		interrupts = <0 IRQ_TYPE_NONE>, /* fifoevent */
 			     <1 IRQ_TYPE_NONE>;	/* termcount */
+		rb-gpios = <&gpmc 0 GPIO_ACTIVE_HIGH>; /* gpmc_wait0 pin */
 		ti,nand-ecc-opt = "bch8";
 		ti,elm-id = <&elm>;
 		nand-bus-width = <16>;
Signature · 1 line
2.1.4
#42 lore raw

PATCH v5 20/26 ARM: dts: am437x: Fix NAND device nodes

In reply to Roger Quadros

Add compatible id, GPMC register resource and interrupt resource to NAND controller nodes.

The GPMC driver now implements gpiochip and irqchip so enable gpio-controller and interrupt-controller properties.

With this the interrupt parent of NAND node changes so fix it accordingly.

---
 arch/arm/boot/dts/am4372.dtsi        | 4 ++++
 arch/arm/boot/dts/am437x-cm-t43.dts  | 7 +++++--
 arch/arm/boot/dts/am437x-gp-evm.dts  | 6 +++++-
 arch/arm/boot/dts/am43x-epos-evm.dts | 6 +++++-
 4 files changed, 19 insertions(+), 4 deletions(-)
arch/arm/boot/dts/am4372.dtsi +4 -0
index 38790a32..5b58679 100644
@@ -893,6 +893,10 @@
 			gpmc,num-waitpins = <2>;
 			#address-cells = <2>;
 			#size-cells = <1>;
+			gpio-controller;
+			#gpio-cells = <2>;
+			interrupt-controller;
+			#interrupt-cells = <2>;
 			status = "disabled";
 		};
 
arch/arm/boot/dts/am437x-cm-t43.dts +5 -2
index 8677f4c..1600cad 100644
@@ -146,10 +146,13 @@
 	pinctrl-0 = <&nand_flash_x8>;
 	ranges = <0 0 0x08000000 0x1000000>;
 	nand@0,0 {
-		reg = <0 0 0>;
+		compatible = "ti,omap2-nand";
+		reg = <0 0 4>;		/* CS0, offset 0, IO size 4 */
+		interrupt-parent = <&gpmc>;
+		interrupts = <0 IRQ_TYPE_NONE>, /* fifoevent */
+			     <1 IRQ_TYPE_NONE>;	/* termcount */
 		ti,nand-ecc-opt = "bch8";
 		ti,elm-id = <&elm>;
-
 		nand-bus-width = <8>;
 		gpmc,device-width = <1>;
 		gpmc,sync-clk-ps = <0>;
arch/arm/boot/dts/am437x-gp-evm.dts +5 -1
index 64d4332..7081b88 100644
@@ -812,9 +812,13 @@
 	status = "okay";
 	pinctrl-names = "default";
 	pinctrl-0 = <&nand_flash_x8>;
-	ranges = <0 0 0 0x01000000>;	/* minimum GPMC partition = 16MB */
+	ranges = <0 0 0x08000000 0x01000000>;	/* CS0 space. Min partition = 16MB */
 	nand@0,0 {
+		compatible = "ti,omap2-nand";
 		reg = <0 0 4>;		/* device IO registers */
+		interrupt-parent = <&gpmc>;
+		interrupts = <0 IRQ_TYPE_NONE>, /* fifoevent */
+			     <1 IRQ_TYPE_NONE>;	/* termcount */
 		ti,nand-ecc-opt = "bch16";
 		ti,elm-id = <&elm>;
 		nand-bus-width = <8>;
arch/arm/boot/dts/am43x-epos-evm.dts +5 -1
index 746fd2b..12b08cf 100644
@@ -561,9 +561,13 @@
 	status = "okay";	/* Disable QSPI when enabling GPMC (NAND) */
 	pinctrl-names = "default";
 	pinctrl-0 = <&nand_flash_x8>;
-	ranges = <0 0 0x08000000 0x1000000>;	/* CS0: 16MB for NAND */
+	ranges = <0 0 0x08000000 0x01000000>;	/* CS0 space. Min partition = 16MB */
 	nand@0,0 {
+		compatible = "ti,omap2-nand";
 		reg = <0 0 4>; /* CS0, offset 0, IO size 4 */
+		interrupt-parent = <&gpmc>;
+		interrupts = <0 IRQ_TYPE_NONE>, /* fifoevent */
+			     <1 IRQ_TYPE_NONE>;	/* termcount */
 		ti,nand-ecc-opt = "bch16";
 		ti,elm-id = <&elm>;
 		nand-bus-width = <8>;
Signature · 1 line
2.1.4
#43 lore raw

PATCH v5 21/26 ARM: dts: am437x: Provide NAND ready pin

In reply to Roger Quadros

On these boards NAND ready pin status is avilable over GPMC_WAIT0 pin.

For NAND we don't use GPMC wait pin monitoring but get the NAND Ready/Busy# status using GPIOlib. GPMC driver provides the WAIT0 pin status over GPIOlib.

Read speed increases from 16516 KiB/ to 18813 KiB/s and write speed was unchanged at 9941 KiB/s.

Measured using mtd_speedtest.ko.

---
 arch/arm/boot/dts/am437x-gp-evm.dts  | 3 +--
 arch/arm/boot/dts/am43x-epos-evm.dts | 3 +--
 2 files changed, 2 insertions(+), 4 deletions(-)
arch/arm/boot/dts/am437x-gp-evm.dts +1 -2
index 7081b88..2405004 100644
@@ -819,6 +819,7 @@
 		interrupt-parent = <&gpmc>;
 		interrupts = <0 IRQ_TYPE_NONE>, /* fifoevent */
 			     <1 IRQ_TYPE_NONE>;	/* termcount */
+		rb-gpios = <&gpmc 0 GPIO_ACTIVE_HIGH>;	/* gpmc_wait0 */
 		ti,nand-ecc-opt = "bch16";
 		ti,elm-id = <&elm>;
 		nand-bus-width = <8>;
@@ -837,11 +838,9 @@
 		gpmc,access-ns = <30>;
 		gpmc,rd-cycle-ns = <40>;
 		gpmc,wr-cycle-ns = <40>;
-		gpmc,wait-pin = <0>;
 		gpmc,bus-turnaround-ns = <0>;
 		gpmc,cycle2cycle-delay-ns = <0>;
 		gpmc,clk-activation-ns = <0>;
-		gpmc,wait-monitoring-ns = <0>;
 		gpmc,wr-access-ns = <40>;
 		gpmc,wr-data-mux-bus-ns = <0>;
 		/* MTD partition table */
arch/arm/boot/dts/am43x-epos-evm.dts +1 -2
index 12b08cf..8d71af6 100644
@@ -568,6 +568,7 @@
 		interrupt-parent = <&gpmc>;
 		interrupts = <0 IRQ_TYPE_NONE>, /* fifoevent */
 			     <1 IRQ_TYPE_NONE>;	/* termcount */
+		rb-gpios = <&gpmc 0 GPIO_ACTIVE_HIGH>;	/* gpmc_wait0 */
 		ti,nand-ecc-opt = "bch16";
 		ti,elm-id = <&elm>;
 		nand-bus-width = <8>;
@@ -586,11 +587,9 @@
 		gpmc,access-ns = <30>; /* tCEA + 4*/
 		gpmc,rd-cycle-ns = <40>;
 		gpmc,wr-cycle-ns = <40>;
-		gpmc,wait-pin = <0>;
 		gpmc,bus-turnaround-ns = <0>;
 		gpmc,cycle2cycle-delay-ns = <0>;
 		gpmc,clk-activation-ns = <0>;
-		gpmc,wait-monitoring-ns = <0>;
 		gpmc,wr-access-ns = <40>;
 		gpmc,wr-data-mux-bus-ns = <0>;
 		/* MTD partition table */
Signature · 1 line
2.1.4
#44 lore raw

PATCH v5 22/26 ARM: dts: am335x: Fix NAND device nodes

In reply to Roger Quadros

Add compatible id, GPMC register resource and interrupt resource to NAND controller nodes.

The GPMC driver now implements gpiochip and irqchip so enable gpio-controller and interrupt-controller properties.

With this the interrupt parent of NAND node changes so fix it accordingly.

Cc Teresa Remmet <[email protected]>
Cc Ilya Ledvich <[email protected]>
Cc Yegor Yefremov <[email protected]>
Cc Rostislav Lisovy <[email protected]>
Cc Enric Balletbo i Serra <[email protected]>
---
 arch/arm/boot/dts/am335x-baltos-ir5221.dts | 6 +++++-
 arch/arm/boot/dts/am335x-chilisom.dtsi     | 5 +++++
 arch/arm/boot/dts/am335x-cm-t335.dts       | 6 +++++-
 arch/arm/boot/dts/am335x-evm.dts           | 4 ++++
 arch/arm/boot/dts/am335x-igep0033.dtsi     | 5 +++++
 arch/arm/boot/dts/am335x-phycore-som.dtsi  | 5 +++++
 arch/arm/boot/dts/am33xx.dtsi              | 4 ++++
 7 files changed, 33 insertions(+), 2 deletions(-)
arch/arm/boot/dts/am335x-baltos-ir5221.dts +5 -1
index ded1eb6..7b6bcb0 100644
@@ -236,7 +236,11 @@
 	status = "okay";
 
 	nand@0,0 {
-		reg = <0 0 0>; /* CS0, offset 0 */
+		compatible = "ti,omap2-nand";
+		reg = <0 0 4>; /* CS0, offset 0, IO size 4 */
+		interrupt-parent = <&gpmc>;
+		interrupts = <0 IRQ_TYPE_NONE>, /* fifoevent */
+			     <1 IRQ_TYPE_NONE>;	/* termcount */
 		nand-bus-width = <8>;
 		ti,nand-ecc-opt = "bch8";
 		ti,nand-xfer-type = "polled";
arch/arm/boot/dts/am335x-chilisom.dtsi +5 -0
index fda457b..e8e7d9d 100644
@@ -7,6 +7,7 @@
  * published by the Free Software Foundation.
  */
 #include "am33xx.dtsi"
+#include <dt-bindings/interrupt-controller/irq.h>
 
 / {
 	model = "Grinn AM335x ChiliSOM";
@@ -218,7 +219,11 @@
 	pinctrl-0 = <&nandflash_pins>;
 	ranges = <0 0 0x08000000 0x01000000>; /* CS0 0 @addr 0x08000000, size 0x01000000 */
 	nand@0,0 {
+		compatible = "ti,omap2-nand";
 		reg = <0 0 4>;	/* CS0, offset 0, IO size 4 */
+		interrupt-parent = <&gpmc>;
+		interrupts = <0 IRQ_TYPE_NONE>, /* fifoevent */
+			     <1 IRQ_TYPE_NONE>;	/* termcount */
 		ti,nand-ecc-opt = "bch8";
 		ti,elm-id = <&elm>;
 		nand-bus-width = <8>;
arch/arm/boot/dts/am335x-cm-t335.dts +5 -1
index 5d5fb62..53120b1 100644
@@ -406,7 +406,11 @@ status = "okay";
 	pinctrl-0 = <&nandflash_pins>;
 	ranges = <0 0 0x08000000 0x10000000>;	/* CS0: NAND */
 	nand@0,0 {
-		reg = <0 0 0>; /* CS0, offset 0 */
+		compatible = "ti,omap2-nand";
+		reg = <0 0 4>; /* CS0, offset 0, IO size 4 */
+		interrupt-parent = <&gpmc>;
+		interrupts = <0 IRQ_TYPE_NONE>, /* fifoevent */
+			     <1 IRQ_TYPE_NONE>;	/* termcount */
 		ti,nand-ecc-opt = "bch8";
 		ti,elm-id = <&elm>;
 		nand-bus-width = <8>;
arch/arm/boot/dts/am335x-evm.dts +4 -0
index 0d6a68c..4e7a53e6a 100644
@@ -519,7 +519,11 @@
 	pinctrl-0 = <&nandflash_pins_s0>;
 	ranges = <0 0 0x08000000 0x1000000>;	/* CS0: 16MB for NAND */
 	nand@0,0 {
+		compatible = "ti,omap2-nand";
 		reg = <0 0 4>; /* CS0, offset 0, IO size 4 */
+		interrupt-parent = <&gpmc>;
+		interrupts = <0 IRQ_TYPE_NONE>, /* fifoevent */
+			     <1 IRQ_TYPE_NONE>;	/* termcount */
 		ti,nand-ecc-opt = "bch8";
 		ti,elm-id = <&elm>;
 		nand-bus-width = <8>;
arch/arm/boot/dts/am335x-igep0033.dtsi +5 -0
index 54f1135..4cfe041 100644
@@ -11,6 +11,7 @@
 /dts-v1/;
 
 #include "am33xx.dtsi"
+#include <dt-bindings/interrupt-controller/irq.h>
 
 / {
 	cpus {
@@ -129,7 +130,11 @@
 	ranges = <0 0 0x08000000 0x1000000>;	/* CS0: 16MB for NAND */
 
 	nand@0,0 {
+		compatible = "ti,omap2-nand";
 		reg = <0 0 4>; /* CS0, offset 0, IO size 4 */
+		interrupt-parent = <&gpmc>;
+		interrupts = <0 IRQ_TYPE_NONE>, /* fifoevent */
+			     <1 IRQ_TYPE_NONE>;	/* termcount */
 		nand-bus-width = <8>;
 		ti,nand-ecc-opt = "bch8";
 		gpmc,device-width = <1>;
arch/arm/boot/dts/am335x-phycore-som.dtsi +5 -0
index c20ae6c..80a5687 100644
@@ -8,6 +8,7 @@
  */
 
 #include "am33xx.dtsi"
+#include <dt-bindings/interrupt-controller/irq.h>
 
 / {
 	model = "Phytec AM335x phyCORE";
@@ -165,7 +166,11 @@
 	pinctrl-0 = <&nandflash_pins>;
 	ranges = <0 0 0x08000000 0x1000000>;   /* CS0: NAND */
 	nandflash: nand@0,0 {
+		compatible = "ti,omap2-nand";
 		reg = <0 0 4>; /* CS0, offset 0, IO size 4 */
+		interrupt-parent = <&gpmc>;
+		interrupts = <0 IRQ_TYPE_NONE>, /* fifoevent */
+			     <1 IRQ_TYPE_NONE>;	/* termcount */
 		nand-bus-width = <8>;
 		ti,nand-ecc-opt = "bch8";
 		gpmc,device-nand = "true";
arch/arm/boot/dts/am33xx.dtsi +4 -0
index 04885f9..5797c03 100644
@@ -865,6 +865,10 @@
 			gpmc,num-waitpins = <2>;
 			#address-cells = <2>;
 			#size-cells = <1>;
+			gpio-controller;
+			#gpio-cells = <2>;
+			interrupt-controller;
+			#interrupt-cells = <2>;
 			status = "disabled";
 		};
 
Signature · 1 line
2.1.4
#45 lore raw

PATCH v5 23/26 ARM: dts: am335x: Provide NAND ready pin

In reply to Roger Quadros

On these boards NAND ready pin status is avilable over GPMC_WAIT0 pin.

For NAND we don't use GPMC wait pin monitoring but get the NAND Ready/Busy# status using GPIOlib. GPMC driver provides the WAIT0 pin status over GPIOlib.

Read speed increases from 7869 KiB/ to 8875 KiB/s and write speed was unchanged at 5100 KiB/s.

Measured using mtd_speedtest.ko on am335x-evm.

Cc Teresa Remmet <[email protected]>
Cc Ilya Ledvich <[email protected]>
Cc Yegor Yefremov <[email protected]>
Cc Rostislav Lisovy <[email protected]>
Cc Enric Balletbo i Serra <[email protected]>
---
 arch/arm/boot/dts/am335x-baltos-ir5221.dts | 4 +---
 arch/arm/boot/dts/am335x-chilisom.dtsi     | 4 +---
 arch/arm/boot/dts/am335x-cm-t335.dts       | 4 +---
 arch/arm/boot/dts/am335x-evm.dts           | 4 +---
 arch/arm/boot/dts/am335x-igep0033.dtsi     | 4 +---
 arch/arm/boot/dts/am335x-phycore-som.dtsi  | 4 +---
 6 files changed, 6 insertions(+), 18 deletions(-)
arch/arm/boot/dts/am335x-baltos-ir5221.dts +1 -3
index 7b6bcb0..17e92e8 100644
@@ -241,6 +241,7 @@
 		interrupt-parent = <&gpmc>;
 		interrupts = <0 IRQ_TYPE_NONE>, /* fifoevent */
 			     <1 IRQ_TYPE_NONE>;	/* termcount */
+		rb-gpios = <&gpmc 0 GPIO_ACTIVE_HIGH>; /* gpmc_wait0 */
 		nand-bus-width = <8>;
 		ti,nand-ecc-opt = "bch8";
 		ti,nand-xfer-type = "polled";
@@ -261,12 +262,9 @@
 		gpmc,access-ns = <64>;
 		gpmc,rd-cycle-ns = <82>;
 		gpmc,wr-cycle-ns = <82>;
-		gpmc,wait-on-read = "true";
-		gpmc,wait-on-write = "true";
 		gpmc,bus-turnaround-ns = <0>;
 		gpmc,cycle2cycle-delay-ns = <0>;
 		gpmc,clk-activation-ns = <0>;
-		gpmc,wait-monitoring-ns = <0>;
 		gpmc,wr-access-ns = <40>;
 		gpmc,wr-data-mux-bus-ns = <0>;
 
arch/arm/boot/dts/am335x-chilisom.dtsi +1 -3
index e8e7d9d..6b8e70a 100644
@@ -224,6 +224,7 @@
 		interrupt-parent = <&gpmc>;
 		interrupts = <0 IRQ_TYPE_NONE>, /* fifoevent */
 			     <1 IRQ_TYPE_NONE>;	/* termcount */
+		rb-gpios = <&gpmc 0 GPIO_ACTIVE_HIGH>; /* gpmc_wait0 */
 		ti,nand-ecc-opt = "bch8";
 		ti,elm-id = <&elm>;
 		nand-bus-width = <8>;
@@ -242,12 +243,9 @@
 		gpmc,access-ns = <64>;
 		gpmc,rd-cycle-ns = <82>;
 		gpmc,wr-cycle-ns = <82>;
-		gpmc,wait-on-read = "true";
-		gpmc,wait-on-write = "true";
 		gpmc,bus-turnaround-ns = <0>;
 		gpmc,cycle2cycle-delay-ns = <0>;
 		gpmc,clk-activation-ns = <0>;
-		gpmc,wait-monitoring-ns = <0>;
 		gpmc,wr-access-ns = <40>;
 		gpmc,wr-data-mux-bus-ns = <0>;
 	};
arch/arm/boot/dts/am335x-cm-t335.dts +1 -3
index 53120b1..817b1de 100644
@@ -411,6 +411,7 @@ status = "okay";
 		interrupt-parent = <&gpmc>;
 		interrupts = <0 IRQ_TYPE_NONE>, /* fifoevent */
 			     <1 IRQ_TYPE_NONE>;	/* termcount */
+		rb-gpios = <&gpmc 0 GPIO_ACTIVE_HIGH>; /* gpmc_wait0 */
 		ti,nand-ecc-opt = "bch8";
 		ti,elm-id = <&elm>;
 		nand-bus-width = <8>;
@@ -429,12 +430,9 @@ status = "okay";
 		gpmc,access-ns = <64>;
 		gpmc,rd-cycle-ns = <82>;
 		gpmc,wr-cycle-ns = <82>;
-		gpmc,wait-on-read = "true";
-		gpmc,wait-on-write = "true";
 		gpmc,bus-turnaround-ns = <0>;
 		gpmc,cycle2cycle-delay-ns = <0>;
 		gpmc,clk-activation-ns = <0>;
-		gpmc,wait-monitoring-ns = <0>;
 		gpmc,wr-access-ns = <40>;
 		gpmc,wr-data-mux-bus-ns = <0>;
 		/* MTD partition table */
arch/arm/boot/dts/am335x-evm.dts +1 -3
index 4e7a53e6a..516673b 100644
@@ -524,6 +524,7 @@
 		interrupt-parent = <&gpmc>;
 		interrupts = <0 IRQ_TYPE_NONE>, /* fifoevent */
 			     <1 IRQ_TYPE_NONE>;	/* termcount */
+		rb-gpios = <&gpmc 0 GPIO_ACTIVE_HIGH>; /* gpmc_wait0 */
 		ti,nand-ecc-opt = "bch8";
 		ti,elm-id = <&elm>;
 		nand-bus-width = <8>;
@@ -542,12 +543,9 @@
 		gpmc,access-ns = <64>;
 		gpmc,rd-cycle-ns = <82>;
 		gpmc,wr-cycle-ns = <82>;
-		gpmc,wait-on-read = "true";
-		gpmc,wait-on-write = "true";
 		gpmc,bus-turnaround-ns = <0>;
 		gpmc,cycle2cycle-delay-ns = <0>;
 		gpmc,clk-activation-ns = <0>;
-		gpmc,wait-monitoring-ns = <0>;
 		gpmc,wr-access-ns = <40>;
 		gpmc,wr-data-mux-bus-ns = <0>;
 		/* MTD partition table */
arch/arm/boot/dts/am335x-igep0033.dtsi +1 -3
index 4cfe041..df63484 100644
@@ -135,6 +135,7 @@
 		interrupt-parent = <&gpmc>;
 		interrupts = <0 IRQ_TYPE_NONE>, /* fifoevent */
 			     <1 IRQ_TYPE_NONE>;	/* termcount */
+		rb-gpios = <&gpmc 0 GPIO_ACTIVE_HIGH>; /* gpmc_wait0 */
 		nand-bus-width = <8>;
 		ti,nand-ecc-opt = "bch8";
 		gpmc,device-width = <1>;
@@ -152,12 +153,9 @@
 		gpmc,access-ns = <64>;
 		gpmc,rd-cycle-ns = <82>;
 		gpmc,wr-cycle-ns = <82>;
-		gpmc,wait-on-read = "true";
-		gpmc,wait-on-write = "true";
 		gpmc,bus-turnaround-ns = <0>;
 		gpmc,cycle2cycle-delay-ns = <0>;
 		gpmc,clk-activation-ns = <0>;
-		gpmc,wait-monitoring-ns = <0>;
 		gpmc,wr-access-ns = <40>;
 		gpmc,wr-data-mux-bus-ns = <0>;
 
arch/arm/boot/dts/am335x-phycore-som.dtsi +1 -3
index 80a5687..86f7731 100644
@@ -171,6 +171,7 @@
 		interrupt-parent = <&gpmc>;
 		interrupts = <0 IRQ_TYPE_NONE>, /* fifoevent */
 			     <1 IRQ_TYPE_NONE>;	/* termcount */
+		rb-gpios = <&gpmc 0 GPIO_ACTIVE_HIGH>; /* gpmc_wait0 */
 		nand-bus-width = <8>;
 		ti,nand-ecc-opt = "bch8";
 		gpmc,device-nand = "true";
@@ -189,13 +190,10 @@
 		gpmc,access-ns = <30>;
 		gpmc,rd-cycle-ns = <30>;
 		gpmc,wr-cycle-ns = <30>;
-		gpmc,wait-on-read = "true";
-		gpmc,wait-on-write = "true";
 		gpmc,bus-turnaround-ns = <0>;
 		gpmc,cycle2cycle-delay-ns = <50>;
 		gpmc,cycle2cycle-diffcsen;
 		gpmc,clk-activation-ns = <0>;
-		gpmc,wait-monitoring-ns = <0>;
 		gpmc,wr-access-ns = <30>;
 		gpmc,wr-data-mux-bus-ns = <0>;
 
Signature · 1 line
2.1.4
#46 lore raw

PATCH v5 24/26 ARM: dts: dm814x: Fix gpmc and NAND node

In reply to Roger Quadros

Make gpmc node gpio+interrupt capable.

Add compatible id and interrupt to NAND node.

---
 arch/arm/boot/dts/dm8148-evm.dts       | 8 +++++---
 arch/arm/boot/dts/dm814x.dtsi          | 4 ++++
 arch/arm/boot/dts/dra62x-j5eco-evm.dts | 8 +++++---
 3 files changed, 14 insertions(+), 6 deletions(-)
arch/arm/boot/dts/dm8148-evm.dts +5 -3
index 862977f..1e8036e 100644
@@ -6,6 +6,7 @@
 /dts-v1/;
 
 #include "dm814x.dtsi"
+#include <dt-bindings/interrupt-controller/irq.h>
 
 / {
 	model = "DM8148 EVM";
@@ -39,8 +40,12 @@
 	ranges = <0 0 0x04000000 0x01000000>;	/* CS0: 16MB for NAND */
 
 	nand@0,0 {
+		compatible = "ti,omap2-nand";
 		linux,mtd-name= "micron,mt29f2g16aadwp";
 		reg = <0 0 4>; /* CS0, offset 0, IO size 4 */
+		interrupt-parent = <&gpmc>;
+		interrupts = <0 IRQ_TYPE_NONE>, /* fifoevent */
+			     <1 IRQ_TYPE_NONE>; /* termcount */
 		#address-cells = <1>;
 		#size-cells = <1>;
 		ti,nand-ecc-opt = "bch8";
@@ -60,12 +65,9 @@
 		gpmc,access-ns = <64>;
 		gpmc,rd-cycle-ns = <82>;
 		gpmc,wr-cycle-ns = <82>;
-		gpmc,wait-on-read = "true";
-		gpmc,wait-on-write = "true";
 		gpmc,bus-turnaround-ns = <0>;
 		gpmc,cycle2cycle-delay-ns = <0>;
 		gpmc,clk-activation-ns = <0>;
-		gpmc,wait-monitoring-ns = <0>;
 		gpmc,wr-access-ns = <40>;
 		gpmc,wr-data-mux-bus-ns = <0>;
 		partition@0 {
arch/arm/boot/dts/dm814x.dtsi +4 -0
index 3fe68b1..b9a1470 100644
@@ -559,6 +559,10 @@
 			gpmc,num-waitpins = <2>;
 			#address-cells = <2>;
 			#size-cells = <1>;
+			gpio-controller;
+			#gpio-cells = <2>;
+			interrupt-controller;
+			#interrupt-cells = <2>;
 		};
 	};
 };
arch/arm/boot/dts/dra62x-j5eco-evm.dts +5 -3
index 3937a58..05b955c 100644
@@ -6,6 +6,7 @@
 /dts-v1/;
 
 #include "dra62x.dtsi"
+#include <dt-bindings/interrupt-controller/irq.h>
 
 / {
 	model = "DRA62x J5 Eco EVM";
@@ -39,8 +40,12 @@
 	ranges = <0 0 0x04000000 0x01000000>;	/* CS0: 16MB for NAND */
 
 	nand@0,0 {
+		compatible = "ti,omap2-nand";
 		linux,mtd-name= "micron,mt29f2g16aadwp";
 		reg = <0 0 4>; /* CS0, offset 0, IO size 4 */
+		interrupt-parent = <&gpmc>;
+		interrupts = <0 IRQ_TYPE_NONE>, /* fifoevent */
+			     <1 IRQ_TYPE_NONE>; /* termcount */
 		#address-cells = <1>;
 		#size-cells = <1>;
 		ti,nand-ecc-opt = "bch8";
@@ -60,12 +65,9 @@
 		gpmc,access-ns = <64>;
 		gpmc,rd-cycle-ns = <82>;
 		gpmc,wr-cycle-ns = <82>;
-		gpmc,wait-on-read = "true";
-		gpmc,wait-on-write = "true";
 		gpmc,bus-turnaround-ns = <0>;
 		gpmc,cycle2cycle-delay-ns = <0>;
 		gpmc,clk-activation-ns = <0>;
-		gpmc,wait-monitoring-ns = <0>;
 		gpmc,wr-access-ns = <40>;
 		gpmc,wr-data-mux-bus-ns = <0>;
 		partition@0 {
Signature · 1 line
2.1.4
#47 lore raw

PATCH v5 25/26 ARM: dts: dm816x: Fix gpmc and NAND node

In reply to Roger Quadros

Make gpmc node gpio+interrupt capable.

Add compatible id and interrupt to NAND node.

---
 arch/arm/boot/dts/dm8168-evm.dts | 8 +++++---
 arch/arm/boot/dts/dm816x.dtsi    | 4 ++++
 2 files changed, 9 insertions(+), 3 deletions(-)
arch/arm/boot/dts/dm8168-evm.dts +5 -3
index 169a855..f50348b 100644
@@ -6,6 +6,7 @@
 /dts-v1/;
 
 #include "dm816x.dtsi"
+#include <dt-bindings/interrupt-controller/irq.h>
 
 / {
 	model = "DM8168 EVM";
@@ -85,8 +86,12 @@
 	ranges = <0 0 0x04000000 0x01000000>;	/* CS0: 16MB for NAND */
 
 	nand@0,0 {
+		compatible = "ti,omap2-nand";
 		linux,mtd-name= "micron,mt29f2g16aadwp";
 		reg = <0 0 4>; /* CS0, offset 0, IO size 4 */
+		interrupt-parent = <&gpmc>;
+		interrupts = <0 IRQ_TYPE_NONE>, /* fifoevent */
+			     <1 IRQ_TYPE_NONE>; /* termcount */
 		#address-cells = <1>;
 		#size-cells = <1>;
 		ti,nand-ecc-opt = "bch8";
@@ -106,12 +111,9 @@
 		gpmc,access-ns = <64>;
 		gpmc,rd-cycle-ns = <82>;
 		gpmc,wr-cycle-ns = <82>;
-		gpmc,wait-on-read = "true";
-		gpmc,wait-on-write = "true";
 		gpmc,bus-turnaround-ns = <0>;
 		gpmc,cycle2cycle-delay-ns = <0>;
 		gpmc,clk-activation-ns = <0>;
-		gpmc,wait-monitoring-ns = <0>;
 		gpmc,wr-access-ns = <40>;
 		gpmc,wr-data-mux-bus-ns = <0>;
 		partition@0 {
arch/arm/boot/dts/dm816x.dtsi +4 -0
index c3b8811..115519e 100644
@@ -183,6 +183,10 @@
 			dma-names = "rxtx";
 			gpmc,num-cs = <6>;
 			gpmc,num-waitpins = <2>;
+			gpio-controller;
+			#gpio-cells = <2>;
+			interrupt-controller;
+			#interrupt-cells = <2>;
 		};
 
 		i2c1: i2c@48028000 {
Signature · 1 line
2.1.4
#48 lore raw

PATCH v5 26/26 ARM: dts: omap3: Fix gpmc and NAND nodes

In reply to Roger Quadros

Add compatible id, GPMC register resource and interrupt resource to NAND controller nodes.

The GPMC driver now implements gpiochip and irqchip so enable gpio-controller and interrupt-controller properties.

With this the interrupt parent of NAND node changes so fix it accordingly.

---
 arch/arm/boot/dts/logicpd-torpedo-37xx-devkit.dts |  3 ++-
 arch/arm/boot/dts/logicpd-torpedo-som.dtsi        |  8 ++++++--
 arch/arm/boot/dts/omap3-beagle.dts                |  5 ++++-
 arch/arm/boot/dts/omap3-cm-t3x.dtsi               |  6 +++++-
 arch/arm/boot/dts/omap3-devkit8000-common.dtsi    |  4 ++++
 arch/arm/boot/dts/omap3-evm-37xx.dts              |  8 ++++++--
 arch/arm/boot/dts/omap3-gta04.dtsi                |  4 ++++
 arch/arm/boot/dts/omap3-igep.dtsi                 |  6 +++++-
 arch/arm/boot/dts/omap3-igep0020-common.dtsi      |  4 ++--
 arch/arm/boot/dts/omap3-igep0030-common.dtsi      |  4 ++++
 arch/arm/boot/dts/omap3-ldp.dts                   | 10 +++++++---
 arch/arm/boot/dts/omap3-lilly-a83x.dtsi           |  6 +++++-
 arch/arm/boot/dts/omap3-overo-base.dtsi           |  6 +++++-
 arch/arm/boot/dts/omap3-pandora-common.dtsi       |  4 ++++
 arch/arm/boot/dts/omap3-tao3530.dtsi              |  6 +++++-
 arch/arm/boot/dts/omap3.dtsi                      |  4 ++++
 arch/arm/boot/dts/omap3430-sdp.dts                |  6 +++++-
 17 files changed, 77 insertions(+), 17 deletions(-)
arch/arm/boot/dts/logicpd-torpedo-37xx-devkit.dts +2 -1
index 874ce46..490f41a 100644
@@ -93,7 +93,8 @@
 };
 
 &gpmc {
-	ranges = <1 0 0x08000000 0x1000000>;	/* CS1: 16MB for LAN9221 */
+	ranges = <0 0 0x30000000 0x1000000	/* CS0: 16MB for NAND */
+		  1 0 0x2c000000 0x1000000>;	/* CS1: 16MB for LAN9221 */
 
 	ethernet@gpmc {
 		pinctrl-names = "default";
arch/arm/boot/dts/logicpd-torpedo-som.dtsi +6 -2
index 2eca34c..ed8a62a 100644
@@ -35,11 +35,15 @@
 };
 
 &gpmc {
-	ranges = <0 0 0x00000000 0x1000000>;	/* CS0: 16MB for NAND */
+	ranges = <0 0 0x30000000 0x1000000>;	/* CS0: 16MB for NAND */
 
 	nand@0,0 {
-		linux,mtd-name = "micron,mt29f4g16abbda3w";
+		compatible = "ti,omap2-nand";
 		reg = <0 0 4>; /* CS0, offset 0, IO size 4 */
+		interrupt-parent = <&gpmc>;
+		interrupts = <0 IRQ_TYPE_NONE>, /* fifoevent */
+			     <1 IRQ_TYPE_NONE>;	/* termcount */
+		linux,mtd-name = "micron,mt29f4g16abbda3w";
 		nand-bus-width = <16>;
 		ti,nand-ecc-opt = "bch8";
 		gpmc,sync-clk-ps = <0>;
arch/arm/boot/dts/omap3-beagle.dts +4 -1
index 8ba465d..4602866 100644
@@ -384,8 +384,11 @@
 
 	/* Chip select 0 */
 	nand@0,0 {
+		compatible = "ti,omap2-nand";
 		reg = <0 0 4>;		/* NAND I/O window, 4 bytes */
-		interrupts = <20>;
+		interrupt-parent = <&gpmc>;
+		interrupts = <0 IRQ_TYPE_NONE>, /* fifoevent */
+			     <1 IRQ_TYPE_NONE>;	/* termcount */
 		ti,nand-ecc-opt = "ham1";
 		nand-bus-width = <16>;
 		#address-cells = <1>;
arch/arm/boot/dts/omap3-cm-t3x.dtsi +5 -1
index e5f7f5c..a8127bc 100644
@@ -261,10 +261,14 @@
 };
 
 &gpmc {
-	ranges = <0 0 0x00000000 0x01000000>;
+	ranges = <0 0 0x30000000 0x01000000>;	/* CS0: 16MB for NAND */
 
 	nand@0,0 {
+		compatible = "ti,omap2-nand";
 		reg = <0 0 4>;	/* CS0, offset 0, IO size 4 */
+		interrupt-parent = <&gpmc>;
+		interrupts = <0 IRQ_TYPE_NONE>, /* fifoevent */
+			     <1 IRQ_TYPE_NONE>;	/* termcount */
 		nand-bus-width = <8>;
 		gpmc,device-width = <1>;
 		ti,nand-ecc-opt = "sw";
arch/arm/boot/dts/omap3-devkit8000-common.dtsi +4 -0
index 86850bb..b1b8ebf 100644
@@ -204,7 +204,11 @@
 	ranges = <0 0 0x30000000 0x1000000>;       /* CS0: 16MB for NAND */
 
 	nand@0,0 {
+		compatible = "ti,omap2-nand";
 		reg = <0 0 4>; /* CS0, offset 0, IO size 4 */
+		interrupt-parent = <&gpmc>;
+		interrupts = <0 IRQ_TYPE_NONE>, /* fifoevent */
+			     <1 IRQ_TYPE_NONE>;	/* termcount */
 		nand-bus-width = <16>;
 		gpmc,device-width = <2>;
 		ti,nand-ecc-opt = "sw";
arch/arm/boot/dts/omap3-evm-37xx.dts +6 -2
index ac18865..76056ba 100644
@@ -154,12 +154,16 @@
 };
 
 &gpmc {
-	ranges = <0 0 0x00000000 0x1000000>,	/* CS0: 16MB for NAND */
+	ranges = <0 0 0x30000000 0x1000000>,	/* CS0: 16MB for NAND */
 		 <5 0 0x2c000000 0x01000000>;
 
 	nand@0,0 {
+		compatible = "ti,omap2-nand";
+		reg = <0 0 4>; /* CS0, offset 0, IO size 4 */
+		interrupt-parent = <&gpmc>;
+		interrupts = <0 IRQ_TYPE_NONE>, /* fifoevent */
+			     <1 IRQ_TYPE_NONE>;	/* termcount */
 		linux,mtd-name= "hynix,h8kds0un0mer-4em";
-		reg = <0 0 4>;	/* CS0, offset 0, IO size 4 */
 		nand-bus-width = <16>;
 		gpmc,device-width = <2>;
 		ti,nand-ecc-opt = "bch8";
arch/arm/boot/dts/omap3-gta04.dtsi +4 -0
index 5e2d643..ab9fb8f 100644
@@ -492,7 +492,11 @@
 	ranges = <0 0 0x30000000 0x1000000>; /* CS0: 16MB for NAND */
 
 	nand@0,0 {
+		compatible = "ti,omap2-nand";
 		reg = <0 0 4>; /* CS0, offset 0, IO size 4 */
+		interrupt-parent = <&gpmc>;
+		interrupts = <0 IRQ_TYPE_NONE>, /* fifoevent */
+			     <1 IRQ_TYPE_NONE>;	/* termcount */
 		nand-bus-width = <16>;
 		ti,nand-ecc-opt = "bch8";
 
arch/arm/boot/dts/omap3-igep.dtsi +5 -1
index 4fc7e0f..41f5d38 100644
@@ -99,8 +99,12 @@
 
 &gpmc {
 	nand@0,0 {
+		compatible = "ti,omap2-nand";
+		reg = <0 0 4>; /* CS0, offset 0, IO size 4 */
+		interrupt-parent = <&gpmc>;
+		interrupts = <0 IRQ_TYPE_NONE>, /* fifoevent */
+			     <1 IRQ_TYPE_NONE>;	/* termcount */
 		linux,mtd-name= "micron,mt29c4g96maz";
-		reg = <0 0 4>;	/* CS0, offset 0, IO size 4 */
 		nand-bus-width = <16>;
 		gpmc,device-width = <2>;
 		ti,nand-ecc-opt = "bch8";
arch/arm/boot/dts/omap3-igep0020-common.dtsi +2 -2
index d90f12c..d6f839c 100644
@@ -210,8 +210,8 @@
 };
 
 &gpmc {
-	ranges = <0 0 0x00000000 0x20000000>,
-		 <5 0 0x2c000000 0x01000000>;
+	ranges = <0 0 0x30000000 0x01000000>,	/* CS0: 16MB for NAND */
+		 <5 0 0x2c000000 0x01000000>;	/* CS5: 16MB for ethernet */
 
 	ethernet@gpmc {
 		pinctrl-names = "default";
arch/arm/boot/dts/omap3-igep0030-common.dtsi +4 -0
index 63f8b9a..e94d942 100644
@@ -99,3 +99,7 @@
 	pinctrl-names = "default";
 	pinctrl-0 = <&uart2_pins>;
 };
+
+&gpmc {
+	ranges = <0 0 0x30000000 0x01000000>;   /* CS0: 16MB for NAND */
+};
arch/arm/boot/dts/omap3-ldp.dts +7 -3
index 5401630..2f353da 100644
@@ -97,12 +97,16 @@
 };
 
 &gpmc {
-	ranges = <0 0 0x00000000 0x01000000>,
-		 <1 0 0x08000000 0x01000000>;
+	ranges = <0 0 0x30000000 0x1000000>,	/* CS0 space, 16MB */
+		 <1 0 0x08000000 0x1000000>;	/* CS1 space, 16MB */
 
 	nand@0,0 {
+		compatible = "ti,omap2-nand";
+		reg = <0 0 4>; /* CS0, offset 0, IO size 4 */
+		interrupt-parent = <&gpmc>;
+		interrupts = <0 IRQ_TYPE_NONE>, /* fifoevent */
+			     <1 IRQ_TYPE_NONE>;	/* termcount */
 		linux,mtd-name= "micron,nand";
-		reg = <0 0 4>;	/* CS0, offset 0, IO size 4 */
 		nand-bus-width = <16>;
 		gpmc,device-width = <2>;
 		ti,nand-ecc-opt = "bch8";
arch/arm/boot/dts/omap3-lilly-a83x.dtsi +5 -1
index 93f8dfe..eff816e 100644
@@ -362,7 +362,11 @@
 		<7 0 0x15000000 0x01000000>;
 
 	nand@0,0 {
-		reg = <0 0 4>;	/* CS0, offset 0, IO size 4 */
+		compatible = "ti,omap2-nand";
+		reg = <0 0 4>; /* CS0, offset 0, IO size 4 */
+		interrupt-parent = <&gpmc>;
+		interrupts = <0 IRQ_TYPE_NONE>, /* fifoevent */
+			     <1 IRQ_TYPE_NONE>;	/* termcount */
 		nand-bus-width = <16>;
 		ti,nand-ecc-opt = "bch8";
 		/* no elm on omap3 */
arch/arm/boot/dts/omap3-overo-base.dtsi +5 -1
index a29ad16..de256fa 100644
@@ -226,8 +226,12 @@
 	ranges = <0 0 0x00000000 0x20000000>;
 
 	nand@0,0 {
+		compatible = "ti,omap2-nand";
 		linux,mtd-name= "micron,mt29c4g96maz";
-		reg = <0 0 0>;
+		reg = <0 0 4>;	/* CS0, offset 0, IO size 4 */
+		interrupt-parent = <&gpmc>;
+		interrupts = <0 IRQ_TYPE_NONE>, /* fifoevent */
+			     <1 IRQ_TYPE_NONE>;	/* termcount */
 		nand-bus-width = <16>;
 		gpmc,device-width = <2>;
 		ti,nand-ecc-opt = "bch8";
arch/arm/boot/dts/omap3-pandora-common.dtsi +4 -0
index 13e9d1f..bcf39d6 100644
@@ -546,7 +546,11 @@
 	ranges = <0 0 0x30000000 0x1000000>; /* CS0: 16MB for NAND */
 
 	nand@0,0 {
+		compatible = "ti,omap2-nand";
 		reg = <0 0 4>; /* CS0, offset 0, IO size 4 */
+		interrupt-parent = <&gpmc>;
+		interrupts = <0 IRQ_TYPE_NONE>, /* fifoevent */
+			     <1 IRQ_TYPE_NONE>;	/* termcount */
 		nand-bus-width = <16>;
 		ti,nand-ecc-opt = "sw";
 
arch/arm/boot/dts/omap3-tao3530.dtsi +5 -1
index ae5dbbd..644d3c8 100644
@@ -275,10 +275,14 @@
 };
 
 &gpmc {
-	ranges = <0 0 0x00000000 0x01000000>;
+	ranges = <0 0 0x30000000 0x01000000>;	/* CS0: 16MB for NAND */
 
 	nand@0,0 {
+		compatible = "ti,omap2-nand";
 		reg = <0 0 4>; /* CS0, offset 0, IO size 4 */
+		interrupt-parent = <&gpmc>;
+		interrupts = <0 IRQ_TYPE_NONE>, /* fifoevent */
+			     <1 IRQ_TYPE_NONE>;	/* termcount */
 		nand-bus-width = <16>;
 		gpmc,device-width = <2>;	/* GPMC_DEVWIDTH_16BIT */
 		ti,nand-ecc-opt = "sw";
arch/arm/boot/dts/omap3.dtsi +4 -0
index d1ffabb..9dbbcf6 100644
@@ -723,6 +723,10 @@
 			gpmc,num-waitpins = <4>;
 			#address-cells = <2>;
 			#size-cells = <1>;
+			gpio-controller;
+			#gpio-cells = <2>;
+			interrupt-controller;
+			#interrupt-cells = <2>;
 		};
 
 		usb_otg_hs: usb_otg_hs@480ab000 {
arch/arm/boot/dts/omap3430-sdp.dts +5 -1
index 16b0cdf..a0dc8d8 100644
@@ -103,10 +103,14 @@
 	};
 
 	nand@1,0 {
+		compatible = "ti,omap2-nand";
+		reg = <0 0 4>; /* CS0, offset 0, IO size 4 */
+		interrupt-parent = <&gpmc>;
+		interrupts = <0 IRQ_TYPE_NONE>, /* fifoevent */
+			     <1 IRQ_TYPE_NONE>;	/* termcount */
 		linux,mtd-name= "micron,mt29f1g08abb";
 		#address-cells = <1>;
 		#size-cells = <1>;
-		reg = <1 0 4>;	/* CS1, offset 0, IO size 4 */
 		ti,nand-ecc-opt = "sw";
 		nand-bus-width = <8>;
 		gpmc,cs-on-ns = <0>;
Signature · 1 line
2.1.4
maintainer
#49 lore raw
In reply to Roger Quadros
Quoted 7 lines · Roger Quadros

Hi,

@Tony
Patches 15 and 24 are new and will need your review.
I've modified patch 22 to include the new am335x boards introduced since v4.4.

Patches are based on top of omap-for-v4.6/dt so that the DT changes apply cleanly.

Looks OK to me. Can we merge the dts changes separately? Otherwise we will easily end up with tons of conflicts..

Regards,

Tony

#50 lore raw
Quoted 11 lines · Tony Lindgren
Quoted 7 lines · Roger Quadros

Hi,

@Tony
Patches 15 and 24 are new and will need your review.
I've modified patch 22 to include the new am335x boards introduced since v4.4.

Patches are based on top of omap-for-v4.6/dt so that the DT changes apply cleanly.

Looks OK to me. Can we merge the dts changes separately? Otherwise we will easily end up with tons of conflicts..

I agree. But we just need to keep in mind that NAND functionality will be broken till all the patches in this series are merged. We don't maintain backward compatibility with the old DT implementation.

Do you want me to send you the DT patches separately or you can pick up patches 18 to 26?

cheers,
-roger
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html

maintainer
#51 lore raw
Quoted 8 lines · Roger Quadros
Quoted 7 lines · Tony Lindgren
Quoted 6 lines · Roger Quadros

Hi,

@Tony
Patches 15 and 24 are new and will need your review.
I've modified patch 22 to include the new am335x boards introduced since v4.4.

Quoted 8 lines
Quoted 4 lines
Quoted 1 line

Patches are based on top of omap-for-v4.6/dt so that the DT changes apply cleanly.

Looks OK to me. Can we merge the dts changes separately? Otherwise we will easily end up with tons of conflicts..

I agree. But we just need to keep in mind that NAND functionality will be broken till all the patches in this series are merged. We don't maintain backward compatibility with the old DT implementation.

Please let's not do that! That breaks booting and git bisect. It's better to have a minimal branch where each patch boots fine.

Also, I think you should at least print a warning for the old binding. Otherwise people with out of tree boards will have hard time updating their patches to send to mainline tree.

Quoted 2 lines

Do you want me to send you the DT patches separately or you can pick up patches 18 to 26?

Sounds like some things need to be rearranged a bit first though :)

Regards,

Tony

#52 lore raw
Quoted 14 lines · Tony Lindgren
Quoted 13 lines · Roger Quadros
Quoted 11 lines · Tony Lindgren
Quoted 7 lines · Roger Quadros

Hi,

@Tony
Patches 15 and 24 are new and will need your review.
I've modified patch 22 to include the new am335x boards introduced since v4.4.

Patches are based on top of omap-for-v4.6/dt so that the DT changes apply cleanly.

Looks OK to me. Can we merge the dts changes separately? Otherwise we will easily end up with tons of conflicts..

Quoted 6 lines
Quoted 3 lines

I agree. But we just need to keep in mind that NAND functionality will be broken till all the patches in this series are merged. We don't maintain backward compatibility with the old DT implementation.

Please let's not do that! That breaks booting and git bisect. It's better to have a minimal branch where each patch boots fine.

Understood. I'll send out a patch set with only the minimal DT changes that doesn't break anything. This should be a preparatory step for the DT clean up.

Quoted 4 lines

Also, I think you should at least print a warning for the old binding. Otherwise people with out of tree boards will have hard time updating their patches to send to mainline tree.

OK. I'll add this warning mechanism to the omap-gpmc driver.

cheers,
-roger

#53 lore raw
Quoted 19 lines · Roger Quadros
Quoted 18 lines · Tony Lindgren
Quoted 16 lines · Roger Quadros
Quoted 11 lines · Tony Lindgren
Quoted 7 lines · Roger Quadros

Hi,

@Tony
Patches 15 and 24 are new and will need your review.
I've modified patch 22 to include the new am335x boards introduced since v4.4.

Patches are based on top of omap-for-v4.6/dt so that the DT changes apply cleanly.

Looks OK to me. Can we merge the dts changes separately? Otherwise we will easily end up with tons of conflicts..

I agree. But we just need to keep in mind that NAND functionality will be broken till all the patches in this series are merged. We don't maintain backward compatibility with the old DT implementation.

Quoted 7 lines
Quoted 2 lines

Please let's not do that! That breaks booting and git bisect. It's better to have a minimal branch where each patch boots fine.

Understood. I'll send out a patch set with only the minimal DT changes that doesn't break anything. This should be a preparatory step for the DT clean up.

Would you mind and try testing this on a few boards as even miminal DT changes can break things and thus I would like to see you test it if possible on the boards affected by the DT change.

Quoted 5 lines
Quoted 4 lines

Also, I think you should at least print a warning for the old binding. Otherwise people with out of tree boards will have hard time updating their patches to send to mainline tree.

Second that I agree with Tony on this it's just the reality. Nick

Quoted 9 lines

OK. I'll add this warning mechanism to the omap-gpmc driver.

cheers,
-roger

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

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

#54 lore raw
In reply to Roger Quadros

Brian,

Quoted 11 lines · Roger Quadros

Hi,

@Tony
Patches 15 and 24 are new and will need your review.
I've modified patch 22 to include the new am335x boards introduced since v4.4.

Patches are based on top of omap-for-v4.6/dt so that the DT changes apply cleanly.

@Brian
If you can Ack the MTD related changes we can push the series (excluding DT patches) to an immutable branch and you can then pull it into l2-mtd.git

Gentle ping on this. Thanks.

cheers,
-roger

Quoted 124 lines

Patches tested on:
dra-evm, am437x-gp-evm, beagleboard-c4, beagleboard-c4-legacyboot

Changelog:
v5:

(quoted diff) +0 -2
-changed ready/busy# GPIO DT binding from "ready-gpio" to "rb-gpios".
-use irqdomain for gpmc NAND interrupts: fifoevent and termcount

v4:
-Warn if using older incompatible DT i.e. compatible property not present in nand node.
-Applied Tony's patch to fix broken ethernet on torpedo.

v3:

(quoted diff) +0 -3
-Fixed and tested NAND using legacy boot on omap3-beagle.
-Support rising and falling edge interrupts on WAITpins.
-Update DT node of all gpmc users.

Patches summary:

We do a couple of things in this series which result in cleaner device tree implementation, faster perfomance and multi-platform support. As an added bonus we get to use the GPMC_WAIT pins as GPI/Interrupts.

- Establish a custom interface between NAND and GPMC driver. This is needed because all of the NAND registers sit in the GPMC register space.

- Clean up device tree support so that omap-gpmc IP and the omap2 NAND driver can be used on non-OMAP platforms. e.g. Keystone.

- Implement GPIOCHIP for the GPMC WAITPINS. SoCs can contain
2 to 4 of these and most of them would be unused otherwise. It also allows a cleaner implementation of NAND Ready pin status for the NAND driver.

- Implement GPMC IRQ domain to proivde the 2 NAND events and GPMC WAITPIN edge interrupts.

- Implement GPIOlib based NAND ready pin checking for OMAP NAND driver. On dra7-evm, Read speed increases from 13768 KiB/ to 17246 KiB/s. Write speed was unchanged at 7123 KiB/s.

This series is available at git-9UaJU3cA/F/[email protected]:rogerq/linux.git in branch
for-v4.6/gpmc-v5

--
cheers,
-roger

Roger Quadros (26):
ARM: OMAP2+: gpmc: Add platform data
ARM: OMAP2+: gpmc: Add gpmc timings and settings to platform data
memory: omap-gpmc: Introduce GPMC to NAND interface
mtd: nand: omap2: Use gpmc_omap_get_nand_ops() to get NAND registers
memory: omap-gpmc: Add GPMC-NAND ops to get writebufferempty status
mtd: nand: omap2: Switch to using GPMC-NAND ops for writebuffer empty
check
memory: omap-gpmc: Implement IRQ domain for NAND IRQs
mtd: nand: omap: Copy platform data parameters to omap_nand_info data
mtd: nand: omap: Clean up device tree support
mtd: nand: omap: Update DT binding documentation
memory: omap-gpmc: Prevent mapping into 1st 16MB
memory: omap-gpmc: Move device tree binding to correct location
memory: omap-gpmc: Support general purpose input for WAITPINs
memory: omap-gpmc: Reserve WAITPIN if needed for WAIT monitoring
memory: omap-gpmc: Support WAIT pin edge interrupts
memory: omap-gpmc: Prevent GPMC_STATUS from being accessed via
gpmc_regs
mtd: nand: omap2: Implement NAND ready using gpiolib
ARM: dts: dra7: Fix NAND device nodes.
ARM: dts: dra7x-evm: Provide NAND ready pin
ARM: dts: am437x: Fix NAND device nodes
ARM: dts: am437x: Provide NAND ready pin
ARM: dts: am335x: Fix NAND device nodes
ARM: dts: am335x: Provide NAND ready pin
ARM: dts: dm814x: Fix gpmc and NAND node
ARM: dts: dm816x: Fix gpmc and NAND node
ARM: dts: omap3: Fix gpmc and NAND nodes

 Documentation/devicetree/bindings/bus/ti-gpmc.txt  | 130 ----
 .../bindings/memory-controllers/omap-gpmc.txt      | 141 +++++
 .../devicetree/bindings/mtd/gpmc-nand.txt          |  19 +-
 arch/arm/boot/dts/am335x-baltos-ir5221.dts         |  10 +-
 arch/arm/boot/dts/am335x-chilisom.dtsi             |   9 +-
 arch/arm/boot/dts/am335x-cm-t335.dts               |  10 +-
 arch/arm/boot/dts/am335x-evm.dts                   |   8 +-
 arch/arm/boot/dts/am335x-igep0033.dtsi             |   9 +-
 arch/arm/boot/dts/am335x-phycore-som.dtsi          |   9 +-
 arch/arm/boot/dts/am33xx.dtsi                      |   4 +
 arch/arm/boot/dts/am4372.dtsi                      |   4 +
 arch/arm/boot/dts/am437x-cm-t43.dts                |   7 +-
 arch/arm/boot/dts/am437x-gp-evm.dts                |   9 +-
 arch/arm/boot/dts/am43x-epos-evm.dts               |   9 +-
 arch/arm/boot/dts/dm8148-evm.dts                   |   8 +-
 arch/arm/boot/dts/dm814x.dtsi                      |   4 +
 arch/arm/boot/dts/dm8168-evm.dts                   |   8 +-
 arch/arm/boot/dts/dm816x.dtsi                      |   4 +
 arch/arm/boot/dts/dra62x-j5eco-evm.dts             |   8 +-
 arch/arm/boot/dts/dra7-evm.dts                     |   7 +-
 arch/arm/boot/dts/dra7.dtsi                        |   4 +
 arch/arm/boot/dts/dra72-evm.dts                    |   7 +-
 arch/arm/boot/dts/logicpd-torpedo-37xx-devkit.dts  |   3 +-
 arch/arm/boot/dts/logicpd-torpedo-som.dtsi         |   8 +-
 arch/arm/boot/dts/omap3-beagle.dts                 |   5 +-
 arch/arm/boot/dts/omap3-cm-t3x.dtsi                |   6 +-
 arch/arm/boot/dts/omap3-devkit8000-common.dtsi     |   4 +
 arch/arm/boot/dts/omap3-evm-37xx.dts               |   8 +-
 arch/arm/boot/dts/omap3-gta04.dtsi                 |   4 +
 arch/arm/boot/dts/omap3-igep.dtsi                  |   6 +-
 arch/arm/boot/dts/omap3-igep0020-common.dtsi       |   4 +-
 arch/arm/boot/dts/omap3-igep0030-common.dtsi       |   4 +
 arch/arm/boot/dts/omap3-ldp.dts                    |  10 +-
 arch/arm/boot/dts/omap3-lilly-a83x.dtsi            |   6 +-
 arch/arm/boot/dts/omap3-overo-base.dtsi            |   6 +-
 arch/arm/boot/dts/omap3-pandora-common.dtsi        |   4 +
 arch/arm/boot/dts/omap3-tao3530.dtsi               |   6 +-
 arch/arm/boot/dts/omap3.dtsi                       |   4 +
 arch/arm/boot/dts/omap3430-sdp.dts                 |   6 +-
 arch/arm/mach-omap2/gpmc-nand.c                    |   7 +-
 drivers/memory/Kconfig                             |   1 +
 drivers/memory/omap-gpmc.c                         | 653 +++++++++++++--------
Quoted 9 lines
 drivers/mtd/nand/omap2.c                           | 193 ++++--
 include/linux/omap-gpmc.h                          | 177 ++----
 include/linux/platform_data/gpmc-omap.h            | 167 ++++++
 include/linux/platform_data/mtd-nand-omap2.h       |  12 +-
 46 files changed, 1121 insertions(+), 611 deletions(-)
 delete mode 100644 Documentation/devicetree/bindings/bus/ti-gpmc.txt
 create mode 100644 Documentation/devicetree/bindings/memory-controllers/omap-gpmc.txt
 create mode 100644 include/linux/platform_data/gpmc-omap.h

--
To unsubscribe from this list: send the line "unsubscribe devicetree" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html

Acked-by
#55 lore raw
Quoted 7 lines · Roger Quadros
Quoted 6 lines · Roger Quadros

Hi,

@Tony
Patches 15 and 24 are new and will need your review.
I've modified patch 22 to include the new am335x boards introduced since v4.4.

Quoted 7 lines
Quoted 5 lines

Patches are based on top of omap-for-v4.6/dt so that the DT changes apply cleanly.

@Brian
If you can Ack the MTD related changes we can push the series (excluding DT patches) to an immutable branch and you can then pull it into l2-mtd.git

Gentle ping on this. Thanks.

I think this series looks a lot better. I don't think I have any fundamental issues with the MTD stuff, aside from the one comment about the 'reg' property. If we get a satisfactory answer for that (and you fix the small stuff), then:

(That's also presuming the relevant players are all on board with the DT "ABI" breakage. But I think your old binding really needed a fixup, so the warning might be sufficient.)

Brian
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html