Provide GPMC memory to OMAP nand/onenand as resource
Subsystems (7)
cover Provide GPMC memory to OMAP nand/onenand as resource
Hi Tony, Artem,
This series modifies GPMC to provide OMAP onenand & nand peripherals with GPMC allocated address space as resource. This conversion helps in smooth migration of gpmc code to driver.
This series has been made over [1-3], but is not functionally dependent on those, only depedency is w.r.t avoiding trivial merge conflict (if [3] is not taken before this series), and that too would affect only nand mtd driver.
This is targeted for 3.5, if this can be taken for 3.5, it also helps in making mtd drivers feel less vibration when GPMC gets converted to driver.
Regards
Afzal
[1] http://marc.info/?l=linux-omap&m=133675123118577&w=2
[2] http://marc.info/?l=linux-omap&m=133675123718579&w=2
[3] http://marc.info/?l=linux-omap&m=133675124818580&w=2
Afzal Mohammed (4):
ARM: OMAP2+: gpmc-nand: update resource with memory
ARM: OMAP2+: gpmc-onenand: provide memory as resource
mtd: nand: omap2: obtain memory from resource
mtd: onenand: omap2: obtain memory from resource
arch/arm/mach-omap2/gpmc-nand.c | 4 +++- arch/arm/mach-omap2/gpmc-onenand.c | 23 ++++++++++++++++++++++- arch/arm/plat-omap/include/plat/nand.h | 1 - drivers/mtd/nand/omap2.c | 19 +++++++++++++++---- drivers/mtd/onenand/omap2.c | 29 ++++++++++++++++------------- 5 files changed, 56 insertions(+), 20 deletions(-)
Signature · 1 line
1.7.10
PATCH 1/4 ARM: OMAP2+: gpmc-nand: update resource with memory
Currently omap nand driver uses a field in platform data - phys_base for passing the address space allocated by gpmc for nand. Use struct resource instead. With this change omap nand driver has to get address space from memory resource.
This helps in smooth migration of gpmc to driver.
--- arch/arm/mach-omap2/gpmc-nand.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
arch/arm/mach-omap2/gpmc-nand.c +3 -1
@@ -90,12 +90,14 @@ int __init gpmc_nand_init(struct omap_nand_platform_data *gpmc_nand_data) gpmc_nand_device.dev.platform_data = gpmc_nand_data; err =gpmc_cs_request (gpmc_nand_data->cs,NAND_IO_SIZE , - &gpmc_nand_data->phys_base); + (unsigned long *)&gpmc_nand_resource.start);if (err <0 ) {dev_err (dev,"Cannot request GPMC CS\n" );return err; } + gpmc_nand_resource.end = gpmc_nand_resource.start +NAND_IO_SIZE -1 ; +/* Set timings in GPMC */ err =omap2_nand_gpmc_retime (gpmc_nand_data);if (err <0 ) {
Signature · 1 line
1.7.10
PATCH 2/4 ARM: OMAP2+: gpmc-onenand: provide memory as resource
In reply to Afzal MohammedCurrently omap onenand driver invokes gpmc_cs_request, obtains address space allocated by gpmc to onenand. Remove this, instead use resource structure; this is now updated with address space for onenand by gpmc initialization with the help of gpmc_cs_request. And remove usage of gpmc_cs_request in onenand driver.
This helps in smooth migration of gpmc to driver.
--- arch/arm/mach-omap2/gpmc-onenand.c | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-)
arch/arm/mach-omap2/gpmc-onenand.c +22 -1
@@ -23,11 +23,19 @@#include <plat/board.h> #include <plat/gpmc.h> +#define ONENAND_IO_SIZE SZ_128K +static struct omap_onenand_platform_data *gpmc_onenand_data; +static struct resource gpmc_onenand_resource = { + .flags =IORESOURCE_MEM , +}; +static struct platform_device gpmc_onenand_device = { .name ="omap2-onenand" , .id =-1 , + .num_resources =1 , + .resource = &gpmc_onenand_resource, };static int omap2_onenand_set_async_mode (int cs,void __iomem *onenand_base)
@@ -390,6 +398,8 @@ static int gpmc_onenand_setup(void __iomem *onenand_base, int *freq_ptr)void __init gpmc_onenand_init (struct omap_onenand_platform_data *_onenand_data) { +int err; + gpmc_onenand_data = _onenand_data; gpmc_onenand_data->onenand_setup = gpmc_onenand_setup; gpmc_onenand_device.dev.platform_data = gpmc_onenand_data;
@@ -401,8 +411,19 @@ void __init gpmc_onenand_init(struct omap_onenand_platform_data *_onenand_data) gpmc_onenand_data->flags |=ONENAND_SYNC_READ ; } + err =gpmc_cs_request (gpmc_onenand_data->cs,ONENAND_IO_SIZE , + (unsigned long *)&gpmc_onenand_resource.start); +if (err <0 ) { +pr_err ("%s: Cannot request GPMC CS\n" , __func__); +return ; + } + + gpmc_onenand_resource.end = gpmc_onenand_resource.start + +ONENAND_IO_SIZE -1 ; +if (platform_device_register (&gpmc_onenand_device) <0 ) { -printk (KERN_ERR "Unable to register OneNAND device\n" ); +pr_err ("%s: Unable to register OneNAND device\n" , __func__); +gpmc_cs_free (gpmc_onenand_data->cs);return ; } }
Signature · 1 line
1.7.10
PATCH 3/4 mtd: nand: omap2: obtain memory from resource
In reply to Afzal Mohammedgpmc initialization done by platform code now updates struct resource with the address space alloted for nand. Use this interface to obtain memory rather than relying on platform data field - phys_base.
--- arch/arm/plat-omap/include/plat/nand.h | 1 - drivers/mtd/nand/omap2.c | 19 +++++++++++++++---- 2 files changed, 15 insertions(+), 5 deletions(-)
arch/arm/plat-omap/include/plat/nand.h +0 -1
@@ -26,7 +26,6 @@ struct omap_nand_platform_data {bool dev_ready;int gpmc_irq;enum nand_io xfer_type; -unsigned long phys_base;int devsize;enum omap_ecc ecc_opt;struct gpmc_nand_regs reg;
drivers/mtd/nand/omap2.c +15 -4
@@ -128,6 +128,7 @@ struct omap_nand_info {int gpmc_cs;unsigned long phys_base; +unsigned long mem_size;struct completion comp;int dma_ch;int gpmc_irq;
@@ -1049,6 +1050,7 @@ static int __devinit omap_nand_probe(struct platform_device *pdev)struct omap_nand_platform_data *pdata;int err;int i, offset; +struct resource *res; pdata = pdev->dev.platform_data;if (pdata ==NULL ) {
@@ -1068,7 +1070,6 @@ static int __devinit omap_nand_probe(struct platform_device *pdev) info->pdev = pdev; info->gpmc_cs = pdata->cs; - info->phys_base = pdata->phys_base; info->reg = pdata->reg; info->mtd.priv = &info->nand;
@@ -1081,13 +1082,23 @@ static int __devinit omap_nand_probe(struct platform_device *pdev)/* NAND write protect off */ gpmc_cs_configure (info->gpmc_cs,GPMC_CONFIG_WP ,0 ); -if (!request_mem_region (info->phys_base,NAND_IO_SIZE , + res =platform_get_resource (pdev,IORESOURCE_MEM ,0 ); +if (res ==NULL ) { + err = -EINVAL ; +dev_err (&pdev->dev,"error getting memory resource\n" ); + goto out_free_info; + } + + info->phys_base = res->start; + info->mem_size =resource_size (res); + +if (!request_mem_region (info->phys_base, info->mem_size, pdev->dev.driver->name)) { err = -EBUSY ; goto out_free_info; } - info->nand.IO_ADDR_R =ioremap (info->phys_base,NAND_IO_SIZE ); + info->nand.IO_ADDR_R =ioremap (info->phys_base, info->mem_size);if (!info->nand.IO_ADDR_R) { err = -ENOMEM ; goto out_release_mem_region;
@@ -1229,7 +1240,7 @@ static int __devinit omap_nand_probe(struct platform_device *pdev)return 0 ; out_release_mem_region: -release_mem_region (info->phys_base,NAND_IO_SIZE ); +release_mem_region (info->phys_base, info->mem_size); out_free_info:kfree (info);
Signature · 1 line
1.7.10
PATCH 4/4 mtd: onenand: omap2: obtain memory from resource
In reply to Afzal Mohammedgpmc initialization for onenand done by platform code now provides onenand address space as memory resource. Hence remove usage of gpmc_cs_request in onenand driver and obtain memory details from resource structure.
--- drivers/mtd/onenand/omap2.c | 29 ++++++++++++++++------------- 1 file changed, 16 insertions(+), 13 deletions(-)
drivers/mtd/onenand/omap2.c +16 -13
@@ -48,13 +48,13 @@#define DRIVER_NAME "omap2-onenand" -#define ONENAND_IO_SIZE SZ_128K#define ONENAND_BUFRAM_SIZE (1024 * 5)struct omap2_onenand {struct platform_device *pdev;int gpmc_cs;unsigned long phys_base; +unsigned int mem_size;int gpio_irq;struct mtd_info mtd;struct onenand_chip onenand;
@@ -626,6 +626,7 @@ static int __devinit omap2_onenand_probe(struct platform_device *pdev)struct omap2_onenand *c;struct onenand_chip *this;int r; +struct resource *res; pdata = pdev->dev.platform_data;if (pdata ==NULL ) {
@@ -647,20 +648,24 @@ static int __devinit omap2_onenand_probe(struct platform_device *pdev) c->gpio_irq =0 ; } - r =gpmc_cs_request (c->gpmc_cs,ONENAND_IO_SIZE , &c->phys_base); -if (r <0 ) { -dev_err (&pdev->dev,"Cannot request GPMC CS\n" ); + 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; } -if (request_mem_region (c->phys_base,ONENAND_IO_SIZE , + 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,ONENAND_IO_SIZE ); +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_free_cs; + goto err_kfree; } - c->onenand.base =ioremap (c->phys_base,ONENAND_IO_SIZE ); + c->onenand.base =ioremap (c->phys_base, c->mem_size);if (c->onenand.base ==NULL ) { r = -ENOMEM ; goto err_release_mem_region;
@@ -776,9 +781,7 @@ err_release_gpio: err_iounmap:iounmap (c->onenand.base); err_release_mem_region: -release_mem_region (c->phys_base,ONENAND_IO_SIZE ); -err_free_cs: -gpmc_cs_free (c->gpmc_cs); +release_mem_region (c->phys_base, c->mem_size); err_kfree:kfree (c);
@@ -800,7 +803,7 @@ static int __devexit omap2_onenand_remove(struct platform_device *pdev)gpio_free (c->gpio_irq); }iounmap (c->onenand.base); -release_mem_region (c->phys_base,ONENAND_IO_SIZE ); +release_mem_region (c->phys_base, c->mem_size);gpmc_cs_free (c->gpmc_cs);kfree (c);
Signature · 1 line
1.7.10