From: Roger Quadros <rogerq@ti.com>
To: <tony@atomide.com>, <computersforpeace@gmail.com>
Cc: <pekon@ti.com>, <ezequiel.garcia@free-electrons.com>,
<robertcnelson@gmail.com>, <jg1.han@samsung.com>,
<dwmw2@infradead.org>, <javier@dowhile0.org>, <nsekhar@ti.com>,
<linux-omap@vger.kernel.org>, <linux-mtd@lists.infradead.org>,
<devicetree@vger.kernel.org>, <linux-kernel@vger.kernel.org>,
Roger Quadros <rogerq@ti.com>
Subject: [RFC PATCH 04/16] ARM: OMAP2+: gpmc: use platform data to configure CS space and poplulate device
Date: Wed, 21 May 2014 14:20:52 +0300 [thread overview]
Message-ID: <1400671264-10702-5-git-send-email-rogerq@ti.com> (raw)
In-Reply-To: <1400671264-10702-1-git-send-email-rogerq@ti.com>
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.
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 <rogerq@ti.com>
---
arch/arm/mach-omap2/gpmc.c | 137 ++++++++++++++++++++++++++++++++++++++-------
1 file changed, 118 insertions(+), 19 deletions(-)
diff --git a/arch/arm/mach-omap2/gpmc.c b/arch/arm/mach-omap2/gpmc.c
index 6b4a322..04bae67 100644
--- a/arch/arm/mach-omap2/gpmc.c
+++ b/arch/arm/mach-omap2/gpmc.c
@@ -160,7 +160,6 @@ static DEFINE_SPINLOCK(gpmc_mem_lock);
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 resource_size_t phys_base, mem_size;
static unsigned gpmc_capability;
@@ -1630,11 +1629,102 @@ 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;
+
+ 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;
+
+ 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)
@@ -1663,8 +1753,6 @@ static int gpmc_probe(struct platform_device *pdev)
pm_runtime_enable(&pdev->dev);
pm_runtime_get_sync(&pdev->dev);
- gpmc_dev = &pdev->dev;
-
l = gpmc_read_reg(GPMC_REVISION);
/*
@@ -1683,31 +1771,40 @@ static int gpmc_probe(struct platform_device *pdev)
gpmc_capability = GPMC_HAS_WR_ACCESS | GPMC_HAS_WR_DATA_MUX_BUS;
if (GPMC_REVISION_MAJOR(l) > 0x5)
gpmc_capability |= GPMC_HAS_MUX_AAD;
- dev_info(gpmc_dev, "GPMC revision %d.%d\n", GPMC_REVISION_MAJOR(l),
+ dev_info(dev, "GPMC revision %d.%d\n", GPMC_REVISION_MAJOR(l),
GPMC_REVISION_MINOR(l));
gpmc_mem_init();
if (gpmc_setup_irq() < 0)
- dev_warn(gpmc_dev, "gpmc_setup_irq failed\n");
+ dev_warn(dev, "gpmc_setup_irq failed\n");
/* Now the GPMC is initialised, unreserve the chip-selects */
gpmc_cs_map = 0;
- if (!pdev->dev.of_node) {
- gpmc_cs_num = GPMC_CS_NUM;
- gpmc_nr_waitpins = GPMC_NR_WAITPINS;
- }
+ if (!dev->of_node) {
+ /* Legacy probing based on platform data */
+ if (!dev->platform_data) {
+ dev_err(dev, "missing platform data\n");
+ rc = -EINVAL;
+ goto error;
+ }
+ gpmc_probe_legacy(pdev);
- rc = gpmc_probe_dt(pdev);
- if (rc < 0) {
- pm_runtime_put_sync(&pdev->dev);
- clk_put(gpmc_l3_clk);
- dev_err(gpmc_dev, "failed to probe DT parameters\n");
- return rc;
+ } else {
+ rc = gpmc_probe_dt(pdev);
+ if (rc < 0) {
+ dev_err(dev, "failed to probe DT parameters\n");
+ goto error;
+ }
}
return 0;
+
+error:
+ pm_runtime_put_sync(dev);
+ clk_put(gpmc_l3_clk);
+ return rc;
}
static int gpmc_remove(struct platform_device *pdev)
@@ -1716,7 +1813,6 @@ static int gpmc_remove(struct platform_device *pdev)
gpmc_mem_exit();
pm_runtime_put_sync(&pdev->dev);
pm_runtime_disable(&pdev->dev);
- gpmc_dev = NULL;
return 0;
}
@@ -1760,7 +1856,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)
@@ -1782,12 +1878,15 @@ 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,
+ sizeof(gpmc_pdata));
WARN(IS_ERR(pdev), "could not build omap_device for %s\n", oh_name);
return PTR_RET(pdev);
}
-omap_postcore_initcall(omap_gpmc_init);
+
+/* must run after machine_init code. i.e. arch_init */
+omap_subsys_initcall(omap_gpmc_init);
/**
* gpmc_generic_init - Initialize platform data for a Chip Select
--
1.8.3.2
next prev parent reply other threads:[~2014-05-21 11:21 UTC|newest]
Thread overview: 28+ messages / expand[flat|nested] mbox.gz Atom feed top
2014-05-21 11:20 [RFC PATCH 00/16] OMAP: GPMC: Restructure OMAP GPMC driver (NAND) Roger Quadros
2014-05-21 11:20 ` [RFC PATCH 01/16] ARM: OMAP2+: gpmc: Add platform data Roger Quadros
2014-05-21 11:20 ` [RFC PATCH 02/16] ARM: OMAP2+: gpmc: Add gpmc timings and settings to " Roger Quadros
2014-05-21 11:20 ` [RFC PATCH 03/16] ARM: OMAP2+: gmpc: add gpmc_generic_init() Roger Quadros
2014-05-21 11:20 ` Roger Quadros [this message]
2014-05-21 11:20 ` [RFC PATCH 05/16] ARM: OMAP2+: gpmc: Use low level read/write for context save/restore Roger Quadros
2014-05-21 11:20 ` [RFC PATCH 06/16] ARM: OMAP2+: gpmc: add NAND specific setup Roger Quadros
2014-05-21 11:20 ` [RFC PATCH 07/16] ARM: OMAP2+: nand: Update gpmc_nand_init() to use generic_gpmc_init() Roger Quadros
2014-05-21 11:20 ` [RFC PATCH 08/16] mtd: nand: omap: Fix build warning Roger Quadros
2014-05-22 0:54 ` Jingoo Han
2014-05-22 8:17 ` Roger Quadros
2014-05-21 11:20 ` [RFC PATCH 09/16] mtd: nand: omap: Move IRQ handling from GPMC to NAND driver Roger Quadros
2014-05-21 11:20 ` [RFC PATCH 10/16] mtd: nand: omap: Move gpmc_update_nand_reg to nand driver Roger Quadros
2014-05-21 11:20 ` [RFC PATCH 11/16] mtd: nand: omap: Move NAND write protect code from GPMC to NAND driver Roger Quadros
2014-05-21 11:21 ` [RFC PATCH 12/16] mtd: nand: omap: Copy platform data parameters to omap_nand_info data Roger Quadros
2014-05-21 11:21 ` [RFC PATCH 13/16] mtd: nand: omap: True device tree support Roger Quadros
2014-05-21 11:21 ` [RFC PATCH 14/16] ARM: OMAP: gpmc: Update DT binding documentation Roger Quadros
2014-05-21 11:21 ` [RFC PATCH 15/16] mtd: nand: omap: " Roger Quadros
2014-05-21 11:21 ` [RFC PATCH 16/16] ARM: dts: omap3-beagle: Add NAND device Roger Quadros
2014-05-21 16:08 ` [RFC PATCH 00/16] OMAP: GPMC: Restructure OMAP GPMC driver (NAND) Ezequiel Garcia
2014-05-22 8:12 ` [RFC PATCH 00/16] OMAP: GPMC: Restructure OMAP GPMC driver (NAND) : DT binding change proposal Roger Quadros
2014-05-22 11:51 ` Javier Martinez Canillas
2014-05-22 14:46 ` Ezequiel Garcia
2014-05-23 8:16 ` Roger Quadros
2014-05-23 9:40 ` Javier Martinez Canillas
2014-05-26 7:23 ` Roger Quadros
2014-05-23 14:53 ` Tony Lindgren
2014-05-26 7:33 ` Roger Quadros
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1400671264-10702-5-git-send-email-rogerq@ti.com \
--to=rogerq@ti.com \
--cc=computersforpeace@gmail.com \
--cc=devicetree@vger.kernel.org \
--cc=dwmw2@infradead.org \
--cc=ezequiel.garcia@free-electrons.com \
--cc=javier@dowhile0.org \
--cc=jg1.han@samsung.com \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-mtd@lists.infradead.org \
--cc=linux-omap@vger.kernel.org \
--cc=nsekhar@ti.com \
--cc=pekon@ti.com \
--cc=robertcnelson@gmail.com \
--cc=tony@atomide.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
Powered by JetHome