Skip to content

Commit

Permalink
Merge branch 'clockevents/4.2' of http://git.linaro.org/people/daniel…
Browse files Browse the repository at this point in the history
….lezcano/linux into timers/core

Pull clockevents/clocksource changes from Daniel Lezcano:

  - Removed dead code in the files related to mach-msm for qcom (Stephen Boyd)
  - Cleaned up code for exynos_mct (Krzysztof Kozlowski)
  - Added the new timer lpc3220 (Joachim Eastwood)
  - Added the new timer STM32 and ARM system timer (Maxime Coquelin)
  • Loading branch information
Thomas Gleixner committed Jun 2, 2015
2 parents be3ef76 + d4688bd commit 09cbbf0
Show file tree
Hide file tree
Showing 10 changed files with 632 additions and 78 deletions.
26 changes: 26 additions & 0 deletions Documentation/devicetree/bindings/arm/armv7m_systick.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
* ARMv7M System Timer

ARMv7-M includes a system timer, known as SysTick. Current driver only
implements the clocksource feature.

Required properties:
- compatible : Should be "arm,armv7m-systick"
- reg : The address range of the timer

Required clocking property, have to be one of:
- clocks : The input clock of the timer
- clock-frequency : The rate in HZ in input of the ARM SysTick

Examples:

systick: timer@e000e010 {
compatible = "arm,armv7m-systick";
reg = <0xe000e010 0x10>;
clocks = <&clk_systick>;
};

systick: timer@e000e010 {
compatible = "arm,armv7m-systick";
reg = <0xe000e010 0x10>;
clock-frequency = <90000000>;
};
26 changes: 26 additions & 0 deletions Documentation/devicetree/bindings/timer/nxp,lpc3220-timer.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
* NXP LPC3220 timer

The NXP LPC3220 timer is used on a wide range of NXP SoCs. This
includes LPC32xx, LPC178x, LPC18xx and LPC43xx parts.

Required properties:
- compatible:
Should be "nxp,lpc3220-timer".
- reg:
Address and length of the register set.
- interrupts:
Reference to the timer interrupt
- clocks:
Should contain a reference to timer clock.
- clock-names:
Should contain "timerclk".

Example:

timer1: timer@40085000 {
compatible = "nxp,lpc3220-timer";
reg = <0x40085000 0x1000>;
interrupts = <13>;
clocks = <&ccu1 CLK_CPU_TIMER1>;
clock-names = "timerclk";
};
22 changes: 22 additions & 0 deletions Documentation/devicetree/bindings/timer/st,stm32-timer.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
. STMicroelectronics STM32 timer

The STM32 MCUs family has several general-purpose 16 and 32 bits timers.

Required properties:
- compatible : Should be "st,stm32-timer"
- reg : Address and length of the register set
- clocks : Reference on the timer input clock
- interrupts : Reference to the timer interrupt

Optional properties:
- resets: Reference to a reset controller asserting the timer

Example:

timer5: timer@40000c00 {
compatible = "st,stm32-timer";
reg = <0x40000c00 0x400>;
interrupts = <50>;
resets = <&rrc 259>;
clocks = <&clk_pmtr1>;
};
17 changes: 17 additions & 0 deletions drivers/clocksource/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,16 @@ config CLKSRC_EFM32
Support to use the timers of EFM32 SoCs as clock source and clock
event device.

config CLKSRC_LPC32XX
bool
select CLKSRC_MMIO
select CLKSRC_OF

config CLKSRC_STM32
bool "Clocksource for STM32 SoCs" if COMPILE_TEST
depends on OF
select CLKSRC_MMIO

config ARM_ARCH_TIMER
bool
select CLKSRC_OF if OF
Expand Down Expand Up @@ -139,6 +149,13 @@ config CLKSRC_ARM_GLOBAL_TIMER_SCHED_CLOCK
help
Use ARM global timer clock source as sched_clock

config ARMV7M_SYSTICK
bool
select CLKSRC_OF if OF
select CLKSRC_MMIO
help
This options enables support for the ARMv7M system timer unit

