timer changes for v4.1
Subsystems (27)
Ingo Molnar
maintainerLinus,
Please pull the latest timers-core-for-linus git tree from:
git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git timers-core-for-linus
# HEAD: def747087e83aa5f6a71582cfa71e18341988688 timers/PM: Drop unnecessary braces from tick_freeze()
The main changes in this cycle were:
- clockevents state machine cleanups and enhancements (Viresh Kumar)
- clockevents broadcast notifier horror to state machine conversion and related cleanups. (Thomas Gleixner, Rafael J. Wysocki)
- clocksource and timekeeping core updates. (John Stultz)
- clocksource driver updates and fixes. (Ben Dooks, Dmitry Osipenko, Hans de Goede, Laurent Pinchart, Maxime Ripard, Xunlei Pang)
- y2038 fixes. (Xunlei Pang, John Stultz)
- NMI-safe ktime_get_raw_fast() and general refactoring of the clock code, in preparation to perf's per event clock ID support. (Peter Zijlstra)
- generic sched/clock fixes, optimizations and cleanups (Daniel Thompson)
- clockevents cpu_down() race fix (Preeti U Murthy)
Thanks,
Ingo
------------------>
Ben Dooks (2):
clocksource/drivers/dw_apb_timers_of: Fix IO endianness causing time jumps clocksource/drivers/at91: Fix IO endianness
Daniel Thompson (5):
timers, sched/clock: Match scope of read and write seqcounts timers, sched/clock: Optimize cache line usage
timers, sched/clock: Remove suspend from clock_read_data() timers, sched/clock: Remove redundant notrace from update function timers, sched/clock: Avoid deadlock during read from NMI
Dmitry Osipenko (1):
clocksource/drivers/tegra: Fix IO endianness
Hans de Goede (1):
clocksource/drivers/sun4i-timer: Only register a sched_clock on sun4i and sun5i
Ingo Molnar (3):
timers, sched/clock: Clean up the code a bit
tick: Further simplify tick-internal.h
clockevents: Clean up clockchips.h
John Stultz (13):
clocksource: Simplify the clocks_calc_max_nsecs() logic
clocksource: Simplify the logic around clocksource wrapping safety margins
clocksource: Add 'max_cycles' to 'struct clocksource'
timekeeping: Add debugging checks to warn if we see delays
timekeeping: Add checks to cap clocksource reads to the 'max_cycles' value
timekeeping: Try to catch clocksource delta underflows
timekeeping: Add warnings when overflows or underflows are observed
clocksource: Improve clocksource watchdog reporting
clocksource: Mostly kill clocksource_register()
clocksource, sparc32: Convert to using clocksource_register_hz()
clocksource: Add some debug info about clocksources being registered
clocksource: Rename __clocksource_updatefreq_*() to __clocksource_update_freq_*()
clocksource: Improve comment explaining clocks_calc_max_nsecs()'s 50% safety margin
Laurent Pinchart (1):
clocksource/drivers/arm_arch_timer: Rename 'arch_timer_probed()' to 'arch_timer_needs_probing()' to reflect behaviour
Maxime Ripard (4):
clocksource/drivers/sun5i: Switch to request_irq() clocksource/drivers/sun5i: Use of_io_request_and_map() clocksource/drivers/sun5i: Refactor the current code clocksource/drivers/sun5i: Add clock notifiers
Peter Zijlstra (7):
time: Rename timekeeper::tkr to timekeeper::tkr_mono
time: Add timerkeeper::tkr_raw
time: Parametrize all tk_fast_mono users
time: Introduce tk_fast_raw
time: Add ktime_get_tai_ns()
timer: Allocate per-cpu tvec_base's statically
timer: Further simplify the SMP and HOTPLUG logic
Preeti U Murthy (1):
clockevents: Fix cpu_down() race for hrtimer based broadcasting
Rafael J. Wysocki (3):
clockevents: Remove broadcast oneshot control leftovers timers/PM: Fix up tick_unfreeze()
timers/PM: Drop unnecessary braces from tick_freeze()
Thomas Gleixner (29):
clockevents: Remove CONFIG_GENERIC_CLOCKEVENTS_BUILD
tick: Move clocksource related stuff to timekeeping.h
tick: Simplify tick-internal.h
tick: Move core only declarations and functions to core
clockevents: Remove extra local_irq_save() in clockevents_exchange_device()
clockevents: Make suspend/resume calls explicit
tick: Make tick_resume_broadcast_oneshot() static
tick/xen: Provide and use tick_suspend_local() and tick_resume_local() arm/bL_switcher: Kill tick suspend hackery
ACPI/PAD: Remove the local APIC nonsense
clockevents: Provide explicit broadcast control functions x86/amd/idle, clockevents: Use explicit broadcast control function ACPI/PAD: Use explicit broadcast control function ACPI/processor: Use explicit broadcast control function
cpuidle: Use explicit broadcast control function
intel_idle: Use explicit broadcast control function
ARM: OMAP: Use explicit broadcast control function
clockevents: Remove the broadcast control leftovers
clockevents: Provide explicit broadcast oneshot control functions x86/amd/idle, clockevents: Use explicit broadcast oneshot control functions ACPI/PAD: Use explicit broadcast oneshot control function ACPI/idle: Use explicit broadcast control function
intel_idle: Use explicit broadcast oneshot control function
ARM: OMAP: Use explicit broadcast oneshot control function
ARM: Tegra: Use explicit broadcast oneshot control function sched/idle: Use explicit broadcast oneshot control function
clockevents: Make tick handover explicit
clockevents: Cleanup dead cpu explicitely
timekeeping: Get rid of stale comment
Viresh Kumar (6):
clockevents: Introduce mode specific callbacks
clockevents: Handle tick device's resume separately
clockevents: Manage device's state separately for the core
clockevents: Don't validate dev->mode against CLOCK_EVT_MODE_UNUSED for new interface clocksource/drivers/efm32: Use CLOCK_EVT_FEAT_PERIODIC for defining features
timer: Don't initialize 'tvec_base' on hotplug
Xunlei Pang (18):
time: Add y2038 safe read_boot_clock64()
time: Add y2038 safe read_persistent_clock64()
time: Add y2038 safe update_persistent_clock64()
ARM: OMAP: 32k counter: Provide y2038-safe omap_read_persistent_clock() replacement clocksource/drivers/tegra: Provide y2038-safe tegra_read_persistent_clock() replacement ARM, clocksource/drivers: Provide read_boot_clock64() and read_persistent_clock64() and use them drivers/rtc: Provide y2038 safe rtc_class_ops.set_mmss() replacement drivers/rtc/test: Update driver to address y2038/y2106 issues drivers/rtc/ab3100: Update driver to address y2038/y2106 issues drivers/rtc/mc13xxx: Update driver to address y2038/y2106 issues drivers/rtc/mxc: Modify rtc_update_alarm() not to touch the alarm time drivers/rtc/mxc: Convert get_alarm_or_time()/set_alarm_or_time() to use time64_t drivers/rtc/mxc: Update driver to address y2038/y2106 issues
alpha, rtc: Change to use rtc_class_ops's set_mmss64()
time: Don't build timekeeping_inject_sleeptime64() if no one uses it drivers/rtc: Remove redundant rtc_valid_tm() from rtc_resume()
time: Fix a bug in timekeeping_suspend() with no persistent clock
time, drivers/rtc: Don't bother with rtc_resume() for the nonstop clocksource
arch/alpha/kernel/rtc.c | 8 +- arch/arm/common/bL_switcher.c | 16 +- arch/arm/include/asm/mach/time.h | 3 +- arch/arm/kernel/time.c | 6 +- arch/arm/mach-omap2/cpuidle44xx.c | 10 +- arch/arm/mach-tegra/cpuidle-tegra114.c | 6 +- arch/arm/mach-tegra/cpuidle-tegra20.c | 10 +- arch/arm/mach-tegra/cpuidle-tegra30.c | 10 +- arch/arm/plat-omap/counter_32k.c | 20 +- arch/arm64/kernel/vdso.c | 10 +- arch/mips/lasat/sysctl.c | 4 +- arch/s390/kernel/time.c | 20 +- arch/sparc/kernel/time_32.c | 6 +- arch/tile/kernel/time.c | 24 +- arch/x86/kernel/process.c | 13 +- arch/x86/kernel/vsyscall_gtod.c | 24 +- arch/x86/kvm/x86.c | 14 +- arch/x86/xen/suspend.c | 11 +- drivers/acpi/acpi_pad.c | 29 +- drivers/acpi/processor_idle.c | 20 +- drivers/clocksource/arm_arch_timer.c | 12 +- drivers/clocksource/dw_apb_timer_of.c | 2 +- drivers/clocksource/em_sti.c | 2 +- drivers/clocksource/sh_cmt.c | 2 +- drivers/clocksource/sh_tmu.c | 2 +- drivers/clocksource/sun4i_timer.c | 10 +- drivers/clocksource/tegra20_timer.c | 19 +- drivers/clocksource/time-efm32.c | 2 +- drivers/clocksource/timer-atmel-pit.c | 4 +- drivers/clocksource/timer-sun5i.c | 299 +++++++++++++++----- drivers/cpuidle/driver.c | 23 +- drivers/idle/intel_idle.c | 17 +- drivers/rtc/class.c | 8 +- drivers/rtc/interface.c | 8 +- drivers/rtc/rtc-ab3100.c | 55 ++-- drivers/rtc/rtc-mc13xxx.c | 32 +-- drivers/rtc/rtc-mxc.c | 55 ++-- drivers/rtc/rtc-test.c | 19 +- drivers/rtc/systohc.c | 7 +- include/linux/clockchips.h | 154 ++++++----- include/linux/clocksource.h | 25 +- include/linux/rtc.h | 1 + include/linux/tick.h | 190 +++++-------- include/linux/timekeeper_internal.h | 16 +- include/linux/timekeeping.h | 18 +- kernel/cpu.c | 5 + kernel/sched/idle.c | 5 +- kernel/time/Kconfig | 6 - kernel/time/Makefile | 6 +- kernel/time/clockevents.c | 229 +++++++++------ kernel/time/clocksource.c | 173 ++++++------ kernel/time/hrtimer.c | 9 +- kernel/time/jiffies.c | 7 +- kernel/time/ntp.c | 14 +- kernel/time/sched_clock.c | 236 +++++++++++----- kernel/time/tick-broadcast.c | 179 ++++++------ kernel/time/tick-common.c | 82 ++++-- kernel/time/tick-internal.h | 211 ++++++-------- kernel/time/tick-oneshot.c | 6 +- kernel/time/tick-sched.c | 7 +- kernel/time/tick-sched.h | 74 +++++ kernel/time/timekeeping.c | 490 ++++++++++++++++++++++----------- kernel/time/timekeeping.h | 7 + kernel/time/timer.c | 149 +++++----- kernel/time/timer_list.c | 34 ++- lib/Kconfig.debug | 13 + 66 files changed, 1849 insertions(+), 1339 deletions(-) create mode 100644 kernel/time/tick-sched.h
arch/alpha/kernel/rtc.c +4 -4
@@ -116,7 +116,7 @@ alpha_rtc_set_time(struct device *dev, struct rtc_time *tm) }static int -alpha_rtc_set_mmss (struct device *dev,unsigned long nowtime) +alpha_rtc_set_mmss (struct device *dev,time64_t nowtime) {int retval =0 ;int real_seconds, real_minutes, cmos_minutes;
@@ -211,7 +211,7 @@ alpha_rtc_ioctl(struct device *dev, unsigned int cmd, unsigned long arg)static const struct rtc_class_ops alpha_rtc_ops = { .read_time = alpha_rtc_read_time, .set_time = alpha_rtc_set_time, - .set_mmss = alpha_rtc_set_mmss, + .set_mmss64 = alpha_rtc_set_mmss, .ioctl = alpha_rtc_ioctl, };
@@ -276,7 +276,7 @@ do_remote_mmss(void *data) }static int -remote_set_mmss (struct device *dev,unsigned long now) +remote_set_mmss (struct device *dev,time64_t now) {union remote_data x;if (smp_processor_id () != boot_cpuid) {
@@ -290,7 +290,7 @@ remote_set_mmss(struct device *dev, unsigned long now)static const struct rtc_class_ops remote_rtc_ops = { .read_time = remote_read_time, .set_time = remote_set_time, - .set_mmss = remote_set_mmss, + .set_mmss64 = remote_set_mmss, .ioctl = alpha_rtc_ioctl, };#endif
arch/arm/common/bL_switcher.c +2 -14
@@ -151,8 +151,6 @@ static int bL_switch_to(unsigned int new_cluster_id)unsigned int mpidr, this_cpu, that_cpu;unsigned int ob_mpidr, ob_cpu, ob_cluster, ib_mpidr, ib_cpu, ib_cluster;struct completion inbound_alive; -struct tick_device *tdev; -enum clock_event_mode tdev_mode;long volatile *handshake_ptr;int ipi_nr, ret;
@@ -219,13 +217,7 @@ static int bL_switch_to(unsigned int new_cluster_id)/* redirect GIC's SGIs to our counterpart */ gic_migrate_target (bL_gic_id[ib_cpu][ib_cluster]); - tdev =tick_get_device (this_cpu); -if (tdev && !cpumask_equal (tdev->evtdev->cpumask,cpumask_of (this_cpu))) - tdev =NULL ; -if (tdev) { - tdev_mode = tdev->evtdev->mode; -clockevents_set_mode (tdev->evtdev,CLOCK_EVT_MODE_SHUTDOWN ); - } +tick_suspend_local (); ret =cpu_pm_enter ();
@@ -251,11 +243,7 @@ static int bL_switch_to(unsigned int new_cluster_id) ret =cpu_pm_exit (); -if (tdev) { -clockevents_set_mode (tdev->evtdev, tdev_mode); -clockevents_program_event (tdev->evtdev, - tdev->evtdev->next_event,1 ); - } +tick_resume_local ();trace_cpu_migrate_finish (ktime_get_real_ns (), ib_mpidr);local_fiq_enable ();
arch/arm/include/asm/mach/time.h +1 -2
@@ -12,8 +12,7 @@extern void timer_tick (void ); -struct timespec ; -typedef void (*clock_access_fn )(struct timespec *); +typedef void (*clock_access_fn )(struct timespec64 *);extern int register_persistent_clock (clock_access_fn read_boot,clock_access_fn read_persistent);
arch/arm/kernel/time.c +3 -3
@@ -76,7 +76,7 @@ void timer_tick(void) }#endif -static void dummy_clock_access (struct timespec *ts) +static void dummy_clock_access (struct timespec64 *ts) { ts->tv_sec =0 ; ts->tv_nsec =0 ;
@@ -85,12 +85,12 @@ static void dummy_clock_access(struct timespec *ts)static clock_access_fn __read_persistent_clock = dummy_clock_access;static clock_access_fn __read_boot_clock = dummy_clock_access;; -void read_persistent_clock (struct timespec *ts) +void read_persistent_clock64 (struct timespec64 *ts) {__read_persistent_clock (ts); } -void read_boot_clock (struct timespec *ts) +void read_boot_clock64 (struct timespec64 *ts) {__read_boot_clock (ts); }
arch/arm/mach-omap2/cpuidle44xx.c +4 -6
@@ -14,7 +14,7 @@#include <linux/cpuidle.h> #include <linux/cpu_pm.h> #include <linux/export.h> -#include <linux/clockchips.h> +#include <linux/tick.h> #include <asm/cpuidle.h> #include <asm/proc-fns.h>
@@ -84,7 +84,6 @@ static int omap_enter_idle_coupled(struct cpuidle_device *dev, {struct idle_statedata *cx = state_ptr + index;u32 mpuss_can_lose_context =0 ; -int cpu_id =smp_processor_id ();/* * CPU0 has to wait and stay ON until CPU1 is OFF state.
@@ -112,7 +111,7 @@ static int omap_enter_idle_coupled(struct cpuidle_device *dev, mpuss_can_lose_context = (cx->mpu_state ==PWRDM_POWER_RET ) && (cx->mpu_logic_state ==PWRDM_POWER_OFF ); -clockevents_notify (CLOCK_EVT_NOTIFY_BROADCAST_ENTER , &cpu_id); +tick_broadcast_enter ();/* * Call idle CPU PM enter notifier chain so that
@@ -169,7 +168,7 @@ static int omap_enter_idle_coupled(struct cpuidle_device *dev,if (dev->cpu ==0 && mpuss_can_lose_context)cpu_cluster_pm_exit (); -clockevents_notify (CLOCK_EVT_NOTIFY_BROADCAST_EXIT , &cpu_id); +tick_broadcast_exit (); fail:cpuidle_coupled_parallel_barrier (dev, &abort_barrier);
@@ -184,8 +183,7 @@ static int omap_enter_idle_coupled(struct cpuidle_device *dev,*/ static void omap_setup_broadcast_timer (void *arg) { -int cpu =smp_processor_id (); -clockevents_notify (CLOCK_EVT_NOTIFY_BROADCAST_ON , &cpu); +tick_broadcast_enable (); }static struct cpuidle_driver omap4_idle_driver = {
arch/arm/mach-tegra/cpuidle-tegra114.c +3 -3
@@ -15,7 +15,7 @@*/ #include <asm/firmware.h> -#include <linux/clockchips.h> +#include <linux/tick.h> #include <linux/cpuidle.h> #include <linux/cpu_pm.h> #include <linux/kernel.h>
@@ -44,7 +44,7 @@ static int tegra114_idle_power_down(struct cpuidle_device *dev,tegra_set_cpu_in_lp2 ();cpu_pm_enter (); -clockevents_notify (CLOCK_EVT_NOTIFY_BROADCAST_ENTER , &dev->cpu); +tick_broadcast_enter ();call_firmware_op (prepare_idle);
@@ -52,7 +52,7 @@ static int tegra114_idle_power_down(struct cpuidle_device *dev,if (call_firmware_op (do_idle,0 ) == -ENOSYS )cpu_suspend (0 , tegra30_sleep_cpu_secondary_finish); -clockevents_notify (CLOCK_EVT_NOTIFY_BROADCAST_EXIT , &dev->cpu); +tick_broadcast_exit ();cpu_pm_exit ();tegra_clear_cpu_in_lp2 ();
arch/arm/mach-tegra/cpuidle-tegra20.c +5 -5
@@ -20,7 +20,7 @@*/ #include <linux/clk/tegra.h> -#include <linux/clockchips.h> +#include <linux/tick.h> #include <linux/cpuidle.h> #include <linux/cpu_pm.h> #include <linux/kernel.h>
@@ -136,11 +136,11 @@ static bool tegra20_cpu_cluster_power_down(struct cpuidle_device *dev,if (tegra20_reset_cpu_1 () || !tegra_cpu_rail_off_ready ())return false; -clockevents_notify (CLOCK_EVT_NOTIFY_BROADCAST_ENTER , &dev->cpu); +tick_broadcast_enter ();tegra_idle_lp2_last (); -clockevents_notify (CLOCK_EVT_NOTIFY_BROADCAST_EXIT , &dev->cpu); +tick_broadcast_exit ();if (cpu_online (1 ))tegra20_wake_cpu1_from_reset ();
@@ -153,13 +153,13 @@ static bool tegra20_idle_enter_lp2_cpu_1(struct cpuidle_device *dev,struct cpuidle_driver *drv, int index) { - clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_ENTER, &dev->cpu); +tick_broadcast_enter ();cpu_suspend (0 , tegra20_sleep_cpu_secondary_finish);tegra20_cpu_clear_resettable (); -clockevents_notify (CLOCK_EVT_NOTIFY_BROADCAST_EXIT , &dev->cpu); +tick_broadcast_exit ();return true; }
arch/arm/mach-tegra/cpuidle-tegra30.c +5 -5
@@ -20,7 +20,7 @@*/ #include <linux/clk/tegra.h> -#include <linux/clockchips.h> +#include <linux/tick.h> #include <linux/cpuidle.h> #include <linux/cpu_pm.h> #include <linux/kernel.h>
@@ -76,11 +76,11 @@ static bool tegra30_cpu_cluster_power_down(struct cpuidle_device *dev,return false; } -clockevents_notify (CLOCK_EVT_NOTIFY_BROADCAST_ENTER , &dev->cpu); +tick_broadcast_enter ();tegra_idle_lp2_last (); -clockevents_notify (CLOCK_EVT_NOTIFY_BROADCAST_EXIT , &dev->cpu); +tick_broadcast_exit ();return true; }
@@ -90,13 +90,13 @@ static bool tegra30_cpu_core_power_down(struct cpuidle_device *dev,struct cpuidle_driver *drv, int index) { - clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_ENTER, &dev->cpu); +tick_broadcast_enter ();smp_wmb ();cpu_suspend (0 , tegra30_sleep_cpu_secondary_finish); -clockevents_notify (CLOCK_EVT_NOTIFY_BROADCAST_EXIT , &dev->cpu); +tick_broadcast_exit ();return true; }
arch/arm/plat-omap/counter_32k.c +7 -13
@@ -44,24 +44,20 @@ static u64 notrace omap_32k_read_sched_clock(void) }/** -* omap_read_persistent_clock - Return time from a persistent clock. +* omap_read_persistent_clock64 - Return time from a persistent clock. * * Reads the time from a source which isn't disabled during PM, the * 32k sync timer. Convert the cycles elapsed since last read into -* nsecs and adds to a monotonically increasing timespec. +* nsecs and adds to a monotonically increasing timespec64. */ -static struct timespec persistent_ts; +static struct timespec64 persistent_ts;static cycles_t cycles;static unsigned int persistent_mult, persistent_shift; -static DEFINE_SPINLOCK (read_persistent_clock_lock); -static void omap_read_persistent_clock (struct timespec *ts) +static void omap_read_persistent_clock64 (struct timespec64 *ts) {unsigned long long nsecs;cycles_t last_cycles; -unsigned long flags; - -spin_lock_irqsave (&read_persistent_clock_lock, flags); last_cycles = cycles; cycles = sync32k_cnt_reg ?readl_relaxed (sync32k_cnt_reg) :0 ;
@@ -69,11 +65,9 @@ static void omap_read_persistent_clock(struct timespec *ts) nsecs =clocksource_cyc2ns (cycles - last_cycles, persistent_mult, persistent_shift); -timespec_add_ns (&persistent_ts, nsecs); +timespec64_add_ns (&persistent_ts, nsecs); *ts = persistent_ts; - -spin_unlock_irqrestore (&read_persistent_clock_lock, flags); }/**
@@ -103,7 +97,7 @@ int __init omap_init_clocksource_32k(void __iomem *vbase)/* * 120000 rough estimate from the calculations in -* __clocksource_updatefreq_scale. +* __clocksource_update_freq_scale. */ clocks_calc_mult_shift (&persistent_mult, &persistent_shift,32768 ,NSEC_PER_SEC ,120000 );
@@ -116,7 +110,7 @@ int __init omap_init_clocksource_32k(void __iomem *vbase) }sched_clock_register (omap_32k_read_sched_clock,32 ,32768 ); -register_persistent_clock (NULL , omap_read_persistent_clock); +register_persistent_clock (NULL , omap_read_persistent_clock64);pr_info ("OMAP clocksource: 32k_counter at 32768 Hz\n" );return 0 ;
arch/arm64/kernel/vdso.c +5 -5
@@ -200,7 +200,7 @@ int arch_setup_additional_pages(struct linux_binprm *bprm,void update_vsyscall (struct timekeeper *tk) {struct timespec xtime_coarse; -u32 use_syscall =strcmp (tk->tkr.clock->name,"arch_sys_counter" ); +u32 use_syscall =strcmp (tk->tkr_mono.clock->name,"arch_sys_counter" ); ++vdso_data->tb_seq_count;smp_wmb ();
@@ -213,11 +213,11 @@ void update_vsyscall(struct timekeeper *tk) vdso_data->wtm_clock_nsec = tk->wall_to_monotonic.tv_nsec;if (!use_syscall) { - vdso_data->cs_cycle_last = tk->tkr.cycle_last; + vdso_data->cs_cycle_last = tk->tkr_mono.cycle_last; vdso_data->xtime_clock_sec = tk->xtime_sec; - vdso_data->xtime_clock_nsec = tk->tkr.xtime_nsec; - vdso_data->cs_mult = tk->tkr.mult; - vdso_data->cs_shift = tk->tkr.shift; + vdso_data->xtime_clock_nsec = tk->tkr_mono.xtime_nsec; + vdso_data->cs_mult = tk->tkr_mono.mult; + vdso_data->cs_shift = tk->tkr_mono.shift; }smp_wmb ();
arch/mips/lasat/sysctl.c +2 -2
@@ -75,11 +75,11 @@ static int rtctmp;int proc_dolasatrtc (struct ctl_table *table,int write,void *buffer,size_t *lenp,loff_t *ppos) { -struct timespec ts; +struct timespec64 ts;int r;if (!write) { -read_persistent_clock (&ts); +read_persistent_clock64 (&ts); rtctmp = ts.tv_sec;/* check for time < 0 and set to 0 */ if (rtctmp <0 )
arch/s390/kernel/time.c +10 -10
@@ -215,20 +215,20 @@ void update_vsyscall(struct timekeeper *tk) {u64 nsecps; -if (tk->tkr.clock != &clocksource_tod) +if (tk->tkr_mono.clock != &clocksource_tod)return ;/* Make userspace gettimeofday spin until we're done. */ ++vdso_data->tb_update_count;smp_wmb (); - vdso_data->xtime_tod_stamp = tk->tkr.cycle_last; + vdso_data->xtime_tod_stamp = tk->tkr_mono.cycle_last; vdso_data->xtime_clock_sec = tk->xtime_sec; - vdso_data->xtime_clock_nsec = tk->tkr.xtime_nsec; + vdso_data->xtime_clock_nsec = tk->tkr_mono.xtime_nsec; vdso_data->wtom_clock_sec = tk->xtime_sec + tk->wall_to_monotonic.tv_sec; - vdso_data->wtom_clock_nsec = tk->tkr.xtime_nsec + - + ((u64 ) tk->wall_to_monotonic.tv_nsec << tk->tkr.shift); - nsecps = (u64 )NSEC_PER_SEC << tk->tkr.shift; + vdso_data->wtom_clock_nsec = tk->tkr_mono.xtime_nsec + + + ((u64 ) tk->wall_to_monotonic.tv_nsec << tk->tkr_mono.shift); + nsecps = (u64 )NSEC_PER_SEC << tk->tkr_mono.shift;while (vdso_data->wtom_clock_nsec >= nsecps) { vdso_data->wtom_clock_nsec -= nsecps; vdso_data->wtom_clock_sec++;
@@ -236,7 +236,7 @@ void update_vsyscall(struct timekeeper *tk) vdso_data->xtime_coarse_sec = tk->xtime_sec; vdso_data->xtime_coarse_nsec = - (long )(tk->tkr.xtime_nsec >> tk->tkr.shift); + (long )(tk->tkr_mono.xtime_nsec >> tk->tkr_mono.shift); vdso_data->wtom_coarse_sec = vdso_data->xtime_coarse_sec + tk->wall_to_monotonic.tv_sec; vdso_data->wtom_coarse_nsec =
@@ -246,8 +246,8 @@ void update_vsyscall(struct timekeeper *tk) vdso_data->wtom_coarse_sec++; } - vdso_data->tk_mult = tk->tkr.mult; - vdso_data->tk_shift = tk->tkr.shift; + vdso_data->tk_mult = tk->tkr_mono.mult; + vdso_data->tk_shift = tk->tkr_mono.shift;smp_wmb (); ++vdso_data->tb_update_count; }
@@ -283,7 +283,7 @@ void __init time_init(void)if (register_external_irq (EXT_IRQ_TIMING_ALERT , timing_alert_interrupt))panic ("Couldn't request external interrupt 0x1406" ); -if (clocksource_register (&clocksource_tod) !=0 ) +if (__clocksource_register (&clocksource_tod) !=0 )panic ("Could not register TOD clock source" );/* Enable TOD clock interrupts on the boot cpu. */
arch/sparc/kernel/time_32.c +1 -5
@@ -181,17 +181,13 @@ static struct clocksource timer_cs = { .rating = 100, .read = timer_cs_read, .mask = CLOCKSOURCE_MASK(64), - .shift = 2, .flags = CLOCK_SOURCE_IS_CONTINUOUS, };static __init int setup_timer_cs (void ) { timer_cs_enabled =1 ; - timer_cs.mult =clocksource_hz2mult (sparc_config.clock_rate, - timer_cs.shift); - -return clocksource_register (&timer_cs); +return clocksource_register_hz (&timer_cs, sparc_config.clock_rate); }#ifdef CONFIG_SMP
arch/tile/kernel/time.c +12 -12
@@ -257,34 +257,34 @@ void update_vsyscall_tz(void)void update_vsyscall (struct timekeeper *tk) { -if (tk->tkr.clock != &cycle_counter_cs) +if (tk->tkr_mono.clock != &cycle_counter_cs)return ;write_seqcount_begin (&vdso_data->tb_seq); - vdso_data->cycle_last = tk->tkr.cycle_last; - vdso_data->mask = tk->tkr.mask; - vdso_data->mult = tk->tkr.mult; - vdso_data->shift = tk->tkr.shift; + vdso_data->cycle_last = tk->tkr_mono.cycle_last; + vdso_data->mask = tk->tkr_mono.mask; + vdso_data->mult = tk->tkr_mono.mult; + vdso_data->shift = tk->tkr_mono.shift; vdso_data->wall_time_sec = tk->xtime_sec; - vdso_data->wall_time_snsec = tk->tkr.xtime_nsec; + vdso_data->wall_time_snsec = tk->tkr_mono.xtime_nsec; vdso_data->monotonic_time_sec = tk->xtime_sec + tk->wall_to_monotonic.tv_sec; - vdso_data->monotonic_time_snsec = tk->tkr.xtime_nsec + vdso_data->monotonic_time_snsec = tk->tkr_mono.xtime_nsec + ((u64 )tk->wall_to_monotonic.tv_nsec - << tk->tkr.shift); + << tk->tkr_mono.shift);while (vdso_data->monotonic_time_snsec >= - (((u64 )NSEC_PER_SEC ) << tk->tkr.shift)) { + (((u64 )NSEC_PER_SEC ) << tk->tkr_mono.shift)) { vdso_data->monotonic_time_snsec -= - ((u64 )NSEC_PER_SEC ) << tk->tkr.shift; + ((u64 )NSEC_PER_SEC ) << tk->tkr_mono.shift; vdso_data->monotonic_time_sec++; } vdso_data->wall_time_coarse_sec = tk->xtime_sec; - vdso_data->wall_time_coarse_nsec = (long )(tk->tkr.xtime_nsec >> - tk->tkr.shift); + vdso_data->wall_time_coarse_nsec = (long )(tk->tkr_mono.xtime_nsec >> + tk->tkr_mono.shift); vdso_data->monotonic_time_coarse_sec = vdso_data->wall_time_coarse_sec + tk->wall_to_monotonic.tv_sec;
arch/x86/kernel/process.c +5 -8
@@ -9,7 +9,7 @@#include <linux/sched.h> #include <linux/module.h> #include <linux/pm.h> -#include <linux/clockchips.h> +#include <linux/tick.h> #include <linux/random.h> #include <linux/user-return-notifier.h> #include <linux/dmi.h>
@@ -377,14 +377,11 @@ static void amd_e400_idle(void)if (!cpumask_test_cpu (cpu, amd_e400_c1e_mask)) {cpumask_set_cpu (cpu, amd_e400_c1e_mask); -/* -* Force broadcast so ACPI can not interfere. -*/ -clockevents_notify (CLOCK_EVT_NOTIFY_BROADCAST_FORCE , - &cpu); +/* Force broadcast so ACPI can not interfere. */ +tick_broadcast_force ();pr_info ("Switch to broadcast mode on CPU%d\n" , cpu); } -clockevents_notify (CLOCK_EVT_NOTIFY_BROADCAST_ENTER , &cpu); +tick_broadcast_enter ();default_idle ();
@@ -393,7 +390,7 @@ static void amd_e400_idle(void)* called with interrupts disabled. */ local_irq_disable (); -clockevents_notify (CLOCK_EVT_NOTIFY_BROADCAST_EXIT , &cpu); +tick_broadcast_exit ();local_irq_enable (); }else default_idle ();
arch/x86/kernel/vsyscall_gtod.c +12 -12
@@ -31,30 +31,30 @@ void update_vsyscall(struct timekeeper *tk)gtod_write_begin (vdata);/* copy vsyscall data */ - vdata->vclock_mode = tk->tkr.clock->archdata.vclock_mode; - vdata->cycle_last = tk->tkr.cycle_last; - vdata->mask = tk->tkr.mask; - vdata->mult = tk->tkr.mult; - vdata->shift = tk->tkr.shift; + vdata->vclock_mode = tk->tkr_mono.clock->archdata.vclock_mode; + vdata->cycle_last = tk->tkr_mono.cycle_last; + vdata->mask = tk->tkr_mono.mask; + vdata->mult = tk->tkr_mono.mult; + vdata->shift = tk->tkr_mono.shift; vdata->wall_time_sec = tk->xtime_sec; - vdata->wall_time_snsec = tk->tkr.xtime_nsec; + vdata->wall_time_snsec = tk->tkr_mono.xtime_nsec; vdata->monotonic_time_sec = tk->xtime_sec + tk->wall_to_monotonic.tv_sec; - vdata->monotonic_time_snsec = tk->tkr.xtime_nsec + vdata->monotonic_time_snsec = tk->tkr_mono.xtime_nsec + ((u64 )tk->wall_to_monotonic.tv_nsec - << tk->tkr.shift); + << tk->tkr_mono.shift);while (vdata->monotonic_time_snsec >= - (((u64 )NSEC_PER_SEC ) << tk->tkr.shift)) { + (((u64 )NSEC_PER_SEC ) << tk->tkr_mono.shift)) { vdata->monotonic_time_snsec -= - ((u64 )NSEC_PER_SEC ) << tk->tkr.shift; + ((u64 )NSEC_PER_SEC ) << tk->tkr_mono.shift; vdata->monotonic_time_sec++; } vdata->wall_time_coarse_sec = tk->xtime_sec; - vdata->wall_time_coarse_nsec = (long )(tk->tkr.xtime_nsec >> - tk->tkr.shift); + vdata->wall_time_coarse_nsec = (long )(tk->tkr_mono.xtime_nsec >> + tk->tkr_mono.shift); vdata->monotonic_time_coarse_sec = vdata->wall_time_coarse_sec + tk->wall_to_monotonic.tv_sec;
arch/x86/kvm/x86.c +7 -7
@@ -1070,19 +1070,19 @@ static void update_pvclock_gtod(struct timekeeper *tk)struct pvclock_gtod_data *vdata = &pvclock_gtod_data;u64 boot_ns; - boot_ns =ktime_to_ns (ktime_add (tk->tkr.base_mono, tk->offs_boot)); + boot_ns =ktime_to_ns (ktime_add (tk->tkr_mono.base, tk->offs_boot));write_seqcount_begin (&vdata->seq);/* copy pvclock gtod data */ - vdata->clock.vclock_mode = tk->tkr.clock->archdata.vclock_mode; - vdata->clock.cycle_last = tk->tkr.cycle_last; - vdata->clock.mask = tk->tkr.mask; - vdata->clock.mult = tk->tkr.mult; - vdata->clock.shift = tk->tkr.shift; + vdata->clock.vclock_mode = tk->tkr_mono.clock->archdata.vclock_mode; + vdata->clock.cycle_last = tk->tkr_mono.cycle_last; + vdata->clock.mask = tk->tkr_mono.mask; + vdata->clock.mult = tk->tkr_mono.mult; + vdata->clock.shift = tk->tkr_mono.shift; vdata->boot_ns = boot_ns; - vdata->nsec_base = tk->tkr.xtime_nsec; + vdata->nsec_base = tk->tkr_mono.xtime_nsec;write_seqcount_end (&vdata->seq); }
arch/x86/xen/suspend.c +4 -7
@@ -1,5 +1,5 @@#include <linux/types.h> -#include <linux/clockchips.h> +#include <linux/tick.h> #include <xen/interface/xen.h> #include <xen/grant_table.h>
@@ -81,17 +81,14 @@ void xen_arch_post_suspend(int cancelled)static void xen_vcpu_notify_restore (void *data) { -unsigned long reason = (unsigned long )data; -/* Boot processor notified via generic timekeeping_resume() */ -if (smp_processor_id () ==0 ) +if (smp_processor_id () ==0 )return ; -clockevents_notify (reason,NULL ); +tick_resume_local (); }void xen_arch_resume (void ) { -on_each_cpu (xen_vcpu_notify_restore, - (void *)CLOCK_EVT_NOTIFY_RESUME ,1 ); +on_each_cpu (xen_vcpu_notify_restore,NULL ,1 ); }
drivers/acpi/acpi_pad.c +5 -24
@@ -26,7 +26,7 @@#include <linux/kthread.h> #include <linux/freezer.h> #include <linux/cpu.h> -#include <linux/clockchips.h> +#include <linux/tick.h> #include <linux/slab.h> #include <linux/acpi.h> #include <asm/mwait.h>
@@ -41,8 +41,6 @@ static unsigned long power_saving_mwait_eax;static unsigned char tsc_detected_unstable;static unsigned char tsc_marked_unstable; -static unsigned char lapic_detected_unstable; -static unsigned char lapic_marked_unstable;static void power_saving_mwait_init (void ) {
@@ -82,13 +80,10 @@ static void power_saving_mwait_init(void)*/ if (!boot_cpu_has (X86_FEATURE_NONSTOP_TSC )) tsc_detected_unstable =1 ; -if (!boot_cpu_has (X86_FEATURE_ARAT )) - lapic_detected_unstable =1 ;break ;default : -/* TSC & LAPIC could halt in idle */ +/* TSC could halt in idle */ tsc_detected_unstable = 1; - lapic_detected_unstable = 1; }#endif }
@@ -155,7 +150,6 @@ static int power_saving_thread(void *data)sched_setscheduler (current,SCHED_RR , ¶m);while (!kthread_should_stop ()) { -int cpu;unsigned long expire_time;try_to_freeze ();
@@ -177,28 +171,15 @@ static int power_saving_thread(void *data)mark_tsc_unstable ("TSC halts in idle" ); tsc_marked_unstable =1 ; } -if (lapic_detected_unstable && !lapic_marked_unstable) { -int i; -/* LAPIC could halt in idle, so notify users */ -for_each_online_cpu (i) -clockevents_notify ( -CLOCK_EVT_NOTIFY_BROADCAST_ON , - &i); - lapic_marked_unstable =1 ; - }local_irq_disable (); - cpu =smp_processor_id (); -if (lapic_marked_unstable) -clockevents_notify ( -CLOCK_EVT_NOTIFY_BROADCAST_ENTER , &cpu); +tick_broadcast_enable (); +tick_broadcast_enter ();stop_critical_timings ();mwait_idle_with_hints (power_saving_mwait_eax,1 );start_critical_timings (); -if (lapic_marked_unstable) -clockevents_notify ( -CLOCK_EVT_NOTIFY_BROADCAST_EXIT , &cpu); +tick_broadcast_exit ();local_irq_enable ();if (time_before (expire_time, jiffies)) {
drivers/acpi/processor_idle.c +9 -11
@@ -32,7 +32,7 @@#include <linux/acpi.h> #include <linux/dmi.h> #include <linux/sched.h> /* need_resched() */ -#include <linux/clockchips.h> +#include <linux/tick.h> #include <linux/cpuidle.h> #include <linux/syscore_ops.h> #include <acpi/processor.h>
@@ -157,12 +157,11 @@ static void lapic_timer_check_state(int state, struct acpi_processor *pr,static void __lapic_timer_propagate_broadcast (void *arg) {struct acpi_processor *pr = (struct acpi_processor *) arg; -unsigned long reason; - reason = pr->power.timer_broadcast_on_state <INT_MAX ? -CLOCK_EVT_NOTIFY_BROADCAST_ON :CLOCK_EVT_NOTIFY_BROADCAST_OFF ; - -clockevents_notify (reason, &pr->id); +if (pr->power.timer_broadcast_on_state <INT_MAX ) +tick_broadcast_enable (); +else +tick_broadcast_disable (); }static void lapic_timer_propagate_broadcast (struct acpi_processor *pr)
@@ -179,11 +178,10 @@ static void lapic_timer_state_broadcast(struct acpi_processor *pr,int state = cx - pr->power.states;if (state >= pr->power.timer_broadcast_on_state) { -unsigned long reason; - - reason = broadcast ?CLOCK_EVT_NOTIFY_BROADCAST_ENTER : -CLOCK_EVT_NOTIFY_BROADCAST_EXIT ; -clockevents_notify (reason, &pr->id); +if (broadcast) +tick_broadcast_enter (); +else +tick_broadcast_exit (); } }
drivers/clocksource/arm_arch_timer.c +6 -6
@@ -661,17 +661,17 @@ static const struct of_device_id arch_timer_mem_of_match[] __initconst = { };static bool __init -arch_timer_probed (int type,const struct of_device_id *matches) +arch_timer_needs_probing (int type,const struct of_device_id *matches) {struct device_node *dn; -bool probed = true; +bool needs_probing = false; dn =of_find_matching_node (NULL , matches);if (dn &&of_device_is_available (dn) && !(arch_timers_present & type)) - probed = false; + needs_probing = true;of_node_put (dn); -return probed; +return needs_probing; }static void __init arch_timer_common_init (void )
@@ -680,9 +680,9 @@ static void __init arch_timer_common_init(void)/* Wait until both nodes are probed if we have two timers */ if ((arch_timers_present & mask) != mask) { -if (!arch_timer_probed (ARCH_MEM_TIMER , arch_timer_mem_of_match)) +if (arch_timer_needs_probing (ARCH_MEM_TIMER , arch_timer_mem_of_match))return ; -if (!arch_timer_probed (ARCH_CP15_TIMER , arch_timer_of_match)) +if (arch_timer_needs_probing (ARCH_CP15_TIMER , arch_timer_of_match))return ; }
drivers/clocksource/dw_apb_timer_of.c +1 -1
@@ -108,7 +108,7 @@ static void __init add_clocksource(struct device_node *source_timer) static u64 notrace read_sched_clock(void) { -return ~__raw_readl (sched_io_base); +return ~readl_relaxed (sched_io_base); }static const struct of_device_id sptimer_ids[]__initconst = {
drivers/clocksource/em_sti.c +1 -1
@@ -210,7 +210,7 @@ static int em_sti_clocksource_enable(struct clocksource *cs) ret =em_sti_start (p,USER_CLOCKSOURCE );if (!ret) -__clocksource_updatefreq_hz (cs, p->rate); +__clocksource_update_freq_hz (cs, p->rate);return ret; }
drivers/clocksource/sh_cmt.c +1 -1
@@ -641,7 +641,7 @@ static int sh_cmt_clocksource_enable(struct clocksource *cs) ret =sh_cmt_start (ch,FLAG_CLOCKSOURCE );if (!ret) { -__clocksource_updatefreq_hz (cs, ch->rate); +__clocksource_update_freq_hz (cs, ch->rate); ch->cs_enabled = true; }return ret;
drivers/clocksource/sh_tmu.c +1 -1
@@ -272,7 +272,7 @@ static int sh_tmu_clocksource_enable(struct clocksource *cs) ret =sh_tmu_enable (ch);if (!ret) { -__clocksource_updatefreq_hz (cs, ch->rate); +__clocksource_update_freq_hz (cs, ch->rate); ch->cs_enabled = true; }
drivers/clocksource/sun4i_timer.c +9 -1
@@ -170,7 +170,15 @@ static void __init sun4i_timer_init(struct device_node *node)TIMER_CTL_CLK_SRC (TIMER_CTL_CLK_SRC_OSC24M ), timer_base + TIMER_CTL_REG(1)); -sched_clock_register (sun4i_timer_sched_read,32 , rate); +/* +* sched_clock_register does not have priorities, and on sun6i and +* later there is a better sched_clock registered by arm_arch_timer.c +*/ +if (of_machine_is_compatible ("allwinner,sun4i-a10" ) || +of_machine_is_compatible ("allwinner,sun5i-a13" ) || +of_machine_is_compatible ("allwinner,sun5i-a10s" )) +sched_clock_register (sun4i_timer_sched_read,32 , rate); +clocksource_mmio_init (timer_base +TIMER_CNTVAL_REG (1 ), node->name, rate,350 ,32 , clocksource_mmio_readl_down);
drivers/clocksource/tegra20_timer.c +9 -10
@@ -51,15 +51,15 @@static void __iomem *timer_reg_base;static void __iomem *rtc_base; -static struct timespec persistent_ts; +static struct timespec64 persistent_ts;static u64 persistent_ms, last_persistent_ms;static struct delay_timer tegra_delay_timer;#define timer_writel (value, reg) \ - __raw_writel(value, timer_reg_base + (reg)) + writel_relaxed(value, timer_reg_base + (reg))#define timer_readl (reg) \ - __raw_readl(timer_reg_base + (reg)) + readl_relaxed(timer_reg_base + (reg))static int tegra_timer_set_next_event (unsigned long cycles,struct clock_event_device *evt)
@@ -120,26 +120,25 @@ static u64 tegra_rtc_read_ms(void) }/* -* tegra_read_persistent_clock - Return time from a persistent clock. +* tegra_read_persistent_clock64 - Return time from a persistent clock. * * Reads the time from a source which isn't disabled during PM, the * 32k sync timer. Convert the cycles elapsed since last read into -* nsecs and adds to a monotonically increasing timespec. +* nsecs and adds to a monotonically increasing timespec64. * Care must be taken that this funciton is not called while the * tegra_rtc driver could be executing to avoid race conditions * on the RTC shadow register */ -static void tegra_read_persistent_clock (struct timespec *ts) +static void tegra_read_persistent_clock64 (struct timespec64 *ts) {u64 delta; -struct timespec *tsp = &persistent_ts; last_persistent_ms = persistent_ms; persistent_ms =tegra_rtc_read_ms (); delta = persistent_ms - last_persistent_ms; -timespec_add_ns (tsp, delta *NSEC_PER_MSEC ); - *ts = *tsp; +timespec64_add_ns (&persistent_ts, delta *NSEC_PER_MSEC ); + *ts = persistent_ts; }static unsigned long tegra_delay_timer_read_counter_long (void )
@@ -252,7 +251,7 @@ static void __init tegra20_init_rtc(struct device_node *np)else clk_prepare_enable (clk); -register_persistent_clock (NULL , tegra_read_persistent_clock); +register_persistent_clock (NULL , tegra_read_persistent_clock64); }CLOCKSOURCE_OF_DECLARE (tegra20_rtc,"nvidia,tegra20-rtc" , tegra20_init_rtc);
drivers/clocksource/time-efm32.c +1 -1
@@ -111,7 +111,7 @@ static irqreturn_t efm32_clock_event_handler(int irq, void *dev_id)static struct efm32_clock_event_ddata clock_event_ddata = { .evtdev = { .name ="efm32 clockevent" , - .features =CLOCK_EVT_FEAT_ONESHOT |CLOCK_EVT_MODE_PERIODIC , + .features =CLOCK_EVT_FEAT_ONESHOT |CLOCK_EVT_FEAT_PERIODIC , .set_mode = efm32_clock_event_set_mode, .set_next_event = efm32_clock_event_set_next_event, .rating =200 ,
drivers/clocksource/timer-atmel-pit.c +2 -2
@@ -61,12 +61,12 @@ static inline struct pit_data *clkevt_to_pit_data(struct clock_event_device *clkstatic inline unsigned int pit_read (void __iomem *base,unsigned int reg_offset) { -return __raw_readl (base + reg_offset); +return readl_relaxed (base + reg_offset); }static inline void pit_write (void __iomem *base,unsigned int reg_offset,unsigned long value) { -__raw_writel (value, base + reg_offset); +writel_relaxed (value, base + reg_offset); }/*
drivers/clocksource/timer-sun5i.c +228 -71
382 lines not on this page · raw message
drivers/cpuidle/driver.c +11 -12
@@ -13,7 +13,7 @@#include <linux/sched.h> #include <linux/cpuidle.h> #include <linux/cpumask.h> -#include <linux/clockchips.h> +#include <linux/tick.h> #include "cpuidle.h"
@@ -130,21 +130,20 @@ static inline void __cpuidle_unset_driver(struct cpuidle_driver *drv)#endif /** -* cpuidle_setup_broadcast_timer - enable/disable the broadcast timer +* cpuidle_setup_broadcast_timer - enable/disable the broadcast timer on a cpu * @arg: a void pointer used to match the SMP cross call API * -* @arg is used as a value of type 'long' with one of the two values: -* - CLOCK_EVT_NOTIFY_BROADCAST_ON -* - CLOCK_EVT_NOTIFY_BROADCAST_OFF +* If @arg is NULL broadcast is disabled otherwise enabled * -* Set the broadcast timer notification for the current CPU. This function -* is executed per CPU by an SMP cross call. It not supposed to be called -* directly. +* This function is executed per CPU by an SMP cross call. It's not +* supposed to be called directly. */ static void cpuidle_setup_broadcast_timer (void *arg) { -int cpu =smp_processor_id (); -clockevents_notify ((long )(arg), &cpu); +if (arg) +tick_broadcast_enable (); +else +tick_broadcast_disable (); }/**
@@ -239,7 +238,7 @@ static int __cpuidle_register_driver(struct cpuidle_driver *drv)if (drv->bctimer)on_each_cpu_mask (drv->cpumask, cpuidle_setup_broadcast_timer, - (void *)CLOCK_EVT_NOTIFY_BROADCAST_ON ,1 ); + (void *)1 ,1 );poll_idle_init (drv);
@@ -263,7 +262,7 @@ static void __cpuidle_unregister_driver(struct cpuidle_driver *drv)if (drv->bctimer) { drv->bctimer =0 ;on_each_cpu_mask (drv->cpumask, cpuidle_setup_broadcast_timer, - (void *)CLOCK_EVT_NOTIFY_BROADCAST_OFF ,1 ); +NULL ,1 ); }__cpuidle_unset_driver (drv);
drivers/idle/intel_idle.c +8 -9
@@ -55,7 +55,7 @@#include <linux/kernel.h> #include <linux/cpuidle.h> -#include <linux/clockchips.h> +#include <linux/tick.h> #include <trace/events/power.h> #include <linux/sched.h> #include <linux/notifier.h>
@@ -638,12 +638,12 @@ static int intel_idle(struct cpuidle_device *dev,leave_mm (cpu);if (!(lapic_timer_reliable_states & (1 << (cstate)))) -clockevents_notify (CLOCK_EVT_NOTIFY_BROADCAST_ENTER , &cpu); +tick_broadcast_enter ();mwait_idle_with_hints (eax, ecx);if (!(lapic_timer_reliable_states & (1 << (cstate)))) -clockevents_notify (CLOCK_EVT_NOTIFY_BROADCAST_EXIT , &cpu); +tick_broadcast_exit ();return index; }
@@ -665,13 +665,12 @@ static void intel_idle_freeze(struct cpuidle_device *dev,static void __setup_broadcast_timer (void *arg) { -unsigned long reason = (unsigned long )arg; -int cpu =smp_processor_id (); - - reason = reason ? -CLOCK_EVT_NOTIFY_BROADCAST_ON :CLOCK_EVT_NOTIFY_BROADCAST_OFF ; +unsigned long on = (unsigned long )arg; -clockevents_notify (reason, &cpu); +if (on) +tick_broadcast_enable (); +else +tick_broadcast_disable (); } static int cpu_hotplug_notify(struct notifier_block *n,
drivers/rtc/class.c +2 -6
@@ -55,7 +55,7 @@ static int rtc_suspend(struct device *dev)struct timespec64 delta, delta_delta;int err; -if (has_persistent_clock ()) +if (timekeeping_rtc_skipsuspend ())return 0 ;if (strcmp (dev_name (&rtc->dev),CONFIG_RTC_HCTOSYS_DEVICE ) !=0 )
@@ -102,7 +102,7 @@ static int rtc_resume(struct device *dev)struct timespec64 sleep_time;int err; -if (has_persistent_clock ()) +if (timekeeping_rtc_skipresume ())return 0 ; rtc_hctosys_ret = -ENODEV ;
@@ -117,10 +117,6 @@ static int rtc_resume(struct device *dev)return 0 ; } -if (rtc_valid_tm (&tm) !=0 ) { -pr_debug ("%s: bogus resume time\n" ,dev_name (&rtc->dev)); -return 0 ; - } new_rtc.tv_sec =rtc_tm_to_time64 (&tm); new_rtc.tv_nsec =0 ;
drivers/rtc/interface.c +7 -1
@@ -72,7 +72,11 @@ int rtc_set_time(struct rtc_device *rtc, struct rtc_time *tm) err = -ENODEV ; else if (rtc->ops->set_time) err = rtc->ops->set_time (rtc->dev.parent, tm); - else if (rtc->ops->set_mmss) { + else if (rtc->ops->set_mmss64) { +time64_t secs64 =rtc_tm_to_time64 (tm); + + err = rtc->ops->set_mmss64 (rtc->dev.parent, secs64); + } else if (rtc->ops->set_mmss) {time64_t secs64 =rtc_tm_to_time64 (tm); err = rtc->ops->set_mmss (rtc->dev.parent, secs64); } else
@@ -96,6 +100,8 @@ int rtc_set_mmss(struct rtc_device *rtc, unsigned long secs)if (!rtc->ops) err = -ENODEV ; +else if (rtc->ops->set_mmss64) + err = rtc->ops->set_mmss64 (rtc->dev.parent, secs);else if (rtc->ops->set_mmss) err = rtc->ops->set_mmss (rtc->dev.parent, secs);else if (rtc->ops->read_time && rtc->ops->set_time) {
drivers/rtc/rtc-ab3100.c +27 -28
119 lines not on this page · raw message
drivers/rtc/rtc-mc13xxx.c +14 -18
@@ -83,20 +83,19 @@ static int mc13xxx_rtc_read_time(struct device *dev, struct rtc_time *tm)return ret; }while (days1 != days2); -rtc_time_to_tm (days1 *SEC_PER_DAY + seconds, tm); +rtc_time64_to_tm ((time64_t )days1 *SEC_PER_DAY + seconds, tm);return rtc_valid_tm (tm); } -static int mc13xxx_rtc_set_mmss (struct device *dev,unsigned long secs) +static int mc13xxx_rtc_set_mmss (struct device *dev,time64_t secs) {struct mc13xxx_rtc *priv =dev_get_drvdata (dev);unsigned int seconds, days;unsigned int alarmseconds;int ret; - seconds = secs %SEC_PER_DAY ; - days = secs /SEC_PER_DAY ; + days =div_s64_rem (secs,SEC_PER_DAY , &seconds);mc13xxx_lock (priv->mc13xxx);
@@ -159,7 +158,7 @@ static int mc13xxx_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alarm) {struct mc13xxx_rtc *priv =dev_get_drvdata (dev);unsigned seconds, days; -unsigned long s1970; +time64_t s1970;int enabled, pending;int ret;
@@ -189,10 +188,10 @@ static int mc13xxx_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alarm) alarm->enabled = enabled; alarm->pending = pending; - s1970 = days *SEC_PER_DAY + seconds; + s1970 = (time64_t )days *SEC_PER_DAY + seconds; -rtc_time_to_tm (s1970, &alarm->time); -dev_dbg (dev,"%s: %lu\n" , __func__, s1970); +rtc_time64_to_tm (s1970, &alarm->time); +dev_dbg (dev,"%s: %lld\n" , __func__, (long long )s1970);return 0 ; }
@@ -200,8 +199,8 @@ static int mc13xxx_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alarm)static int mc13xxx_rtc_set_alarm (struct device *dev,struct rtc_wkalrm *alarm) {struct mc13xxx_rtc *priv =dev_get_drvdata (dev); -unsigned long s1970; -unsigned seconds, days; +time64_t s1970; +u32 seconds, days;int ret;mc13xxx_lock (priv->mc13xxx);
@@ -215,20 +214,17 @@ static int mc13xxx_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alarm)if (unlikely (ret)) goto out; - ret =rtc_tm_to_time (&alarm->time, &s1970); -if (unlikely (ret)) - goto out; + s1970 =rtc_tm_to_time64 (&alarm->time); -dev_dbg (dev,"%s: o%2.s %lu\n" , __func__, alarm->enabled ?"n" :"ff" , - s1970); +dev_dbg (dev,"%s: o%2.s %lld\n" , __func__, alarm->enabled ?"n" :"ff" , + (long long )s1970); ret =mc13xxx_rtc_irq_enable_unlocked (dev, alarm->enabled,MC13XXX_IRQ_TODA );if (unlikely (ret)) goto out; - seconds = s1970 %SEC_PER_DAY ; - days = s1970 /SEC_PER_DAY ; + days =div_s64_rem (s1970,SEC_PER_DAY , &seconds); ret =mc13xxx_reg_write (priv->mc13xxx,MC13XXX_RTCDAYA , days);if (unlikely (ret))
@@ -268,7 +264,7 @@ static irqreturn_t mc13xxx_rtc_update_handler(int irq, void *dev)static const struct rtc_class_ops mc13xxx_rtc_ops = { .read_time = mc13xxx_rtc_read_time, - .set_mmss = mc13xxx_rtc_set_mmss, + .set_mmss64 = mc13xxx_rtc_set_mmss, .read_alarm = mc13xxx_rtc_read_alarm, .set_alarm = mc13xxx_rtc_set_alarm, .alarm_irq_enable = mc13xxx_rtc_alarm_irq_enable,
drivers/rtc/rtc-mxc.c +20 -35
140 lines not on this page · raw message
drivers/rtc/rtc-test.c +17 -2
@@ -13,6 +13,10 @@#include <linux/rtc.h> #include <linux/platform_device.h> +static int test_mmss64; +module_param (test_mmss64, int,0644 ); +MODULE_PARM_DESC (test_mmss64,"Test struct rtc_class_ops.set_mmss64()." ); +static struct platform_device *test0 =NULL , *test1 =NULL ; static int test_rtc_read_alarm(struct device *dev,
@@ -30,7 +34,13 @@ static int test_rtc_set_alarm(struct device *dev,static int test_rtc_read_time (struct device *dev,struct rtc_time *tm) { -rtc_time_to_tm (get_seconds (), tm); +rtc_time64_to_tm (ktime_get_real_seconds (), tm); +return 0 ; +} + +static int test_rtc_set_mmss64 (struct device *dev,time64_t secs) +{ +dev_info (dev,"%s, secs = %lld\n" , __func__, (long long )secs);return 0 ; }
@@ -55,7 +65,7 @@ static int test_rtc_alarm_irq_enable(struct device *dev, unsigned int enable)return 0 ; } -static const struct rtc_class_ops test_rtc_ops = { +static struct rtc_class_ops test_rtc_ops = { .proc = test_rtc_proc, .read_time = test_rtc_read_time, .read_alarm = test_rtc_read_alarm,
@@ -101,6 +111,11 @@ static int test_probe(struct platform_device *plat_dev)int err;struct rtc_device *rtc; +if (test_mmss64) { + test_rtc_ops.set_mmss64 = test_rtc_set_mmss64; + test_rtc_ops.set_mmss =NULL ; + } + rtc =devm_rtc_device_register (&plat_dev->dev,"test" , &test_rtc_ops,THIS_MODULE );if (IS_ERR (rtc)) {
drivers/rtc/systohc.c +5 -2
@@ -11,7 +11,7 @@* rtc_set_ntp_time - Save NTP synchronized time to the RTC * @now: Current time of day * -* Replacement for the NTP platform function update_persistent_clock +* Replacement for the NTP platform function update_persistent_clock64 * that stores time for later retrieval by rtc_hctosys. * * Returns 0 on successful RTC update, -ENODEV if a RTC update is not
@@ -35,7 +35,10 @@ int rtc_set_ntp_time(struct timespec64 now)if (rtc) {/* rtc_hctosys exclusively uses UTC, so we call set_time here, * not set_mmss. */ -if (rtc->ops && (rtc->ops->set_time || rtc->ops->set_mmss)) +if (rtc->ops && + (rtc->ops->set_time || + rtc->ops->set_mmss64 || + rtc->ops->set_mmss)) err =rtc_set_time (rtc, &tm);rtc_class_close (rtc); }
include/linux/clockchips.h +79 -75
249 lines not on this page · raw message
include/linux/clocksource.h +17 -8
@@ -56,6 +56,7 @@ struct module;* @shift: cycle to nanosecond divisor (power of two) * @max_idle_ns: max idle time permitted by the clocksource (nsecs) * @maxadj: maximum adjustment value to mult (~11%) +* @max_cycles: maximum safe cycle value which won't overflow on multiplication * @flags: flags describing special properties * @archdata: arch-specific data * @suspend: suspend function for the clocksource, if necessary
@@ -76,7 +77,7 @@ struct clocksource {#ifdef CONFIG_ARCH_CLOCKSOURCE_DATA struct arch_clocksource_data archdata;#endif - +u64 max_cycles;const char *name;struct list_head list;int rating;
@@ -178,7 +179,6 @@ static inline s64 clocksource_cyc2ns(cycle_t cycles, u32 mult, u32 shift) } -extern int clocksource_register (struct clocksource *);extern int clocksource_unregister (struct clocksource *);extern void clocksource_touch_watchdog (void );extern struct clocksource *clocksource_get_next (void );
@@ -189,7 +189,7 @@ extern struct clocksource * __init clocksource_default_clock(void);extern void clocksource_mark_unstable (struct clocksource *cs);extern u64 -clocks_calc_max_nsecs (u32 mult,u32 shift,u32 maxadj,u64 mask); +clocks_calc_max_nsecs (u32 mult,u32 shift,u32 maxadj,u64 mask,u64 *max_cycles);extern void clocks_calc_mult_shift (u32 *mult,u32 *shift,u32 from,u32 to,u32 minsec);
@@ -200,7 +200,16 @@ clocks_calc_mult_shift(u32 *mult, u32 *shift, u32 from, u32 to, u32 minsec);extern int __clocksource_register_scale (struct clocksource *cs,u32 scale,u32 freq);extern void -__clocksource_updatefreq_scale (struct clocksource *cs,u32 scale,u32 freq); +__clocksource_update_freq_scale (struct clocksource *cs,u32 scale,u32 freq); + +/* +* Don't call this unless you are a default clocksource +* (AKA: jiffies) and absolutely have to. +*/ +static inline int __clocksource_register (struct clocksource *cs) +{ +return __clocksource_register_scale (cs,1 ,0 ); +}static inline int clocksource_register_hz (struct clocksource *cs,u32 hz) {
@@ -212,14 +221,14 @@ static inline int clocksource_register_khz(struct clocksource *cs, u32 khz)return __clocksource_register_scale (cs,1000 , khz); } -static inline void __clocksource_updatefreq_hz (struct clocksource *cs,u32 hz) +static inline void __clocksource_update_freq_hz (struct clocksource *cs,u32 hz) { -__clocksource_updatefreq_scale (cs,1 , hz); +__clocksource_update_freq_scale (cs,1 , hz); } -static inline void __clocksource_updatefreq_khz (struct clocksource *cs,u32 khz) +static inline void __clocksource_update_freq_khz (struct clocksource *cs,u32 khz) { -__clocksource_updatefreq_scale (cs,1000 , khz); +__clocksource_update_freq_scale (cs,1000 , khz); }
include/linux/rtc.h +1 -0
@@ -77,6 +77,7 @@ struct rtc_class_ops {int (*read_alarm)(struct device *,struct rtc_wkalrm *);int (*set_alarm)(struct device *,struct rtc_wkalrm *);int (*proc)(struct device *,struct seq_file *); +int (*set_mmss64)(struct device *,time64_t secs);int (*set_mmss)(struct device *,unsigned long secs);int (*read_callback)(struct device *,int data);int (*alarm_irq_enable)(struct device *,unsigned int enabled);
include/linux/tick.h +69 -121
232 lines not on this page · raw message
include/linux/timekeeper_internal.h +8 -8
@@ -16,16 +16,16 @@* @read: Read function of @clock * @mask: Bitmask for two's complement subtraction of non 64bit clocks * @cycle_last: @clock cycle value at last update -* @mult: NTP adjusted multiplier for scaled math conversion +* @mult: (NTP adjusted) multiplier for scaled math conversion * @shift: Shift value for scaled math conversion * @xtime_nsec: Shifted (fractional) nano seconds offset for readout -* @base_mono: ktime_t (nanoseconds) base time for readout +* @base: ktime_t (nanoseconds) base time for readout * * This struct has size 56 byte on 64 bit. Together with a seqcount it * occupies a single 64byte cache line. * * The struct is separate from struct timekeeper as it is also used -* for a fast NMI safe accessor to clock monotonic. +* for a fast NMI safe accessors. */ struct tk_read_base {struct clocksource *clock;
@@ -35,12 +35,13 @@ struct tk_read_base {u32 mult;u32 shift;u64 xtime_nsec; -ktime_t base_mono; +ktime_t base; };/** * struct timekeeper - Structure holding internal timekeeping values. -* @tkr: The readout base structure +* @tkr_mono: The readout base structure for CLOCK_MONOTONIC +* @tkr_raw: The readout base structure for CLOCK_MONOTONIC_RAW * @xtime_sec: Current CLOCK_REALTIME time in seconds * @ktime_sec: Current CLOCK_MONOTONIC time in seconds * @wall_to_monotonic: CLOCK_REALTIME to CLOCK_MONOTONIC offset
@@ -48,7 +49,6 @@ struct tk_read_base {* @offs_boot: Offset clock monotonic -> clock boottime * @offs_tai: Offset clock monotonic -> clock tai * @tai_offset: The current UTC to TAI offset in seconds -* @base_raw: Monotonic raw base time in ktime_t format * @raw_time: Monotonic raw base time in timespec64 format * @cycle_interval: Number of clock cycles in one NTP interval * @xtime_interval: Number of clock shifted nano seconds in one NTP
@@ -76,7 +76,8 @@ struct tk_read_base {* used instead. */ struct timekeeper { -struct tk_read_base tkr; +struct tk_read_base tkr_mono; +struct tk_read_base tkr_raw;u64 xtime_sec;unsigned long ktime_sec;struct timespec64 wall_to_monotonic;
@@ -84,7 +85,6 @@ struct timekeeper {ktime_t offs_boot;ktime_t offs_tai;s32 tai_offset; -ktime_t base_raw;struct timespec64 raw_time;/* The following members are for timekeeping internal use */
include/linux/timekeeping.h +12 -6
@@ -214,12 +214,18 @@ static inline u64 ktime_get_boot_ns(void)return ktime_to_ns (ktime_get_boottime ()); } +static inline u64 ktime_get_tai_ns (void ) +{ +return ktime_to_ns (ktime_get_clocktai ()); +} +static inline u64 ktime_get_raw_ns (void ) {return ktime_to_ns (ktime_get_raw ()); }extern u64 ktime_get_mono_fast_ns (void ); +extern u64 ktime_get_raw_fast_ns (void );/* * Timespec interfaces utilizing the ktime based ones
@@ -242,6 +248,9 @@ static inline void timekeeping_clocktai(struct timespec *ts)/* * RTC specific */ +extern bool timekeeping_rtc_skipsuspend (void ); +extern bool timekeeping_rtc_skipresume (void ); +extern void timekeeping_inject_sleeptime64 (struct timespec64 *delta);/*
@@ -253,17 +262,14 @@ extern void getnstime_raw_and_real(struct timespec *ts_raw,/* * Persistent clock related interfaces */ -extern bool persistent_clock_exist;extern int persistent_clock_is_local; -static inline bool has_persistent_clock (void ) -{ -return persistent_clock_exist; -} -extern void read_persistent_clock (struct timespec *ts); +extern void read_persistent_clock64 (struct timespec64 *ts);extern void read_boot_clock (struct timespec *ts); +extern void read_boot_clock64 (struct timespec64 *ts);extern int update_persistent_clock (struct timespec now); +extern int update_persistent_clock64 (struct timespec64 now);#endif
kernel/cpu.c +5 -0
@@ -20,6 +20,7 @@#include <linux/gfp.h> #include <linux/suspend.h> #include <linux/lockdep.h> +#include <linux/tick.h> #include <trace/events/power.h> #include "smpboot.h"
@@ -338,6 +339,8 @@ static int __ref take_cpu_down(void *_param)return err;cpu_notify (CPU_DYING | param->mod, param->hcpu); +/* Give up timekeeping duties */ +tick_handover_do_timer ();/* Park the stopper thread */ kthread_park (current);return 0 ;
@@ -411,10 +414,12 @@ static int __ref _cpu_down(unsigned int cpu, int tasks_frozen)while (!idle_cpu (cpu))cpu_relax (); +hotplug_cpu__broadcast_tick_pull (cpu);/* This actually kills the CPU. */ __cpu_die (cpu);/* CPU is completely dead: tell everyone. Too late to complain. */ +tick_cleanup_dead_cpu (cpu);cpu_notify_nofail (CPU_DEAD | mod, hcpu);check_for_tasks (cpu);
kernel/sched/idle.c +2 -3
@@ -158,8 +158,7 @@ static void cpuidle_idle_call(void)* is used from another cpu as a broadcast timer, this call may * fail if it is not available */ -if (broadcast && -clockevents_notify (CLOCK_EVT_NOTIFY_BROADCAST_ENTER , &dev->cpu)) +if (broadcast &&tick_broadcast_enter ()) goto use_default;/* Take note of the planned idle state. */
@@ -176,7 +175,7 @@ static void cpuidle_idle_call(void)idle_set_state (this_rq (),NULL );if (broadcast) -clockevents_notify (CLOCK_EVT_NOTIFY_BROADCAST_EXIT , &dev->cpu); +tick_broadcast_exit ();/* * Give the governor an opportunity to reflect on the outcome
kernel/time/Kconfig +0 -6
@@ -33,12 +33,6 @@ config ARCH_USES_GETTIMEOFFSET config GENERIC_CLOCKEVENTS bool -# Migration helper. Builds, but does not invoke -config GENERIC_CLOCKEVENTS_BUILD - bool - default y - depends on GENERIC_CLOCKEVENTS - # Architecture can handle broadcast in a driver-agnostic way config ARCH_HAS_TICK_BROADCAST bool
kernel/time/Makefile +2 -4
@@ -2,15 +2,13 @@ obj-y += time.o timer.o hrtimer.o itimer.o posix-timers.o posix-cpu-timers.o obj-y += timekeeping.o ntp.o clocksource.o jiffies.o timer_list.o obj-y += timeconv.o timecounter.o posix-clock.o alarmtimer.o -obj-$(CONFIG_GENERIC_CLOCKEVENTS_BUILD) += clockevents.o -obj-$(CONFIG_GENERIC_CLOCKEVENTS) += tick-common.o +obj-$(CONFIG_GENERIC_CLOCKEVENTS) += clockevents.o tick-common.o ifeq ($(CONFIG_GENERIC_CLOCKEVENTS_BROADCAST),y) obj-y += tick-broadcast.o obj-$(CONFIG_TICK_ONESHOT) += tick-broadcast-hrtimer.o endif obj-$(CONFIG_GENERIC_SCHED_CLOCK) += sched_clock.o -obj-$(CONFIG_TICK_ONESHOT) += tick-oneshot.o -obj-$(CONFIG_TICK_ONESHOT) += tick-sched.o +obj-$(CONFIG_TICK_ONESHOT) += tick-oneshot.o tick-sched.o obj-$(CONFIG_TIMER_STATS) += timer_stats.o obj-$(CONFIG_DEBUG_FS) += timekeeping_debug.o obj-$(CONFIG_TEST_UDELAY) += test_udelay.o
kernel/time/clockevents.c +147 -82
350 lines not on this page · raw message
kernel/time/clocksource.c +80 -93
158 lines not on this page · raw message
kernel/time/sched_clock.c +161 -75
236 lines not on this page · raw message
kernel/time/tick-broadcast.c +96 -83
179 lines not on this page · raw message
kernel/time/tick-common.c +63 -19
82 lines not on this page · raw message
kernel/time/tick-internal.h +89 -122
211 lines not on this page · raw message
kernel/time/tick-sched.h new file +74 -0
74 lines not on this page · raw message
kernel/time/timekeeping.c +325 -165
490 lines not on this page · raw message
kernel/time/timer.c +67 -82
149 lines not on this page · raw message
The rest of this diff is not shown. View the raw message.
Part of the diff is not shown here. View the raw message.