ARM: OMAP2+: dmtimer: remove redundant sysconfig context restore
[pandora-kernel.git] / arch / arm / plat-omap / dmtimer.c
1 /*
2  * linux/arch/arm/plat-omap/dmtimer.c
3  *
4  * OMAP Dual-Mode Timers
5  *
6  * Copyright (C) 2010 Texas Instruments Incorporated - http://www.ti.com/
7  * Tarun Kanti DebBarma <tarun.kanti@ti.com>
8  * Thara Gopinath <thara@ti.com>
9  *
10  * dmtimer adaptation to platform_driver.
11  *
12  * Copyright (C) 2005 Nokia Corporation
13  * OMAP2 support by Juha Yrjola
14  * API improvements and OMAP2 clock framework support by Timo Teras
15  *
16  * Copyright (C) 2009 Texas Instruments
17  * Added OMAP4 support - Santosh Shilimkar <santosh.shilimkar@ti.com>
18  *
19  * This program is free software; you can redistribute it and/or modify it
20  * under the terms of the GNU General Public License as published by the
21  * Free Software Foundation; either version 2 of the License, or (at your
22  * option) any later version.
23  *
24  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
25  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
26  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
27  * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
28  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
29  * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
31  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32  *
33  * You should have received a copy of the  GNU General Public License along
34  * with this program; if not, write  to the Free Software Foundation, Inc.,
35  * 675 Mass Ave, Cambridge, MA 02139, USA.
36  */
37
38 #include <linux/module.h>
39 #include <linux/io.h>
40 #include <linux/slab.h>
41 #include <linux/err.h>
42 #include <linux/pm_runtime.h>
43
44 #include <plat/dmtimer.h>
45
46 static LIST_HEAD(omap_timer_list);
47 static DEFINE_SPINLOCK(dm_timer_lock);
48
49 /**
50  * omap_dm_timer_read_reg - read timer registers in posted and non-posted mode
51  * @timer:      timer pointer over which read operation to perform
52  * @reg:        lowest byte holds the register offset
53  *
54  * The posted mode bit is encoded in reg. Note that in posted mode write
55  * pending bit must be checked. Otherwise a read of a non completed write
56  * will produce an error.
57  */
58 static inline u32 omap_dm_timer_read_reg(struct omap_dm_timer *timer, u32 reg)
59 {
60         WARN_ON((reg & 0xff) < _OMAP_TIMER_WAKEUP_EN_OFFSET);
61         return __omap_dm_timer_read(timer, reg, timer->posted);
62 }
63
64 /**
65  * omap_dm_timer_write_reg - write timer registers in posted and non-posted mode
66  * @timer:      timer pointer over which write operation is to perform
67  * @reg:        lowest byte holds the register offset
68  * @value:      data to write into the register
69  *
70  * The posted mode bit is encoded in reg. Note that in posted mode the write
71  * pending bit must be checked. Otherwise a write on a register which has a
72  * pending write will be lost.
73  */
74 static void omap_dm_timer_write_reg(struct omap_dm_timer *timer, u32 reg,
75                                                 u32 value)
76 {
77         WARN_ON((reg & 0xff) < _OMAP_TIMER_WAKEUP_EN_OFFSET);
78         __omap_dm_timer_write(timer, reg, value, timer->posted);
79 }
80
81 static void omap_timer_restore_context(struct omap_dm_timer *timer)
82 {
83         if (timer->revision == 1)
84                 __raw_writel(timer->context.tistat, timer->sys_stat);
85
86         __raw_writel(timer->context.tisr, timer->irq_stat);
87         omap_dm_timer_write_reg(timer, OMAP_TIMER_WAKEUP_EN_REG,
88                                 timer->context.twer);
89         omap_dm_timer_write_reg(timer, OMAP_TIMER_COUNTER_REG,
90                                 timer->context.tcrr);
91         omap_dm_timer_write_reg(timer, OMAP_TIMER_LOAD_REG,
92                                 timer->context.tldr);
93         omap_dm_timer_write_reg(timer, OMAP_TIMER_MATCH_REG,
94                                 timer->context.tmar);
95         omap_dm_timer_write_reg(timer, OMAP_TIMER_IF_CTRL_REG,
96                                 timer->context.tsicr);
97         __raw_writel(timer->context.tier, timer->irq_ena);
98         omap_dm_timer_write_reg(timer, OMAP_TIMER_CTRL_REG,
99                                 timer->context.tclr);
100 }
101
102 static void omap_dm_timer_wait_for_reset(struct omap_dm_timer *timer)
103 {
104         int c;
105
106         if (!timer->sys_stat)
107                 return;
108
109         c = 0;
110         while (!(__raw_readl(timer->sys_stat) & 1)) {
111                 c++;
112                 if (c > 100000) {
113                         printk(KERN_ERR "Timer failed to reset\n");
114                         return;
115                 }
116         }
117 }
118
119 static void omap_dm_timer_reset(struct omap_dm_timer *timer)
120 {
121         omap_dm_timer_enable(timer);
122         if (timer->pdev->id != 1) {
123                 omap_dm_timer_write_reg(timer, OMAP_TIMER_IF_CTRL_REG, 0x06);
124                 omap_dm_timer_wait_for_reset(timer);
125         }
126
127         __omap_dm_timer_reset(timer, 0, 0);
128         omap_dm_timer_disable(timer);
129         timer->posted = 1;
130 }
131
132 int omap_dm_timer_prepare(struct omap_dm_timer *timer)
133 {
134         struct dmtimer_platform_data *pdata = timer->pdev->dev.platform_data;
135         int ret;
136
137         timer->fclk = clk_get(&timer->pdev->dev, "fck");
138         if (WARN_ON_ONCE(IS_ERR_OR_NULL(timer->fclk))) {
139                 timer->fclk = NULL;
140                 dev_err(&timer->pdev->dev, ": No fclk handle.\n");
141                 return -EINVAL;
142         }
143
144         if (pdata->needs_manual_reset)
145                 omap_dm_timer_reset(timer);
146
147         ret = omap_dm_timer_set_source(timer, OMAP_TIMER_SRC_32_KHZ);
148
149         timer->posted = 1;
150         return ret;
151 }
152
153 struct omap_dm_timer *omap_dm_timer_request(void)
154 {
155         struct omap_dm_timer *timer = NULL, *t;
156         unsigned long flags;
157         int ret = 0;
158
159         spin_lock_irqsave(&dm_timer_lock, flags);
160         list_for_each_entry(t, &omap_timer_list, node) {
161                 if (t->reserved)
162                         continue;
163
164                 timer = t;
165                 timer->reserved = 1;
166                 break;
167         }
168
169         if (timer) {
170                 ret = omap_dm_timer_prepare(timer);
171                 if (ret) {
172                         timer->reserved = 0;
173                         timer = NULL;
174                 }
175         }
176         spin_unlock_irqrestore(&dm_timer_lock, flags);
177
178         if (!timer)
179                 pr_debug("%s: timer request failed!\n", __func__);
180
181         return timer;
182 }
183 EXPORT_SYMBOL_GPL(omap_dm_timer_request);
184
185 struct omap_dm_timer *omap_dm_timer_request_specific(int id)
186 {
187         struct omap_dm_timer *timer = NULL, *t;
188         unsigned long flags;
189         int ret = 0;
190
191         spin_lock_irqsave(&dm_timer_lock, flags);
192         list_for_each_entry(t, &omap_timer_list, node) {
193                 if (t->pdev->id == id && !t->reserved) {
194                         timer = t;
195                         timer->reserved = 1;
196                         break;
197                 }
198         }
199
200         if (timer) {
201                 ret = omap_dm_timer_prepare(timer);
202                 if (ret) {
203                         timer->reserved = 0;
204                         timer = NULL;
205                 }
206         }
207         spin_unlock_irqrestore(&dm_timer_lock, flags);
208
209         if (!timer)
210                 pr_debug("%s: timer%d request failed!\n", __func__, id);
211
212         return timer;
213 }
214 EXPORT_SYMBOL_GPL(omap_dm_timer_request_specific);
215
216 int omap_dm_timer_free(struct omap_dm_timer *timer)
217 {
218         if (unlikely(!timer))
219                 return -EINVAL;
220
221         clk_put(timer->fclk);
222
223         WARN_ON(!timer->reserved);
224         timer->reserved = 0;
225         return 0;
226 }
227 EXPORT_SYMBOL_GPL(omap_dm_timer_free);
228
229 void omap_dm_timer_enable(struct omap_dm_timer *timer)
230 {
231         pm_runtime_get_sync(&timer->pdev->dev);
232 }
233 EXPORT_SYMBOL_GPL(omap_dm_timer_enable);
234
235 void omap_dm_timer_disable(struct omap_dm_timer *timer)
236 {
237         pm_runtime_put_sync(&timer->pdev->dev);
238 }
239 EXPORT_SYMBOL_GPL(omap_dm_timer_disable);
240
241 int omap_dm_timer_get_irq(struct omap_dm_timer *timer)
242 {
243         if (timer)
244                 return timer->irq;
245         return -EINVAL;
246 }
247 EXPORT_SYMBOL_GPL(omap_dm_timer_get_irq);
248
249 #if defined(CONFIG_ARCH_OMAP1)
250
251 /**
252  * omap_dm_timer_modify_idlect_mask - Check if any running timers use ARMXOR
253  * @inputmask: current value of idlect mask
254  */
255 __u32 omap_dm_timer_modify_idlect_mask(__u32 inputmask)
256 {
257         int i = 0;
258         struct omap_dm_timer *timer = NULL;
259         unsigned long flags;
260
261         /* If ARMXOR cannot be idled this function call is unnecessary */
262         if (!(inputmask & (1 << 1)))
263                 return inputmask;
264
265         /* If any active timer is using ARMXOR return modified mask */
266         spin_lock_irqsave(&dm_timer_lock, flags);
267         list_for_each_entry(timer, &omap_timer_list, node) {
268                 u32 l;
269
270                 l = omap_dm_timer_read_reg(timer, OMAP_TIMER_CTRL_REG);
271                 if (l & OMAP_TIMER_CTRL_ST) {
272                         if (((omap_readl(MOD_CONF_CTRL_1) >> (i * 2)) & 0x03) == 0)
273                                 inputmask &= ~(1 << 1);
274                         else
275                                 inputmask &= ~(1 << 2);
276                 }
277                 i++;
278         }
279         spin_unlock_irqrestore(&dm_timer_lock, flags);
280
281         return inputmask;
282 }
283 EXPORT_SYMBOL_GPL(omap_dm_timer_modify_idlect_mask);
284
285 #else
286
287 struct clk *omap_dm_timer_get_fclk(struct omap_dm_timer *timer)
288 {
289         if (timer)
290                 return timer->fclk;
291         return NULL;
292 }
293 EXPORT_SYMBOL_GPL(omap_dm_timer_get_fclk);
294
295 __u32 omap_dm_timer_modify_idlect_mask(__u32 inputmask)
296 {
297         BUG();
298
299         return 0;
300 }
301 EXPORT_SYMBOL_GPL(omap_dm_timer_modify_idlect_mask);
302
303 #endif
304
305 int omap_dm_timer_trigger(struct omap_dm_timer *timer)
306 {
307         if (unlikely(!timer || pm_runtime_suspended(&timer->pdev->dev))) {
308                 pr_err("%s: timer not available or enabled.\n", __func__);
309                 return -EINVAL;
310         }
311
312         omap_dm_timer_write_reg(timer, OMAP_TIMER_TRIGGER_REG, 0);
313         return 0;
314 }
315 EXPORT_SYMBOL_GPL(omap_dm_timer_trigger);
316
317 int omap_dm_timer_start(struct omap_dm_timer *timer)
318 {
319         u32 l;
320
321         if (unlikely(!timer))
322                 return -EINVAL;
323
324         omap_dm_timer_enable(timer);
325
326         if (timer->loses_context) {
327                 u32 ctx_loss_cnt_after =
328                         timer->get_context_loss_count(&timer->pdev->dev);
329                 if (ctx_loss_cnt_after != timer->ctx_loss_count)
330                         omap_timer_restore_context(timer);
331         }
332
333         l = omap_dm_timer_read_reg(timer, OMAP_TIMER_CTRL_REG);
334         if (!(l & OMAP_TIMER_CTRL_ST)) {
335                 l |= OMAP_TIMER_CTRL_ST;
336                 omap_dm_timer_write_reg(timer, OMAP_TIMER_CTRL_REG, l);
337         }
338
339         /* Save the context */
340         timer->context.tclr = l;
341         return 0;
342 }
343 EXPORT_SYMBOL_GPL(omap_dm_timer_start);
344
345 int omap_dm_timer_stop(struct omap_dm_timer *timer)
346 {
347         unsigned long rate = 0;
348         struct dmtimer_platform_data *pdata = timer->pdev->dev.platform_data;
349
350         if (unlikely(!timer))
351                 return -EINVAL;
352
353         if (!pdata->needs_manual_reset)
354                 rate = clk_get_rate(timer->fclk);
355
356         __omap_dm_timer_stop(timer, timer->posted, rate);
357
358         if (timer->loses_context && timer->get_context_loss_count)
359                 timer->ctx_loss_count =
360                         timer->get_context_loss_count(&timer->pdev->dev);
361
362         /*
363          * Since the register values are computed and written within
364          * __omap_dm_timer_stop, we need to use read to retrieve the
365          * context.
366          */
367         timer->context.tclr =
368                         omap_dm_timer_read_reg(timer, OMAP_TIMER_CTRL_REG);
369         timer->context.tisr = __raw_readl(timer->irq_stat);
370         omap_dm_timer_disable(timer);
371         return 0;
372 }
373 EXPORT_SYMBOL_GPL(omap_dm_timer_stop);
374
375 int omap_dm_timer_set_source(struct omap_dm_timer *timer, int source)
376 {
377         int ret;
378         struct dmtimer_platform_data *pdata;
379
380         if (unlikely(!timer))
381                 return -EINVAL;
382
383         pdata = timer->pdev->dev.platform_data;
384
385         if (source < 0 || source >= 3)
386                 return -EINVAL;
387
388         ret = pdata->set_timer_src(timer->pdev, source);
389
390         return ret;
391 }
392 EXPORT_SYMBOL_GPL(omap_dm_timer_set_source);
393
394 int omap_dm_timer_set_load(struct omap_dm_timer *timer, int autoreload,
395                             unsigned int load)
396 {
397         u32 l;
398
399         if (unlikely(!timer))
400                 return -EINVAL;
401
402         omap_dm_timer_enable(timer);
403         l = omap_dm_timer_read_reg(timer, OMAP_TIMER_CTRL_REG);
404         if (autoreload)
405                 l |= OMAP_TIMER_CTRL_AR;
406         else
407                 l &= ~OMAP_TIMER_CTRL_AR;
408         omap_dm_timer_write_reg(timer, OMAP_TIMER_CTRL_REG, l);
409         omap_dm_timer_write_reg(timer, OMAP_TIMER_LOAD_REG, load);
410
411         omap_dm_timer_write_reg(timer, OMAP_TIMER_TRIGGER_REG, 0);
412         /* Save the context */
413         timer->context.tclr = l;
414         timer->context.tldr = load;
415         omap_dm_timer_disable(timer);
416         return 0;
417 }
418 EXPORT_SYMBOL_GPL(omap_dm_timer_set_load);
419
420 /* Optimized set_load which removes costly spin wait in timer_start */
421 int omap_dm_timer_set_load_start(struct omap_dm_timer *timer, int autoreload,
422                             unsigned int load)
423 {
424         u32 l;
425
426         if (unlikely(!timer))
427                 return -EINVAL;
428
429         omap_dm_timer_enable(timer);
430
431         if (timer->loses_context) {
432                 u32 ctx_loss_cnt_after =
433                         timer->get_context_loss_count(&timer->pdev->dev);
434                 if (ctx_loss_cnt_after != timer->ctx_loss_count)
435                         omap_timer_restore_context(timer);
436         }
437
438         l = omap_dm_timer_read_reg(timer, OMAP_TIMER_CTRL_REG);
439         if (autoreload) {
440                 l |= OMAP_TIMER_CTRL_AR;
441                 omap_dm_timer_write_reg(timer, OMAP_TIMER_LOAD_REG, load);
442         } else {
443                 l &= ~OMAP_TIMER_CTRL_AR;
444         }
445         l |= OMAP_TIMER_CTRL_ST;
446
447         __omap_dm_timer_load_start(timer, l, load, timer->posted);
448
449         /* Save the context */
450         timer->context.tclr = l;
451         timer->context.tldr = load;
452         timer->context.tcrr = load;
453         return 0;
454 }
455 EXPORT_SYMBOL_GPL(omap_dm_timer_set_load_start);
456
457 int omap_dm_timer_set_match(struct omap_dm_timer *timer, int enable,
458                              unsigned int match)
459 {
460         u32 l;
461
462         if (unlikely(!timer))
463                 return -EINVAL;
464
465         omap_dm_timer_enable(timer);
466         l = omap_dm_timer_read_reg(timer, OMAP_TIMER_CTRL_REG);
467         if (enable)
468                 l |= OMAP_TIMER_CTRL_CE;
469         else
470                 l &= ~OMAP_TIMER_CTRL_CE;
471         omap_dm_timer_write_reg(timer, OMAP_TIMER_CTRL_REG, l);
472         omap_dm_timer_write_reg(timer, OMAP_TIMER_MATCH_REG, match);
473
474         /* Save the context */
475         timer->context.tclr = l;
476         timer->context.tmar = match;
477         omap_dm_timer_disable(timer);
478         return 0;
479 }
480 EXPORT_SYMBOL_GPL(omap_dm_timer_set_match);
481
482 int omap_dm_timer_set_pwm(struct omap_dm_timer *timer, int def_on,
483                            int toggle, int trigger)
484 {
485         u32 l;
486
487         if (unlikely(!timer))
488                 return -EINVAL;
489
490         omap_dm_timer_enable(timer);
491         l = omap_dm_timer_read_reg(timer, OMAP_TIMER_CTRL_REG);
492         l &= ~(OMAP_TIMER_CTRL_GPOCFG | OMAP_TIMER_CTRL_SCPWM |
493                OMAP_TIMER_CTRL_PT | (0x03 << 10));
494         if (def_on)
495                 l |= OMAP_TIMER_CTRL_SCPWM;
496         if (toggle)
497                 l |= OMAP_TIMER_CTRL_PT;
498         l |= trigger << 10;
499         omap_dm_timer_write_reg(timer, OMAP_TIMER_CTRL_REG, l);
500
501         /* Save the context */
502         timer->context.tclr = l;
503         omap_dm_timer_disable(timer);
504         return 0;
505 }
506 EXPORT_SYMBOL_GPL(omap_dm_timer_set_pwm);
507
508 int omap_dm_timer_set_prescaler(struct omap_dm_timer *timer, int prescaler)
509 {
510         u32 l;
511
512         if (unlikely(!timer))
513                 return -EINVAL;
514
515         omap_dm_timer_enable(timer);
516         l = omap_dm_timer_read_reg(timer, OMAP_TIMER_CTRL_REG);
517         l &= ~(OMAP_TIMER_CTRL_PRE | (0x07 << 2));
518         if (prescaler >= 0x00 && prescaler <= 0x07) {
519                 l |= OMAP_TIMER_CTRL_PRE;
520                 l |= prescaler << 2;
521         }
522         omap_dm_timer_write_reg(timer, OMAP_TIMER_CTRL_REG, l);
523
524         /* Save the context */
525         timer->context.tclr = l;
526         omap_dm_timer_disable(timer);
527         return 0;
528 }
529 EXPORT_SYMBOL_GPL(omap_dm_timer_set_prescaler);
530
531 int omap_dm_timer_set_int_enable(struct omap_dm_timer *timer,
532                                   unsigned int value)
533 {
534         if (unlikely(!timer))
535                 return -EINVAL;
536
537         omap_dm_timer_enable(timer);
538         __omap_dm_timer_int_enable(timer, value);
539
540         /* Save the context */
541         timer->context.tier = value;
542         timer->context.twer = value;
543         omap_dm_timer_disable(timer);
544         return 0;
545 }
546 EXPORT_SYMBOL_GPL(omap_dm_timer_set_int_enable);
547
548 unsigned int omap_dm_timer_read_status(struct omap_dm_timer *timer)
549 {
550         unsigned int l;
551
552         if (unlikely(!timer || pm_runtime_suspended(&timer->pdev->dev))) {
553                 pr_err("%s: timer not available or enabled.\n", __func__);
554                 return 0;
555         }
556
557         l = __raw_readl(timer->irq_stat);
558
559         return l;
560 }
561 EXPORT_SYMBOL_GPL(omap_dm_timer_read_status);
562
563 int omap_dm_timer_write_status(struct omap_dm_timer *timer, unsigned int value)
564 {
565         if (unlikely(!timer || pm_runtime_suspended(&timer->pdev->dev)))
566                 return -EINVAL;
567
568         __omap_dm_timer_write_status(timer, value);
569         /* Save the context */
570         timer->context.tisr = value;
571         return 0;
572 }
573 EXPORT_SYMBOL_GPL(omap_dm_timer_write_status);
574
575 unsigned int omap_dm_timer_read_counter(struct omap_dm_timer *timer)
576 {
577         if (unlikely(!timer || pm_runtime_suspended(&timer->pdev->dev))) {
578                 pr_err("%s: timer not iavailable or enabled.\n", __func__);
579                 return 0;
580         }
581
582         return __omap_dm_timer_read_counter(timer, timer->posted);
583 }
584 EXPORT_SYMBOL_GPL(omap_dm_timer_read_counter);
585
586 int omap_dm_timer_write_counter(struct omap_dm_timer *timer, unsigned int value)
587 {
588         if (unlikely(!timer || pm_runtime_suspended(&timer->pdev->dev))) {
589                 pr_err("%s: timer not available or enabled.\n", __func__);
590                 return -EINVAL;
591         }
592
593         omap_dm_timer_write_reg(timer, OMAP_TIMER_COUNTER_REG, value);
594
595         /* Save the context */
596         timer->context.tcrr = value;
597         return 0;
598 }
599 EXPORT_SYMBOL_GPL(omap_dm_timer_write_counter);
600
601 int omap_dm_timers_active(void)
602 {
603         struct omap_dm_timer *timer;
604
605         list_for_each_entry(timer, &omap_timer_list, node) {
606                 if (!timer->reserved)
607                         continue;
608
609                 if (omap_dm_timer_read_reg(timer, OMAP_TIMER_CTRL_REG) &
610                     OMAP_TIMER_CTRL_ST) {
611                         return 1;
612                 }
613         }
614         return 0;
615 }
616 EXPORT_SYMBOL_GPL(omap_dm_timers_active);
617
618 /**
619  * omap_dm_timer_probe - probe function called for every registered device
620  * @pdev:       pointer to current timer platform device
621  *
622  * Called by driver framework at the end of device registration for all
623  * timer devices.
624  */
625 static int __devinit omap_dm_timer_probe(struct platform_device *pdev)
626 {
627         int ret;
628         unsigned long flags;
629         struct omap_dm_timer *timer;
630         struct resource *mem, *irq, *ioarea;
631         struct dmtimer_platform_data *pdata = pdev->dev.platform_data;
632
633         if (!pdata) {
634                 dev_err(&pdev->dev, "%s: no platform data.\n", __func__);
635                 return -ENODEV;
636         }
637
638         irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
639         if (unlikely(!irq)) {
640                 dev_err(&pdev->dev, "%s: no IRQ resource.\n", __func__);
641                 return -ENODEV;
642         }
643
644         mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
645         if (unlikely(!mem)) {
646                 dev_err(&pdev->dev, "%s: no memory resource.\n", __func__);
647                 return -ENODEV;
648         }
649
650         ioarea = request_mem_region(mem->start, resource_size(mem),
651                         pdev->name);
652         if (!ioarea) {
653                 dev_err(&pdev->dev, "%s: region already claimed.\n", __func__);
654                 return -EBUSY;
655         }
656
657         timer = kzalloc(sizeof(struct omap_dm_timer), GFP_KERNEL);
658         if (!timer) {
659                 dev_err(&pdev->dev, "%s: no memory for omap_dm_timer.\n",
660                         __func__);
661                 ret = -ENOMEM;
662                 goto err_free_ioregion;
663         }
664
665         timer->io_base = ioremap(mem->start, resource_size(mem));
666         if (!timer->io_base) {
667                 dev_err(&pdev->dev, "%s: ioremap failed.\n", __func__);
668                 ret = -ENOMEM;
669                 goto err_free_mem;
670         }
671
672         timer->id = pdev->id;
673         timer->irq = irq->start;
674         timer->reserved = pdata->reserved;
675         timer->pdev = pdev;
676         timer->loses_context = pdata->loses_context;
677         timer->get_context_loss_count = pdata->get_context_loss_count;
678
679         /* Skip pm_runtime_enable for OMAP1 */
680         if (!pdata->needs_manual_reset) {
681                 pm_runtime_enable(&pdev->dev);
682                 pm_runtime_irq_safe(&pdev->dev);
683         }
684
685         if (!timer->reserved) {
686                 pm_runtime_get_sync(&pdev->dev);
687                 __omap_dm_timer_init_regs(timer);
688                 pm_runtime_put(&pdev->dev);
689         }
690
691         /* add the timer element to the list */
692         spin_lock_irqsave(&dm_timer_lock, flags);
693         list_add_tail(&timer->node, &omap_timer_list);
694         spin_unlock_irqrestore(&dm_timer_lock, flags);
695
696         dev_dbg(&pdev->dev, "Device Probed.\n");
697
698         return 0;
699
700 err_free_mem:
701         kfree(timer);
702
703 err_free_ioregion:
704         release_mem_region(mem->start, resource_size(mem));
705
706         return ret;
707 }
708
709 /**
710  * omap_dm_timer_remove - cleanup a registered timer device
711  * @pdev:       pointer to current timer platform device
712  *
713  * Called by driver framework whenever a timer device is unregistered.
714  * In addition to freeing platform resources it also deletes the timer
715  * entry from the local list.
716  */
717 static int __devexit omap_dm_timer_remove(struct platform_device *pdev)
718 {
719         struct omap_dm_timer *timer;
720         unsigned long flags;
721         int ret = -EINVAL;
722
723         spin_lock_irqsave(&dm_timer_lock, flags);
724         list_for_each_entry(timer, &omap_timer_list, node)
725                 if (timer->pdev->id == pdev->id) {
726                         list_del(&timer->node);
727                         kfree(timer);
728                         ret = 0;
729                         break;
730                 }
731         spin_unlock_irqrestore(&dm_timer_lock, flags);
732
733         return ret;
734 }
735
736 static struct platform_driver omap_dm_timer_driver = {
737         .probe  = omap_dm_timer_probe,
738         .remove = __devexit_p(omap_dm_timer_remove),
739         .driver = {
740                 .name   = "omap_timer",
741         },
742 };
743
744 static int __init omap_dm_timer_driver_init(void)
745 {
746         return platform_driver_register(&omap_dm_timer_driver);
747 }
748
749 static void __exit omap_dm_timer_driver_exit(void)
750 {
751         platform_driver_unregister(&omap_dm_timer_driver);
752 }
753
754 early_platform_init("earlytimer", &omap_dm_timer_driver);
755 module_init(omap_dm_timer_driver_init);
756 module_exit(omap_dm_timer_driver_exit);
757
758 MODULE_DESCRIPTION("OMAP Dual-Mode Timer Driver");
759 MODULE_LICENSE("GPL");
760 MODULE_ALIAS("platform:" DRIVER_NAME);
761 MODULE_AUTHOR("Texas Instruments Inc");