config ATMEL_PIT
select CLKSRC_OF if OF
def_bool SOC_AT91SAM9 || SOC_SAMA5
Expand Down
3 changes: 3 additions & 0 deletions drivers/clocksource/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,9 @@ obj-$(CONFIG_ARCH_NSPIRE) += zevio-timer.o
obj-$(CONFIG_ARCH_BCM_MOBILE) += bcm_kona_timer.o
obj-$(CONFIG_CADENCE_TTC_TIMER) += cadence_ttc_timer.o
obj-$(CONFIG_CLKSRC_EFM32) += time-efm32.o
obj-$(CONFIG_CLKSRC_STM32) += timer-stm32.o
obj-$(CONFIG_CLKSRC_EXYNOS_MCT) += exynos_mct.o
obj-$(CONFIG_CLKSRC_LPC32XX) += time-lpc32xx.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
Expand All @@ -45,6 +47,7 @@ obj-$(CONFIG_MTK_TIMER) += mtk_timer.o

obj-$(CONFIG_ARM_ARCH_TIMER) += arm_arch_timer.o
obj-$(CONFIG_ARM_GLOBAL_TIMER) += arm_global_timer.o
obj-$(CONFIG_ARMV7M_SYSTICK) += armv7m_systick.o
obj-$(CONFIG_CLKSRC_METAG_GENERIC) += metag_generic.o
obj-$(CONFIG_ARCH_HAS_TICK_BROADCAST) += dummy_timer.o
obj-$(CONFIG_ARCH_KEYSTONE) += timer-keystone.o
Expand Down
79 changes: 79 additions & 0 deletions drivers/clocksource/armv7m_systick.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
/*
* Copyright (C) Maxime Coquelin 2015
* Author: Maxime Coquelin <mcoquelin.stm32@gmail.com>
* License terms: GNU General Public License (GPL), version 2
*/

#include <linux/kernel.h>
#include <linux/clocksource.h>
#include <linux/clockchips.h>
#include <linux/of.h>
#include <linux/of_address.h>
#include <linux/clk.h>
#include <linux/bitops.h>

#define SYST_CSR 0x00
#define SYST_RVR 0x04
#define SYST_CVR 0x08
#define SYST_CALIB 0x0c

#define SYST_CSR_ENABLE BIT(0)

#define SYSTICK_LOAD_RELOAD_MASK 0x00FFFFFF

static void __init system_timer_of_register(struct device_node *np)
{
struct clk *clk = NULL;
void __iomem *base;
u32 rate;
int ret;

base = of_iomap(np, 0);
if (!base) {
pr_warn("system-timer: invalid base address\n");
return;
}

ret = of_property_read_u32(np, "clock-frequency", &rate);
if (ret) {
clk = of_clk_get(np, 0);
if (IS_ERR(clk))
goto out_unmap;

ret = clk_prepare_enable(clk);
if (ret)
goto out_clk_put;

rate = clk_get_rate(clk);
if (!rate)
goto out_clk_disable;
}

writel_relaxed(SYSTICK_LOAD_RELOAD_MASK, base + SYST_RVR);
writel_relaxed(SYST_CSR_ENABLE, base + SYST_CSR);

ret = clocksource_mmio_init(base + SYST_CVR, "arm_system_timer", rate,
200, 24, clocksource_mmio_readl_down);
if (ret) {
pr_err("failed to init clocksource (%d)\n", ret);
if (clk)
goto out_clk_disable;
else
goto out_unmap;
}

pr_info("ARM System timer initialized as clocksource\n");

return;

out_clk_disable:
clk_disable_unprepare(clk);
out_clk_put:
clk_put(clk);
out_unmap:
iounmap(base);
pr_warn("ARM System timer register failed (%d)\n", ret);
}

CLOCKSOURCE_OF_DECLARE(arm_systick, "arm,armv7m-systick",
system_timer_of_register);
22 changes: 3 additions & 19 deletions drivers/clocksource/exynos_mct.c
Original file line number Diff line number Diff line change
Expand Up @@ -209,7 +209,7 @@ static void exynos4_frc_resume(struct clocksource *cs)
exynos4_mct_frc_start();
}

