[PATCH 01/36] ARM: OMAP3: hwmod: Fix gpmc memory resource space

2014-06-11 Thread Roger Quadros
Signed-off-by: Roger Quadros rog...@ti.com
---
 arch/arm/mach-omap2/omap_hwmod_3xxx_data.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c 
b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c
index 71ac7d5..f2848a8 100644
--- a/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c
+++ b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c
@@ -3426,7 +3426,7 @@ static struct omap_hwmod_addr_space 
omap3xxx_counter_32k_addrs[] = {
 static struct omap_hwmod_addr_space omap3xxx_gpmc_addrs[] = {
{
.pa_start   = 0x6e00,
-   .pa_end = 0x6e000fff,
+   .pa_end = 0x6e0002d4,
.flags  = ADDR_TYPE_RT
},
{ }
-- 
1.8.3.2

--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 36/36] ARM: OMAP2+: defconfig: Enable TI GPMC driver

2014-06-11 Thread Roger Quadros
This is needed for NAND and OneNAND to work.

Signed-off-by: Roger Quadros rog...@ti.com
---
 arch/arm/configs/omap2plus_defconfig | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/arch/arm/configs/omap2plus_defconfig 
b/arch/arm/configs/omap2plus_defconfig
index a4e8d01..98dad6c 100644
--- a/arch/arm/configs/omap2plus_defconfig
+++ b/arch/arm/configs/omap2plus_defconfig
@@ -79,6 +79,8 @@ CONFIG_DEVTMPFS_MOUNT=y
 CONFIG_DMA_CMA=y
 CONFIG_OMAP_OCP2SCP=y
 CONFIG_CONNECTOR=y
+CONFIG_MEMORY=y
+CONFIG_TI_GPMC=y
 CONFIG_MTD=y
 CONFIG_MTD_CMDLINE_PARTS=y
 CONFIG_MTD_BLOCK=y
-- 
1.8.3.2

--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 33/36] ARM: OMAP2+: board-flash: Use gpmc_generic_init() for NOR

2014-06-11 Thread Roger Quadros
Don't access any GPMC registers here. Use gpmc_generic_init()
to pass GPMC Chip Select settings, platform device and platform data
to the GPMC driver.

Signed-off-by: Roger Quadros rog...@ti.com
---
 arch/arm/mach-omap2/board-flash.c | 28 +++-
 1 file changed, 11 insertions(+), 17 deletions(-)

diff --git a/arch/arm/mach-omap2/board-flash.c 
b/arch/arm/mach-omap2/board-flash.c
index b6885e4..617e441 100644
--- a/arch/arm/mach-omap2/board-flash.c
+++ b/arch/arm/mach-omap2/board-flash.c
@@ -41,7 +41,10 @@ static struct physmap_flash_data board_nor_data = {
 };
 
 static struct resource board_nor_resource = {
+   /* GPMC driver will fixup the resource, see gpmc_probe_legacy () */
.flags  = IORESOURCE_MEM,
+   .start  = 0,
+   .end= FLASH_SIZE_SDPV1 - 1, /* fixed @runtime for SDPV2 */
 };
 
 static struct platform_device board_nor_device = {
@@ -62,23 +65,14 @@ __init board_nor_init(struct mtd_partition *nor_parts, u8 
nr_parts, u8 cs)
board_nor_data.parts= nor_parts;
board_nor_data.nr_parts = nr_parts;
 
-   /* Configure start address and size of NOR device */
-   if (omap_rev() = OMAP3430_REV_ES1_0) {
-   err = gpmc_cs_request(cs, FLASH_SIZE_SDPV2 - 1,
-   (unsigned long *)board_nor_resource.start);
-   board_nor_resource.end = board_nor_resource.start
-   + FLASH_SIZE_SDPV2 - 1;
-   } else {
-   err = gpmc_cs_request(cs, FLASH_SIZE_SDPV1 - 1,
-   (unsigned long *)board_nor_resource.start);
-   board_nor_resource.end = board_nor_resource.start
-   + FLASH_SIZE_SDPV1 - 1;
-   }
-   if (err  0) {
-   pr_err(NOR: Can't request GPMC CS\n);
-   return;
-   }
-   if (platform_device_register(board_nor_device)  0)
+   /* Configure size of NOR device */
+   if (omap_rev() = OMAP3430_REV_ES1_0)
+   board_nor_resource.end = FLASH_SIZE_SDPV2 - 1;
+
+   err = gpmc_generic_init(cs, false,
+   NULL, NULL, NULL,
+   board_nor_device, sizeof(board_nor_data));
+   if (err)
pr_err(Unable to register NOR device\n);
 }
 
-- 
1.8.3.2

--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 34/36] ARM: OMAP2+: gpmc: Make externally unused functions/defines private

2014-06-11 Thread Roger Quadros
Most of the GPMC functions are now not used by other drivers.
Make them private.

Signed-off-by: Roger Quadros rog...@ti.com
---
 arch/arm/mach-omap2/gpmc.c | 84 ++
 arch/arm/mach-omap2/gpmc.h | 63 --
 2 files changed, 56 insertions(+), 91 deletions(-)

diff --git a/arch/arm/mach-omap2/gpmc.c b/arch/arm/mach-omap2/gpmc.c
index 7a667ca..9173f71 100644
--- a/arch/arm/mach-omap2/gpmc.c
+++ b/arch/arm/mach-omap2/gpmc.c
@@ -80,6 +80,45 @@
 #define GPMC_ECC_CTRL_ECCREG8  0x008
 #define GPMC_ECC_CTRL_ECCREG9  0x009
 
+/* ECC commands */
+#define GPMC_ECC_READ  0 /* Reset Hardware ECC for read */
+#define GPMC_ECC_WRITE 1 /* Reset Hardware ECC for write */
+#define GPMC_ECC_READSYN   2 /* Reset before syndrom is read back */
+
+/* CS CONFIG registers */
+#define GPMC_CS_CONFIG10x00
+#define GPMC_CS_CONFIG20x04
+#define GPMC_CS_CONFIG30x08
+#define GPMC_CS_CONFIG40x0c
+#define GPMC_CS_CONFIG50x10
+#define GPMC_CS_CONFIG60x14
+#define GPMC_CS_CONFIG70x18
+
+#define GPMC_CONFIG1_WRAPBURST_SUPP (1  31)
+#define GPMC_CONFIG1_READMULTIPLE_SUPP  (1  30)
+#define GPMC_CONFIG1_READTYPE_ASYNC (0  29)
+#define GPMC_CONFIG1_READTYPE_SYNC  (1  29)
+#define GPMC_CONFIG1_WRITEMULTIPLE_SUPP (1  28)
+#define GPMC_CONFIG1_WRITETYPE_ASYNC(0  27)
+#define GPMC_CONFIG1_WRITETYPE_SYNC (1  27)
+#define GPMC_CONFIG1_CLKACTIVATIONTIME(val) ((val  3)  25)
+#define GPMC_CONFIG1_PAGE_LEN(val)  ((val  3)  23)
+#define GPMC_CONFIG1_WAIT_READ_MON  (1  22)
+#define GPMC_CONFIG1_WAIT_WRITE_MON (1  21)
+#define GPMC_CONFIG1_WAIT_MON_IIME(val) ((val  3)  18)
+#define GPMC_CONFIG1_WAIT_PIN_SEL(val)  ((val  3)  16)
+#define GPMC_CONFIG1_DEVICESIZE(val)((val  3)  12)
+#define GPMC_CONFIG1_DEVICESIZE_16  GPMC_CONFIG1_DEVICESIZE(1)
+#define GPMC_CONFIG1_DEVICETYPE(val)((val  3)  10)
+#define GPMC_CONFIG1_DEVICETYPE_NOR GPMC_CONFIG1_DEVICETYPE(0)
+#define GPMC_CONFIG1_MUXTYPE(val)   ((val  3)  8)
+#define GPMC_CONFIG1_TIME_PARA_GRAN (1  4)
+#define GPMC_CONFIG1_FCLK_DIV(val)  (val  3)
+#define GPMC_CONFIG1_FCLK_DIV2  (GPMC_CONFIG1_FCLK_DIV(1))
+#define GPMC_CONFIG1_FCLK_DIV3  (GPMC_CONFIG1_FCLK_DIV(2))
+#define GPMC_CONFIG1_FCLK_DIV4  (GPMC_CONFIG1_FCLK_DIV(3))
+#define GPMC_CONFIG7_CSVALID   (1  6)
+
 #defineGPMC_CONFIG2_CSEXTRADELAY   BIT(7)
 #defineGPMC_CONFIG3_ADVEXTRADELAY  BIT(7)
 #defineGPMC_CONFIG4_OEEXTRADELAY   BIT(7)
@@ -87,6 +126,12 @@
 #defineGPMC_CONFIG6_CYCLE2CYCLEDIFFCSENBIT(6)
 #defineGPMC_CONFIG6_CYCLE2CYCLESAMECSENBIT(7)
 
+#define GPMC_DEVICETYPE_NOR0
+#define GPMC_DEVICETYPE_NAND   2
+#define WR_RD_PIN_MONITORING   0x0060
+#define GPMC_IRQ_FIFOEVENTENABLE   0x01
+#define GPMC_IRQ_COUNT_EVENT   0x02
+
 #define GPMC_CS0_OFFSET0x60
 #define GPMC_CS_SIZE   0x30
 #defineGPMC_BCH_SIZE   0x10
@@ -163,7 +208,7 @@ static u32 gpmc_read_reg(int idx)
return __raw_readl(gpmc_base + idx);
 }
 
-void gpmc_cs_write_reg(int cs, int idx, u32 val)
+static void gpmc_cs_write_reg(int cs, int idx, u32 val)
 {
void __iomem *reg_addr;
 
@@ -215,11 +260,6 @@ static unsigned int gpmc_ps_to_ticks(unsigned int time_ps)
return (time_ps + tick_ps - 1) / tick_ps;
 }
 
