Merge branch 'timers-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip into next

Pull timer core updates from Thomas Gleixner:
 "This time you get nothing really exciting:
   - A huge update to the sh* clocksource drivers
   - Support for two more ARM SoCs
   - Removal of the deprecated setup_sched_clock() API
   - The usual pile of fixlets all over the place"

* 'timers-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: (23 commits)
  clocksource: Add Freescale FlexTimer Module (FTM) timer support
  ARM: dts: vf610: Add Freescale FlexTimer Module timer node.
  clocksource: ftm: Add FlexTimer Module (FTM) Timer devicetree Documentation
  clocksource: sh_tmu: Remove unnecessary OOM messages
  clocksource: sh_mtu2: Remove unnecessary OOM messages
  clocksource: sh_cmt: Remove unnecessary OOM messages
  clocksource: em_sti: Remove unnecessary OOM messages
  clocksource: dw_apb_timer_of: Do not trace read_sched_clock
  clocksource: Fix clocksource_mmio_readX_down
  clocksource: Fix type confusion for clocksource_mmio_readX_Y
  clocksource: sh_tmu: Fix channel IRQ retrieval in legacy case
  clocksource: qcom: Implement read_current_timer for udelay
  ntp: Make is_error_status() use its argument
  ntp: Convert simple_strtol to kstrtol
  timer_stats/doc: Fix /proc/timer_stats documentation
  sched_clock: Remove deprecated setup_sched_clock() API
  ARM: sun6i: a31: Add support for the High Speed Timers
  clocksource: sun5i: Add support for reset controller
  clocksource: efm32: use $vendor,$device scheme for compatible string
  KConfig: Vexpress: build the ARM_GLOBAL_TIMER with vexpress platform
  ...
This commit is contained in:
Linus Torvalds 2014-06-04 15:57:20 -07:00
commit 82e627eb5e
25 changed files with 496 additions and 50 deletions

View File

@ -4,8 +4,11 @@
** Timer node required properties:
- compatible : Should be "arm,cortex-a9-global-timer"
Driver supports versions r2p0 and above.
- compatible : should contain
* "arm,cortex-a5-global-timer" for Cortex-A5 global timers.
* "arm,cortex-a9-global-timer" for Cortex-A9 global
timers or any compatible implementation. Note: driver
supports versions r2p0 and above.
- interrupts : One interrupt to each core

View File

