Commit 48b00236 authored by Tony Lindgren's avatar Tony Lindgren

Merge branch 'cleanup-timer' of git://github.com/jonhunter/linux into omap-for-v3.8/timer

parents 9dc57643 258e84af
...@@ -25,6 +25,7 @@ ...@@ -25,6 +25,7 @@
#include <linux/err.h> #include <linux/err.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <linux/platform_data/dmtimer-omap.h>
#include <mach/irqs.h> #include <mach/irqs.h>
......
...@@ -51,7 +51,6 @@ ...@@ -51,7 +51,6 @@
#include <asm/mach/time.h> #include <asm/mach/time.h>
#include <plat/counter-32k.h> #include <plat/counter-32k.h>
#include <plat/dmtimer.h>
#include <mach/hardware.h> #include <mach/hardware.h>
......
...@@ -17,7 +17,6 @@ ...@@ -17,7 +17,6 @@
#include <linux/platform_data/spi-omap2-mcspi.h> #include <linux/platform_data/spi-omap2-mcspi.h>
#include <plat-omap/dma-omap.h> #include <plat-omap/dma-omap.h>
#include <plat/dmtimer.h>
#include "omap_hwmod.h" #include "omap_hwmod.h"
#include "l3_2xxx.h" #include "l3_2xxx.h"
......
...@@ -18,7 +18,6 @@ ...@@ -18,7 +18,6 @@
#include <linux/platform_data/spi-omap2-mcspi.h> #include <linux/platform_data/spi-omap2-mcspi.h>
#include <plat-omap/dma-omap.h> #include <plat-omap/dma-omap.h>
#include <plat/dmtimer.h>
#include "omap_hwmod.h" #include "omap_hwmod.h"
#include "mmc.h" #include "mmc.h"
......
...@@ -30,7 +30,6 @@ ...@@ -30,7 +30,6 @@
#include "clock.h" #include "clock.h"
#include "powerdomain.h" #include "powerdomain.h"
#include "clockdomain.h" #include "clockdomain.h"
#include <plat/dmtimer.h>
#include "omap-pm.h" #include "omap-pm.h"
#include "soc.h" #include "soc.h"
......
...@@ -39,6 +39,8 @@ ...@@ -39,6 +39,8 @@
#include <linux/of.h> #include <linux/of.h>
#include <linux/of_address.h> #include <linux/of_address.h>
#include <linux/of_irq.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/mach/time.h>
#include <asm/smp_twd.h> #include <asm/smp_twd.h>
...@@ -160,11 +162,6 @@ static struct of_device_id omap_timer_match[] __initdata = { ...@@ -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 * omap_get_timer_dt - get a timer using device-tree
* @match - device-tree match structure for matching a device type * @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, ...@@ -245,10 +242,8 @@ static int __init omap_dm_timer_init_one(struct omap_dm_timer *timer,
const char *oh_name; const char *oh_name;
struct device_node *np; struct device_node *np;
struct omap_hwmod *oh; struct omap_hwmod *oh;
struct resource irq_rsrc, mem_rsrc; struct resource irq, mem;
size_t size; int r = 0;
int res = 0;
int r;
if (of_have_populated_dt()) { if (of_have_populated_dt()) {
np = omap_get_timer_dt(omap_timer_match, NULL); 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, ...@@ -280,20 +275,18 @@ static int __init omap_dm_timer_init_one(struct omap_dm_timer *timer,
if (!of_have_populated_dt()) { if (!of_have_populated_dt()) {
r = omap_hwmod_get_resource_byname(oh, IORESOURCE_IRQ, NULL, r = omap_hwmod_get_resource_byname(oh, IORESOURCE_IRQ, NULL,
&irq_rsrc); &irq);
if (r) if (r)
return -ENXIO; return -ENXIO;
timer->irq = irq_rsrc.start; timer->irq = irq.start;
r = omap_hwmod_get_resource_byname(oh, IORESOURCE_MEM, NULL, r = omap_hwmod_get_resource_byname(oh, IORESOURCE_MEM, NULL,
&mem_rsrc); &mem);
if (r) if (r)
return -ENXIO; return -ENXIO;
timer->phys_base = mem_rsrc.start;
size = mem_rsrc.end - mem_rsrc.start;
/* Static mapping, never released */ /* 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) if (!timer->io_base)
...@@ -310,10 +303,10 @@ static int __init omap_dm_timer_init_one(struct omap_dm_timer *timer, ...@@ -310,10 +303,10 @@ static int __init omap_dm_timer_init_one(struct omap_dm_timer *timer,
src = clk_get(NULL, fck_source); src = clk_get(NULL, fck_source);
if (IS_ERR(src)) { if (IS_ERR(src)) {
res = -EINVAL; r = -EINVAL;
} else { } else {
res = clk_set_parent(timer->fclk, src); r = clk_set_parent(timer->fclk, src);
if (IS_ERR_VALUE(res)) if (IS_ERR_VALUE(r))
pr_warn("%s: %s cannot set source\n", pr_warn("%s: %s cannot set source\n",
__func__, oh->name); __func__, oh->name);
clk_put(src); clk_put(src);
...@@ -334,7 +327,7 @@ static int __init omap_dm_timer_init_one(struct omap_dm_timer *timer, ...@@ -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->rate = clk_get_rate(timer->fclk);
timer->reserved = 1; timer->reserved = 1;
return res; return r;
} }
static void __init omap2_gp_clockevent_init(int gptimer_id, static void __init omap2_gp_clockevent_init(int gptimer_id,
...@@ -408,6 +401,11 @@ static u32 notrace dmtimer_read_sched_clock(void) ...@@ -408,6 +401,11 @@ static u32 notrace dmtimer_read_sched_clock(void)
} }
#ifdef CONFIG_OMAP_32K_TIMER #ifdef CONFIG_OMAP_32K_TIMER
static struct of_device_id omap_counter_match[] __initdata = {
{ .compatible = "ti,omap-counter32k", },
{ }
};
/* Setup free-running counter for clocksource */ /* Setup free-running counter for clocksource */
static int __init omap2_sync32k_clocksource_init(void) static int __init omap2_sync32k_clocksource_init(void)
{ {
......
...@@ -43,6 +43,8 @@ ...@@ -43,6 +43,8 @@
#include <linux/pm_runtime.h> #include <linux/pm_runtime.h>
#include <linux/of.h> #include <linux/of.h>
#include <linux/of_device.h> #include <linux/of_device.h>
#include <linux/platform_device.h>
#include <linux/platform_data/dmtimer-omap.h>
#include <plat/dmtimer.h> #include <plat/dmtimer.h>
...@@ -99,32 +101,39 @@ static void omap_timer_restore_context(struct omap_dm_timer *timer) ...@@ -99,32 +101,39 @@ static void omap_timer_restore_context(struct omap_dm_timer *timer)
timer->context.tclr); 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) if (timer->revision != 1)
return; return -EINVAL;
c = 0; omap_dm_timer_write_reg(timer, OMAP_TIMER_IF_CTRL_REG, 0x06);
while (!(__raw_readl(timer->sys_stat) & 1)) {
c++; do {
if (c > 100000) { l = __omap_dm_timer_read(timer,
printk(KERN_ERR "Timer failed to reset\n"); OMAP_TIMER_V1_SYS_STAT_OFFSET, 0);
return; } 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) /* Configure timer for smart-idle mode */
{ l = __omap_dm_timer_read(timer, OMAP_TIMER_OCP_CFG_OFFSET, 0);
omap_dm_timer_write_reg(timer, OMAP_TIMER_IF_CTRL_REG, 0x06); l |= 0x2 << 0x3;
omap_dm_timer_wait_for_reset(timer); __omap_dm_timer_write(timer, OMAP_TIMER_OCP_CFG_OFFSET, l, 0);
__omap_dm_timer_reset(timer, 0, 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 * FIXME: OMAP1 devices do not use the clock framework for dmtimers so
* do not call clk_get() for these devices. * do not call clk_get() for these devices.
...@@ -140,8 +149,13 @@ int omap_dm_timer_prepare(struct omap_dm_timer *timer) ...@@ -140,8 +149,13 @@ int omap_dm_timer_prepare(struct omap_dm_timer *timer)
omap_dm_timer_enable(timer); omap_dm_timer_enable(timer);
if (timer->capability & OMAP_TIMER_NEEDS_RESET) if (timer->capability & OMAP_TIMER_NEEDS_RESET) {
omap_dm_timer_reset(timer); rc = omap_dm_timer_reset(timer);
if (rc) {
omap_dm_timer_disable(timer);
return rc;
}
}
__omap_dm_timer_enable_posted(timer); __omap_dm_timer_enable_posted(timer);
omap_dm_timer_disable(timer); omap_dm_timer_disable(timer);
......
...@@ -79,8 +79,6 @@ struct omap_timer_capability_dev_attr { ...@@ -79,8 +79,6 @@ struct omap_timer_capability_dev_attr {
u32 timer_capability; u32 timer_capability;
}; };
struct omap_dm_timer;
struct timer_regs { struct timer_regs {
u32 tidr; u32 tidr;
u32 tier; u32 tier;
...@@ -101,12 +99,29 @@ struct timer_regs { ...@@ -101,12 +99,29 @@ struct timer_regs {
u32 towr; u32 towr;
}; };
struct dmtimer_platform_data { struct omap_dm_timer {
/* set_timer_src - Only used for OMAP1 devices */ int id;
int (*set_timer_src)(struct platform_device *pdev, int source); int irq;
u32 timer_errata; struct clk *fclk;
u32 timer_capability;
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 (*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); int omap_dm_timer_reserve_systimer(int id);
...@@ -260,35 +275,6 @@ int omap_dm_timers_active(void); ...@@ -260,35 +275,6 @@ int omap_dm_timers_active(void);
#define OMAP_TIMER_TICK_INT_MASK_COUNT_REG \ #define OMAP_TIMER_TICK_INT_MASK_COUNT_REG \
(_OMAP_TIMER_TICK_INT_MASK_COUNT_OFFSET | (WP_TOWR << WPSHIFT)) (_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, static inline u32 __omap_dm_timer_read(struct omap_dm_timer *timer, u32 reg,
int posted) int posted)
{ {
...@@ -317,8 +303,6 @@ static inline void __omap_dm_timer_init_regs(struct omap_dm_timer *timer) ...@@ -317,8 +303,6 @@ static inline void __omap_dm_timer_init_regs(struct omap_dm_timer *timer)
tidr = __raw_readl(timer->io_base); tidr = __raw_readl(timer->io_base);
if (!(tidr >> 16)) { if (!(tidr >> 16)) {
timer->revision = 1; 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_stat = timer->io_base + OMAP_TIMER_V1_STAT_OFFSET;
timer->irq_ena = timer->io_base + OMAP_TIMER_V1_INT_EN_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; 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) ...@@ -326,7 +310,6 @@ static inline void __omap_dm_timer_init_regs(struct omap_dm_timer *timer)
timer->func_base = timer->io_base; timer->func_base = timer->io_base;
} else { } else {
timer->revision = 2; timer->revision = 2;
timer->sys_stat = NULL;
timer->irq_stat = timer->io_base + OMAP_TIMER_V2_IRQSTATUS; timer->irq_stat = timer->io_base + OMAP_TIMER_V2_IRQSTATUS;
timer->irq_ena = timer->io_base + OMAP_TIMER_V2_IRQENABLE_SET; timer->irq_ena = timer->io_base + OMAP_TIMER_V2_IRQENABLE_SET;
timer->irq_dis = timer->io_base + OMAP_TIMER_V2_IRQENABLE_CLR; 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) ...@@ -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 * __omap_dm_timer_enable_posted - enables write posted mode
* @timer: pointer to timer instance handle * @timer: pointer to timer instance handle
......
...@@ -19,7 +19,6 @@ ...@@ -19,7 +19,6 @@
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/interrupt.h> #include <linux/interrupt.h>
#include <plat/dmtimer.h>
#include <dspbridge/dbdefs.h> #include <dspbridge/dbdefs.h>
#include <dspbridge/dspdeh.h> #include <dspbridge/dspdeh.h>
......
/*
* 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__ */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment