1 // SPDX-License-Identifier: GPL-2.0+
3 * linux/arch/arm/plat-omap/dmtimer.c
5 * OMAP Dual-Mode Timers
7 * Copyright (C) 2010 Texas Instruments Incorporated - http://www.ti.com/
11 * dmtimer adaptation to platform_driver.
13 * Copyright (C) 2005 Nokia Corporation
14 * OMAP2 support by Juha Yrjola
15 * API improvements and OMAP2 clock framework support by Timo Teras
17 * Copyright (C) 2009 Texas Instruments
21 #include <linux/clk.h>
22 #include <linux/clk-provider.h>
23 #include <linux/cpu_pm.h>
24 #include <linux/module.h>
26 #include <linux/device.h>
27 #include <linux/err.h>
28 #include <linux/pm_runtime.h>
30 #include <linux/of_device.h>
31 #include <linux/platform_device.h>
32 #include <linux/platform_data/dmtimer-omap.h>
34 #include <clocksource/timer-ti-dm.h>
36 static u32 omap_reserved_systimers;
37 static LIST_HEAD(omap_timer_list);
38 static DEFINE_SPINLOCK(dm_timer_lock);
48 * omap_dm_timer_read_reg - read timer registers in posted and non-posted mode
49 * @timer: timer pointer over which read operation to perform
50 * @reg: lowest byte holds the register offset
52 * The posted mode bit is encoded in reg. Note that in posted mode write
53 * pending bit must be checked. Otherwise a read of a non completed write
54 * will produce an error.
56 static inline u32 omap_dm_timer_read_reg(struct omap_dm_timer *timer, u32 reg)
58 WARN_ON((reg & 0xff) < _OMAP_TIMER_WAKEUP_EN_OFFSET);
59 return __omap_dm_timer_read(timer, reg, timer->posted);
63 * omap_dm_timer_write_reg - write timer registers in posted and non-posted mode
64 * @timer: timer pointer over which write operation is to perform
65 * @reg: lowest byte holds the register offset
66 * @value: data to write into the register
68 * The posted mode bit is encoded in reg. Note that in posted mode the write
69 * pending bit must be checked. Otherwise a write on a register which has a
70 * pending write will be lost.
72 static void omap_dm_timer_write_reg(struct omap_dm_timer *timer, u32 reg,
75 WARN_ON((reg & 0xff) < _OMAP_TIMER_WAKEUP_EN_OFFSET);
76 __omap_dm_timer_write(timer, reg, value, timer->posted);
79 static void omap_timer_restore_context(struct omap_dm_timer *timer)
81 omap_dm_timer_write_reg(timer, OMAP_TIMER_WAKEUP_EN_REG,
83 omap_dm_timer_write_reg(timer, OMAP_TIMER_COUNTER_REG,
85 omap_dm_timer_write_reg(timer, OMAP_TIMER_LOAD_REG,
87 omap_dm_timer_write_reg(timer, OMAP_TIMER_MATCH_REG,
89 omap_dm_timer_write_reg(timer, OMAP_TIMER_IF_CTRL_REG,
90 timer->context.tsicr);
91 writel_relaxed(timer->context.tier, timer->irq_ena);
92 omap_dm_timer_write_reg(timer, OMAP_TIMER_CTRL_REG,
96 static void omap_timer_save_context(struct omap_dm_timer *timer)
99 omap_dm_timer_read_reg(timer, OMAP_TIMER_CTRL_REG);
100 timer->context.twer =
101 omap_dm_timer_read_reg(timer, OMAP_TIMER_WAKEUP_EN_REG);
102 timer->context.tldr =
103 omap_dm_timer_read_reg(timer, OMAP_TIMER_LOAD_REG);
104 timer->context.tmar =
105 omap_dm_timer_read_reg(timer, OMAP_TIMER_MATCH_REG);
106 timer->context.tier = readl_relaxed(timer->irq_ena);
107 timer->context.tsicr =
108 omap_dm_timer_read_reg(timer, OMAP_TIMER_IF_CTRL_REG);
111 static int omap_timer_context_notifier(struct notifier_block *nb,
112 unsigned long cmd, void *v)
114 struct omap_dm_timer *timer;
116 timer = container_of(nb, struct omap_dm_timer, nb);
119 case CPU_CLUSTER_PM_ENTER:
120 if ((timer->capability & OMAP_TIMER_ALWON) ||
121 !atomic_read(&timer->enabled))
123 omap_timer_save_context(timer);
125 case CPU_CLUSTER_PM_ENTER_FAILED:
126 case CPU_CLUSTER_PM_EXIT:
127 if ((timer->capability & OMAP_TIMER_ALWON) ||
128 !atomic_read(&timer->enabled))
130 omap_timer_restore_context(timer);
137 static int omap_dm_timer_reset(struct omap_dm_timer *timer)
139 u32 l, timeout = 100000;
141 if (timer->revision != 1)
144 omap_dm_timer_write_reg(timer, OMAP_TIMER_IF_CTRL_REG, 0x06);
147 l = __omap_dm_timer_read(timer,
148 OMAP_TIMER_V1_SYS_STAT_OFFSET, 0);
149 } while (!l && timeout--);
152 dev_err(&timer->pdev->dev, "Timer failed to reset\n");
156 /* Configure timer for smart-idle mode */
157 l = __omap_dm_timer_read(timer, OMAP_TIMER_OCP_CFG_OFFSET, 0);
159 __omap_dm_timer_write(timer, OMAP_TIMER_OCP_CFG_OFFSET, l, 0);
166 static int omap_dm_timer_of_set_source(struct omap_dm_timer *timer)
172 * FIXME: OMAP1 devices do not use the clock framework for dmtimers so
173 * do not call clk_get() for these devices.
178 parent = clk_get(&timer->pdev->dev, NULL);
182 /* Bail out if both clocks point to fck */
183 if (clk_is_match(parent, timer->fclk))
186 ret = clk_set_parent(timer->fclk, parent);
188 pr_err("%s: failed to set parent\n", __func__);
195 static int omap_dm_timer_set_source(struct omap_dm_timer *timer, int source)
198 const char *parent_name;
200 struct dmtimer_platform_data *pdata;
202 if (unlikely(!timer) || IS_ERR(timer->fclk))
206 case OMAP_TIMER_SRC_SYS_CLK:
207 parent_name = "timer_sys_ck";
209 case OMAP_TIMER_SRC_32_KHZ:
210 parent_name = "timer_32k_ck";
212 case OMAP_TIMER_SRC_EXT_CLK:
213 parent_name = "timer_ext_ck";
219 pdata = timer->pdev->dev.platform_data;
222 * FIXME: Used for OMAP1 devices only because they do not currently
223 * use the clock framework to set the parent clock. To be removed
224 * once OMAP1 migrated to using clock framework for dmtimers
226 if (pdata && pdata->set_timer_src)
227 return pdata->set_timer_src(timer->pdev, source);
229 #if defined(CONFIG_COMMON_CLK)
230 /* Check if the clock has configurable parents */
231 if (clk_hw_get_num_parents(__clk_get_hw(timer->fclk)) < 2)
235 parent = clk_get(&timer->pdev->dev, parent_name);
236 if (IS_ERR(parent)) {
237 pr_err("%s: %s not found\n", __func__, parent_name);
241 ret = clk_set_parent(timer->fclk, parent);
243 pr_err("%s: failed to set %s as parent\n", __func__,
251 static void omap_dm_timer_enable(struct omap_dm_timer *timer)
253 pm_runtime_get_sync(&timer->pdev->dev);
256 static void omap_dm_timer_disable(struct omap_dm_timer *timer)
258 pm_runtime_put_sync(&timer->pdev->dev);
261 static int omap_dm_timer_prepare(struct omap_dm_timer *timer)
266 * FIXME: OMAP1 devices do not use the clock framework for dmtimers so
267 * do not call clk_get() for these devices.
269 if (!(timer->capability & OMAP_TIMER_NEEDS_RESET)) {
270 timer->fclk = clk_get(&timer->pdev->dev, "fck");
271 if (WARN_ON_ONCE(IS_ERR(timer->fclk))) {
272 dev_err(&timer->pdev->dev, ": No fclk handle.\n");
277 omap_dm_timer_enable(timer);
279 if (timer->capability & OMAP_TIMER_NEEDS_RESET) {
280 rc = omap_dm_timer_reset(timer);
282 omap_dm_timer_disable(timer);
287 __omap_dm_timer_enable_posted(timer);
288 omap_dm_timer_disable(timer);
290 rc = omap_dm_timer_of_set_source(timer);
292 return omap_dm_timer_set_source(timer, OMAP_TIMER_SRC_32_KHZ);
297 static inline u32 omap_dm_timer_reserved_systimer(int id)
299 return (omap_reserved_systimers & (1 << (id - 1))) ? 1 : 0;
302 int omap_dm_timer_reserve_systimer(int id)
304 if (omap_dm_timer_reserved_systimer(id))
307 omap_reserved_systimers |= (1 << (id - 1));
312 static struct omap_dm_timer *_omap_dm_timer_request(int req_type, void *data)
314 struct omap_dm_timer *timer = NULL, *t;
315 struct device_node *np = NULL;
327 case REQUEST_BY_NODE:
328 np = (struct device_node *)data;
335 spin_lock_irqsave(&dm_timer_lock, flags);
336 list_for_each_entry(t, &omap_timer_list, node) {
342 if (id == t->pdev->id) {
349 if (cap == (t->capability & cap)) {
351 * If timer is not NULL, we have already found
352 * one timer. But it was not an exact match
353 * because it had more capabilities than what
354 * was required. Therefore, unreserve the last
355 * timer found and see if this one is a better
363 /* Exit loop early if we find an exact match */
364 if (t->capability == cap)
368 case REQUEST_BY_NODE:
369 if (np == t->pdev->dev.of_node) {
383 spin_unlock_irqrestore(&dm_timer_lock, flags);
385 if (timer && omap_dm_timer_prepare(timer)) {
391 pr_debug("%s: timer request failed!\n", __func__);
396 static struct omap_dm_timer *omap_dm_timer_request(void)
398 return _omap_dm_timer_request(REQUEST_ANY, NULL);
401 static struct omap_dm_timer *omap_dm_timer_request_specific(int id)
403 /* Requesting timer by ID is not supported when device tree is used */
404 if (of_have_populated_dt()) {
405 pr_warn("%s: Please use omap_dm_timer_request_by_node()\n",
410 return _omap_dm_timer_request(REQUEST_BY_ID, &id);
414 * omap_dm_timer_request_by_cap - Request a timer by capability
415 * @cap: Bit mask of capabilities to match
417 * Find a timer based upon capabilities bit mask. Callers of this function
418 * should use the definitions found in the plat/dmtimer.h file under the
419 * comment "timer capabilities used in hwmod database". Returns pointer to
420 * timer handle on success and a NULL pointer on failure.
422 struct omap_dm_timer *omap_dm_timer_request_by_cap(u32 cap)
424 return _omap_dm_timer_request(REQUEST_BY_CAP, &cap);
428 * omap_dm_timer_request_by_node - Request a timer by device-tree node
429 * @np: Pointer to device-tree timer node
431 * Request a timer based upon a device node pointer. Returns pointer to
432 * timer handle on success and a NULL pointer on failure.
434 static struct omap_dm_timer *omap_dm_timer_request_by_node(struct device_node *np)
439 return _omap_dm_timer_request(REQUEST_BY_NODE, np);
442 static int omap_dm_timer_free(struct omap_dm_timer *timer)
444 if (unlikely(!timer))
447 clk_put(timer->fclk);
449 WARN_ON(!timer->reserved);
454 int omap_dm_timer_get_irq(struct omap_dm_timer *timer)
461 #if defined(CONFIG_ARCH_OMAP1)
462 #include <mach/hardware.h>
464 static struct clk *omap_dm_timer_get_fclk(struct omap_dm_timer *timer)
470 * omap_dm_timer_modify_idlect_mask - Check if any running timers use ARMXOR
471 * @inputmask: current value of idlect mask
473 __u32 omap_dm_timer_modify_idlect_mask(__u32 inputmask)
476 struct omap_dm_timer *timer = NULL;
479 /* If ARMXOR cannot be idled this function call is unnecessary */
480 if (!(inputmask & (1 << 1)))
483 /* If any active timer is using ARMXOR return modified mask */
484 spin_lock_irqsave(&dm_timer_lock, flags);
485 list_for_each_entry(timer, &omap_timer_list, node) {
488 l = omap_dm_timer_read_reg(timer, OMAP_TIMER_CTRL_REG);
489 if (l & OMAP_TIMER_CTRL_ST) {
490 if (((omap_readl(MOD_CONF_CTRL_1) >> (i * 2)) & 0x03) == 0)
491 inputmask &= ~(1 << 1);
493 inputmask &= ~(1 << 2);
497 spin_unlock_irqrestore(&dm_timer_lock, flags);
504 static struct clk *omap_dm_timer_get_fclk(struct omap_dm_timer *timer)
506 if (timer && !IS_ERR(timer->fclk))
511 __u32 omap_dm_timer_modify_idlect_mask(__u32 inputmask)
520 int omap_dm_timer_trigger(struct omap_dm_timer *timer)
522 if (unlikely(!timer || !atomic_read(&timer->enabled))) {
523 pr_err("%s: timer not available or enabled.\n", __func__);
527 omap_dm_timer_write_reg(timer, OMAP_TIMER_TRIGGER_REG, 0);
531 static int omap_dm_timer_start(struct omap_dm_timer *timer)
535 if (unlikely(!timer))
538 omap_dm_timer_enable(timer);
540 l = omap_dm_timer_read_reg(timer, OMAP_TIMER_CTRL_REG);
541 if (!(l & OMAP_TIMER_CTRL_ST)) {
542 l |= OMAP_TIMER_CTRL_ST;
543 omap_dm_timer_write_reg(timer, OMAP_TIMER_CTRL_REG, l);
549 static int omap_dm_timer_stop(struct omap_dm_timer *timer)
551 unsigned long rate = 0;
553 if (unlikely(!timer))
556 if (!(timer->capability & OMAP_TIMER_NEEDS_RESET))
557 rate = clk_get_rate(timer->fclk);
559 __omap_dm_timer_stop(timer, timer->posted, rate);
561 omap_dm_timer_disable(timer);
565 static int omap_dm_timer_set_load(struct omap_dm_timer *timer,
568 if (unlikely(!timer))
571 omap_dm_timer_enable(timer);
572 omap_dm_timer_write_reg(timer, OMAP_TIMER_LOAD_REG, load);
574 omap_dm_timer_disable(timer);
578 static int omap_dm_timer_set_match(struct omap_dm_timer *timer, int enable,
583 if (unlikely(!timer))
586 omap_dm_timer_enable(timer);
587 l = omap_dm_timer_read_reg(timer, OMAP_TIMER_CTRL_REG);
589 l |= OMAP_TIMER_CTRL_CE;
591 l &= ~OMAP_TIMER_CTRL_CE;
592 omap_dm_timer_write_reg(timer, OMAP_TIMER_MATCH_REG, match);
593 omap_dm_timer_write_reg(timer, OMAP_TIMER_CTRL_REG, l);
595 omap_dm_timer_disable(timer);
599 static int omap_dm_timer_set_pwm(struct omap_dm_timer *timer, int def_on,
600 int toggle, int trigger, int autoreload)
604 if (unlikely(!timer))
607 omap_dm_timer_enable(timer);
608 l = omap_dm_timer_read_reg(timer, OMAP_TIMER_CTRL_REG);
609 l &= ~(OMAP_TIMER_CTRL_GPOCFG | OMAP_TIMER_CTRL_SCPWM |
610 OMAP_TIMER_CTRL_PT | (0x03 << 10) | OMAP_TIMER_CTRL_AR);
612 l |= OMAP_TIMER_CTRL_SCPWM;
614 l |= OMAP_TIMER_CTRL_PT;
617 l |= OMAP_TIMER_CTRL_AR;
618 omap_dm_timer_write_reg(timer, OMAP_TIMER_CTRL_REG, l);
620 omap_dm_timer_disable(timer);
624 static int omap_dm_timer_get_pwm_status(struct omap_dm_timer *timer)
628 if (unlikely(!timer))
631 omap_dm_timer_enable(timer);
632 l = omap_dm_timer_read_reg(timer, OMAP_TIMER_CTRL_REG);
633 omap_dm_timer_disable(timer);
638 static int omap_dm_timer_set_prescaler(struct omap_dm_timer *timer,
643 if (unlikely(!timer) || prescaler < -1 || prescaler > 7)
646 omap_dm_timer_enable(timer);
647 l = omap_dm_timer_read_reg(timer, OMAP_TIMER_CTRL_REG);
648 l &= ~(OMAP_TIMER_CTRL_PRE | (0x07 << 2));
649 if (prescaler >= 0) {
650 l |= OMAP_TIMER_CTRL_PRE;
653 omap_dm_timer_write_reg(timer, OMAP_TIMER_CTRL_REG, l);
655 omap_dm_timer_disable(timer);
659 static int omap_dm_timer_set_int_enable(struct omap_dm_timer *timer,
662 if (unlikely(!timer))
665 omap_dm_timer_enable(timer);
666 __omap_dm_timer_int_enable(timer, value);
668 omap_dm_timer_disable(timer);
673 * omap_dm_timer_set_int_disable - disable timer interrupts
674 * @timer: pointer to timer handle
675 * @mask: bit mask of interrupts to be disabled
677 * Disables the specified timer interrupts for a timer.
679 static int omap_dm_timer_set_int_disable(struct omap_dm_timer *timer, u32 mask)
683 if (unlikely(!timer))
686 omap_dm_timer_enable(timer);
688 if (timer->revision == 1)
689 l = readl_relaxed(timer->irq_ena) & ~mask;
691 writel_relaxed(l, timer->irq_dis);
692 l = omap_dm_timer_read_reg(timer, OMAP_TIMER_WAKEUP_EN_REG) & ~mask;
693 omap_dm_timer_write_reg(timer, OMAP_TIMER_WAKEUP_EN_REG, l);
695 omap_dm_timer_disable(timer);
699 static unsigned int omap_dm_timer_read_status(struct omap_dm_timer *timer)
703 if (unlikely(!timer || !atomic_read(&timer->enabled))) {
704 pr_err("%s: timer not available or enabled.\n", __func__);
708 l = readl_relaxed(timer->irq_stat);
713 static int omap_dm_timer_write_status(struct omap_dm_timer *timer, unsigned int value)
715 if (unlikely(!timer || !atomic_read(&timer->enabled)))
718 __omap_dm_timer_write_status(timer, value);
723 static unsigned int omap_dm_timer_read_counter(struct omap_dm_timer *timer)
725 if (unlikely(!timer || !atomic_read(&timer->enabled))) {
726 pr_err("%s: timer not iavailable or enabled.\n", __func__);
730 return __omap_dm_timer_read_counter(timer, timer->posted);
733 static int omap_dm_timer_write_counter(struct omap_dm_timer *timer, unsigned int value)
735 if (unlikely(!timer || !atomic_read(&timer->enabled))) {
736 pr_err("%s: timer not available or enabled.\n", __func__);
740 omap_dm_timer_write_reg(timer, OMAP_TIMER_COUNTER_REG, value);
742 /* Save the context */
743 timer->context.tcrr = value;
747 int omap_dm_timers_active(void)
749 struct omap_dm_timer *timer;
751 list_for_each_entry(timer, &omap_timer_list, node) {
752 if (!timer->reserved)
755 if (omap_dm_timer_read_reg(timer, OMAP_TIMER_CTRL_REG) &
756 OMAP_TIMER_CTRL_ST) {
763 static int __maybe_unused omap_dm_timer_runtime_suspend(struct device *dev)
765 struct omap_dm_timer *timer = dev_get_drvdata(dev);
767 atomic_set(&timer->enabled, 0);
769 if (timer->capability & OMAP_TIMER_ALWON || !timer->func_base)
772 omap_timer_save_context(timer);
777 static int __maybe_unused omap_dm_timer_runtime_resume(struct device *dev)
779 struct omap_dm_timer *timer = dev_get_drvdata(dev);
781 if (!(timer->capability & OMAP_TIMER_ALWON) && timer->func_base)
782 omap_timer_restore_context(timer);
784 atomic_set(&timer->enabled, 1);
789 static const struct dev_pm_ops omap_dm_timer_pm_ops = {
790 SET_RUNTIME_PM_OPS(omap_dm_timer_runtime_suspend,
791 omap_dm_timer_runtime_resume, NULL)
794 static const struct of_device_id omap_timer_match[];
797 * omap_dm_timer_probe - probe function called for every registered device
798 * @pdev: pointer to current timer platform device
800 * Called by driver framework at the end of device registration for all
803 static int omap_dm_timer_probe(struct platform_device *pdev)
806 struct omap_dm_timer *timer;
807 struct device *dev = &pdev->dev;
808 const struct dmtimer_platform_data *pdata;
811 pdata = of_device_get_match_data(dev);
813 pdata = dev_get_platdata(dev);
815 dev->platform_data = (void *)pdata;
818 dev_err(dev, "%s: no platform data.\n", __func__);
822 timer = devm_kzalloc(dev, sizeof(*timer), GFP_KERNEL);
826 timer->irq = platform_get_irq(pdev, 0);
830 timer->fclk = ERR_PTR(-ENODEV);
831 timer->io_base = devm_platform_ioremap_resource(pdev, 0);
832 if (IS_ERR(timer->io_base))
833 return PTR_ERR(timer->io_base);
835 platform_set_drvdata(pdev, timer);
838 if (of_find_property(dev->of_node, "ti,timer-alwon", NULL))
839 timer->capability |= OMAP_TIMER_ALWON;
840 if (of_find_property(dev->of_node, "ti,timer-dsp", NULL))
841 timer->capability |= OMAP_TIMER_HAS_DSP_IRQ;
842 if (of_find_property(dev->of_node, "ti,timer-pwm", NULL))
843 timer->capability |= OMAP_TIMER_HAS_PWM;
844 if (of_find_property(dev->of_node, "ti,timer-secure", NULL))
845 timer->capability |= OMAP_TIMER_SECURE;
847 timer->id = pdev->id;
848 timer->capability = pdata->timer_capability;
849 timer->reserved = omap_dm_timer_reserved_systimer(timer->id);
852 if (!(timer->capability & OMAP_TIMER_ALWON)) {
853 timer->nb.notifier_call = omap_timer_context_notifier;
854 cpu_pm_register_notifier(&timer->nb);
858 timer->errata = pdata->timer_errata;
862 pm_runtime_enable(dev);
864 if (!timer->reserved) {
865 ret = pm_runtime_get_sync(dev);
867 dev_err(dev, "%s: pm_runtime_get_sync failed!\n",
871 __omap_dm_timer_init_regs(timer);
875 /* add the timer element to the list */
876 spin_lock_irqsave(&dm_timer_lock, flags);
877 list_add_tail(&timer->node, &omap_timer_list);
878 spin_unlock_irqrestore(&dm_timer_lock, flags);
880 dev_dbg(dev, "Device Probed.\n");
885 pm_runtime_put_noidle(dev);
886 pm_runtime_disable(dev);
891 * omap_dm_timer_remove - cleanup a registered timer device
892 * @pdev: pointer to current timer platform device
894 * Called by driver framework whenever a timer device is unregistered.
895 * In addition to freeing platform resources it also deletes the timer
896 * entry from the local list.
898 static int omap_dm_timer_remove(struct platform_device *pdev)
900 struct omap_dm_timer *timer;
904 spin_lock_irqsave(&dm_timer_lock, flags);
905 list_for_each_entry(timer, &omap_timer_list, node)
906 if (!strcmp(dev_name(&timer->pdev->dev),
907 dev_name(&pdev->dev))) {
908 if (!(timer->capability & OMAP_TIMER_ALWON))
909 cpu_pm_unregister_notifier(&timer->nb);
910 list_del(&timer->node);
914 spin_unlock_irqrestore(&dm_timer_lock, flags);
916 pm_runtime_disable(&pdev->dev);
921 static const struct omap_dm_timer_ops dmtimer_ops = {
922 .request_by_node = omap_dm_timer_request_by_node,
923 .request_specific = omap_dm_timer_request_specific,
924 .request = omap_dm_timer_request,
925 .set_source = omap_dm_timer_set_source,
926 .get_irq = omap_dm_timer_get_irq,
927 .set_int_enable = omap_dm_timer_set_int_enable,
928 .set_int_disable = omap_dm_timer_set_int_disable,
929 .free = omap_dm_timer_free,
930 .enable = omap_dm_timer_enable,
931 .disable = omap_dm_timer_disable,
932 .get_fclk = omap_dm_timer_get_fclk,
933 .start = omap_dm_timer_start,
934 .stop = omap_dm_timer_stop,
935 .set_load = omap_dm_timer_set_load,
936 .set_match = omap_dm_timer_set_match,
937 .set_pwm = omap_dm_timer_set_pwm,
938 .get_pwm_status = omap_dm_timer_get_pwm_status,
939 .set_prescaler = omap_dm_timer_set_prescaler,
940 .read_counter = omap_dm_timer_read_counter,
941 .write_counter = omap_dm_timer_write_counter,
942 .read_status = omap_dm_timer_read_status,
943 .write_status = omap_dm_timer_write_status,
946 static const struct dmtimer_platform_data omap3plus_pdata = {
947 .timer_errata = OMAP_TIMER_ERRATA_I103_I767,
948 .timer_ops = &dmtimer_ops,
951 static const struct of_device_id omap_timer_match[] = {
953 .compatible = "ti,omap2420-timer",
956 .compatible = "ti,omap3430-timer",
957 .data = &omap3plus_pdata,
960 .compatible = "ti,omap4430-timer",
961 .data = &omap3plus_pdata,
964 .compatible = "ti,omap5430-timer",
965 .data = &omap3plus_pdata,
968 .compatible = "ti,am335x-timer",
969 .data = &omap3plus_pdata,
972 .compatible = "ti,am335x-timer-1ms",
973 .data = &omap3plus_pdata,
976 .compatible = "ti,dm816-timer",
977 .data = &omap3plus_pdata,
981 MODULE_DEVICE_TABLE(of, omap_timer_match);
983 static struct platform_driver omap_dm_timer_driver = {
984 .probe = omap_dm_timer_probe,
985 .remove = omap_dm_timer_remove,
987 .name = "omap_timer",
988 .of_match_table = of_match_ptr(omap_timer_match),
989 .pm = &omap_dm_timer_pm_ops,
993 module_platform_driver(omap_dm_timer_driver);
995 MODULE_DESCRIPTION("OMAP Dual-Mode Timer Driver");
996 MODULE_LICENSE("GPL");
997 MODULE_AUTHOR("Texas Instruments Inc");