-unsigned int gpmc_ticks_to_ns(unsigned int ticks)
-{
-   return ticks * gpmc_get_fclk_period() / 1000;
-}
-
 static unsigned int gpmc_ticks_to_ps(unsigned int ticks)
 {
return ticks * gpmc_get_fclk_period();
@@ -315,7 +355,7 @@ static int set_gpmc_timing_reg(int cs, int reg, int st_bit, 
int end_bit,
return -1
 #endif
 
-int gpmc_calc_divider(unsigned int sync_clk)
+static int gpmc_calc_divider(unsigned int sync_clk)
 {
int div;
u32 l;
@@ -330,7 +370,7 @@ int gpmc_calc_divider(unsigned int sync_clk)
return div;
 }
 
-int gpmc_cs_set_timings(int cs, const struct gpmc_timings *t)
+static int gpmc_cs_set_timings(int cs, const struct gpmc_timings *t)
 {
int div;
u32 l;
@@ -537,7 +577,7 @@ static int gpmc_cs_remap(int cs, u32 base)
return 0;
 }
 
-int gpmc_cs_request(int cs, unsigned long size, unsigned long *base)
+static int gpmc_cs_request(int cs, unsigned long size, unsigned long *base)
 {
struct resource *res = gpmc_cs_mem[cs];
int r = -1;
@@ -575,9 +615,8 @@ out:
spin_unlock(gpmc_mem_lock);
return r;
 }
-EXPORT_SYMBOL(gpmc_cs_request);
 
-void gpmc_cs_free(int cs)
+static void gpmc_cs_free(int cs)
 {
struct resource *res = gpmc_cs_mem[cs];
 
@@ -594,18 +633,6 @@ void gpmc_cs_free(int cs)
gpmc_cs_set_reserved(cs, 0);
spin_unlock(gpmc_mem_lock);
 }

[PATCH 28/36] ARM: OMAP2+: nand: Update gpmc_nand_init() to use generic_gpmc_init()

2014-06-11 Thread Roger Quadros
This function should only be called by board init code for
legacy boot.

Re-arrange init order so that gpmc device is created after
the gpmc platform data is initialized by board files.
i.e. move omap_gpmc_init() to subsys_initcall.

Load gpmc platform driver later in the boot process.
i.e. move gpmc_init() to module_initcall.

NOTE: this will break legacy boot since they call gpmc_cs_*()
functions before gpmc_mem_init() is called. They will eventually
be fixed.

Signed-off-by: Roger Quadros rog...@ti.com
---
 arch/arm/mach-omap2/gpmc-nand.c | 51 -
 arch/arm/mach-omap2/gpmc.c  | 17 +-
 2 files changed, 21 insertions(+), 47 deletions(-)

diff --git a/arch/arm/mach-omap2/gpmc-nand.c b/arch/arm/mach-omap2/gpmc-nand.c
index f7491d0..42371e3 100644
--- a/arch/arm/mach-omap2/gpmc-nand.c
+++ b/arch/arm/mach-omap2/gpmc-nand.c
@@ -25,9 +25,12 @@
 #defineNAND_IO_SIZE4
 
 static struct resource gpmc_nand_resource[] = {
+/* GPMC driver will fixup all the resources, see gpmc_probe_legacy () */
{
/* GPMC I/O space */
.flags  = IORESOURCE_MEM,
+   .start  = 0,
+   .end= NAND_IO_SIZE - 1,
},
{
/* GPMC register space */
@@ -95,61 +98,27 @@ int gpmc_nand_init(struct omap_nand_platform_data 
*gpmc_nand_data,
 {
int err = 0;
struct gpmc_settings s;
-   struct device *dev = gpmc_nand_device.dev;
-   struct resource res;
 
memset(s, 0, sizeof(struct gpmc_settings));
 
gpmc_nand_device.dev.platform_data = gpmc_nand_data;
 
-   err = gpmc_cs_request(gpmc_nand_data-cs, NAND_IO_SIZE,
-   (unsigned long *)gpmc_nand_resource[0].start);
-   if (err  0) {
-   dev_err(dev, Cannot request GPMC CS %d, error %d\n,
-   gpmc_nand_data-cs, err);
-   return err;
-   }
-
-   gpmc_nand_resource[0].end = gpmc_nand_resource[0].start +
-   NAND_IO_SIZE - 1;
-
-   gpmc_get_mem_resource(res);
-   gpmc_nand_resource[1].start = res.start;
-   gpmc_nand_resource[1].end = res.end;
-
-   gpmc_nand_resource[2].start = gpmc_get_irq();
-
-   if (gpmc_t) {
-   err = gpmc_cs_set_timings(gpmc_nand_data-cs, gpmc_t);
-   if (err  0) {
-   dev_err(dev, Unable to set gpmc timings: %d\n, err);
-   return err;
-   }
-   }
-
gpmc_set_legacy(gpmc_nand_data, s);
 
s.device_nand = true;
 
-   err = gpmc_cs_program_settings(gpmc_nand_data-cs, s);
-   if (err  0)
-   goto out_free_cs;
-
if (!gpmc_hwecc_bch_capable(gpmc_nand_data-ecc_opt)) {
-   dev_err(dev, Unsupported NAND ECC scheme selected\n);
+   pr_err(%s: Unsupported NAND ECC scheme selected\n, __func__);
return -EINVAL;
}
 
-   err = platform_device_register(gpmc_nand_device);
-   if (err  0) {
-   dev_err(dev, Unable to register NAND device\n);
-   goto out_free_cs;
+   err = gpmc_generic_init(gpmc_nand_data-cs, true,
+   s, NULL, gpmc_t,
+   gpmc_nand_device, sizeof(*gpmc_nand_data));
+   if (err) {
+   pr_err(%s: gpmc_generic_init() failed %d\n, __func__, err);
+   return err;
}
 
return 0;
-
-out_free_cs:
-   gpmc_cs_free(gpmc_nand_data-cs);
-
-   return err;
 }
diff --git a/arch/arm/mach-omap2/gpmc.c b/arch/arm/mach-omap2/gpmc.c
index 34545ca..7a667ca 100644
--- a/arch/arm/mach-omap2/gpmc.c
+++ b/arch/arm/mach-omap2/gpmc.c
@@ -1401,9 +1401,6 @@ static void gpmc_probe_legacy(struct platform_device 
*pdev)
gpmc_cs_num = GPMC_CS_NUM;
gpmc_nr_waitpins = GPMC_NR_WAITPINS;
 
-   if (!gpmc_pdata)
-   return;
-
for (i = 0; i  GPMC_CS_NUM; i++) {
cs = gpmc_pdata-cs[i];
if (!cs-valid)
@@ -1609,6 +1606,12 @@ static int gpmc_probe(struct platform_device *pdev)
}
} else {
/* Legacy probing based on platform data */
+   if (!dev-platform_data) {
+   dev_err(dev, No platform data\n);
+   rc = -EINVAL;
+   goto error;
+   }
+
gpmc_probe_legacy(pdev);
}
 
@@ -1669,7 +1672,7 @@ static __exit void gpmc_exit(void)
 
 }
 
-omap_postcore_initcall(gpmc_init);
+module_init(gpmc_init);
 module_exit(gpmc_exit);
 
 static int __init omap_gpmc_init(void)
@@ -1691,12 +1694,14 @@ static int __init omap_gpmc_init(void)
return -ENODEV;
}
 
-   pdev = omap_device_build(DEVICE_NAME, -1, oh, NULL, 0);
+   pdev = omap_device_build(DEVICE_NAME, -1, oh, (void *)gpmc_pdata,
+

[PATCH 25/36] ARM: OMAP2+: gpmc: Support multiple Chip Selects per device

2014-06-11 Thread Roger Quadros
Some devices (e.g. tusb6010) need 2 chip selects to work with
2 separate IOMEM resources. Allow such use case. The user just
needs to call gpmc_generic_init() for as many chip selects
with the same platform_device pointer. The GPMC driver will
take care of fixing up the memory resources.

Signed-off-by: Roger Quadros rog...@ti.com
---
 arch/arm/mach-omap2/gpmc.c | 134 ++---
 1 file changed, 91 insertions(+), 43 deletions(-)

diff --git a/arch/arm/mach-omap2/gpmc.c b/arch/arm/mach-omap2/gpmc.c
index 5563360..34545ca 100644
--- a/arch/arm/mach-omap2/gpmc.c
+++ b/arch/arm/mach-omap2/gpmc.c
@@ -1388,9 +1388,14 @@ static int gpmc_nand_setup(struct platform_device 
*parent_pdev,
 
 static void gpmc_probe_legacy(struct platform_device *pdev)
 {
-   int i, rc;
+   int i, rc, j;
struct device *dev = pdev-dev;
struct gpmc_omap_platform_data *gpmc_pdata;
+   struct resource *mem_res;
+   unsigned long cs_base;
+   resource_size_t size;
+   struct gpmc_timings gpmc_timings;
+   struct gpmc_omap_cs_data *cs;
 
gpmc_pdata = dev-platform_data;
gpmc_cs_num = GPMC_CS_NUM;
@@ -1400,52 +1405,10 @@ static void gpmc_probe_legacy(struct platform_device 
*pdev)
return;
 
for (i = 0; i  GPMC_CS_NUM; i++) {
-   struct resource *mem_res;
-   unsigned long cs_base;
-   resource_size_t size;
-   struct gpmc_timings gpmc_timings;
-   struct gpmc_omap_cs_data *cs;
-
cs = gpmc_pdata-cs[i];
if (!cs-valid)
continue;
 
-   /*
-* Request a CS space. Use size from
-* platform device's MEM resource
-*/
-   if (!cs-pdev)
-   goto skip_mem;
-
-   mem_res = cs-pdev-resource;
-   if (cs-pdev-num_resources  1 ||
-   resource_type(mem_res) != IORESOURCE_MEM) {
-   dev_err(dev, Invalid IOMEM resource for CS %d\n, i);
-   continue;
-   }
-
-   size = mem_res-end - mem_res-start + 1;
-   if (gpmc_cs_request(i, size, cs_base)) {
-   dev_err(dev, Couldn't request resource for CS %d\n,
-   i);
-   continue;
-   }
-
-   mem_res-start = cs_base;
-   mem_res-end = cs_base + size - 1;
-
-   /* FIXME: When do we need to call gpmc_cs_remap()? */
-skip_mem:
-
-   /* Customized NAND setup */
-   if (cs-is_nand) {
-   if (gpmc_nand_setup(pdev, cs)) {
-   dev_err(dev, Error setting up NAND on CS %d\n,
-   i);
-   continue;
-   }
-   }
-
if (cs-settings) {
if (gpmc_cs_program_settings(i, cs-settings)) {
dev_err(dev,
@@ -1474,10 +1437,95 @@ skip_mem:
continue;
}
}
+   }
+
+   /*
+* All Chip Selects must be configured before platform devices are
+* created as some devices (e.g. tusb6010) can use multiple
+* Chip selects.
+*/
+
+   /* Fixup Memory resources */
+   for (i = 0; i  GPMC_CS_NUM; i++) {
+   int required_resources;
+
+   cs = gpmc_pdata-cs[i];
+   if (!cs-valid)
+   continue;
 
if (!cs-pdev)
continue;
 
+   /* Customized NAND setup */
+   if (cs-is_nand) {
+   if (gpmc_nand_setup(pdev, cs)) {
+   dev_err(dev, Error setting up NAND on CS %d\n,
+   i);
+   continue;
+   }
+   }
+
+   mem_res = cs-pdev-resource;
+
+   /*
+* If device is present multiple times, fix the subsequent
+* resources
+*/
+   required_resources = 1;
+   for (j = 0; j  i; j++) {
+   if (gpmc_pdata-cs[j].pdev == cs-pdev) {
+   mem_res++;
+   required_resources++;
+   }
+   }
+
+   if (cs-pdev-num_resources  required_resources ||
+   resource_type(mem_res) != IORESOURCE_MEM) {
+   dev_err(dev, Invalid IOMEM resource for CS %d\n, i);
+   continue;
+   }
+
+   /*
+* Request a CS space. Use size from
+* platform device's MEM resource
+*/
+   size = mem_res-end - mem_res-start + 

[PATCH 26/36] ARM: OMAP2+: gpmc-smc91x: Get rid of retime() from omap_smc91x_platform_data

2014-06-11 Thread Roger Quadros
The retime() function is not provided by board files so get rid of
it from omap_smc91x_platform_data().

Instead change it to smc91c96_get_device_timing() to get the device
timings.

Signed-off-by: Roger Quadros rog...@ti.com
---
 arch/arm/mach-omap2/board-3430sdp.c |  8 --
 arch/arm/mach-omap2/gpmc-smc91x.c   | 55 ++---
 arch/arm/mach-omap2/gpmc-smc91x.h   |  1 -
 3 files changed, 27 insertions(+), 37 deletions(-)

diff --git a/arch/arm/mach-omap2/board-3430sdp.c 
b/arch/arm/mach-omap2/board-3430sdp.c
index d95d0ef..b781090 100644
--- a/arch/arm/mach-omap2/board-3430sdp.c
+++ b/arch/arm/mach-omap2/board-3430sdp.c
@@ -411,8 +411,12 @@ static int __init omap3430_i2c_init(void)
 
 static struct omap_smc91x_platform_data board_smc91x_data = {
.cs = 3,
-   .flags  = GPMC_MUX_ADD_DATA | GPMC_TIMINGS_SMC91C96 |
-   IORESOURCE_IRQ_LOWLEVEL,
+   /*
+* Don't use GPMC_TIMINGS_SMC91C96 flag here as generic
+* timing doesn't seem to have worked.
+* Leave bootloader timing intact.
+*/
+   .flags  = GPMC_MUX_ADD_DATA | IORESOURCE_IRQ_LOWLEVEL,
 };
 
 static void __init board_smc91x_init(void)
diff --git a/arch/arm/mach-omap2/gpmc-smc91x.c 
b/arch/arm/mach-omap2/gpmc-smc91x.c
index 61a0635..7f5d84a 100644
--- a/arch/arm/mach-omap2/gpmc-smc91x.c
+++ b/arch/arm/mach-omap2/gpmc-smc91x.c
@@ -59,10 +59,8 @@ static struct gpmc_settings smc91x_settings = {
  * http://www.smsc.com/main/catalog/lan91c96.html
  * REVISIT: Level shifters can add at least to the access latency.
  */
-static int smc91c96_gpmc_retime(void)
+static void smc91c96_get_device_timing(struct gpmc_device_timings *dev_t)
 {
-   struct gpmc_timings t;
-   struct gpmc_device_timings dev_t;
const int t3 = 10;  /* Figure 12.2 read and 12.4 write */
const int t4_r = 20;/* Figure 12.2 read */
const int t4_w = 5; /* Figure 12.4 write */
@@ -72,33 +70,19 @@ static int smc91c96_gpmc_retime(void)
const int t8 = 5;   /* Figure 12.4 write */
const int t20 = 185;/* Figure 12.2 read and 12.4 write */
 
-   /*
-* FIXME: Calculate the address and data bus muxed timings.
-* Note that at least adv_rd_off needs to be changed according
-* to omap3430 TRM Figure 11-11. Are the sdp boards using the
-* FPGA in between smc91x and omap as the timings are different
-* from above?
-*/
-   if (gpmc_cfg-flags  GPMC_MUX_ADD_DATA)
-   return 0;
-
-   memset(dev_t, 0, sizeof(dev_t));
-
-   dev_t.t_oeasu = t3 * 1000;
-   dev_t.t_oe = t5 * 1000;
-   dev_t.t_cez_r = t4_r * 1000;
-   dev_t.t_oez = t6 * 1000;
-   dev_t.t_rd_cycle = (t20 - t3) * 1000;
+   memset(dev_t, 0, sizeof(*dev_t));
 
-   dev_t.t_weasu = t3 * 1000;
-   dev_t.t_wpl = t7 * 1000;
-   dev_t.t_wph = t8 * 1000;
-   dev_t.t_cez_w = t4_w * 1000;
-   dev_t.t_wr_cycle = (t20 - t3) * 1000;
+   dev_t-t_oeasu = t3 * 1000;
+   dev_t-t_oe = t5 * 1000;
+   dev_t-t_cez_r = t4_r * 1000;
+   dev_t-t_oez = t6 * 1000;
+   dev_t-t_rd_cycle = (t20 - t3) * 1000;
 
-   gpmc_calc_timings(t, smc91x_settings, dev_t);
-
-   return gpmc_cs_set_timings(gpmc_cfg-cs, t);
+   dev_t-t_weasu = t3 * 1000;
+   dev_t-t_wpl = t7 * 1000;
+   dev_t-t_wph = t8 * 1000;
+   dev_t-t_cez_w = t4_w * 1000;
+   dev_t-t_wr_cycle = (t20 - t3) * 1000;
 }
 
 /*
@@ -110,12 +94,10 @@ void __init gpmc_smc91x_init(struct 
omap_smc91x_platform_data *board_data)
 {
unsigned long cs_mem_base;
int ret;
+   struct gpmc_device_timings dev_t;
 
gpmc_cfg = board_data;
 
-   if (gpmc_cfg-flags  GPMC_TIMINGS_SMC91C96)
-   gpmc_cfg-retime = smc91c96_gpmc_retime;
-
if (gpmc_cs_request(gpmc_cfg-cs, SZ_16M, cs_mem_base)  0) {
printk(KERN_ERR Failed to request GPMC mem for smc91x\n);
return;
@@ -137,10 +119,15 @@ void __init gpmc_smc91x_init(struct 
omap_smc91x_platform_data *board_data)
if (ret  0)
goto free1;
 
-   if (gpmc_cfg-retime) {
-   ret = gpmc_cfg-retime();
-   if (ret != 0)
+   if (gpmc_cfg-flags  GPMC_TIMINGS_SMC91C96) {
+   struct gpmc_timings gpmc_t;
+
+   smc91c96_get_device_timing(dev_t);
+   gpmc_calc_timings(gpmc_t, smc91x_settings, dev_t);
+   if (gpmc_cs_set_timings(gpmc_cfg-cs, gpmc_t)) {
+   pr_err(%s: failed to set GPMC timings\n, __func__);
goto free1;
+   }
}
 
if (gpio_request_one(gpmc_cfg-gpio_irq, GPIOF_IN, SMC91X irq)  0)
diff --git a/arch/arm/mach-omap2/gpmc-smc91x.h 
b/arch/arm/mach-omap2/gpmc-smc91x.h
index b64fbee..1da09a0 100644
--- a/arch/arm/mach-omap2/gpmc-smc91x.h
+++ b/arch/arm/mach-omap2/gpmc-smc91x.h
@@ -22,7 +22,6 @@ struct 

[PATCH 24/36] ARM: OMAP2+: gpmc: add NAND specific setup

2014-06-11 Thread Roger Quadros
Provide NAND specific resources and platform data.

Signed-off-by: Roger Quadros rog...@ti.com
---
 arch/arm/mach-omap2/gpmc.c | 45 +
 1 file changed, 45 insertions(+)

diff --git a/arch/arm/mach-omap2/gpmc.c b/arch/arm/mach-omap2/gpmc.c
index c26ba3f..5563360 100644
--- a/arch/arm/mach-omap2/gpmc.c
+++ b/arch/arm/mach-omap2/gpmc.c
@@ -1350,6 +1350,42 @@ static int gpmc_probe_dt(struct platform_device *pdev)
 }
 #endif
 
+static int gpmc_nand_setup(struct platform_device *parent_pdev,
+  struct gpmc_omap_cs_data *cs)
+{
+   struct resource *res;
+   struct resource *res_gpmc;
+
+   if (!cs-pdev)
+   return -EINVAL;
+
+   res = cs-pdev-resource;
+
+   if (cs-pdev-num_resources  3)
+   return -EINVAL;
+
+   if (resource_type(res[1]) != IORESOURCE_MEM ||
+   resource_type(res[2]) != IORESOURCE_IRQ)
+   return -EINVAL;
+
+   if (!cs-settings)
+   return -EINVAL;
+
+   /* GPMC register space */
+   res_gpmc = platform_get_resource(parent_pdev, IORESOURCE_MEM, 0);
+   if (!res_gpmc)
+   return -EINVAL;
+
+   res[1] = *res_gpmc;
+
+   /* setup IRQ resources */
+   res[2].start = gpmc_irq;
+
+   cs-settings-device_nand = true;
+
+   return 0;
+}
+
 static void gpmc_probe_legacy(struct platform_device *pdev)
 {
int i, rc;
@@ -1401,6 +1437,15 @@ static void gpmc_probe_legacy(struct platform_device 
*pdev)
/* FIXME: When do we need to call gpmc_cs_remap()? */
 skip_mem:
 
+   /* Customized NAND setup */
+   if (cs-is_nand) {
+   if (gpmc_nand_setup(pdev, cs)) {
+   dev_err(dev, Error setting up NAND on CS %d\n,
+   i);
+   continue;
+   }
+   }
+
if (cs-settings) {
if (gpmc_cs_program_settings(i, cs-settings)) {
dev_err(dev,
-- 
1.8.3.2

--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 19/36] mtd: onenand: omap: Use devres managed resources

2014-06-11 Thread Roger Quadros
Use devres managed resources for Memory, GPIO and Interrupt
resources.

0 is a valid gpio, so use gpio_is_valid() to check for
valid gpio number.

Signed-off-by: Roger Quadros rog...@ti.com
---
 drivers/mtd/onenand/omap2.c | 92 -
 1 file changed, 33 insertions(+), 59 deletions(-)

diff --git a/drivers/mtd/onenand/omap2.c b/drivers/mtd/onenand/omap2.c
index 238dd7a..b6a9ec0 100644
--- a/drivers/mtd/onenand/omap2.c
+++ b/drivers/mtd/onenand/omap2.c
@@ -38,8 +38,7 @@
 #include asm/mach/flash.h
 #include linux/platform_data/mtd-onenand-omap2.h
 #include linux/platform_data/gpmc-omap.h
-#include asm/gpio.h
-
+#include linux/gpio.h
 #include linux/omap-dma.h
 
 #define DRIVER_NAME omap2-onenand
@@ -835,6 +834,7 @@ static int omap2_onenand_probe(struct platform_device *pdev)
int r;
struct resource *res;
struct mtd_part_parser_data ppdata = {};
+   struct device *dev = pdev-dev;
 
pdata = dev_get_platdata(pdev-dev);
if (pdata == NULL) {
@@ -842,7 +842,7 @@ static int omap2_onenand_probe(struct platform_device *pdev)
return -ENODEV;
}
 
-   c = kzalloc(sizeof(struct omap2_onenand), GFP_KERNEL);
+   c = devm_kzalloc(dev, sizeof(struct omap2_onenand), GFP_KERNEL);
if (!c)
return -ENOMEM;
 
@@ -855,50 +855,40 @@ static int omap2_onenand_probe(struct platform_device 
*pdev)
c-dma_channel = pdata-dma_channel;
if (c-dma_channel  0) {
/* if -1, don't use DMA */
-   c-gpio_irq = 0;
+   c-gpio_irq = -EINVAL;
}
 
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-   if (res == NULL) {
-   r = -EINVAL;
-   dev_err(pdev-dev, error getting memory resource\n);
-   goto err_kfree;
-   }
+   c-onenand.base = devm_ioremap_resource(dev, res);
+   if (IS_ERR(c-onenand.base))
+   return PTR_ERR(c-onenand.base);
 
c-phys_base = res-start;
c-mem_size = resource_size(res);
 
-   if (request_mem_region(c-phys_base, c-mem_size,
-  pdev-dev.driver-name) == NULL) {
-   dev_err(pdev-dev, Cannot reserve memory region at 0x%08lx, 
size: 0x%x\n,
-   c-phys_base, c-mem_size);
-   r = -EBUSY;
-   goto err_kfree;
-   }
-   c-onenand.base = ioremap(c-phys_base, c-mem_size);
-   if (c-onenand.base == NULL) {
-   r = -ENOMEM;
-   goto err_release_mem_region;
-   }
-
r = omap2_onenand_setup(c);
-   if (r  0) {
-   dev_err(pdev-dev, setup failed:%d\n, r);
-   goto err_iounmap;
-   }
+   if (r)
+   return -ENODEV;
 
-   if (c-gpio_irq) {
-   if ((r = gpio_request(c-gpio_irq, OneNAND irq))  0) {
-   dev_err(pdev-dev,  Failed to request GPIO%d for 
-   OneNAND\n, c-gpio_irq);
-   goto err_iounmap;
-   }
-   gpio_direction_input(c-gpio_irq);
+   if (gpio_is_valid(c-gpio_irq)) {
+   r = devm_gpio_request(dev, c-gpio_irq, OneNAND irq);
+   if (r) {
+   dev_err(dev, Failed to request GPIO %d,
+   c-gpio_irq);
+   return r;
+   }
+
+   gpio_direction_input(c-gpio_irq);
 
-   if ((r = request_irq(gpio_to_irq(c-gpio_irq),
-omap2_onenand_interrupt, IRQF_TRIGGER_RISING,
-pdev-dev.driver-name, c))  0)
-   goto err_release_gpio;
+   r = devm_request_irq(dev, gpio_to_irq(c-gpio_irq),
+omap2_onenand_interrupt,
+IRQF_TRIGGER_RISING,
+pdev-dev.driver-name, c);
+   if (r) {
+   dev_err(dev, failed to request IRQ %d:%d\n,
+   c-gpio_irq, r);
+   return r;
+   }
}
 
if (c-dma_channel = 0) {
@@ -915,9 +905,8 @@ static int omap2_onenand_probe(struct platform_device *pdev)
omap_set_dma_dest_burst_mode(c-dma_channel,
 OMAP_DMA_DATA_BURST_8);
} else {
-   dev_info(pdev-dev,
-failed to allocate DMA for OneNAND, 
-using PIO instead\n);
+   dev_info(dev,
+failed to allocate DMA for OneNAND, using PIO 
instead\n);
c-dma_channel = -1;
}
}
@@ -947,8 +936,11 @@ static int omap2_onenand_probe(struct platform_device 
*pdev)
if (pdata-skip_initial_unlocking)
this-options |= 

[PATCH 21/36] ARM: dts: OMAP2+: Fix OneNAND device nodes

2014-06-11 Thread Roger Quadros
Add compatible id, fix chip select partition size and
I/O space size. OneNAND devices just need 128KB for I/O
and the minimum possible chips select partition can be
16MB.

Signed-off-by: Roger Quadros rog...@ti.com
---
 arch/arm/boot/dts/omap2420-n8x0-common.dtsi | 5 +++--
 arch/arm/boot/dts/omap3-n900.dts| 6 --
 arch/arm/boot/dts/omap3-n950-n9.dtsi| 6 --
 arch/arm/boot/dts/omap3430-sdp.dts  | 8 +---
 4 files changed, 16 insertions(+), 9 deletions(-)

diff --git a/arch/arm/boot/dts/omap2420-n8x0-common.dtsi 
b/arch/arm/boot/dts/omap2420-n8x0-common.dtsi
index 89608b2..14a67fb3 100644
--- a/arch/arm/boot/dts/omap2420-n8x0-common.dtsi
+++ b/arch/arm/boot/dts/omap2420-n8x0-common.dtsi
@@ -34,14 +34,15 @@
 };
 
 gpmc {
-   ranges = 0 0 0x0400 0x1000;
+   ranges = 0 0 0x0400 0x100;/* CS0 space, 16MB min. */
 
/* gpio-irq for dma: 26 */
 
onenand@0,0 {
+   compatible = ti,omap2-onenand;
#address-cells = 1;
#size-cells = 1;
-   reg = 0 0 0x1000;
+   reg = 0 0 0x2;/* OneNAND I/O 128K */
 
gpmc,sync-read;
gpmc,burst-length = 16;
diff --git a/arch/arm/boot/dts/omap3-n900.dts b/arch/arm/boot/dts/omap3-n900.dts
index 1a57b61..0c5af81 100644
--- a/arch/arm/boot/dts/omap3-n900.dts
+++ b/arch/arm/boot/dts/omap3-n900.dts
@@ -501,14 +501,16 @@
 };
 
 gpmc {
-   ranges = 0 0 0x0400 0x1000; /* 256MB */
+   ranges = 0 0 0x0400 0x100;/* CS0 space, 16MB min. */
 
/* gpio-irq for dma: 65 */
 
onenand@0,0 {
+   compatible = ti,omap2-onenand;
#address-cells = 1;
#size-cells = 1;
-   reg = 0 0 0x1000;
+   reg = 0 0 0x2;/* OneNAND I/O 128K */
+   ti,onenand-sync-rw;
 
gpmc,sync-read;
gpmc,sync-write;
diff --git a/arch/arm/boot/dts/omap3-n950-n9.dtsi 
b/arch/arm/boot/dts/omap3-n950-n9.dtsi
index 5c26c18..9dcb367 100644
--- a/arch/arm/boot/dts/omap3-n950-n9.dtsi
+++ b/arch/arm/boot/dts/omap3-n950-n9.dtsi
@@ -101,12 +101,14 @@
 };
 
 gpmc {
-   ranges = 0 0 0x0400 0x2000;
+   ranges = 0 0 0x0400 0x100;/* CS0 space, 16MB min. */
 
onenand@0,0 {
+   compatible = ti,omap2-onenand;
#address-cells = 1;
#size-cells = 1;
-   reg = 0 0 0x2000;
+   reg = 0 0 0x2;/* OneNAND I/O 128K */
+   ti,onenand-sync-rw;
 
gpmc,sync-read;
gpmc,sync-write;
diff --git a/arch/arm/boot/dts/omap3430-sdp.dts 
b/arch/arm/boot/dts/omap3430-sdp.dts
index bf5f8b9..d6fe226 100644
--- a/arch/arm/boot/dts/omap3430-sdp.dts
+++ b/arch/arm/boot/dts/omap3430-sdp.dts
@@ -52,7 +52,7 @@
 gpmc {
ranges = 0 0 0x1000 0x0800,
 1 0 0x2800 0x0800,
-2 0 0x2000 0x1000,
+2 0 0x2000 0x100,/* CS2, 16MB min. */
 255 0 0x6e00 0x02d4; /* GPMC reg */
 
nor@0,0 {
@@ -151,10 +151,11 @@
};
 
onenand@2,0 {
-   linux,mtd-name= samsung,kfm2g16q2m-deb8;
+   compatible = ti,omap2-onenand;
#address-cells = 1;
#size-cells = 1;
-   reg = 2 0 0x1000;
+   reg = 2 0 0x2;/* OneNAND I/O 128K */
+   ti,onenand-sync-rw;
 
gpmc,device-width = 2;
gpmc,mux-add-data = 2;
@@ -173,6 +174,7 @@
gpmc,access-ns = 78;
gpmc,wr-data-mux-bus-ns = 30;
 
+   linux,mtd-name= samsung,kfm2g16q2m-deb8;
partition@0 {
label = xloader-onenand;
reg = 0 0x8;
-- 
1.8.3.2

--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 20/36] mtd: onenand: omap: Clean up device tree support

2014-06-11 Thread Roger Quadros
Move OneNAND specific device tree parsing to NAND driver.
The OneNAND device node must have its own compatible id.

Add a new property 'ti,onenand-sync-rw' to indicate
synchronous read + write support. Default mode would be
only synchronous reads.

Signed-off-by: Roger Quadros rog...@ti.com
---
 .../devicetree/bindings/mtd/gpmc-onenand.txt   |  4 +
 arch/arm/mach-omap2/gpmc-onenand.c | 14 
 arch/arm/mach-omap2/gpmc.c | 55 +++--
 drivers/mtd/onenand/omap2.c| 90 --
 include/linux/platform_data/mtd-onenand-omap2.h|  4 +-
 5 files changed, 84 insertions(+), 83 deletions(-)

diff --git a/Documentation/devicetree/bindings/mtd/gpmc-onenand.txt 
b/Documentation/devicetree/bindings/mtd/gpmc-onenand.txt
index b752942..7fc9c13 100644
--- a/Documentation/devicetree/bindings/mtd/gpmc-onenand.txt
+++ b/Documentation/devicetree/bindings/mtd/gpmc-onenand.txt
@@ -9,9 +9,12 @@ Documentation/devicetree/bindings/bus/ti-gpmc.txt
 
 Required properties:
 
+ - compatible: ti,omap2-onenand
  - reg:The CS line the peripheral is connected to
  - gpmc,device-width   Width of the ONENAND device connected to the GPMC
in bytes. Must be 1 or 2.
+ - ti,onenand-sync-rw: Bool. Enable synchronous Read and Write. If not
+   present, only Synchronous Read is enabled.
 
 Optional properties:
 
@@ -35,6 +38,7 @@ Example for an OMAP3430 board:
#size-cells = 1;
 
onenand@0 {
+   compatible = ti,omap2-onenand
reg = 0 0 0; /* CS0, offset 0 */
gpmc,device-width = 2;
 
diff --git a/arch/arm/mach-omap2/gpmc-onenand.c 
b/arch/arm/mach-omap2/gpmc-onenand.c
index d09c342..37ed4f1 100644
--- a/arch/arm/mach-omap2/gpmc-onenand.c
+++ b/arch/arm/mach-omap2/gpmc-onenand.c
@@ -75,20 +75,6 @@ static int omap2_onenand_setup_async(struct 
omap_onenand_platform_data
struct gpmc_device_timings dev_t;
int ret;
 
-   if (gpmc_onenand_data-of_node) {
-   gpmc_read_settings_dt(gpmc_onenand_data-of_node,
- onenand_async);
-   if (onenand_async.sync_read || onenand_async.sync_write) {
-   if (onenand_async.sync_write)
-   gpmc_onenand_data-flags |=
-   ONENAND_SYNC_READWRITE;
-   else
-   gpmc_onenand_data-flags |= ONENAND_SYNC_READ;
-   onenand_async.sync_read = false;
-   onenand_async.sync_write = false;
-   }
-   }
-
ret = gpmc_cs_program_settings(gpmc_onenand_data-cs, onenand_async);
if (ret  0)
return ret;
diff --git a/arch/arm/mach-omap2/gpmc.c b/arch/arm/mach-omap2/gpmc.c
index 50ef1a9..ee030cd 100644
--- a/arch/arm/mach-omap2/gpmc.c
+++ b/arch/arm/mach-omap2/gpmc.c
@@ -39,7 +39,6 @@
 #include common.h
 #include omap_device.h
 #include gpmc.h
-#include gpmc-onenand.h
 
 #defineDEVICE_NAME omap-gpmc
 
@@ -1166,43 +1165,6 @@ static void __maybe_unused gpmc_read_timings_dt(struct 
device_node *np,
of_property_read_bool(np, gpmc,time-para-granularity);
 }
 
-#if IS_ENABLED(CONFIG_MTD_ONENAND)
-static int gpmc_probe_onenand_child(struct platform_device *pdev,
-struct device_node *child)
-{
-   u32 val;
-   struct omap_onenand_platform_data *gpmc_onenand_data;
-
-   if (of_property_read_u32(child, reg, val)  0) {
-   dev_err(pdev-dev, %s has no 'reg' property\n,
-   child-full_name);
-   return -ENODEV;
-   }
-
-   gpmc_onenand_data = devm_kzalloc(pdev-dev, sizeof(*gpmc_onenand_data),
-GFP_KERNEL);
-   if (!gpmc_onenand_data)
-   return -ENOMEM;
-
-   gpmc_onenand_data-cs = val;
-   gpmc_onenand_data-of_node = child;
-   gpmc_onenand_data-dma_channel = -1;
-
-   if (!of_property_read_u32(child, dma-channel, val))
-   gpmc_onenand_data-dma_channel = val;
-
-   gpmc_onenand_init(gpmc_onenand_data);
-
-   return 0;
-}
-#else
-static int gpmc_probe_onenand_child(struct platform_device *pdev,
-   struct device_node *child)
-{
-   return 0;
-}
-#endif
-
 /**
  * gpmc_probe_generic_child - configures the gpmc for a child device
  * @pdev:  pointer to gpmc platform device
@@ -1292,6 +1254,12 @@ static int gpmc_probe_generic_child(struct 
platform_device *pdev,
}
 
gpmc_s.device_nand = true;
+
+   } else if (of_node_cmp(child-name, onenand) == 0) {
+   /* DT incorrectly sets sync modes, onenand default is async */
+   gpmc_s.sync_read = false;
+   gpmc_s.sync_write = false;
+
   

[PATCH 23/36] ARM: OMAP2+: gpmc: use platform data to configure CS space and poplulate device

2014-06-11 Thread Roger Quadros
Add gpmc_probe_legacy() that will be called for non DT boots. This function
will use platform data to setup each chip select and populate the child
platform device for each of the chip selects.

Signed-off-by: Roger Quadros rog...@ti.com
---
 arch/arm/mach-omap2/gpmc.c | 129 ++---
 1 file changed, 111 insertions(+), 18 deletions(-)

diff --git a/arch/arm/mach-omap2/gpmc.c b/arch/arm/mach-omap2/gpmc.c
index d3a64ed..c26ba3f 100644
--- a/arch/arm/mach-omap2/gpmc.c
+++ b/arch/arm/mach-omap2/gpmc.c
@@ -1302,11 +1302,6 @@ 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);
-
-   if (!of_id)
-   return 0;
 
ret = of_property_read_u32(pdev-dev.of_node, gpmc,num-cs,
   gpmc_cs_num);
@@ -1355,11 +1350,106 @@ static int gpmc_probe_dt(struct platform_device *pdev)
 }
 #endif
 
+static void gpmc_probe_legacy(struct platform_device *pdev)
+{
+   int i, rc;
+   struct device *dev = pdev-dev;
+   struct gpmc_omap_platform_data *gpmc_pdata;
+
+   gpmc_pdata = dev-platform_data;
+   gpmc_cs_num = GPMC_CS_NUM;
+   gpmc_nr_waitpins = GPMC_NR_WAITPINS;
+
+   if (!gpmc_pdata)
+   return;
+
+   for (i = 0; i  GPMC_CS_NUM; i++) {
+   struct resource *mem_res;
+   unsigned long cs_base;
+   resource_size_t size;
+   struct gpmc_timings gpmc_timings;
+   struct gpmc_omap_cs_data *cs;
+
+   cs = gpmc_pdata-cs[i];
+   if (!cs-valid)
+   continue;
+
+   /*
+* Request a CS space. Use size from
+* platform device's MEM resource
+*/
+   if (!cs-pdev)
+   goto skip_mem;
+
+   mem_res = cs-pdev-resource;
+   if (cs-pdev-num_resources  1 ||
+   resource_type(mem_res) != IORESOURCE_MEM) {
+   dev_err(dev, Invalid IOMEM resource for CS %d\n, i);
+   continue;
+   }
+
+   size = mem_res-end - mem_res-start + 1;
+   if (gpmc_cs_request(i, size, cs_base)) {
+   dev_err(dev, Couldn't request resource for CS %d\n,
+   i);
+   continue;
+   }
+
+   mem_res-start = cs_base;
+   mem_res-end = cs_base + size - 1;
+
+   /* FIXME: When do we need to call gpmc_cs_remap()? */
+skip_mem:
+
+   if (cs-settings) {
+   if (gpmc_cs_program_settings(i, cs-settings)) {
+   dev_err(dev,
+   Couldn't program settings for CS %d\n,
+   i);
+   continue;
+   }
+   }
+
+   /* give device_timings priority over gpmc_timings */
+   if (cs-device_timings) {
+   gpmc_calc_timings(gpmc_timings, cs-settings,
+ cs-device_timings);
+
+   if (gpmc_cs_set_timings(i, gpmc_timings)) {
+   dev_err(dev,
+   Couldn't program timings for CS %d\n,
+   i);
+   continue;
+   }
+   } else if (cs-gpmc_timings) {
+   if (gpmc_cs_set_timings(i, cs-gpmc_timings)) {
+   dev_err(dev,
+   Couldn't program timings for CS %d\n,
+   i);
+   continue;
+   }
+   }
+
+   if (!cs-pdev)
+   continue;
+
+   cs-pdev-dev.parent = dev;
+   rc = platform_device_register(cs-pdev);
+   if (rc  0) {
+   dev_err(dev,
+   Failed to register device %s on CS %d\n,
+   cs-pdev-name, i);
+   continue;
+   }
+   }
+}
+
 static int gpmc_probe(struct platform_device *pdev)
 {
int rc;
u32 l;
struct resource *res;
+   struct device *dev = pdev-dev;
 
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (res == NULL)
@@ -1390,7 +1480,7 @@ static int gpmc_probe(struct platform_device *pdev)
pm_runtime_enable(pdev-dev);
pm_runtime_get_sync(pdev-dev);
 
-   gpmc_dev = pdev-dev;
+   gpmc_dev = dev;
 
l = gpmc_read_reg(GPMC_REVISION);
 
@@ -1410,7 +1500,7 @@ static int gpmc_probe(struct platform_device *pdev)

[PATCH 22/36] ARM: OMAP2+: gmpc: add gpmc_generic_init()

2014-06-11 Thread Roger Quadros
This function populates platform data for the specified Chip Select.
It should be called by board init code.

Signed-off-by: Roger Quadros rog...@ti.com
---
 arch/arm/mach-omap2/gpmc.c | 79 ++
 arch/arm/mach-omap2/gpmc.h |  6 
 2 files changed, 85 insertions(+)

diff --git a/arch/arm/mach-omap2/gpmc.c b/arch/arm/mach-omap2/gpmc.c
index ee030cd..d3a64ed 100644
--- a/arch/arm/mach-omap2/gpmc.c
+++ b/arch/arm/mach-omap2/gpmc.c
@@ -30,6 +30,7 @@
 #include linux/of_mtd.h
 #include linux/of_device.h
 #include linux/pm_runtime.h
+#include linux/slab.h
 
 #include linux/platform_data/mtd-nand-omap2.h
 
@@ -108,6 +109,8 @@
 
 #define GPMC_NR_WAITPINS   4
 
+static struct gpmc_omap_platform_data gpmc_pdata;
+
 /* Structure to save gpmc cs context */
 struct gpmc_cs_config {
u32 config1;
@@ -1510,6 +1513,82 @@ static int __init omap_gpmc_init(void)
 omap_postcore_initcall(omap_gpmc_init);
 
 /**
+ * gpmc_generic_init - Initialize platform data for a Chip Select
+ *
+ * @cs chip select number
+ * @is_nandtrue if device is NAND flash.
+ * @settings   GPMC settings
+ * @device_timings device timings for device on this CS
+ * @gpmc_timings   GPMC timings
+ * @pdev   platform device for the device on this CS
+ * @pdata_size platform data size for the platform device
+ */
+int gpmc_generic_init(int cs, bool is_nand,
+ struct gpmc_settings *settings,
+ struct gpmc_device_timings *device_timings,
+ struct gpmc_timings *gpmc_timings,
+ struct platform_device *pdev, unsigned pdata_size)
+{
+   struct gpmc_settings *gpmc_s = NULL;
+   struct gpmc_device_timings *gpmc_dev_t = NULL;
+   struct gpmc_timings *gpmc_t;
+
+   if (cs = GPMC_CS_NUM) {
+   pr_err(%s: Invalid cs specified. Max CS = %d\n,
+  __func__, GPMC_CS_NUM);
+   return -EINVAL;
+   }
+
+   if (gpmc_pdata.cs[cs].valid) {
+   pr_err(%s: cs %d already requested, ignoring new request\n,
+  __func__, cs);
+   return -EINVAL;
+   }
+
+   if (settings) {
+   gpmc_s = kmemdup(settings, sizeof(*settings), GFP_KERNEL);
+   if (!gpmc_s)
+   return -ENOMEM;
+
+   gpmc_pdata.cs[cs].settings = gpmc_s;
+   }
+
+   if (device_timings) {
+   gpmc_dev_t = kmemdup(device_timings, sizeof(*device_timings),
+GFP_KERNEL);
+   if (!gpmc_dev_t)
+   goto dev_t_fail;
+
+   gpmc_pdata.cs[cs].device_timings = gpmc_dev_t;
+   }
+
+   if (gpmc_timings) {
+   gpmc_t = kmemdup(gpmc_timings, sizeof(*gpmc_timings),
+GFP_KERNEL);
+   if (!gpmc_t)
+   goto gpmc_t_fail;
+
+   gpmc_pdata.cs[cs].gpmc_timings = gpmc_t;
+   }
+
+   gpmc_pdata.cs[cs].is_nand = is_nand;
+   gpmc_pdata.cs[cs].pdev = pdev;
+   gpmc_pdata.cs[cs].pdata_size = pdata_size;
+   gpmc_pdata.cs[cs].valid = true;
+
+   return 0;
+
+gpmc_t_fail:
+   if (device_timings)
+   kfree(gpmc_dev_t);
+dev_t_fail:
+   if (settings)
+   kfree(gpmc_s);
+
+   return -ENOMEM;
+}
+
+/**
  * omap_gpmc_retime - Reconfigre GPMC timings for the device
  *
  * @cs Chip select number
diff --git a/arch/arm/mach-omap2/gpmc.h b/arch/arm/mach-omap2/gpmc.h
index 6204913..301bc66 100644
--- a/arch/arm/mach-omap2/gpmc.h
+++ b/arch/arm/mach-omap2/gpmc.h
@@ -77,5 +77,11 @@ extern void omap3_gpmc_save_context(void);
 extern void omap3_gpmc_restore_context(void);
 extern void gpmc_read_settings_dt(struct device_node *np,
  struct gpmc_settings *p);
+int gpmc_generic_init(int cs, bool is_nand,
+ struct gpmc_settings *settings,
+ struct gpmc_device_timings *device_timings,
+ struct gpmc_timings *gpmc_timings,
+ struct platform_device *pdev,
+ unsigned pdata_size);
 
 #endif
-- 
1.8.3.2

--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 32/36] ARM: OMAP2+: onenand: Use gpmc_generic_init()

2014-06-11 Thread Roger Quadros
Don't access any GPMC registers here. Use gpmc_generic_init()
to pass GPMC Chip Select settings, platform device and platform data
to the GPMC driver.

Signed-off-by: Roger Quadros rog...@ti.com
---
 arch/arm/mach-omap2/gpmc-onenand.c | 53 --
 1 file changed, 11 insertions(+), 42 deletions(-)

diff --git a/arch/arm/mach-omap2/gpmc-onenand.c 
b/arch/arm/mach-omap2/gpmc-onenand.c
index 37ed4f1..139b3dd 100644
--- a/arch/arm/mach-omap2/gpmc-onenand.c
+++ b/arch/arm/mach-omap2/gpmc-onenand.c
@@ -27,7 +27,10 @@
 #defineONENAND_IO_SIZE SZ_128K
 
 static struct resource gpmc_onenand_resource = {
+/* GPMC driver will fixup the memory resource, see gpmc_probe_legacy() */
.flags  = IORESOURCE_MEM,
+   .start  = 0,
+   .end= ONENAND_IO_SIZE - 1,
 };
 
 static struct platform_device gpmc_onenand_device = {
@@ -68,29 +71,11 @@ static void omap2_onenand_get_async_timings(struct 
gpmc_device_timings *dev_t)
dev_t-t_wph = t_wph * 1000;
 }
 
-static int omap2_onenand_setup_async(struct omap_onenand_platform_data
-*gpmc_onenand_data)
-{
-   struct gpmc_timings gpmc_t;
-   struct gpmc_device_timings dev_t;
-   int ret;
-
-   ret = gpmc_cs_program_settings(gpmc_onenand_data-cs, onenand_async);
-   if (ret  0)
-   return ret;
-
-   omap2_onenand_get_async_timings(dev_t);
-   gpmc_calc_timings(gpmc_t, onenand_async, dev_t);
-   if (gpmc_cs_set_timings(gpmc_onenand_data-cs, gpmc_t))
-   return -EINVAL;
-
-   return 0;
-}
-
 void gpmc_onenand_init(struct omap_onenand_platform_data *gpmc_onenand_data)
 {
int err;
struct device *dev = gpmc_onenand_device.dev;
+   struct gpmc_device_timings dev_t;
 
gpmc_onenand_device.dev.platform_data = gpmc_onenand_data;
 
@@ -106,29 +91,13 @@ void gpmc_onenand_init(struct omap_onenand_platform_data 
*gpmc_onenand_data)
else
gpmc_onenand_data-flags = ~ONENAND_IN_OMAP34XX;
 
-   err = gpmc_cs_request(gpmc_onenand_data-cs, ONENAND_IO_SIZE,
-   (unsigned long *)gpmc_onenand_resource.start);
-   if (err  0) {
-   dev_err(dev, Cannot request GPMC CS %d, error %d\n,
-   gpmc_onenand_data-cs, err);
-   return;
-   }
-
-   gpmc_onenand_resource.end = gpmc_onenand_resource.start +
-   ONENAND_IO_SIZE - 1;
-
-   if (omap2_onenand_setup_async(gpmc_onenand_data)) {
-   pr_err(%s: Failed to setup ASYNC timings\n, __func__);
-   goto fail;
-   }
-
-   if (platform_device_register(gpmc_onenand_device)  0) {
-   dev_err(dev, Unable to register OneNAND device\n);
-   goto fail;
-   }
 
-   return;
+   omap2_onenand_get_async_timings(dev_t);
 
-fail:
-   gpmc_cs_free(gpmc_onenand_data-cs);
+   err = gpmc_generic_init(gpmc_onenand_data-cs, false,
+   onenand_async, dev_t, NULL,
+   gpmc_onenand_device,
+   sizeof(*gpmc_onenand_data));
+   if (err)
+   pr_err(%s: gpmc_generic_init() failed %d\n, __func__, err);
 }
-- 
1.8.3.2

--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 18/36] ARM: OMAP2+: gpmc-onenand: Move Synchronous setting code to drivers/

2014-06-11 Thread Roger Quadros
Move the code that puts the onenand in synchronous mode
into the appropriate place i.e. drivers/mtd/onenand/omap2.c.

Make use of omap_gpmc_get_clk_period() and omap_gpmc_retime()
to calculate the necessary timings and configure the GPMC
parent's timings.

Signed-off-by: Roger Quadros rog...@ti.com
---
 arch/arm/mach-omap2/gpmc-onenand.c  | 262 +--
 drivers/mtd/onenand/omap2.c | 264 +++-
 include/linux/platform_data/mtd-onenand-omap2.h |   2 +-
 3 files changed, 258 insertions(+), 270 deletions(-)

diff --git a/arch/arm/mach-omap2/gpmc-onenand.c 
b/arch/arm/mach-omap2/gpmc-onenand.c
index bed8efe..d09c342 100644
--- a/arch/arm/mach-omap2/gpmc-onenand.c
+++ b/arch/arm/mach-omap2/gpmc-onenand.c
@@ -26,16 +26,6 @@
 
 #defineONENAND_IO_SIZE SZ_128K
 
-#defineONENAND_FLAG_SYNCREAD   (1  0)
-#defineONENAND_FLAG_SYNCWRITE  (1  1)
-#defineONENAND_FLAG_HF (1  2)
-#defineONENAND_FLAG_VHF(1  3)
-
-static unsigned onenand_flags;
-static unsigned latency;
-
-static struct omap_onenand_platform_data *gpmc_onenand_data;
-
 static struct resource gpmc_onenand_resource = {
.flags  = IORESOURCE_MEM,
 };
@@ -52,15 +42,6 @@ static struct gpmc_settings onenand_async = {
.mux_add_data   = GPMC_MUX_AD,
 };
 
-static struct gpmc_settings onenand_sync = {
-   .burst_read = true,
-   .burst_wrap = true,
-   .burst_len  = GPMC_BURST_16,
-   .device_width   = GPMC_DEVWIDTH_16BIT,
-   .mux_add_data   = GPMC_MUX_AD,
-   .wait_pin   = 0,
-};
-
 static void omap2_onenand_get_async_timings(struct gpmc_device_timings *dev_t)
 {
const int t_cer = 15;
@@ -87,184 +68,8 @@ static void omap2_onenand_get_async_timings(struct 
gpmc_device_timings *dev_t)
dev_t-t_wph = t_wph * 1000;
 }
 
-static void omap2_onenand_set_async_mode(void __iomem *onenand_base)
-{
-   u32 reg;
-
-   /* Ensure sync read and sync write are disabled */
-   reg = readw(onenand_base + ONENAND_REG_SYS_CFG1);
-   reg = ~ONENAND_SYS_CFG1_SYNC_READ  ~ONENAND_SYS_CFG1_SYNC_WRITE;
-   writew(reg, onenand_base + ONENAND_REG_SYS_CFG1);
-}
-
-static void set_onenand_cfg(void __iomem *onenand_base)
-{
-   u32 reg;
-
-   reg = readw(onenand_base + ONENAND_REG_SYS_CFG1);
-   reg = ~((0x7  ONENAND_SYS_CFG1_BRL_SHIFT) | (0x7  9));
-   reg |=  (latency  ONENAND_SYS_CFG1_BRL_SHIFT) |
-   ONENAND_SYS_CFG1_BL_16;
-   if (onenand_flags  ONENAND_FLAG_SYNCREAD)
-   reg |= ONENAND_SYS_CFG1_SYNC_READ;
-   else
-   reg = ~ONENAND_SYS_CFG1_SYNC_READ;
-   if (onenand_flags  ONENAND_FLAG_SYNCWRITE)
-   reg |= ONENAND_SYS_CFG1_SYNC_WRITE;
-   else
-   reg = ~ONENAND_SYS_CFG1_SYNC_WRITE;
-   if (onenand_flags  ONENAND_FLAG_HF)
-   reg |= ONENAND_SYS_CFG1_HF;
-   else
-   reg = ~ONENAND_SYS_CFG1_HF;
-   if (onenand_flags  ONENAND_FLAG_VHF)
-   reg |= ONENAND_SYS_CFG1_VHF;
-   else
-   reg = ~ONENAND_SYS_CFG1_VHF;
-   writew(reg, onenand_base + ONENAND_REG_SYS_CFG1);
-}
-
-static int omap2_onenand_get_freq(struct omap_onenand_platform_data *cfg,
- void __iomem *onenand_base)
-{
-   u16 ver = readw(onenand_base + ONENAND_REG_VERSION_ID);
-   int freq;
-
-   switch ((ver  4)  0xf) {
-   case 0:
-   freq = 40;
-   break;
-   case 1:
-   freq = 54;
-   break;
-   case 2:
-   freq = 66;
-   break;
-   case 3:
-   freq = 83;
-   break;
-   case 4:
-   freq = 104;
-   break;
-   default:
-   freq = 54;
-   break;
-   }
-
-   return freq;
-}
-
-static void omap2_onenand_calc_sync_timings(struct gpmc_timings *t,
-   unsigned int flags,
-   int freq)
-{
-   struct gpmc_device_timings dev_t;
-   const int t_cer  = 15;
-   const int t_avdp = 12;
-   const int t_cez  = 20; /* max of t_cez, t_oez */
-   const int t_wpl  = 40;
-   const int t_wph  = 30;
-   int min_gpmc_clk_period, t_ces, t_avds, t_avdh, t_ach, t_aavdh, t_rdyo;
-   int div, gpmc_clk_ns;
-
-   if (flags  ONENAND_SYNC_READ)
-   onenand_flags = ONENAND_FLAG_SYNCREAD;
-   else if (flags  ONENAND_SYNC_READWRITE)
-   onenand_flags = ONENAND_FLAG_SYNCREAD | ONENAND_FLAG_SYNCWRITE;
-
-   switch (freq) {
-   case 104:
-   min_gpmc_clk_period = 9600; /* 104 MHz */
-   t_ces   = 3;
-   t_avds  = 4;
-   t_avdh  = 2;
-   t_ach   = 3;
-   t_aavdh = 6;
-   t_rdyo  = 6;
-   break;
-   case 83:
-   

[PATCH 30/36] ARM: OMAP2+: gpmc-smsc911x: Use gpmc_generic_init()

2014-06-11 Thread Roger Quadros
Don't access any GPMC registers here. Use gpmc_generic_init()
to pass GPMC Chip Select settings, platform device and platform data
to the GPMC driver.

Some boards use multiple smsc911x devices, so we dynamically
allocate pdev and pdata.

Signed-off-by: Roger Quadros rog...@ti.com
---
 arch/arm/mach-omap2/gpmc-smsc911x.c | 76 ++---
 1 file changed, 46 insertions(+), 30 deletions(-)

diff --git a/arch/arm/mach-omap2/gpmc-smsc911x.c 
b/arch/arm/mach-omap2/gpmc-smsc911x.c
index 2757504..9492db0 100644
--- a/arch/arm/mach-omap2/gpmc-smsc911x.c
+++ b/arch/arm/mach-omap2/gpmc-smsc911x.c
@@ -19,19 +19,11 @@
 #include linux/interrupt.h
 #include linux/io.h
 #include linux/smsc911x.h
+#include linux/slab.h
 
 #include gpmc.h
 #include gpmc-smsc911x.h
 
-static struct resource gpmc_smsc911x_resources[] = {
-   [0] = {
-   .flags  = IORESOURCE_MEM,
-   },
-   [1] = {
-   .flags  = IORESOURCE_IRQ | IORESOURCE_IRQ_LOWLEVEL,
-   },
-};
-
 static struct smsc911x_platform_config gpmc_smsc911x_config = {
.phy_interface  = PHY_INTERFACE_MODE_MII,
.irq_polarity   = SMSC911X_IRQ_POLARITY_ACTIVE_LOW,
@@ -45,24 +37,43 @@ static struct smsc911x_platform_config gpmc_smsc911x_config 
= {
  */
 void __init gpmc_smsc911x_init(struct omap_smsc911x_platform_data *gpmc_cfg)
 {
-   struct platform_device *pdev;
-   unsigned long cs_mem_base;
int ret;
+   struct platform_device *pdev;
+   struct resource *res;
+
+   /*
+* This function can be called multiple times per board so the platform
+* device and resources have to be allocated separately for each
+* device.
+*/
+   pdev = kzalloc(sizeof(*pdev), GFP_KERNEL);
+   if (!pdev)
+   goto fail;
+
+   /* needs 2 resources */
+   res = kzalloc(2 * sizeof(*res), GFP_KERNEL);
+   if (!res)
+   goto free1;
 
-   if (gpmc_cs_request(gpmc_cfg-cs, SZ_16M, cs_mem_base)  0) {
-   pr_err(Failed to request GPMC mem region\n);
-   return;
-   }
+   pdev-name = smsc911x;
+   pdev-id = gpmc_cfg-id;
+   pdev-dev.platform_data = gpmc_smsc911x_config,
+   pdev-num_resources = 2;
+   pdev-resource = res;
+
+   /* res[0]  Will be relocated by GPMC driver, see gpmc_probe_legacy() */
+   res[0].flags = IORESOURCE_MEM;
+   res[0].start = 0;
+   res[0].end = 0xff;
 
-   gpmc_smsc911x_resources[0].start = cs_mem_base + 0x0;
-   gpmc_smsc911x_resources[0].end = cs_mem_base + 0xff;
 
if (gpio_request_one(gpmc_cfg-gpio_irq, GPIOF_IN, smsc911x irq)) {
pr_err(Failed to request IRQ GPIO%d\n, gpmc_cfg-gpio_irq);
-   goto free1;
+   goto free2;
}
 
-   gpmc_smsc911x_resources[1].start = gpio_to_irq(gpmc_cfg-gpio_irq);
+   res[1].start = gpio_to_irq(gpmc_cfg-gpio_irq);
+   res[1].flags = IORESOURCE_IRQ | IORESOURCE_IRQ_LOWLEVEL;
 
if (gpio_is_valid(gpmc_cfg-gpio_reset)) {
ret = gpio_request_one(gpmc_cfg-gpio_reset,
@@ -70,7 +81,7 @@ void __init gpmc_smsc911x_init(struct 
omap_smsc911x_platform_data *gpmc_cfg)
if (ret) {
pr_err(Failed to request reset GPIO%d\n,
   gpmc_cfg-gpio_reset);
-   goto free2;
+   goto free3;
}
 
gpio_set_value(gpmc_cfg-gpio_reset, 0);
@@ -80,21 +91,26 @@ void __init gpmc_smsc911x_init(struct 
omap_smsc911x_platform_data *gpmc_cfg)
 
gpmc_smsc911x_config.flags = gpmc_cfg-flags ? : SMSC911X_USE_16BIT;
 
-   pdev = platform_device_register_resndata(NULL, smsc911x, gpmc_cfg-id,
-gpmc_smsc911x_resources, ARRAY_SIZE(gpmc_smsc911x_resources),
-gpmc_smsc911x_config, sizeof(gpmc_smsc911x_config));
-   if (IS_ERR(pdev)) {
-   pr_err(Unable to register platform device\n);
-   gpio_free(gpmc_cfg-gpio_reset);
-   goto free2;
+   ret = gpmc_generic_init(gpmc_cfg-cs, false,
+   NULL, NULL, NULL,
+   pdev,
+   sizeof(gpmc_smsc911x_config));
+   if (ret) {
+   pr_err(%s: gpmc_generic_init() failed %d\n, __func__, ret);
+   goto free4;
}
 
return;
 
-free2:
+free4:
+   if (gpio_is_valid(gpmc_cfg-gpio_reset))
+   gpio_free(gpmc_cfg-gpio_reset);
+free3:
gpio_free(gpmc_cfg-gpio_irq);
+free2:
+   kfree(res);
 free1:
-   gpmc_cs_free(gpmc_cfg-cs);
-
+   kfree(pdev);
+fail:
pr_err(Could not initialize smsc911x device\n);
 }
-- 
1.8.3.2

--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 29/36] ARM: OMAP2+: gpmc-smc91x: Use gpmc_generic_init()

2014-06-11 Thread Roger Quadros
Don't access any GPMC registers here. Use gpmc_generic_init()
to pass GPMC Chip Select settings, platform device and platform data
to the GPMC driver.

Signed-off-by: Roger Quadros rog...@ti.com
---
 arch/arm/mach-omap2/gpmc-smc91x.c | 50 +++
 1 file changed, 19 insertions(+), 31 deletions(-)

diff --git a/arch/arm/mach-omap2/gpmc-smc91x.c 
b/arch/arm/mach-omap2/gpmc-smc91x.c
index 7f5d84a..4ac0d4d 100644
--- a/arch/arm/mach-omap2/gpmc-smc91x.c
+++ b/arch/arm/mach-omap2/gpmc-smc91x.c
@@ -25,8 +25,11 @@
 static struct omap_smc91x_platform_data *gpmc_cfg;
 
 static struct resource gpmc_smc91x_resources[] = {
+/* GPMC driver will fixup the 1st memory resource, see gpmc_probe_legacy () */
[0] = {
.flags  = IORESOURCE_MEM,
+   .start  = 0,
+   .end= 0xf,
},
[1] = {
.flags  = IORESOURCE_IRQ,
@@ -92,21 +95,11 @@ static void smc91c96_get_device_timing(struct 
gpmc_device_timings *dev_t)
  */
 void __init gpmc_smc91x_init(struct omap_smc91x_platform_data *board_data)
 {
-   unsigned long cs_mem_base;
int ret;
struct gpmc_device_timings dev_t;
 
gpmc_cfg = board_data;
 
-   if (gpmc_cs_request(gpmc_cfg-cs, SZ_16M, cs_mem_base)  0) {
-   printk(KERN_ERR Failed to request GPMC mem for smc91x\n);
-   return;
-   }
-
-   gpmc_smc91x_resources[0].start = cs_mem_base + 0x300;
-   gpmc_smc91x_resources[0].end = cs_mem_base + 0x30f;
-   gpmc_smc91x_resources[1].flags |= (gpmc_cfg-flags  IRQF_TRIGGER_MASK);
-
if (gpmc_cfg-flags  GPMC_MUX_ADD_DATA)
smc91x_settings.mux_add_data = GPMC_MUX_AD;
if (gpmc_cfg-flags  GPMC_READ_MON)
@@ -115,34 +108,24 @@ void __init gpmc_smc91x_init(struct 
omap_smc91x_platform_data *board_data)
smc91x_settings.wait_on_write = true;
if (gpmc_cfg-wait_pin)
smc91x_settings.wait_pin = gpmc_cfg-wait_pin;
-   ret = gpmc_cs_program_settings(gpmc_cfg-cs, smc91x_settings);
-   if (ret  0)
-   goto free1;
-
-   if (gpmc_cfg-flags  GPMC_TIMINGS_SMC91C96) {
-   struct gpmc_timings gpmc_t;
 
+   if (gpmc_cfg-flags  GPMC_TIMINGS_SMC91C96)
smc91c96_get_device_timing(dev_t);
-   gpmc_calc_timings(gpmc_t, smc91x_settings, dev_t);
-   if (gpmc_cs_set_timings(gpmc_cfg-cs, gpmc_t)) {
-   pr_err(%s: failed to set GPMC timings\n, __func__);
-   goto free1;
-   }
-   }
 
if (gpio_request_one(gpmc_cfg-gpio_irq, GPIOF_IN, SMC91X irq)  0)
goto free1;
 
gpmc_smc91x_resources[1].start = gpio_to_irq(gpmc_cfg-gpio_irq);
+   gpmc_smc91x_resources[1].flags |= (gpmc_cfg-flags  IRQF_TRIGGER_MASK);
 
-   if (gpmc_cfg-gpio_pwrdwn) {
+   if (gpio_is_valid(gpmc_cfg-gpio_pwrdwn)) {
ret = gpio_request_one(gpmc_cfg-gpio_pwrdwn,
   GPIOF_OUT_INIT_LOW, SMC91X powerdown);
if (ret)
goto free2;
}
 
-   if (gpmc_cfg-gpio_reset) {
+   if (gpio_is_valid(gpmc_cfg-gpio_reset)) {
ret = gpio_request_one(gpmc_cfg-gpio_reset,
   GPIOF_OUT_INIT_LOW, SMC91X reset);
if (ret)
@@ -153,21 +136,26 @@ void __init gpmc_smc91x_init(struct 
omap_smc91x_platform_data *board_data)
gpio_set_value(gpmc_cfg-gpio_reset, 0);
}
 
-   if (platform_device_register(gpmc_smc91x_device)  0) {
-   printk(KERN_ERR Unable to register smc91x device\n);
-   gpio_free(gpmc_cfg-gpio_reset);
-   goto free3;
+   ret = gpmc_generic_init(gpmc_cfg-cs, false,
+   smc91x_settings,
+   gpmc_cfg-flags  GPMC_TIMINGS_SMC91C96 ?
+   dev_t : NULL, NULL,
+   gpmc_smc91x_device, sizeof(gpmc_smc91x_info));
+   if (ret) {
+   pr_err(%s: gpmc_generic_init() failed %d\n, __func__, ret);
+   goto free4;
}
 
return;
 
+free4:
+   if (gpio_is_valid(gpmc_cfg-gpio_reset))
+   gpio_free(gpmc_cfg-gpio_reset);
 free3:
-   if (gpmc_cfg-gpio_pwrdwn)
+   if (gpio_is_valid(gpmc_cfg-gpio_pwrdwn))
gpio_free(gpmc_cfg-gpio_pwrdwn);
 free2:
gpio_free(gpmc_cfg-gpio_irq);
 free1:
-   gpmc_cs_free(gpmc_cfg-cs);
-
printk(KERN_ERR Could not initialize smc91x\n);
 }
-- 
1.8.3.2

--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 17/36] ARM: OMAP2+: gpmc-onenand: Use Async settings/timings by default

2014-06-11 Thread Roger Quadros
Onenand device operates in Asynchronous mode by default. So
configure GPMC settings/timings based on Async mode before the onenand
device is created.

Signed-off-by: Roger Quadros rog...@ti.com
---
 arch/arm/mach-omap2/gpmc-onenand.c | 66 ++
 1 file changed, 32 insertions(+), 34 deletions(-)

diff --git a/arch/arm/mach-omap2/gpmc-onenand.c 
b/arch/arm/mach-omap2/gpmc-onenand.c
index 8b6876c..bed8efe 100644
--- a/arch/arm/mach-omap2/gpmc-onenand.c
+++ b/arch/arm/mach-omap2/gpmc-onenand.c
@@ -61,9 +61,8 @@ static struct gpmc_settings onenand_sync = {
.wait_pin   = 0,
 };
 
-static void omap2_onenand_calc_async_timings(struct gpmc_timings *t)
+static void omap2_onenand_get_async_timings(struct gpmc_device_timings *dev_t)
 {
-   struct gpmc_device_timings dev_t;
const int t_cer = 15;
const int t_avdp = 12;
const int t_aavdh = 7;
@@ -74,20 +73,18 @@ static void omap2_onenand_calc_async_timings(struct 
gpmc_timings *t)
const int t_wpl = 40;
const int t_wph = 30;
 
-   memset(dev_t, 0, sizeof(dev_t));
-
-   dev_t.t_avdp_r = max_t(int, t_avdp, t_cer) * 1000;
-   dev_t.t_avdp_w = dev_t.t_avdp_r;
-   dev_t.t_aavdh = t_aavdh * 1000;
-   dev_t.t_aa = t_aa * 1000;
-   dev_t.t_ce = t_ce * 1000;
-   dev_t.t_oe = t_oe * 1000;
-   dev_t.t_cez_r = t_cez * 1000;
-   dev_t.t_cez_w = dev_t.t_cez_r;
-   dev_t.t_wpl = t_wpl * 1000;
-   dev_t.t_wph = t_wph * 1000;
-
-   gpmc_calc_timings(t, onenand_async, dev_t);
+   memset(dev_t, 0, sizeof(*dev_t));
+
+   dev_t-t_avdp_r = max_t(int, t_avdp, t_cer) * 1000;
+   dev_t-t_avdp_w = dev_t-t_avdp_r;
+   dev_t-t_aavdh = t_aavdh * 1000;
+   dev_t-t_aa = t_aa * 1000;
+   dev_t-t_ce = t_ce * 1000;
+   dev_t-t_oe = t_oe * 1000;
+   dev_t-t_cez_r = t_cez * 1000;
+   dev_t-t_cez_w = dev_t-t_cez_r;
+   dev_t-t_wpl = t_wpl * 1000;
+   dev_t-t_wph = t_wph * 1000;
 }
 
 static void omap2_onenand_set_async_mode(void __iomem *onenand_base)
@@ -267,9 +264,10 @@ static void omap2_onenand_calc_sync_timings(struct 
gpmc_timings *t,
gpmc_calc_timings(t, onenand_sync, dev_t);
 }
 
-static int omap2_onenand_setup_async(void __iomem *onenand_base)
+static int omap2_onenand_setup_async(void)
 {
-   struct gpmc_timings t;
+   struct gpmc_timings gpmc_t;
+   struct gpmc_device_timings dev_t;
int ret;
 
if (gpmc_onenand_data-of_node) {
@@ -286,19 +284,14 @@ static int omap2_onenand_setup_async(void __iomem 
*onenand_base)
}
}
 
-   omap2_onenand_set_async_mode(onenand_base);
-
-   omap2_onenand_calc_async_timings(t);
-
ret = gpmc_cs_program_settings(gpmc_onenand_data-cs, onenand_async);
if (ret  0)
return ret;
 
-   ret = gpmc_cs_set_timings(gpmc_onenand_data-cs, t);
-   if (ret  0)
-   return ret;
-
-   omap2_onenand_set_async_mode(onenand_base);
+   omap2_onenand_get_async_timings(dev_t);
+   gpmc_calc_timings(gpmc_t, onenand_async, dev_t);
+   if (gpmc_cs_set_timings(gpmc_onenand_data-cs, gpmc_t))
+   return -EINVAL;
 
return 0;
 }
@@ -349,11 +342,7 @@ static int gpmc_onenand_setup(void __iomem *onenand_base, 
int *freq_ptr)
unsigned l = ONENAND_SYNC_READ | ONENAND_SYNC_READWRITE;
int ret;
 
-   ret = omap2_onenand_setup_async(onenand_base);
-   if (ret) {
-   dev_err(dev, unable to set to async mode\n);
-   return ret;
-   }
+   omap2_onenand_set_async_mode(onenand_base);
 
if (!(gpmc_onenand_data-flags  l))
return 0;
@@ -396,9 +385,18 @@ void gpmc_onenand_init(struct omap_onenand_platform_data 
*_onenand_data)
gpmc_onenand_resource.end = gpmc_onenand_resource.start +
ONENAND_IO_SIZE - 1;
 
+   if (omap2_onenand_setup_async()) {
+   pr_err(%s: Failed to setup ASYNC timings\n, __func__);
+   goto fail;
+   }
+
if (platform_device_register(gpmc_onenand_device)  0) {
dev_err(dev, Unable to register OneNAND device\n);
-   gpmc_cs_free(gpmc_onenand_data-cs);
-   return;
+   goto fail;
}
+
+   return;
+
+fail:
+   gpmc_cs_free(gpmc_onenand_data-cs);
 }
-- 
1.8.3.2

--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 27/36] ARM: OMAP2+: usb-tusb6010: Use omap_gpmc_retime()

2014-06-11 Thread Roger Quadros
In order to change the GPMC settings/timings on the fly,
we must use omap_gpmc_retime(). The other gpmc_*() functions
will soon be made private and moved out of arch/mach-omap2/

CC: Felipe Balbi ba...@ti.com
Signed-off-by: Roger Quadros rog...@ti.com
---
 arch/arm/mach-omap2/usb-tusb6010.c | 94 ++
 1 file changed, 44 insertions(+), 50 deletions(-)

diff --git a/arch/arm/mach-omap2/usb-tusb6010.c 
b/arch/arm/mach-omap2/usb-tusb6010.c
index e832bc7..71e6246 100644
--- a/arch/arm/mach-omap2/usb-tusb6010.c
+++ b/arch/arm/mach-omap2/usb-tusb6010.c
@@ -48,58 +48,48 @@ static struct gpmc_settings tusb_sync = {
 
 /* NOTE:  timings are from tusb 6010 datasheet Rev 1.8, 12-Sept 2006 */
 
-static int tusb_set_async_mode(unsigned sysclk_ps)
+static void tusb_get_async_timings(unsigned sysclk_ps,
+  struct gpmc_device_timings *dev_t)
 {
-   struct gpmc_device_timings dev_t;
-   struct gpmc_timings t;
-   unsignedt_acsnh_advnh = sysclk_ps + 3000;
-
-   memset(dev_t, 0, sizeof(dev_t));
-
-   dev_t.t_ceasu = 8 * 1000;
-   dev_t.t_avdasu = t_acsnh_advnh - 7000;
-   dev_t.t_ce_avd = 1000;
-   dev_t.t_avdp_r = t_acsnh_advnh;
-   dev_t.t_oeasu = t_acsnh_advnh + 1000;
-   dev_t.t_oe = 300;
-   dev_t.t_cez_r = 7000;
-   dev_t.t_cez_w = dev_t.t_cez_r;
-   dev_t.t_avdp_w = t_acsnh_advnh;
-   dev_t.t_weasu = t_acsnh_advnh + 1000;
-   dev_t.t_wpl = 300;
-   dev_t.cyc_aavdh_we = 1;
-
-   gpmc_calc_timings(t, tusb_async, dev_t);
-
-   return gpmc_cs_set_timings(async_cs, t);
+   unsigned t_acsnh_advnh = sysclk_ps + 3000;
+
+   memset(dev_t, 0, sizeof(*dev_t));
+
+   dev_t-t_ceasu = 8 * 1000;
+   dev_t-t_avdasu = t_acsnh_advnh - 7000;
+   dev_t-t_ce_avd = 1000;
+   dev_t-t_avdp_r = t_acsnh_advnh;
+   dev_t-t_oeasu = t_acsnh_advnh + 1000;
+   dev_t-t_oe = 300;
+   dev_t-t_cez_r = 7000;
+   dev_t-t_cez_w = dev_t-t_cez_r;
+   dev_t-t_avdp_w = t_acsnh_advnh;
+   dev_t-t_weasu = t_acsnh_advnh + 1000;
+   dev_t-t_wpl = 300;
+   dev_t-cyc_aavdh_we = 1;
 }
 
-static int tusb_set_sync_mode(unsigned sysclk_ps)
+static void tusb_get_sync_timings(unsigned sysclk_ps,
+ struct gpmc_device_timings *dev_t)
 {
-   struct gpmc_device_timings dev_t;
-   struct gpmc_timings t;
-   unsignedt_scsnh_advnh = sysclk_ps + 3000;
-
-   memset(dev_t, 0, sizeof(dev_t));
-
-   dev_t.clk = 11100;
-   dev_t.t_bacc = 1000;
-   dev_t.t_ces = 1000;
-   dev_t.t_ceasu = 8 * 1000;
-   dev_t.t_avdasu = t_scsnh_advnh - 7000;
-   dev_t.t_ce_avd = 1000;
-   dev_t.t_avdp_r = t_scsnh_advnh;
-   dev_t.cyc_aavdh_oe = 3;
-   dev_t.cyc_oe = 5;
-   dev_t.t_ce_rdyz = 7000;
-   dev_t.t_avdp_w = t_scsnh_advnh;
-   dev_t.cyc_aavdh_we = 3;
-   dev_t.cyc_wpl = 6;
-   dev_t.t_ce_rdyz = 7000;
-
-   gpmc_calc_timings(t, tusb_sync, dev_t);
-
-   return gpmc_cs_set_timings(sync_cs, t);
+   unsigned t_scsnh_advnh = sysclk_ps + 3000;
+
+   memset(dev_t, 0, sizeof(dev_t));
+
+   dev_t-clk = 11100;
+   dev_t-t_bacc = 1000;
+   dev_t-t_ces = 1000;
+   dev_t-t_ceasu = 8 * 1000;
+   dev_t-t_avdasu = t_scsnh_advnh - 7000;
+   dev_t-t_ce_avd = 1000;
+   dev_t-t_avdp_r = t_scsnh_advnh;
+   dev_t-cyc_aavdh_oe = 3;
+   dev_t-cyc_oe = 5;
+   dev_t-t_ce_rdyz = 7000;
+   dev_t-t_avdp_w = t_scsnh_advnh;
+   dev_t-cyc_aavdh_we = 3;
+   dev_t-cyc_wpl = 6;
+   dev_t-t_ce_rdyz = 7000;
 }
 
 /* tusb driver calls this when it changes the chip's clocking */
@@ -110,18 +100,22 @@ int tusb6010_platform_retime(unsigned is_refclk)
 
unsignedsysclk_ps;
int status;
+   struct gpmc_device_timings dev_t;
 
if (!refclk_psec)
return -ENODEV;
 
sysclk_ps = is_refclk ? refclk_psec : TUSB6010_OSCCLK_60;
 
-   status = tusb_set_async_mode(sysclk_ps);
+   tusb_get_async_timings(sysclk_ps, dev_t);
+   status = omap_gpmc_retime(async_cs, tusb_async, dev_t);
if (status  0) {
printk(error, async, status);
goto done;
}
-   status = tusb_set_sync_mode(sysclk_ps);
+
+   tusb_get_sync_timings(sysclk_ps, dev_t);
+   status = omap_gpmc_retime(sync_cs, tusb_sync, dev_t);
if (status  0)
printk(error, sync, status);
 done:
-- 
1.8.3.2

--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 31/36] ARM: OMAP2: usb-tusb6010: Use gpmc_generic_init()

2014-06-11 Thread Roger Quadros
Don't access any GPMC registers here. Use gpmc_generic_init()
to pass GPMC Chip Select settings, platform device and platform data
to the GPMC driver.

CC: Felipe Balbi ba...@ti.com
Signed-off-by: Roger Quadros rog...@ti.com
---
 arch/arm/mach-omap2/usb-tusb6010.c | 78 +++---
 1 file changed, 39 insertions(+), 39 deletions(-)

diff --git a/arch/arm/mach-omap2/usb-tusb6010.c 
b/arch/arm/mach-omap2/usb-tusb6010.c
index 71e6246..d28f5cd 100644
--- a/arch/arm/mach-omap2/usb-tusb6010.c
+++ b/arch/arm/mach-omap2/usb-tusb6010.c
@@ -125,13 +125,17 @@ EXPORT_SYMBOL_GPL(tusb6010_platform_retime);
 
 static struct resource tusb_resources[] = {
/* Order is significant!  The start/end fields
-* are updated during setup..
+* are updated by GPMC driver, see gpmc_probe_legacy()
 */
-   { /* Asynchronous access */
-   .flags  = IORESOURCE_MEM,
+   { /* Asynchronous access, for PIO */
+   .flags = IORESOURCE_MEM,
+   .start = 0,
+   .end = 0x9ff,
},
-   { /* Synchronous access */
-   .flags  = IORESOURCE_MEM,
+   { /* Synchronous access, for DMA */
+   .flags = IORESOURCE_MEM,
+   .start = 0,
+   .end = 0x9ff,
},
{ /* IRQ */
.name   = mc,
@@ -163,37 +167,16 @@ tusb6010_setup_interface(struct musb_hdrc_platform_data 
*data,
int status;
static char error[] __initdata =
KERN_ERR tusb6010 init error %d, %d\n;
+   struct gpmc_device_timings dev_async_t;
+   struct gpmc_device_timings dev_sync_t;
 
-   /* ASYNC region, primarily for PIO */
-   status = gpmc_cs_request(async, SZ_16M, (unsigned long *)
-   tusb_resources[0].start);
-   if (status  0) {
-   printk(error, 1, status);
-   return status;
-   }
-   tusb_resources[0].end = tusb_resources[0].start + 0x9ff;
+   /* GPMC settings */
tusb_async.wait_pin = waitpin;
async_cs = async;
 
-   status = gpmc_cs_program_settings(async_cs, tusb_async);
-   if (status  0)
-   return status;
-
-   /* SYNC region, primarily for DMA */
-   status = gpmc_cs_request(sync, SZ_16M, (unsigned long *)
-   tusb_resources[1].start);
-   if (status  0) {
-   printk(error, 2, status);
-   return status;
-   }
-   tusb_resources[1].end = tusb_resources[1].start + 0x9ff;
tusb_sync.wait_pin = waitpin;
sync_cs = sync;
 
-   status = gpmc_cs_program_settings(sync_cs, tusb_sync);
-   if (status  0)
-   return status;
-
/* IRQ */
status = gpio_request_one(irq, GPIOF_IN, TUSB6010 irq);
if (status  0) {
@@ -208,11 +191,10 @@ tusb6010_setup_interface(struct musb_hdrc_platform_data 
*data,
return -ENODEV;
}
refclk_psec = ps_refclk;
-   status = tusb6010_platform_retime(1);
-   if (status  0) {
-   printk(error, 5, status);
-   return status;
-   }
+
+   /* device timings */
+   tusb_get_async_timings(ps_refclk, dev_async_t);
+   tusb_get_sync_timings(ps_refclk, dev_sync_t);
 
/* finish device setup ... */
if (!data) {
@@ -240,11 +222,29 @@ tusb6010_setup_interface(struct musb_hdrc_platform_data 
*data,
omap_mux_init_signal(sys_ndmareq5, 0);
}
 
-   /* so far so good ... register the device */
-   status = platform_device_register(tusb_device);
-   if (status  0) {
-   printk(error, 7, status);
-   return status;
+   /* Register ASYNC region */
+   status = gpmc_generic_init(async_cs, false,
+  tusb_async, dev_async_t, NULL,
+  tusb_device, sizeof(*data));
+
+   if (status) {
+   pr_err(%s: failed to register ASYNC region\n, __func__);
+   goto fail;
}
+
+   /* Register SYNC region */
+   status = gpmc_generic_init(sync_cs, false,
+  tusb_sync, dev_sync_t, NULL,
+  tusb_device, sizeof(*data));
+   if (status) {
+   pr_err(%s: failed to register SYNC region\n, __func__);
+   goto fail;
+   }
+
return 0;
+
+fail:
+   gpio_free(irq);
+   return status;
+
 }
-- 
1.8.3.2

--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 14/36] ARM: OMAP2+: gpmc: Allow drivers to reconfigure GPMC settings timings

2014-06-11 Thread Roger Quadros
Some devices (e.g. TUSB6010, omap-onenand) need to reconfigure the GPMC
timings in order to operate with different peripheral clock frequencies.
Introduce omap_gpmc_retime() to allow them to do that. The driver
needs to pass the chips select number, GPMC settings and Device timings to
omap_gpmc_retime().

NOTE: Device tree and board code must still pass the most conservative
timings to GPMC so that the device can be probed by the respective driver.
e.g. Onenand must operate in asynchronous mode at bootup. The device driver
can then request for more optimal timings via omap_gpmc_retime().

Signed-off-by: Roger Quadros rog...@ti.com
---
 arch/arm/mach-omap2/gpmc.c  | 36 +
 include/linux/platform_data/gpmc-omap.h | 12 +++
 2 files changed, 48 insertions(+)

diff --git a/arch/arm/mach-omap2/gpmc.c b/arch/arm/mach-omap2/gpmc.c
index 70cb6b0..90b7686 100644
--- a/arch/arm/mach-omap2/gpmc.c
+++ b/arch/arm/mach-omap2/gpmc.c
@@ -1542,6 +1542,42 @@ static int __init omap_gpmc_init(void)
 }
 omap_postcore_initcall(omap_gpmc_init);
 
+/**
+ * omap_gpmc_retime - Reconfigre GPMC timings for the device
+ *
+ * @cs Chip select number
+ * @gpmc_s GPMC settings
+ * @dev_t  New device timings to set
+ */
+int omap_gpmc_retime(int cs, struct gpmc_settings *gpmc_s,
+struct gpmc_device_timings *dev_t)
+{
+   struct gpmc_timings gpmc_t;
+   struct device *dev = gpmc_dev;
+
+   if (!gpmc_dev)
+   return -ENODEV;
+
+   if (cs  0 || cs = gpmc_cs_num) {
+   dev_err(dev, %s: Invalid find Chip Select\n, __func__);
+   return cs;
+   }
+
+   if (gpmc_cs_program_settings(cs, gpmc_s)) {
+   dev_err(dev, %s: Failed to set GPMC settings\n, __func__);
+   return -EINVAL;
+   }
+
+   gpmc_calc_timings(gpmc_t, gpmc_s, dev_t);
+   if (gpmc_cs_set_timings(cs, gpmc_t)) {
+   dev_err(dev, %s: Failed to set GPMC timings\n, __func__);
+   return -EINVAL;
+   }
+
+   return 0;
+}
+EXPORT_SYMBOL_GPL(omap_gpmc_retime);
+
 static struct omap3_gpmc_regs gpmc_context;
 
 void omap3_gpmc_save_context(void)
diff --git a/include/linux/platform_data/gpmc-omap.h 
b/include/linux/platform_data/gpmc-omap.h
index e861112..0d40c2a 100644
--- a/include/linux/platform_data/gpmc-omap.h
+++ b/include/linux/platform_data/gpmc-omap.h
@@ -166,4 +166,16 @@ struct gpmc_omap_platform_data {
struct gpmc_omap_cs_data cs[GPMC_CS_NUM];
 };
 
+#ifdef CONFIG_ARCH_OMAP2PLUS
+int omap_gpmc_retime(int cs, struct gpmc_settings *gpmc_s,
+struct gpmc_device_timings *dev_t);
+#else
+static inline int omap_gpmc_retime(int cs,
+  struct gpmc_settings *gpmc_s,
+  struct gpmc_device_timings *dev_t)
+{
+   return 0;
+}
+#endif /* CONFIG_ARCH_OMAP2PLUS */
+
 #endif /* _GPMC_OMAP_H */
-- 
1.8.3.2

--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 16/36] mtd: onenand: omap: Remove regulator management code

2014-06-11 Thread Roger Quadros
None of the OMAP platforms are suppying the regulator_can_sleep
parameter via platform data. Regulator management is generic
enough to be done in onenand_base driver if required.

Mark the regulator_can_sleep platform data parameter as deprecated.

Signed-off-by: Roger Quadros rog...@ti.com
---
 drivers/mtd/onenand/omap2.c | 42 +
 include/linux/platform_data/mtd-onenand-omap2.h |  3 +-
 2 files changed, 3 insertions(+), 42 deletions(-)

diff --git a/drivers/mtd/onenand/omap2.c b/drivers/mtd/onenand/omap2.c
index d945473..a5f5ad8 100644
--- a/drivers/mtd/onenand/omap2.c
+++ b/drivers/mtd/onenand/omap2.c
@@ -34,7 +34,6 @@
 #include linux/dma-mapping.h
 #include linux/io.h
 #include linux/slab.h
-#include linux/regulator/consumer.h
 
 #include asm/mach/flash.h
 #include linux/platform_data/mtd-onenand-omap2.h
@@ -59,7 +58,6 @@ struct omap2_onenand {
int dma_channel;
int freq;
int (*setup)(void __iomem *base, int *freq_ptr);
-   struct regulator *regulator;
u8 flags;
 };
 
@@ -583,30 +581,6 @@ static void omap2_onenand_shutdown(struct platform_device 
*pdev)
memset((__force void *)c-onenand.base, 0, ONENAND_BUFRAM_SIZE);
 }
 
-static int omap2_onenand_enable(struct mtd_info *mtd)
-{
-   int ret;
-   struct omap2_onenand *c = container_of(mtd, struct omap2_onenand, mtd);
-
-   ret = regulator_enable(c-regulator);
-   if (ret != 0)
-   dev_err(c-pdev-dev, can't enable regulator\n);
-
-   return ret;
-}
-
-static int omap2_onenand_disable(struct mtd_info *mtd)
-{
-   int ret;
-   struct omap2_onenand *c = container_of(mtd, struct omap2_onenand, mtd);
-
-   ret = regulator_disable(c-regulator);
-   if (ret != 0)
-   dev_err(c-pdev-dev, can't disable regulator\n);
-
-   return ret;
-}
-
 static int omap2_onenand_probe(struct platform_device *pdev)
 {
struct omap_onenand_platform_data *pdata;
@@ -728,22 +702,11 @@ static int omap2_onenand_probe(struct platform_device 
*pdev)
}
}
 
-   if (pdata-regulator_can_sleep) {
-   c-regulator = regulator_get(pdev-dev, vonenand);
-   if (IS_ERR(c-regulator)) {
-   dev_err(pdev-dev,  Failed to get regulator\n);
-   r = PTR_ERR(c-regulator);
-   goto err_release_dma;
-   }
-   c-onenand.enable = omap2_onenand_enable;
-   c-onenand.disable = omap2_onenand_disable;
-   }
-
if (pdata-skip_initial_unlocking)
this-options |= ONENAND_SKIP_INITIAL_UNLOCKING;
 
if ((r = onenand_scan(c-mtd, 1))  0)
-   goto err_release_regulator;
+   goto err_release_dma;
 
ppdata.of_node = pdata-of_node;
r = mtd_device_parse_register(c-mtd, NULL, ppdata,
@@ -758,8 +721,6 @@ static int omap2_onenand_probe(struct platform_device *pdev)
 
 err_release_onenand:
onenand_release(c-mtd);
-err_release_regulator:
-   regulator_put(c-regulator);
 err_release_dma:
if (c-dma_channel != -1)
omap_free_dma(c-dma_channel);
@@ -783,7 +744,6 @@ static int omap2_onenand_remove(struct platform_device 
*pdev)
struct omap2_onenand *c = dev_get_drvdata(pdev-dev);
 
onenand_release(c-mtd);
-   regulator_put(c-regulator);
if (c-dma_channel != -1)
omap_free_dma(c-dma_channel);
omap2_onenand_shutdown(pdev);
diff --git a/include/linux/platform_data/mtd-onenand-omap2.h 
b/include/linux/platform_data/mtd-onenand-omap2.h
index 56ff0e6..445b41e 100644
--- a/include/linux/platform_data/mtd-onenand-omap2.h
+++ b/include/linux/platform_data/mtd-onenand-omap2.h
@@ -25,10 +25,11 @@ struct omap_onenand_platform_data {
int (*onenand_setup)(void __iomem *, int *freq_ptr);
int dma_channel;
u8  flags;
-   u8  regulator_can_sleep;
u8  skip_initial_unlocking;
 
/* for passing the partitions */
struct device_node  *of_node;
+
+   u8  regulator_can_sleep;/* deprecated */
 };
 #endif
-- 
1.8.3.2

--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 15/36] ARM: OMAP2+: gpmc: Allow drivers to query GPMC_CLK period

2014-06-11 Thread Roger Quadros
GPMC_CLK is the external clock output pin that is used for syncronous
accesses.

Device drivers need to know the fastest possible GPMC_CLK period in order
to calculate the most optimal device timings. Add the function
omap_gpmc_get_clk_period() to allow drivers to get the nearset possible
(equal to or greater than) GPMC_CLK period given the minimum
clock period supported by the attached device.

This is especially needed by the onenand driver as it calculates
device timings on the fly for various onenand speed grades.

Signed-off-by: Roger Quadros rog...@ti.com
---
 arch/arm/mach-omap2/gpmc.c  | 38 +
 include/linux/platform_data/gpmc-omap.h |  8 +++
 2 files changed, 46 insertions(+)

diff --git a/arch/arm/mach-omap2/gpmc.c b/arch/arm/mach-omap2/gpmc.c
index 90b7686..50ef1a9 100644
--- a/arch/arm/mach-omap2/gpmc.c
+++ b/arch/arm/mach-omap2/gpmc.c
@@ -1578,6 +1578,44 @@ int omap_gpmc_retime(int cs, struct gpmc_settings 
*gpmc_s,
 }
 EXPORT_SYMBOL_GPL(omap_gpmc_retime);
 
+/**
+ * omap_gpmc_get_clk_period - Get the nearest possible (equal to or higer) GPMC
+ * synchronous clock (GPMC_CLK) period.
+ *
+ * @cs Chip select number
+ * @min_ps Minimum synchronous clock period supporded by the device
+ *
+ * Returns the nearest possible GPMC clock period in picoseconds, equal to or
+ * higher than the requested period. 0 in case of error.
+ */
+unsigned long omap_gpmc_get_clk_period(int cs,
+  unsigned long min_ps)
+{
+   int div;
+   unsigned long clk_ps;
+   struct device *dev = gpmc_dev;
+
+   if (!gpmc_dev)
+   return 0;
+
+   if (cs  0 || cs = gpmc_cs_num) {
+   dev_err(dev, %s: Invalid Chip Select\n, __func__);
+   return cs;
+   }
+
+   div = gpmc_calc_divider(min_ps);
+   if (div  0) {
+   dev_err(dev, %s: Can't support requested clock period %lu 
ps\n,
+   __func__, min_ps);
+   return 0;
+   }
+
+   clk_ps = gpmc_get_fclk_period() * div;
+
+   return clk_ps;
+}
+EXPORT_SYMBOL_GPL(omap_gpmc_get_clk_period);
+
 static struct omap3_gpmc_regs gpmc_context;
 
 void omap3_gpmc_save_context(void)
diff --git a/include/linux/platform_data/gpmc-omap.h 
b/include/linux/platform_data/gpmc-omap.h
index 0d40c2a..05e4b6f 100644
--- a/include/linux/platform_data/gpmc-omap.h
+++ b/include/linux/platform_data/gpmc-omap.h
@@ -169,6 +169,8 @@ struct gpmc_omap_platform_data {
 #ifdef CONFIG_ARCH_OMAP2PLUS
 int omap_gpmc_retime(int cs, struct gpmc_settings *gpmc_s,
 struct gpmc_device_timings *dev_t);
+unsigned long omap_gpmc_get_clk_period(int cs,
+  unsigned long min_ps);
 #else
 static inline int omap_gpmc_retime(int cs,
   struct gpmc_settings *gpmc_s,
@@ -176,6 +178,12 @@ static inline int omap_gpmc_retime(int cs,
 {
return 0;
 }
+
+static inline unsigned long omap_gpmc_get_clk_period(int cs,
+unsigned long min_ps)
+{
+   return 0;
+}
 #endif /* CONFIG_ARCH_OMAP2PLUS */
 
 #endif /* _GPMC_OMAP_H */
-- 
1.8.3.2

--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 11/36] mtd: nand: omap: Update DT binding documentation

2014-06-11 Thread Roger Quadros
Add compatible id, interrupts and update reg property description.
As the NAND controller needs access to GPMC register space, we need
to pass a second memory resource to the NAND controller node.

Due to the wierd way the reg property has been implemented (i.e.
CS number required in 1st number of reg property) we will need to
use a number outside the possible CS numbers for the GPMC register space.

As a SoC can have fewer than 10 chip selects, 255 seems like a safe
bet for the GPMC register space.

Signed-off-by: Roger Quadros rog...@ti.com
---
 Documentation/devicetree/bindings/mtd/gpmc-nand.txt | 16 +---
 1 file changed, 13 insertions(+), 3 deletions(-)

diff --git a/Documentation/devicetree/bindings/mtd/gpmc-nand.txt 
b/Documentation/devicetree/bindings/mtd/gpmc-nand.txt
index 5e1f31b..8831116 100644
--- a/Documentation/devicetree/bindings/mtd/gpmc-nand.txt
+++ b/Documentation/devicetree/bindings/mtd/gpmc-nand.txt
@@ -13,7 +13,13 @@ Documentation/devicetree/bindings/mtd/nand.txt
 
 Required properties:
 
+ - compatible: ti,omap2-nand
  - reg:The CS line the peripheral is connected to
+   Should contain 2 resource specifiers
+   - range id (CS number), base offset and length of the
+ NAND I/O space
+   - range id,  base offset and length of the GPMC register space.
+ - interrupts: Interrupt resource specifier for GPMC interrupt.
 
 Optional properties:
 
@@ -53,17 +59,21 @@ Example for an AM33xx board:
gpmc: gpmc@5000 {
compatible = ti,am3352-gpmc;
ti,hwmods = gpmc;
-   reg = 0x5000 0x100;
+   reg = 0x5000 0x36c;
interrupts = 100;
gpmc,num-cs = 8;
gpmc,num-waitpins = 2;
#address-cells = 2;
#size-cells = 1;
-   ranges = 0 0 0x0800 0x2000;   /* CS0: NAND */
+   ranges = 0 0 0x0800 0x100  /* CS0 space, 16MB */
+ 255 0 0x5000 0x36c;  /* GPMC reg space */
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 */
+  255 0 0x36c;/* GPMC reg space */
+   interrupts = 100;
nand-bus-width = 16;
ti,nand-ecc-opt = bch8;
ti,nand-xfer-type = polled;
-- 
1.8.3.2

--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 12/36] ARM: dts: omap3-beagle: Add NAND device

2014-06-11 Thread Roger Quadros
The beagle board contains a 16-bit NAND device connected to
chip select 0 of the GPMC controller.

Signed-off-by: Roger Quadros rog...@ti.com
---
 arch/arm/boot/dts/omap3-beagle.dts | 53 ++
 1 file changed, 53 insertions(+)

diff --git a/arch/arm/boot/dts/omap3-beagle.dts 
b/arch/arm/boot/dts/omap3-beagle.dts
index 3c3e6da..fafd229 100644
--- a/arch/arm/boot/dts/omap3-beagle.dts
+++ b/arch/arm/boot/dts/omap3-beagle.dts
@@ -350,3 +350,56 @@
};
};
 };
+
+gpmc {
+   ranges = 0 0 0x3000 0x100  /* CS0 space, 16MB */
+ 255 0 0x6e00 0x02d4; /* register space */
+
+   /* Chip select 0 */
+   nand@0,0 {
+   compatible = ti,omap2-nand;
+   reg = 0 0 4/* NAND I/O window, 4 bytes */
+  255 0 0x02d4;   /* GPMC register space */
+   interrupts = 20;
+   ti,nand-ecc-opt = ham1;
+   nand-bus-width = 16;
+   #address-cells = 1;
+   #size-cells = 1;
+
+   gpmc,cs-on-ns = 0;
+   gpmc,cs-rd-off-ns = 36;
+   gpmc,cs-wr-off-ns = 36;
+   gpmc,adv-on-ns = 6;
+   gpmc,adv-rd-off-ns = 24;
+   gpmc,adv-wr-off-ns = 36;
+   gpmc,oe-on-ns = 6;
+   gpmc,oe-off-ns = 48;
+   gpmc,we-on-ns = 6;
+   gpmc,we-off-ns = 30;
+   gpmc,rd-cycle-ns = 72;
+   gpmc,wr-cycle-ns = 72;
+   gpmc,access-ns = 54;
+   gpmc,wr-access-ns = 30;
+
+   partition@0 {
+   label = X-Loader;
+   reg = 0 0x8;
+   };
+   partition@8 {
+   label = U-Boot;
+   reg = 0x8 0x1e;
+   };
+   partition@1c {
+   label = U-Boot Env;
+   reg = 0x26 0x2;
+   };
+   partition@28 {
+   label = Kernel;
+   reg = 0x28 0x40;
+   };
+   partition@78 {
+   label = Filesystem;
+   reg = 0x68 0xf98;
+   };
+   };
+};
-- 
1.8.3.2

--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 13/36] ARM: OMAP2+: gpmc.c: sanity check bank-width DT property

2014-06-11 Thread Roger Quadros
Make sure bank-width property provided via DT is sane.

Signed-off-by: Roger Quadros rog...@ti.com
---
 arch/arm/mach-omap2/gpmc.c | 17 +
 1 file changed, 13 insertions(+), 4 deletions(-)

diff --git a/arch/arm/mach-omap2/gpmc.c b/arch/arm/mach-omap2/gpmc.c
index c713616..70cb6b0 100644
--- a/arch/arm/mach-omap2/gpmc.c
+++ b/arch/arm/mach-omap2/gpmc.c
@@ -1219,6 +1219,7 @@ static int gpmc_probe_generic_child(struct 
platform_device *pdev,
struct resource res;
unsigned long base;
int ret, cs;
+   struct device *dev = pdev-dev;
 
if (of_property_read_u32(child, reg, cs)  0) {
dev_err(pdev-dev, %s has no 'reg' property\n,
@@ -1284,7 +1285,7 @@ static int gpmc_probe_generic_child(struct 
platform_device *pdev,
gpmc_s.device_width = GPMC_DEVWIDTH_16BIT;
break;
default:
-   dev_err(pdev-dev, %s: invalid 'nand-bus-width'\n,
+   dev_err(dev, %s: invalid 'nand-bus-width'\n,
child-name);
ret = -EINVAL;
goto err;
@@ -1292,10 +1293,18 @@ static int gpmc_probe_generic_child(struct 
platform_device *pdev,
 
gpmc_s.device_nand = true;
} else {
-   ret = of_property_read_u32(child, bank-width,
-  gpmc_s.device_width);
-   if (ret  0)
+   if (of_property_read_u32(child, bank-width,
+gpmc_s.device_width)) {
+   dev_err(dev, %s: no 'bank-width' property\n,
+   child-name);
+   goto err;
+   }
+
+   if (gpmc_s.device_width  1 || gpmc_s.device_width  2) {
+   dev_err(dev, %s: invalid 'bank-width'\n,
+   child-name);
goto err;
+   }
}
 
ret = gpmc_cs_program_settings(cs, gpmc_s);
-- 
1.8.3.2

--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 07/36] mtd: nand: omap: Move NAND write protect code from GPMC to NAND driver

2014-06-11 Thread Roger Quadros
The write protect (WP) pin is only used for NAND devices. So move
the code into the NAND driver.

Get rid of gpmc_configure() as it is no longer used.

Signed-off-by: Roger Quadros rog...@ti.com
---
 arch/arm/mach-omap2/gpmc-nand.c  |  4 
 arch/arm/mach-omap2/gpmc.c   | 29 
 arch/arm/mach-omap2/gpmc.h   |  5 -
 drivers/mtd/nand/omap2.c | 23 ++
 include/linux/platform_data/mtd-nand-omap2.h |  1 +
 5 files changed, 24 insertions(+), 38 deletions(-)

diff --git a/arch/arm/mach-omap2/gpmc-nand.c b/arch/arm/mach-omap2/gpmc-nand.c
index aaebd2f..9649fd9 100644
--- a/arch/arm/mach-omap2/gpmc-nand.c
+++ b/arch/arm/mach-omap2/gpmc-nand.c
@@ -138,10 +138,6 @@ int gpmc_nand_init(struct omap_nand_platform_data 
*gpmc_nand_data,
if (err  0)
goto out_free_cs;
 
-   err = gpmc_configure(GPMC_CONFIG_WP, 0);
-   if (err  0)
-   goto out_free_cs;
-
if (!gpmc_hwecc_bch_capable(gpmc_nand_data-ecc_opt)) {
dev_err(dev, Unsupported NAND ECC scheme selected\n);
return -EINVAL;
diff --git a/arch/arm/mach-omap2/gpmc.c b/arch/arm/mach-omap2/gpmc.c
index 0a8b6ca..a0c2194 100644
--- a/arch/arm/mach-omap2/gpmc.c
+++ b/arch/arm/mach-omap2/gpmc.c
@@ -596,35 +596,6 @@ void gpmc_cs_free(int cs)
 }
 EXPORT_SYMBOL(gpmc_cs_free);
 
-/**
- * gpmc_configure - write request to configure gpmc
- * @cmd: command type
- * @wval: value to write
- * @return status of the operation
- */
-int gpmc_configure(int cmd, int wval)
-{
-   u32 regval;
-
-   switch (cmd) {
-   case GPMC_CONFIG_WP:
-   regval = gpmc_read_reg(GPMC_CONFIG);
-   if (wval)
-   regval = ~GPMC_CONFIG_WRITEPROTECT; /* WP is ON */
-   else
-   regval |= GPMC_CONFIG_WRITEPROTECT;  /* WP is OFF */
-   gpmc_write_reg(GPMC_CONFIG, regval);
-   break;
-
-   default:
-   pr_err(%s: command not supported\n, __func__);
-   return -EINVAL;
-   }
-
-   return 0;
-}
-EXPORT_SYMBOL(gpmc_configure);
-
 void gpmc_get_mem_resource(struct resource *res)
 {
res-start =  phys_base;
diff --git a/arch/arm/mach-omap2/gpmc.h b/arch/arm/mach-omap2/gpmc.h
index 479ce84..6204913 100644
--- a/arch/arm/mach-omap2/gpmc.h
+++ b/arch/arm/mach-omap2/gpmc.h
@@ -22,9 +22,6 @@
 #define GPMC_CS_CONFIG60x14
 #define GPMC_CS_CONFIG70x18
 
-/* Control Commands */
-#define GPMC_CONFIG_WP 0x0005
-
 /* ECC commands */
 #define GPMC_ECC_READ  0 /* Reset Hardware ECC for read */
 #define GPMC_ECC_WRITE 1 /* Reset Hardware ECC for write */
@@ -57,7 +54,6 @@
 
 #define GPMC_DEVICETYPE_NOR0
 #define GPMC_DEVICETYPE_NAND   2
-#define GPMC_CONFIG_WRITEPROTECT   0x0010
 #define WR_RD_PIN_MONITORING   0x0060
 #define GPMC_IRQ_FIFOEVENTENABLE   0x01
 #define GPMC_IRQ_COUNT_EVENT   0x02
@@ -79,7 +75,6 @@ extern int gpmc_cs_request(int cs, unsigned long size, 
unsigned long *base);
 extern void gpmc_cs_free(int cs);
 extern void omap3_gpmc_save_context(void);
 extern void omap3_gpmc_restore_context(void);
-extern int gpmc_configure(int cmd, int wval);
 extern void gpmc_read_settings_dt(struct device_node *np,
  struct gpmc_settings *p);
 
diff --git a/drivers/mtd/nand/omap2.c b/drivers/mtd/nand/omap2.c
index 120acee..bb41796 100644
--- a/drivers/mtd/nand/omap2.c
+++ b/drivers/mtd/nand/omap2.c
@@ -140,6 +140,9 @@
 #define GPMC_IRQ_FIFOEVENT BIT(0)
 #define GPMC_IRQ_TERMCOUNT BIT(1)
 
+/* GPMC_CONFIG register bits */
+#define GPMC_CONFIG_WRITEPROTECT   BIT(4)
+
 /* GPMC register offsets */
 #define GPMC_REVISION  0x00
 #define GPMC_SYSCONFIG 0x10
@@ -206,6 +209,22 @@ struct omap_nand_info {
 };
 
 /**
+ * omap_nand_writeprotect - Control the WP line to the NAND chip
+ */
+static void omap_nand_writeprotect(struct omap_nand_info *info, bool on)
+{
+   u32 val;
+
+   val = readl(info-reg.gpmc_config);
+   if (on)
+   val |= GPMC_CONFIG_WRITEPROTECT;
+   else
+   val = GPMC_CONFIG_WRITEPROTECT;
+
+   writel(val, info-reg.gpmc_config);
+}
+
+/**
  * omap_prefetch_enable - configures and starts prefetch transfer
  * @cs: cs (chip select) number
  * @fifo_th: fifo threshold to be used for read/ write
@@ -1622,6 +1641,7 @@ static void gpmc_update_nand_reg(struct omap_nand_info 
*info)
int cs = info-gpmc_cs;
void __iomem *gpmc_base = info-gpmc_base;
 
+   reg-gpmc_config = gpmc_base + GPMC_CONFIG;
reg-gpmc_status = gpmc_base + GPMC_STATUS;
reg-gpmc_irqstatus = gpmc_base + GPMC_IRQSTATUS;
reg-gpmc_irqenable = gpmc_base + GPMC_IRQENABLE;
@@ -2029,6 +2049,9 @@ static int omap_nand_probe(struct platform_device *pdev)
goto 

[PATCH 09/36] mtd: nand: omap: Clean up device tree support

2014-06-11 Thread 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.

Signed-off-by: Roger Quadros rog...@ti.com
---
 arch/arm/mach-omap2/gpmc-nand.c  |   5 +-
 arch/arm/mach-omap2/gpmc.c   | 128 ++-
 drivers/mtd/nand/omap2.c | 125 ++
 include/linux/platform_data/mtd-nand-omap2.h |   6 +-
 4 files changed, 139 insertions(+), 125 deletions(-)

diff --git a/arch/arm/mach-omap2/gpmc-nand.c b/arch/arm/mach-omap2/gpmc-nand.c
index 9649fd9..f7491d0 100644
--- a/arch/arm/mach-omap2/gpmc-nand.c
+++ b/arch/arm/mach-omap2/gpmc-nand.c
@@ -127,10 +127,7 @@ int gpmc_nand_init(struct omap_nand_platform_data 
*gpmc_nand_data,
}
}
 
-   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;
 
diff --git a/arch/arm/mach-omap2/gpmc.c b/arch/arm/mach-omap2/gpmc.c
index a0c2194..c713616 100644
--- a/arch/arm/mach-omap2/gpmc.c
+++ b/arch/arm/mach-omap2/gpmc.c
@@ -29,7 +29,6 @@
 #include linux/of_address.h
 #include linux/of_mtd.h
 #include linux/of_device.h
-#include linux/mtd/nand.h
 #include linux/pm_runtime.h
 
 #include linux/platform_data/mtd-nand-omap2.h
@@ -40,7 +39,6 @@
 #include common.h
 #include omap_device.h
 #include gpmc.h
-#include gpmc-nand.h
 #include gpmc-onenand.h
 
 #defineDEVICE_NAME omap-gpmc
@@ -1168,96 +1166,6 @@ static void __maybe_unused gpmc_read_timings_dt(struct 
device_node *np,
of_property_read_bool(np, gpmc,time-para-granularity);
 }
 
-#if IS_ENABLED(CONFIG_MTD_NAND)
-
-static const char * const nand_xfer_types[] = {
-   [NAND_OMAP_PREFETCH_POLLED] = prefetch-polled,
-   [NAND_OMAP_POLLED]  = polled,
-   [NAND_OMAP_PREFETCH_DMA]= prefetch-dma,
-   [NAND_OMAP_PREFETCH_IRQ]= prefetch-irq,
-};
-
-static int gpmc_probe_nand_child(struct platform_device *pdev,
-struct device_node *child)
-{
-   u32 val;
-   const char *s;
-   struct gpmc_timings gpmc_t;
-   struct omap_nand_platform_data *gpmc_nand_data;
-
-   if (of_property_read_u32(child, reg, val)  0) {
-   dev_err(pdev-dev, %s has no 'reg' property\n,
-   child-full_name);
-   return -ENODEV;
-   }
-
-   gpmc_nand_data = devm_kzalloc(pdev-dev, sizeof(*gpmc_nand_data),
- GFP_KERNEL);
-   if (!gpmc_nand_data)
-   return -ENOMEM;
-
-   gpmc_nand_data-cs = val;
-   gpmc_nand_data-of_node = child;
-
-   /* Detect availability of ELM module */
-   gpmc_nand_data-elm_of_node = of_parse_phandle(child, ti,elm-id, 0);
-   if (gpmc_nand_data-elm_of_node == NULL)
-   gpmc_nand_data-elm_of_node =
-   of_parse_phandle(child, elm_id, 0);
-   if (gpmc_nand_data-elm_of_node == NULL)
-   pr_warn(%s: ti,elm-id property not found\n, __func__);
-
-   /* select ecc-scheme for NAND */
-   if (of_property_read_string(child, ti,nand-ecc-opt, s)) {
-   pr_err(%s: ti,nand-ecc-opt not found\n, __func__);
-   return -ENODEV;
-   }
-   if (!strcmp(s, ham1) || !strcmp(s, sw) ||
-   !strcmp(s, hw) || !strcmp(s, hw-romcode))
-   gpmc_nand_data-ecc_opt =
-   OMAP_ECC_HAM1_CODE_HW;
-   else if (!strcmp(s, bch4))
-   if (gpmc_nand_data-elm_of_node)
-   gpmc_nand_data-ecc_opt =
-   OMAP_ECC_BCH4_CODE_HW;
-   else
-   gpmc_nand_data-ecc_opt =
-   OMAP_ECC_BCH4_CODE_HW_DETECTION_SW;
-   else if (!strcmp(s, bch8))
-   if (gpmc_nand_data-elm_of_node)
-   gpmc_nand_data-ecc_opt =
-   OMAP_ECC_BCH8_CODE_HW;
-   else
-   gpmc_nand_data-ecc_opt =
-   OMAP_ECC_BCH8_CODE_HW_DETECTION_SW;
-   else
-   pr_err(%s: ti,nand-ecc-opt invalid value\n, __func__);
-
-   /* select data transfer mode for NAND controller */
-   if (!of_property_read_string(child, ti,nand-xfer-type, s))
-   for (val = 0; val  ARRAY_SIZE(nand_xfer_types); val++)
-   if (!strcasecmp(s, nand_xfer_types[val])) {
-   gpmc_nand_data-xfer_type = val;
-   break;
-   }
-
-   val = of_get_nand_bus_width(child);
-   if (val == 16)
-   gpmc_nand_data-devsize = NAND_BUSWIDTH_16;
-
-   gpmc_read_timings_dt(child, 

[PATCH 10/36] ARM: dts: OMAP2+: Fix NAND device nodes

2014-06-11 Thread Roger Quadros
Add compatible id, GPMC register resource and interrupt
resource to NAND controller nodes.

Signed-off-by: Roger Quadros rog...@ti.com
---
 arch/arm/boot/dts/am335x-evm.dts |  8 ++--
 arch/arm/boot/dts/am335x-igep0033.dtsi   |  8 ++--
 arch/arm/boot/dts/am43x-epos-evm.dts |  8 ++--
 arch/arm/boot/dts/omap3-devkit8000.dts   |  9 +++--
 arch/arm/boot/dts/omap3-evm-37xx.dts | 10 +++---
 arch/arm/boot/dts/omap3-igep0020.dts | 10 +++---
 arch/arm/boot/dts/omap3-igep0030.dts |  8 ++--
 arch/arm/boot/dts/omap3-ldp.dts  | 10 +++---
 arch/arm/boot/dts/omap3-lilly-a83x.dtsi  | 10 +++---
 arch/arm/boot/dts/omap3-lilly-dbb056.dts |  7 ---
 arch/arm/boot/dts/omap3430-sdp.dts   |  8 ++--
 11 files changed, 69 insertions(+), 27 deletions(-)

diff --git a/arch/arm/boot/dts/am335x-evm.dts b/arch/arm/boot/dts/am335x-evm.dts
index 6028217..fa25f2b 100644
--- a/arch/arm/boot/dts/am335x-evm.dts
+++ b/arch/arm/boot/dts/am335x-evm.dts
@@ -437,9 +437,13 @@
status = okay;
pinctrl-names = default;
pinctrl-0 = nandflash_pins_s0;
-   ranges = 0 0 0x0800 0x1000;   /* CS0: NAND */
+   ranges = 0 0 0x0800 0x1000 /* CS0 space, 16MB */
+ 255 0 0x5000 0x36c;  /* GPMC reg */
nand@0,0 {
-   reg = 0 0 0; /* CS0, offset 0 */
+   compatible = ti,omap2-nand;
+   reg = 0 0 4/* CS0, I/O window 4 bytes */
+  255 0 0x36c;/* GPMC reg */
+   interrupts = 100;
ti,nand-ecc-opt = bch8;
ti,elm-id = elm;
nand-bus-width = 8;
diff --git a/arch/arm/boot/dts/am335x-igep0033.dtsi 
b/arch/arm/boot/dts/am335x-igep0033.dtsi
index 9f22c18..4c3f21f 100644
--- a/arch/arm/boot/dts/am335x-igep0033.dtsi
+++ b/arch/arm/boot/dts/am335x-igep0033.dtsi
@@ -112,10 +112,14 @@
pinctrl-names = default;
pinctrl-0 = nandflash_pins;
 
-   ranges = 0 0 0x0800 0x1000;   /* CS0: NAND */
+   ranges = 0 0 0x0800 0x1000 /* CS0 space, 16MB */
+ 255 0 0x5000 0x36c;  /* GPMC reg */
 
nand@0,0 {
-   reg = 0 0 0; /* CS0, offset 0 */
+   compatible = ti,omap2-nand;
+   reg = 0 0 4/* CS0, I/O window 4 bytes */
+  255 0 0x36c;/* GPMC reg */
+   interrupts = 100;
nand-bus-width = 8;
ti,nand-ecc-opt = bch8;
gpmc,device-width = 1;
diff --git a/arch/arm/boot/dts/am43x-epos-evm.dts 
b/arch/arm/boot/dts/am43x-epos-evm.dts
index 167dbc8..d757134 100644
--- a/arch/arm/boot/dts/am43x-epos-evm.dts
+++ b/arch/arm/boot/dts/am43x-epos-evm.dts
@@ -268,9 +268,13 @@
status = okay;
pinctrl-names = default;
pinctrl-0 = nand_flash_x8;
-   ranges = 0 0 0x0800 0x1000;   /* CS0: NAND */
+   ranges = 0 0 0x0800 0x1000 /* CS0 space, 16MB */
+ 255 0 0x5000 0x36c;  /* GPMC reg */
nand@0,0 {
-   reg = 0 0 0; /* CS0, offset 0 */
+   compatible = ti,omap2-nand;
+   reg = 0 0 4/* CS0, I/O window 4 bytes */
+  255 0 0x36c;/* GPMC reg */
+   interrupts = GIC_SPI 4 IRQ_TYPE_LEVEL_HIGH;
ti,nand-ecc-opt = bch8;
ti,elm-id = elm;
nand-bus-width = 8;
diff --git a/arch/arm/boot/dts/omap3-devkit8000.dts 
b/arch/arm/boot/dts/omap3-devkit8000.dts
index da402f0..c5c7bbd 100644
--- a/arch/arm/boot/dts/omap3-devkit8000.dts
+++ b/arch/arm/boot/dts/omap3-devkit8000.dts
@@ -106,10 +106,15 @@
 };
 
 gpmc {
-   ranges = 0 0 0x3000 0x04;   /* CS0: NAND */
+   ranges = 0 0 0x3000 0x100  /* CS0 space, 16MB */
+ 255 0 0x6e00 0x02d4; /* register space */
 
+   /* Chip select 0 */
nand@0,0 {
-   reg = 0 0 0; /* CS0, offset 0 */
+   compatible = ti,omap2-nand;
+   reg = 0 0 4/* NAND I/O window, 4 bytes */
+  255 0 0x02d4;   /* GPMC register space */
+   interrupts = 20;
nand-bus-width = 16;
 
gpmc,sync-clk-ps = 0;
diff --git a/arch/arm/boot/dts/omap3-evm-37xx.dts 
b/arch/arm/boot/dts/omap3-evm-37xx.dts
index 4df68ad..7b2b3f4 100644
--- a/arch/arm/boot/dts/omap3-evm-37xx.dts
+++ b/arch/arm/boot/dts/omap3-evm-37xx.dts
@@ -95,12 +95,16 @@
 };
 
 gpmc {
-   ranges = 0 0 0x 0x2000,
-5 0 0x2c00 0x0100;
+   ranges = 0 0 0x 0x100  /* CS0 space, 16MB */
+ 5 0 0x2c00 0x100  /* CS5 space, 16MB */
+ 255 0 0x6e00 0x02d4; /* GPMC reg */
 
nand@0,0 {
+   compatible = ti,omap2-nand;
+   reg = 0 0 4/* CS0, I/O window, 4 bytes */
+  

[PATCH 04/36] ARM: OMAP2+: gpmc: Add gpmc timings and settings to platform data

2014-06-11 Thread Roger Quadros
Add device_timings, gpmc_timings and gpmc_setting to
gpmc platform data.

Signed-off-by: Roger Quadros rog...@ti.com
---
 arch/arm/mach-omap2/gpmc.h  | 134 --
 include/linux/platform_data/gpmc-omap.h | 139 
 2 files changed, 139 insertions(+), 134 deletions(-)

diff --git a/arch/arm/mach-omap2/gpmc.h b/arch/arm/mach-omap2/gpmc.h
index c476712..13554e7 100644
--- a/arch/arm/mach-omap2/gpmc.h
+++ b/arch/arm/mach-omap2/gpmc.h
@@ -71,140 +71,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_16BIT2   /* 16-bit device width */
-#define GPMC_MUX_AAD   1   /* Addr-Addr-Data multiplex */
-#define GPMC_MUX_AD2   /* 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 

[PATCH 03/36] ARM: OMAP2+: gpmc: Add platform data

2014-06-11 Thread Roger Quadros
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.

Signed-off-by: Roger Quadros rog...@ti.com
---
 arch/arm/mach-omap2/gpmc.h  |  4 +---
 include/linux/platform_data/gpmc-omap.h | 30 ++
 2 files changed, 31 insertions(+), 3 deletions(-)
 create mode 100644 include/linux/platform_data/gpmc-omap.h

diff --git a/arch/arm/mach-omap2/gpmc.h b/arch/arm/mach-omap2/gpmc.h
index 707f6d5..c476712 100644
--- a/arch/arm/mach-omap2/gpmc.h
+++ b/arch/arm/mach-omap2/gpmc.h
@@ -12,9 +12,7 @@
 #define __OMAP2_GPMC_H
 
 #include linux/platform_data/mtd-nand-omap2.h
-
-/* Maximum Number of Chip Selects */
-#define GPMC_CS_NUM8
+#include linux/platform_data/gpmc-omap.h
 
 #define GPMC_CS_CONFIG10x00
 #define GPMC_CS_CONFIG20x04
diff --git a/include/linux/platform_data/gpmc-omap.h 
b/include/linux/platform_data/gpmc-omap.h
new file mode 100644
index 000..d32d9de
--- /dev/null
+++ b/include/linux/platform_data/gpmc-omap.h
@@ -0,0 +1,30 @@
+/*
+ * OMAP GPMC Platform data
+ *
+ * Copyright (C) 2014 Texas Instruments, Inc. - http://www.ti.com
+ * Roger Quadros rog...@ti.com
+ *
+ * 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_NUM8
+
+/* 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 */
-- 
1.8.3.2

--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 08/36] mtd: nand: omap: Copy platform data parameters to omap_nand_info data

2014-06-11 Thread 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.

Signed-off-by: Roger Quadros rog...@ti.com
---
 drivers/mtd/nand/omap2.c | 27 ++-
 1 file changed, 18 insertions(+), 9 deletions(-)

diff --git a/drivers/mtd/nand/omap2.c b/drivers/mtd/nand/omap2.c
index bb41796..e205863 100644
--- a/drivers/mtd/nand/omap2.c
+++ b/drivers/mtd/nand/omap2.c
@@ -184,15 +184,19 @@ static struct nand_ecclayout omap_oobinfo;
 
 struct omap_nand_info {
struct nand_hw_control  controller;
-   struct omap_nand_platform_data  *pdata;
struct mtd_info mtd;
struct nand_chipnand;
struct platform_device  *pdev;
 
int gpmc_cs;
+   booldev_ready;
+   enum nand_ioxfer_type;
+   int devsize;
+   enum omap_ecc   ecc_opt;
+   struct device_node  *elm_of_node;
+
unsigned long   phys_base;
void __iomem*gpmc_base;
-   enum omap_ecc   ecc_opt;
struct completion   comp;
struct dma_chan *dma;
int gpmc_irq;
@@ -1708,6 +1712,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;
+
mtd = info-mtd;
mtd-priv   = info-nand;
mtd-name   = dev_name(pdev-dev);
@@ -1762,7 +1771,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 {
@@ -1771,7 +1780,7 @@ static int omap_nand_probe(struct platform_device *pdev)
}
 
/* 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)) {
pr_err(nand device scan failed, may be bus-width mismatch\n);
err = -ENXIO;
@@ -1779,14 +1788,14 @@ static int omap_nand_probe(struct platform_device *pdev)
}
 
/* check for small page devices */
-   if ((mtd-oobsize  64)  (pdata-ecc_opt != OMAP_ECC_HAM1_CODE_HW)) {
+   if ((mtd-oobsize  64)  (info-ecc_opt != OMAP_ECC_HAM1_CODE_HW)) {
pr_err(small page devices are not supported\n);
err = -EINVAL;
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;
@@ -1849,7 +1858,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;
}
@@ -1945,7 +1954,7 @@ static int omap_nand_probe(struct platform_device *pdev)
ecclayout-oobfree-offset  =
ecclayout-eccpos[ecclayout-eccbytes - 1] + 1;
/* This ECC scheme requires ELM H/W block */
-   if (is_elm_present(info, pdata-elm_of_node, BCH4_ECC)  0) {
+   if (is_elm_present(info, info-elm_of_node, BCH4_ECC)  0) {
pr_err(nand: error: could not initialize ELM\n);
err = -ENODEV;
goto return_error;
@@ -2011,7 +2020,7 @@ static int omap_nand_probe(struct platform_device *pdev)
nand_chip-ecc.read_page= omap_read_page_bch;
nand_chip-ecc.write_page   = omap_write_page_bch;
/* This ECC scheme requires ELM H/W block */
-   err = is_elm_present(info, pdata-elm_of_node, BCH8_ECC);
+   err = is_elm_present(info, info-elm_of_node, BCH8_ECC);
if (err  0) {
pr_err(nand: error: could not initialize ELM\n);

[PATCH 06/36] mtd: nand: omap: Move gpmc_update_nand_reg to nand driver

2014-06-11 Thread Roger Quadros
GPMC and NAND drivers share the same register space but never use the
same registers. As there is no clear address seperation between the
registers for GPMC and NAND, we can't easily split it up into 2 regions
i.e. one for GPMC and other for NAND. Instead, we simply remap the entire
register space in both the drivers. The NAND driver doesn't re-request
the region as it is already requested by the GPMC driver (parent).

Signed-off-by: Roger Quadros rog...@ti.com
---
 arch/arm/mach-omap2/gpmc-nand.c  |  16 +++-
 arch/arm/mach-omap2/gpmc.c   |  34 +---
 arch/arm/mach-omap2/gpmc.h   |   5 +-
 drivers/mtd/nand/omap2.c | 123 ---
 include/linux/platform_data/mtd-nand-omap2.h |   3 +-
 5 files changed, 127 insertions(+), 54 deletions(-)

diff --git a/arch/arm/mach-omap2/gpmc-nand.c b/arch/arm/mach-omap2/gpmc-nand.c
index 3e6420b..aaebd2f 100644
--- a/arch/arm/mach-omap2/gpmc-nand.c
+++ b/arch/arm/mach-omap2/gpmc-nand.c
@@ -26,11 +26,16 @@
 
 static struct resource gpmc_nand_resource[] = {
{
+   /* GPMC I/O space */
.flags  = IORESOURCE_MEM,
},
{
-   .flags  = IORESOURCE_IRQ,
+   /* GPMC register space */
+   .flags  = IORESOURCE_MEM,
},
+   {
+   .flags  = IORESOURCE_IRQ,
+   }
 };
 
 static struct platform_device gpmc_nand_device = {
@@ -91,6 +96,7 @@ int gpmc_nand_init(struct omap_nand_platform_data 
*gpmc_nand_data,
int err = 0;
struct gpmc_settings s;
struct device *dev = gpmc_nand_device.dev;
+   struct resource res;
 
memset(s, 0, sizeof(struct gpmc_settings));
 
@@ -107,7 +113,11 @@ int gpmc_nand_init(struct omap_nand_platform_data 
*gpmc_nand_data,
gpmc_nand_resource[0].end = gpmc_nand_resource[0].start +
NAND_IO_SIZE - 1;
 
-   gpmc_nand_resource[1].start = gpmc_get_irq();
+   gpmc_get_mem_resource(res);
+   gpmc_nand_resource[1].start = res.start;
+   gpmc_nand_resource[1].end = res.end;
+
+   gpmc_nand_resource[2].start = gpmc_get_irq();
 
if (gpmc_t) {
err = gpmc_cs_set_timings(gpmc_nand_data-cs, gpmc_t);
@@ -132,8 +142,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)) {
dev_err(dev, Unsupported NAND ECC scheme selected\n);
return -EINVAL;
diff --git a/arch/arm/mach-omap2/gpmc.c b/arch/arm/mach-omap2/gpmc.c
index 2524541..0a8b6ca 100644
--- a/arch/arm/mach-omap2/gpmc.c
+++ b/arch/arm/mach-omap2/gpmc.c
@@ -625,38 +625,10 @@ int gpmc_configure(int cmd, int wval)
 }
 EXPORT_SYMBOL(gpmc_configure);
 
-void gpmc_update_nand_reg(struct gpmc_nand_regs *reg, int cs)
+void gpmc_get_mem_resource(struct resource *res)
 {
-   int i;
-
-   reg-gpmc_status = gpmc_base + GPMC_STATUS;
-   reg-gpmc_irqstatus = gpmc_base + GPMC_IRQSTATUS;
-   reg-gpmc_irqenable = gpmc_base + GPMC_IRQENABLE;
-   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 +
-   GPMC_CS_NAND_ADDRESS + GPMC_CS_SIZE * cs;
-   reg-gpmc_nand_data = gpmc_base + GPMC_CS0_OFFSET +
-   GPMC_CS_NAND_DATA + GPMC_CS_SIZE * cs;
-   reg-gpmc_prefetch_config1 = gpmc_base + GPMC_PREFETCH_CONFIG1;
-   reg-gpmc_prefetch_config2 = gpmc_base + GPMC_PREFETCH_CONFIG2;
-   reg-gpmc_prefetch_control = gpmc_base + GPMC_PREFETCH_CONTROL;
-   reg-gpmc_prefetch_status = gpmc_base + GPMC_PREFETCH_STATUS;
-   reg-gpmc_ecc_config = gpmc_base + GPMC_ECC_CONFIG;
-   reg-gpmc_ecc_control = gpmc_base + GPMC_ECC_CONTROL;
-   reg-gpmc_ecc_size_config = gpmc_base + GPMC_ECC_SIZE_CONFIG;
-   reg-gpmc_ecc1_result = gpmc_base + GPMC_ECC1_RESULT;
-
-   for (i = 0; i  GPMC_BCH_NUM_REMAINDER; i++) {
-   reg-gpmc_bch_result0[i] = gpmc_base + GPMC_ECC_BCH_RESULT_0 +
-  GPMC_BCH_SIZE * i;
-   reg-gpmc_bch_result1[i] = gpmc_base + GPMC_ECC_BCH_RESULT_1 +
-  GPMC_BCH_SIZE * i;
-   reg-gpmc_bch_result2[i] = gpmc_base + GPMC_ECC_BCH_RESULT_2 +
-  GPMC_BCH_SIZE * i;
-   reg-gpmc_bch_result3[i] = gpmc_base + GPMC_ECC_BCH_RESULT_3 +
-  GPMC_BCH_SIZE * i;
-   }
+   res-start =  phys_base;
+   res-end = res-start + mem_size - 1;
 }
 
 int gpmc_get_irq(void)
diff --git a/arch/arm/mach-omap2/gpmc.h 

[PATCH 05/36] mtd: nand: omap: Move IRQ handling from GPMC to NAND driver

2014-06-11 Thread Roger Quadros
Since the Interrupt Events are used only by the NAND driver,
there is no point in managing the Interrupt registers
in the GPMC driver and complicating it with irqchip modeling.

Let's manage the interrupt registers directly in the NAND driver
and get rid of irqchip model from GPMC driver.

Get rid of IRQ commands and unused commands from gpmc_configure() in
the GPMC driver.

Signed-off-by: Roger Quadros rog...@ti.com
---
 arch/arm/mach-omap2/gpmc-nand.c  |   8 +-
 arch/arm/mach-omap2/gpmc.c   | 168 ++-
 arch/arm/mach-omap2/gpmc.h   |   8 +-
 drivers/mtd/nand/omap2.c |  76 ++--
 include/linux/platform_data/mtd-nand-omap2.h |   2 +
 5 files changed, 56 insertions(+), 206 deletions(-)

diff --git a/arch/arm/mach-omap2/gpmc-nand.c b/arch/arm/mach-omap2/gpmc-nand.c
index 4349e82..3e6420b 100644
--- a/arch/arm/mach-omap2/gpmc-nand.c
+++ b/arch/arm/mach-omap2/gpmc-nand.c
@@ -31,9 +31,6 @@ static struct resource gpmc_nand_resource[] = {
{
.flags  = IORESOURCE_IRQ,
},
-   {
-   .flags  = IORESOURCE_IRQ,
-   },
 };
 
 static struct platform_device gpmc_nand_device = {
@@ -110,10 +107,7 @@ int gpmc_nand_init(struct omap_nand_platform_data 
*gpmc_nand_data,
gpmc_nand_resource[0].end = gpmc_nand_resource[0].start +
NAND_IO_SIZE - 1;
 
-   gpmc_nand_resource[1].start =
-   gpmc_get_client_irq(GPMC_IRQ_FIFOEVENTENABLE);
-   gpmc_nand_resource[2].start =
-   gpmc_get_client_irq(GPMC_IRQ_COUNT_EVENT);
+   gpmc_nand_resource[1].start = gpmc_get_irq();
 
if (gpmc_t) {
err = gpmc_cs_set_timings(gpmc_nand_data-cs, gpmc_t);
diff --git a/arch/arm/mach-omap2/gpmc.c b/arch/arm/mach-omap2/gpmc.c
index 9fe8c94..2524541 100644
--- a/arch/arm/mach-omap2/gpmc.c
+++ b/arch/arm/mach-omap2/gpmc.c
@@ -111,15 +111,6 @@
 
 #define GPMC_NR_WAITPINS   4
 
-/* XXX: Only NAND irq has been considered,currently these are the only ones 
used
- */
-#defineGPMC_NR_IRQ 2
-
-struct gpmc_client_irq {
-   unsignedirq;
-   u32 bitmask;
-};
-
 /* Structure to save gpmc cs context */
 struct gpmc_cs_config {
u32 config1;
@@ -147,10 +138,6 @@ 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;
-
 static struct resource gpmc_mem_root;
 static struct resource gpmc_cs_mem[GPMC_CS_NUM];
 static DEFINE_SPINLOCK(gpmc_mem_lock);
@@ -159,15 +146,13 @@ static unsigned int gpmc_cs_map = ((1  GPMC_CS_NUM) - 
1);
 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 int gpmc_irq = -EINVAL;
 static resource_size_t phys_base, mem_size;
 static unsigned gpmc_capability;
 static void __iomem *gpmc_base;
 
 static struct clk *gpmc_l3_clk;
 
-static irqreturn_t gpmc_handle_irq(int irq, void *dev);
-
 static void gpmc_write_reg(int idx, u32 val)
 {
__raw_writel(val, gpmc_base + idx);
@@ -622,14 +607,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)
@@ -653,6 +630,8 @@ void gpmc_update_nand_reg(struct gpmc_nand_regs *reg, int 
cs)
int i;
 
reg-gpmc_status = gpmc_base + GPMC_STATUS;
+   reg-gpmc_irqstatus = gpmc_base + GPMC_IRQSTATUS;
+   reg-gpmc_irqenable = gpmc_base + GPMC_IRQENABLE;
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 +
@@ -680,113 +659,9 @@ void gpmc_update_nand_reg(struct gpmc_nand_regs *reg, int 
cs)
}
 }
 
-int gpmc_get_client_irq(unsigned irq_config)
-{
-   int i;
-
-   if (hweight32(irq_config)  1)
-   return 0;
-
-   for (i = 0; i  GPMC_NR_IRQ; i++)
-   if (gpmc_client_irq[i].bitmask  irq_config)
-   return gpmc_client_irq[i].irq;
-
-   return 0;
-}
-
-static int gpmc_irq_endis(unsigned irq, 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;
- 

[PATCH 02/36] ARM: dts: OMAP2+: Fix GPMC register space size

2014-06-11 Thread Roger Quadros
Use actual register space size from Reference Manual.

Signed-off-by: Roger Quadros rog...@ti.com
---
 arch/arm/boot/dts/am33xx.dtsi   | 2 +-
 arch/arm/boot/dts/am4372.dtsi   | 2 +-
 arch/arm/boot/dts/omap2420.dtsi | 2 +-
 arch/arm/boot/dts/omap2430.dtsi | 2 +-
 arch/arm/boot/dts/omap3.dtsi| 2 +-
 arch/arm/boot/dts/omap4.dtsi| 2 +-
 arch/arm/boot/dts/omap5.dtsi| 2 +-
 7 files changed, 7 insertions(+), 7 deletions(-)

diff --git a/arch/arm/boot/dts/am33xx.dtsi b/arch/arm/boot/dts/am33xx.dtsi
index 7ad75b4..27f0b25 100644
--- a/arch/arm/boot/dts/am33xx.dtsi
+++ b/arch/arm/boot/dts/am33xx.dtsi
@@ -767,7 +767,7 @@
compatible = ti,am3352-gpmc;
ti,hwmods = gpmc;
ti,no-idle-on-init;
-   reg = 0x5000 0x2000;
+   reg = 0x5000 0x36c;
interrupts = 100;
gpmc,num-cs = 7;
gpmc,num-waitpins = 2;
diff --git a/arch/arm/boot/dts/am4372.dtsi b/arch/arm/boot/dts/am4372.dtsi
index d1f8707..0014d5d 100644
--- a/arch/arm/boot/dts/am4372.dtsi
+++ b/arch/arm/boot/dts/am4372.dtsi
@@ -727,7 +727,7 @@
ti,hwmods = gpmc;
clocks = l3s_gclk;
clock-names = fck;
-   reg = 0x5000 0x2000;
+   reg = 0x5000 0x36c;
interrupts = GIC_SPI 100 IRQ_TYPE_LEVEL_HIGH;
gpmc,num-cs = 7;
gpmc,num-waitpins = 2;
diff --git a/arch/arm/boot/dts/omap2420.dtsi b/arch/arm/boot/dts/omap2420.dtsi
index 2d99798..d0f5953 100644
--- a/arch/arm/boot/dts/omap2420.dtsi
+++ b/arch/arm/boot/dts/omap2420.dtsi
@@ -79,7 +79,7 @@
 
gpmc: gpmc@6800a000 {
compatible = ti,omap2420-gpmc;
-   reg = 0x6800a000 0x1000;
+   reg = 0x6800a000 0x23c;
#address-cells = 2;
#size-cells = 1;
interrupts = 20;
diff --git a/arch/arm/boot/dts/omap2430.dtsi b/arch/arm/boot/dts/omap2430.dtsi
index 42d2c61..94f81e8 100644
--- a/arch/arm/boot/dts/omap2430.dtsi
+++ b/arch/arm/boot/dts/omap2430.dtsi
@@ -106,7 +106,7 @@
 
gpmc: gpmc@6e00 {
compatible = ti,omap2430-gpmc;
-   reg = 0x6e00 0x1000;
+   reg = 0x6e00 0x23c;
#address-cells = 2;
#size-cells = 1;
interrupts = 20;
diff --git a/arch/arm/boot/dts/omap3.dtsi b/arch/arm/boot/dts/omap3.dtsi
index 4231191..fc7a3e3 100644
--- a/arch/arm/boot/dts/omap3.dtsi
+++ b/arch/arm/boot/dts/omap3.dtsi
@@ -687,7 +687,7 @@
gpmc: gpmc@6e00 {
compatible = ti,omap3430-gpmc;
ti,hwmods = gpmc;
-   reg = 0x6e00 0x02d0;
+   reg = 0x6e00 0x02d4;
interrupts = 20;
gpmc,num-cs = 8;
gpmc,num-waitpins = 4;
diff --git a/arch/arm/boot/dts/omap4.dtsi b/arch/arm/boot/dts/omap4.dtsi
index 649b5cd..469c699 100644
--- a/arch/arm/boot/dts/omap4.dtsi
+++ b/arch/arm/boot/dts/omap4.dtsi
@@ -288,7 +288,7 @@
 
gpmc: gpmc@5000 {
compatible = ti,omap4430-gpmc;
-   reg = 0x5000 0x1000;
+   reg = 0x5000 0x37c;
#address-cells = 2;
#size-cells = 1;
interrupts = GIC_SPI 20 IRQ_TYPE_LEVEL_HIGH;
diff --git a/arch/arm/boot/dts/omap5.dtsi b/arch/arm/boot/dts/omap5.dtsi
index 36b4312..187c93f 100644
--- a/arch/arm/boot/dts/omap5.dtsi
+++ b/arch/arm/boot/dts/omap5.dtsi
@@ -317,7 +317,7 @@
 
gpmc: gpmc@5000 {
compatible = ti,omap4430-gpmc;
-   reg = 0x5000 0x1000;
+   reg = 0x5000 0x37c;
#address-cells = 2;
#size-cells = 1;
interrupts = GIC_SPI 20 IRQ_TYPE_LEVEL_HIGH;
-- 
1.8.3.2

--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 00/36] OMAP: GPMC: Restructure and move OMAP GPMC driver out of mach-omap2

2014-06-11 Thread Roger Quadros
Hi,

This is a complete functional set to get the gpmc driver out of mach-omap2
and into drivers/memory. The DT binding remains the same except for the
following minor changes
- compatible property is required for NAND  OneNAND nodes
- Second register space and interrupts properties are required for
  NAND controller node
- ti,onenand-sync-rw property added for OneNAND node.

The series does the following changes
- Move GPMC IRQ and NAND register handling to NAND driver.
  The entire GPMC register space is made available to the NAND driver.
- Clean up NAND device tree handling. Don't rely on legacy platform device
  i.e. don't call gpmc_nand_init()
- Add 2 public APIs omap_gpmc_retime() and omap_gpmc_get_clk_period()
  omap_gpmc_retime() allows to reconfigure the GPMC settings and timings
  for the specified Chip select region.
  omap_gpmc_get_clk_period() allows to query the GPMC_CLK (external clock)
  period, to perform timing calculations.
  Both functions will be needed by the OneNAND driver since it calculates
  device timings on the fly and needs to change from Asynchronous mode
  to Synchronous mode.
- Setup OneNAND in Asynchronous mode by default and move Synchronous
  setting code into OneNAND driver.
- Clean up OneNAND device tree handling. Don't rely on legacy platform device
  i.e. don't call gpmc_onenand_init()
- Introduce gpmc_generic_init() that should be used by board files to specify
  GPMC chip select setting/timing and platform device within that Chip Select.
- Stop using all gpmc*() that are meant to be private to GPMC driver.
- Move GPMC driver into drivers/memory

Tested on:

- beagleboard C4: NAND
- Nokia N900: OneNAND

Changelog:

[1] RFC patch - https://lkml.org/lkml/2014/5/21/218

cheers,
-roger

---
Roger Quadros (36):
  ARM: OMAP3: hwmod: Fix gpmc memory resource space
  ARM: dts: OMAP2+: Fix GPMC register space size
  ARM: OMAP2+: gpmc: Add platform data
  ARM: OMAP2+: gpmc: Add gpmc timings and settings to platform data
  mtd: nand: omap: Move IRQ handling from GPMC to NAND driver
  mtd: nand: omap: Move gpmc_update_nand_reg to nand driver
  mtd: nand: omap: Move NAND write protect code from GPMC to NAND driver
  mtd: nand: omap: Copy platform data parameters to omap_nand_info data
  mtd: nand: omap: Clean up device tree support
  ARM: dts: OMAP2+: Fix NAND device nodes
  mtd: nand: omap: Update DT binding documentation
  ARM: dts: omap3-beagle: Add NAND device
  ARM: OMAP2+: gpmc.c: sanity check bank-width DT property
  ARM: OMAP2+: gpmc: Allow drivers to reconfigure GPMC settings 
timings
  ARM: OMAP2+: gpmc: Allow drivers to query GPMC_CLK period
  mtd: onenand: omap: Remove regulator management code
  ARM: OMAP2+: gpmc-onenand: Use Async settings/timings by default
  ARM: OMAP2+: gpmc-onenand: Move Synchronous setting code to drivers/
  mtd: onenand: omap: Use devres managed resources
  mtd: onenand: omap: Clean up device tree support
  ARM: dts: OMAP2+: Fix OneNAND device nodes
  ARM: OMAP2+: gmpc: add gpmc_generic_init()
  ARM: OMAP2+: gpmc: use platform data to configure CS space and
poplulate device
  ARM: OMAP2+: gpmc: add NAND specific setup
  ARM: OMAP2+: gpmc: Support multiple Chip Selects per device
  ARM: OMAP2+: gpmc-smc91x: Get rid of retime() from
omap_smc91x_platform_data
  ARM: OMAP2+: usb-tusb6010: Use omap_gpmc_retime()
  ARM: OMAP2+: nand: Update gpmc_nand_init() to use generic_gpmc_init()
  ARM: OMAP2+: gpmc-smc91x: Use gpmc_generic_init()
  ARM: OMAP2+: gpmc-smsc911x: Use gpmc_generic_init()
  ARM: OMAP2: usb-tusb6010: Use gpmc_generic_init()
  ARM: OMAP2+: onenand: Use gpmc_generic_init()
  ARM: OMAP2+: board-flash: Use gpmc_generic_init() for NOR
  ARM: OMAP2+: gpmc: Make externally unused functions/defines private
  ARM: OMAP2+: gpmc: move GPMC driver into drivers/memory
  ARM: OMAP2+: defconfig: Enable TI GPMC driver

 .../devicetree/bindings/mtd/gpmc-nand.txt  |   16 +-
 .../devicetree/bindings/mtd/gpmc-onenand.txt   |4 +
 arch/arm/boot/dts/am335x-evm.dts   |8 +-
 arch/arm/boot/dts/am335x-igep0033.dtsi |8 +-
 arch/arm/boot/dts/am33xx.dtsi  |2 +-
 arch/arm/boot/dts/am4372.dtsi  |2 +-
 arch/arm/boot/dts/am43x-epos-evm.dts   |8 +-
 arch/arm/boot/dts/omap2420-n8x0-common.dtsi|5 +-
 arch/arm/boot/dts/omap2420.dtsi|2 +-
 arch/arm/boot/dts/omap2430.dtsi|2 +-
 arch/arm/boot/dts/omap3-beagle.dts |   53 +
 arch/arm/boot/dts/omap3-devkit8000.dts |9 +-
 arch/arm/boot/dts/omap3-evm-37xx.dts   |   10 +-
 arch/arm/boot/dts/omap3-igep0020.dts   |   10 +-
 arch/arm/boot/dts/omap3-igep0030.dts   |8 +-
 arch/arm/boot/dts/omap3-ldp.dts|   10 +-
 arch/arm/boot/dts/omap3-lilly-a83x.dtsi|   10 +-
 arch/arm/boot/dts/omap3-lilly-dbb056.dts   |7 +-
 

[resend][PATCH 35/36] ARM: OMAP2+: gpmc: move GPMC driver into drivers/memory

2014-06-11 Thread Roger Quadros
Resending with rename detection option to git-format-patch
for easier review.

From: Roger Quadros rog...@ti.com

Move the GPMC driver out of mach-omap2. We leave behind only
the mach-omap2 specific bits in mach-omap2/gpmc_legacy.c
i.e. gpmc_generic_init() for use by board files to register
the GPMC configuration and omap3_gpmc_save/restore_context() for
use by OMAP3 OFF mode support.

The GPMC driver is now enabled by its own kernel config option
TI_GPMC. The other drivers that need GPMC to work i.e. MTD_ONENAND_OMAP2
and MTD_NAND_OMAP2 are made to depend on TI_GPMC.

Signed-off-by: Roger Quadros rog...@ti.com
---
 arch/arm/mach-omap2/Makefile   |   2 +-
 arch/arm/mach-omap2/gpmc_legacy.c  | 296 
 drivers/memory/Kconfig |  10 +
 drivers/memory/Makefile|   1 +
 .../mach-omap2/gpmc.c = drivers/memory/ti-gpmc.c  | 388 +++--
 drivers/mtd/nand/Kconfig   |   2 +-
 drivers/mtd/onenand/Kconfig|   6 +-
 7 files changed, 447 insertions(+), 258 deletions(-)
 create mode 100644 arch/arm/mach-omap2/gpmc_legacy.c
 rename arch/arm/mach-omap2/gpmc.c = drivers/memory/ti-gpmc.c (90%)

diff --git a/arch/arm/mach-omap2/Makefile b/arch/arm/mach-omap2/Makefile
index 8421f38..a2e7426 100644
--- a/arch/arm/mach-omap2/Makefile
+++ b/arch/arm/mach-omap2/Makefile
@@ -6,7 +6,7 @@ ccflags-$(CONFIG_ARCH_MULTIPLATFORM) := 
-I$(srctree)/$(src)/include \
-I$(srctree)/arch/arm/plat-omap/include
 
 # Common support
-obj-y := id.o io.o control.o mux.o devices.o fb.o serial.o gpmc.o timer.o pm.o 
\
+obj-y := id.o io.o control.o mux.o devices.o fb.o serial.o gpmc_legacy.o 
timer.o pm.o \
 common.o gpio.o dma.o wd_timer.o display.o i2c.o hdq1w.o omap_hwmod.o \
 omap_device.o sram.o drm.o
 
diff --git a/arch/arm/mach-omap2/gpmc_legacy.c 
b/arch/arm/mach-omap2/gpmc_legacy.c
new file mode 100644
index 000..3b3f86e
--- /dev/null
+++ b/arch/arm/mach-omap2/gpmc_legacy.c
@@ -0,0 +1,296 @@
+/*
+ * GPMC support functions
+ *
+ * Copyright (C) 2005-2006 Nokia Corporation
+ *
+ * Author: Juha Yrjola
+ *
+ * Copyright (C) 2009 Texas Instruments
+ * Added OMAP4 support - Santosh Shilimkar santosh.shilim...@ti.com
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include linux/kernel.h
+#include linux/platform_device.h
+#include linux/slab.h
+#include linux/io.h
+
+#include soc.h
+#include gpmc.h
+#include omap_device.h
+
+#defineDEVICE_NAME omap-gpmc
+
+/* CS CONFIG registers */
+#define GPMC_CS_CONFIG10x00
+#define GPMC_CS_CONFIG20x04
+#define GPMC_CS_CONFIG30x08
+#define GPMC_CS_CONFIG40x0c
+#define GPMC_CS_CONFIG50x10
+#define GPMC_CS_CONFIG60x14
+#define GPMC_CS_CONFIG70x18
+
+#define GPMC_CS0_OFFSET0x60
+#define GPMC_CS_SIZE   0x30
+
+/* GPMC register offsets */
+#define GPMC_SYSCONFIG 0x10
+#define GPMC_IRQENABLE 0x1c
+#define GPMC_TIMEOUT_CONTROL   0x40
+#define GPMC_CONFIG0x50
+#define GPMC_PREFETCH_CONFIG1  0x1e0
+#define GPMC_PREFETCH_CONFIG2  0x1e4
+#define GPMC_PREFETCH_CONTROL  0x1ec
+
+#define GPMC_CONFIG7_CSVALID   (1  6)
+
+static struct gpmc_omap_platform_data gpmc_pdata;
+
+/* Structure to save gpmc cs context */
+struct gpmc_cs_config {
+   u32 config1;
+   u32 config2;
+   u32 config3;
+   u32 config4;
+   u32 config5;
+   u32 config6;
+   u32 config7;
+   int is_valid;
+};
+
+/*
+ * Structure to save/restore gpmc context
+ * to support core off on OMAP3
+ */
+struct omap3_gpmc_regs {
+   u32 sysconfig;
+   u32 irqenable;
+   u32 timeout_ctrl;
+   u32 config;
+   u32 prefetch_config1;
+   u32 prefetch_config2;
+   u32 prefetch_control;
+   struct gpmc_cs_config cs_context[GPMC_CS_NUM];
+};
+
+static int __init omap_gpmc_init(void)
+{
+   struct omap_hwmod *oh;
+   struct platform_device *pdev;
+   char *oh_name = gpmc;
+
+   /*
+* if the board boots up with a populated DT, do not
+* manually add the device from this initcall
+*/
+   if (of_have_populated_dt())
+   return -ENODEV;
+
+   oh = omap_hwmod_lookup(oh_name);
+   if (!oh) {
+   pr_err(Could not look up %s\n, oh_name);
+   return -ENODEV;
+   }
+
+   pdev = omap_device_build(DEVICE_NAME, -1, oh, (void *)gpmc_pdata,
+sizeof(gpmc_pdata));
+   WARN(IS_ERR(pdev), could not build omap_device for %s\n, oh_name);
+
+   return PTR_RET(pdev);
+}
+/* must run after machine_init code. i.e. arch_init */
+omap_subsys_initcall(omap_gpmc_init);
+
+/**
+ * 

Re: [PATCH 00/36] OMAP: GPMC: Restructure and move OMAP GPMC driver out of mach-omap2

2014-06-11 Thread Roger Quadros
Hi Javier,

On 06/11/2014 02:52 PM, Javier Martinez Canillas wrote:
 Hello Roger,
 
 What a great series!!

Thanks :)

 
 On Wed, Jun 11, 2014 at 10:56 AM, Roger Quadros rog...@ti.com wrote:
 Hi,

 This is a complete functional set to get the gpmc driver out of mach-omap2
 and into drivers/memory. The DT binding remains the same except for the
 following minor changes
 
 I probably won't have time to do a proper review until at least next
 week but doing a quick glance it looks very good to me.
 
 - compatible property is required for NAND  OneNAND nodes
 
 This is a minor ABI breakage but I agree with you that it is wrong
 that these were not introduced in the first place and relied on the
 dev node so I think is not that bad to break it in this case.
 
 - Second register space and interrupts properties are required for
   NAND controller node
 - ti,onenand-sync-rw property added for OneNAND node.

 The series does the following changes
 - Move GPMC IRQ and NAND register handling to NAND driver.
   The entire GPMC register space is made available to the NAND driver.
 - Clean up NAND device tree handling. Don't rely on legacy platform device
   i.e. don't call gpmc_nand_init()
 - Add 2 public APIs omap_gpmc_retime() and omap_gpmc_get_clk_period()
   omap_gpmc_retime() allows to reconfigure the GPMC settings and timings
   for the specified Chip select region.
   omap_gpmc_get_clk_period() allows to query the GPMC_CLK (external clock)
   period, to perform timing calculations.
   Both functions will be needed by the OneNAND driver since it calculates
   device timings on the fly and needs to change from Asynchronous mode
   to Synchronous mode.
 - Setup OneNAND in Asynchronous mode by default and move Synchronous
   setting code into OneNAND driver.
 - Clean up OneNAND device tree handling. Don't rely on legacy platform device
   i.e. don't call gpmc_onenand_init()
 - Introduce gpmc_generic_init() that should be used by board files to specify
   GPMC chip select setting/timing and platform device within that Chip 
 Select.
 - Stop using all gpmc*() that are meant to be private to GPMC driver.
 - Move GPMC driver into drivers/memory

 Tested on:

 - beagleboard C4: NAND
 - Nokia N900: OneNAND

 
 Do you have a tree somewhere that I can use it to test on the boards I
 maintain and post patches to update the DTS according the new binding?

You can find the series at
g...@github.com:rogerq/linux.git
gpmc-3.16-v1

cheers,
-roger

--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 00/36] OMAP: GPMC: Restructure and move OMAP GPMC driver out of mach-omap2

2014-06-11 Thread Javier Martinez Canillas
Hello Roger,

What a great series!!

On Wed, Jun 11, 2014 at 10:56 AM, Roger Quadros rog...@ti.com wrote:
 Hi,

 This is a complete functional set to get the gpmc driver out of mach-omap2
 and into drivers/memory. The DT binding remains the same except for the
 following minor changes

I probably won't have time to do a proper review until at least next
week but doing a quick glance it looks very good to me.

 - compatible property is required for NAND  OneNAND nodes

This is a minor ABI breakage but I agree with you that it is wrong
that these were not introduced in the first place and relied on the
dev node so I think is not that bad to break it in this case.

 - Second register space and interrupts properties are required for
   NAND controller node
 - ti,onenand-sync-rw property added for OneNAND node.

 The series does the following changes
 - Move GPMC IRQ and NAND register handling to NAND driver.
   The entire GPMC register space is made available to the NAND driver.
 - Clean up NAND device tree handling. Don't rely on legacy platform device
   i.e. don't call gpmc_nand_init()
 - Add 2 public APIs omap_gpmc_retime() and omap_gpmc_get_clk_period()
   omap_gpmc_retime() allows to reconfigure the GPMC settings and timings
   for the specified Chip select region.
   omap_gpmc_get_clk_period() allows to query the GPMC_CLK (external clock)
   period, to perform timing calculations.
   Both functions will be needed by the OneNAND driver since it calculates
   device timings on the fly and needs to change from Asynchronous mode
   to Synchronous mode.
 - Setup OneNAND in Asynchronous mode by default and move Synchronous
   setting code into OneNAND driver.
 - Clean up OneNAND device tree handling. Don't rely on legacy platform device
   i.e. don't call gpmc_onenand_init()
 - Introduce gpmc_generic_init() that should be used by board files to specify
   GPMC chip select setting/timing and platform device within that Chip Select.
 - Stop using all gpmc*() that are meant to be private to GPMC driver.
 - Move GPMC driver into drivers/memory

 Tested on:

 - beagleboard C4: NAND
 - Nokia N900: OneNAND


Do you have a tree somewhere that I can use it to test on the boards I
maintain and post patches to update the DTS according the new binding?

 Changelog:

 [1] RFC patch - https://lkml.org/lkml/2014/5/21/218

 cheers,
 -roger

 ---
 Roger Quadros (36):
   ARM: OMAP3: hwmod: Fix gpmc memory resource space
   ARM: dts: OMAP2+: Fix GPMC register space size
   ARM: OMAP2+: gpmc: Add platform data
   ARM: OMAP2+: gpmc: Add gpmc timings and settings to platform data
   mtd: nand: omap: Move IRQ handling from GPMC to NAND driver
   mtd: nand: omap: Move gpmc_update_nand_reg to nand driver
   mtd: nand: omap: Move NAND write protect code from GPMC to NAND driver
   mtd: nand: omap: Copy platform data parameters to omap_nand_info data
   mtd: nand: omap: Clean up device tree support
   ARM: dts: OMAP2+: Fix NAND device nodes
   mtd: nand: omap: Update DT binding documentation
   ARM: dts: omap3-beagle: Add NAND device
   ARM: OMAP2+: gpmc.c: sanity check bank-width DT property
   ARM: OMAP2+: gpmc: Allow drivers to reconfigure GPMC settings 
 timings
   ARM: OMAP2+: gpmc: Allow drivers to query GPMC_CLK period
   mtd: onenand: omap: Remove regulator management code
   ARM: OMAP2+: gpmc-onenand: Use Async settings/timings by default
   ARM: OMAP2+: gpmc-onenand: Move Synchronous setting code to drivers/
   mtd: onenand: omap: Use devres managed resources
   mtd: onenand: omap: Clean up device tree support
   ARM: dts: OMAP2+: Fix OneNAND device nodes
   ARM: OMAP2+: gmpc: add gpmc_generic_init()
   ARM: OMAP2+: gpmc: use platform data to configure CS space and
 poplulate device
   ARM: OMAP2+: gpmc: add NAND specific setup
   ARM: OMAP2+: gpmc: Support multiple Chip Selects per device
   ARM: OMAP2+: gpmc-smc91x: Get rid of retime() from
 omap_smc91x_platform_data
   ARM: OMAP2+: usb-tusb6010: Use omap_gpmc_retime()
   ARM: OMAP2+: nand: Update gpmc_nand_init() to use generic_gpmc_init()
   ARM: OMAP2+: gpmc-smc91x: Use gpmc_generic_init()
   ARM: OMAP2+: gpmc-smsc911x: Use gpmc_generic_init()
   ARM: OMAP2: usb-tusb6010: Use gpmc_generic_init()
   ARM: OMAP2+: onenand: Use gpmc_generic_init()
   ARM: OMAP2+: board-flash: Use gpmc_generic_init() for NOR
   ARM: OMAP2+: gpmc: Make externally unused functions/defines private
   ARM: OMAP2+: gpmc: move GPMC driver into drivers/memory
   ARM: OMAP2+: defconfig: Enable TI GPMC driver

  .../devicetree/bindings/mtd/gpmc-nand.txt  |   16 +-
  .../devicetree/bindings/mtd/gpmc-onenand.txt   |4 +
  arch/arm/boot/dts/am335x-evm.dts   |8 +-
  arch/arm/boot/dts/am335x-igep0033.dtsi |8 +-
  arch/arm/boot/dts/am33xx.dtsi  |2 +-
  arch/arm/boot/dts/am4372.dtsi  |2 +-
  arch/arm/boot/dts/am43x-epos-evm.dts   |8 +-
  arch/arm/boot/dts/omap2420-n8x0-common.dtsi   

[PATCH] [media] staging: allow omap4iss to be modular

2014-06-11 Thread Arnd Bergmann
The OMAP4 camera support depends on I2C and VIDEO_V4L2, both
of which can be loadable modules. This causes build failures
if we want the camera driver to be built-in.

This can be solved by turning the option into tristate,
which unfortunately causes another problem, because the
driver incorrectly calls a platform-internal interface
for omap4_ctrl_pad_readl/omap4_ctrl_pad_writel.
To work around that, we can export those symbols, but
that isn't really the correct solution, as we should not
have dependencies on platform code this way.

Signed-off-by: Arnd Bergmann a...@arndb.de
---
This is one of just two patches we currently need to get
'make allmodconfig' to build again on ARM.

diff --git a/arch/arm/mach-omap2/control.c b/arch/arm/mach-omap2/control.c
index 751f354..05d2d98 100644
--- a/arch/arm/mach-omap2/control.c
+++ b/arch/arm/mach-omap2/control.c
@@ -190,11 +190,13 @@ u32 omap4_ctrl_pad_readl(u16 offset)
 {
return readl_relaxed(OMAP4_CTRL_PAD_REGADDR(offset));
 }
+EXPORT_SYMBOL_GPL(omap4_ctrl_pad_readl);
 
 void omap4_ctrl_pad_writel(u32 val, u16 offset)
 {
writel_relaxed(val, OMAP4_CTRL_PAD_REGADDR(offset));
 }
+EXPORT_SYMBOL_GPL(omap4_ctrl_pad_writel);
 
 #ifdef CONFIG_ARCH_OMAP3
 
diff --git a/drivers/staging/media/omap4iss/Kconfig 
b/drivers/staging/media/omap4iss/Kconfig
index 78b0fba..0c3e3c1 100644
--- a/drivers/staging/media/omap4iss/Kconfig
+++ b/drivers/staging/media/omap4iss/Kconfig
@@ -1,5 +1,5 @@
 config VIDEO_OMAP4
-   bool OMAP 4 Camera support
+   tristate OMAP 4 Camera support
depends on VIDEO_V4L2  VIDEO_V4L2_SUBDEV_API  I2C  ARCH_OMAP4
select VIDEOBUF2_DMA_CONTIG
---help---

--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH] [media] staging: allow omap4iss to be modular

2014-06-11 Thread Tony Lindgren
* Arnd Bergmann a...@arndb.de [140611 07:37]:
 The OMAP4 camera support depends on I2C and VIDEO_V4L2, both
 of which can be loadable modules. This causes build failures
 if we want the camera driver to be built-in.

That's good news, but let's not fix it this way.
 
 This can be solved by turning the option into tristate,
 which unfortunately causes another problem, because the
 driver incorrectly calls a platform-internal interface
 for omap4_ctrl_pad_readl/omap4_ctrl_pad_writel.
 To work around that, we can export those symbols, but
 that isn't really the correct solution, as we should not
 have dependencies on platform code this way.
 
 Signed-off-by: Arnd Bergmann a...@arndb.de
 ---
 This is one of just two patches we currently need to get
 'make allmodconfig' to build again on ARM.
 
 diff --git a/arch/arm/mach-omap2/control.c b/arch/arm/mach-omap2/control.c
 index 751f354..05d2d98 100644
 --- a/arch/arm/mach-omap2/control.c
 +++ b/arch/arm/mach-omap2/control.c
 @@ -190,11 +190,13 @@ u32 omap4_ctrl_pad_readl(u16 offset)
  {
   return readl_relaxed(OMAP4_CTRL_PAD_REGADDR(offset));
  }
 +EXPORT_SYMBOL_GPL(omap4_ctrl_pad_readl);
  
  void omap4_ctrl_pad_writel(u32 val, u16 offset)
  {
   writel_relaxed(val, OMAP4_CTRL_PAD_REGADDR(offset));
  }
 +EXPORT_SYMBOL_GPL(omap4_ctrl_pad_writel);
  
  #ifdef CONFIG_ARCH_OMAP3

Exporting these will likely cause immediate misuse in other
drivers all over the place.

These should just use either pinctrl-single.c instead for muxing.
Or if they are not mux registers, we do have the syscon mapping
available in omap4.dtsi that pbias-regulator.c is already using.

Laurent, got any better ideas?

Regards,

Tony
--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH] [media] staging: allow omap4iss to be modular

2014-06-11 Thread Arnd Bergmann
On Wednesday 11 June 2014 09:42:04 Nishanth Menon wrote:
 On 06/11/2014 09:35 AM, Arnd Bergmann wrote:
  The OMAP4 camera support depends on I2C and VIDEO_V4L2, both
  of which can be loadable modules. This causes build failures
  if we want the camera driver to be built-in.
  
  This can be solved by turning the option into tristate,
  which unfortunately causes another problem, because the
  driver incorrectly calls a platform-internal interface
  for omap4_ctrl_pad_readl/omap4_ctrl_pad_writel.
  To work around that, we can export those symbols, but
  that isn't really the correct solution, as we should not
  have dependencies on platform code this way.
  
  Signed-off-by: Arnd Bergmann a...@arndb.de
  ---
  This is one of just two patches we currently need to get
  'make allmodconfig' to build again on ARM.
  
  diff --git a/arch/arm/mach-omap2/control.c b/arch/arm/mach-omap2/control.c
  index 751f354..05d2d98 100644
  --- a/arch/arm/mach-omap2/control.c
  +++ b/arch/arm/mach-omap2/control.c
  @@ -190,11 +190,13 @@ u32 omap4_ctrl_pad_readl(u16 offset)
   {
  return readl_relaxed(OMAP4_CTRL_PAD_REGADDR(offset));
   }
  +EXPORT_SYMBOL_GPL(omap4_ctrl_pad_readl);
   
   void omap4_ctrl_pad_writel(u32 val, u16 offset)
   {
  writel_relaxed(val, OMAP4_CTRL_PAD_REGADDR(offset));
   }
  +EXPORT_SYMBOL_GPL(omap4_ctrl_pad_writel);
   
   #ifdef CONFIG_ARCH_OMAP3
   
  diff --git a/drivers/staging/media/omap4iss/Kconfig 
  b/drivers/staging/media/omap4iss/Kconfig
  index 78b0fba..0c3e3c1 100644
  --- a/drivers/staging/media/omap4iss/Kconfig
  +++ b/drivers/staging/media/omap4iss/Kconfig
  @@ -1,5 +1,5 @@
   config VIDEO_OMAP4
  -   bool OMAP 4 Camera support
  +   tristate OMAP 4 Camera support
  depends on VIDEO_V4L2  VIDEO_V4L2_SUBDEV_API  I2C  ARCH_OMAP4
  select VIDEOBUF2_DMA_CONTIG
  ---help---
  
 
 This was discussed in detail here:
 http://marc.info/?t=14019869251r=1w=2
 Direct dependency from a staging driver to mach-omap2 driver is not
 something we'd like, right?

So it was decided to just leave ARM allmodconfig broken?

Why not at least do this instead?

8
From 3a965f4fd5a6b3ef4a66aa4e7c916cfd34fd5706 Mon Sep 17 00:00:00 2001
From: Arnd Bergmann a...@arndb.de
Date: Tue, 21 Jan 2014 09:32:43 +0100
Subject: [PATCH] [media] staging: tighten omap4iss dependencies

The OMAP4 camera support depends on I2C and VIDEO_V4L2, both
of which can be loadable modules. This causes build failures
if we want the camera driver to be built-in.

This can be solved by turning the option into tristate,
which unfortunately causes another problem, because the
driver incorrectly calls a platform-internal interface
for omap4_ctrl_pad_readl/omap4_ctrl_pad_writel.

Instead, this patch just forbids the invalid configurations
and ensures that the driver can only be built if all its
dependencies are built-in.

Signed-off-by: Arnd Bergmann a...@arndb.de

diff --git a/drivers/staging/media/omap4iss/Kconfig 
b/drivers/staging/media/omap4iss/Kconfig
index 78b0fba..8afc6fe 100644
--- a/drivers/staging/media/omap4iss/Kconfig
+++ b/drivers/staging/media/omap4iss/Kconfig
@@ -1,6 +1,6 @@
 config VIDEO_OMAP4
bool OMAP 4 Camera support
-   depends on VIDEO_V4L2  VIDEO_V4L2_SUBDEV_API  I2C  ARCH_OMAP4
+   depends on VIDEO_V4L2=y  VIDEO_V4L2_SUBDEV_API  I2C=y  ARCH_OMAP4
select VIDEOBUF2_DMA_CONTIG
---help---
  Driver for an OMAP 4 ISS controller.

--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH] [media] staging: allow omap4iss to be modular

2014-06-11 Thread Nishanth Menon
On 06/11/2014 09:49 AM, Arnd Bergmann wrote:
 On Wednesday 11 June 2014 09:42:04 Nishanth Menon wrote:
 On 06/11/2014 09:35 AM, Arnd Bergmann wrote:
 The OMAP4 camera support depends on I2C and VIDEO_V4L2, both
 of which can be loadable modules. This causes build failures
 if we want the camera driver to be built-in.

 This can be solved by turning the option into tristate,
 which unfortunately causes another problem, because the
 driver incorrectly calls a platform-internal interface
 for omap4_ctrl_pad_readl/omap4_ctrl_pad_writel.
 To work around that, we can export those symbols, but
 that isn't really the correct solution, as we should not
 have dependencies on platform code this way.

 Signed-off-by: Arnd Bergmann a...@arndb.de
 ---
 This is one of just two patches we currently need to get
 'make allmodconfig' to build again on ARM.

 diff --git a/arch/arm/mach-omap2/control.c b/arch/arm/mach-omap2/control.c
 index 751f354..05d2d98 100644
 --- a/arch/arm/mach-omap2/control.c
 +++ b/arch/arm/mach-omap2/control.c
 @@ -190,11 +190,13 @@ u32 omap4_ctrl_pad_readl(u16 offset)
  {
 return readl_relaxed(OMAP4_CTRL_PAD_REGADDR(offset));
  }
 +EXPORT_SYMBOL_GPL(omap4_ctrl_pad_readl);
  
  void omap4_ctrl_pad_writel(u32 val, u16 offset)
  {
 writel_relaxed(val, OMAP4_CTRL_PAD_REGADDR(offset));
  }
 +EXPORT_SYMBOL_GPL(omap4_ctrl_pad_writel);
  
  #ifdef CONFIG_ARCH_OMAP3
  
 diff --git a/drivers/staging/media/omap4iss/Kconfig 
 b/drivers/staging/media/omap4iss/Kconfig
 index 78b0fba..0c3e3c1 100644
 --- a/drivers/staging/media/omap4iss/Kconfig
 +++ b/drivers/staging/media/omap4iss/Kconfig
 @@ -1,5 +1,5 @@
  config VIDEO_OMAP4
 -   bool OMAP 4 Camera support
 +   tristate OMAP 4 Camera support
 depends on VIDEO_V4L2  VIDEO_V4L2_SUBDEV_API  I2C  ARCH_OMAP4
 select VIDEOBUF2_DMA_CONTIG
 ---help---


 This was discussed in detail here:
 http://marc.info/?t=14019869251r=1w=2
 Direct dependency from a staging driver to mach-omap2 driver is not
 something we'd like, right?
 
 So it was decided to just leave ARM allmodconfig broken?
 
 Why not at least do this instead?
 
 8
 From 3a965f4fd5a6b3ef4a66aa4e7c916cfd34fd5706 Mon Sep 17 00:00:00 2001
 From: Arnd Bergmann a...@arndb.de
 Date: Tue, 21 Jan 2014 09:32:43 +0100
 Subject: [PATCH] [media] staging: tighten omap4iss dependencies
 
 The OMAP4 camera support depends on I2C and VIDEO_V4L2, both
 of which can be loadable modules. This causes build failures
 if we want the camera driver to be built-in.
 
 This can be solved by turning the option into tristate,
 which unfortunately causes another problem, because the
 driver incorrectly calls a platform-internal interface
 for omap4_ctrl_pad_readl/omap4_ctrl_pad_writel.
 
 Instead, this patch just forbids the invalid configurations
 and ensures that the driver can only be built if all its
 dependencies are built-in.
 
 Signed-off-by: Arnd Bergmann a...@arndb.de
 
 diff --git a/drivers/staging/media/omap4iss/Kconfig 
 b/drivers/staging/media/omap4iss/Kconfig
 index 78b0fba..8afc6fe 100644
 --- a/drivers/staging/media/omap4iss/Kconfig
 +++ b/drivers/staging/media/omap4iss/Kconfig
 @@ -1,6 +1,6 @@
  config VIDEO_OMAP4
   bool OMAP 4 Camera support
 - depends on VIDEO_V4L2  VIDEO_V4L2_SUBDEV_API  I2C  ARCH_OMAP4
 + depends on VIDEO_V4L2=y  VIDEO_V4L2_SUBDEV_API  I2C=y  ARCH_OMAP4
   select VIDEOBUF2_DMA_CONTIG
   ---help---
 Driver for an OMAP 4 ISS controller.
 

I am ok with this if Tony and Laurent have no issues. Considering that
Laurent was working on coverting iss driver to dt, the detailed
discussion could take place at that point in time.

-- 
Regards,
Nishanth Menon
--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH] [media] staging: allow omap4iss to be modular

2014-06-11 Thread Nishanth Menon
On 06/11/2014 09:35 AM, Arnd Bergmann wrote:
 The OMAP4 camera support depends on I2C and VIDEO_V4L2, both
 of which can be loadable modules. This causes build failures
 if we want the camera driver to be built-in.
 
 This can be solved by turning the option into tristate,
 which unfortunately causes another problem, because the
 driver incorrectly calls a platform-internal interface
 for omap4_ctrl_pad_readl/omap4_ctrl_pad_writel.
 To work around that, we can export those symbols, but
 that isn't really the correct solution, as we should not
 have dependencies on platform code this way.
 
 Signed-off-by: Arnd Bergmann a...@arndb.de
 ---
 This is one of just two patches we currently need to get
 'make allmodconfig' to build again on ARM.
 
 diff --git a/arch/arm/mach-omap2/control.c b/arch/arm/mach-omap2/control.c
 index 751f354..05d2d98 100644
 --- a/arch/arm/mach-omap2/control.c
 +++ b/arch/arm/mach-omap2/control.c
 @@ -190,11 +190,13 @@ u32 omap4_ctrl_pad_readl(u16 offset)
  {
   return readl_relaxed(OMAP4_CTRL_PAD_REGADDR(offset));
  }
 +EXPORT_SYMBOL_GPL(omap4_ctrl_pad_readl);
  
  void omap4_ctrl_pad_writel(u32 val, u16 offset)
  {
   writel_relaxed(val, OMAP4_CTRL_PAD_REGADDR(offset));
  }
 +EXPORT_SYMBOL_GPL(omap4_ctrl_pad_writel);
  
  #ifdef CONFIG_ARCH_OMAP3
  
 diff --git a/drivers/staging/media/omap4iss/Kconfig 
 b/drivers/staging/media/omap4iss/Kconfig
 index 78b0fba..0c3e3c1 100644
 --- a/drivers/staging/media/omap4iss/Kconfig
 +++ b/drivers/staging/media/omap4iss/Kconfig
 @@ -1,5 +1,5 @@
  config VIDEO_OMAP4
 - bool OMAP 4 Camera support
 + tristate OMAP 4 Camera support
   depends on VIDEO_V4L2  VIDEO_V4L2_SUBDEV_API  I2C  ARCH_OMAP4
   select VIDEOBUF2_DMA_CONTIG
   ---help---
 
 --
 To unsubscribe from this list: send the line unsubscribe linux-omap in
 the body of a message to majord...@vger.kernel.org
 More majordomo info at  http://vger.kernel.org/majordomo-info.html
 

This was discussed in detail here:
http://marc.info/?t=14019869251r=1w=2
Direct dependency from a staging driver to mach-omap2 driver is not
something we'd like, right?

-- 
Regards,
Nishanth Menon
--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH] [media] staging: allow omap4iss to be modular

2014-06-11 Thread Tony Lindgren
* Arnd Bergmann a...@arndb.de [140611 07:51]:
 On Wednesday 11 June 2014 09:42:04 Nishanth Menon wrote:
  On 06/11/2014 09:35 AM, Arnd Bergmann wrote:
   The OMAP4 camera support depends on I2C and VIDEO_V4L2, both
   of which can be loadable modules. This causes build failures
   if we want the camera driver to be built-in.
   
   This can be solved by turning the option into tristate,
   which unfortunately causes another problem, because the
   driver incorrectly calls a platform-internal interface
   for omap4_ctrl_pad_readl/omap4_ctrl_pad_writel.
   To work around that, we can export those symbols, but
   that isn't really the correct solution, as we should not
   have dependencies on platform code this way.
   
   Signed-off-by: Arnd Bergmann a...@arndb.de
   ---
   This is one of just two patches we currently need to get
   'make allmodconfig' to build again on ARM.
   
   diff --git a/arch/arm/mach-omap2/control.c b/arch/arm/mach-omap2/control.c
   index 751f354..05d2d98 100644
   --- a/arch/arm/mach-omap2/control.c
   +++ b/arch/arm/mach-omap2/control.c
   @@ -190,11 +190,13 @@ u32 omap4_ctrl_pad_readl(u16 offset)
{
 return readl_relaxed(OMAP4_CTRL_PAD_REGADDR(offset));
}
   +EXPORT_SYMBOL_GPL(omap4_ctrl_pad_readl);

void omap4_ctrl_pad_writel(u32 val, u16 offset)
{
 writel_relaxed(val, OMAP4_CTRL_PAD_REGADDR(offset));
}
   +EXPORT_SYMBOL_GPL(omap4_ctrl_pad_writel);

#ifdef CONFIG_ARCH_OMAP3

   diff --git a/drivers/staging/media/omap4iss/Kconfig 
   b/drivers/staging/media/omap4iss/Kconfig
   index 78b0fba..0c3e3c1 100644
   --- a/drivers/staging/media/omap4iss/Kconfig
   +++ b/drivers/staging/media/omap4iss/Kconfig
   @@ -1,5 +1,5 @@
config VIDEO_OMAP4
   - bool OMAP 4 Camera support
   + tristate OMAP 4 Camera support
 depends on VIDEO_V4L2  VIDEO_V4L2_SUBDEV_API  I2C  ARCH_OMAP4
 select VIDEOBUF2_DMA_CONTIG
 ---help---
   
  
  This was discussed in detail here:
  http://marc.info/?t=14019869251r=1w=2
  Direct dependency from a staging driver to mach-omap2 driver is not
  something we'd like, right?
 
 So it was decided to just leave ARM allmodconfig broken?
 
 Why not at least do this instead?
 
 8
 From 3a965f4fd5a6b3ef4a66aa4e7c916cfd34fd5706 Mon Sep 17 00:00:00 2001
 From: Arnd Bergmann a...@arndb.de
 Date: Tue, 21 Jan 2014 09:32:43 +0100
 Subject: [PATCH] [media] staging: tighten omap4iss dependencies
 
 The OMAP4 camera support depends on I2C and VIDEO_V4L2, both
 of which can be loadable modules. This causes build failures
 if we want the camera driver to be built-in.
 
 This can be solved by turning the option into tristate,
 which unfortunately causes another problem, because the
 driver incorrectly calls a platform-internal interface
 for omap4_ctrl_pad_readl/omap4_ctrl_pad_writel.
 
 Instead, this patch just forbids the invalid configurations
 and ensures that the driver can only be built if all its
 dependencies are built-in.
 
Makes sense to me if the media people are OK with this:

Acked-by: Tony Lindgren t...@atomide.com

 Signed-off-by: Arnd Bergmann a...@arndb.de
 
 diff --git a/drivers/staging/media/omap4iss/Kconfig 
 b/drivers/staging/media/omap4iss/Kconfig
 index 78b0fba..8afc6fe 100644
 --- a/drivers/staging/media/omap4iss/Kconfig
 +++ b/drivers/staging/media/omap4iss/Kconfig
 @@ -1,6 +1,6 @@
  config VIDEO_OMAP4
   bool OMAP 4 Camera support
 - depends on VIDEO_V4L2  VIDEO_V4L2_SUBDEV_API  I2C  ARCH_OMAP4
 + depends on VIDEO_V4L2=y  VIDEO_V4L2_SUBDEV_API  I2C=y  ARCH_OMAP4
   select VIDEOBUF2_DMA_CONTIG
   ---help---
 Driver for an OMAP 4 ISS controller.
 
--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 0/5] Handle non-secure L2C initialization on Exynos4

2014-06-11 Thread Tomasz Figa
This series intends to add support for L2 cache on Exynos4 SoCs on boards
running under secure firmware, which requires certain initialization steps
to be done with help of firmware, as selected registers are writable only
from secure mode.

First three patches extend existing support for secure write in L2C driver
to account for design of secure firmware running on Exynos. Namely:
 1) direct read access to certain registers is needed on Exynos, because
secure firmware calls set several registers at once,
 2) not all boards are running secure firmware, so .write_sec callback
needs to be installed in Exynos firmware ops initialization code,
 3) write access to {DATA,TAG}_LATENCY_CTRL registers fron non-secure world
is not allowed and so must use l2c_write_sec as well.
Those patches might affect other platforms using .write_sec callback, so
I'd like to kindly ask any interested people for testing.

Further two patches add impelmentation of .write_sec for Exynos secure
firmware and necessary DT nodes to enable L2 cache.

Tested on Exynos4210-based Universal C210 board (without secure firmware)
and Exynos4412-based TRATS2 board (with secure firmware).

Tomasz Figa (5):
  ARM: mm: cache-l2x0: Add base address argument to write_sec callback
  ARM: Get outer cache .write_sec callback from mach_desc only if not
NULL
  ARM: mm: cache-l2x0: Use l2c_write_sec() for LATENCY_CTRL registers
  ARM: EXYNOS: Add .write_sec outer cache callback for L2C-310
  ARM: dts: exynos4: Add nodes for L2 cache controller

 arch/arm/boot/dts/exynos4210.dtsi  |  9 ++
 arch/arm/boot/dts/exynos4x12.dtsi  |  9 ++
 arch/arm/include/asm/mach/arch.h   |  3 +-
 arch/arm/include/asm/outercache.h  |  2 +-
 arch/arm/kernel/irq.c  |  3 +-
 arch/arm/mach-exynos/firmware.c| 61 ++
 arch/arm/mach-highbank/highbank.c  |  3 +-
 arch/arm/mach-omap2/omap4-common.c |  3 +-
 arch/arm/mach-ux500/cache-l2x0.c   |  3 +-
 arch/arm/mm/cache-l2x0.c   | 10 +++
 10 files changed, 95 insertions(+), 11 deletions(-)

-- 
1.9.3

--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 1/5] ARM: mm: cache-l2x0: Add base address argument to write_sec callback

2014-06-11 Thread Tomasz Figa
For certain platforms (e.g. Exynos) it is necessary to read back some
values from registers before they can be written (i.e. SMC calls that
set multiple registers per call), so base address of L2C controller is
needed for .write_sec operation. This patch adds base argument to
.write_sec callback so that its implementation can also access registers
directly.

Signed-off-by: Tomasz Figa t.f...@samsung.com
---
 arch/arm/include/asm/mach/arch.h   | 3 ++-
 arch/arm/include/asm/outercache.h  | 2 +-
 arch/arm/mach-highbank/highbank.c  | 3 ++-
 arch/arm/mach-omap2/omap4-common.c | 3 ++-
 arch/arm/mach-ux500/cache-l2x0.c   | 3 ++-
 arch/arm/mm/cache-l2x0.c   | 2 +-
 6 files changed, 10 insertions(+), 6 deletions(-)

diff --git a/arch/arm/include/asm/mach/arch.h b/arch/arm/include/asm/mach/arch.h
index 060a75e..ddaebcd 100644
--- a/arch/arm/include/asm/mach/arch.h
+++ b/arch/arm/include/asm/mach/arch.h
@@ -46,7 +46,8 @@ struct machine_desc {
enum reboot_modereboot_mode;/* default restart mode */
unsignedl2c_aux_val;/* L2 cache aux value   */
unsignedl2c_aux_mask;   /* L2 cache aux mask*/
-   void(*l2c_write_sec)(unsigned long, unsigned);
+   void(*l2c_write_sec)(void __iomem *,
+unsigned long, unsigned);
struct smp_operations   *smp;   /* SMP operations   */
bool(*smp_init)(void);
void(*fixup)(struct tag *, char **);
diff --git a/arch/arm/include/asm/outercache.h 
b/arch/arm/include/asm/outercache.h
index 891a56b..5cc703b 100644
--- a/arch/arm/include/asm/outercache.h
+++ b/arch/arm/include/asm/outercache.h
@@ -35,7 +35,7 @@ struct outer_cache_fns {
void (*resume)(void);
 
/* This is an ARM L2C thing */
-   void (*write_sec)(unsigned long, unsigned);
+   void (*write_sec)(void __iomem *, unsigned long, unsigned);
 };
 
 extern struct outer_cache_fns outer_cache;
diff --git a/arch/arm/mach-highbank/highbank.c 
b/arch/arm/mach-highbank/highbank.c
index 8c35ae4..2bd3243 100644
--- a/arch/arm/mach-highbank/highbank.c
+++ b/arch/arm/mach-highbank/highbank.c
@@ -51,7 +51,8 @@ static void __init highbank_scu_map_io(void)
 }
 
 
-static void highbank_l2c310_write_sec(unsigned long val, unsigned reg)
+static void highbank_l2c310_write_sec(void __iomem *base,
+ unsigned long val, unsigned reg)
 {
if (reg == L2X0_CTRL)
highbank_smc1(0x102, val);
diff --git a/arch/arm/mach-omap2/omap4-common.c 
b/arch/arm/mach-omap2/omap4-common.c
index 326cd98..bdbe658 100644
--- a/arch/arm/mach-omap2/omap4-common.c
+++ b/arch/arm/mach-omap2/omap4-common.c
@@ -167,7 +167,8 @@ void __iomem *omap4_get_l2cache_base(void)
return l2cache_base;
 }
 
-static void omap4_l2c310_write_sec(unsigned long val, unsigned reg)
+static void omap4_l2c310_write_sec(void __iomem *base,
+  unsigned long val, unsigned reg)
 {
unsigned smc_op;
 
diff --git a/arch/arm/mach-ux500/cache-l2x0.c b/arch/arm/mach-ux500/cache-l2x0.c
index 842ebed..35c2623 100644
--- a/arch/arm/mach-ux500/cache-l2x0.c
+++ b/arch/arm/mach-ux500/cache-l2x0.c
@@ -35,7 +35,8 @@ static int __init ux500_l2x0_unlock(void)
return 0;
 }
 
-static void ux500_l2c310_write_sec(unsigned long val, unsigned reg)
+static void ux500_l2c310_write_sec(void __iomem *base,
+  unsigned long val, unsigned reg)
 {
/*
 * We can't write to secure registers as we are in non-secure
diff --git a/arch/arm/mm/cache-l2x0.c b/arch/arm/mm/cache-l2x0.c
index efc5cab..1695eab 100644
--- a/arch/arm/mm/cache-l2x0.c
+++ b/arch/arm/mm/cache-l2x0.c
@@ -72,7 +72,7 @@ static void l2c_write_sec(unsigned long val, void __iomem 
*base, unsigned reg)
if (val == readl_relaxed(base + reg))
return;
if (outer_cache.write_sec)
-   outer_cache.write_sec(val, reg);
+   outer_cache.write_sec(base, val, reg);
else
writel_relaxed(val, base + reg);
 }
-- 
1.9.3

--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 5/5] ARM: dts: exynos4: Add nodes for L2 cache controller

2014-06-11 Thread Tomasz Figa
This patch adds device tree nodes for L2 cache controller present on
Exynos4 SoCs.

Signed-off-by: Tomasz Figa t.f...@samsung.com
---
 arch/arm/boot/dts/exynos4210.dtsi | 9 +
 arch/arm/boot/dts/exynos4x12.dtsi | 9 +
 2 files changed, 18 insertions(+)

diff --git a/arch/arm/boot/dts/exynos4210.dtsi 
b/arch/arm/boot/dts/exynos4210.dtsi
index ee3001f..99970ab 100644
--- a/arch/arm/boot/dts/exynos4210.dtsi
+++ b/arch/arm/boot/dts/exynos4210.dtsi
@@ -54,6 +54,15 @@
reg = 0x10023CA0 0x20;
};
 
+   l2c: l2-cache-controller@10502000 {
+   compatible = arm,pl310-cache;
+   reg = 0x10502000 0x1000;
+   cache-unified;
+   cache-level = 2;
+   arm,tag-latency = 2 2 1;
+   arm,data-latency = 2 2 1;
+   };
+
gic: interrupt-controller@1049 {
cpu-offset = 0x8000;
};
diff --git a/arch/arm/boot/dts/exynos4x12.dtsi 
b/arch/arm/boot/dts/exynos4x12.dtsi
index c5a943d..9487f9c 100644
--- a/arch/arm/boot/dts/exynos4x12.dtsi
+++ b/arch/arm/boot/dts/exynos4x12.dtsi
@@ -60,6 +60,15 @@
reg = 0x10023CA0 0x20;
};
 
+   l2c: l2-cache-controller@10502000 {
+   compatible = arm,pl310-cache;
+   reg = 0x10502000 0x1000;
+   cache-unified;
+   cache-level = 2;
+   arm,tag-latency = 2 2 1;
+   arm,data-latency = 3 2 1;
+   };
+
clock: clock-controller@1003 {
compatible = samsung,exynos4412-clock;
reg = 0x1003 0x2;
-- 
1.9.3

--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [RFC] irqchip: gic: always mask interrupts during suspend

2014-06-11 Thread Stephen Warren
On 06/10/2014 05:48 PM, Brian Norris wrote:
 On Wed, Jun 11, 2014 at 01:34:39AM +0200, Thomas Gleixner wrote:
 On Tue, 10 Jun 2014, Brian Norris wrote:
 Other random thought: it seems like any irqchip driver which does lazy IRQ
 masking ought to use IRQCHIP_MASK_ON_SUSPEND. So maybe the IRQ core should 
 just
 do something like:

 if (!chip-irq_disable)
 chip-flags |= IRQCHIP_MASK_ON_SUSPEND;

 No. Lazy irq disable and the suspend logic are different beasts.
 
 OK, fair enough. Drop that random thought then. It's not in the patch
 content anyway.
 
 That's up to the platform to decide this. Just for the record: there
 is a world outside of ARM...
 
 OK. But GIC is ARM-specific, so we can still constrain this patch and
 related topics to the world of ARM.
 
 But that brings me to a different question:

 Why are you not putting that customization into the device tree
 instead of trying to add this to some random arch/arm/mach-foo
 files?
 
 I'm not adding customization to arch/arm/mach-foo files. I'm trying to
 remove it.
 
 This property could be added to device tree, if there was really a valid
 use case for a GIC which leaves its interrupts unmasked for suspend. My
 question in this patch is essentially: does such a use case exist?

DT should genernally only contain data that's expected to vary between
boards, or just possibly between SoCs. Anything that the kernel knows
simply because it knows what HW model it's driving has no place in DT,
since it just adds redundant work to parse the DT and end up with the
same data.

--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 3/5] ARM: mm: cache-l2x0: Use l2c_write_sec() for LATENCY_CTRL registers

2014-06-11 Thread Tomasz Figa
According to the documentation, TAG_LATENCY_CTRL and DATA_LATENCY_CTRL
registers of L2C-310 can be written only in secure mode, so
l2c_write_sec() should be used to change them, instead of plain
writel_relaxed().

Signed-off-by: Tomasz Figa t.f...@samsung.com
---
 arch/arm/mm/cache-l2x0.c | 8 
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/arch/arm/mm/cache-l2x0.c b/arch/arm/mm/cache-l2x0.c
index 1695eab..0180eb7 100644
--- a/arch/arm/mm/cache-l2x0.c
+++ b/arch/arm/mm/cache-l2x0.c
@@ -1024,20 +1024,20 @@ static void __init l2c310_of_parse(const struct 
device_node *np,
 
of_property_read_u32_array(np, arm,tag-latency, tag, ARRAY_SIZE(tag));
if (tag[0]  tag[1]  tag[2])
-   writel_relaxed(
+   l2c_write_sec(
L310_LATENCY_CTRL_RD(tag[0] - 1) |
L310_LATENCY_CTRL_WR(tag[1] - 1) |
L310_LATENCY_CTRL_SETUP(tag[2] - 1),
-   l2x0_base + L310_TAG_LATENCY_CTRL);
+   l2x0_base, L310_TAG_LATENCY_CTRL);
 
of_property_read_u32_array(np, arm,data-latency,
   data, ARRAY_SIZE(data));
if (data[0]  data[1]  data[2])
-   writel_relaxed(
+   l2c_write_sec(
L310_LATENCY_CTRL_RD(data[0] - 1) |
L310_LATENCY_CTRL_WR(data[1] - 1) |
L310_LATENCY_CTRL_SETUP(data[2] - 1),
-   l2x0_base + L310_DATA_LATENCY_CTRL);
+   l2x0_base, L310_DATA_LATENCY_CTRL);
 
of_property_read_u32_array(np, arm,filter-ranges,
   filter, ARRAY_SIZE(filter));
-- 
1.9.3

--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 2/5] ARM: Get outer cache .write_sec callback from mach_desc only if not NULL

2014-06-11 Thread Tomasz Figa
Certain platforms (i.e. Exynos) might need to set .write_sec callback
from firmware initialization which is happenning in .init_early callback
of machine descriptor. However current code will overwrite the pointer
with whatever is present in machine descriptor, even though it can be
already set earlier. This patch fixes this by making the assignment
conditional, depending on whether current .write_sec callback is NULL.

Signed-off-by: Tomasz Figa t.f...@samsung.com
---
 arch/arm/kernel/irq.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/arch/arm/kernel/irq.c b/arch/arm/kernel/irq.c
index 2c42576..e7383b9 100644
--- a/arch/arm/kernel/irq.c
+++ b/arch/arm/kernel/irq.c
@@ -125,7 +125,8 @@ void __init init_IRQ(void)
 
if (IS_ENABLED(CONFIG_OF)  IS_ENABLED(CONFIG_CACHE_L2X0) 
(machine_desc-l2c_aux_mask || machine_desc-l2c_aux_val)) {
-   outer_cache.write_sec = machine_desc-l2c_write_sec;
+   if (!outer_cache.write_sec)
+   outer_cache.write_sec = machine_desc-l2c_write_sec;
ret = l2x0_of_init(machine_desc-l2c_aux_val,
   machine_desc-l2c_aux_mask);
if (ret)
-- 
1.9.3

--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 4/5] ARM: EXYNOS: Add .write_sec outer cache callback for L2C-310

2014-06-11 Thread Tomasz Figa
Exynos4 SoCs equipped with an L2C-310 cache controller and running under
secure firmware require certain registers of aforementioned IP to be
accessed only from secure mode. This means that SMC calls are required
for certain register writes. To handle this, an implementation of
.write_sec callback is provided by this patch.

Signed-off-by: Tomasz Figa t.f...@samsung.com
---
 arch/arm/mach-exynos/firmware.c | 61 +
 1 file changed, 61 insertions(+)

diff --git a/arch/arm/mach-exynos/firmware.c b/arch/arm/mach-exynos/firmware.c
index eb91d23..34f7798 100644
--- a/arch/arm/mach-exynos/firmware.c
+++ b/arch/arm/mach-exynos/firmware.c
@@ -14,7 +14,9 @@
 #include linux/of.h
 #include linux/of_address.h
 
+#include asm/cputype.h
 #include asm/firmware.h
+#include asm/hardware/cache-l2x0.h
 
 #include mach/map.h
 
@@ -70,6 +72,55 @@ static const struct firmware_ops exynos_firmware_ops = {
.cpu_boot   = exynos_cpu_boot,
 };
 
+static void exynos_l2_write_sec(void __iomem *base, unsigned long val,
+   unsigned reg)
+{
+   switch (reg) {
+   case L2X0_CTRL:
+   exynos_smc(SMC_CMD_L2X0CTRL, val, 0, 0);
+   break;
+
+   case L2X0_AUX_CTRL:
+   exynos_smc(SMC_CMD_L2X0SETUP2,
+   readl_relaxed(base + L310_POWER_CTRL),
+   val, 0);
+   break;
+
+   case L2X0_DEBUG_CTRL:
+   exynos_smc(SMC_CMD_L2X0DEBUG, val, 0, 0);
+   break;
+
+   case L310_TAG_LATENCY_CTRL:
+   exynos_smc(SMC_CMD_L2X0SETUP1,
+   val,
+   readl_relaxed(base + L310_DATA_LATENCY_CTRL),
+   readl_relaxed(base + L310_PREFETCH_CTRL));
+   break;
+
+   case L310_DATA_LATENCY_CTRL:
+   exynos_smc(SMC_CMD_L2X0SETUP1,
+   readl_relaxed(base + L310_TAG_LATENCY_CTRL),
+   val,
+   readl_relaxed(base + L310_PREFETCH_CTRL));
+   break;
+
+   case L310_PREFETCH_CTRL:
+   exynos_smc(SMC_CMD_L2X0SETUP1,
+   readl_relaxed(base + L310_TAG_LATENCY_CTRL),
+   readl_relaxed(base + L310_DATA_LATENCY_CTRL),
+   val);
+   break;
+
+   case L310_POWER_CTRL:
+   exynos_smc(SMC_CMD_L2X0SETUP2, val,
+   readl_relaxed(base + L2X0_AUX_CTRL), 0);
+   break;
+
+   default:
+   WARN_ONCE(1, %s: ignoring write to reg 0x%x\n, __func__, reg);
+   }
+}
+
 void __init exynos_firmware_init(void)
 {
struct device_node *nd;
@@ -89,4 +140,14 @@ void __init exynos_firmware_init(void)
pr_info(Running under secure firmware.\n);
 
register_firmware_ops(exynos_firmware_ops);
+
+   /*
+* Exynos 4 SoCs (based on Cortex A9 and equipped with L2C-310),
+* running under secure firmware, require certain registers of L2
+* cache controller to be written in secure mode. Here .write_sec
+* callback is provided to perform necessary SMC calls.
+*/
+   if (IS_ENABLED(CONFIG_CACHE_L2X0)
+read_cpuid_part_number() == ARM_CPU_PART_CORTEX_A9)
+   outer_cache.write_sec = exynos_l2_write_sec;
 }
-- 
1.9.3

--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 1/5] ARM: mm: cache-l2x0: Add base address argument to write_sec callback

2014-06-11 Thread Jon Loeliger
 diff --git a/arch/arm/include/asm/mach/arch.h 
 b/arch/arm/include/asm/mach/arch.h
 index 060a75e..ddaebcd 100644
 --- a/arch/arm/include/asm/mach/arch.h
 +++ b/arch/arm/include/asm/mach/arch.h
 @@ -46,7 +46,8 @@ struct machine_desc {
 enum reboot_modereboot_mode;/* default restart mode */
 unsignedl2c_aux_val;/* L2 cache aux value   */
 unsignedl2c_aux_mask;   /* L2 cache aux mask*/
 -   void(*l2c_write_sec)(unsigned long, unsigned);
 +   void(*l2c_write_sec)(void __iomem *,
 +unsigned long, unsigned);
 struct smp_operations   *smp;   /* SMP operations   */
 bool(*smp_init)(void);
 void(*fixup)(struct tag *, char **);

 diff --git a/arch/arm/mm/cache-l2x0.c b/arch/arm/mm/cache-l2x0.c
 index efc5cab..1695eab 100644
 --- a/arch/arm/mm/cache-l2x0.c
 +++ b/arch/arm/mm/cache-l2x0.c
 @@ -72,7 +72,7 @@ static void l2c_write_sec(unsigned long val, void __iomem 
 *base, unsigned reg)
 if (val == readl_relaxed(base + reg))
 return;
 if (outer_cache.write_sec)
 -   outer_cache.write_sec(val, reg);
 +   outer_cache.write_sec(base, val, reg);
 else
 writel_relaxed(val, base + reg);
  }

The parameter order (base, val, reg) seems very non-intuitive.
Are you matching some existing prototype or adhering to some
backwards compatibility issue?  If not wouldn't, say, (base, reg, val)
or (val, base, reg) be more intuitive?

Thanks,
jdl
--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 1/5] ARM: mm: cache-l2x0: Add base address argument to write_sec callback

2014-06-11 Thread Tomasz Figa
On 11.06.2014 18:00, Jon Loeliger wrote:
 diff --git a/arch/arm/include/asm/mach/arch.h 
 b/arch/arm/include/asm/mach/arch.h
 index 060a75e..ddaebcd 100644
 --- a/arch/arm/include/asm/mach/arch.h
 +++ b/arch/arm/include/asm/mach/arch.h
 @@ -46,7 +46,8 @@ struct machine_desc {
 enum reboot_modereboot_mode;/* default restart mode */
 unsignedl2c_aux_val;/* L2 cache aux value   */
 unsignedl2c_aux_mask;   /* L2 cache aux mask*/
 -   void(*l2c_write_sec)(unsigned long, unsigned);
 +   void(*l2c_write_sec)(void __iomem *,
 +unsigned long, unsigned);
 struct smp_operations   *smp;   /* SMP operations   */
 bool(*smp_init)(void);
 void(*fixup)(struct tag *, char **);
 
 diff --git a/arch/arm/mm/cache-l2x0.c b/arch/arm/mm/cache-l2x0.c
 index efc5cab..1695eab 100644
 --- a/arch/arm/mm/cache-l2x0.c
 +++ b/arch/arm/mm/cache-l2x0.c
 @@ -72,7 +72,7 @@ static void l2c_write_sec(unsigned long val, void __iomem 
 *base, unsigned reg)
 if (val == readl_relaxed(base + reg))
 return;
 if (outer_cache.write_sec)
 -   outer_cache.write_sec(val, reg);
 +   outer_cache.write_sec(base, val, reg);
 else
 writel_relaxed(val, base + reg);
  }
 
 The parameter order (base, val, reg) seems very non-intuitive.
 Are you matching some existing prototype or adhering to some
 backwards compatibility issue?  If not wouldn't, say, (base, reg, val)
 or (val, base, reg) be more intuitive?

Hmm, I didn't think too much about this, so this order is just whatever
first came to my mind, probably because I'm used to xxx_write(ctx, val,
reg) accessors found in many drivers.

Anyway, l2c_write_sec() in arm/mm/cache-l2x0.c, which calls
outer_cache.write_sec(), already uses (val, base, reg) convention, so
probably this one would be most suitable. I'll change in v2.

Best regards,
Tomasz
--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH] iio: ti_am335x_adc: Use same step id at FIFOs both ends

2014-06-11 Thread Jan Kardell
Since AI lines could be selected at will (linux-3.11) the sending
and receiving ends of the FIFO does not agree about what step is used
for a line. It only works if the last lines are used, like 5,6,7,
and fails if ie 2,4,6 is selected in DT.

Signed-off-by: Jan Kardell jan.kard...@telliq.com
---
 drivers/iio/adc/ti_am335x_adc.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/iio/adc/ti_am335x_adc.c b/drivers/iio/adc/ti_am335x_adc.c
index a4db302..d5dc4c6 100644
--- a/drivers/iio/adc/ti_am335x_adc.c
+++ b/drivers/iio/adc/ti_am335x_adc.c
@@ -374,7 +374,7 @@ static int tiadc_read_raw(struct iio_dev *indio_dev,
return -EAGAIN;
}
}
-   map_val = chan-channel + TOTAL_CHANNELS;
+   map_val = adc_dev-channel_step[chan-scan_index];
 
/*
 * We check the complete FIFO. We programmed just one entry but in case
-- 
1.8.4.5

--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [GIT PULL] mfd: Immutable branch between MFD and OMAP, due for v3.16

2014-06-11 Thread Tony Lindgren
* Lee Jones lee.jo...@linaro.org [140603 01:08]:
 On Mon, 02 Jun 2014, Tony Lindgren wrote:
  * Tony Lindgren t...@atomide.com [140528 11:11]:
   * Lee Jones lee.jo...@linaro.org [140528 00:14]:
Thanks Tony, here's the pull-request:

The following changes since commit 
455c6fdbd219161bd09b1165f11699d6d73de11c:

  Linux 3.14 (2014-03-30 20:40:15 -0700)

are available in the git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/lee/mfd.git 
tags/mfd-omap-v3.16-1

for you to fetch changes up to 43fef47f94a1ae46fb2720dada32fa3b5547bee2:

  mfd: twl4030-power: Add a configuration to turn off oscillator during 
off-idle (2014-05-28 08:06:18 +0100)


Second immutable branch between MFD and OMAP due for the v3.16 merge 
window.
   
   Thanks a lot, this will make it easier for me to chase down potential
   PM related regressions ;) I'm merging this for testing only into the
   linux-omap master branch, no need for me to include it into any
   of my upstream heading branches.
  
  Lee, I'm not seeing this in linux next, did you maybe forget to merge
  it into the MFD tree?
 
 I didn't forget, but I didn't do it either. :)
 
 I have re-merged all of the IBs this morning, so should be in -next
 by tomorrow.

Still not seeing this branch being merged..

Regards,

Tony
--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html