2 * linux/arch/arm/plat-omap/dmtimer.c
4 * OMAP Dual-Mode Timers
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>
10 * dmtimer adaptation to platform_driver.
12 * Copyright (C) 2005 Nokia Corporation
13 * OMAP2 support by Juha Yrjola
14 * API improvements and OMAP2 clock framework support by Timo Teras
16 * Copyright (C) 2009 Texas Instruments
17 * Added OMAP4 support - Santosh Shilimkar <santosh.shilimkar@ti.com>
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.
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.
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.
38 #include <linux/clk.h>
39 #include <linux/clk-provider.h>
40 #include <linux/module.h>
42 #include <linux/device.h>
43 #include <linux/err.h>
44 #include <linux/pm_runtime.h>
46 #include <linux/of_device.h>
47 #include <linux/platform_device.h>
48 #include <linux/platform_data/dmtimer-omap.h>
50 #include <clocksource/timer-ti-dm.h>
52 static u32 omap_reserved_systimers
;
53 static LIST_HEAD(omap_timer_list
);
54 static DEFINE_SPINLOCK(dm_timer_lock
);
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
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.
72 static inline u32
omap_dm_timer_read_reg(struct omap_dm_timer
*timer
, u32 reg
)
74 WARN_ON((reg
& 0xff) < _OMAP_TIMER_WAKEUP_EN_OFFSET
);
75 return __omap_dm_timer_read(timer
, reg
, timer
->posted
);
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
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.
88 static void omap_dm_timer_write_reg(struct omap_dm_timer
*timer
, u32 reg
,
91 WARN_ON((reg
& 0xff) < _OMAP_TIMER_WAKEUP_EN_OFFSET
);
92 __omap_dm_timer_write(timer
, reg
, value
, timer
->posted
);
95 static void omap_timer_restore_context(struct omap_dm_timer
*timer
)
97 omap_dm_timer_write_reg(timer
, OMAP_TIMER_WAKEUP_EN_REG
,
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
);
112 static int omap_dm_timer_reset(struct omap_dm_timer
*timer
)
114 u32 l
, timeout
= 100000;
116 if (timer
->revision
!= 1)
119 omap_dm_timer_write_reg(timer
, OMAP_TIMER_IF_CTRL_REG
, 0x06);
122 l
= __omap_dm_timer_read(timer
,
123 OMAP_TIMER_V1_SYS_STAT_OFFSET
, 0);
124 } while (!l
&& timeout
--);
127 dev_err(&timer
->pdev
->dev
, "Timer failed to reset\n");
131 /* Configure timer for smart-idle mode */
132 l
= __omap_dm_timer_read(timer
, OMAP_TIMER_OCP_CFG_OFFSET
, 0);
134 __omap_dm_timer_write(timer
, OMAP_TIMER_OCP_CFG_OFFSET
, l
, 0);
141 static int omap_dm_timer_of_set_source(struct omap_dm_timer
*timer
)
147 * FIXME: OMAP1 devices do not use the clock framework for dmtimers so
148 * do not call clk_get() for these devices.
153 parent
= clk_get(&timer
->pdev
->dev
, NULL
);
157 /* Bail out if both clocks point to fck */
158 if (clk_is_match(parent
, timer
->fclk
))
161 ret
= clk_set_parent(timer
->fclk
, parent
);
163 pr_err("%s: failed to set parent\n", __func__
);
170 static int omap_dm_timer_set_source(struct omap_dm_timer
*timer
, int source
)
173 const char *parent_name
;
175 struct dmtimer_platform_data
*pdata
;
177 if (unlikely(!timer
) || IS_ERR(timer
->fclk
))
181 case OMAP_TIMER_SRC_SYS_CLK
:
182 parent_name
= "timer_sys_ck";
184 case OMAP_TIMER_SRC_32_KHZ
:
185 parent_name
= "timer_32k_ck";
187 case OMAP_TIMER_SRC_EXT_CLK
:
188 parent_name
= "timer_ext_ck";
194 pdata
= timer
->pdev
->dev
.platform_data
;
197 * FIXME: Used for OMAP1 devices only because they do not currently
198 * use the clock framework to set the parent clock. To be removed
199 * once OMAP1 migrated to using clock framework for dmtimers
201 if (pdata
&& pdata
->set_timer_src
)
202 return pdata
->set_timer_src(timer
->pdev
, source
);
204 #if defined(CONFIG_COMMON_CLK)
205 /* Check if the clock has configurable parents */
206 if (clk_hw_get_num_parents(__clk_get_hw(timer
->fclk
)) < 2)
210 parent
= clk_get(&timer
->pdev
->dev
, parent_name
);
211 if (IS_ERR(parent
)) {
212 pr_err("%s: %s not found\n", __func__
, parent_name
);
216 ret
= clk_set_parent(timer
->fclk
, parent
);
218 pr_err("%s: failed to set %s as parent\n", __func__
,
226 static void omap_dm_timer_enable(struct omap_dm_timer
*timer
)
230 pm_runtime_get_sync(&timer
->pdev
->dev
);
232 if (!(timer
->capability
& OMAP_TIMER_ALWON
)) {
233 if (timer
->get_context_loss_count
) {
234 c
= timer
->get_context_loss_count(&timer
->pdev
->dev
);
235 if (c
!= timer
->ctx_loss_count
) {
236 omap_timer_restore_context(timer
);
237 timer
->ctx_loss_count
= c
;
240 omap_timer_restore_context(timer
);
245 static void omap_dm_timer_disable(struct omap_dm_timer
*timer
)
247 pm_runtime_put_sync(&timer
->pdev
->dev
);
250 static int omap_dm_timer_prepare(struct omap_dm_timer
*timer
)
255 * FIXME: OMAP1 devices do not use the clock framework for dmtimers so
256 * do not call clk_get() for these devices.
258 if (!(timer
->capability
& OMAP_TIMER_NEEDS_RESET
)) {
259 timer
->fclk
= clk_get(&timer
->pdev
->dev
, "fck");
260 if (WARN_ON_ONCE(IS_ERR(timer
->fclk
))) {
261 dev_err(&timer
->pdev
->dev
, ": No fclk handle.\n");
266 omap_dm_timer_enable(timer
);
268 if (timer
->capability
& OMAP_TIMER_NEEDS_RESET
) {
269 rc
= omap_dm_timer_reset(timer
);
271 omap_dm_timer_disable(timer
);
276 __omap_dm_timer_enable_posted(timer
);
277 omap_dm_timer_disable(timer
);
279 rc
= omap_dm_timer_of_set_source(timer
);
281 return omap_dm_timer_set_source(timer
, OMAP_TIMER_SRC_32_KHZ
);
286 static inline u32
omap_dm_timer_reserved_systimer(int id
)
288 return (omap_reserved_systimers
& (1 << (id
- 1))) ? 1 : 0;
291 int omap_dm_timer_reserve_systimer(int id
)
293 if (omap_dm_timer_reserved_systimer(id
))
296 omap_reserved_systimers
|= (1 << (id
- 1));
301 static struct omap_dm_timer
*_omap_dm_timer_request(int req_type
, void *data
)
303 struct omap_dm_timer
*timer
= NULL
, *t
;
304 struct device_node
*np
= NULL
;
316 case REQUEST_BY_NODE
:
317 np
= (struct device_node
*)data
;
324 spin_lock_irqsave(&dm_timer_lock
, flags
);
325 list_for_each_entry(t
, &omap_timer_list
, node
) {
331 if (id
== t
->pdev
->id
) {
338 if (cap
== (t
->capability
& cap
)) {
340 * If timer is not NULL, we have already found
341 * one timer. But it was not an exact match
342 * because it had more capabilities than what
343 * was required. Therefore, unreserve the last
344 * timer found and see if this one is a better
352 /* Exit loop early if we find an exact match */
353 if (t
->capability
== cap
)
357 case REQUEST_BY_NODE
:
358 if (np
== t
->pdev
->dev
.of_node
) {
372 spin_unlock_irqrestore(&dm_timer_lock
, flags
);
374 if (timer
&& omap_dm_timer_prepare(timer
)) {
380 pr_debug("%s: timer request failed!\n", __func__
);
385 static struct omap_dm_timer
*omap_dm_timer_request(void)
387 return _omap_dm_timer_request(REQUEST_ANY
, NULL
);
390 static struct omap_dm_timer
*omap_dm_timer_request_specific(int id
)
392 /* Requesting timer by ID is not supported when device tree is used */
393 if (of_have_populated_dt()) {
394 pr_warn("%s: Please use omap_dm_timer_request_by_node()\n",
399 return _omap_dm_timer_request(REQUEST_BY_ID
, &id
);
403 * omap_dm_timer_request_by_cap - Request a timer by capability
404 * @cap: Bit mask of capabilities to match
406 * Find a timer based upon capabilities bit mask. Callers of this function
407 * should use the definitions found in the plat/dmtimer.h file under the
408 * comment "timer capabilities used in hwmod database". Returns pointer to
409 * timer handle on success and a NULL pointer on failure.
411 struct omap_dm_timer
*omap_dm_timer_request_by_cap(u32 cap
)
413 return _omap_dm_timer_request(REQUEST_BY_CAP
, &cap
);
417 * omap_dm_timer_request_by_node - Request a timer by device-tree node
418 * @np: Pointer to device-tree timer node
420 * Request a timer based upon a device node pointer. Returns pointer to
421 * timer handle on success and a NULL pointer on failure.
423 static struct omap_dm_timer
*omap_dm_timer_request_by_node(struct device_node
*np
)
428 return _omap_dm_timer_request(REQUEST_BY_NODE
, np
);
431 static int omap_dm_timer_free(struct omap_dm_timer
*timer
)
433 if (unlikely(!timer
))
436 clk_put(timer
->fclk
);
438 WARN_ON(!timer
->reserved
);
443 int omap_dm_timer_get_irq(struct omap_dm_timer
*timer
)
450 #if defined(CONFIG_ARCH_OMAP1)
451 #include <mach/hardware.h>
453 static struct clk
*omap_dm_timer_get_fclk(struct omap_dm_timer
*timer
)
459 * omap_dm_timer_modify_idlect_mask - Check if any running timers use ARMXOR
460 * @inputmask: current value of idlect mask
462 __u32
omap_dm_timer_modify_idlect_mask(__u32 inputmask
)
465 struct omap_dm_timer
*timer
= NULL
;
468 /* If ARMXOR cannot be idled this function call is unnecessary */
469 if (!(inputmask
& (1 << 1)))
472 /* If any active timer is using ARMXOR return modified mask */
473 spin_lock_irqsave(&dm_timer_lock
, flags
);
474 list_for_each_entry(timer
, &omap_timer_list
, node
) {
477 l
= omap_dm_timer_read_reg(timer
, OMAP_TIMER_CTRL_REG
);
478 if (l
& OMAP_TIMER_CTRL_ST
) {
479 if (((omap_readl(MOD_CONF_CTRL_1
) >> (i
* 2)) & 0x03) == 0)
480 inputmask
&= ~(1 << 1);
482 inputmask
&= ~(1 << 2);
486 spin_unlock_irqrestore(&dm_timer_lock
, flags
);
493 static struct clk
*omap_dm_timer_get_fclk(struct omap_dm_timer
*timer
)
495 if (timer
&& !IS_ERR(timer
->fclk
))
500 __u32
omap_dm_timer_modify_idlect_mask(__u32 inputmask
)
509 int omap_dm_timer_trigger(struct omap_dm_timer
*timer
)
511 if (unlikely(!timer
|| pm_runtime_suspended(&timer
->pdev
->dev
))) {
512 pr_err("%s: timer not available or enabled.\n", __func__
);
516 omap_dm_timer_write_reg(timer
, OMAP_TIMER_TRIGGER_REG
, 0);
520 static int omap_dm_timer_start(struct omap_dm_timer
*timer
)
524 if (unlikely(!timer
))
527 omap_dm_timer_enable(timer
);
529 l
= omap_dm_timer_read_reg(timer
, OMAP_TIMER_CTRL_REG
);
530 if (!(l
& OMAP_TIMER_CTRL_ST
)) {
531 l
|= OMAP_TIMER_CTRL_ST
;
532 omap_dm_timer_write_reg(timer
, OMAP_TIMER_CTRL_REG
, l
);
535 /* Save the context */
536 timer
->context
.tclr
= l
;
540 static int omap_dm_timer_stop(struct omap_dm_timer
*timer
)
542 unsigned long rate
= 0;
544 if (unlikely(!timer
))
547 if (!(timer
->capability
& OMAP_TIMER_NEEDS_RESET
))
548 rate
= clk_get_rate(timer
->fclk
);
550 __omap_dm_timer_stop(timer
, timer
->posted
, rate
);
553 * Since the register values are computed and written within
554 * __omap_dm_timer_stop, we need to use read to retrieve the
557 timer
->context
.tclr
=
558 omap_dm_timer_read_reg(timer
, OMAP_TIMER_CTRL_REG
);
559 omap_dm_timer_disable(timer
);
563 static int omap_dm_timer_set_load(struct omap_dm_timer
*timer
, int autoreload
,
568 if (unlikely(!timer
))
571 omap_dm_timer_enable(timer
);
572 l
= omap_dm_timer_read_reg(timer
, OMAP_TIMER_CTRL_REG
);
574 l
|= OMAP_TIMER_CTRL_AR
;
576 l
&= ~OMAP_TIMER_CTRL_AR
;
577 omap_dm_timer_write_reg(timer
, OMAP_TIMER_CTRL_REG
, l
);
578 omap_dm_timer_write_reg(timer
, OMAP_TIMER_LOAD_REG
, load
);
580 omap_dm_timer_write_reg(timer
, OMAP_TIMER_TRIGGER_REG
, 0);
581 /* Save the context */
582 timer
->context
.tclr
= l
;
583 timer
->context
.tldr
= load
;
584 omap_dm_timer_disable(timer
);
588 /* Optimized set_load which removes costly spin wait in timer_start */
589 int omap_dm_timer_set_load_start(struct omap_dm_timer
*timer
, int autoreload
,
594 if (unlikely(!timer
))
597 omap_dm_timer_enable(timer
);
599 l
= omap_dm_timer_read_reg(timer
, OMAP_TIMER_CTRL_REG
);
601 l
|= OMAP_TIMER_CTRL_AR
;
602 omap_dm_timer_write_reg(timer
, OMAP_TIMER_LOAD_REG
, load
);
604 l
&= ~OMAP_TIMER_CTRL_AR
;
606 l
|= OMAP_TIMER_CTRL_ST
;
608 __omap_dm_timer_load_start(timer
, l
, load
, timer
->posted
);
610 /* Save the context */
611 timer
->context
.tclr
= l
;
612 timer
->context
.tldr
= load
;
613 timer
->context
.tcrr
= load
;
616 static int omap_dm_timer_set_match(struct omap_dm_timer
*timer
, int enable
,
621 if (unlikely(!timer
))
624 omap_dm_timer_enable(timer
);
625 l
= omap_dm_timer_read_reg(timer
, OMAP_TIMER_CTRL_REG
);
627 l
|= OMAP_TIMER_CTRL_CE
;
629 l
&= ~OMAP_TIMER_CTRL_CE
;
630 omap_dm_timer_write_reg(timer
, OMAP_TIMER_MATCH_REG
, match
);
631 omap_dm_timer_write_reg(timer
, OMAP_TIMER_CTRL_REG
, l
);
633 /* Save the context */
634 timer
->context
.tclr
= l
;
635 timer
->context
.tmar
= match
;
636 omap_dm_timer_disable(timer
);
640 static int omap_dm_timer_set_pwm(struct omap_dm_timer
*timer
, int def_on
,
641 int toggle
, int trigger
)
645 if (unlikely(!timer
))
648 omap_dm_timer_enable(timer
);
649 l
= omap_dm_timer_read_reg(timer
, OMAP_TIMER_CTRL_REG
);
650 l
&= ~(OMAP_TIMER_CTRL_GPOCFG
| OMAP_TIMER_CTRL_SCPWM
|
651 OMAP_TIMER_CTRL_PT
| (0x03 << 10));
653 l
|= OMAP_TIMER_CTRL_SCPWM
;
655 l
|= OMAP_TIMER_CTRL_PT
;
657 omap_dm_timer_write_reg(timer
, OMAP_TIMER_CTRL_REG
, l
);
659 /* Save the context */
660 timer
->context
.tclr
= l
;
661 omap_dm_timer_disable(timer
);
665 static int omap_dm_timer_set_prescaler(struct omap_dm_timer
*timer
,
670 if (unlikely(!timer
) || prescaler
< -1 || prescaler
> 7)
673 omap_dm_timer_enable(timer
);
674 l
= omap_dm_timer_read_reg(timer
, OMAP_TIMER_CTRL_REG
);
675 l
&= ~(OMAP_TIMER_CTRL_PRE
| (0x07 << 2));
676 if (prescaler
>= 0) {
677 l
|= OMAP_TIMER_CTRL_PRE
;
680 omap_dm_timer_write_reg(timer
, OMAP_TIMER_CTRL_REG
, l
);
682 /* Save the context */
683 timer
->context
.tclr
= l
;
684 omap_dm_timer_disable(timer
);
688 static int omap_dm_timer_set_int_enable(struct omap_dm_timer
*timer
,
691 if (unlikely(!timer
))
694 omap_dm_timer_enable(timer
);
695 __omap_dm_timer_int_enable(timer
, value
);
697 /* Save the context */
698 timer
->context
.tier
= value
;
699 timer
->context
.twer
= value
;
700 omap_dm_timer_disable(timer
);
705 * omap_dm_timer_set_int_disable - disable timer interrupts
706 * @timer: pointer to timer handle
707 * @mask: bit mask of interrupts to be disabled
709 * Disables the specified timer interrupts for a timer.
711 static int omap_dm_timer_set_int_disable(struct omap_dm_timer
*timer
, u32 mask
)
715 if (unlikely(!timer
))
718 omap_dm_timer_enable(timer
);
720 if (timer
->revision
== 1)
721 l
= readl_relaxed(timer
->irq_ena
) & ~mask
;
723 writel_relaxed(l
, timer
->irq_dis
);
724 l
= omap_dm_timer_read_reg(timer
, OMAP_TIMER_WAKEUP_EN_REG
) & ~mask
;
725 omap_dm_timer_write_reg(timer
, OMAP_TIMER_WAKEUP_EN_REG
, l
);
727 /* Save the context */
728 timer
->context
.tier
&= ~mask
;
729 timer
->context
.twer
&= ~mask
;
730 omap_dm_timer_disable(timer
);
734 static unsigned int omap_dm_timer_read_status(struct omap_dm_timer
*timer
)
738 if (unlikely(!timer
|| pm_runtime_suspended(&timer
->pdev
->dev
))) {
739 pr_err("%s: timer not available or enabled.\n", __func__
);
743 l
= readl_relaxed(timer
->irq_stat
);
748 static int omap_dm_timer_write_status(struct omap_dm_timer
*timer
, unsigned int value
)
750 if (unlikely(!timer
|| pm_runtime_suspended(&timer
->pdev
->dev
)))
753 __omap_dm_timer_write_status(timer
, value
);
758 static unsigned int omap_dm_timer_read_counter(struct omap_dm_timer
*timer
)
760 if (unlikely(!timer
|| pm_runtime_suspended(&timer
->pdev
->dev
))) {
761 pr_err("%s: timer not iavailable or enabled.\n", __func__
);
765 return __omap_dm_timer_read_counter(timer
, timer
->posted
);
768 static int omap_dm_timer_write_counter(struct omap_dm_timer
*timer
, unsigned int value
)
770 if (unlikely(!timer
|| pm_runtime_suspended(&timer
->pdev
->dev
))) {
771 pr_err("%s: timer not available or enabled.\n", __func__
);
775 omap_dm_timer_write_reg(timer
, OMAP_TIMER_COUNTER_REG
, value
);
777 /* Save the context */
778 timer
->context
.tcrr
= value
;
782 int omap_dm_timers_active(void)
784 struct omap_dm_timer
*timer
;
786 list_for_each_entry(timer
, &omap_timer_list
, node
) {
787 if (!timer
->reserved
)
790 if (omap_dm_timer_read_reg(timer
, OMAP_TIMER_CTRL_REG
) &
791 OMAP_TIMER_CTRL_ST
) {
798 static const struct of_device_id omap_timer_match
[];
801 * omap_dm_timer_probe - probe function called for every registered device
802 * @pdev: pointer to current timer platform device
804 * Called by driver framework at the end of device registration for all
807 static int omap_dm_timer_probe(struct platform_device
*pdev
)
810 struct omap_dm_timer
*timer
;
811 struct resource
*mem
, *irq
;
812 struct device
*dev
= &pdev
->dev
;
813 const struct dmtimer_platform_data
*pdata
;
816 pdata
= of_device_get_match_data(dev
);
818 pdata
= dev_get_platdata(dev
);
820 dev
->platform_data
= (void *)pdata
;
823 dev_err(dev
, "%s: no platform data.\n", __func__
);
827 irq
= platform_get_resource(pdev
, IORESOURCE_IRQ
, 0);
828 if (unlikely(!irq
)) {
829 dev_err(dev
, "%s: no IRQ resource.\n", __func__
);
833 mem
= platform_get_resource(pdev
, IORESOURCE_MEM
, 0);
834 if (unlikely(!mem
)) {
835 dev_err(dev
, "%s: no memory resource.\n", __func__
);
839 timer
= devm_kzalloc(dev
, sizeof(*timer
), GFP_KERNEL
);
843 timer
->fclk
= ERR_PTR(-ENODEV
);
844 timer
->io_base
= devm_ioremap_resource(dev
, mem
);
845 if (IS_ERR(timer
->io_base
))
846 return PTR_ERR(timer
->io_base
);
849 if (of_find_property(dev
->of_node
, "ti,timer-alwon", NULL
))
850 timer
->capability
|= OMAP_TIMER_ALWON
;
851 if (of_find_property(dev
->of_node
, "ti,timer-dsp", NULL
))
852 timer
->capability
|= OMAP_TIMER_HAS_DSP_IRQ
;
853 if (of_find_property(dev
->of_node
, "ti,timer-pwm", NULL
))
854 timer
->capability
|= OMAP_TIMER_HAS_PWM
;
855 if (of_find_property(dev
->of_node
, "ti,timer-secure", NULL
))
856 timer
->capability
|= OMAP_TIMER_SECURE
;
858 timer
->id
= pdev
->id
;
859 timer
->capability
= pdata
->timer_capability
;
860 timer
->reserved
= omap_dm_timer_reserved_systimer(timer
->id
);
861 timer
->get_context_loss_count
= pdata
->get_context_loss_count
;
865 timer
->errata
= pdata
->timer_errata
;
867 timer
->irq
= irq
->start
;
870 pm_runtime_enable(dev
);
872 if (!timer
->reserved
) {
873 ret
= pm_runtime_get_sync(dev
);
875 dev_err(dev
, "%s: pm_runtime_get_sync failed!\n",
879 __omap_dm_timer_init_regs(timer
);
883 /* add the timer element to the list */
884 spin_lock_irqsave(&dm_timer_lock
, flags
);
885 list_add_tail(&timer
->node
, &omap_timer_list
);
886 spin_unlock_irqrestore(&dm_timer_lock
, flags
);
888 dev_dbg(dev
, "Device Probed.\n");
893 pm_runtime_put_noidle(dev
);
894 pm_runtime_disable(dev
);
899 * omap_dm_timer_remove - cleanup a registered timer device
900 * @pdev: pointer to current timer platform device
902 * Called by driver framework whenever a timer device is unregistered.
903 * In addition to freeing platform resources it also deletes the timer
904 * entry from the local list.
906 static int omap_dm_timer_remove(struct platform_device
*pdev
)
908 struct omap_dm_timer
*timer
;
912 spin_lock_irqsave(&dm_timer_lock
, flags
);
913 list_for_each_entry(timer
, &omap_timer_list
, node
)
914 if (!strcmp(dev_name(&timer
->pdev
->dev
),
915 dev_name(&pdev
->dev
))) {
916 list_del(&timer
->node
);
920 spin_unlock_irqrestore(&dm_timer_lock
, flags
);
922 pm_runtime_disable(&pdev
->dev
);
927 const static struct omap_dm_timer_ops dmtimer_ops
= {
928 .request_by_node
= omap_dm_timer_request_by_node
,
929 .request_specific
= omap_dm_timer_request_specific
,
930 .request
= omap_dm_timer_request
,
931 .set_source
= omap_dm_timer_set_source
,
932 .get_irq
= omap_dm_timer_get_irq
,
933 .set_int_enable
= omap_dm_timer_set_int_enable
,
934 .set_int_disable
= omap_dm_timer_set_int_disable
,
935 .free
= omap_dm_timer_free
,
936 .enable
= omap_dm_timer_enable
,
937 .disable
= omap_dm_timer_disable
,
938 .get_fclk
= omap_dm_timer_get_fclk
,
939 .start
= omap_dm_timer_start
,
940 .stop
= omap_dm_timer_stop
,
941 .set_load
= omap_dm_timer_set_load
,
942 .set_match
= omap_dm_timer_set_match
,
943 .set_pwm
= omap_dm_timer_set_pwm
,
944 .set_prescaler
= omap_dm_timer_set_prescaler
,
945 .read_counter
= omap_dm_timer_read_counter
,
946 .write_counter
= omap_dm_timer_write_counter
,
947 .read_status
= omap_dm_timer_read_status
,
948 .write_status
= omap_dm_timer_write_status
,
951 static const struct dmtimer_platform_data omap3plus_pdata
= {
952 .timer_errata
= OMAP_TIMER_ERRATA_I103_I767
,
953 .timer_ops
= &dmtimer_ops
,
956 static const struct of_device_id omap_timer_match
[] = {
958 .compatible
= "ti,omap2420-timer",
961 .compatible
= "ti,omap3430-timer",
962 .data
= &omap3plus_pdata
,
965 .compatible
= "ti,omap4430-timer",
966 .data
= &omap3plus_pdata
,
969 .compatible
= "ti,omap5430-timer",
970 .data
= &omap3plus_pdata
,
973 .compatible
= "ti,am335x-timer",
974 .data
= &omap3plus_pdata
,
977 .compatible
= "ti,am335x-timer-1ms",
978 .data
= &omap3plus_pdata
,
981 .compatible
= "ti,dm816-timer",
982 .data
= &omap3plus_pdata
,
986 MODULE_DEVICE_TABLE(of
, omap_timer_match
);
988 static struct platform_driver omap_dm_timer_driver
= {
989 .probe
= omap_dm_timer_probe
,
990 .remove
= omap_dm_timer_remove
,
992 .name
= "omap_timer",
993 .of_match_table
= of_match_ptr(omap_timer_match
),
997 module_platform_driver(omap_dm_timer_driver
);
999 MODULE_DESCRIPTION("OMAP Dual-Mode Timer Driver");
1000 MODULE_LICENSE("GPL");
1001 MODULE_ALIAS("platform:" DRIVER_NAME
);
1002 MODULE_AUTHOR("Texas Instruments Inc");