Merge tag 'for_linus-4.15-rc2' of git://git.kernel.org/pub/scm/linux/kernel/git/jwess...
[sfrench/cifs-2.6.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/clk.h>
39 #include <linux/clk-provider.h>
40 #include <linux/module.h>
41 #include <linux/io.h>
42 #include <linux/device.h>
43 #include <linux/err.h>
44 #include <linux/pm_runtime.h>
45 #include <linux/of.h>
46 #include <linux/of_device.h>
47 #include <linux/platform_device.h>
48 #include <linux/platform_data/dmtimer-omap.h>
49
50 #include <plat/dmtimer.h>
51
52 static u32 omap_reserved_systimers;
53 static LIST_HEAD(omap_timer_list);
54 static DEFINE_SPINLOCK(dm_timer_lock);
55
56 enum {
57         REQUEST_ANY = 0,
58         REQUEST_BY_ID,
59         REQUEST_BY_CAP,
60         REQUEST_BY_NODE,
61 };
62
63 /**
64  * omap_dm_timer_read_reg - read timer registers in posted and non-posted mode
65  * @timer:      timer pointer over which read operation to perform
66  * @reg:        lowest byte holds the register offset
67  *
68  * The posted mode bit is encoded in reg. Note that in posted mode write
69  * pending bit must be checked. Otherwise a read of a non completed write
70  * will produce an error.
71  */
72 static inline u32 omap_dm_timer_read_reg(struct omap_dm_timer *timer, u32 reg)
73 {
74         WARN_ON((reg & 0xff) < _OMAP_TIMER_WAKEUP_EN_OFFSET);
75         return __omap_dm_timer_read(timer, reg, timer->posted);
76 }
77
78 /**
79  * omap_dm_timer_write_reg - write timer registers in posted and non-posted mode
80  * @timer:      timer pointer over which write operation is to perform
81  * @reg:        lowest byte holds the register offset
82  * @value:      data to write into the register
83  *
84  * The posted mode bit is encoded in reg. Note that in posted mode the write
85  * pending bit must be checked. Otherwise a write on a register which has a
86  * pending write will be lost.
87  */
88 static void omap_dm_timer_write_reg(struct omap_dm_timer *timer, u32 reg,
89                                                 u32 value)
90 {
91         WARN_ON((reg & 0xff) < _OMAP_TIMER_WAKEUP_EN_OFFSET);
92         __omap_dm_timer_write(timer, reg, value, timer->posted);
93 }
94
95 static void omap_timer_restore_context(struct omap_dm_timer *timer)
96 {
97         omap_dm_timer_write_reg(timer, OMAP_TIMER_WAKEUP_EN_REG,
98                                 timer->context.twer);
99         omap_dm_timer_write_reg(timer, OMAP_TIMER_COUNTER_REG,
100                                 timer->context.tcrr);
101         omap_dm_timer_write_reg(timer, OMAP_TIMER_LOAD_REG,
102                                 timer->context.tldr);
103         omap_dm_timer_write_reg(timer, OMAP_TIMER_MATCH_REG,
104                                 timer->context.tmar);
105         omap_dm_timer_write_reg(timer, OMAP_TIMER_IF_CTRL_REG,
106                                 timer->context.tsicr);
107         writel_relaxed(timer->context.tier, timer->irq_ena);
108         omap_dm_timer_write_reg(timer, OMAP_TIMER_CTRL_REG,
109                                 timer->context.tclr);
110 }
111
112 static int omap_dm_timer_reset(struct omap_dm_timer *timer)
113 {
114         u32 l, timeout = 100000;
115
116         if (timer->revision != 1)
117                 return -EINVAL;
118
119         omap_dm_timer_write_reg(timer, OMAP_TIMER_IF_CTRL_REG, 0x06);
120
121         do {
122                 l = __omap_dm_timer_read(timer,
123                                          OMAP_TIMER_V1_SYS_STAT_OFFSET, 0);
124         } while (!l && timeout--);
125
126         if (!timeout) {
127                 dev_err(&timer->pdev->dev, "Timer failed to reset\n");
128                 return -ETIMEDOUT;
129         }
130
131         /* Configure timer for smart-idle mode */
132         l = __omap_dm_timer_read(timer, OMAP_TIMER_OCP_CFG_OFFSET, 0);
133         l |= 0x2 << 0x3;
134         __omap_dm_timer_write(timer, OMAP_TIMER_OCP_CFG_OFFSET, l, 0);
135
136         timer->posted = 0;
137
138         return 0;
139 }
140
141 static int omap_dm_timer_of_set_source(struct omap_dm_timer *timer)
142 {
143         int ret;
144         struct clk *parent;
145
146         /*
147          * FIXME: OMAP1 devices do not use the clock framework for dmtimers so
148          * do not call clk_get() for these devices.
149          */
150         if (!timer->fclk)
151                 return -ENODEV;
152
153         parent = clk_get(&timer->pdev->dev, NULL);
154         if (IS_ERR(parent))
155                 return -ENODEV;
156
157         ret = clk_set_parent(timer->fclk, parent);
158         if (ret < 0)
159                 pr_err("%s: failed to set parent\n", __func__);
160
161         clk_put(parent);
162
163         return ret;
164 }
165
166 static int omap_dm_timer_prepare(struct omap_dm_timer *timer)
167 {
168         int rc;
169
170         /*
171          * FIXME: OMAP1 devices do not use the clock framework for dmtimers so
172          * do not call clk_get() for these devices.
173          */
174         if (!(timer->capability & OMAP_TIMER_NEEDS_RESET)) {
175                 timer->fclk = clk_get(&timer->pdev->dev, "fck");
176                 if (WARN_ON_ONCE(IS_ERR(timer->fclk))) {
177                         dev_err(&timer->pdev->dev, ": No fclk handle.\n");
178                         return -EINVAL;
179                 }
180         }
181
182         omap_dm_timer_enable(timer);
183
184         if (timer->capability & OMAP_TIMER_NEEDS_RESET) {
185                 rc = omap_dm_timer_reset(timer);
186                 if (rc) {
187                         omap_dm_timer_disable(timer);
188                         return rc;
189                 }
190         }
191
192         __omap_dm_timer_enable_posted(timer);
193         omap_dm_timer_disable(timer);
194
195         rc = omap_dm_timer_of_set_source(timer);
196         if (rc == -ENODEV)
197                 return omap_dm_timer_set_source(timer, OMAP_TIMER_SRC_32_KHZ);
198
199         return rc;
200 }
201
202 static inline u32 omap_dm_timer_reserved_systimer(int id)
203 {
204         return (omap_reserved_systimers & (1 << (id - 1))) ? 1 : 0;
205 }
206
207 int omap_dm_timer_reserve_systimer(int id)
208 {
209         if (omap_dm_timer_reserved_systimer(id))
210                 return -ENODEV;
211
212         omap_reserved_systimers |= (1 << (id - 1));
213
214         return 0;
215 }
216
217 static struct omap_dm_timer *_omap_dm_timer_request(int req_type, void *data)
218 {
219         struct omap_dm_timer *timer = NULL, *t;
220         struct device_node *np = NULL;
221         unsigned long flags;
222         u32 cap = 0;
223         int id = 0;
224
225         switch (req_type) {
226         case REQUEST_BY_ID:
227                 id = *(int *)data;
228                 break;
229         case REQUEST_BY_CAP:
230                 cap = *(u32 *)data;
231                 break;
232         case REQUEST_BY_NODE:
233                 np = (struct device_node *)data;
234                 break;
235         default:
236                 /* REQUEST_ANY */
237                 break;
238         }
239
240         spin_lock_irqsave(&dm_timer_lock, flags);
241         list_for_each_entry(t, &omap_timer_list, node) {
242                 if (t->reserved)
243                         continue;
244
245                 switch (req_type) {
246                 case REQUEST_BY_ID:
247                         if (id == t->pdev->id) {
248                                 timer = t;
249                                 timer->reserved = 1;
250                                 goto found;
251                         }
252                         break;
253                 case REQUEST_BY_CAP:
254                         if (cap == (t->capability & cap)) {
255                                 /*
256                                  * If timer is not NULL, we have already found
257                                  * one timer. But it was not an exact match
258                                  * because it had more capabilities than what
259                                  * was required. Therefore, unreserve the last
260                                  * timer found and see if this one is a better
261                                  * match.
262                                  */
263                                 if (timer)
264                                         timer->reserved = 0;
265                                 timer = t;
266                                 timer->reserved = 1;
267
268                                 /* Exit loop early if we find an exact match */
269                                 if (t->capability == cap)
270                                         goto found;
271                         }
272                         break;
273                 case REQUEST_BY_NODE:
274                         if (np == t->pdev->dev.of_node) {
275                                 timer = t;
276                                 timer->reserved = 1;
277                                 goto found;
278                         }
279                         break;
280                 default:
281                         /* REQUEST_ANY */
282                         timer = t;
283                         timer->reserved = 1;
284                         goto found;
285                 }
286         }
287 found:
288         spin_unlock_irqrestore(&dm_timer_lock, flags);
289
290         if (timer && omap_dm_timer_prepare(timer)) {
291                 timer->reserved = 0;
292                 timer = NULL;
293         }
294
295         if (!timer)
296                 pr_debug("%s: timer request failed!\n", __func__);
297
298         return timer;
299 }
300
301 struct omap_dm_timer *omap_dm_timer_request(void)
302 {
303         return _omap_dm_timer_request(REQUEST_ANY, NULL);
304 }
305 EXPORT_SYMBOL_GPL(omap_dm_timer_request);
306
307 struct omap_dm_timer *omap_dm_timer_request_specific(int id)
308 {
309         /* Requesting timer by ID is not supported when device tree is used */
310         if (of_have_populated_dt()) {
311                 pr_warn("%s: Please use omap_dm_timer_request_by_cap/node()\n",
312                         __func__);
313                 return NULL;
314         }
315
316         return _omap_dm_timer_request(REQUEST_BY_ID, &id);
317 }
318 EXPORT_SYMBOL_GPL(omap_dm_timer_request_specific);
319
320 /**
321  * omap_dm_timer_request_by_cap - Request a timer by capability
322  * @cap:        Bit mask of capabilities to match
323  *
324  * Find a timer based upon capabilities bit mask. Callers of this function
325  * should use the definitions found in the plat/dmtimer.h file under the
326  * comment "timer capabilities used in hwmod database". Returns pointer to
327  * timer handle on success and a NULL pointer on failure.
328  */
329 struct omap_dm_timer *omap_dm_timer_request_by_cap(u32 cap)
330 {
331         return _omap_dm_timer_request(REQUEST_BY_CAP, &cap);
332 }
333 EXPORT_SYMBOL_GPL(omap_dm_timer_request_by_cap);
334
335 /**
336  * omap_dm_timer_request_by_node - Request a timer by device-tree node
337  * @np:         Pointer to device-tree timer node
338  *
339  * Request a timer based upon a device node pointer. Returns pointer to
340  * timer handle on success and a NULL pointer on failure.
341  */
342 struct omap_dm_timer *omap_dm_timer_request_by_node(struct device_node *np)
343 {
344         if (!np)
345                 return NULL;
346
347         return _omap_dm_timer_request(REQUEST_BY_NODE, np);
348 }
349 EXPORT_SYMBOL_GPL(omap_dm_timer_request_by_node);
350
351 int omap_dm_timer_free(struct omap_dm_timer *timer)
352 {
353         if (unlikely(!timer))
354                 return -EINVAL;
355
356         clk_put(timer->fclk);
357
358         WARN_ON(!timer->reserved);
359         timer->reserved = 0;
360         return 0;
361 }
362 EXPORT_SYMBOL_GPL(omap_dm_timer_free);
363
364 void omap_dm_timer_enable(struct omap_dm_timer *timer)
365 {
366         int c;
367
368         pm_runtime_get_sync(&timer->pdev->dev);
369
370         if (!(timer->capability & OMAP_TIMER_ALWON)) {
371                 if (timer->get_context_loss_count) {
372                         c = timer->get_context_loss_count(&timer->pdev->dev);
373                         if (c != timer->ctx_loss_count) {
374                                 omap_timer_restore_context(timer);
375                                 timer->ctx_loss_count = c;
376                         }
377                 } else {
378                         omap_timer_restore_context(timer);
379                 }
380         }
381 }
382 EXPORT_SYMBOL_GPL(omap_dm_timer_enable);
383
384 void omap_dm_timer_disable(struct omap_dm_timer *timer)
385 {
386         pm_runtime_put_sync(&timer->pdev->dev);
387 }
388 EXPORT_SYMBOL_GPL(omap_dm_timer_disable);
389
390 int omap_dm_timer_get_irq(struct omap_dm_timer *timer)
391 {
392         if (timer)
393                 return timer->irq;
394         return -EINVAL;
395 }
396 EXPORT_SYMBOL_GPL(omap_dm_timer_get_irq);
397
398 #if defined(CONFIG_ARCH_OMAP1)
399 #include <mach/hardware.h>
400 /**
401  * omap_dm_timer_modify_idlect_mask - Check if any running timers use ARMXOR
402  * @inputmask: current value of idlect mask
403  */
404 __u32 omap_dm_timer_modify_idlect_mask(__u32 inputmask)
405 {
406         int i = 0;
407         struct omap_dm_timer *timer = NULL;
408         unsigned long flags;
409
410         /* If ARMXOR cannot be idled this function call is unnecessary */
411         if (!(inputmask & (1 << 1)))
412                 return inputmask;
413
414         /* If any active timer is using ARMXOR return modified mask */
415         spin_lock_irqsave(&dm_timer_lock, flags);
416         list_for_each_entry(timer, &omap_timer_list, node) {
417                 u32 l;
418
419                 l = omap_dm_timer_read_reg(timer, OMAP_TIMER_CTRL_REG);
420                 if (l & OMAP_TIMER_CTRL_ST) {
421                         if (((omap_readl(MOD_CONF_CTRL_1) >> (i * 2)) & 0x03) == 0)
422                                 inputmask &= ~(1 << 1);
423                         else
424                                 inputmask &= ~(1 << 2);
425                 }
426                 i++;
427         }
428         spin_unlock_irqrestore(&dm_timer_lock, flags);
429
430         return inputmask;
431 }
432 EXPORT_SYMBOL_GPL(omap_dm_timer_modify_idlect_mask);
433
434 #else
435
436 struct clk *omap_dm_timer_get_fclk(struct omap_dm_timer *timer)
437 {
438         if (timer && !IS_ERR(timer->fclk))
439                 return timer->fclk;
440         return NULL;
441 }
442 EXPORT_SYMBOL_GPL(omap_dm_timer_get_fclk);
443
444 __u32 omap_dm_timer_modify_idlect_mask(__u32 inputmask)
445 {
446         BUG();
447
448         return 0;
449 }
450 EXPORT_SYMBOL_GPL(omap_dm_timer_modify_idlect_mask);
451
452 #endif
453
454 int omap_dm_timer_trigger(struct omap_dm_timer *timer)
455 {
456         if (unlikely(!timer || pm_runtime_suspended(&timer->pdev->dev))) {
457                 pr_err("%s: timer not available or enabled.\n", __func__);
458                 return -EINVAL;
459         }
460
461         omap_dm_timer_write_reg(timer, OMAP_TIMER_TRIGGER_REG, 0);
462         return 0;
463 }
464 EXPORT_SYMBOL_GPL(omap_dm_timer_trigger);
465
466 int omap_dm_timer_start(struct omap_dm_timer *timer)
467 {
468         u32 l;
469
470         if (unlikely(!timer))
471                 return -EINVAL;
472
473         omap_dm_timer_enable(timer);
474
475         l = omap_dm_timer_read_reg(timer, OMAP_TIMER_CTRL_REG);
476         if (!(l & OMAP_TIMER_CTRL_ST)) {
477                 l |= OMAP_TIMER_CTRL_ST;
478                 omap_dm_timer_write_reg(timer, OMAP_TIMER_CTRL_REG, l);
479         }
480
481         /* Save the context */
482         timer->context.tclr = l;
483         return 0;
484 }
485 EXPORT_SYMBOL_GPL(omap_dm_timer_start);
486
487 int omap_dm_timer_stop(struct omap_dm_timer *timer)
488 {
489         unsigned long rate = 0;
490
491         if (unlikely(!timer))
492                 return -EINVAL;
493
494         if (!(timer->capability & OMAP_TIMER_NEEDS_RESET))
495                 rate = clk_get_rate(timer->fclk);
496
497         __omap_dm_timer_stop(timer, timer->posted, rate);
498
499         /*
500          * Since the register values are computed and written within
501          * __omap_dm_timer_stop, we need to use read to retrieve the
502          * context.
503          */
504         timer->context.tclr =
505                         omap_dm_timer_read_reg(timer, OMAP_TIMER_CTRL_REG);
506         omap_dm_timer_disable(timer);
507         return 0;
508 }
509 EXPORT_SYMBOL_GPL(omap_dm_timer_stop);
510
511 int omap_dm_timer_set_source(struct omap_dm_timer *timer, int source)
512 {
513         int ret;
514         char *parent_name = NULL;
515         struct clk *parent;
516         struct dmtimer_platform_data *pdata;
517
518         if (unlikely(!timer))
519                 return -EINVAL;
520
521         pdata = timer->pdev->dev.platform_data;
522
523         if (source < 0 || source >= 3)
524                 return -EINVAL;
525
526         /*
527          * FIXME: Used for OMAP1 devices only because they do not currently
528          * use the clock framework to set the parent clock. To be removed
529          * once OMAP1 migrated to using clock framework for dmtimers
530          */
531         if (pdata && pdata->set_timer_src)
532                 return pdata->set_timer_src(timer->pdev, source);
533
534         if (IS_ERR(timer->fclk))
535                 return -EINVAL;
536
537 #if defined(CONFIG_COMMON_CLK)
538         /* Check if the clock has configurable parents */
539         if (clk_hw_get_num_parents(__clk_get_hw(timer->fclk)) < 2)
540                 return 0;
541 #endif
542
543         switch (source) {
544         case OMAP_TIMER_SRC_SYS_CLK:
545                 parent_name = "timer_sys_ck";
546                 break;
547
548         case OMAP_TIMER_SRC_32_KHZ:
549                 parent_name = "timer_32k_ck";
550                 break;
551
552         case OMAP_TIMER_SRC_EXT_CLK:
553                 parent_name = "timer_ext_ck";
554                 break;
555         }
556
557         parent = clk_get(&timer->pdev->dev, parent_name);
558         if (IS_ERR(parent)) {
559                 pr_err("%s: %s not found\n", __func__, parent_name);
560                 return -EINVAL;
561         }
562
563         ret = clk_set_parent(timer->fclk, parent);
564         if (ret < 0)
565                 pr_err("%s: failed to set %s as parent\n", __func__,
566                         parent_name);
567
568         clk_put(parent);
569
570         return ret;
571 }
572 EXPORT_SYMBOL_GPL(omap_dm_timer_set_source);
573
574 int omap_dm_timer_set_load(struct omap_dm_timer *timer, int autoreload,
575                             unsigned int load)
576 {
577         u32 l;
578
579         if (unlikely(!timer))
580                 return -EINVAL;
581
582         omap_dm_timer_enable(timer);
583         l = omap_dm_timer_read_reg(timer, OMAP_TIMER_CTRL_REG);
584         if (autoreload)
585                 l |= OMAP_TIMER_CTRL_AR;
586         else
587                 l &= ~OMAP_TIMER_CTRL_AR;
588         omap_dm_timer_write_reg(timer, OMAP_TIMER_CTRL_REG, l);
589         omap_dm_timer_write_reg(timer, OMAP_TIMER_LOAD_REG, load);
590
591         omap_dm_timer_write_reg(timer, OMAP_TIMER_TRIGGER_REG, 0);
592         /* Save the context */
593         timer->context.tclr = l;
594         timer->context.tldr = load;
595         omap_dm_timer_disable(timer);
596         return 0;
597 }
598 EXPORT_SYMBOL_GPL(omap_dm_timer_set_load);
599
600 /* Optimized set_load which removes costly spin wait in timer_start */
601 int omap_dm_timer_set_load_start(struct omap_dm_timer *timer, int autoreload,
602                             unsigned int load)
603 {
604         u32 l;
605
606         if (unlikely(!timer))
607                 return -EINVAL;
608
609         omap_dm_timer_enable(timer);
610
611         l = omap_dm_timer_read_reg(timer, OMAP_TIMER_CTRL_REG);
612         if (autoreload) {
613                 l |= OMAP_TIMER_CTRL_AR;
614                 omap_dm_timer_write_reg(timer, OMAP_TIMER_LOAD_REG, load);
615         } else {
616                 l &= ~OMAP_TIMER_CTRL_AR;
617         }
618         l |= OMAP_TIMER_CTRL_ST;
619
620         __omap_dm_timer_load_start(timer, l, load, timer->posted);
621
622         /* Save the context */
623         timer->context.tclr = l;
624         timer->context.tldr = load;
625         timer->context.tcrr = load;
626         return 0;
627 }
628 EXPORT_SYMBOL_GPL(omap_dm_timer_set_load_start);
629
630 int omap_dm_timer_set_match(struct omap_dm_timer *timer, int enable,
631                              unsigned int match)
632 {
633         u32 l;
634
635         if (unlikely(!timer))
636                 return -EINVAL;
637
638         omap_dm_timer_enable(timer);
639         l = omap_dm_timer_read_reg(timer, OMAP_TIMER_CTRL_REG);
640         if (enable)
641                 l |= OMAP_TIMER_CTRL_CE;
642         else
643                 l &= ~OMAP_TIMER_CTRL_CE;
644         omap_dm_timer_write_reg(timer, OMAP_TIMER_MATCH_REG, match);
645         omap_dm_timer_write_reg(timer, OMAP_TIMER_CTRL_REG, l);
646
647         /* Save the context */
648         timer->context.tclr = l;
649         timer->context.tmar = match;
650         omap_dm_timer_disable(timer);
651         return 0;
652 }
653 EXPORT_SYMBOL_GPL(omap_dm_timer_set_match);
654
655 int omap_dm_timer_set_pwm(struct omap_dm_timer *timer, int def_on,
656                            int toggle, int trigger)
657 {
658         u32 l;
659
660         if (unlikely(!timer))
661                 return -EINVAL;
662
663         omap_dm_timer_enable(timer);
664         l = omap_dm_timer_read_reg(timer, OMAP_TIMER_CTRL_REG);
665         l &= ~(OMAP_TIMER_CTRL_GPOCFG | OMAP_TIMER_CTRL_SCPWM |
666                OMAP_TIMER_CTRL_PT | (0x03 << 10));
667         if (def_on)
668                 l |= OMAP_TIMER_CTRL_SCPWM;
669         if (toggle)
670                 l |= OMAP_TIMER_CTRL_PT;
671         l |= trigger << 10;
672         omap_dm_timer_write_reg(timer, OMAP_TIMER_CTRL_REG, l);
673
674         /* Save the context */
675         timer->context.tclr = l;
676         omap_dm_timer_disable(timer);
677         return 0;
678 }
679 EXPORT_SYMBOL_GPL(omap_dm_timer_set_pwm);
680
681 int omap_dm_timer_set_prescaler(struct omap_dm_timer *timer, int prescaler)
682 {
683         u32 l;
684
685         if (unlikely(!timer))
686                 return -EINVAL;
687
688         omap_dm_timer_enable(timer);
689         l = omap_dm_timer_read_reg(timer, OMAP_TIMER_CTRL_REG);
690         l &= ~(OMAP_TIMER_CTRL_PRE | (0x07 << 2));
691         if (prescaler >= 0x00 && prescaler <= 0x07) {
692                 l |= OMAP_TIMER_CTRL_PRE;
693                 l |= prescaler << 2;
694         }
695         omap_dm_timer_write_reg(timer, OMAP_TIMER_CTRL_REG, l);
696
697         /* Save the context */
698         timer->context.tclr = l;
699         omap_dm_timer_disable(timer);
700         return 0;
701 }
702 EXPORT_SYMBOL_GPL(omap_dm_timer_set_prescaler);
703
704 int omap_dm_timer_set_int_enable(struct omap_dm_timer *timer,
705                                   unsigned int value)
706 {
707         if (unlikely(!timer))
708                 return -EINVAL;
709
710         omap_dm_timer_enable(timer);
711         __omap_dm_timer_int_enable(timer, value);
712
713         /* Save the context */
714         timer->context.tier = value;
715         timer->context.twer = value;
716         omap_dm_timer_disable(timer);
717         return 0;
718 }
719 EXPORT_SYMBOL_GPL(omap_dm_timer_set_int_enable);
720
721 /**
722  * omap_dm_timer_set_int_disable - disable timer interrupts
723  * @timer:      pointer to timer handle
724  * @mask:       bit mask of interrupts to be disabled
725  *
726  * Disables the specified timer interrupts for a timer.
727  */
728 int omap_dm_timer_set_int_disable(struct omap_dm_timer *timer, u32 mask)
729 {
730         u32 l = mask;
731
732         if (unlikely(!timer))
733                 return -EINVAL;
734
735         omap_dm_timer_enable(timer);
736
737         if (timer->revision == 1)
738                 l = readl_relaxed(timer->irq_ena) & ~mask;
739
740         writel_relaxed(l, timer->irq_dis);
741         l = omap_dm_timer_read_reg(timer, OMAP_TIMER_WAKEUP_EN_REG) & ~mask;
742         omap_dm_timer_write_reg(timer, OMAP_TIMER_WAKEUP_EN_REG, l);
743
744         /* Save the context */
745         timer->context.tier &= ~mask;
746         timer->context.twer &= ~mask;
747         omap_dm_timer_disable(timer);
748         return 0;
749 }
750 EXPORT_SYMBOL_GPL(omap_dm_timer_set_int_disable);
751
752 unsigned int omap_dm_timer_read_status(struct omap_dm_timer *timer)
753 {
754         unsigned int l;
755
756         if (unlikely(!timer || pm_runtime_suspended(&timer->pdev->dev))) {
757                 pr_err("%s: timer not available or enabled.\n", __func__);
758                 return 0;
759         }
760
761         l = readl_relaxed(timer->irq_stat);
762
763         return l;
764 }
765 EXPORT_SYMBOL_GPL(omap_dm_timer_read_status);
766
767 int omap_dm_timer_write_status(struct omap_dm_timer *timer, unsigned int value)
768 {
769         if (unlikely(!timer || pm_runtime_suspended(&timer->pdev->dev)))
770                 return -EINVAL;
771
772         __omap_dm_timer_write_status(timer, value);
773
774         return 0;
775 }
776 EXPORT_SYMBOL_GPL(omap_dm_timer_write_status);
777
778 unsigned int omap_dm_timer_read_counter(struct omap_dm_timer *timer)
779 {
780         if (unlikely(!timer || pm_runtime_suspended(&timer->pdev->dev))) {
781                 pr_err("%s: timer not iavailable or enabled.\n", __func__);
782                 return 0;
783         }
784
785         return __omap_dm_timer_read_counter(timer, timer->posted);
786 }
787 EXPORT_SYMBOL_GPL(omap_dm_timer_read_counter);
788
789 int omap_dm_timer_write_counter(struct omap_dm_timer *timer, unsigned int value)
790 {
791         if (unlikely(!timer || pm_runtime_suspended(&timer->pdev->dev))) {
792                 pr_err("%s: timer not available or enabled.\n", __func__);
793                 return -EINVAL;
794         }
795
796         omap_dm_timer_write_reg(timer, OMAP_TIMER_COUNTER_REG, value);
797
798         /* Save the context */
799         timer->context.tcrr = value;
800         return 0;
801 }
802 EXPORT_SYMBOL_GPL(omap_dm_timer_write_counter);
803
804 int omap_dm_timers_active(void)
805 {
806         struct omap_dm_timer *timer;
807
808         list_for_each_entry(timer, &omap_timer_list, node) {
809                 if (!timer->reserved)
810                         continue;
811
812                 if (omap_dm_timer_read_reg(timer, OMAP_TIMER_CTRL_REG) &
813                     OMAP_TIMER_CTRL_ST) {
814                         return 1;
815                 }
816         }
817         return 0;
818 }
819 EXPORT_SYMBOL_GPL(omap_dm_timers_active);
820
821 static const struct of_device_id omap_timer_match[];
822
823 /**
824  * omap_dm_timer_probe - probe function called for every registered device
825  * @pdev:       pointer to current timer platform device
826  *
827  * Called by driver framework at the end of device registration for all
828  * timer devices.
829  */
830 static int omap_dm_timer_probe(struct platform_device *pdev)
831 {
832         unsigned long flags;
833         struct omap_dm_timer *timer;
834         struct resource *mem, *irq;
835         struct device *dev = &pdev->dev;
836         const struct of_device_id *match;
837         const struct dmtimer_platform_data *pdata;
838         int ret;
839
840         match = of_match_device(of_match_ptr(omap_timer_match), dev);
841         pdata = match ? match->data : dev->platform_data;
842
843         if (!pdata && !dev->of_node) {
844                 dev_err(dev, "%s: no platform data.\n", __func__);
845                 return -ENODEV;
846         }
847
848         irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
849         if (unlikely(!irq)) {
850                 dev_err(dev, "%s: no IRQ resource.\n", __func__);
851                 return -ENODEV;
852         }
853
854         mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
855         if (unlikely(!mem)) {
856                 dev_err(dev, "%s: no memory resource.\n", __func__);
857                 return -ENODEV;
858         }
859
860         timer = devm_kzalloc(dev, sizeof(*timer), GFP_KERNEL);
861         if (!timer)
862                 return  -ENOMEM;
863
864         timer->fclk = ERR_PTR(-ENODEV);
865         timer->io_base = devm_ioremap_resource(dev, mem);
866         if (IS_ERR(timer->io_base))
867                 return PTR_ERR(timer->io_base);
868
869         if (dev->of_node) {
870                 if (of_find_property(dev->of_node, "ti,timer-alwon", NULL))
871                         timer->capability |= OMAP_TIMER_ALWON;
872                 if (of_find_property(dev->of_node, "ti,timer-dsp", NULL))
873                         timer->capability |= OMAP_TIMER_HAS_DSP_IRQ;
874                 if (of_find_property(dev->of_node, "ti,timer-pwm", NULL))
875                         timer->capability |= OMAP_TIMER_HAS_PWM;
876                 if (of_find_property(dev->of_node, "ti,timer-secure", NULL))
877                         timer->capability |= OMAP_TIMER_SECURE;
878         } else {
879                 timer->id = pdev->id;
880                 timer->capability = pdata->timer_capability;
881                 timer->reserved = omap_dm_timer_reserved_systimer(timer->id);
882                 timer->get_context_loss_count = pdata->get_context_loss_count;
883         }
884
885         if (pdata)
886                 timer->errata = pdata->timer_errata;
887
888         timer->irq = irq->start;
889         timer->pdev = pdev;
890
891         /* Skip pm_runtime_enable for OMAP1 */
892         if (!(timer->capability & OMAP_TIMER_NEEDS_RESET)) {
893                 pm_runtime_enable(dev);
894                 pm_runtime_irq_safe(dev);
895         }
896
897         if (!timer->reserved) {
898                 ret = pm_runtime_get_sync(dev);
899                 if (ret < 0) {
900                         dev_err(dev, "%s: pm_runtime_get_sync failed!\n",
901                                 __func__);
902                         goto err_get_sync;
903                 }
904                 __omap_dm_timer_init_regs(timer);
905                 pm_runtime_put(dev);
906         }
907
908         /* add the timer element to the list */
909         spin_lock_irqsave(&dm_timer_lock, flags);
910         list_add_tail(&timer->node, &omap_timer_list);
911         spin_unlock_irqrestore(&dm_timer_lock, flags);
912
913         dev_dbg(dev, "Device Probed.\n");
914
915         return 0;
916
917 err_get_sync:
918         pm_runtime_put_noidle(dev);
919         pm_runtime_disable(dev);
920         return ret;
921 }
922
923 /**
924  * omap_dm_timer_remove - cleanup a registered timer device
925  * @pdev:       pointer to current timer platform device
926  *
927  * Called by driver framework whenever a timer device is unregistered.
928  * In addition to freeing platform resources it also deletes the timer
929  * entry from the local list.
930  */
931 static int omap_dm_timer_remove(struct platform_device *pdev)
932 {
933         struct omap_dm_timer *timer;
934         unsigned long flags;
935         int ret = -EINVAL;
936
937         spin_lock_irqsave(&dm_timer_lock, flags);
938         list_for_each_entry(timer, &omap_timer_list, node)
939                 if (!strcmp(dev_name(&timer->pdev->dev),
940                             dev_name(&pdev->dev))) {
941                         list_del(&timer->node);
942                         ret = 0;
943                         break;
944                 }
945         spin_unlock_irqrestore(&dm_timer_lock, flags);
946
947         pm_runtime_disable(&pdev->dev);
948
949         return ret;
950 }
951
952 static const struct dmtimer_platform_data omap3plus_pdata = {
953         .timer_errata = OMAP_TIMER_ERRATA_I103_I767,
954 };
955
956 static const struct of_device_id omap_timer_match[] = {
957         {
958                 .compatible = "ti,omap2420-timer",
959         },
960         {
961                 .compatible = "ti,omap3430-timer",
962                 .data = &omap3plus_pdata,
963         },
964         {
965                 .compatible = "ti,omap4430-timer",
966                 .data = &omap3plus_pdata,
967         },
968         {
969                 .compatible = "ti,omap5430-timer",
970                 .data = &omap3plus_pdata,
971         },
972         {
973                 .compatible = "ti,am335x-timer",
974                 .data = &omap3plus_pdata,
975         },
976         {
977                 .compatible = "ti,am335x-timer-1ms",
978                 .data = &omap3plus_pdata,
979         },
980         {
981                 .compatible = "ti,dm816-timer",
982                 .data = &omap3plus_pdata,
983         },
984         {},
985 };
986 MODULE_DEVICE_TABLE(of, omap_timer_match);
987
988 static struct platform_driver omap_dm_timer_driver = {
989         .probe  = omap_dm_timer_probe,
990         .remove = omap_dm_timer_remove,
991         .driver = {
992                 .name   = "omap_timer",
993                 .of_match_table = of_match_ptr(omap_timer_match),
994         },
995 };
996
997 early_platform_init("earlytimer", &omap_dm_timer_driver);
998 module_platform_driver(omap_dm_timer_driver);
999
1000 MODULE_DESCRIPTION("OMAP Dual-Mode Timer Driver");
1001 MODULE_LICENSE("GPL");
1002 MODULE_ALIAS("platform:" DRIVER_NAME);
1003 MODULE_AUTHOR("Texas Instruments Inc");