Merge branch 'cleanup-timer' of git://github.com/jonhunter/linux into omap-for-v3.8/timer
This commit is contained in:
commit
48b0023607
@ -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>
|
||||
|
||||
|
@ -51,7 +51,6 @@
|
||||
#include <asm/mach/time.h>
|
||||
|
||||
#include <plat/counter-32k.h>
|
||||
#include <plat/dmtimer.h>
|
||||
|
||||
#include <mach/hardware.h>
|
||||
|
||||
|
@ -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"
|
||||
|
@ -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"
|
||||
|
@ -30,7 +30,6 @@
|
||||
#include "clock.h"
|
||||
#include "powerdomain.h"
|
||||
#include "clockdomain.h"
|
||||
#include <plat/dmtimer.h>
|
||||
#include "omap-pm.h"
|
||||
|
||||
#include "soc.h"
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
/* 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);
|
||||
|
@ -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
|
||||
|
@ -19,7 +19,6 @@
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <plat/dmtimer.h>
|
||||
|
||||
#include <dspbridge/dbdefs.h>
|
||||
#include <dspbridge/dspdeh.h>
|
||||
|
31
include/linux/platform_data/dmtimer-omap.h
Normal file
31
include/linux/platform_data/dmtimer-omap.h
Normal file
@ -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__ */
|
Loading…
Reference in New Issue
Block a user