cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

timer-ti-dm.c (23632B)


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