Skip to content

Commit

Permalink
Merge branch 'timers-core-for-linus' of git://git.kernel.org/pub/scm/…
Browse files Browse the repository at this point in the history
…linux/kernel/git/tip/tip

Pull timer updates from Thomas Gleixner:
 "A rather largish update for everything time and timer related:

   - Cache footprint optimizations for both hrtimers and timer wheel

   - Lower the NOHZ impact on systems which have NOHZ or timer migration
     disabled at runtime.

   - Optimize run time overhead of hrtimer interrupt by making the clock
     offset updates smarter

   - hrtimer cleanups and removal of restrictions to tackle some
     problems in sched/perf

   - Some more leap second tweaks

   - Another round of changes addressing the 2038 problem

   - First step to change the internals of clock event devices by
     introducing the necessary infrastructure

   - Allow constant folding for usecs/msecs_to_jiffies()

   - The usual pile of clockevent/clocksource driver updates

  The hrtimer changes contain updates to sched, perf and x86 as they
  depend on them plus changes all over the tree to cleanup API changes
  and redundant code, which got copied all over the place.  The y2038
  changes touch s390 to remove the last non 2038 safe code related to
  boot/persistant clock"

* 'timers-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: (114 commits)
  clocksource: Increase dependencies of timer-stm32 to limit build wreckage
  timer: Minimize nohz off overhead
  timer: Reduce timer migration overhead if disabled
  timer: Stats: Simplify the flags handling
  timer: Replace timer base by a cpu index
  timer: Use hlist for the timer wheel hash buckets
  timer: Remove FIFO "guarantee"
  timers: Sanitize catchup_timer_jiffies() usage
  hrtimer: Allow hrtimer::function() to free the timer
  seqcount: Introduce raw_write_seqcount_barrier()
  seqcount: Rename write_seqcount_barrier()
  hrtimer: Fix hrtimer_is_queued() hole
  hrtimer: Remove HRTIMER_STATE_MIGRATE
  selftest: Timers: Avoid signal deadlock in leap-a-day
  timekeeping: Copy the shadow-timekeeper over the real timekeeper last
  clockevents: Check state instead of mode in suspend/resume path
  selftests: timers: Add leap-second timer edge testing to leap-a-day.c
  ntp: Do leapsecond adjustment in adjtimex read path
  time: Prevent early expiry of hrtimers[CLOCK_REALTIME] at the leap second edge
  ntp: Introduce and use SECS_PER_DAY macro instead of 86400
  ...
  • Loading branch information
torvalds committed Jun 23, 2015
2 parents d70b3ef + 1cb6c21 commit 43224b9
Show file tree
Hide file tree
Showing 78 changed files with 2,292 additions and 1,563 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>;
};
34 changes: 27 additions & 7 deletions Kbuild
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,9 @@
# Kbuild for top-level directory of the kernel
# This file takes care of the following:
# 1) Generate bounds.h
# 2) Generate asm-offsets.h (may need bounds.h)
# 3) Check for missing system calls
# 2) Generate timeconst.h
# 3) Generate asm-offsets.h (may need bounds.h and timeconst.h)
# 4) Check for missing system calls

# Default sed regexp - multiline due to syntax constraints
define sed-y
Expand Down Expand Up @@ -47,7 +48,26 @@ $(obj)/$(bounds-file): kernel/bounds.s FORCE
$(call filechk,offsets,__LINUX_BOUNDS_H__)

#####
# 2) Generate asm-offsets.h
# 2) Generate timeconst.h

timeconst-file := include/generated/timeconst.h

#always += $(timeconst-file)
targets += $(timeconst-file)

quiet_cmd_gentimeconst = GEN $@
define cmd_gentimeconst
(echo $(CONFIG_HZ) | bc -q $< ) > $@
endef
define filechk_gentimeconst
(echo $(CONFIG_HZ) | bc -q $< )
endef

$(obj)/$(timeconst-file): kernel/time/timeconst.bc FORCE
$(call filechk,gentimeconst)

#####
# 3) Generate asm-offsets.h
#

offsets-file := include/generated/asm-offsets.h
Expand All @@ -57,15 +77,15 @@ targets += arch/$(SRCARCH)/kernel/asm-offsets.s

# We use internal kbuild rules to avoid the "is up to date" message from make
arch/$(SRCARCH)/kernel/asm-offsets.s: arch/$(SRCARCH)/kernel/asm-offsets.c \
$(obj)/$(bounds-file) FORCE
$(obj)/$(timeconst-file) $(obj)/$(bounds-file) FORCE
$(Q)mkdir -p $(dir $@)
$(call if_changed_dep,cc_s_c)

$(obj)/$(offsets-file): arch/$(SRCARCH)/kernel/asm-offsets.s FORCE
$(call filechk,offsets,__ASM_OFFSETS_H__)

#####
# 3) Check for missing system calls
# 4) Check for missing system calls
#

always += missing-syscalls
Expand All @@ -77,5 +97,5 @@ quiet_cmd_syscalls = CALL $<
missing-syscalls: scripts/checksyscalls.sh $(offsets-file) FORCE
$(call cmd,syscalls)

# Keep these two files during make clean
no-clean-files := $(bounds-file) $(offsets-file)
# Keep these three files during make clean
no-clean-files := $(bounds-file) $(offsets-file) $(timeconst-file)
5 changes: 3 additions & 2 deletions arch/s390/include/asm/timex.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
#define _ASM_S390_TIMEX_H

