Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0+
0002 /*
0003  * linux/arch/arm/plat-omap/dmtimer.c
0004  *
0005  * OMAP Dual-Mode Timers
0006  *
0007  * Copyright (C) 2010 Texas Instruments Incorporated - https://www.ti.com/
0008  * Tarun Kanti DebBarma <tarun.kanti@ti.com>
0009  * Thara Gopinath <thara@ti.com>
0010  *
0011  * dmtimer adaptation to platform_driver.
0012  *
0013  * Copyright (C) 2005 Nokia Corporation
0014  * OMAP2 support by Juha Yrjola
0015  * API improvements and OMAP2 clock framework support by Timo Teras
0016  *
0017  * Copyright (C) 2009 Texas Instruments
0018  * Added OMAP4 support - Santosh Shilimkar <santosh.shilimkar@ti.com>
0019  */
0020 
0021 #include <linux/clk.h>
0022 #include <linux/clk-provider.h>
0023 #include <linux/cpu_pm.h>
0024 #include <linux/module.h>
0025 #include <linux/io.h>
0026 #include <linux/device.h>
0027 #include <linux/err.h>
0028 #include <linux/pm_runtime.h>
0029 #include <linux/of.h>
0030 #include <linux/of_device.h>
0031 #include <linux/platform_device.h>
0032 #include <linux/platform_data/dmtimer-omap.h>
0033 
0034 #include <clocksource/timer-ti-dm.h>
0035 
0036 static u32 omap_reserved_systimers;
0037 static LIST_HEAD(omap_timer_list);
0038 static DEFINE_SPINLOCK(dm_timer_lock);
0039 
0040 enum {
0041     REQUEST_ANY = 0,
0042     REQUEST_BY_ID,
0043     REQUEST_BY_CAP,
0044     REQUEST_BY_NODE,
0045 };
0046 
0047 static inline u32 __omap_dm_timer_read(struct omap_dm_timer *timer, u32 reg,
0048                         int posted)
0049 {
0050     if (posted)
0051         while (readl_relaxed(timer->pend) & (reg >> WPSHIFT))
0052             cpu_relax();
0053 
0054     return readl_relaxed(timer->func_base + (reg & 0xff));
0055 }
0056 
0057 static inline void __omap_dm_timer_write(struct omap_dm_timer *timer,
0058                     u32 reg, u32 val, int posted)
0059 {
0060     if (posted)
0061         while (readl_relaxed(timer->pend) & (reg >> WPSHIFT))
0062             cpu_relax();
0063 
0064     writel_relaxed(val, timer->func_base + (reg & 0xff));
0065 }
0066 
0067 static inline void __omap_dm_timer_init_regs(struct omap_dm_timer *timer)
0068 {
0069     u32 tidr;
0070 
0071     /* Assume v1 ip if bits [31:16] are zero */
0072     tidr = readl_relaxed(timer->io_base);
0073     if (!(tidr >> 16)) {
0074         timer->revision = 1;
0075         timer->irq_stat = timer->io_base + OMAP_TIMER_V1_STAT_OFFSET;
0076         timer->irq_ena = timer->io_base + OMAP_TIMER_V1_INT_EN_OFFSET;
0077         timer->irq_dis = timer->io_base + OMAP_TIMER_V1_INT_EN_OFFSET;
0078         timer->pend = timer->io_base + _OMAP_TIMER_WRITE_PEND_OFFSET;
0079         timer->func_base = timer->io_base;
0080     } else {
0081         timer->revision = 2;
0082         timer->irq_stat = timer->io_base + OMAP_TIMER_V2_IRQSTATUS;
0083         timer->irq_ena = timer->io_base + OMAP_TIMER_V2_IRQENABLE_SET;
0084         timer->irq_dis = timer->io_base + OMAP_TIMER_V2_IRQENABLE_CLR;
0085         timer->pend = timer->io_base +
0086             _OMAP_TIMER_WRITE_PEND_OFFSET +
0087                 OMAP_TIMER_V2_FUNC_OFFSET;
0088         timer->func_base = timer->io_base + OMAP_TIMER_V2_FUNC_OFFSET;
0089     }
0090 }
0091 
0092 /*
0093  * __omap_dm_timer_enable_posted - enables write posted mode
0094  * @timer:      pointer to timer instance handle
0095  *
0096  * Enables the write posted mode for the timer. When posted mode is enabled
0097  * writes to certain timer registers are immediately acknowledged by the
0098  * internal bus and hence prevents stalling the CPU waiting for the write to
0099  * complete. Enabling this feature can improve performance for writing to the
0100  * timer registers.
0101  */
0102 static inline void __omap_dm_timer_enable_posted(struct omap_dm_timer *timer)
0103 {
0104     if (timer->posted)
0105         return;
0106 
0107     if (timer->errata & OMAP_TIMER_ERRATA_I103_I767) {
0108         timer->posted = OMAP_TIMER_NONPOSTED;
0109         __omap_dm_timer_write(timer, OMAP_TIMER_IF_CTRL_REG, 0, 0);
0110         return;
0111     }
0112 
0113     __omap_dm_timer_write(timer, OMAP_TIMER_IF_CTRL_REG,
0114                   OMAP_TIMER_CTRL_POSTED, 0);
0115     timer->context.tsicr = OMAP_TIMER_CTRL_POSTED;
0116     timer->posted = OMAP_TIMER_POSTED;
0117 }
0118 
0119 static inline void __omap_dm_timer_stop(struct omap_dm_timer *timer,
0120                     int posted, unsigned long rate)
0121 {
0122     u32 l;
0123 
0124     l = __omap_dm_timer_read(timer, OMAP_TIMER_CTRL_REG, posted);
0125     if (l & OMAP_TIMER_CTRL_ST) {
0126         l &= ~0x1;
0127         __omap_dm_timer_write(timer, OMAP_TIMER_CTRL_REG, l, posted);
0128 #ifdef CONFIG_ARCH_OMAP2PLUS
0129         /* Readback to make sure write has completed */
0130         __omap_dm_timer_read(timer, OMAP_TIMER_CTRL_REG, posted);
0131         /*
0132          * Wait for functional clock period x 3.5 to make sure that
0133          * timer is stopped
0134          */
0135         udelay(3500000 / rate + 1);
0136 #endif
0137     }
0138 
0139     /* Ack possibly pending interrupt */
0140     writel_relaxed(OMAP_TIMER_INT_OVERFLOW, timer->irq_stat);
0141 }
0142 
0143 static inline void __omap_dm_timer_int_enable(struct omap_dm_timer *timer,
0144                         unsigned int value)
0145 {
0146     writel_relaxed(value, timer->irq_ena);
0147     __omap_dm_timer_write(timer, OMAP_TIMER_WAKEUP_EN_REG, value, 0);
0148 }
0149 
0150 static inline unsigned int
0151 __omap_dm_timer_read_counter(struct omap_dm_timer *timer, int posted)
0152 {
0153     return __omap_dm_timer_read(timer, OMAP_TIMER_COUNTER_REG, posted);
0154 }
0155 
0156 static inline void __omap_dm_timer_write_status(struct omap_dm_timer *timer,
0157                         unsigned int value)
0158 {
0159     writel_relaxed(value, timer->irq_stat);
0160 }
0161 
0162 /**
0163  * omap_dm_timer_read_reg - read timer registers in posted and non-posted mode
0164  * @timer:      timer pointer over which read operation to perform
0165  * @reg:        lowest byte holds the register offset
0166  *
0167  * The posted mode bit is encoded in reg. Note that in posted mode write
0168  * pending bit must be checked. Otherwise a read of a non completed write
0169  * will produce an error.
0170  */
0171 static inline u32 omap_dm_timer_read_reg(struct omap_dm_timer *timer, u32 reg)
0172 {
0173     WARN_ON((reg & 0xff) < _OMAP_TIMER_WAKEUP_EN_OFFSET);
0174     return __omap_dm_timer_read(timer, reg, timer->posted);
0175 }
0176 
0177 /**
0178  * omap_dm_timer_write_reg - write timer registers in posted and non-posted mode
0179  * @timer:      timer pointer over which write operation is to perform
0180  * @reg:        lowest byte holds the register offset
0181  * @value:      data to write into the register
0182  *
0183  * The posted mode bit is encoded in reg. Note that in posted mode the write
0184  * pending bit must be checked. Otherwise a write on a register which has a
0185  * pending write will be lost.
0186  */
0187 static void omap_dm_timer_write_reg(struct omap_dm_timer *timer, u32 reg,
0188                         u32 value)
0189 {
0190     WARN_ON((reg & 0xff) < _OMAP_TIMER_WAKEUP_EN_OFFSET);
0191     __omap_dm_timer_write(timer, reg, value, timer->posted);
0192 }
0193 
0194 static void omap_timer_restore_context(struct omap_dm_timer *timer)
0195 {
0196     __omap_dm_timer_write(timer, OMAP_TIMER_OCP_CFG_OFFSET,
0197                   timer->context.ocp_cfg, 0);
0198 
0199     omap_dm_timer_write_reg(timer, OMAP_TIMER_WAKEUP_EN_REG,
0200                 timer->context.twer);
0201     omap_dm_timer_write_reg(timer, OMAP_TIMER_COUNTER_REG,
0202                 timer->context.tcrr);
0203     omap_dm_timer_write_reg(timer, OMAP_TIMER_LOAD_REG,
0204                 timer->context.tldr);
0205     omap_dm_timer_write_reg(timer, OMAP_TIMER_MATCH_REG,
0206                 timer->context.tmar);
0207     omap_dm_timer_write_reg(timer, OMAP_TIMER_IF_CTRL_REG,
0208                 timer->context.tsicr);
0209     writel_relaxed(timer->context.tier, timer->irq_ena);
0210     omap_dm_timer_write_reg(timer, OMAP_TIMER_CTRL_REG,
0211                 timer->context.tclr);
0212 }
0213 
0214 static void omap_timer_save_context(struct omap_dm_timer *timer)
0215 {
0216     timer->context.ocp_cfg =
0217         __omap_dm_timer_read(timer, OMAP_TIMER_OCP_CFG_OFFSET, 0);
0218 
0219     timer->context.tclr =
0220             omap_dm_timer_read_reg(timer, OMAP_TIMER_CTRL_REG);
0221     timer->context.twer =
0222             omap_dm_timer_read_reg(timer, OMAP_TIMER_WAKEUP_EN_REG);
0223     timer->context.tldr =
0224             omap_dm_timer_read_reg(timer, OMAP_TIMER_LOAD_REG);
0225     timer->context.tmar =
0226             omap_dm_timer_read_reg(timer, OMAP_TIMER_MATCH_REG);
0227     timer->context.tier = readl_relaxed(timer->irq_ena);
0228     timer->context.tsicr =
0229             omap_dm_timer_read_reg(timer, OMAP_TIMER_IF_CTRL_REG);
0230 }
0231 
0232 static int omap_timer_context_notifier(struct notifier_block *nb,
0233                        unsigned long cmd, void *v)
0234 {
0235     struct omap_dm_timer *timer;
0236 
0237     timer = container_of(nb, struct omap_dm_timer, nb);
0238 
0239     switch (cmd) {
0240     case CPU_CLUSTER_PM_ENTER:
0241         if ((timer->capability & OMAP_TIMER_ALWON) ||
0242             !atomic_read(&timer->enabled))
0243             break;
0244         omap_timer_save_context(timer);
0245         break;
0246     case CPU_CLUSTER_PM_ENTER_FAILED:   /* No need to restore context */
0247         break;
0248     case CPU_CLUSTER_PM_EXIT:
0249         if ((timer->capability & OMAP_TIMER_ALWON) ||
0250             !atomic_read(&timer->enabled))
0251             break;
0252         omap_timer_restore_context(timer);
0253         break;
0254     }
0255 
0256     return NOTIFY_OK;
0257 }
0258 
0259 static int omap_dm_timer_reset(struct omap_dm_timer *timer)
0260 {
0261     u32 l, timeout = 100000;
0262 
0263     if (timer->revision != 1)
0264         return -EINVAL;
0265 
0266     omap_dm_timer_write_reg(timer, OMAP_TIMER_IF_CTRL_REG, 0x06);
0267 
0268     do {
0269         l = __omap_dm_timer_read(timer,
0270                      OMAP_TIMER_V1_SYS_STAT_OFFSET, 0);
0271     } while (!l && timeout--);
0272 
0273     if (!timeout) {
0274         dev_err(&timer->pdev->dev, "Timer failed to reset\n");
0275         return -ETIMEDOUT;
0276     }
0277 
0278     /* Configure timer for smart-idle mode */
0279     l = __omap_dm_timer_read(timer, OMAP_TIMER_OCP_CFG_OFFSET, 0);
0280     l |= 0x2 << 0x3;
0281     __omap_dm_timer_write(timer, OMAP_TIMER_OCP_CFG_OFFSET, l, 0);
0282 
0283     timer->posted = 0;
0284 
0285     return 0;
0286 }
0287 
0288 static int omap_dm_timer_set_source(struct omap_dm_timer *timer, int source)
0289 {
0290     int ret;
0291     const char *parent_name;
0292     struct clk *parent;
0293     struct dmtimer_platform_data *pdata;
0294 
0295     if (unlikely(!timer) || IS_ERR(timer->fclk))
0296         return -EINVAL;
0297 
0298     switch (source) {
0299     case OMAP_TIMER_SRC_SYS_CLK:
0300         parent_name = "timer_sys_ck";
0301         break;
0302     case OMAP_TIMER_SRC_32_KHZ:
0303         parent_name = "timer_32k_ck";
0304         break;
0305     case OMAP_TIMER_SRC_EXT_CLK:
0306         parent_name = "timer_ext_ck";
0307         break;
0308     default:
0309         return -EINVAL;
0310     }
0311 
0312     pdata = timer->pdev->dev.platform_data;
0313 
0314     /*
0315      * FIXME: Used for OMAP1 devices only because they do not currently
0316      * use the clock framework to set the parent clock. To be removed
0317      * once OMAP1 migrated to using clock framework for dmtimers
0318      */
0319     if (pdata && pdata->set_timer_src)
0320         return pdata->set_timer_src(timer->pdev, source);
0321 
0322 #if defined(CONFIG_COMMON_CLK)
0323     /* Check if the clock has configurable parents */
0324     if (clk_hw_get_num_parents(__clk_get_hw(timer->fclk)) < 2)
0325         return 0;
0326 #endif
0327 
0328     parent = clk_get(&timer->pdev->dev, parent_name);
0329     if (IS_ERR(parent)) {
0330         pr_err("%s: %s not found\n", __func__, parent_name);
0331         return -EINVAL;
0332     }
0333 
0334     ret = clk_set_parent(timer->fclk, parent);
0335     if (ret < 0)
0336         pr_err("%s: failed to set %s as parent\n", __func__,
0337             parent_name);
0338 
0339     clk_put(parent);
0340 
0341     return ret;
0342 }
0343 
0344 static void omap_dm_timer_enable(struct omap_dm_timer *timer)
0345 {
0346     pm_runtime_get_sync(&timer->pdev->dev);
0347 }
0348 
0349 static void omap_dm_timer_disable(struct omap_dm_timer *timer)
0350 {
0351     pm_runtime_put_sync(&timer->pdev->dev);
0352 }
0353 
0354 static int omap_dm_timer_prepare(struct omap_dm_timer *timer)
0355 {
0356     int rc;
0357 
0358     /*
0359      * FIXME: OMAP1 devices do not use the clock framework for dmtimers so
0360      * do not call clk_get() for these devices.
0361      */
0362     if (!(timer->capability & OMAP_TIMER_NEEDS_RESET)) {
0363         timer->fclk = clk_get(&timer->pdev->dev, "fck");
0364         if (WARN_ON_ONCE(IS_ERR(timer->fclk))) {
0365             dev_err(&timer->pdev->dev, ": No fclk handle.\n");
0366             return -EINVAL;
0367         }
0368     }
0369 
0370     omap_dm_timer_enable(timer);
0371 
0372     if (timer->capability & OMAP_TIMER_NEEDS_RESET) {
0373         rc = omap_dm_timer_reset(timer);
0374         if (rc) {
0375             omap_dm_timer_disable(timer);
0376             return rc;
0377         }
0378     }
0379 
0380     __omap_dm_timer_enable_posted(timer);
0381     omap_dm_timer_disable(timer);
0382 
0383     return 0;
0384 }
0385 
0386 static inline u32 omap_dm_timer_reserved_systimer(int id)
0387 {
0388     return (omap_reserved_systimers & (1 << (id - 1))) ? 1 : 0;
0389 }
0390 
0391 int omap_dm_timer_reserve_systimer(int id)
0392 {
0393     if (omap_dm_timer_reserved_systimer(id))
0394         return -ENODEV;
0395 
0396     omap_reserved_systimers |= (1 << (id - 1));
0397 
0398     return 0;
0399 }
0400 
0401 static struct omap_dm_timer *_omap_dm_timer_request(int req_type, void *data)
0402 {
0403     struct omap_dm_timer *timer = NULL, *t;
0404     struct device_node *np = NULL;
0405     unsigned long flags;
0406     u32 cap = 0;
0407     int id = 0;
0408 
0409     switch (req_type) {
0410     case REQUEST_BY_ID:
0411         id = *(int *)data;
0412         break;
0413     case REQUEST_BY_CAP:
0414         cap = *(u32 *)data;
0415         break;
0416     case REQUEST_BY_NODE:
0417         np = (struct device_node *)data;
0418         break;
0419     default:
0420         /* REQUEST_ANY */
0421         break;
0422     }
0423 
0424     spin_lock_irqsave(&dm_timer_lock, flags);
0425     list_for_each_entry(t, &omap_timer_list, node) {
0426         if (t->reserved)
0427             continue;
0428 
0429         switch (req_type) {
0430         case REQUEST_BY_ID:
0431             if (id == t->pdev->id) {
0432                 timer = t;
0433                 timer->reserved = 1;
0434                 goto found;
0435             }
0436             break;
0437         case REQUEST_BY_CAP:
0438             if (cap == (t->capability & cap)) {
0439                 /*
0440                  * If timer is not NULL, we have already found
0441                  * one timer. But it was not an exact match
0442                  * because it had more capabilities than what
0443                  * was required. Therefore, unreserve the last
0444                  * timer found and see if this one is a better
0445                  * match.
0446                  */
0447                 if (timer)
0448                     timer->reserved = 0;
0449                 timer = t;
0450                 timer->reserved = 1;
0451 
0452                 /* Exit loop early if we find an exact match */
0453                 if (t->capability == cap)
0454                     goto found;
0455             }
0456             break;
0457         case REQUEST_BY_NODE:
0458             if (np == t->pdev->dev.of_node) {
0459                 timer = t;
0460                 timer->reserved = 1;
0461                 goto found;
0462             }
0463             break;
0464         default:
0465             /* REQUEST_ANY */
0466             timer = t;
0467             timer->reserved = 1;
0468             goto found;
0469         }
0470     }
0471 found:
0472     spin_unlock_irqrestore(&dm_timer_lock, flags);
0473 
0474     if (timer && omap_dm_timer_prepare(timer)) {
0475         timer->reserved = 0;
0476         timer = NULL;
0477     }
0478 
0479     if (!timer)
0480         pr_debug("%s: timer request failed!\n", __func__);
0481 
0482     return timer;
0483 }
0484 
0485 static struct omap_dm_timer *omap_dm_timer_request(void)
0486 {
0487     return _omap_dm_timer_request(REQUEST_ANY, NULL);
0488 }
0489 
0490 static struct omap_dm_timer *omap_dm_timer_request_specific(int id)
0491 {
0492     /* Requesting timer by ID is not supported when device tree is used */
0493     if (of_have_populated_dt()) {
0494         pr_warn("%s: Please use omap_dm_timer_request_by_node()\n",
0495             __func__);
0496         return NULL;
0497     }
0498 
0499     return _omap_dm_timer_request(REQUEST_BY_ID, &id);
0500 }
0501 
0502 /**
0503  * omap_dm_timer_request_by_cap - Request a timer by capability
0504  * @cap:    Bit mask of capabilities to match
0505  *
0506  * Find a timer based upon capabilities bit mask. Callers of this function
0507  * should use the definitions found in the plat/dmtimer.h file under the
0508  * comment "timer capabilities used in hwmod database". Returns pointer to
0509  * timer handle on success and a NULL pointer on failure.
0510  */
0511 struct omap_dm_timer *omap_dm_timer_request_by_cap(u32 cap)
0512 {
0513     return _omap_dm_timer_request(REQUEST_BY_CAP, &cap);
0514 }
0515 
0516 /**
0517  * omap_dm_timer_request_by_node - Request a timer by device-tree node
0518  * @np:     Pointer to device-tree timer node
0519  *
0520  * Request a timer based upon a device node pointer. Returns pointer to
0521  * timer handle on success and a NULL pointer on failure.
0522  */
0523 static struct omap_dm_timer *omap_dm_timer_request_by_node(struct device_node *np)
0524 {
0525     if (!np)
0526         return NULL;
0527 
0528     return _omap_dm_timer_request(REQUEST_BY_NODE, np);
0529 }
0530 
0531 static int omap_dm_timer_free(struct omap_dm_timer *timer)
0532 {
0533     if (unlikely(!timer))
0534         return -EINVAL;
0535 
0536     clk_put(timer->fclk);
0537 
0538     WARN_ON(!timer->reserved);
0539     timer->reserved = 0;
0540     return 0;
0541 }
0542 
0543 int omap_dm_timer_get_irq(struct omap_dm_timer *timer)
0544 {
0545     if (timer)
0546         return timer->irq;
0547     return -EINVAL;
0548 }
0549 
0550 #if defined(CONFIG_ARCH_OMAP1)
0551 #include <linux/soc/ti/omap1-io.h>
0552 
0553 static struct clk *omap_dm_timer_get_fclk(struct omap_dm_timer *timer)
0554 {
0555     return NULL;
0556 }
0557 
0558 /**
0559  * omap_dm_timer_modify_idlect_mask - Check if any running timers use ARMXOR
0560  * @inputmask: current value of idlect mask
0561  */
0562 __u32 omap_dm_timer_modify_idlect_mask(__u32 inputmask)
0563 {
0564     int i = 0;
0565     struct omap_dm_timer *timer = NULL;
0566     unsigned long flags;
0567 
0568     /* If ARMXOR cannot be idled this function call is unnecessary */
0569     if (!(inputmask & (1 << 1)))
0570         return inputmask;
0571 
0572     /* If any active timer is using ARMXOR return modified mask */
0573     spin_lock_irqsave(&dm_timer_lock, flags);
0574     list_for_each_entry(timer, &omap_timer_list, node) {
0575         u32 l;
0576 
0577         l = omap_dm_timer_read_reg(timer, OMAP_TIMER_CTRL_REG);
0578         if (l & OMAP_TIMER_CTRL_ST) {
0579             if (((omap_readl(MOD_CONF_CTRL_1) >> (i * 2)) & 0x03) == 0)
0580                 inputmask &= ~(1 << 1);
0581             else
0582                 inputmask &= ~(1 << 2);
0583         }
0584         i++;
0585     }
0586     spin_unlock_irqrestore(&dm_timer_lock, flags);
0587 
0588     return inputmask;
0589 }
0590 
0591 #else
0592 
0593 static struct clk *omap_dm_timer_get_fclk(struct omap_dm_timer *timer)
0594 {
0595     if (timer && !IS_ERR(timer->fclk))
0596         return timer->fclk;
0597     return NULL;
0598 }
0599 
0600 __u32 omap_dm_timer_modify_idlect_mask(__u32 inputmask)
0601 {
0602     BUG();
0603 
0604     return 0;
0605 }
0606 
0607 #endif
0608 
0609 int omap_dm_timer_trigger(struct omap_dm_timer *timer)
0610 {
0611     if (unlikely(!timer || !atomic_read(&timer->enabled))) {
0612         pr_err("%s: timer not available or enabled.\n", __func__);
0613         return -EINVAL;
0614     }
0615 
0616     omap_dm_timer_write_reg(timer, OMAP_TIMER_TRIGGER_REG, 0);
0617     return 0;
0618 }
0619 
0620 static int omap_dm_timer_start(struct omap_dm_timer *timer)
0621 {
0622     u32 l;
0623 
0624     if (unlikely(!timer))
0625         return -EINVAL;
0626 
0627     omap_dm_timer_enable(timer);
0628 
0629     l = omap_dm_timer_read_reg(timer, OMAP_TIMER_CTRL_REG);
0630     if (!(l & OMAP_TIMER_CTRL_ST)) {
0631         l |= OMAP_TIMER_CTRL_ST;
0632         omap_dm_timer_write_reg(timer, OMAP_TIMER_CTRL_REG, l);
0633     }
0634 
0635     return 0;
0636 }
0637 
0638 static int omap_dm_timer_stop(struct omap_dm_timer *timer)
0639 {
0640     unsigned long rate = 0;
0641 
0642     if (unlikely(!timer))
0643         return -EINVAL;
0644 
0645     if (!(timer->capability & OMAP_TIMER_NEEDS_RESET))
0646         rate = clk_get_rate(timer->fclk);
0647 
0648     __omap_dm_timer_stop(timer, timer->posted, rate);
0649 
0650     omap_dm_timer_disable(timer);
0651     return 0;
0652 }
0653 
0654 static int omap_dm_timer_set_load(struct omap_dm_timer *timer,
0655                   unsigned int load)
0656 {
0657     if (unlikely(!timer))
0658         return -EINVAL;
0659 
0660     omap_dm_timer_enable(timer);
0661     omap_dm_timer_write_reg(timer, OMAP_TIMER_LOAD_REG, load);
0662 
0663     omap_dm_timer_disable(timer);
0664     return 0;
0665 }
0666 
0667 static int omap_dm_timer_set_match(struct omap_dm_timer *timer, int enable,
0668                    unsigned int match)
0669 {
0670     u32 l;
0671 
0672     if (unlikely(!timer))
0673         return -EINVAL;
0674 
0675     omap_dm_timer_enable(timer);
0676     l = omap_dm_timer_read_reg(timer, OMAP_TIMER_CTRL_REG);
0677     if (enable)
0678         l |= OMAP_TIMER_CTRL_CE;
0679     else
0680         l &= ~OMAP_TIMER_CTRL_CE;
0681     omap_dm_timer_write_reg(timer, OMAP_TIMER_MATCH_REG, match);
0682     omap_dm_timer_write_reg(timer, OMAP_TIMER_CTRL_REG, l);
0683 
0684     omap_dm_timer_disable(timer);
0685     return 0;
0686 }
0687 
0688 static int omap_dm_timer_set_pwm(struct omap_dm_timer *timer, int def_on,
0689                  int toggle, int trigger, int autoreload)
0690 {
0691     u32 l;
0692 
0693     if (unlikely(!timer))
0694         return -EINVAL;
0695 
0696     omap_dm_timer_enable(timer);
0697     l = omap_dm_timer_read_reg(timer, OMAP_TIMER_CTRL_REG);
0698     l &= ~(OMAP_TIMER_CTRL_GPOCFG | OMAP_TIMER_CTRL_SCPWM |
0699            OMAP_TIMER_CTRL_PT | (0x03 << 10) | OMAP_TIMER_CTRL_AR);
0700     if (def_on)
0701         l |= OMAP_TIMER_CTRL_SCPWM;
0702     if (toggle)
0703         l |= OMAP_TIMER_CTRL_PT;
0704     l |= trigger << 10;
0705     if (autoreload)
0706         l |= OMAP_TIMER_CTRL_AR;
0707     omap_dm_timer_write_reg(timer, OMAP_TIMER_CTRL_REG, l);
0708 
0709     omap_dm_timer_disable(timer);
0710     return 0;
0711 }
0712 
0713 static int omap_dm_timer_get_pwm_status(struct omap_dm_timer *timer)
0714 {
0715     u32 l;
0716 
0717     if (unlikely(!timer))
0718         return -EINVAL;
0719 
0720     omap_dm_timer_enable(timer);
0721     l = omap_dm_timer_read_reg(timer, OMAP_TIMER_CTRL_REG);
0722     omap_dm_timer_disable(timer);
0723 
0724     return l;
0725 }
0726 
0727 static int omap_dm_timer_set_prescaler(struct omap_dm_timer *timer,
0728                     int prescaler)
0729 {
0730     u32 l;
0731 
0732     if (unlikely(!timer) || prescaler < -1 || prescaler > 7)
0733         return -EINVAL;
0734 
0735     omap_dm_timer_enable(timer);
0736     l = omap_dm_timer_read_reg(timer, OMAP_TIMER_CTRL_REG);
0737     l &= ~(OMAP_TIMER_CTRL_PRE | (0x07 << 2));
0738     if (prescaler >= 0) {
0739         l |= OMAP_TIMER_CTRL_PRE;
0740         l |= prescaler << 2;
0741     }
0742     omap_dm_timer_write_reg(timer, OMAP_TIMER_CTRL_REG, l);
0743 
0744     omap_dm_timer_disable(timer);
0745     return 0;
0746 }
0747 
0748 static int omap_dm_timer_set_int_enable(struct omap_dm_timer *timer,
0749                     unsigned int value)
0750 {
0751     if (unlikely(!timer))
0752         return -EINVAL;
0753 
0754     omap_dm_timer_enable(timer);
0755     __omap_dm_timer_int_enable(timer, value);
0756 
0757     omap_dm_timer_disable(timer);
0758     return 0;
0759 }
0760 
0761 /**
0762  * omap_dm_timer_set_int_disable - disable timer interrupts
0763  * @timer:  pointer to timer handle
0764  * @mask:   bit mask of interrupts to be disabled
0765  *
0766  * Disables the specified timer interrupts for a timer.
0767  */
0768 static int omap_dm_timer_set_int_disable(struct omap_dm_timer *timer, u32 mask)
0769 {
0770     u32 l = mask;
0771 
0772     if (unlikely(!timer))
0773         return -EINVAL;
0774 
0775     omap_dm_timer_enable(timer);
0776 
0777     if (timer->revision == 1)
0778         l = readl_relaxed(timer->irq_ena) & ~mask;
0779 
0780     writel_relaxed(l, timer->irq_dis);
0781     l = omap_dm_timer_read_reg(timer, OMAP_TIMER_WAKEUP_EN_REG) & ~mask;
0782     omap_dm_timer_write_reg(timer, OMAP_TIMER_WAKEUP_EN_REG, l);
0783 
0784     omap_dm_timer_disable(timer);
0785     return 0;
0786 }
0787 
0788 static unsigned int omap_dm_timer_read_status(struct omap_dm_timer *timer)
0789 {
0790     unsigned int l;
0791 
0792     if (unlikely(!timer || !atomic_read(&timer->enabled))) {
0793         pr_err("%s: timer not available or enabled.\n", __func__);
0794         return 0;
0795     }
0796 
0797     l = readl_relaxed(timer->irq_stat);
0798 
0799     return l;
0800 }
0801 
0802 static int omap_dm_timer_write_status(struct omap_dm_timer *timer, unsigned int value)
0803 {
0804     if (unlikely(!timer || !atomic_read(&timer->enabled)))
0805         return -EINVAL;
0806 
0807     __omap_dm_timer_write_status(timer, value);
0808 
0809     return 0;
0810 }
0811 
0812 static unsigned int omap_dm_timer_read_counter(struct omap_dm_timer *timer)
0813 {
0814     if (unlikely(!timer || !atomic_read(&timer->enabled))) {
0815         pr_err("%s: timer not iavailable or enabled.\n", __func__);
0816         return 0;
0817     }
0818 
0819     return __omap_dm_timer_read_counter(timer, timer->posted);
0820 }
0821 
0822 static int omap_dm_timer_write_counter(struct omap_dm_timer *timer, unsigned int value)
0823 {
0824     if (unlikely(!timer || !atomic_read(&timer->enabled))) {
0825         pr_err("%s: timer not available or enabled.\n", __func__);
0826         return -EINVAL;
0827     }
0828 
0829     omap_dm_timer_write_reg(timer, OMAP_TIMER_COUNTER_REG, value);
0830 
0831     /* Save the context */
0832     timer->context.tcrr = value;
0833     return 0;
0834 }
0835 
0836 int omap_dm_timers_active(void)
0837 {
0838     struct omap_dm_timer *timer;
0839 
0840     list_for_each_entry(timer, &omap_timer_list, node) {
0841         if (!timer->reserved)
0842             continue;
0843 
0844         if (omap_dm_timer_read_reg(timer, OMAP_TIMER_CTRL_REG) &
0845             OMAP_TIMER_CTRL_ST) {
0846             return 1;
0847         }
0848     }
0849     return 0;
0850 }
0851 
0852 static int __maybe_unused omap_dm_timer_runtime_suspend(struct device *dev)
0853 {
0854     struct omap_dm_timer *timer = dev_get_drvdata(dev);
0855 
0856     atomic_set(&timer->enabled, 0);
0857 
0858     if (timer->capability & OMAP_TIMER_ALWON || !timer->func_base)
0859         return 0;
0860 
0861     omap_timer_save_context(timer);
0862 
0863     return 0;
0864 }
0865 
0866 static int __maybe_unused omap_dm_timer_runtime_resume(struct device *dev)
0867 {
0868     struct omap_dm_timer *timer = dev_get_drvdata(dev);
0869 
0870     if (!(timer->capability & OMAP_TIMER_ALWON) && timer->func_base)
0871         omap_timer_restore_context(timer);
0872 
0873     atomic_set(&timer->enabled, 1);
0874 
0875     return 0;
0876 }
0877 
0878 static const struct dev_pm_ops omap_dm_timer_pm_ops = {
0879     SET_RUNTIME_PM_OPS(omap_dm_timer_runtime_suspend,
0880                omap_dm_timer_runtime_resume, NULL)
0881 };
0882 
0883 static const struct of_device_id omap_timer_match[];
0884 
0885 /**
0886  * omap_dm_timer_probe - probe function called for every registered device
0887  * @pdev:   pointer to current timer platform device
0888  *
0889  * Called by driver framework at the end of device registration for all
0890  * timer devices.
0891  */
0892 static int omap_dm_timer_probe(struct platform_device *pdev)
0893 {
0894     unsigned long flags;
0895     struct omap_dm_timer *timer;
0896     struct device *dev = &pdev->dev;
0897     const struct dmtimer_platform_data *pdata;
0898     int ret;
0899 
0900     pdata = of_device_get_match_data(dev);
0901     if (!pdata)
0902         pdata = dev_get_platdata(dev);
0903     else
0904         dev->platform_data = (void *)pdata;
0905 
0906     if (!pdata) {
0907         dev_err(dev, "%s: no platform data.\n", __func__);
0908         return -ENODEV;
0909     }
0910 
0911     timer = devm_kzalloc(dev, sizeof(*timer), GFP_KERNEL);
0912     if (!timer)
0913         return  -ENOMEM;
0914 
0915     timer->irq = platform_get_irq(pdev, 0);
0916     if (timer->irq < 0)
0917         return timer->irq;
0918 
0919     timer->fclk = ERR_PTR(-ENODEV);
0920     timer->io_base = devm_platform_ioremap_resource(pdev, 0);
0921     if (IS_ERR(timer->io_base))
0922         return PTR_ERR(timer->io_base);
0923 
0924     platform_set_drvdata(pdev, timer);
0925 
0926     if (dev->of_node) {
0927         if (of_find_property(dev->of_node, "ti,timer-alwon", NULL))
0928             timer->capability |= OMAP_TIMER_ALWON;
0929         if (of_find_property(dev->of_node, "ti,timer-dsp", NULL))
0930             timer->capability |= OMAP_TIMER_HAS_DSP_IRQ;
0931         if (of_find_property(dev->of_node, "ti,timer-pwm", NULL))
0932             timer->capability |= OMAP_TIMER_HAS_PWM;
0933         if (of_find_property(dev->of_node, "ti,timer-secure", NULL))
0934             timer->capability |= OMAP_TIMER_SECURE;
0935     } else {
0936         timer->id = pdev->id;
0937         timer->capability = pdata->timer_capability;
0938         timer->reserved = omap_dm_timer_reserved_systimer(timer->id);
0939     }
0940 
0941     if (!(timer->capability & OMAP_TIMER_ALWON)) {
0942         timer->nb.notifier_call = omap_timer_context_notifier;
0943         cpu_pm_register_notifier(&timer->nb);
0944     }
0945 
0946     timer->errata = pdata->timer_errata;
0947 
0948     timer->pdev = pdev;
0949 
0950     pm_runtime_enable(dev);
0951 
0952     if (!timer->reserved) {
0953         ret = pm_runtime_get_sync(dev);
0954         if (ret < 0) {
0955             dev_err(dev, "%s: pm_runtime_get_sync failed!\n",
0956                 __func__);
0957             goto err_get_sync;
0958         }
0959         __omap_dm_timer_init_regs(timer);
0960         pm_runtime_put(dev);
0961     }
0962 
0963     /* add the timer element to the list */
0964     spin_lock_irqsave(&dm_timer_lock, flags);
0965     list_add_tail(&timer->node, &omap_timer_list);
0966     spin_unlock_irqrestore(&dm_timer_lock, flags);
0967 
0968     dev_dbg(dev, "Device Probed.\n");
0969 
0970     return 0;
0971 
0972 err_get_sync:
0973     pm_runtime_put_noidle(dev);
0974     pm_runtime_disable(dev);
0975     return ret;
0976 }
0977 
0978 /**
0979  * omap_dm_timer_remove - cleanup a registered timer device
0980  * @pdev:   pointer to current timer platform device
0981  *
0982  * Called by driver framework whenever a timer device is unregistered.
0983  * In addition to freeing platform resources it also deletes the timer
0984  * entry from the local list.
0985  */
0986 static int omap_dm_timer_remove(struct platform_device *pdev)
0987 {
0988     struct omap_dm_timer *timer;
0989     unsigned long flags;
0990     int ret = -EINVAL;
0991 
0992     spin_lock_irqsave(&dm_timer_lock, flags);
0993     list_for_each_entry(timer, &omap_timer_list, node)
0994         if (!strcmp(dev_name(&timer->pdev->dev),
0995                 dev_name(&pdev->dev))) {
0996             if (!(timer->capability & OMAP_TIMER_ALWON))
0997                 cpu_pm_unregister_notifier(&timer->nb);
0998             list_del(&timer->node);
0999             ret = 0;
1000             break;
1001         }
1002     spin_unlock_irqrestore(&dm_timer_lock, flags);
1003 
1004     pm_runtime_disable(&pdev->dev);
1005 
1006     return ret;
1007 }
1008 
1009 static const struct omap_dm_timer_ops dmtimer_ops = {
1010     .request_by_node = omap_dm_timer_request_by_node,
1011     .request_specific = omap_dm_timer_request_specific,
1012     .request = omap_dm_timer_request,
1013     .set_source = omap_dm_timer_set_source,
1014     .get_irq = omap_dm_timer_get_irq,
1015     .set_int_enable = omap_dm_timer_set_int_enable,
1016     .set_int_disable = omap_dm_timer_set_int_disable,
1017     .free = omap_dm_timer_free,
1018     .enable = omap_dm_timer_enable,
1019     .disable = omap_dm_timer_disable,
1020     .get_fclk = omap_dm_timer_get_fclk,
1021     .start = omap_dm_timer_start,
1022     .stop = omap_dm_timer_stop,
1023     .set_load = omap_dm_timer_set_load,
1024     .set_match = omap_dm_timer_set_match,
1025     .set_pwm = omap_dm_timer_set_pwm,
1026     .get_pwm_status = omap_dm_timer_get_pwm_status,
1027     .set_prescaler = omap_dm_timer_set_prescaler,
1028     .read_counter = omap_dm_timer_read_counter,
1029     .write_counter = omap_dm_timer_write_counter,
1030     .read_status = omap_dm_timer_read_status,
1031     .write_status = omap_dm_timer_write_status,
1032 };
1033 
1034 static const struct dmtimer_platform_data omap3plus_pdata = {
1035     .timer_errata = OMAP_TIMER_ERRATA_I103_I767,
1036     .timer_ops = &dmtimer_ops,
1037 };
1038 
1039 static const struct dmtimer_platform_data am6_pdata = {
1040     .timer_ops = &dmtimer_ops,
1041 };
1042 
1043 static const struct of_device_id omap_timer_match[] = {
1044     {
1045         .compatible = "ti,omap2420-timer",
1046     },
1047     {
1048         .compatible = "ti,omap3430-timer",
1049         .data = &omap3plus_pdata,
1050     },
1051     {
1052         .compatible = "ti,omap4430-timer",
1053         .data = &omap3plus_pdata,
1054     },
1055     {
1056         .compatible = "ti,omap5430-timer",
1057         .data = &omap3plus_pdata,
1058     },
1059     {
1060         .compatible = "ti,am335x-timer",
1061         .data = &omap3plus_pdata,
1062     },
1063     {
1064         .compatible = "ti,am335x-timer-1ms",
1065         .data = &omap3plus_pdata,
1066     },
1067     {
1068         .compatible = "ti,dm816-timer",
1069         .data = &omap3plus_pdata,
1070     },
1071     {
1072         .compatible = "ti,am654-timer",
1073         .data = &am6_pdata,
1074     },
1075     {},
1076 };
1077 MODULE_DEVICE_TABLE(of, omap_timer_match);
1078 
1079 static struct platform_driver omap_dm_timer_driver = {
1080     .probe  = omap_dm_timer_probe,
1081     .remove = omap_dm_timer_remove,
1082     .driver = {
1083         .name   = "omap_timer",
1084         .of_match_table = of_match_ptr(omap_timer_match),
1085         .pm = &omap_dm_timer_pm_ops,
1086     },
1087 };
1088 
1089 module_platform_driver(omap_dm_timer_driver);
1090 
1091 MODULE_DESCRIPTION("OMAP Dual-Mode Timer Driver");
1092 MODULE_LICENSE("GPL");
1093 MODULE_AUTHOR("Texas Instruments Inc");