aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTony Lindgren <tony@atomide.com>2012-11-13 16:52:38 -0500
committerTony Lindgren <tony@atomide.com>2012-11-13 16:52:38 -0500
commit9dc57643738f9fbe45c10cc062903d5dfda5bdd9 (patch)
tree1579e10fe2cf0b5473080c74e1184976372df8f2
parentd308ba50a1234b299a00e63a95e61fdeb2f1a2df (diff)
parentb1538832191d59e29b1077e64cf416a7617b45bc (diff)
Merge branch 'fixes-timer' of github.com:jonhunter/linux into omap-for-v3.8/timer
-rw-r--r--arch/arm/mach-omap2/omap_hwmod_2xxx_ipblock_data.c15
-rw-r--r--arch/arm/mach-omap2/omap_hwmod_3xxx_data.c41
-rw-r--r--arch/arm/mach-omap2/omap_hwmod_44xx_data.c4
-rw-r--r--arch/arm/mach-omap2/timer.c70
-rw-r--r--arch/arm/plat-omap/dmtimer.c77
-rw-r--r--arch/arm/plat-omap/include/plat/dmtimer.h72
6 files changed, 188 insertions, 91 deletions
diff --git a/arch/arm/mach-omap2/omap_hwmod_2xxx_ipblock_data.c b/arch/arm/mach-omap2/omap_hwmod_2xxx_ipblock_data.c
index a0116d08cf45..0db8f450bad9 100644
--- a/arch/arm/mach-omap2/omap_hwmod_2xxx_ipblock_data.c
+++ b/arch/arm/mach-omap2/omap_hwmod_2xxx_ipblock_data.c
@@ -58,8 +58,9 @@ static struct omap_hwmod_class_sysconfig omap2xxx_timer_sysc = {
58 .syss_offs = 0x0014, 58 .syss_offs = 0x0014,
59 .sysc_flags = (SYSC_HAS_SIDLEMODE | SYSC_HAS_CLOCKACTIVITY | 59 .sysc_flags = (SYSC_HAS_SIDLEMODE | SYSC_HAS_CLOCKACTIVITY |
60 SYSC_HAS_ENAWAKEUP | SYSC_HAS_SOFTRESET | 60 SYSC_HAS_ENAWAKEUP | SYSC_HAS_SOFTRESET |
61 SYSC_HAS_AUTOIDLE), 61 SYSC_HAS_AUTOIDLE | SYSS_HAS_RESET_STATUS),
62 .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART), 62 .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART),
63 .clockact = CLOCKACT_TEST_ICLK,
63 .sysc_fields = &omap_hwmod_sysc_type1, 64 .sysc_fields = &omap_hwmod_sysc_type1,
64}; 65};
65 66
@@ -268,6 +269,7 @@ struct omap_hwmod omap2xxx_timer1_hwmod = {
268 }, 269 },
269 .dev_attr = &capability_alwon_dev_attr, 270 .dev_attr = &capability_alwon_dev_attr,
270 .class = &omap2xxx_timer_hwmod_class, 271 .class = &omap2xxx_timer_hwmod_class,
272 .flags = HWMOD_SET_DEFAULT_CLOCKACT,
271}; 273};
272 274
273/* timer2 */ 275/* timer2 */
@@ -286,6 +288,7 @@ struct omap_hwmod omap2xxx_timer2_hwmod = {
286 }, 288 },
287 }, 289 },
288 .class = &omap2xxx_timer_hwmod_class, 290 .class = &omap2xxx_timer_hwmod_class,
291 .flags = HWMOD_SET_DEFAULT_CLOCKACT,
289}; 292};
290 293
291/* timer3 */ 294/* timer3 */
@@ -304,6 +307,7 @@ struct omap_hwmod omap2xxx_timer3_hwmod = {
304 }, 307 },
305 }, 308 },
306 .class = &omap2xxx_timer_hwmod_class, 309 .class = &omap2xxx_timer_hwmod_class,
310 .flags = HWMOD_SET_DEFAULT_CLOCKACT,
307}; 311};
308 312
309/* timer4 */ 313/* timer4 */
@@ -322,6 +326,7 @@ struct omap_hwmod omap2xxx_timer4_hwmod = {
322 }, 326 },
323 }, 327 },
324 .class = &omap2xxx_timer_hwmod_class, 328 .class = &omap2xxx_timer_hwmod_class,
329 .flags = HWMOD_SET_DEFAULT_CLOCKACT,
325}; 330};
326 331
327/* timer5 */ 332/* timer5 */
@@ -341,6 +346,7 @@ struct omap_hwmod omap2xxx_timer5_hwmod = {
341 }, 346 },
342 .dev_attr = &capability_dsp_dev_attr, 347 .dev_attr = &capability_dsp_dev_attr,
343 .class = &omap2xxx_timer_hwmod_class, 348 .class = &omap2xxx_timer_hwmod_class,
349 .flags = HWMOD_SET_DEFAULT_CLOCKACT,
344}; 350};
345 351
346/* timer6 */ 352/* timer6 */
@@ -360,6 +366,7 @@ struct omap_hwmod omap2xxx_timer6_hwmod = {
360 }, 366 },
361 .dev_attr = &capability_dsp_dev_attr, 367 .dev_attr = &capability_dsp_dev_attr,
362 .class = &omap2xxx_timer_hwmod_class, 368 .class = &omap2xxx_timer_hwmod_class,
369 .flags = HWMOD_SET_DEFAULT_CLOCKACT,
363}; 370};
364 371
365/* timer7 */ 372/* timer7 */
@@ -379,6 +386,7 @@ struct omap_hwmod omap2xxx_timer7_hwmod = {
379 }, 386 },
380 .dev_attr = &capability_dsp_dev_attr, 387 .dev_attr = &capability_dsp_dev_attr,
381 .class = &omap2xxx_timer_hwmod_class, 388 .class = &omap2xxx_timer_hwmod_class,
389 .flags = HWMOD_SET_DEFAULT_CLOCKACT,
382}; 390};
383 391
384/* timer8 */ 392/* timer8 */
@@ -398,6 +406,7 @@ struct omap_hwmod omap2xxx_timer8_hwmod = {
398 }, 406 },
399 .dev_attr = &capability_dsp_dev_attr, 407 .dev_attr = &capability_dsp_dev_attr,
400 .class = &omap2xxx_timer_hwmod_class, 408 .class = &omap2xxx_timer_hwmod_class,
409 .flags = HWMOD_SET_DEFAULT_CLOCKACT,
401}; 410};
402 411
403/* timer9 */ 412/* timer9 */
@@ -417,6 +426,7 @@ struct omap_hwmod omap2xxx_timer9_hwmod = {
417 }, 426 },
418 .dev_attr = &capability_pwm_dev_attr, 427 .dev_attr = &capability_pwm_dev_attr,
419 .class = &omap2xxx_timer_hwmod_class, 428 .class = &omap2xxx_timer_hwmod_class,
429 .flags = HWMOD_SET_DEFAULT_CLOCKACT,
420}; 430};
421 431
422/* timer10 */ 432/* timer10 */
@@ -436,6 +446,7 @@ struct omap_hwmod omap2xxx_timer10_hwmod = {
436 }, 446 },
437 .dev_attr = &capability_pwm_dev_attr, 447 .dev_attr = &capability_pwm_dev_attr,
438 .class = &omap2xxx_timer_hwmod_class, 448 .class = &omap2xxx_timer_hwmod_class,
449 .flags = HWMOD_SET_DEFAULT_CLOCKACT,
439}; 450};
440 451
441/* timer11 */ 452/* timer11 */
@@ -455,6 +466,7 @@ struct omap_hwmod omap2xxx_timer11_hwmod = {
455 }, 466 },
456 .dev_attr = &capability_pwm_dev_attr, 467 .dev_attr = &capability_pwm_dev_attr,
457 .class = &omap2xxx_timer_hwmod_class, 468 .class = &omap2xxx_timer_hwmod_class,
469 .flags = HWMOD_SET_DEFAULT_CLOCKACT,
458}; 470};
459 471
460/* timer12 */ 472/* timer12 */
@@ -474,6 +486,7 @@ struct omap_hwmod omap2xxx_timer12_hwmod = {
474 }, 486 },
475 .dev_attr = &capability_pwm_dev_attr, 487 .dev_attr = &capability_pwm_dev_attr,
476 .class = &omap2xxx_timer_hwmod_class, 488 .class = &omap2xxx_timer_hwmod_class,
489 .flags = HWMOD_SET_DEFAULT_CLOCKACT,
477}; 490};
478 491
479/* wd_timer2 */ 492/* wd_timer2 */
diff --git a/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c
index abe66ced903f..addc1c24ca2e 100644
--- a/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c
+++ b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c
@@ -153,29 +153,16 @@ static struct omap_hwmod omap3xxx_debugss_hwmod = {
153}; 153};
154 154
155/* timer class */ 155/* timer class */
156static struct omap_hwmod_class_sysconfig omap3xxx_timer_1ms_sysc = {
157 .rev_offs = 0x0000,
158 .sysc_offs = 0x0010,
159 .syss_offs = 0x0014,
160 .sysc_flags = (SYSC_HAS_SIDLEMODE | SYSC_HAS_CLOCKACTIVITY |
161 SYSC_HAS_ENAWAKEUP | SYSC_HAS_SOFTRESET |
162 SYSC_HAS_EMUFREE | SYSC_HAS_AUTOIDLE),
163 .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART),
164 .sysc_fields = &omap_hwmod_sysc_type1,
165};
166
167static struct omap_hwmod_class omap3xxx_timer_1ms_hwmod_class = {
168 .name = "timer",
169 .sysc = &omap3xxx_timer_1ms_sysc,
170};
171
172static struct omap_hwmod_class_sysconfig omap3xxx_timer_sysc = { 156static struct omap_hwmod_class_sysconfig omap3xxx_timer_sysc = {
173 .rev_offs = 0x0000, 157 .rev_offs = 0x0000,
174 .sysc_offs = 0x0010, 158 .sysc_offs = 0x0010,
175 .syss_offs = 0x0014, 159 .syss_offs = 0x0014,
176 .sysc_flags = (SYSC_HAS_SIDLEMODE | SYSC_HAS_ENAWAKEUP | 160 .sysc_flags = (SYSC_HAS_SIDLEMODE | SYSC_HAS_CLOCKACTIVITY |
177 SYSC_HAS_SOFTRESET | SYSC_HAS_AUTOIDLE), 161 SYSC_HAS_ENAWAKEUP | SYSC_HAS_SOFTRESET |
162 SYSC_HAS_EMUFREE | SYSC_HAS_AUTOIDLE |
163 SYSS_HAS_RESET_STATUS),
178 .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART), 164 .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART),
165 .clockact = CLOCKACT_TEST_ICLK,
179 .sysc_fields = &omap_hwmod_sysc_type1, 166 .sysc_fields = &omap_hwmod_sysc_type1,
180}; 167};
181 168
@@ -224,7 +211,8 @@ static struct omap_hwmod omap3xxx_timer1_hwmod = {
224 }, 211 },
225 }, 212 },
226 .dev_attr = &capability_alwon_dev_attr, 213 .dev_attr = &capability_alwon_dev_attr,
227 .class = &omap3xxx_timer_1ms_hwmod_class, 214 .class = &omap3xxx_timer_hwmod_class,
215 .flags = HWMOD_SET_DEFAULT_CLOCKACT,
228}; 216};
229 217
230/* timer2 */ 218/* timer2 */
@@ -241,7 +229,8 @@ static struct omap_hwmod omap3xxx_timer2_hwmod = {
241 .idlest_idle_bit = OMAP3430_ST_GPT2_SHIFT, 229 .idlest_idle_bit = OMAP3430_ST_GPT2_SHIFT,
242 }, 230 },
243 }, 231 },
244 .class = &omap3xxx_timer_1ms_hwmod_class, 232 .class = &omap3xxx_timer_hwmod_class,
233 .flags = HWMOD_SET_DEFAULT_CLOCKACT,
245}; 234};
246 235
247/* timer3 */ 236/* timer3 */
@@ -259,6 +248,7 @@ static struct omap_hwmod omap3xxx_timer3_hwmod = {
259 }, 248 },
260 }, 249 },
261 .class = &omap3xxx_timer_hwmod_class, 250 .class = &omap3xxx_timer_hwmod_class,
251 .flags = HWMOD_SET_DEFAULT_CLOCKACT,
262}; 252};
263 253
264/* timer4 */ 254/* timer4 */
@@ -276,6 +266,7 @@ static struct omap_hwmod omap3xxx_timer4_hwmod = {
276 }, 266 },
277 }, 267 },
278 .class = &omap3xxx_timer_hwmod_class, 268 .class = &omap3xxx_timer_hwmod_class,
269 .flags = HWMOD_SET_DEFAULT_CLOCKACT,
279}; 270};
280 271
281/* timer5 */ 272/* timer5 */
@@ -294,6 +285,7 @@ static struct omap_hwmod omap3xxx_timer5_hwmod = {
294 }, 285 },
295 .dev_attr = &capability_dsp_dev_attr, 286 .dev_attr = &capability_dsp_dev_attr,
296 .class = &omap3xxx_timer_hwmod_class, 287 .class = &omap3xxx_timer_hwmod_class,
288 .flags = HWMOD_SET_DEFAULT_CLOCKACT,
297}; 289};
298 290
299/* timer6 */ 291/* timer6 */
@@ -312,6 +304,7 @@ static struct omap_hwmod omap3xxx_timer6_hwmod = {
312 }, 304 },
313 .dev_attr = &capability_dsp_dev_attr, 305 .dev_attr = &capability_dsp_dev_attr,
314 .class = &omap3xxx_timer_hwmod_class, 306 .class = &omap3xxx_timer_hwmod_class,
307 .flags = HWMOD_SET_DEFAULT_CLOCKACT,
315}; 308};
316 309
317/* timer7 */ 310/* timer7 */
@@ -330,6 +323,7 @@ static struct omap_hwmod omap3xxx_timer7_hwmod = {
330 }, 323 },
331 .dev_attr = &capability_dsp_dev_attr, 324 .dev_attr = &capability_dsp_dev_attr,
332 .class = &omap3xxx_timer_hwmod_class, 325 .class = &omap3xxx_timer_hwmod_class,
326 .flags = HWMOD_SET_DEFAULT_CLOCKACT,
333}; 327};
334 328
335/* timer8 */ 329/* timer8 */
@@ -348,6 +342,7 @@ static struct omap_hwmod omap3xxx_timer8_hwmod = {
348 }, 342 },
349 .dev_attr = &capability_dsp_pwm_dev_attr, 343 .dev_attr = &capability_dsp_pwm_dev_attr,
350 .class = &omap3xxx_timer_hwmod_class, 344 .class = &omap3xxx_timer_hwmod_class,
345 .flags = HWMOD_SET_DEFAULT_CLOCKACT,
351}; 346};
352 347
353/* timer9 */ 348/* timer9 */
@@ -366,6 +361,7 @@ static struct omap_hwmod omap3xxx_timer9_hwmod = {
366 }, 361 },
367 .dev_attr = &capability_pwm_dev_attr, 362 .dev_attr = &capability_pwm_dev_attr,
368 .class = &omap3xxx_timer_hwmod_class, 363 .class = &omap3xxx_timer_hwmod_class,
364 .flags = HWMOD_SET_DEFAULT_CLOCKACT,
369}; 365};
370 366
371/* timer10 */ 367/* timer10 */
@@ -383,7 +379,8 @@ static struct omap_hwmod omap3xxx_timer10_hwmod = {
383 }, 379 },
384 }, 380 },
385 .dev_attr = &capability_pwm_dev_attr, 381 .dev_attr = &capability_pwm_dev_attr,
386 .class = &omap3xxx_timer_1ms_hwmod_class, 382 .class = &omap3xxx_timer_hwmod_class,
383 .flags = HWMOD_SET_DEFAULT_CLOCKACT,
387}; 384};
388 385
389/* timer11 */ 386/* timer11 */
@@ -402,6 +399,7 @@ static struct omap_hwmod omap3xxx_timer11_hwmod = {
402 }, 399 },
403 .dev_attr = &capability_pwm_dev_attr, 400 .dev_attr = &capability_pwm_dev_attr,
404 .class = &omap3xxx_timer_hwmod_class, 401 .class = &omap3xxx_timer_hwmod_class,
402 .flags = HWMOD_SET_DEFAULT_CLOCKACT,
405}; 403};
406 404
407/* timer12 */ 405/* timer12 */
@@ -425,6 +423,7 @@ static struct omap_hwmod omap3xxx_timer12_hwmod = {
425 }, 423 },
426 .dev_attr = &capability_secure_dev_attr, 424 .dev_attr = &capability_secure_dev_attr,
427 .class = &omap3xxx_timer_hwmod_class, 425 .class = &omap3xxx_timer_hwmod_class,
426 .flags = HWMOD_SET_DEFAULT_CLOCKACT,
428}; 427};
429 428
430/* 429/*
diff --git a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c
index 7a6132848f5d..399f4ce9cab1 100644
--- a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c
+++ b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c
@@ -3067,6 +3067,7 @@ static struct omap_hwmod_class_sysconfig omap44xx_timer_1ms_sysc = {
3067 SYSC_HAS_SIDLEMODE | SYSC_HAS_SOFTRESET | 3067 SYSC_HAS_SIDLEMODE | SYSC_HAS_SOFTRESET |
3068 SYSS_HAS_RESET_STATUS), 3068 SYSS_HAS_RESET_STATUS),
3069 .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART), 3069 .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART),
3070 .clockact = CLOCKACT_TEST_ICLK,
3070 .sysc_fields = &omap_hwmod_sysc_type1, 3071 .sysc_fields = &omap_hwmod_sysc_type1,
3071}; 3072};
3072 3073
@@ -3120,6 +3121,7 @@ static struct omap_hwmod omap44xx_timer1_hwmod = {
3120 .name = "timer1", 3121 .name = "timer1",
3121 .class = &omap44xx_timer_1ms_hwmod_class, 3122 .class = &omap44xx_timer_1ms_hwmod_class,
3122 .clkdm_name = "l4_wkup_clkdm", 3123 .clkdm_name = "l4_wkup_clkdm",
3124 .flags = HWMOD_SET_DEFAULT_CLOCKACT,
3123 .mpu_irqs = omap44xx_timer1_irqs, 3125 .mpu_irqs = omap44xx_timer1_irqs,
3124 .main_clk = "timer1_fck", 3126 .main_clk = "timer1_fck",
3125 .prcm = { 3127 .prcm = {
@@ -3142,6 +3144,7 @@ static struct omap_hwmod omap44xx_timer2_hwmod = {
3142 .name = "timer2", 3144 .name = "timer2",
3143 .class = &omap44xx_timer_1ms_hwmod_class, 3145 .class = &omap44xx_timer_1ms_hwmod_class,
3144 .clkdm_name = "l4_per_clkdm", 3146 .clkdm_name = "l4_per_clkdm",
3147 .flags = HWMOD_SET_DEFAULT_CLOCKACT,
3145 .mpu_irqs = omap44xx_timer2_irqs, 3148 .mpu_irqs = omap44xx_timer2_irqs,
3146 .main_clk = "timer2_fck", 3149 .main_clk = "timer2_fck",
3147 .prcm = { 3150 .prcm = {
@@ -3316,6 +3319,7 @@ static struct omap_hwmod omap44xx_timer10_hwmod = {
3316 .name = "timer10", 3319 .name = "timer10",
3317 .class = &omap44xx_timer_1ms_hwmod_class, 3320 .class = &omap44xx_timer_1ms_hwmod_class,
3318 .clkdm_name = "l4_per_clkdm", 3321 .clkdm_name = "l4_per_clkdm",
3322 .flags = HWMOD_SET_DEFAULT_CLOCKACT,
3319 .mpu_irqs = omap44xx_timer10_irqs, 3323 .mpu_irqs = omap44xx_timer10_irqs,
3320 .main_clk = "timer10_fck", 3324 .main_clk = "timer10_fck",
3321 .prcm = { 3325 .prcm = {
diff --git a/arch/arm/mach-omap2/timer.c b/arch/arm/mach-omap2/timer.c
index 684d2fc3d485..099e4060afe9 100644
--- a/arch/arm/mach-omap2/timer.c
+++ b/arch/arm/mach-omap2/timer.c
@@ -108,7 +108,7 @@ static int omap2_gp_timer_set_next_event(unsigned long cycles,
108 struct clock_event_device *evt) 108 struct clock_event_device *evt)
109{ 109{
110 __omap_dm_timer_load_start(&clkev, OMAP_TIMER_CTRL_ST, 110 __omap_dm_timer_load_start(&clkev, OMAP_TIMER_CTRL_ST,
111 0xffffffff - cycles, 1); 111 0xffffffff - cycles, OMAP_TIMER_POSTED);
112 112
113 return 0; 113 return 0;
114} 114}
@@ -118,7 +118,7 @@ static void omap2_gp_timer_set_mode(enum clock_event_mode mode,
118{ 118{
119 u32 period; 119 u32 period;
120 120
121 __omap_dm_timer_stop(&clkev, 1, clkev.rate); 121 __omap_dm_timer_stop(&clkev, OMAP_TIMER_POSTED, clkev.rate);
122 122
123 switch (mode) { 123 switch (mode) {
124 case CLOCK_EVT_MODE_PERIODIC: 124 case CLOCK_EVT_MODE_PERIODIC:
@@ -126,10 +126,10 @@ static void omap2_gp_timer_set_mode(enum clock_event_mode mode,
126 period -= 1; 126 period -= 1;
127 /* Looks like we need to first set the load value separately */ 127 /* Looks like we need to first set the load value separately */
128 __omap_dm_timer_write(&clkev, OMAP_TIMER_LOAD_REG, 128 __omap_dm_timer_write(&clkev, OMAP_TIMER_LOAD_REG,
129 0xffffffff - period, 1); 129 0xffffffff - period, OMAP_TIMER_POSTED);
130 __omap_dm_timer_load_start(&clkev, 130 __omap_dm_timer_load_start(&clkev,
131 OMAP_TIMER_CTRL_AR | OMAP_TIMER_CTRL_ST, 131 OMAP_TIMER_CTRL_AR | OMAP_TIMER_CTRL_ST,
132 0xffffffff - period, 1); 132 0xffffffff - period, OMAP_TIMER_POSTED);
133 break; 133 break;
134 case CLOCK_EVT_MODE_ONESHOT: 134 case CLOCK_EVT_MODE_ONESHOT:
135 break; 135 break;
@@ -222,10 +222,24 @@ void __init omap_dmtimer_init(void)
222 } 222 }
223} 223}
224 224
225/**
226 * omap_dm_timer_get_errata - get errata flags for a timer
227 *
228 * Get the timer errata flags that are specific to the OMAP device being used.
229 */
230u32 __init omap_dm_timer_get_errata(void)
231{
232 if (cpu_is_omap24xx())
233 return 0;
234
235 return OMAP_TIMER_ERRATA_I103_I767;
236}
237
225static int __init omap_dm_timer_init_one(struct omap_dm_timer *timer, 238static int __init omap_dm_timer_init_one(struct omap_dm_timer *timer,
226 int gptimer_id, 239 int gptimer_id,
227 const char *fck_source, 240 const char *fck_source,
228 const char *property) 241 const char *property,
242 int posted)
229{ 243{
230 char name[10]; /* 10 = sizeof("gptXX_Xck0") */ 244 char name[10]; /* 10 = sizeof("gptXX_Xck0") */
231 const char *oh_name; 245 const char *oh_name;
@@ -260,9 +274,7 @@ static int __init omap_dm_timer_init_one(struct omap_dm_timer *timer,
260 oh_name = name; 274 oh_name = name;
261 } 275 }
262 276
263 omap_hwmod_setup_one(oh_name);
264 oh = omap_hwmod_lookup(oh_name); 277 oh = omap_hwmod_lookup(oh_name);
265
266 if (!oh) 278 if (!oh)
267 return -ENODEV; 279 return -ENODEV;
268 280
@@ -292,8 +304,6 @@ static int __init omap_dm_timer_init_one(struct omap_dm_timer *timer,
292 if (IS_ERR(timer->fclk)) 304 if (IS_ERR(timer->fclk))
293 return -ENODEV; 305 return -ENODEV;
294 306
295 omap_hwmod_enable(oh);
296
297 /* FIXME: Need to remove hard-coded test on timer ID */ 307 /* FIXME: Need to remove hard-coded test on timer ID */
298 if (gptimer_id != 12) { 308 if (gptimer_id != 12) {
299 struct clk *src; 309 struct clk *src;
@@ -302,19 +312,26 @@ static int __init omap_dm_timer_init_one(struct omap_dm_timer *timer,
302 if (IS_ERR(src)) { 312 if (IS_ERR(src)) {
303 res = -EINVAL; 313 res = -EINVAL;
304 } else { 314 } else {
305 res = __omap_dm_timer_set_source(timer->fclk, src); 315 res = clk_set_parent(timer->fclk, src);
306 if (IS_ERR_VALUE(res)) 316 if (IS_ERR_VALUE(res))
307 pr_warn("%s: %s cannot set source\n", 317 pr_warn("%s: %s cannot set source\n",
308 __func__, oh->name); 318 __func__, oh->name);
309 clk_put(src); 319 clk_put(src);
310 } 320 }
311 } 321 }
322
323 omap_hwmod_setup_one(oh_name);
324 omap_hwmod_enable(oh);
312 __omap_dm_timer_init_regs(timer); 325 __omap_dm_timer_init_regs(timer);
313 __omap_dm_timer_reset(timer, 1, 1);
314 timer->posted = 1;
315 326
316 timer->rate = clk_get_rate(timer->fclk); 327 if (posted)
328 __omap_dm_timer_enable_posted(timer);
329
330 /* Check that the intended posted configuration matches the actual */
331 if (posted != timer->posted)
332 return -EINVAL;
317 333
334 timer->rate = clk_get_rate(timer->fclk);
318 timer->reserved = 1; 335 timer->reserved = 1;
319 336
320 return res; 337 return res;
@@ -326,7 +343,17 @@ static void __init omap2_gp_clockevent_init(int gptimer_id,
326{ 343{
327 int res; 344 int res;
328 345
329 res = omap_dm_timer_init_one(&clkev, gptimer_id, fck_source, property); 346 clkev.errata = omap_dm_timer_get_errata();
347
348 /*
349 * For clock-event timers we never read the timer counter and
350 * so we are not impacted by errata i103 and i767. Therefore,
351 * we can safely ignore this errata for clock-event timers.
352 */
353 __omap_dm_timer_override_errata(&clkev, OMAP_TIMER_ERRATA_I103_I767);
354
355 res = omap_dm_timer_init_one(&clkev, gptimer_id, fck_source, property,
356 OMAP_TIMER_POSTED);
330 BUG_ON(res); 357 BUG_ON(res);
331 358
332 omap2_gp_timer_irq.dev_id = &clkev; 359 omap2_gp_timer_irq.dev_id = &clkev;
@@ -359,7 +386,8 @@ static bool use_gptimer_clksrc;
359 */ 386 */
360static cycle_t clocksource_read_cycles(struct clocksource *cs) 387static cycle_t clocksource_read_cycles(struct clocksource *cs)
361{ 388{
362 return (cycle_t)__omap_dm_timer_read_counter(&clksrc, 1); 389 return (cycle_t)__omap_dm_timer_read_counter(&clksrc,
390 OMAP_TIMER_NONPOSTED);
363} 391}
364 392
365static struct clocksource clocksource_gpt = { 393static struct clocksource clocksource_gpt = {
@@ -373,7 +401,8 @@ static struct clocksource clocksource_gpt = {
373static u32 notrace dmtimer_read_sched_clock(void) 401static u32 notrace dmtimer_read_sched_clock(void)
374{ 402{
375 if (clksrc.reserved) 403 if (clksrc.reserved)
376 return __omap_dm_timer_read_counter(&clksrc, 1); 404 return __omap_dm_timer_read_counter(&clksrc,
405 OMAP_TIMER_NONPOSTED);
377 406
378 return 0; 407 return 0;
379} 408}
@@ -451,11 +480,15 @@ static void __init omap2_gptimer_clocksource_init(int gptimer_id,
451{ 480{
452 int res; 481 int res;
453 482
454 res = omap_dm_timer_init_one(&clksrc, gptimer_id, fck_source, NULL); 483 clksrc.errata = omap_dm_timer_get_errata();
484
485 res = omap_dm_timer_init_one(&clksrc, gptimer_id, fck_source, NULL,
486 OMAP_TIMER_NONPOSTED);
455 BUG_ON(res); 487 BUG_ON(res);
456 488
457 __omap_dm_timer_load_start(&clksrc, 489 __omap_dm_timer_load_start(&clksrc,
458 OMAP_TIMER_CTRL_ST | OMAP_TIMER_CTRL_AR, 0, 1); 490 OMAP_TIMER_CTRL_ST | OMAP_TIMER_CTRL_AR, 0,
491 OMAP_TIMER_NONPOSTED);
459 setup_sched_clock(dmtimer_read_sched_clock, 32, clksrc.rate); 492 setup_sched_clock(dmtimer_read_sched_clock, 32, clksrc.rate);
460 493
461 if (clocksource_register_hz(&clocksource_gpt, clksrc.rate)) 494 if (clocksource_register_hz(&clocksource_gpt, clksrc.rate))
@@ -693,6 +726,7 @@ static int __init omap_timer_init(struct omap_hwmod *oh, void *unused)
693 if (timer_dev_attr) 726 if (timer_dev_attr)
694 pdata->timer_capability = timer_dev_attr->timer_capability; 727 pdata->timer_capability = timer_dev_attr->timer_capability;
695 728
729 pdata->timer_errata = omap_dm_timer_get_errata();
696 pdata->get_context_loss_count = omap_pm_get_dev_context_loss_count; 730 pdata->get_context_loss_count = omap_pm_get_dev_context_loss_count;
697 731
698 pdev = omap_device_build(name, id, oh, pdata, sizeof(*pdata), 732 pdev = omap_device_build(name, id, oh, pdata, sizeof(*pdata),
diff --git a/arch/arm/plat-omap/dmtimer.c b/arch/arm/plat-omap/dmtimer.c
index 9dca23e4d6b0..9deeb3064d33 100644
--- a/arch/arm/plat-omap/dmtimer.c
+++ b/arch/arm/plat-omap/dmtimer.c
@@ -35,6 +35,7 @@
35 * 675 Mass Ave, Cambridge, MA 02139, USA. 35 * 675 Mass Ave, Cambridge, MA 02139, USA.
36 */ 36 */
37 37
38#include <linux/clk.h>
38#include <linux/module.h> 39#include <linux/module.h>
39#include <linux/io.h> 40#include <linux/io.h>
40#include <linux/device.h> 41#include <linux/device.h>
@@ -83,10 +84,6 @@ static void omap_dm_timer_write_reg(struct omap_dm_timer *timer, u32 reg,
83 84
84static void omap_timer_restore_context(struct omap_dm_timer *timer) 85static void omap_timer_restore_context(struct omap_dm_timer *timer)
85{ 86{
86 if (timer->revision == 1)
87 __raw_writel(timer->context.tistat, timer->sys_stat);
88
89 __raw_writel(timer->context.tisr, timer->irq_stat);
90 omap_dm_timer_write_reg(timer, OMAP_TIMER_WAKEUP_EN_REG, 87 omap_dm_timer_write_reg(timer, OMAP_TIMER_WAKEUP_EN_REG,
91 timer->context.twer); 88 timer->context.twer);
92 omap_dm_timer_write_reg(timer, OMAP_TIMER_COUNTER_REG, 89 omap_dm_timer_write_reg(timer, OMAP_TIMER_COUNTER_REG,
@@ -121,21 +118,13 @@ static void omap_dm_timer_wait_for_reset(struct omap_dm_timer *timer)
121 118
122static void omap_dm_timer_reset(struct omap_dm_timer *timer) 119static void omap_dm_timer_reset(struct omap_dm_timer *timer)
123{ 120{
124 omap_dm_timer_enable(timer); 121 omap_dm_timer_write_reg(timer, OMAP_TIMER_IF_CTRL_REG, 0x06);
125 if (timer->pdev->id != 1) { 122 omap_dm_timer_wait_for_reset(timer);
126 omap_dm_timer_write_reg(timer, OMAP_TIMER_IF_CTRL_REG, 0x06);
127 omap_dm_timer_wait_for_reset(timer);
128 }
129
130 __omap_dm_timer_reset(timer, 0, 0); 123 __omap_dm_timer_reset(timer, 0, 0);
131 omap_dm_timer_disable(timer);
132 timer->posted = 1;
133} 124}
134 125
135int omap_dm_timer_prepare(struct omap_dm_timer *timer) 126int omap_dm_timer_prepare(struct omap_dm_timer *timer)
136{ 127{
137 int ret;
138
139 /* 128 /*
140 * FIXME: OMAP1 devices do not use the clock framework for dmtimers so 129 * FIXME: OMAP1 devices do not use the clock framework for dmtimers so
141 * do not call clk_get() for these devices. 130 * do not call clk_get() for these devices.
@@ -149,13 +138,15 @@ int omap_dm_timer_prepare(struct omap_dm_timer *timer)
149 } 138 }
150 } 139 }
151 140
141 omap_dm_timer_enable(timer);
142
152 if (timer->capability & OMAP_TIMER_NEEDS_RESET) 143 if (timer->capability & OMAP_TIMER_NEEDS_RESET)
153 omap_dm_timer_reset(timer); 144 omap_dm_timer_reset(timer);
154 145
155 ret = omap_dm_timer_set_source(timer, OMAP_TIMER_SRC_32_KHZ); 146 __omap_dm_timer_enable_posted(timer);
147 omap_dm_timer_disable(timer);
156 148
157 timer->posted = 1; 149 return omap_dm_timer_set_source(timer, OMAP_TIMER_SRC_32_KHZ);
158 return ret;
159} 150}
160 151
161static inline u32 omap_dm_timer_reserved_systimer(int id) 152static inline u32 omap_dm_timer_reserved_systimer(int id)
@@ -449,7 +440,6 @@ int omap_dm_timer_stop(struct omap_dm_timer *timer)
449 */ 440 */
450 timer->context.tclr = 441 timer->context.tclr =
451 omap_dm_timer_read_reg(timer, OMAP_TIMER_CTRL_REG); 442 omap_dm_timer_read_reg(timer, OMAP_TIMER_CTRL_REG);
452 timer->context.tisr = __raw_readl(timer->irq_stat);
453 omap_dm_timer_disable(timer); 443 omap_dm_timer_disable(timer);
454 return 0; 444 return 0;
455} 445}
@@ -459,7 +449,7 @@ int omap_dm_timer_set_source(struct omap_dm_timer *timer, int source)
459{ 449{
460 int ret; 450 int ret;
461 char *parent_name = NULL; 451 char *parent_name = NULL;
462 struct clk *fclk, *parent; 452 struct clk *parent;
463 struct dmtimer_platform_data *pdata; 453 struct dmtimer_platform_data *pdata;
464 454
465 if (unlikely(!timer)) 455 if (unlikely(!timer))
@@ -478,11 +468,8 @@ int omap_dm_timer_set_source(struct omap_dm_timer *timer, int source)
478 if (pdata && pdata->set_timer_src) 468 if (pdata && pdata->set_timer_src)
479 return pdata->set_timer_src(timer->pdev, source); 469 return pdata->set_timer_src(timer->pdev, source);
480 470
481 fclk = clk_get(&timer->pdev->dev, "fck"); 471 if (!timer->fclk)
482 if (IS_ERR_OR_NULL(fclk)) {
483 pr_err("%s: fck not found\n", __func__);
484 return -EINVAL; 472 return -EINVAL;
485 }
486 473
487 switch (source) { 474 switch (source) {
488 case OMAP_TIMER_SRC_SYS_CLK: 475 case OMAP_TIMER_SRC_SYS_CLK:
@@ -501,18 +488,15 @@ int omap_dm_timer_set_source(struct omap_dm_timer *timer, int source)
501 parent = clk_get(&timer->pdev->dev, parent_name); 488 parent = clk_get(&timer->pdev->dev, parent_name);
502 if (IS_ERR_OR_NULL(parent)) { 489 if (IS_ERR_OR_NULL(parent)) {
503 pr_err("%s: %s not found\n", __func__, parent_name); 490 pr_err("%s: %s not found\n", __func__, parent_name);
504 ret = -EINVAL; 491 return -EINVAL;
505 goto out;
506 } 492 }
507 493
508 ret = clk_set_parent(fclk, parent); 494 ret = clk_set_parent(timer->fclk, parent);
509 if (IS_ERR_VALUE(ret)) 495 if (IS_ERR_VALUE(ret))
510 pr_err("%s: failed to set %s as parent\n", __func__, 496 pr_err("%s: failed to set %s as parent\n", __func__,
511 parent_name); 497 parent_name);
512 498
513 clk_put(parent); 499 clk_put(parent);
514out:
515 clk_put(fclk);
516 500
517 return ret; 501 return ret;
518} 502}
@@ -595,8 +579,8 @@ int omap_dm_timer_set_match(struct omap_dm_timer *timer, int enable,
595 l |= OMAP_TIMER_CTRL_CE; 579 l |= OMAP_TIMER_CTRL_CE;
596 else 580 else
597 l &= ~OMAP_TIMER_CTRL_CE; 581 l &= ~OMAP_TIMER_CTRL_CE;
598 omap_dm_timer_write_reg(timer, OMAP_TIMER_CTRL_REG, l);
599 omap_dm_timer_write_reg(timer, OMAP_TIMER_MATCH_REG, match); 582 omap_dm_timer_write_reg(timer, OMAP_TIMER_MATCH_REG, match);
583 omap_dm_timer_write_reg(timer, OMAP_TIMER_CTRL_REG, l);
600 584
601 /* Save the context */ 585 /* Save the context */
602 timer->context.tclr = l; 586 timer->context.tclr = l;
@@ -672,6 +656,37 @@ int omap_dm_timer_set_int_enable(struct omap_dm_timer *timer,
672} 656}
673EXPORT_SYMBOL_GPL(omap_dm_timer_set_int_enable); 657EXPORT_SYMBOL_GPL(omap_dm_timer_set_int_enable);
674 658
659/**
660 * omap_dm_timer_set_int_disable - disable timer interrupts
661 * @timer: pointer to timer handle
662 * @mask: bit mask of interrupts to be disabled
663 *
664 * Disables the specified timer interrupts for a timer.
665 */
666int omap_dm_timer_set_int_disable(struct omap_dm_timer *timer, u32 mask)
667{
668 u32 l = mask;
669
670 if (unlikely(!timer))
671 return -EINVAL;
672
673 omap_dm_timer_enable(timer);
674
675 if (timer->revision == 1)
676 l = __raw_readl(timer->irq_ena) & ~mask;
677
678 __raw_writel(l, timer->irq_dis);
679 l = omap_dm_timer_read_reg(timer, OMAP_TIMER_WAKEUP_EN_REG) & ~mask;
680 omap_dm_timer_write_reg(timer, OMAP_TIMER_WAKEUP_EN_REG, l);
681
682 /* Save the context */
683 timer->context.tier &= ~mask;
684 timer->context.twer &= ~mask;
685 omap_dm_timer_disable(timer);
686 return 0;
687}
688EXPORT_SYMBOL_GPL(omap_dm_timer_set_int_disable);
689
675unsigned int omap_dm_timer_read_status(struct omap_dm_timer *timer) 690unsigned int omap_dm_timer_read_status(struct omap_dm_timer *timer)
676{ 691{
677 unsigned int l; 692 unsigned int l;
@@ -693,8 +708,7 @@ int omap_dm_timer_write_status(struct omap_dm_timer *timer, unsigned int value)
693 return -EINVAL; 708 return -EINVAL;
694 709
695 __omap_dm_timer_write_status(timer, value); 710 __omap_dm_timer_write_status(timer, value);
696 /* Save the context */ 711
697 timer->context.tisr = value;
698 return 0; 712 return 0;
699} 713}
700EXPORT_SYMBOL_GPL(omap_dm_timer_write_status); 714EXPORT_SYMBOL_GPL(omap_dm_timer_write_status);
@@ -797,6 +811,7 @@ static int __devinit omap_dm_timer_probe(struct platform_device *pdev)
797 timer->capability |= OMAP_TIMER_SECURE; 811 timer->capability |= OMAP_TIMER_SECURE;
798 } else { 812 } else {
799 timer->id = pdev->id; 813 timer->id = pdev->id;
814 timer->errata = pdata->timer_errata;
800 timer->capability = pdata->timer_capability; 815 timer->capability = pdata->timer_capability;
801 timer->reserved = omap_dm_timer_reserved_systimer(timer->id); 816 timer->reserved = omap_dm_timer_reserved_systimer(timer->id);
802 timer->get_context_loss_count = pdata->get_context_loss_count; 817 timer->get_context_loss_count = pdata->get_context_loss_count;
diff --git a/arch/arm/plat-omap/include/plat/dmtimer.h b/arch/arm/plat-omap/include/plat/dmtimer.h
index f8943c8f9dbf..05a36e16f3f4 100644
--- a/arch/arm/plat-omap/include/plat/dmtimer.h
+++ b/arch/arm/plat-omap/include/plat/dmtimer.h
@@ -32,7 +32,6 @@
32 * 675 Mass Ave, Cambridge, MA 02139, USA. 32 * 675 Mass Ave, Cambridge, MA 02139, USA.
33 */ 33 */
34 34
35#include <linux/clk.h>
36#include <linux/delay.h> 35#include <linux/delay.h>
37#include <linux/io.h> 36#include <linux/io.h>
38#include <linux/platform_device.h> 37#include <linux/platform_device.h>
@@ -55,6 +54,10 @@
55#define OMAP_TIMER_TRIGGER_OVERFLOW 0x01 54#define OMAP_TIMER_TRIGGER_OVERFLOW 0x01
56#define OMAP_TIMER_TRIGGER_OVERFLOW_AND_COMPARE 0x02 55#define OMAP_TIMER_TRIGGER_OVERFLOW_AND_COMPARE 0x02
57 56
57/* posted mode types */
58#define OMAP_TIMER_NONPOSTED 0x00
59#define OMAP_TIMER_POSTED 0x01
60
58/* timer capabilities used in hwmod database */ 61/* timer capabilities used in hwmod database */
59#define OMAP_TIMER_SECURE 0x80000000 62#define OMAP_TIMER_SECURE 0x80000000
60#define OMAP_TIMER_ALWON 0x40000000 63#define OMAP_TIMER_ALWON 0x40000000
@@ -62,6 +65,16 @@
62#define OMAP_TIMER_NEEDS_RESET 0x10000000 65#define OMAP_TIMER_NEEDS_RESET 0x10000000
63#define OMAP_TIMER_HAS_DSP_IRQ 0x08000000 66#define OMAP_TIMER_HAS_DSP_IRQ 0x08000000
64 67
68/*
69 * timer errata flags
70 *
71 * Errata i103/i767 impacts all OMAP3/4/5 devices including AM33xx. This
72 * errata prevents us from using posted mode on these devices, unless the
73 * timer counter register is never read. For more details please refer to
74 * the OMAP3/4/5 errata documents.
75 */
76#define OMAP_TIMER_ERRATA_I103_I767 0x80000000
77
65struct omap_timer_capability_dev_attr { 78struct omap_timer_capability_dev_attr {
66 u32 timer_capability; 79 u32 timer_capability;
67}; 80};
@@ -70,8 +83,6 @@ struct omap_dm_timer;
70 83
71struct timer_regs { 84struct timer_regs {
72 u32 tidr; 85 u32 tidr;
73 u32 tistat;
74 u32 tisr;
75 u32 tier; 86 u32 tier;
76 u32 twer; 87 u32 twer;
77 u32 tclr; 88 u32 tclr;
@@ -93,6 +104,7 @@ struct timer_regs {
93struct dmtimer_platform_data { 104struct dmtimer_platform_data {
94 /* set_timer_src - Only used for OMAP1 devices */ 105 /* set_timer_src - Only used for OMAP1 devices */
95 int (*set_timer_src)(struct platform_device *pdev, int source); 106 int (*set_timer_src)(struct platform_device *pdev, int source);
107 u32 timer_errata;
96 u32 timer_capability; 108 u32 timer_capability;
97 int (*get_context_loss_count)(struct device *); 109 int (*get_context_loss_count)(struct device *);
98}; 110};
@@ -122,6 +134,7 @@ int omap_dm_timer_set_pwm(struct omap_dm_timer *timer, int def_on, int toggle, i
122int omap_dm_timer_set_prescaler(struct omap_dm_timer *timer, int prescaler); 134int omap_dm_timer_set_prescaler(struct omap_dm_timer *timer, int prescaler);
123 135
124int omap_dm_timer_set_int_enable(struct omap_dm_timer *timer, unsigned int value); 136int omap_dm_timer_set_int_enable(struct omap_dm_timer *timer, unsigned int value);
137int omap_dm_timer_set_int_disable(struct omap_dm_timer *timer, u32 mask);
125 138
126unsigned int omap_dm_timer_read_status(struct omap_dm_timer *timer); 139unsigned int omap_dm_timer_read_status(struct omap_dm_timer *timer);
127int omap_dm_timer_write_status(struct omap_dm_timer *timer, unsigned int value); 140int omap_dm_timer_write_status(struct omap_dm_timer *timer, unsigned int value);
@@ -269,6 +282,7 @@ struct omap_dm_timer {
269 int ctx_loss_count; 282 int ctx_loss_count;
270 int revision; 283 int revision;
271 u32 capability; 284 u32 capability;
285 u32 errata;
272 struct platform_device *pdev; 286 struct platform_device *pdev;
273 struct list_head node; 287 struct list_head node;
274}; 288};
@@ -307,7 +321,7 @@ static inline void __omap_dm_timer_init_regs(struct omap_dm_timer *timer)
307 OMAP_TIMER_V1_SYS_STAT_OFFSET; 321 OMAP_TIMER_V1_SYS_STAT_OFFSET;
308 timer->irq_stat = timer->io_base + OMAP_TIMER_V1_STAT_OFFSET; 322 timer->irq_stat = timer->io_base + OMAP_TIMER_V1_STAT_OFFSET;
309 timer->irq_ena = timer->io_base + OMAP_TIMER_V1_INT_EN_OFFSET; 323 timer->irq_ena = timer->io_base + OMAP_TIMER_V1_INT_EN_OFFSET;
310 timer->irq_dis = NULL; 324 timer->irq_dis = timer->io_base + OMAP_TIMER_V1_INT_EN_OFFSET;
311 timer->pend = timer->io_base + _OMAP_TIMER_WRITE_PEND_OFFSET; 325 timer->pend = timer->io_base + _OMAP_TIMER_WRITE_PEND_OFFSET;
312 timer->func_base = timer->io_base; 326 timer->func_base = timer->io_base;
313 } else { 327 } else {
@@ -340,28 +354,46 @@ static inline void __omap_dm_timer_reset(struct omap_dm_timer *timer,
340 l |= 1 << 2; 354 l |= 1 << 2;
341 355
342 __raw_writel(l, timer->io_base + OMAP_TIMER_OCP_CFG_OFFSET); 356 __raw_writel(l, timer->io_base + OMAP_TIMER_OCP_CFG_OFFSET);
343
344 /* Match hardware reset default of posted mode */
345 __omap_dm_timer_write(timer, OMAP_TIMER_IF_CTRL_REG,
346 OMAP_TIMER_CTRL_POSTED, 0);
347} 357}
348 358
349static inline int __omap_dm_timer_set_source(struct clk *timer_fck, 359/*
350 struct clk *parent) 360 * __omap_dm_timer_enable_posted - enables write posted mode
361 * @timer: pointer to timer instance handle
362 *
363 * Enables the write posted mode for the timer. When posted mode is enabled
364 * writes to certain timer registers are immediately acknowledged by the
365 * internal bus and hence prevents stalling the CPU waiting for the write to
366 * complete. Enabling this feature can improve performance for writing to the
367 * timer registers.
368 */
369static inline void __omap_dm_timer_enable_posted(struct omap_dm_timer *timer)
351{ 370{
352 int ret; 371 if (timer->posted)
372 return;
353 373
354 clk_disable(timer_fck); 374 if (timer->errata & OMAP_TIMER_ERRATA_I103_I767)
355 ret = clk_set_parent(timer_fck, parent); 375 return;
356 clk_enable(timer_fck);
357 376
358 /* 377 __omap_dm_timer_write(timer, OMAP_TIMER_IF_CTRL_REG,
359 * When the functional clock disappears, too quick writes seem 378 OMAP_TIMER_CTRL_POSTED, 0);
360 * to cause an abort. XXX Is this still necessary? 379 timer->context.tsicr = OMAP_TIMER_CTRL_POSTED;
361 */ 380 timer->posted = OMAP_TIMER_POSTED;
362 __delay(300000); 381}
363 382
364 return ret; 383/**
384 * __omap_dm_timer_override_errata - override errata flags for a timer
385 * @timer: pointer to timer handle
386 * @errata: errata flags to be ignored
387 *
388 * For a given timer, override a timer errata by clearing the flags
389 * specified by the errata argument. A specific erratum should only be
390 * overridden for a timer if the timer is used in such a way the erratum
391 * has no impact.
392 */
393static inline void __omap_dm_timer_override_errata(struct omap_dm_timer *timer,
394 u32 errata)
395{
396 timer->errata &= ~errata;
365} 397}
366 398
367static inline void __omap_dm_timer_stop(struct omap_dm_timer *timer, 399static inline void __omap_dm_timer_stop(struct omap_dm_timer *timer,