diff options
author | Tony Lindgren <tony@atomide.com> | 2012-11-21 12:46:19 -0500 |
---|---|---|
committer | Tony Lindgren <tony@atomide.com> | 2012-11-21 12:46:19 -0500 |
commit | 48b0023607c4e524e893a7a378a1dd42234c41a7 (patch) | |
tree | dec8ce3b8dab55ecbc65f71f716236fdab95acd3 /arch/arm/plat-omap | |
parent | 9dc57643738f9fbe45c10cc062903d5dfda5bdd9 (diff) | |
parent | 258e84af9799b8c81cf856dcbd8e2d4cc082741d (diff) |
Merge branch 'cleanup-timer' of git://github.com/jonhunter/linux into omap-for-v3.8/timer
Diffstat (limited to 'arch/arm/plat-omap')
-rw-r--r-- | arch/arm/plat-omap/dmtimer.c | 54 | ||||
-rw-r--r-- | arch/arm/plat-omap/include/plat/dmtimer.h | 80 |
2 files changed, 56 insertions, 78 deletions
diff --git a/arch/arm/plat-omap/dmtimer.c b/arch/arm/plat-omap/dmtimer.c index 9deeb3064d33..89585c293554 100644 --- a/arch/arm/plat-omap/dmtimer.c +++ b/arch/arm/plat-omap/dmtimer.c | |||
@@ -43,6 +43,8 @@ | |||
43 | #include <linux/pm_runtime.h> | 43 | #include <linux/pm_runtime.h> |
44 | #include <linux/of.h> | 44 | #include <linux/of.h> |
45 | #include <linux/of_device.h> | 45 | #include <linux/of_device.h> |
46 | #include <linux/platform_device.h> | ||
47 | #include <linux/platform_data/dmtimer-omap.h> | ||
46 | 48 | ||
47 | #include <plat/dmtimer.h> | 49 | #include <plat/dmtimer.h> |
48 | 50 | ||
@@ -99,32 +101,39 @@ static void omap_timer_restore_context(struct omap_dm_timer *timer) | |||
99 | timer->context.tclr); | 101 | timer->context.tclr); |
100 | } | 102 | } |
101 | 103 | ||
102 | static void omap_dm_timer_wait_for_reset(struct omap_dm_timer *timer) | 104 | static int omap_dm_timer_reset(struct omap_dm_timer *timer) |
103 | { | 105 | { |
104 | int c; | 106 | u32 l, timeout = 100000; |
105 | 107 | ||
106 | if (!timer->sys_stat) | 108 | if (timer->revision != 1) |
107 | return; | 109 | return -EINVAL; |
108 | 110 | ||
109 | c = 0; | 111 | omap_dm_timer_write_reg(timer, OMAP_TIMER_IF_CTRL_REG, 0x06); |
110 | while (!(__raw_readl(timer->sys_stat) & 1)) { | 112 | |
111 | c++; | 113 | do { |
112 | if (c > 100000) { | 114 | l = __omap_dm_timer_read(timer, |
113 | printk(KERN_ERR "Timer failed to reset\n"); | 115 | OMAP_TIMER_V1_SYS_STAT_OFFSET, 0); |
114 | return; | 116 | } while (!l && timeout--); |
115 | } | 117 | |
118 | if (!timeout) { | ||
119 | dev_err(&timer->pdev->dev, "Timer failed to reset\n"); | ||
120 | return -ETIMEDOUT; | ||
116 | } | 121 | } |
117 | } | ||
118 | 122 | ||
119 | static void omap_dm_timer_reset(struct omap_dm_timer *timer) | 123 | /* Configure timer for smart-idle mode */ |
120 | { | 124 | l = __omap_dm_timer_read(timer, OMAP_TIMER_OCP_CFG_OFFSET, 0); |
121 | omap_dm_timer_write_reg(timer, OMAP_TIMER_IF_CTRL_REG, 0x06); | 125 | l |= 0x2 << 0x3; |
122 | omap_dm_timer_wait_for_reset(timer); | 126 | __omap_dm_timer_write(timer, OMAP_TIMER_OCP_CFG_OFFSET, l, 0); |
123 | __omap_dm_timer_reset(timer, 0, 0); | 127 | |
128 | timer->posted = 0; | ||
129 | |||
130 | return 0; | ||
124 | } | 131 | } |
125 | 132 | ||
126 | int omap_dm_timer_prepare(struct omap_dm_timer *timer) | 133 | static int omap_dm_timer_prepare(struct omap_dm_timer *timer) |
127 | { | 134 | { |
135 | int rc; | ||
136 | |||
128 | /* | 137 | /* |
129 | * FIXME: OMAP1 devices do not use the clock framework for dmtimers so | 138 | * FIXME: OMAP1 devices do not use the clock framework for dmtimers so |
130 | * do not call clk_get() for these devices. | 139 | * do not call clk_get() for these devices. |
@@ -140,8 +149,13 @@ int omap_dm_timer_prepare(struct omap_dm_timer *timer) | |||
140 | 149 | ||
141 | omap_dm_timer_enable(timer); | 150 | omap_dm_timer_enable(timer); |
142 | 151 | ||
143 | if (timer->capability & OMAP_TIMER_NEEDS_RESET) | 152 | if (timer->capability & OMAP_TIMER_NEEDS_RESET) { |
144 | omap_dm_timer_reset(timer); | 153 | rc = omap_dm_timer_reset(timer); |
154 | if (rc) { | ||
155 | omap_dm_timer_disable(timer); | ||
156 | return rc; | ||
157 | } | ||
158 | } | ||
145 | 159 | ||
146 | __omap_dm_timer_enable_posted(timer); | 160 | __omap_dm_timer_enable_posted(timer); |
147 | omap_dm_timer_disable(timer); | 161 | omap_dm_timer_disable(timer); |
diff --git a/arch/arm/plat-omap/include/plat/dmtimer.h b/arch/arm/plat-omap/include/plat/dmtimer.h index 05a36e16f3f4..a3fbc48c332e 100644 --- a/arch/arm/plat-omap/include/plat/dmtimer.h +++ b/arch/arm/plat-omap/include/plat/dmtimer.h | |||
@@ -79,8 +79,6 @@ struct omap_timer_capability_dev_attr { | |||
79 | u32 timer_capability; | 79 | u32 timer_capability; |
80 | }; | 80 | }; |
81 | 81 | ||
82 | struct omap_dm_timer; | ||
83 | |||
84 | struct timer_regs { | 82 | struct timer_regs { |
85 | u32 tidr; | 83 | u32 tidr; |
86 | u32 tier; | 84 | u32 tier; |
@@ -101,12 +99,29 @@ struct timer_regs { | |||
101 | u32 towr; | 99 | u32 towr; |
102 | }; | 100 | }; |
103 | 101 | ||
104 | struct dmtimer_platform_data { | 102 | struct omap_dm_timer { |
105 | /* set_timer_src - Only used for OMAP1 devices */ | 103 | int id; |
106 | int (*set_timer_src)(struct platform_device *pdev, int source); | 104 | int irq; |
107 | u32 timer_errata; | 105 | struct clk *fclk; |
108 | u32 timer_capability; | 106 | |
107 | void __iomem *io_base; | ||
108 | void __iomem *irq_stat; /* TISR/IRQSTATUS interrupt status */ | ||
109 | void __iomem *irq_ena; /* irq enable */ | ||
110 | void __iomem *irq_dis; /* irq disable, only on v2 ip */ | ||
111 | void __iomem *pend; /* write pending */ | ||
112 | void __iomem *func_base; /* function register base */ | ||
113 | |||
114 | unsigned long rate; | ||
115 | unsigned reserved:1; | ||
116 | unsigned posted:1; | ||
117 | struct timer_regs context; | ||
109 | int (*get_context_loss_count)(struct device *); | 118 | int (*get_context_loss_count)(struct device *); |
119 | int ctx_loss_count; | ||
120 | int revision; | ||
121 | u32 capability; | ||
122 | u32 errata; | ||
123 | struct platform_device *pdev; | ||
124 | struct list_head node; | ||
110 | }; | 125 | }; |
111 | 126 | ||
112 | int omap_dm_timer_reserve_systimer(int id); | 127 | int omap_dm_timer_reserve_systimer(int id); |
@@ -260,35 +275,6 @@ int omap_dm_timers_active(void); | |||
260 | #define OMAP_TIMER_TICK_INT_MASK_COUNT_REG \ | 275 | #define OMAP_TIMER_TICK_INT_MASK_COUNT_REG \ |
261 | (_OMAP_TIMER_TICK_INT_MASK_COUNT_OFFSET | (WP_TOWR << WPSHIFT)) | 276 | (_OMAP_TIMER_TICK_INT_MASK_COUNT_OFFSET | (WP_TOWR << WPSHIFT)) |
262 | 277 | ||
263 | struct omap_dm_timer { | ||
264 | unsigned long phys_base; | ||
265 | int id; | ||
266 | int irq; | ||
267 | struct clk *fclk; | ||
268 | |||
269 | void __iomem *io_base; | ||
270 | void __iomem *sys_stat; /* TISTAT timer status */ | ||
271 | void __iomem *irq_stat; /* TISR/IRQSTATUS interrupt status */ | ||
272 | void __iomem *irq_ena; /* irq enable */ | ||
273 | void __iomem *irq_dis; /* irq disable, only on v2 ip */ | ||
274 | void __iomem *pend; /* write pending */ | ||
275 | void __iomem *func_base; /* function register base */ | ||
276 | |||
277 | unsigned long rate; | ||
278 | unsigned reserved:1; | ||
279 | unsigned posted:1; | ||
280 | struct timer_regs context; | ||
281 | int (*get_context_loss_count)(struct device *); | ||
282 | int ctx_loss_count; | ||
283 | int revision; | ||
284 | u32 capability; | ||
285 | u32 errata; | ||
286 | struct platform_device *pdev; | ||
287 | struct list_head node; | ||
288 | }; | ||
289 | |||
290 | int omap_dm_timer_prepare(struct omap_dm_timer *timer); | ||
291 | |||
292 | static inline u32 __omap_dm_timer_read(struct omap_dm_timer *timer, u32 reg, | 278 | static inline u32 __omap_dm_timer_read(struct omap_dm_timer *timer, u32 reg, |
293 | int posted) | 279 | int posted) |
294 | { | 280 | { |
@@ -317,8 +303,6 @@ static inline void __omap_dm_timer_init_regs(struct omap_dm_timer *timer) | |||
317 | tidr = __raw_readl(timer->io_base); | 303 | tidr = __raw_readl(timer->io_base); |
318 | if (!(tidr >> 16)) { | 304 | if (!(tidr >> 16)) { |
319 | timer->revision = 1; | 305 | timer->revision = 1; |
320 | timer->sys_stat = timer->io_base + | ||
321 | OMAP_TIMER_V1_SYS_STAT_OFFSET; | ||
322 | timer->irq_stat = timer->io_base + OMAP_TIMER_V1_STAT_OFFSET; | 306 | timer->irq_stat = timer->io_base + OMAP_TIMER_V1_STAT_OFFSET; |
323 | timer->irq_ena = timer->io_base + OMAP_TIMER_V1_INT_EN_OFFSET; | 307 | timer->irq_ena = timer->io_base + OMAP_TIMER_V1_INT_EN_OFFSET; |
324 | timer->irq_dis = timer->io_base + OMAP_TIMER_V1_INT_EN_OFFSET; | 308 | timer->irq_dis = timer->io_base + OMAP_TIMER_V1_INT_EN_OFFSET; |
@@ -326,7 +310,6 @@ static inline void __omap_dm_timer_init_regs(struct omap_dm_timer *timer) | |||
326 | timer->func_base = timer->io_base; | 310 | timer->func_base = timer->io_base; |
327 | } else { | 311 | } else { |
328 | timer->revision = 2; | 312 | timer->revision = 2; |
329 | timer->sys_stat = NULL; | ||
330 | timer->irq_stat = timer->io_base + OMAP_TIMER_V2_IRQSTATUS; | 313 | timer->irq_stat = timer->io_base + OMAP_TIMER_V2_IRQSTATUS; |
331 | timer->irq_ena = timer->io_base + OMAP_TIMER_V2_IRQENABLE_SET; | 314 | timer->irq_ena = timer->io_base + OMAP_TIMER_V2_IRQENABLE_SET; |
332 | timer->irq_dis = timer->io_base + OMAP_TIMER_V2_IRQENABLE_CLR; | 315 | timer->irq_dis = timer->io_base + OMAP_TIMER_V2_IRQENABLE_CLR; |
@@ -337,25 +320,6 @@ static inline void __omap_dm_timer_init_regs(struct omap_dm_timer *timer) | |||
337 | } | 320 | } |
338 | } | 321 | } |
339 | 322 | ||
340 | /* Assumes the source clock has been set by caller */ | ||
341 | static inline void __omap_dm_timer_reset(struct omap_dm_timer *timer, | ||
342 | int autoidle, int wakeup) | ||
343 | { | ||
344 | u32 l; | ||
345 | |||
346 | l = __raw_readl(timer->io_base + OMAP_TIMER_OCP_CFG_OFFSET); | ||
347 | l |= 0x02 << 3; /* Set to smart-idle mode */ | ||
348 | l |= 0x2 << 8; /* Set clock activity to perserve f-clock on idle */ | ||
349 | |||
350 | if (autoidle) | ||
351 | l |= 0x1 << 0; | ||
352 | |||
353 | if (wakeup) | ||
354 | l |= 1 << 2; | ||
355 | |||
356 | __raw_writel(l, timer->io_base + OMAP_TIMER_OCP_CFG_OFFSET); | ||
357 | } | ||
358 | |||
359 | /* | 323 | /* |
360 | * __omap_dm_timer_enable_posted - enables write posted mode | 324 | * __omap_dm_timer_enable_posted - enables write posted mode |
361 | * @timer: pointer to timer instance handle | 325 | * @timer: pointer to timer instance handle |