#include <asm/lowcore.h>
#include <linux/time64.h>

/* The value of the TOD clock for 1.1.1970. */
#define TOD_UNIX_EPOCH 0x7d91048bca000000ULL
Expand Down Expand Up @@ -108,10 +109,10 @@ int get_sync_clock(unsigned long long *clock);
void init_cpu_timer(void);
unsigned long long monotonic_clock(void);

void tod_to_timeval(__u64, struct timespec *);
void tod_to_timeval(__u64 todval, struct timespec64 *xt);

static inline
void stck_to_timespec(unsigned long long stck, struct timespec *ts)
void stck_to_timespec64(unsigned long long stck, struct timespec64 *ts)
{
tod_to_timeval(stck - TOD_UNIX_EPOCH, ts);
}
Expand Down
11 changes: 6 additions & 5 deletions arch/s390/kernel/debug.c
Original file line number Diff line number Diff line change
Expand Up @@ -1457,23 +1457,24 @@ int
debug_dflt_header_fn(debug_info_t * id, struct debug_view *view,
int area, debug_entry_t * entry, char *out_buf)
{
struct timespec time_spec;
struct timespec64 time_spec;
char *except_str;
unsigned long caller;
int rc = 0;
unsigned int level;

level = entry->id.fields.level;
stck_to_timespec(entry->id.stck, &time_spec);
stck_to_timespec64(entry->id.stck, &time_spec);

if (entry->id.fields.exception)
except_str = "*";
else
except_str = "-";
caller = ((unsigned long) entry->caller) & PSW_ADDR_INSN;
rc += sprintf(out_buf, "%02i %011lu:%06lu %1u %1s %02i %p ",
area, time_spec.tv_sec, time_spec.tv_nsec / 1000, level,
except_str, entry->id.fields.cpuid, (void *) caller);
rc += sprintf(out_buf, "%02i %011lld:%06lu %1u %1s %02i %p ",
area, (long long)time_spec.tv_sec,
time_spec.tv_nsec / 1000, level, except_str,
entry->id.fields.cpuid, (void *)caller);
return rc;
}
EXPORT_SYMBOL(debug_dflt_header_fn);
Expand Down
6 changes: 3 additions & 3 deletions arch/s390/kernel/time.c
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ unsigned long long monotonic_clock(void)
}
EXPORT_SYMBOL(monotonic_clock);

void tod_to_timeval(__u64 todval, struct timespec *xt)
void tod_to_timeval(__u64 todval, struct timespec64 *xt)
{
unsigned long long sec;

Expand Down Expand Up @@ -181,12 +181,12 @@ static void timing_alert_interrupt(struct ext_code ext_code,
static void etr_reset(void);
static void stp_reset(void);

void read_persistent_clock(struct timespec *ts)
void read_persistent_clock64(struct timespec64 *ts)
{
tod_to_timeval(get_tod_clock() - TOD_UNIX_EPOCH, ts);
}

void read_boot_clock(struct timespec *ts)
void read_boot_clock64(struct timespec64 *ts)
{
tod_to_timeval(sched_clock_base_cc - TOD_UNIX_EPOCH, ts);
}
Expand Down
5 changes: 2 additions & 3 deletions arch/x86/kernel/cpu/perf_event_intel_rapl.c
Original file line number Diff line number Diff line change
Expand Up @@ -204,9 +204,8 @@ static u64 rapl_event_update(struct perf_event *event)

static void rapl_start_hrtimer(struct rapl_pmu *pmu)
{
__hrtimer_start_range_ns(&pmu->hrtimer,
pmu->timer_interval, 0,
HRTIMER_MODE_REL_PINNED, 0);
hrtimer_start(&pmu->hrtimer, pmu->timer_interval,
HRTIMER_MODE_REL_PINNED);
}

static void rapl_stop_hrtimer(struct rapl_pmu *pmu)
Expand Down
5 changes: 2 additions & 3 deletions arch/x86/kernel/cpu/perf_event_intel_uncore.c
Original file line number Diff line number Diff line change
Expand Up @@ -233,9 +233,8 @@ static enum hrtimer_restart uncore_pmu_hrtimer(struct hrtimer *hrtimer)

void uncore_pmu_start_hrtimer(struct intel_uncore_box *box)
{
__hrtimer_start_range_ns(&box->hrtimer,
ns_to_ktime(box->hrtimer_duration), 0,
HRTIMER_MODE_REL_PINNED, 0);
hrtimer_start(&box->hrtimer, ns_to_ktime(box->hrtimer_duration),
HRTIMER_MODE_REL_PINNED);
}

void uncore_pmu_cancel_hrtimer(struct intel_uncore_box *box)
Expand Down
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 !ARCH_STM32
depends on OF && ARM && (ARCH_STM32 || COMPILE_TEST)
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 <[email protected]>
* 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);
2 changes: 1 addition & 1 deletion drivers/clocksource/asm9260_timer.c
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,7 @@ static void __init asm9260_timer_init(struct device_node *np)
unsigned long rate;

priv.base = of_io_request_and_map(np, 0, np->name);
if (!priv.base)
if (IS_ERR(priv.base))
panic("%s: unable to map resource", np->name);

clk = of_clk_get(np, 0);
Expand Down
Loading

0 comments on commit 43224b9

Please sign in to comment.