@ -9,6 +9,9 @@ Required properties:
one)
- clocks: phandle to the source clock (usually the AHB clock)
Optionnal properties:
- resets: phandle to a reset controller asserting the timer
Example:
timer@01c60000 {
@ -19,4 +22,5 @@ timer@01c60000 {
<0 53 1>,
<0 54 1>;
clocks = <&ahb1_gates 19>;
resets = <&ahb1rst 19>;
};

View File

@ -6,7 +6,7 @@ channels and can be used as PWM or Quadrature Decoder. Available clock sources
are the cpu's HFPERCLK (with a 10-bit prescaler) or an external pin.
Required properties:
- compatible : Should be efm32,timer
- compatible : Should be "energymicro,efm32-timer"
- reg : Address and length of the register set
- clocks : Should contain a reference to the HFPERCLK
@ -16,7 +16,7 @@ Optional properties:
Example:
timer@40010c00 {
compatible = "efm32,timer";
compatible = "energymicro,efm32-timer";
reg = <0x40010c00 0x400>;
interrupts = <14>;
clocks = <&cmu clk_HFPERCLKTIMER3>;

View File

@ -0,0 +1,31 @@
Freescale FlexTimer Module (FTM) Timer
Required properties:
- compatible : should be "fsl,ftm-timer"
- reg : Specifies base physical address and size of the register sets for the
clock event device and clock source device.
- interrupts : Should be the clock event device interrupt.
- clocks : The clocks provided by the SoC to drive the timer, must contain an
entry for each entry in clock-names.
- clock-names : Must include the following entries:
o "ftm-evt"
o "ftm-src"
o "ftm-evt-counter-en"
o "ftm-src-counter-en"
- big-endian: One boolean property, the big endian mode will be in use if it is
present, or the little endian mode will be in use for all the device registers.
Example:
ftm: ftm@400b8000 {
compatible = "fsl,ftm-timer";
reg = <0x400b8000 0x1000 0x400b9000 0x1000>;
interrupts = <0 44 IRQ_TYPE_LEVEL_HIGH>;
clock-names = "ftm-evt", "ftm-src",
"ftm-evt-counter-en", "ftm-src-counter-en";
clocks = <&clks VF610_CLK_FTM2>,
<&clks VF610_CLK_FTM3>,
<&clks VF610_CLK_FTM2_EXT_FIX_EN>,
<&clks VF610_CLK_FTM3_EXT_FIX_EN>;
big-endian;
};

View File

@ -39,9 +39,9 @@ To stop a sample period issue:
The statistics can be retrieved by:
# cat /proc/timer_stats
The readout of /proc/timer_stats automatically disables sampling. The sampled
information is kept until a new sample period is started. This allows multiple
readouts.
While sampling is enabled, each readout from /proc/timer_stats will see
newly updated statistics. Once sampling is disabled, the sampled information
is kept until a new sample period is started. This allows multiple readouts.
Sample output of /proc/timer_stats:

View File

@ -621,6 +621,17 @@
status = "disabled";
};
timer@01c60000 {
compatible = "allwinner,sun6i-a31-hstimer", "allwinner,sun7i-a20-hstimer";
reg = <0x01c60000 0x1000>;
interrupts = <0 51 4>,
<0 52 4>,
<0 53 4>,
<0 54 4>;
clocks = <&ahb1_gates 19>;
resets = <&ahb1_rst 19>;
};
spi0: spi@01c68000 {
compatible = "allwinner,sun6i-a31-spi";
reg = <0x01c68000 0x1000>;

View File

@ -88,6 +88,14 @@
interrupts = <1 13 0x304>;
};
timer@2c000200 {
compatible = "arm,cortex-a5-global-timer",
"arm,cortex-a9-global-timer";
reg = <0x2c000200 0x20>;
interrupts = <1 11 0x304>;
clocks = <&oscclk0>;
};
watchdog@2c000620 {
compatible = "arm,cortex-a5-twd-wdt";
reg = <0x2c000620 0x20>;
@ -120,7 +128,7 @@
compatible = "arm,vexpress,config-bus";
arm,vexpress,config-bridge = <&v2m_sysreg>;
osc@0 {
oscclk0: osc@0 {
/* CPU and internal AXI reference clock */
compatible = "arm,vexpress-osc";
arm,vexpress-sysreg,func = <1 0>;

View File

@ -371,6 +371,19 @@
status = "disabled";
};
ftm: ftm@400b8000 {
compatible = "fsl,ftm-timer";
reg = <0x400b8000 0x1000 0x400b9000 0x1000>;
interrupts = <0 44 IRQ_TYPE_LEVEL_HIGH>;
clock-names = "ftm-evt", "ftm-src",
"ftm-evt-counter-en", "ftm-src-counter-en";
clocks = <&clks VF610_CLK_FTM2>,
<&clks VF610_CLK_FTM3>,
<&clks VF610_CLK_FTM2_EXT_FIX_EN>,
<&clks VF610_CLK_FTM3_EXT_FIX_EN>;
status = "disabled";
};
fec0: ethernet@400d0000 {
compatible = "fsl,mvf600-fec";
reg = <0x400d0000 0x1000>;

View File

@ -4,6 +4,7 @@ config ARCH_VEXPRESS
select ARCH_SUPPORTS_BIG_ENDIAN
select ARM_AMBA
select ARM_GIC
select ARM_GLOBAL_TIMER
select ARM_TIMER_SP804
select COMMON_CLK_VERSATILE
select HAVE_ARM_SCU if SMP

View File

@ -136,6 +136,11 @@ config CLKSRC_SAMSUNG_PWM
for all devicetree enabled platforms. This driver will be
needed only on systems that do not have the Exynos MCT available.
config FSL_FTM_TIMER
bool
help
Support for Freescale FlexTimer Module (FTM) timer.
config VF_PIT_TIMER
bool
help

View File

@ -31,6 +31,7 @@ obj-$(CONFIG_CADENCE_TTC_TIMER) += cadence_ttc_timer.o
obj-$(CONFIG_CLKSRC_EFM32) += time-efm32.o
obj-$(CONFIG_CLKSRC_EXYNOS_MCT) += exynos_mct.o
obj-$(CONFIG_CLKSRC_SAMSUNG_PWM) += samsung_pwm_timer.o
obj-$(CONFIG_FSL_FTM_TIMER) += fsl_ftm_timer.o
obj-$(CONFIG_VF_PIT_TIMER) += vf_pit_timer.o
obj-$(CONFIG_CLKSRC_QCOM) += qcom-timer.o

View File

@ -246,11 +246,12 @@ static void __init global_timer_of_register(struct device_node *np)
int err = 0;
/*
* In r2p0 the comparators for each processor with the global timer
* In A9 r2p0 the comparators for each processor with the global timer
* fire when the timer value is greater than or equal to. In previous
* revisions the comparators fired when the timer value was equal to.
*/
if ((read_cpuid_id() & 0xf0000f) < 0x200000) {
if (read_cpuid_part_number() == ARM_CPU_PART_CORTEX_A9
&& (read_cpuid_id() & 0xf0000f) < 0x200000) {
pr_warn("global-timer: non support for this cpu version.\n");
return;
}

View File

@ -106,7 +106,7 @@ static void __init add_clocksource(struct device_node *source_timer)
sched_rate = rate;
}
static u64 read_sched_clock(void)
static u64 notrace read_sched_clock(void)
{
return ~__raw_readl(sched_io_base);
}

View File

@ -318,10 +318,8 @@ static int em_sti_probe(struct platform_device *pdev)
int irq;
p = devm_kzalloc(&pdev->dev, sizeof(*p), GFP_KERNEL);
if (p == NULL) {
dev_err(&pdev->dev, "failed to allocate driver data\n");
if (p == NULL)
return -ENOMEM;
}
p->pdev = pdev;
platform_set_drvdata(pdev, p);

View File

@ -0,0 +1,367 @@
/*
* Freescale FlexTimer Module (FTM) timer driver.
*
* Copyright 2014 Freescale Semiconductor, Inc.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*/
#include <linux/clk.h>
#include <linux/clockchips.h>
#include <linux/clocksource.h>
#include <linux/err.h>
#include <linux/interrupt.h>
#include <linux/io.h>
#include <linux/of_address.h>
#include <linux/of_irq.h>
#include <linux/sched_clock.h>
#include <linux/slab.h>
#define FTM_SC 0x00
#define FTM_SC_CLK_SHIFT 3
#define FTM_SC_CLK_MASK (0x3 << FTM_SC_CLK_SHIFT)
#define FTM_SC_CLK(c) ((c) << FTM_SC_CLK_SHIFT)
#define FTM_SC_PS_MASK 0x7
#define FTM_SC_TOIE BIT(6)
#define FTM_SC_TOF BIT(7)
#define FTM_CNT 0x04
#define FTM_MOD 0x08
#define FTM_CNTIN 0x4C
#define FTM_PS_MAX 7
struct ftm_clock_device {
void __iomem *clksrc_base;
void __iomem *clkevt_base;
unsigned long periodic_cyc;
unsigned long ps;
bool big_endian;
};
static struct ftm_clock_device *priv;
static inline u32 ftm_readl(void __iomem *addr)
{
if (priv->big_endian)
return ioread32be(addr);
else
return ioread32(addr);
}
static inline void ftm_writel(u32 val, void __iomem *addr)
{
if (priv->big_endian)
iowrite32be(val, addr);
else
iowrite32(val, addr);
}
static inline void ftm_counter_enable(void __iomem *base)
{
u32 val;
/* select and enable counter clock source */
val = ftm_readl(base + FTM_SC);
val &= ~(FTM_SC_PS_MASK | FTM_SC_CLK_MASK);
val |= priv->ps | FTM_SC_CLK(1);
ftm_writel(val, base + FTM_SC);
}
static inline void ftm_counter_disable(void __iomem *base)
{
u32 val;
/* disable counter clock source */
val = ftm_readl(base + FTM_SC);
val &= ~(FTM_SC_PS_MASK | FTM_SC_CLK_MASK);
ftm_writel(val, base + FTM_SC);
}
static inline void ftm_irq_acknowledge(void __iomem *base)
{
u32 val;
val = ftm_readl(base + FTM_SC);
val &= ~FTM_SC_TOF;
ftm_writel(val, base + FTM_SC);
}
static inline void ftm_irq_enable(void __iomem *base)
{
u32 val;
val = ftm_readl(base + FTM_SC);
val |= FTM_SC_TOIE;
ftm_writel(val, base + FTM_SC);
}
static inline void ftm_irq_disable(void __iomem *base)
{
u32 val;
val = ftm_readl(base + FTM_SC);
val &= ~FTM_SC_TOIE;
ftm_writel(val, base + FTM_SC);
}
static inline void ftm_reset_counter(void __iomem *base)
{
/*
* The CNT register contains the FTM counter value.
* Reset clears the CNT register. Writing any value to COUNT
* updates the counter with its initial value, CNTIN.
*/
ftm_writel(0x00, base + FTM_CNT);
}
static u64 ftm_read_sched_clock(void)
{
return ftm_readl(priv->clksrc_base + FTM_CNT);
}
static int ftm_set_next_event(unsigned long delta,
struct clock_event_device *unused)
{
/*
* The CNNIN and MOD are all double buffer registers, writing
* to the MOD register latches the value into a buffer. The MOD
* register is updated with the value of its write buffer with
* the following scenario:
* a, the counter source clock is diabled.
*/
ftm_counter_disable(priv->clkevt_base);
/* Force the value of CNTIN to be loaded into the FTM counter */
ftm_reset_counter(priv->clkevt_base);
/*
* The counter increments until the value of MOD is reached,
* at which point the counter is reloaded with the value of CNTIN.
* The TOF (the overflow flag) bit is set when the FTM counter
* changes from MOD to CNTIN. So we should using the delta - 1.
*/
ftm_writel(delta - 1, priv->clkevt_base + FTM_MOD);
ftm_counter_enable(priv->clkevt_base);
ftm_irq_enable(priv->clkevt_base);
return 0;
}
static void ftm_set_mode(enum clock_event_mode mode,
struct clock_event_device *evt)
{
switch (mode) {
case CLOCK_EVT_MODE_PERIODIC:
ftm_set_next_event(priv->periodic_cyc, evt);
break;
case CLOCK_EVT_MODE_ONESHOT:
ftm_counter_disable(priv->clkevt_base);
break;
default:
return;
}
}
static irqreturn_t ftm_evt_interrupt(int irq, void *dev_id)
{
struct clock_event_device *evt = dev_id;
ftm_irq_acknowledge(priv->clkevt_base);
if (likely(evt->mode == CLOCK_EVT_MODE_ONESHOT)) {
ftm_irq_disable(priv->clkevt_base);
ftm_counter_disable(priv->clkevt_base);
}
evt->event_handler(evt);
return IRQ_HANDLED;
}
static struct clock_event_device ftm_clockevent = {
.name = "Freescale ftm timer",
.features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT,
.set_mode = ftm_set_mode,
.set_next_event = ftm_set_next_event,
.rating = 300,
};
static struct irqaction ftm_timer_irq = {
.name = "Freescale ftm timer",
.flags = IRQF_TIMER | IRQF_IRQPOLL,
.handler = ftm_evt_interrupt,
.dev_id = &ftm_clockevent,
};
static int __init ftm_clockevent_init(unsigned long freq, int irq)
{
int err;
ftm_writel(0x00, priv->clkevt_base + FTM_CNTIN);
ftm_writel(~0UL, priv->clkevt_base + FTM_MOD);
ftm_reset_counter(priv->clkevt_base);
err = setup_irq(irq, &ftm_timer_irq);
if (err) {
pr_err("ftm: setup irq failed: %d\n", err);
return err;
}
ftm_clockevent.cpumask = cpumask_of(0);
ftm_clockevent.irq = irq;
clockevents_config_and_register(&ftm_clockevent,
freq / (1 << priv->ps),
1, 0xffff);
ftm_counter_enable(priv->clkevt_base);
return 0;
}
static int __init ftm_clocksource_init(unsigned long freq)
{
int err;
ftm_writel(0x00, priv->clksrc_base + FTM_CNTIN);
ftm_writel(~0UL, priv->clksrc_base + FTM_MOD);
ftm_reset_counter(priv->clksrc_base);
sched_clock_register(ftm_read_sched_clock, 16, freq / (1 << priv->ps));
err = clocksource_mmio_init(priv->clksrc_base + FTM_CNT, "fsl-ftm",
freq / (1 << priv->ps), 300, 16,
clocksource_mmio_readl_up);
if (err) {
pr_err("ftm: init clock source mmio failed: %d\n", err);
return err;
}
ftm_counter_enable(priv->clksrc_base);
return 0;
}
static int __init __ftm_clk_init(struct device_node *np, char *cnt_name,
char *ftm_name)
{
struct clk *clk;
int err;
clk = of_clk_get_by_name(np, cnt_name);
if (IS_ERR(clk)) {
pr_err("ftm: Cannot get \"%s\": %ld\n", cnt_name, PTR_ERR(clk));
return PTR_ERR(clk);
}
err = clk_prepare_enable(clk);
if (err) {
pr_err("ftm: clock failed to prepare+enable \"%s\": %d\n",
cnt_name, err);
return err;
}
clk = of_clk_get_by_name(np, ftm_name);
if (IS_ERR(clk)) {
pr_err("ftm: Cannot get \"%s\": %ld\n", ftm_name, PTR_ERR(clk));
return PTR_ERR(clk);
}
err = clk_prepare_enable(clk);
if (err)
pr_err("ftm: clock failed to prepare+enable \"%s\": %d\n",
ftm_name, err);
return clk_get_rate(clk);
}
static unsigned long __init ftm_clk_init(struct device_node *np)
{
unsigned long freq;
freq = __ftm_clk_init(np, "ftm-evt-counter-en", "ftm-evt");
if (freq <= 0)
return 0;
freq = __ftm_clk_init(np, "ftm-src-counter-en", "ftm-src");
if (freq <= 0)
return 0;
return freq;
}
static int __init ftm_calc_closest_round_cyc(unsigned long freq)
{
priv->ps = 0;
/* The counter register is only using the lower 16 bits, and
* if the 'freq' value is to big here, then the periodic_cyc
* may exceed 0xFFFF.
*/
do {
priv->periodic_cyc = DIV_ROUND_CLOSEST(freq,
HZ * (1 << priv->ps++));
} while (priv->periodic_cyc > 0xFFFF);
if (priv->ps > FTM_PS_MAX) {
pr_err("ftm: the prescaler is %lu > %d\n",
priv->ps, FTM_PS_MAX);
return -EINVAL;
}
return 0;
}
static void __init ftm_timer_init(struct device_node *np)
{
unsigned long freq;
int irq;
priv = kzalloc(sizeof(*priv), GFP_KERNEL);
if (!priv)
return;
priv->clkevt_base = of_iomap(np, 0);
if (!priv->clkevt_base) {
pr_err("ftm: unable to map event timer registers\n");
goto err;
}
priv->clksrc_base = of_iomap(np, 1);
if (!priv->clksrc_base) {
pr_err("ftm: unable to map source timer registers\n");
goto err;
}
irq = irq_of_parse_and_map(np, 0);
if (irq <= 0) {
pr_err("ftm: unable to get IRQ from DT, %d\n", irq);
goto err;
}
priv->big_endian = of_property_read_bool(np, "big-endian");
freq = ftm_clk_init(np);
if (!freq)
goto err;
if (ftm_calc_closest_round_cyc(freq))
goto err;
if (ftm_clocksource_init(freq))
goto err;
if (ftm_clockevent_init(freq, irq))
goto err;
return;
err:
kfree(priv);
}
CLOCKSOURCE_OF_DECLARE(flextimer, "fsl,ftm-timer", ftm_timer_init);

View File

@ -22,22 +22,22 @@ static inline struct clocksource_mmio *to_mmio_clksrc(struct clocksource *c)
cycle_t clocksource_mmio_readl_up(struct clocksource *c)
{
return readl_relaxed(to_mmio_clksrc(c)->reg);
return (cycle_t)readl_relaxed(to_mmio_clksrc(c)->reg);
}
cycle_t clocksource_mmio_readl_down(struct clocksource *c)
{
return ~readl_relaxed(to_mmio_clksrc(c)->reg);
return ~(cycle_t)readl_relaxed(to_mmio_clksrc(c)->reg) & c->mask;
}
cycle_t clocksource_mmio_readw_up(struct clocksource *c)
{
return readw_relaxed(to_mmio_clksrc(c)->reg);
return (cycle_t)readw_relaxed(to_mmio_clksrc(c)->reg);
}
cycle_t clocksource_mmio_readw_down(struct clocksource *c)
{
return ~(unsigned)readw_relaxed(to_mmio_clksrc(c)->reg);
return ~(cycle_t)readw_relaxed(to_mmio_clksrc(c)->reg) & c->mask;
}
/**

View File

@ -26,6 +26,8 @@
#include <linux/of_irq.h>
#include <linux/sched_clock.h>
#include <asm/delay.h>
#define TIMER_MATCH_VAL 0x0000
#define TIMER_COUNT_VAL 0x0004
#define TIMER_ENABLE 0x0008
@ -179,6 +181,15 @@ static u64 notrace msm_sched_clock_read(void)
return msm_clocksource.read(&msm_clocksource);
}
static unsigned long msm_read_current_timer(void)
{
return msm_clocksource.read(&msm_clocksource);
}
static struct delay_timer msm_delay_timer = {
.read_current_timer = msm_read_current_timer,
};
static void __init msm_timer_init(u32 dgt_hz, int sched_bits, int irq,
bool percpu)
{
@ -217,6 +228,8 @@ err:
if (res)
pr_err("clocksource_register failed\n");
sched_clock_register(msm_sched_clock_read, sched_bits, dgt_hz);
msm_delay_timer.freq = dgt_hz;
register_current_timer_delay(&msm_delay_timer);
}
#ifdef CONFIG_ARCH_QCOM

View File

@ -1106,10 +1106,8 @@ static int sh_cmt_probe(struct platform_device *pdev)
}
cmt = kzalloc(sizeof(*cmt), GFP_KERNEL);
if (cmt == NULL) {
dev_err(&pdev->dev, "failed to allocate driver data\n");
if (cmt == NULL)
return -ENOMEM;
}
ret = sh_cmt_setup(cmt, pdev);
if (ret) {

View File

@ -533,10 +533,8 @@ static int sh_mtu2_probe(struct platform_device *pdev)
}
mtu = kzalloc(sizeof(*mtu), GFP_KERNEL);
if (mtu == NULL) {
dev_err(&pdev->dev, "failed to allocate driver data\n");
if (mtu == NULL)
return -ENOMEM;
}
ret = sh_mtu2_setup(mtu, pdev);
if (ret) {

View File

@ -498,7 +498,7 @@ static int sh_tmu_channel_setup(struct sh_tmu_channel *ch, unsigned int index,
ch->base = tmu->mapbase + 8 + ch->index * 12;
}
ch->irq = platform_get_irq(tmu->pdev, ch->index);
ch->irq = platform_get_irq(tmu->pdev, index);
if (ch->irq < 0) {
dev_err(&tmu->pdev->dev, "ch%u: failed to get irq\n",
ch->index);
@ -644,10 +644,8 @@ static int sh_tmu_probe(struct platform_device *pdev)
}
tmu = kzalloc(sizeof(*tmu), GFP_KERNEL);
if (tmu == NULL) {
dev_err(&pdev->dev, "failed to allocate driver data\n");
if (tmu == NULL)
return -ENOMEM;
}
ret = sh_tmu_setup(tmu, pdev);
if (ret) {

View File

@ -272,4 +272,5 @@ static void __init efm32_timer_init(struct device_node *np)
}
}
}
CLOCKSOURCE_OF_DECLARE(efm32, "efm32,timer", efm32_timer_init);
CLOCKSOURCE_OF_DECLARE(efm32compat, "efm32,timer", efm32_timer_init);
CLOCKSOURCE_OF_DECLARE(efm32, "energymicro,efm32-timer", efm32_timer_init);

View File

@ -16,6 +16,7 @@
#include <linux/interrupt.h>
#include <linux/irq.h>
#include <linux/irqreturn.h>
#include <linux/reset.h>
#include <linux/sched_clock.h>
#include <linux/of.h>
#include <linux/of_address.h>
@ -143,6 +144,7 @@ static u64 sun5i_timer_sched_read(void)
static void __init sun5i_timer_init(struct device_node *node)
{
struct reset_control *rstc;
unsigned long rate;
struct clk *clk;
int ret, irq;
@ -162,6 +164,10 @@ static void __init sun5i_timer_init(struct device_node *node)
clk_prepare_enable(clk);
rate = clk_get_rate(clk);
rstc = of_reset_control_get(node, NULL);
if (!IS_ERR(rstc))
reset_control_deassert(rstc);
writel(~0, timer_base + TIMER_INTVAL_LO_REG(1));
writel(TIMER_CTL_ENABLE | TIMER_CTL_RELOAD,
timer_base + TIMER_CTL_REG(1));

View File

@ -14,7 +14,6 @@ extern void sched_clock_postinit(void);
static inline void sched_clock_postinit(void) { }
#endif
extern void setup_sched_clock(u32 (*read)(void), int bits, unsigned long rate);
extern void sched_clock_register(u64 (*read)(void), int bits,
unsigned long rate);

View File

@ -165,21 +165,21 @@ static inline void pps_set_freq(s64 freq)
static inline int is_error_status(int status)
{
return (time_status & (STA_UNSYNC|STA_CLOCKERR))
return (status & (STA_UNSYNC|STA_CLOCKERR))
/* PPS signal lost when either PPS time or
* PPS frequency synchronization requested
*/
|| ((time_status & (STA_PPSFREQ|STA_PPSTIME))
&& !(time_status & STA_PPSSIGNAL))
|| ((status & (STA_PPSFREQ|STA_PPSTIME))
&& !(status & STA_PPSSIGNAL))
/* PPS jitter exceeded when
* PPS time synchronization requested */
|| ((time_status & (STA_PPSTIME|STA_PPSJITTER))
|| ((status & (STA_PPSTIME|STA_PPSJITTER))
== (STA_PPSTIME|STA_PPSJITTER))
/* PPS wander exceeded or calibration error when
* PPS frequency synchronization requested
*/
|| ((time_status & STA_PPSFREQ)
&& (time_status & (STA_PPSWANDER|STA_PPSERROR)));
|| ((status & STA_PPSFREQ)
&& (status & (STA_PPSWANDER|STA_PPSERROR)));
}
static inline void pps_fill_timex(struct timex *txc)
@ -923,7 +923,10 @@ void __hardpps(const struct timespec *phase_ts, const struct timespec *raw_ts)
static int __init ntp_tick_adj_setup(char *str)
{
ntp_tick_adj = simple_strtol(str, NULL, 0);
int rc = kstrtol(str, 0, (long *)&ntp_tick_adj);
if (rc)
return rc;
ntp_tick_adj <<= NTP_SCALE_SHIFT;
return 1;

View File

@ -49,13 +49,6 @@ static u64 notrace jiffy_sched_clock_read(void)
return (u64)(jiffies - INITIAL_JIFFIES);
}
static u32 __read_mostly (*read_sched_clock_32)(void);
static u64 notrace read_sched_clock_32_wrapper(void)
{
return read_sched_clock_32();
}
static u64 __read_mostly (*read_sched_clock)(void) = jiffy_sched_clock_read;
static inline u64 notrace cyc_to_ns(u64 cyc, u32 mult, u32 shift)
@ -176,12 +169,6 @@ void __init sched_clock_register(u64 (*read)(void), int bits,
pr_debug("Registered %pF as sched_clock source\n", read);
}
void __init setup_sched_clock(u32 (*read)(void), int bits, unsigned long rate)
{
read_sched_clock_32 = read;
sched_clock_register(read_sched_clock_32_wrapper, bits, rate);
}
void __init sched_clock_postinit(void)
{
/*