struct clocksource mct_frc = {
static struct clocksource mct_frc = {
.name = "mct-frc",
.rating = 400,
.read = exynos4_frc_read,
Expand Down Expand Up @@ -413,7 +413,7 @@ static inline void exynos4_tick_set_mode(enum clock_event_mode mode,
}
}

static int exynos4_mct_tick_clear(struct mct_clock_event_device *mevt)
static void exynos4_mct_tick_clear(struct mct_clock_event_device *mevt)
{
struct clock_event_device *evt = &mevt->evt;

Expand All @@ -426,12 +426,8 @@ static int exynos4_mct_tick_clear(struct mct_clock_event_device *mevt)
exynos4_mct_tick_stop(mevt);

/* Clear the MCT tick interrupt */
if (readl_relaxed(reg_base + mevt->base + MCT_L_INT_CSTAT_OFFSET) & 1) {
if (readl_relaxed(reg_base + mevt->base + MCT_L_INT_CSTAT_OFFSET) & 1)
exynos4_mct_write(0x1, mevt->base + MCT_L_INT_CSTAT_OFFSET);
return 1;
} else {
return 0;
}
}

static irqreturn_t exynos4_mct_tick_isr(int irq, void *dev_id)
Expand Down Expand Up @@ -564,18 +560,6 @@ static void __init exynos4_timer_resources(struct device_node *np, void __iomem
free_percpu_irq(mct_irqs[MCT_L0_IRQ], &percpu_mct_tick);
}

void __init mct_init(void __iomem *base, int irq_g0, int irq_l0, int irq_l1)
{
mct_irqs[MCT_G0_IRQ] = irq_g0;
mct_irqs[MCT_L0_IRQ] = irq_l0;
mct_irqs[MCT_L1_IRQ] = irq_l1;
mct_int_type = MCT_INT_SPI;

exynos4_timer_resources(NULL, base);
exynos4_clocksource_init();
exynos4_clockevent_init();
}

static void __init mct_init_dt(struct device_node *np, unsigned int int_type)
{
u32 nr_irqs, i;
Expand Down
59 changes: 0 additions & 59 deletions drivers/clocksource/qcom-timer.c
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,6 @@

#define GPT_HZ 32768

#define MSM_DGT_SHIFT 5

static void __iomem *event_base;
static void __iomem *sts_base;

Expand Down Expand Up @@ -232,7 +230,6 @@ static void __init msm_timer_init(u32 dgt_hz, int sched_bits, int irq,
register_current_timer_delay(&msm_delay_timer);
}

#ifdef CONFIG_ARCH_QCOM
static void __init msm_dt_timer_init(struct device_node *np)
{
u32 freq;
Expand Down Expand Up @@ -285,59 +282,3 @@ static void __init msm_dt_timer_init(struct device_node *np)
}
CLOCKSOURCE_OF_DECLARE(kpss_timer, "qcom,kpss-timer", msm_dt_timer_init);
CLOCKSOURCE_OF_DECLARE(scss_timer, "qcom,scss-timer", msm_dt_timer_init);
#else

static int __init msm_timer_map(phys_addr_t addr, u32 event, u32 source,
u32 sts)
{
void __iomem *base;

base = ioremap(addr, SZ_256);
if (!base) {
pr_err("Failed to map timer base\n");
return -ENOMEM;
}
event_base = base + event;
source_base = base + source;
if (sts)
sts_base = base + sts;

return 0;
}

static notrace cycle_t msm_read_timer_count_shift(struct clocksource *cs)
{
/*
* Shift timer count down by a constant due to unreliable lower bits
* on some targets.
*/
return msm_read_timer_count(cs) >> MSM_DGT_SHIFT;
}

void __init msm7x01_timer_init(void)
{
struct clocksource *cs = &msm_clocksource;

if (msm_timer_map(0xc0100000, 0x0, 0x10, 0x0))
return;
cs->read = msm_read_timer_count_shift;
cs->mask = CLOCKSOURCE_MASK((32 - MSM_DGT_SHIFT));
/* 600 KHz */
msm_timer_init(19200000 >> MSM_DGT_SHIFT, 32 - MSM_DGT_SHIFT, 7,
false);
}

void __init msm7x30_timer_init(void)
{
if (msm_timer_map(0xc0100000, 0x4, 0x24, 0x80))
return;
msm_timer_init(24576000 / 4, 32, 1, false);
}

void __init qsd8x50_timer_init(void)
{
if (msm_timer_map(0xAC100000, 0x0, 0x10, 0x34))
return;
msm_timer_init(19200000 / 4, 32, 7, false);
}
#endif
Loading

0 comments on commit 09cbbf0

Please sign in to comment.