diff options
-rw-r--r-- | arch/arm/mach-omap1/timer.c | 1 | ||||
-rw-r--r-- | arch/arm/mach-omap1/timer32k.c | 1 | ||||
-rw-r--r-- | arch/arm/mach-omap2/omap_hwmod_2420_data.c | 1 | ||||
-rw-r--r-- | arch/arm/mach-omap2/omap_hwmod_2430_data.c | 1 | ||||
-rw-r--r-- | arch/arm/mach-omap2/pm-debug.c | 1 | ||||
-rw-r--r-- | arch/arm/mach-omap2/timer.c | 36 | ||||
-rw-r--r-- | arch/arm/plat-omap/dmtimer.c | 54 | ||||
-rw-r--r-- | arch/arm/plat-omap/include/plat/dmtimer.h | 80 | ||||
-rw-r--r-- | drivers/staging/tidspbridge/core/ue_deh.c | 1 | ||||
-rw-r--r-- | include/linux/platform_data/dmtimer-omap.h | 31 |
10 files changed, 105 insertions, 102 deletions
diff --git a/arch/arm/mach-omap1/timer.c b/arch/arm/mach-omap1/timer.c index cdeb9d3..bde7a35 100644 --- a/arch/arm/mach-omap1/timer.c +++ b/arch/arm/mach-omap1/timer.c @@ -25,6 +25,7 @@ #include <linux/err.h> #include <linux/slab.h> #include <linux/platform_device.h> +#include <linux/platform_data/dmtimer-omap.h> #include <mach/irqs.h> diff --git a/arch/arm/mach-omap1/timer32k.c b/arch/arm/mach-omap1/timer32k.c index 8936819..41152fa 100644 --- a/arch/arm/mach-omap1/timer32k.c +++ b/arch/arm/mach-omap1/timer32k.c @@ -51,7 +51,6 @@ #include <asm/mach/time.h> #include <plat/counter-32k.h> -#include <plat/dmtimer.h> #include <mach/hardware.h> diff --git a/arch/arm/mach-omap2/omap_hwmod_2420_data.c b/arch/arm/mach-omap2/omap_hwmod_2420_data.c index a8b3368..e8efe3d 100644 --- a/arch/arm/mach-omap2/omap_hwmod_2420_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_2420_data.c @@ -17,7 +17,6 @@ #include <linux/platform_data/spi-omap2-mcspi.h> #include <plat-omap/dma-omap.h> -#include <plat/dmtimer.h> #include "omap_hwmod.h" #include "l3_2xxx.h" diff --git a/arch/arm/mach-omap2/omap_hwmod_2430_data.c b/arch/arm/mach-omap2/omap_hwmod_2430_data.c index dc768c5..32d17e3 100644 --- a/arch/arm/mach-omap2/omap_hwmod_2430_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_2430_data.c @@ -18,7 +18,6 @@ #include <linux/platform_data/spi-omap2-mcspi.h> #include <plat-omap/dma-omap.h> -#include <plat/dmtimer.h> #include "omap_hwmod.h" #include "mmc.h" diff --git a/arch/arm/mach-omap2/pm-debug.c b/arch/arm/mach-omap2/pm-debug.c index 3cf4fdfd..e2c291f 100644 --- a/arch/arm/mach-omap2/pm-debug.c +++ b/arch/arm/mach-omap2/pm-debug.c @@ -30,7 +30,6 @@ #include "clock.h" #include "powerdomain.h" #include "clockdomain.h" -#include <plat/dmtimer.h> #include "omap-pm.h" #include "soc.h" diff --git a/arch/arm/mach-omap2/timer.c b/arch/arm/mach-omap2/timer.c index 099e406..b7f43a2 100644 --- a/arch/arm/mach-omap2/timer.c +++ b/arch/arm/mach-omap2/timer.c @@ -39,6 +39,8 @@ #include <linux/of.h> #include <linux/of_address.h> #include <linux/of_irq.h> +#include <linux/platform_device.h> +#include <linux/platform_data/dmtimer-omap.h> #include <asm/mach/time.h> #include <asm/smp_twd.h> @@ -160,11 +162,6 @@ static struct of_device_id omap_timer_match[] __initdata = { { } }; -static struct of_device_id omap_counter_match[] __initdata = { - { .compatible = "ti,omap-counter32k", }, - { } -}; - /** * omap_get_timer_dt - get a timer using device-tree * @match - device-tree match structure for matching a device type @@ -245,10 +242,8 @@ static int __init omap_dm_timer_init_one(struct omap_dm_timer *timer, const char *oh_name; struct device_node *np; struct omap_hwmod *oh; - struct resource irq_rsrc, mem_rsrc; - size_t size; - int res = 0; - int r; + struct resource irq, mem; + int r = 0; if (of_have_populated_dt()) { np = omap_get_timer_dt(omap_timer_match, NULL); @@ -280,20 +275,18 @@ static int __init omap_dm_timer_init_one(struct omap_dm_timer *timer, if (!of_have_populated_dt()) { r = omap_hwmod_get_resource_byname(oh, IORESOURCE_IRQ, NULL, - &irq_rsrc); + &irq); if (r) return -ENXIO; - timer->irq = irq_rsrc.start; + timer->irq = irq.start; r = omap_hwmod_get_resource_byname(oh, IORESOURCE_MEM, NULL, - &mem_rsrc); + &mem); if (r) return -ENXIO; - timer->phys_base = mem_rsrc.start; - size = mem_rsrc.end - mem_rsrc.start; /* Static mapping, never released */ - timer->io_base = ioremap(timer->phys_base, size); + timer->io_base = ioremap(mem.start, mem.end - mem.start); } if (!timer->io_base) @@ -310,10 +303,10 @@ static int __init omap_dm_timer_init_one(struct omap_dm_timer *timer, src = clk_get(NULL, fck_source); if (IS_ERR(src)) { - res = -EINVAL; + r = -EINVAL; } else { - res = clk_set_parent(timer->fclk, src); - if (IS_ERR_VALUE(res)) + r = clk_set_parent(timer->fclk, src); + if (IS_ERR_VALUE(r)) pr_warn("%s: %s cannot set source\n", __func__, oh->name); clk_put(src); @@ -334,7 +327,7 @@ static int __init omap_dm_timer_init_one(struct omap_dm_timer *timer, timer->rate = clk_get_rate(timer->fclk); timer->reserved = 1; - return res; + return r; } static void __init omap2_gp_clockevent_init(int gptimer_id, @@ -408,6 +401,11 @@ static u32 notrace dmtimer_read_sched_clock(void) } #ifdef CONFIG_OMAP_32K_TIMER +static struct of_device_id omap_counter_match[] __initdata = { + { .compatible = "ti,omap-counter32k", }, + { } +}; + /* Setup free-running counter for clocksource */ static int __init omap2_sync32k_clocksource_init(void) { diff --git a/arch/arm/plat-omap/dmtimer.c b/arch/arm/plat-omap/dmtimer.c index 9deeb30..89585c2 100644 --- a/arch/arm/plat-omap/dmtimer.c +++ b/arch/arm/plat-omap/dmtimer.c @@ -43,6 +43,8 @@ #include <linux/pm_runtime.h> #include <linux/of.h> #include <linux/of_device.h> +#include <linux/platform_device.h> +#include <linux/platform_data/dmtimer-omap.h> #include <plat/dmtimer.h> @@ -99,32 +101,39 @@ static void omap_timer_restore_context(struct omap_dm_timer *timer) timer->context.tclr); } -static void omap_dm_timer_wait_for_reset(struct omap_dm_timer *timer) +static int omap_dm_timer_reset(struct omap_dm_timer *timer) { - int c; + u32 l, timeout = 100000; - if (!timer->sys_stat) - return; + if (timer->revision != 1) + return -EINVAL; - c = 0; - while (!(__raw_readl(timer->sys_stat) & 1)) { - c++; - if (c > 100000) { - printk(KERN_ERR "Timer failed to reset\n"); - return; - } + omap_dm_timer_write_reg(timer, OMAP_TIMER_IF_CTRL_REG, 0x06); + + do { + l = __omap_dm_timer_read(timer, + OMAP_TIMER_V1_SYS_STAT_OFFSET, 0); + } while (!l && timeout--); + + if (!timeout) { + dev_err(&timer->pdev->dev, "Timer failed to reset\n"); + return -ETIMEDOUT; } -} -static void omap_dm_timer_reset(struct omap_dm_timer *timer) -{ - omap_dm_timer_write_reg(timer, OMAP_TIMER_IF_CTRL_REG, 0x06); - omap_dm_timer_wait_for_reset(timer); - __omap_dm_timer_reset(timer, 0, 0); + /* Configure timer for smart-idle mode */ + l = __omap_dm_timer_read(timer, OMAP_TIMER_OCP_CFG_OFFSET, 0); + l |= 0x2 << 0x3; + __omap_dm_timer_write(timer, OMAP_TIMER_OCP_CFG_OFFSET, l, 0); + + timer->posted = 0; + + return 0; } -int omap_dm_timer_prepare(struct omap_dm_timer *timer) +static int omap_dm_timer_prepare(struct omap_dm_timer *timer) { + int rc; + /* * FIXME: OMAP1 devices do not use the clock framework for dmtimers so * do not call clk_get() for these devices. @@ -140,8 +149,13 @@ int omap_dm_timer_prepare(struct omap_dm_timer *timer) omap_dm_timer_enable(timer); - if (timer->capability & OMAP_TIMER_NEEDS_RESET) - omap_dm_timer_reset(timer); + if (timer->capability & OMAP_TIMER_NEEDS_RESET) { + rc = omap_dm_timer_reset(timer); + if (rc) { + omap_dm_timer_disable(timer); + return rc; + } + } __omap_dm_timer_enable_posted(timer); omap_dm_timer_disable(timer); diff --git a/arch/arm/plat-omap/include/plat/dmtimer.h b/arch/arm/plat-omap/include/plat/dmtimer.h index 05a36e1..a3fbc48 100644 --- a/arch/arm/plat-omap/include/plat/dmtimer.h +++ b/arch/arm/plat-omap/include/plat/dmtimer.h @@ -79,8 +79,6 @@ struct omap_timer_capability_dev_attr { u32 timer_capability; }; -struct omap_dm_timer; - struct timer_regs { u32 tidr; u32 tier; @@ -101,12 +99,29 @@ struct timer_regs { u32 towr; }; -struct dmtimer_platform_data { - /* set_timer_src - Only used for OMAP1 devices */ - int (*set_timer_src)(struct platform_device *pdev, int source); - u32 timer_errata; - u32 timer_capability; +struct omap_dm_timer { + int id; + int irq; + struct clk *fclk; + + void __iomem *io_base; + void __iomem *irq_stat; /* TISR/IRQSTATUS interrupt status */ + void __iomem *irq_ena; /* irq enable */ + void __iomem *irq_dis; /* irq disable, only on v2 ip */ + void __iomem *pend; /* write pending */ + void __iomem *func_base; /* function register base */ + + unsigned long rate; + unsigned reserved:1; + unsigned posted:1; + struct timer_regs context; int (*get_context_loss_count)(struct device *); + int ctx_loss_count; + int revision; + u32 capability; + u32 errata; + struct platform_device *pdev; + struct list_head node; }; int omap_dm_timer_reserve_systimer(int id); @@ -260,35 +275,6 @@ int omap_dm_timers_active(void); #define OMAP_TIMER_TICK_INT_MASK_COUNT_REG \ (_OMAP_TIMER_TICK_INT_MASK_COUNT_OFFSET | (WP_TOWR << WPSHIFT)) -struct omap_dm_timer { - unsigned long phys_base; - int id; - int irq; - struct clk *fclk; - - void __iomem *io_base; - void __iomem *sys_stat; /* TISTAT timer status */ - void __iomem *irq_stat; /* TISR/IRQSTATUS interrupt status */ - void __iomem *irq_ena; /* irq enable */ - void __iomem *irq_dis; /* irq disable, only on v2 ip */ - void __iomem *pend; /* write pending */ - void __iomem *func_base; /* function register base */ - - unsigned long rate; - unsigned reserved:1; - unsigned posted:1; - struct timer_regs context; - int (*get_context_loss_count)(struct device *); - int ctx_loss_count; - int revision; - u32 capability; - u32 errata; - struct platform_device *pdev; - struct list_head node; -}; - -int omap_dm_timer_prepare(struct omap_dm_timer *timer); - static inline u32 __omap_dm_timer_read(struct omap_dm_timer *timer, u32 reg, int posted) { @@ -317,8 +303,6 @@ static inline void __omap_dm_timer_init_regs(struct omap_dm_timer *timer) tidr = __raw_readl(timer->io_base); if (!(tidr >> 16)) { timer->revision = 1; - timer->sys_stat = timer->io_base + - OMAP_TIMER_V1_SYS_STAT_OFFSET; timer->irq_stat = timer->io_base + OMAP_TIMER_V1_STAT_OFFSET; timer->irq_ena = timer->io_base + OMAP_TIMER_V1_INT_EN_OFFSET; timer->irq_dis = timer->io_base + OMAP_TIMER_V1_INT_EN_OFFSET; @@ -326,7 +310,6 @@ static inline void __omap_dm_timer_init_regs(struct omap_dm_timer *timer) timer->func_base = timer->io_base; } else { timer->revision = 2; - timer->sys_stat = NULL; timer->irq_stat = timer->io_base + OMAP_TIMER_V2_IRQSTATUS; timer->irq_ena = timer->io_base + OMAP_TIMER_V2_IRQENABLE_SET; timer->irq_dis = timer->io_base + OMAP_TIMER_V2_IRQENABLE_CLR; @@ -337,25 +320,6 @@ static inline void __omap_dm_timer_init_regs(struct omap_dm_timer *timer) } } -/* Assumes the source clock has been set by caller */ -static inline void __omap_dm_timer_reset(struct omap_dm_timer *timer, - int autoidle, int wakeup) -{ - u32 l; - - l = __raw_readl(timer->io_base + OMAP_TIMER_OCP_CFG_OFFSET); - l |= 0x02 << 3; /* Set to smart-idle mode */ - l |= 0x2 << 8; /* Set clock activity to perserve f-clock on idle */ - - if (autoidle) - l |= 0x1 << 0; - - if (wakeup) - l |= 1 << 2; - - __raw_writel(l, timer->io_base + OMAP_TIMER_OCP_CFG_OFFSET); -} - /* * __omap_dm_timer_enable_posted - enables write posted mode * @timer: pointer to timer instance handle diff --git a/drivers/staging/tidspbridge/core/ue_deh.c b/drivers/staging/tidspbridge/core/ue_deh.c index 3d28b23..6aea6f1 100644 --- a/drivers/staging/tidspbridge/core/ue_deh.c +++ b/drivers/staging/tidspbridge/core/ue_deh.c @@ -19,7 +19,6 @@ #include <linux/kernel.h> #include <linux/interrupt.h> -#include <plat/dmtimer.h> #include <dspbridge/dbdefs.h> #include <dspbridge/dspdeh.h> diff --git a/include/linux/platform_data/dmtimer-omap.h b/include/linux/platform_data/dmtimer-omap.h new file mode 100644 index 0000000..a19b78d --- /dev/null +++ b/include/linux/platform_data/dmtimer-omap.h @@ -0,0 +1,31 @@ +/* + * DMTIMER platform data for TI OMAP platforms + * + * Copyright (C) 2012 Texas Instruments + * Author: Jon Hunter <jon-hunter@ti.com> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published by + * the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef __PLATFORM_DATA_DMTIMER_OMAP_H__ +#define __PLATFORM_DATA_DMTIMER_OMAP_H__ + +struct dmtimer_platform_data { + /* set_timer_src - Only used for OMAP1 devices */ + int (*set_timer_src)(struct platform_device *pdev, int source); + u32 timer_capability; + u32 timer_errata; + int (*get_context_loss_count)(struct device *); +}; + +#endif /* __PLATFORM_DATA_DMTIMER_OMAP_H__ */ |