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 <[email protected]>
---
 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 devicetree" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to