This patch makes dmtimer switch-over to platform device driver
through following changes:
(1) call to dmtimer initialization routine from timer-gp.c is
removed.
(2) initiate dmtimer early initialization from omap2_init_common_hw
in io.c
(3) modify plat-omap/dmtimer routines to use new register map and
platform data.

Signed-off-by: Tarun Kanti DebBarma <[email protected]>
Signed-off-by: Partha Basak <[email protected]>
Cc: Cousson, Benoit <[email protected]>
Cc: Paul Walmsley <[email protected]>
Cc: Kevin Hilman <[email protected]>
Cc: Tony Lindgren <[email protected]>
---
 arch/arm/mach-omap2/clock2420_data.c |    6 +-
 arch/arm/mach-omap2/clock2430_data.c |    6 +-
 arch/arm/mach-omap2/clock3xxx_data.c |    6 +-
 arch/arm/mach-omap2/clock44xx_data.c |    6 +-
 arch/arm/mach-omap2/io.c             |    2 +
 arch/arm/mach-omap2/timer-gp.c       |    1 -
 arch/arm/plat-omap/dmtimer.c         |  192 +++++++++++++++-------------------
 7 files changed, 92 insertions(+), 127 deletions(-)

diff --git a/arch/arm/mach-omap2/clock2420_data.c 
b/arch/arm/mach-omap2/clock2420_data.c
index 6378e6d..7722da5 100644
--- a/arch/arm/mach-omap2/clock2420_data.c
+++ b/arch/arm/mach-omap2/clock2420_data.c
@@ -1765,11 +1765,7 @@ static struct omap_clk omap2420_clks[] = {
        CLK(NULL,       "virt_prcm_set", &virt_prcm_set, CK_242X),
        /* general l4 interface ck, multi-parent functional clk */
        CLK(NULL,       "gpt1_ick",     &gpt1_ick,      CK_242X),
-       /*
-        * gpt1 will be modified in subsequent patch when dmtimers
-        * will be fully converted to platform device
-        */
-       CLK(NULL,       "gpt1_fck",     &gpt1_fck,      CK_242X),
+       CLK("dmtimer.0",        "fck",  &gpt1_fck,      CK_242X),
        CLK(NULL,       "gpt2_ick",     &gpt2_ick,      CK_242X),
        CLK("dmtimer.1",        "fck",  &gpt2_fck,      CK_242X),
        CLK(NULL,       "gpt3_ick",     &gpt3_ick,      CK_242X),
diff --git a/arch/arm/mach-omap2/clock2430_data.c 
b/arch/arm/mach-omap2/clock2430_data.c
index ae9b44e..a81d071 100644
--- a/arch/arm/mach-omap2/clock2430_data.c
+++ b/arch/arm/mach-omap2/clock2430_data.c
@@ -1851,11 +1851,7 @@ static struct omap_clk omap2430_clks[] = {
        CLK(NULL,       "virt_prcm_set", &virt_prcm_set, CK_243X),
        /* general l4 interface ck, multi-parent functional clk */
        CLK(NULL,       "gpt1_ick",     &gpt1_ick,      CK_243X),
-       /*
-        * gpt1 will be modified in subsequent patch when dmtimers
-        * will be fully converted to platform device
-        */
-       CLK(NULL,       "gpt1_fck",     &gpt1_fck,      CK_243X),
+       CLK("dmtimer.0",        "fck",  &gpt1_fck,      CK_243X),
        CLK(NULL,       "gpt2_ick",     &gpt2_ick,      CK_243X),
        CLK("dmtimer.1",        "fck",  &gpt2_fck,      CK_243X),
        CLK(NULL,       "gpt3_ick",     &gpt3_ick,      CK_243X),
diff --git a/arch/arm/mach-omap2/clock3xxx_data.c 
b/arch/arm/mach-omap2/clock3xxx_data.c
index 1cdcaf5..c140be3 100644
--- a/arch/arm/mach-omap2/clock3xxx_data.c
+++ b/arch/arm/mach-omap2/clock3xxx_data.c
@@ -3334,11 +3334,7 @@ static struct omap_clk omap3xxx_clks[] = {
        CLK(NULL,       "usbhost_48m_fck", &usbhost_48m_fck, CK_3430ES2 | 
CK_AM35XX),
        CLK(NULL,       "usbhost_ick",  &usbhost_ick,   CK_3430ES2 | CK_AM35XX),
        CLK(NULL,       "usim_fck",     &usim_fck,      CK_3430ES2),
-       /*
-        * gpt1 will be changed in subsequent patch when dmtimer
-        * is fully converted to platform device.
-        */
-       CLK(NULL,       "gpt1_fck",     &gpt1_fck,      CK_3XXX),
+       CLK("dmtimer.0",        "fck",  &gpt1_fck,      CK_3XXX),
        CLK(NULL,       "wkup_32k_fck", &wkup_32k_fck,  CK_3XXX),
        CLK(NULL,       "gpio1_dbck",   &gpio1_dbck,    CK_3XXX),
        CLK("omap_wdt", "fck",          &wdt2_fck,      CK_3XXX),
diff --git a/arch/arm/mach-omap2/clock44xx_data.c 
b/arch/arm/mach-omap2/clock44xx_data.c
index 7398158..24e4dc3 100644
--- a/arch/arm/mach-omap2/clock44xx_data.c
+++ b/arch/arm/mach-omap2/clock44xx_data.c
@@ -2574,11 +2574,7 @@ static struct omap_clk omap44xx_clks[] = {
        CLK(NULL,       "smartreflex_core_fck",         &smartreflex_core_fck,  
CK_443X),
        CLK(NULL,       "smartreflex_iva_fck",          &smartreflex_iva_fck,   
CK_443X),
        CLK(NULL,       "smartreflex_mpu_fck",          &smartreflex_mpu_fck,   
CK_443X),
-       /*
-        * gpt1 will be changed in subsequent patch when dmtimer
-        * will be fully converted to platform device.
-        */
-       CLK(NULL,       "gpt1_fck",                     &timer1_fck,    
CK_443X),
+       CLK("dmtimer.0",        "fck",          &timer1_fck,    CK_443X),
        CLK("dmtimer.9",        "fck",          &timer10_fck,   CK_443X),
        CLK("dmtimer.10",       "fck",          &timer11_fck,   CK_443X),
        CLK("dmtimer.1",        "fck",          &timer2_fck,    CK_443X),
diff --git a/arch/arm/mach-omap2/io.c b/arch/arm/mach-omap2/io.c
index 08e3a12..d6edbad 100644
--- a/arch/arm/mach-omap2/io.c
+++ b/arch/arm/mach-omap2/io.c
@@ -45,6 +45,7 @@
 #include "clockdomains.h"
 
 #include <plat/omap_hwmod.h>
+#include "dmtimer.h"
 
 /*
  * The machine specific code may provide the extra mapping besides the
@@ -350,4 +351,5 @@ void __init omap2_init_common_hw(struct omap_sdrc_params 
*sdrc_cs0,
                _omap2_init_reprogram_sdrc();
        }
        gpmc_init();
+       omap2_dm_timer_early_init();
 }
diff --git a/arch/arm/mach-omap2/timer-gp.c b/arch/arm/mach-omap2/timer-gp.c
index 74fbed8..c2d8a0d 100644
--- a/arch/arm/mach-omap2/timer-gp.c
+++ b/arch/arm/mach-omap2/timer-gp.c
@@ -231,7 +231,6 @@ static void __init omap2_gp_timer_init(void)
        twd_base = ioremap(OMAP44XX_LOCAL_TWD_BASE, SZ_256);
        BUG_ON(!twd_base);
 #endif
-       omap_dm_timer_init();
 
        omap2_gp_clockevent_init();
        omap2_gp_clocksource_init();
diff --git a/arch/arm/plat-omap/dmtimer.c b/arch/arm/plat-omap/dmtimer.c
index 2017b1d..360a751 100644
--- a/arch/arm/plat-omap/dmtimer.c
+++ b/arch/arm/plat-omap/dmtimer.c
@@ -48,6 +48,7 @@
 #include <linux/pm_runtime.h>
 #include <plat/dmtimer.h>
 #include <mach/irqs.h>
+#include <linux/err.h>
 
 /* register offsets */
 #define _OMAP_TIMER_ID_OFFSET          0x00
@@ -84,67 +85,6 @@
 #define _OMAP_TIMER_TICK_INT_MASK_SET_OFFSET   0x54    /* TOCR, 34xx only */
 #define _OMAP_TIMER_TICK_INT_MASK_COUNT_OFFSET 0x58    /* TOWR, 34xx only */
 
-
-#define OMAP_TIMER_ID_REG                      (_OMAP_TIMER_ID_OFFSET \
-                                                       | (WP_NONE << WPSHIFT))
-
-#define OMAP_TIMER_OCP_CFG_REG                 (_OMAP_TIMER_OCP_CFG_OFFSET \
-                                                       | (WP_NONE << WPSHIFT))
-
-#define OMAP_TIMER_SYS_STAT_REG                        
(_OMAP_TIMER_SYS_STAT_OFFSET \
-                                                       | (WP_NONE << WPSHIFT))
-
-#define OMAP_TIMER_STAT_REG                    (_OMAP_TIMER_STAT_OFFSET \
-                                                       | (WP_NONE << WPSHIFT))
-
-#define OMAP_TIMER_INT_EN_REG                  (_OMAP_TIMER_INT_EN_OFFSET \
-                                                       | (WP_NONE << WPSHIFT))
-
-#define OMAP_TIMER_WAKEUP_EN_REG               (_OMAP_TIMER_WAKEUP_EN_OFFSET \
-                                                       | (WP_NONE << WPSHIFT))
-
-#define OMAP_TIMER_CTRL_REG                    (_OMAP_TIMER_CTRL_OFFSET \
-                                                       | (WP_TCLR << WPSHIFT))
-
-#define OMAP_TIMER_COUNTER_REG                 (_OMAP_TIMER_COUNTER_OFFSET \
-                                                       | (WP_TCRR << WPSHIFT))
-
-#define OMAP_TIMER_LOAD_REG                    (_OMAP_TIMER_LOAD_OFFSET \
-                                                       | (WP_TLDR << WPSHIFT))
-
-#define OMAP_TIMER_TRIGGER_REG                 (_OMAP_TIMER_TRIGGER_OFFSET \
-                                                       | (WP_TTGR << WPSHIFT))
-
-#define OMAP_TIMER_WRITE_PEND_REG              (_OMAP_TIMER_WRITE_PEND_OFFSET \
-                                                       | (WP_NONE << WPSHIFT))
-
-#define OMAP_TIMER_MATCH_REG                   (_OMAP_TIMER_MATCH_OFFSET \
-                                                       | (WP_TMAR << WPSHIFT))
-
-#define OMAP_TIMER_CAPTURE_REG                 (_OMAP_TIMER_CAPTURE_OFFSET \
-                                                       | (WP_NONE << WPSHIFT))
-
-#define OMAP_TIMER_IF_CTRL_REG                 (_OMAP_TIMER_IF_CTRL_OFFSET \
-                                                       | (WP_NONE << WPSHIFT))
-
-#define OMAP_TIMER_CAPTURE2_REG                        
(_OMAP_TIMER_CAPTURE2_OFFSET \
-                                                       | (WP_NONE << WPSHIFT))
-
-#define OMAP_TIMER_TICK_POS_REG                        
(_OMAP_TIMER_TICK_POS_OFFSET \
-                                                       | (WP_TPIR << WPSHIFT))
-
-#define OMAP_TIMER_TICK_NEG_REG                        
(_OMAP_TIMER_TICK_NEG_OFFSET \
-                                                       | (WP_TNIR << WPSHIFT))
-
-#define OMAP_TIMER_TICK_COUNT_REG              (_OMAP_TIMER_TICK_COUNT_OFFSET \
-                                                       | (WP_TCVR << WPSHIFT))
-
-#define OMAP_TIMER_TICK_INT_MASK_SET_REG                               \
-               (_OMAP_TIMER_TICK_INT_MASK_SET_OFFSET | (WP_TOCR << WPSHIFT))
-
-#define OMAP_TIMER_TICK_INT_MASK_COUNT_REG                             \
-               (_OMAP_TIMER_TICK_INT_MASK_COUNT_OFFSET | (WP_TOWR << WPSHIFT))
-
 struct omap_dm_timer {
        int id;
        unsigned long fclk_rate;
@@ -265,34 +205,48 @@ static struct clk **dm_source_clocks;
 static LIST_HEAD(omap_timer_list);
 static DEFINE_SPINLOCK(dm_timer_lock);
 
-/*
- * Reads timer registers in posted and non-posted mode. The posted mode bit
- * is encoded in reg. Note that in posted mode write pending bit must be
- * checked. Otherwise a read of a non completed write will produce an error.
+/**
+ * omap_dm_timer_read_reg - read timer registers in posted and non-posted mode
+ * @timer:     timer pointer over which read operation to perform
+ * @reg:       lowest byte holds the register offset
+ *
+ * The posted mode bit is encoded in reg. Note that in posted mode write
+ * pending bit must be checked. Otherwise a read of a non completed write
+ * will produce an error.
  */
-static inline u32 omap_dm_timer_read_reg(struct omap_dm_timer *timer, u32 reg)
+static inline u32 omap_dm_timer_read_reg(struct omap_dm_timer *timer, u8 reg)
 {
+       struct dmtimer_platform_data *pdata = timer->pdev->dev.platform_data;
+
        if (timer->posted)
-               while (readl(timer->io_base + (OMAP_TIMER_WRITE_PEND_REG & 
0xff))
-                               & (reg >> WPSHIFT))
+               while (readl(timer->io_base +
+                       ((pdata->reg_map[OMAP_TIMER_WRITE_PEND_REG]) & 0xff))
+                               & (pdata->reg_map[reg] >> WPSHIFT))
                        cpu_relax();
-       return readl(timer->io_base + (reg & 0xff));
+       return readl(timer->io_base + (pdata->reg_map[reg] & 0xff));
 }
 
-/*
- * Writes timer registers in posted and non-posted mode. The posted mode bit
- * is encoded in reg. Note that in posted mode the write pending bit must be
- * checked. Otherwise a write on a register which has a pending write will be
- * lost.
+/**
+ * omap_dm_timer_write_reg - write timer registers in posted and non-posted 
mode
+ * @timer:     timer pointer over which write operation is to perform
+ * @reg:       lowest byte holds the register offset
+ * @value:     data to write into the register
+ *
+ * The posted mode bit is encoded in reg. Note that in posted mode the write
+ * pending bit must be checked. Otherwise a write on a register which has a
+ * pending write will be lost.
  */
-static void omap_dm_timer_write_reg(struct omap_dm_timer *timer, u32 reg,
+static void omap_dm_timer_write_reg(struct omap_dm_timer *timer, u8 reg,
                                                u32 value)
 {
+       struct dmtimer_platform_data *pdata = timer->pdev->dev.platform_data;
+
        if (timer->posted)
-               while (readl(timer->io_base + (OMAP_TIMER_WRITE_PEND_REG & 
0xff))
-                               & (reg >> WPSHIFT))
+               while (readl(timer->io_base +
+                       ((pdata->reg_map[OMAP_TIMER_WRITE_PEND_REG]) & 0xff))
+                               & (pdata->reg_map[reg] >> WPSHIFT))
                        cpu_relax();
-       writel(value, timer->io_base + (reg & 0xff));
+       writel(value, timer->io_base + (pdata->reg_map[reg] & 0xff));
 }
 
 static void omap_dm_timer_wait_for_reset(struct omap_dm_timer *timer)
@@ -397,15 +351,18 @@ EXPORT_SYMBOL_GPL(omap_dm_timer_free);
 
 void omap_dm_timer_enable(struct omap_dm_timer *timer)
 {
+       struct clk *timer_clk;
+
        if (timer->enabled)
                return;
 
-#ifdef CONFIG_ARCH_OMAP2PLUS
-       if (cpu_class_is_omap2()) {
-               clk_enable(timer->fclk);
-               clk_enable(timer->iclk);
-       }
-#endif
+       timer_clk = clk_get(&timer->pdev->dev, "fck");
+       if (IS_ERR(timer_clk)) {
+               dev_err(&timer->pdev->dev,
+               "ERROR: no clk pointer to enable\n");
+               return;
+       } else
+               clk_enable(timer_clk);
 
        timer->enabled = 1;
 }
@@ -413,15 +370,18 @@ EXPORT_SYMBOL_GPL(omap_dm_timer_enable);
 
 void omap_dm_timer_disable(struct omap_dm_timer *timer)
 {
+       struct clk *timer_clk;
+
        if (!timer->enabled)
                return;
 
-#ifdef CONFIG_ARCH_OMAP2PLUS
-       if (cpu_class_is_omap2()) {
-               clk_disable(timer->iclk);
-               clk_disable(timer->fclk);
-       }
-#endif
+       timer_clk = clk_get(&timer->pdev->dev, "fck");
+       if (IS_ERR(timer_clk)) {
+               dev_err(&timer->pdev->dev,
+               "ERROR: no clk pointer to disable\n");
+               return;
+       } else
+               clk_disable(timer_clk);
 
        timer->enabled = 0;
 }
@@ -473,7 +433,12 @@ EXPORT_SYMBOL_GPL(omap_dm_timer_modify_idlect_mask);
 
 struct clk *omap_dm_timer_get_fclk(struct omap_dm_timer *timer)
 {
-       return timer->fclk;
+       struct clk *timer_clk = clk_get(&timer->pdev->dev, "fck");
+
+       if (IS_ERR(timer_clk))
+               return ERR_PTR((int)timer_clk);
+       else
+               return timer_clk;
 }
 EXPORT_SYMBOL_GPL(omap_dm_timer_get_fclk);
 
@@ -520,7 +485,7 @@ void omap_dm_timer_stop(struct omap_dm_timer *timer)
                  * Wait for functional clock period x 3.5 to make sure that
                  * timer is stopped
                  */
-               udelay(3500000 / clk_get_rate(timer->fclk) + 1);
+               udelay(3500000 / timer->fclk_rate + 1);
 #endif
        }
        /* Ack possibly pending interrupt */
@@ -529,27 +494,41 @@ void omap_dm_timer_stop(struct omap_dm_timer *timer)
 }
 EXPORT_SYMBOL_GPL(omap_dm_timer_stop);
 
