提交 68e90740 编写于 作者: I Ingo Molnar

Merge branch 'clockevents/3.13' of git://git.linaro.org/people/dlezcano/linux into timers/core

Pull (mostly) ARM clocksource driver updates from Daniel Lezcano:

" - Soren Brinkmann added FEAT_PERCPU to a clock device when it is local
    per cpu. This feature prevents the clock framework to choose a per cpu
    timer as a broadcast timer. This problem arised when the ARM global
    timer is used when switching to the broadcast timer which is the case
    now on Xillinx with its cpuidle driver.

  - Stephen Boyd extended the generic sched_clock code to support 64bit
    counters and removes the setup_sched_clock deprecation, as that causes
    lots of warnings since there's still users in the arch/arm tree. He
    added also the CLOCK_SOURCE_SUSPEND_NONSTOP flag on the architected
    timer as they continue counting during suspend.

  - Uwe Kleine-König added some missing __init sections and consolidated the
    code by moving the of_node_put call from the drivers to the function
    clocksource_of_init. "
Signed-off-by: NIngo Molnar <mingo@kernel.org>
......@@ -92,6 +92,14 @@
};
};
global_timer: timer@f8f00200 {
compatible = "arm,cortex-a9-global-timer";
reg = <0xf8f00200 0x20>;
interrupts = <1 11 0x301>;
interrupt-parent = <&intc>;
clocks = <&clkc 4>;
};
ttc0: ttc0@f8001000 {
interrupt-parent = <&intc>;
interrupts = < 0 10 4 0 11 4 0 12 4 >;
......
......@@ -274,7 +274,6 @@ static void __init msm_dt_timer_init(struct device_node *np)
pr_err("Unknown frequency\n");
return;
}
of_node_put(np);
event_base = base + 0x4;
sts_base = base + 0x88;
......
......@@ -13,5 +13,6 @@ config ARCH_ZYNQ
select HAVE_SMP
select SPARSE_IRQ
select CADENCE_TTC_TIMER
select ARM_GLOBAL_TIMER
help
Support for Xilinx Zynq ARM Cortex A9 Platform
......@@ -389,7 +389,7 @@ static struct clocksource clocksource_counter = {
.rating = 400,
.read = arch_counter_read,
.mask = CLOCKSOURCE_MASK(56),
.flags = CLOCK_SOURCE_IS_CONTINUOUS,
.flags = CLOCK_SOURCE_IS_CONTINUOUS | CLOCK_SOURCE_SUSPEND_NONSTOP,
};
static struct cyclecounter cyclecounter = {
......
......@@ -169,7 +169,8 @@ static int gt_clockevents_init(struct clock_event_device *clk)
int cpu = smp_processor_id();
clk->name = "arm_global_timer";
clk->features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT;
clk->features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT |
CLOCK_EVT_FEAT_PERCPU;
clk->set_mode = gt_clockevent_set_mode;
clk->set_next_event = gt_clockevent_set_next_event;
clk->cpumask = cpumask_of(cpu);
......
......@@ -49,7 +49,7 @@ struct bcm2835_timer {
static void __iomem *system_clock __read_mostly;
static u32 notrace bcm2835_sched_read(void)
static u64 notrace bcm2835_sched_read(void)
{
return readl_relaxed(system_clock);
}
......@@ -110,7 +110,7 @@ static void __init bcm2835_timer_init(struct device_node *node)
panic("Can't read clock-frequency");
system_clock = base + REG_COUNTER_LO;
setup_sched_clock(bcm2835_sched_read, 32, freq);
sched_clock_register(bcm2835_sched_read, 32, freq);
clocksource_mmio_init(base + REG_COUNTER_LO, node->name,
freq, 300, 32, clocksource_mmio_readl_up);
......
......@@ -53,7 +53,7 @@ static struct clocksource clocksource_dbx500_prcmu = {
#ifdef CONFIG_CLKSRC_DBX500_PRCMU_SCHED_CLOCK
static u32 notrace dbx500_prcmu_sched_clock_read(void)
static u64 notrace dbx500_prcmu_sched_clock_read(void)
{
if (unlikely(!clksrc_dbx500_timer_base))
return 0;
......@@ -81,8 +81,7 @@ void __init clksrc_dbx500_prcmu_init(void __iomem *base)
clksrc_dbx500_timer_base + PRCMU_TIMER_REF);
}
#ifdef CONFIG_CLKSRC_DBX500_PRCMU_SCHED_CLOCK
setup_sched_clock(dbx500_prcmu_sched_clock_read,
32, RATE_32K);
sched_clock_register(dbx500_prcmu_sched_clock_read, 32, RATE_32K);
#endif
clocksource_register_hz(&clocksource_dbx500_prcmu, RATE_32K);
}
......@@ -35,5 +35,6 @@ void __init clocksource_of_init(void)
init_func = match->data;
init_func(np);
of_node_put(np);
}
}
......@@ -23,7 +23,7 @@
#include <linux/clk.h>
#include <linux/sched_clock.h>
static void timer_get_base_and_rate(struct device_node *np,
static void __init timer_get_base_and_rate(struct device_node *np,
void __iomem **base, u32 *rate)
{
struct clk *timer_clk;
......@@ -55,11 +55,11 @@ static void timer_get_base_and_rate(struct device_node *np,
try_clock_freq:
if (of_property_read_u32(np, "clock-freq", rate) &&
of_property_read_u32(np, "clock-frequency", rate))
of_property_read_u32(np, "clock-frequency", rate))
panic("No clock nor clock-frequency property for %s", np->name);
}
static void add_clockevent(struct device_node *event_timer)
static void __init add_clockevent(struct device_node *event_timer)
{
void __iomem *iobase;
struct dw_apb_clock_event_device *ced;
......@@ -82,7 +82,7 @@ static void add_clockevent(struct device_node *event_timer)
static void __iomem *sched_io_base;
static u32 sched_rate;
static void add_clocksource(struct device_node *source_timer)
static void __init add_clocksource(struct device_node *source_timer)
{
void __iomem *iobase;
struct dw_apb_clocksource *cs;
......@@ -106,7 +106,7 @@ static void add_clocksource(struct device_node *source_timer)
sched_rate = rate;
}
static u32 read_sched_clock(void)
static u64 read_sched_clock(void)
{
return __raw_readl(sched_io_base);
}
......@@ -117,7 +117,7 @@ static const struct of_device_id sptimer_ids[] __initconst = {
{ /* Sentinel */ },
};
static void init_sched_clock(void)
static void __init init_sched_clock(void)
{
struct device_node *sched_timer;
......@@ -128,7 +128,7 @@ static void init_sched_clock(void)
of_node_put(sched_timer);
}
setup_sched_clock(read_sched_clock, 32, sched_rate);
sched_clock_register(read_sched_clock, 32, sched_rate);
}
static int num_called;
......@@ -138,12 +138,10 @@ static void __init dw_apb_timer_init(struct device_node *timer)
case 0:
pr_debug("%s: found clockevent timer\n", __func__);
add_clockevent(timer);
of_node_put(timer);
break;
case 1:
pr_debug("%s: found clocksource timer\n", __func__);
add_clocksource(timer);
of_node_put(timer);
init_sched_clock();
break;
default:
......
......@@ -222,7 +222,7 @@ static struct clocksource clocksource_mxs = {
.flags = CLOCK_SOURCE_IS_CONTINUOUS,
};
static u32 notrace mxs_read_sched_clock_v2(void)
static u64 notrace mxs_read_sched_clock_v2(void)
{
return ~readl_relaxed(mxs_timrot_base + HW_TIMROT_RUNNING_COUNTn(1));
}
......@@ -236,7 +236,7 @@ static int __init mxs_clocksource_init(struct clk *timer_clk)
else {
clocksource_mmio_init(mxs_timrot_base + HW_TIMROT_RUNNING_COUNTn(1),
"mxs_timer", c, 200, 32, clocksource_mmio_readl_down);
setup_sched_clock(mxs_read_sched_clock_v2, 32, c);
sched_clock_register(mxs_read_sched_clock_v2, 32, c);
}
return 0;
......
......@@ -76,7 +76,7 @@ static struct delay_timer mtu_delay_timer;
* local implementation which uses the clocksource to get some
* better resolution when scheduling the kernel.
*/
static u32 notrace nomadik_read_sched_clock(void)
static u64 notrace nomadik_read_sched_clock(void)
{
if (unlikely(!mtu_base))
return 0;
......@@ -231,7 +231,7 @@ static void __init __nmdk_timer_init(void __iomem *base, int irq,
"mtu_0");
#ifdef CONFIG_CLKSRC_NOMADIK_MTU_SCHED_CLOCK
setup_sched_clock(nomadik_read_sched_clock, 32, rate);
sched_clock_register(nomadik_read_sched_clock, 32, rate);
#endif
/* Timer 1 is used for events, register irq and clockevents */
......
......@@ -331,7 +331,7 @@ static struct clocksource samsung_clocksource = {
* this wraps around for now, since it is just a relative time
* stamp. (Inspired by U300 implementation.)
*/
static u32 notrace samsung_read_sched_clock(void)
static u64 notrace samsung_read_sched_clock(void)
{
return samsung_clocksource_read(NULL);
}
......@@ -357,7 +357,7 @@ static void __init samsung_clocksource_init(void)
else
pwm.source_reg = pwm.base + pwm.source_id * 0x0c + 0x14;
setup_sched_clock(samsung_read_sched_clock,
sched_clock_register(samsung_read_sched_clock,
pwm.variant.bits, clock_rate);
samsung_clocksource.mask = CLOCKSOURCE_MASK(pwm.variant.bits);
......
......@@ -98,7 +98,7 @@ static struct clock_event_device tegra_clockevent = {
.set_mode = tegra_timer_set_mode,
};
static u32 notrace tegra_read_sched_clock(void)
static u64 notrace tegra_read_sched_clock(void)
{
return timer_readl(TIMERUS_CNTR_1US);
}
......@@ -181,8 +181,6 @@ static void __init tegra20_init_timer(struct device_node *np)
rate = clk_get_rate(clk);
}
of_node_put(np);
switch (rate) {
case 12000000:
timer_writel(0x000b, TIMERUS_USEC_CFG);
......@@ -200,7 +198,7 @@ static void __init tegra20_init_timer(struct device_node *np)
WARN(1, "Unknown clock rate");
}
setup_sched_clock(tegra_read_sched_clock, 32, 1000000);
sched_clock_register(tegra_read_sched_clock, 32, 1000000);
if (clocksource_mmio_init(timer_reg_base + TIMERUS_CNTR_1US,
"timer_us", 1000000, 300, 32, clocksource_mmio_readl_up)) {
......@@ -241,8 +239,6 @@ static void __init tegra20_init_rtc(struct device_node *np)
else
clk_prepare_enable(clk);
of_node_put(np);
register_persistent_clock(NULL, tegra_read_persistent_clock);
}
CLOCKSOURCE_OF_DECLARE(tegra20_rtc, "nvidia,tegra20-rtc", tegra20_init_rtc);
......
......@@ -96,7 +96,7 @@ static void local_timer_ctrl_clrset(u32 clr, u32 set)
local_base + TIMER_CTRL_OFF);
}
static u32 notrace armada_370_xp_read_sched_clock(void)
static u64 notrace armada_370_xp_read_sched_clock(void)
{
return ~readl(timer_base + TIMER0_VAL_OFF);
}
......@@ -258,7 +258,7 @@ static void __init armada_370_xp_timer_common_init(struct device_node *np)
/*
* Set scale and timer for sched_clock.
*/
setup_sched_clock(armada_370_xp_read_sched_clock, 32, timer_clk);
sched_clock_register(armada_370_xp_read_sched_clock, 32, timer_clk);
/*
* Setup free-running clocksource timer (interrupts
......
......@@ -165,9 +165,9 @@ static struct irqaction sirfsoc_timer_irq = {
};
/* Overwrite weak default sched_clock with more precise one */
static u32 notrace sirfsoc_read_sched_clock(void)
static u64 notrace sirfsoc_read_sched_clock(void)
{
return (u32)(sirfsoc_timer_read(NULL) & 0xffffffff);
return sirfsoc_timer_read(NULL);
}
static void __init sirfsoc_clockevent_init(void)
......@@ -206,7 +206,7 @@ static void __init sirfsoc_prima2_timer_init(struct device_node *np)
BUG_ON(clocksource_register_hz(&sirfsoc_clocksource, CLOCK_TICK_RATE));
setup_sched_clock(sirfsoc_read_sched_clock, 32, CLOCK_TICK_RATE);
sched_clock_register(sirfsoc_read_sched_clock, 64, CLOCK_TICK_RATE);
BUG_ON(setup_irq(sirfsoc_timer_irq.irq, &sirfsoc_timer_irq));
......
......@@ -52,7 +52,7 @@ static inline void pit_irq_acknowledge(void)
__raw_writel(PITTFLG_TIF, clkevt_base + PITTFLG);
}
static unsigned int pit_read_sched_clock(void)
static u64 pit_read_sched_clock(void)
{
return __raw_readl(clksrc_base + PITCVAL);
}
......@@ -64,7 +64,7 @@ static int __init pit_clocksource_init(unsigned long rate)
__raw_writel(~0UL, clksrc_base + PITLDVAL);
__raw_writel(PITTCTRL_TEN, clksrc_base + PITTCTRL);
setup_sched_clock(pit_read_sched_clock, 32, rate);
sched_clock_register(pit_read_sched_clock, 32, rate);
return clocksource_mmio_init(clksrc_base + PITCVAL, "vf-pit", rate,
300, 32, clocksource_mmio_readl_down);
}
......
......@@ -137,14 +137,12 @@ static void __init vt8500_timer_init(struct device_node *np)
if (!regbase) {
pr_err("%s: Missing iobase description in Device Tree\n",
__func__);
of_node_put(np);
return;
}
timer_irq = irq_of_parse_and_map(np, 0);
if (!timer_irq) {
pr_err("%s: Missing irq description in Device Tree\n",
__func__);
of_node_put(np);
return;
}
......
......@@ -60,6 +60,7 @@ enum clock_event_mode {
* Core shall set the interrupt affinity dynamically in broadcast mode
*/
#define CLOCK_EVT_FEAT_DYNIRQ 0x000020
#define CLOCK_EVT_FEAT_PERCPU 0x000040
/**
* struct clock_event_device - clock event device descriptor
......
......@@ -70,6 +70,7 @@ static bool tick_check_broadcast_device(struct clock_event_device *curdev,
struct clock_event_device *newdev)
{
if ((newdev->features & CLOCK_EVT_FEAT_DUMMY) ||
(newdev->features & CLOCK_EVT_FEAT_PERCPU) ||
(newdev->features & CLOCK_EVT_FEAT_C3STOP))
return false;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册