ARM: OMAP2+: Allow GPMC probe to complete even if CS mapping fails
authorJon Hunter <jon-hunter@ti.com>
Wed, 6 Mar 2013 20:36:47 +0000 (14:36 -0600)
committerJon Hunter <jon-hunter@ti.com>
Thu, 4 Apr 2013 01:13:40 +0000 (20:13 -0500)
When the GPMC driver is probed, we call gpmc_mem_init() to see which
chip-selects have already been configured and enabled by the boot-loader
and allocate space for them. If we fail to allocate space for one
chip-select, then we return failure from the probe and the GPMC driver
will not be available.

Rather than render the GPMC useless for all GPMC devices, if we fail to
allocate space for one chip-select print a warning and disable the
chip-select. This way other GPMC clients can still be used.

There is no downside to this approach, because all GPMC clients need to
request a chip-select before they can use the GPMC and on requesting a
chip-select, if memory has not already been reserved for the chip-select
then it will be.

Signed-off-by: Jon Hunter <jon-hunter@ti.com>
Tested-by: Ezequiel Garcia <ezequiel.garcia@free-electrons.com>
arch/arm/mach-omap2/gpmc.c

index a259dc0bf0632a05891c16e13d87decf343fbffc..5f6af202807ac9644a42088dbc478cc14eb20ed5 100644 (file)
@@ -785,9 +785,9 @@ static void gpmc_mem_exit(void)
 
 }
 
-static int gpmc_mem_init(void)
+static void gpmc_mem_init(void)
 {
-       int cs, rc;
+       int cs;
 
        /*
         * The first 1MB of GPMC address space is typically mapped to
@@ -804,16 +804,12 @@ static int gpmc_mem_init(void)
                if (!gpmc_cs_mem_enabled(cs))
                        continue;
                gpmc_cs_get_memconf(cs, &base, &size);
-               rc = gpmc_cs_insert_mem(cs, base, size);
-               if (rc < 0) {
-                       while (--cs >= 0)
-                               if (gpmc_cs_mem_enabled(cs))
-                                       gpmc_cs_delete_mem(cs);
-                       return rc;
+               if (gpmc_cs_insert_mem(cs, base, size)) {
+                       pr_warn("%s: disabling cs %d mapped at 0x%x-0x%x\n",
+                               __func__, cs, base, base + size);
+                       gpmc_cs_disable_mem(cs);
                }
        }
-
-       return 0;
 }
 
 static u32 gpmc_round_ps_to_sync_clk(u32 time_ps, u32 sync_clk)
@@ -1611,13 +1607,7 @@ static int gpmc_probe(struct platform_device *pdev)
        dev_info(gpmc_dev, "GPMC revision %d.%d\n", GPMC_REVISION_MAJOR(l),
                 GPMC_REVISION_MINOR(l));
 
-       rc = gpmc_mem_init();
-       if (rc < 0) {
-               clk_disable_unprepare(gpmc_l3_clk);
-               clk_put(gpmc_l3_clk);
-               dev_err(gpmc_dev, "failed to reserve memory\n");
-               return rc;
-       }
+       gpmc_mem_init();
 
        if (gpmc_setup_irq() < 0)
                dev_warn(gpmc_dev, "gpmc_setup_irq failed\n");