-
-
-
-
 int omap_dm_timer_set_source(struct omap_dm_timer *timer, int source)
 {
-       int ret = -EINVAL;
+       int ret = 0;
+       struct clk *timer_clk = NULL;
+       struct dmtimer_platform_data *pdata = timer->pdev->dev.platform_data;
 
-       if (source < 0 || source >= 3)
+       if (source < 0 || source >= NR_CLK_SOURCES)
                return -EINVAL;
 
-#ifdef CONFIG_ARCH_OMAP1
-       if (pdata->set_timer_src)
-               ret = pdata->set_timer_src(timer->pdev, source);
-#else
-       clk_disable(timer->fclk);
-       ret = clk_set_parent(timer->fclk, dm_source_clocks[source]);
-       clk_enable(timer->fclk);
-#endif
+       timer_clk = clk_get(&timer->pdev->dev, "fck");
+       if (IS_ERR(timer_clk)) {
+               dev_err(&timer->pdev->dev,
+               "ERROR: no clk pointer to disable\n");
+               return -EINVAL;
+       } else
+               clk_disable(timer_clk); /* enabled in hwmod */
 
        /*
+        * change the timer clock source and
+        * store the fclk_rate of the new clock source.
+        */
+       ret = pdata->set_timer_src(timer->pdev, source);
+       if (!ret)
+               timer->fclk_rate = clk_get_rate(omap_dm_timer_get_fclk(timer));
+
+       /* enable timer clock again after timer clock source change */
+       if (unlikely(pdata->is_early_init))
+               clk_enable(timer_clk);
+       else {
+               if (pm_runtime_get_sync(&timer->pdev->dev))
+                       dev_warn(&timer->pdev->dev,
+                       "%s: pm_runtime_get_sync FAILED\n",
+                        __func__);
+       }
+       /*
         * When the functional clock disappears, too quick writes seem
         * to cause an abort. XXX Is this still necessary?
         */
@@ -935,6 +914,7 @@ static void __exit omap_dmtimer_driver_exit(void)
        platform_driver_unregister(&omap_dmtimer_driver);
 }
 
+early_platform_init("earlytimer", &omap_dmtimer_driver);
 module_init(omap_dmtimer_driver_init);
 module_exit(omap_dmtimer_driver_exit);
 
-- 
1.6.0.4

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

Reply via email to