Commit 174ddfd5 authored by Linus Torvalds's avatar Linus Torvalds

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

Pull timer updates from Thomas Gleixner:
 "The timer departement delivers:

   - more year 2038 rework

   - a massive rework of the arm achitected timer

   - preparatory patches to allow NTP correction of clock event devices
     to avoid early expiry

   - the usual pile of fixes and enhancements all over the place"

* 'timers-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: (91 commits)
  timer/sysclt: Restrict timer migration sysctl values to 0 and 1
  arm64/arch_timer: Mark errata handlers as __maybe_unused
  Clocksource/mips-gic: Remove redundant non devicetree init
  MIPS/Malta: Probe gic-timer via devicetree
  clocksource: Use GENMASK_ULL in definition of CLOCKSOURCE_MASK
  acpi/arm64: Add SBSA Generic Watchdog support in GTDT driver
  clocksource: arm_arch_timer: add GTDT support for memory-mapped timer
  acpi/arm64: Add memory-mapped timer support in GTDT driver
  clocksource: arm_arch_timer: simplify ACPI support code.
  acpi/arm64: Add GTDT table parse driver
  clocksource: arm_arch_timer: split MMIO timer probing.
  clocksource: arm_arch_timer: add structs to describe MMIO timer
  clocksource: arm_arch_timer: move arch_timer_needs_of_probing into DT init call
  clocksource: arm_arch_timer: refactor arch_timer_needs_probing
  clocksource: arm_arch_timer: split dt-only rate handling
  x86/uv/time: Set ->min_delta_ticks and ->max_delta_ticks
  unicore32/time: Set ->min_delta_ticks and ->max_delta_ticks
  um/time: Set ->min_delta_ticks and ->max_delta_ticks
  tile/time: Set ->min_delta_ticks and ->max_delta_ticks
  score/time: Set ->min_delta_ticks and ->max_delta_ticks
  ...
parents 3cb66535 b94bf594
...@@ -54,6 +54,7 @@ stable kernels. ...@@ -54,6 +54,7 @@ stable kernels.
| ARM | Cortex-A57 | #852523 | N/A | | ARM | Cortex-A57 | #852523 | N/A |
| ARM | Cortex-A57 | #834220 | ARM64_ERRATUM_834220 | | ARM | Cortex-A57 | #834220 | ARM64_ERRATUM_834220 |
| ARM | Cortex-A72 | #853709 | N/A | | ARM | Cortex-A72 | #853709 | N/A |
| ARM | Cortex-A73 | #858921 | ARM64_ERRATUM_858921 |
| ARM | MMU-500 | #841119,#826419 | N/A | | ARM | MMU-500 | #841119,#826419 | N/A |
| | | | | | | | | |
| Cavium | ThunderX ITS | #22375, #24313 | CAVIUM_ERRATUM_22375 | | Cavium | ThunderX ITS | #22375, #24313 | CAVIUM_ERRATUM_22375 |
......
Cortina Systems Gemini timer
This timer is embedded in the Cortina Systems Gemini SoCs.
Required properties:
- compatible : Must be "cortina,gemini-timer"
- reg : Should contain registers location and length
- interrupts : Should contain the three timer interrupts with
flags for rising edge
- syscon : a phandle to the global Gemini system controller
Example:
timer@43000000 {
compatible = "cortina,gemini-timer";
reg = <0x43000000 0x1000>;
interrupts = <14 IRQ_TYPE_EDGE_RISING>, /* Timer 1 */
<15 IRQ_TYPE_EDGE_RISING>, /* Timer 2 */
<16 IRQ_TYPE_EDGE_RISING>; /* Timer 3 */
syscon = <&syscon>;
};
Faraday Technology timer
This timer is a generic IP block from Faraday Technology, embedded in the
Cortina Systems Gemini SoCs and other designs.
Required properties:
- compatible : Must be one of
"faraday,fttmr010"
"cortina,gemini-timer"
- reg : Should contain registers location and length
- interrupts : Should contain the three timer interrupts usually with
flags for falling edge
Optionally required properties:
- clocks : a clock to provide the tick rate for "faraday,fttmr010"
- clock-names : should be "EXTCLK" and "PCLK" for the external tick timer
and peripheral clock respectively, for "faraday,fttmr010"
- syscon : a phandle to the global Gemini system controller if the compatible
type is "cortina,gemini-timer"
Example:
timer@43000000 {
compatible = "faraday,fttmr010";
reg = <0x43000000 0x1000>;
interrupts = <14 IRQ_TYPE_EDGE_FALLING>, /* Timer 1 */
<15 IRQ_TYPE_EDGE_FALLING>, /* Timer 2 */
<16 IRQ_TYPE_EDGE_FALLING>; /* Timer 3 */
clocks = <&extclk>, <&pclk>;
clock-names = "EXTCLK", "PCLK";
};
Rockchip rk timer Rockchip rk timer
Required properties: Required properties:
- compatible: shall be one of: - compatible: should be:
"rockchip,rk3288-timer" - for rk3066, rk3036, rk3188, rk322x, rk3288, rk3368 "rockchip,rk3036-timer", "rockchip,rk3288-timer": for Rockchip RK3036
"rockchip,rk3399-timer" - for rk3399 "rockchip,rk3066-timer", "rockchip,rk3288-timer": for Rockchip RK3066
"rockchip,rk3188-timer", "rockchip,rk3288-timer": for Rockchip RK3188
"rockchip,rk3228-timer", "rockchip,rk3288-timer": for Rockchip RK3228
"rockchip,rk3229-timer", "rockchip,rk3288-timer": for Rockchip RK3229
"rockchip,rk3288-timer": for Rockchip RK3288
"rockchip,rk3368-timer", "rockchip,rk3288-timer": for Rockchip RK3368
"rockchip,rk3399-timer": for Rockchip RK3399
- reg: base address of the timer register starting with TIMERS CONTROL register - reg: base address of the timer register starting with TIMERS CONTROL register
- interrupts: should contain the interrupts for Timer0 - interrupts: should contain the interrupts for Timer0
- clocks : must contain an entry for each entry in clock-names - clocks : must contain an entry for each entry in clock-names
......
...@@ -11119,6 +11119,7 @@ F: drivers/power/supply/bq27xxx_battery_i2c.c ...@@ -11119,6 +11119,7 @@ F: drivers/power/supply/bq27xxx_battery_i2c.c
TIMEKEEPING, CLOCKSOURCE CORE, NTP, ALARMTIMER TIMEKEEPING, CLOCKSOURCE CORE, NTP, ALARMTIMER
M: John Stultz <john.stultz@linaro.org> M: John Stultz <john.stultz@linaro.org>
M: Thomas Gleixner <tglx@linutronix.de> M: Thomas Gleixner <tglx@linutronix.de>
R: Stephen Boyd <sboyd@codeaurora.org>
L: linux-kernel@vger.kernel.org L: linux-kernel@vger.kernel.org
T: git git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git timers/core T: git git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git timers/core
S: Supported S: Supported
......
...@@ -1016,6 +1016,7 @@ SYSCALL_DEFINE2(osf_gettimeofday, struct timeval32 __user *, tv, ...@@ -1016,6 +1016,7 @@ SYSCALL_DEFINE2(osf_gettimeofday, struct timeval32 __user *, tv,
SYSCALL_DEFINE2(osf_settimeofday, struct timeval32 __user *, tv, SYSCALL_DEFINE2(osf_settimeofday, struct timeval32 __user *, tv,
struct timezone __user *, tz) struct timezone __user *, tz)
{ {
struct timespec64 kts64;
struct timespec kts; struct timespec kts;
struct timezone ktz; struct timezone ktz;
...@@ -1023,13 +1024,14 @@ SYSCALL_DEFINE2(osf_settimeofday, struct timeval32 __user *, tv, ...@@ -1023,13 +1024,14 @@ SYSCALL_DEFINE2(osf_settimeofday, struct timeval32 __user *, tv,
if (get_tv32((struct timeval *)&kts, tv)) if (get_tv32((struct timeval *)&kts, tv))
return -EFAULT; return -EFAULT;
kts.tv_nsec *= 1000; kts.tv_nsec *= 1000;
kts64 = timespec_to_timespec64(kts);
} }
if (tz) { if (tz) {
if (copy_from_user(&ktz, tz, sizeof(*tz))) if (copy_from_user(&ktz, tz, sizeof(*tz)))
return -EFAULT; return -EFAULT;
} }
return do_sys_settimeofday(tv ? &kts : NULL, tz ? &ktz : NULL); return do_sys_settimeofday64(tv ? &kts64 : NULL, tz ? &ktz : NULL);
} }
asmlinkage long sys_ni_posix_timers(void); asmlinkage long sys_ni_posix_timers(void);
......
...@@ -106,6 +106,22 @@ smp-sram@0 { ...@@ -106,6 +106,22 @@ smp-sram@0 {
}; };
}; };
timer3: timer@2000e000 {
compatible = "rockchip,rk3188-timer", "rockchip,rk3288-timer";
reg = <0x2000e000 0x20>;
interrupts = <GIC_SPI 46 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&cru SCLK_TIMER3>, <&cru PCLK_TIMER3>;
clock-names = "timer", "pclk";
};
timer6: timer@200380a0 {
compatible = "rockchip,rk3188-timer", "rockchip,rk3288-timer";
reg = <0x200380a0 0x20>;
interrupts = <GIC_SPI 64 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&cru SCLK_TIMER6>, <&cru PCLK_TIMER0>;
clock-names = "timer", "pclk";
};
i2s0: i2s@1011a000 { i2s0: i2s@1011a000 {
compatible = "rockchip,rk3188-i2s", "rockchip,rk3066-i2s"; compatible = "rockchip,rk3188-i2s", "rockchip,rk3066-i2s";
reg = <0x1011a000 0x2000>; reg = <0x1011a000 0x2000>;
...@@ -530,6 +546,7 @@ &emac { ...@@ -530,6 +546,7 @@ &emac {
&global_timer { &global_timer {
interrupts = <GIC_PPI 11 0xf04>; interrupts = <GIC_PPI 11 0xf04>;
status = "disabled";
}; };
&local_timer { &local_timer {
......
...@@ -325,7 +325,7 @@ pwm3: pwm@110b0030 { ...@@ -325,7 +325,7 @@ pwm3: pwm@110b0030 {
}; };
timer: timer@110c0000 { timer: timer@110c0000 {
compatible = "rockchip,rk3288-timer"; compatible = "rockchip,rk3228-timer", "rockchip,rk3288-timer";
reg = <0x110c0000 0x20>; reg = <0x110c0000 0x20>;
interrupts = <GIC_SPI 43 IRQ_TYPE_LEVEL_HIGH>; interrupts = <GIC_SPI 43 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&xin24m>, <&cru PCLK_TIMER>; clocks = <&xin24m>, <&cru PCLK_TIMER>;
......
...@@ -2,6 +2,7 @@ config ARM64 ...@@ -2,6 +2,7 @@ config ARM64
def_bool y def_bool y
select ACPI_CCA_REQUIRED if ACPI select ACPI_CCA_REQUIRED if ACPI
select ACPI_GENERIC_GSI if ACPI select ACPI_GENERIC_GSI if ACPI
select ACPI_GTDT if ACPI
select ACPI_REDUCED_HARDWARE_ONLY if ACPI select ACPI_REDUCED_HARDWARE_ONLY if ACPI
select ACPI_MCFG if ACPI select ACPI_MCFG if ACPI
select ACPI_SPCR_TABLE if ACPI select ACPI_SPCR_TABLE if ACPI
......
...@@ -25,6 +25,7 @@ ...@@ -25,6 +25,7 @@
#include <linux/bug.h> #include <linux/bug.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/jump_label.h> #include <linux/jump_label.h>
#include <linux/smp.h>
#include <linux/types.h> #include <linux/types.h>
#include <clocksource/arm_arch_timer.h> #include <clocksource/arm_arch_timer.h>
...@@ -37,23 +38,43 @@ extern struct static_key_false arch_timer_read_ool_enabled; ...@@ -37,23 +38,43 @@ extern struct static_key_false arch_timer_read_ool_enabled;
#define needs_unstable_timer_counter_workaround() false #define needs_unstable_timer_counter_workaround() false
#endif #endif
enum arch_timer_erratum_match_type {
ate_match_dt,
ate_match_local_cap_id,
ate_match_acpi_oem_info,
};
struct clock_event_device;
struct arch_timer_erratum_workaround { struct arch_timer_erratum_workaround {
const char *id; /* Indicate the Erratum ID */ enum arch_timer_erratum_match_type match_type;
const void *id;
const char *desc;
u32 (*read_cntp_tval_el0)(void); u32 (*read_cntp_tval_el0)(void);
u32 (*read_cntv_tval_el0)(void); u32 (*read_cntv_tval_el0)(void);
u64 (*read_cntvct_el0)(void); u64 (*read_cntvct_el0)(void);
int (*set_next_event_phys)(unsigned long, struct clock_event_device *);
int (*set_next_event_virt)(unsigned long, struct clock_event_device *);
}; };
extern const struct arch_timer_erratum_workaround *timer_unstable_counter_workaround; DECLARE_PER_CPU(const struct arch_timer_erratum_workaround *,
timer_unstable_counter_workaround);
#define arch_timer_reg_read_stable(reg) \ #define arch_timer_reg_read_stable(reg) \
({ \ ({ \
u64 _val; \ u64 _val; \
if (needs_unstable_timer_counter_workaround()) \ if (needs_unstable_timer_counter_workaround()) { \
_val = timer_unstable_counter_workaround->read_##reg();\ const struct arch_timer_erratum_workaround *wa; \
preempt_disable(); \
wa = __this_cpu_read(timer_unstable_counter_workaround); \
if (wa && wa->read_##reg) \
_val = wa->read_##reg(); \
else \ else \
_val = read_sysreg(reg); \ _val = read_sysreg(reg); \
preempt_enable(); \
} else { \
_val = read_sysreg(reg); \
} \
_val; \ _val; \
}) })
......
...@@ -37,7 +37,8 @@ ...@@ -37,7 +37,8 @@
#define ARM64_HAS_NO_FPSIMD 16 #define ARM64_HAS_NO_FPSIMD 16
#define ARM64_WORKAROUND_REPEAT_TLBI 17 #define ARM64_WORKAROUND_REPEAT_TLBI 17
#define ARM64_WORKAROUND_QCOM_FALKOR_E1003 18 #define ARM64_WORKAROUND_QCOM_FALKOR_E1003 18
#define ARM64_WORKAROUND_858921 19
#define ARM64_NCAPS 19 #define ARM64_NCAPS 20
#endif /* __ASM_CPUCAPS_H */ #endif /* __ASM_CPUCAPS_H */
...@@ -80,6 +80,7 @@ ...@@ -80,6 +80,7 @@
#define ARM_CPU_PART_FOUNDATION 0xD00 #define ARM_CPU_PART_FOUNDATION 0xD00
#define ARM_CPU_PART_CORTEX_A57 0xD07 #define ARM_CPU_PART_CORTEX_A57 0xD07
#define ARM_CPU_PART_CORTEX_A53 0xD03 #define ARM_CPU_PART_CORTEX_A53 0xD03
#define ARM_CPU_PART_CORTEX_A73 0xD09
#define APM_CPU_PART_POTENZA 0x000 #define APM_CPU_PART_POTENZA 0x000
...@@ -92,6 +93,7 @@ ...@@ -92,6 +93,7 @@
#define MIDR_CORTEX_A53 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A53) #define MIDR_CORTEX_A53 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A53)
#define MIDR_CORTEX_A57 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A57) #define MIDR_CORTEX_A57 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A57)
#define MIDR_CORTEX_A73 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A73)
#define MIDR_THUNDERX MIDR_CPU_MODEL(ARM_CPU_IMP_CAVIUM, CAVIUM_CPU_PART_THUNDERX) #define MIDR_THUNDERX MIDR_CPU_MODEL(ARM_CPU_IMP_CAVIUM, CAVIUM_CPU_PART_THUNDERX)
#define MIDR_THUNDERX_81XX MIDR_CPU_MODEL(ARM_CPU_IMP_CAVIUM, CAVIUM_CPU_PART_THUNDERX_81XX) #define MIDR_THUNDERX_81XX MIDR_CPU_MODEL(ARM_CPU_IMP_CAVIUM, CAVIUM_CPU_PART_THUNDERX_81XX)
#define MIDR_QCOM_FALKOR_V1 MIDR_CPU_MODEL(ARM_CPU_IMP_QCOM, QCOM_CPU_PART_FALKOR_V1) #define MIDR_QCOM_FALKOR_V1 MIDR_CPU_MODEL(ARM_CPU_IMP_QCOM, QCOM_CPU_PART_FALKOR_V1)
......
...@@ -175,6 +175,8 @@ ...@@ -175,6 +175,8 @@
#define ESR_ELx_SYS64_ISS_SYS_CTR_READ (ESR_ELx_SYS64_ISS_SYS_CTR | \ #define ESR_ELx_SYS64_ISS_SYS_CTR_READ (ESR_ELx_SYS64_ISS_SYS_CTR | \
ESR_ELx_SYS64_ISS_DIR_READ) ESR_ELx_SYS64_ISS_DIR_READ)
#define ESR_ELx_SYS64_ISS_SYS_CNTVCT (ESR_ELx_SYS64_ISS_SYS_VAL(3, 3, 2, 14, 0) | \
ESR_ELx_SYS64_ISS_DIR_READ)
#ifndef __ASSEMBLY__ #ifndef __ASSEMBLY__
#include <asm/types.h> #include <asm/types.h>
......
...@@ -53,6 +53,13 @@ static int cpu_enable_trap_ctr_access(void *__unused) ...@@ -53,6 +53,13 @@ static int cpu_enable_trap_ctr_access(void *__unused)
.midr_range_min = min, \ .midr_range_min = min, \
.midr_range_max = max .midr_range_max = max
#define MIDR_ALL_VERSIONS(model) \
.def_scope = SCOPE_LOCAL_CPU, \
.matches = is_affected_midr_range, \
.midr_model = model, \
.midr_range_min = 0, \
.midr_range_max = (MIDR_VARIANT_MASK | MIDR_REVISION_MASK)
const struct arm64_cpu_capabilities arm64_errata[] = { const struct arm64_cpu_capabilities arm64_errata[] = {
#if defined(CONFIG_ARM64_ERRATUM_826319) || \ #if defined(CONFIG_ARM64_ERRATUM_826319) || \
defined(CONFIG_ARM64_ERRATUM_827319) || \ defined(CONFIG_ARM64_ERRATUM_827319) || \
...@@ -150,6 +157,14 @@ const struct arm64_cpu_capabilities arm64_errata[] = { ...@@ -150,6 +157,14 @@ const struct arm64_cpu_capabilities arm64_errata[] = {
MIDR_CPU_VAR_REV(0, 0), MIDR_CPU_VAR_REV(0, 0),
MIDR_CPU_VAR_REV(0, 0)), MIDR_CPU_VAR_REV(0, 0)),
}, },
#endif
#ifdef CONFIG_ARM64_ERRATUM_858921
{
/* Cortex-A73 all versions */
.desc = "ARM erratum 858921",
.capability = ARM64_WORKAROUND_858921,
MIDR_ALL_VERSIONS(MIDR_CORTEX_A73),
},
#endif #endif
{ {
} }
......
...@@ -1090,20 +1090,29 @@ static void __init setup_feature_capabilities(void) ...@@ -1090,20 +1090,29 @@ static void __init setup_feature_capabilities(void)
* Check if the current CPU has a given feature capability. * Check if the current CPU has a given feature capability.
* Should be called from non-preemptible context. * Should be called from non-preemptible context.
*/ */
bool this_cpu_has_cap(unsigned int cap) static bool __this_cpu_has_cap(const struct arm64_cpu_capabilities *cap_array,
unsigned int cap)
{ {
const struct arm64_cpu_capabilities *caps; const struct arm64_cpu_capabilities *caps;
if (WARN_ON(preemptible())) if (WARN_ON(preemptible()))
return false; return false;
for (caps = arm64_features; caps->desc; caps++) for (caps = cap_array; caps->desc; caps++)
if (caps->capability == cap && caps->matches) if (caps->capability == cap && caps->matches)
return caps->matches(caps, SCOPE_LOCAL_CPU); return caps->matches(caps, SCOPE_LOCAL_CPU);
return false; return false;
} }
extern const struct arm64_cpu_capabilities arm64_errata[];
bool this_cpu_has_cap(unsigned int cap)
{
return (__this_cpu_has_cap(arm64_features, cap) ||
__this_cpu_has_cap(arm64_errata, cap));
}
void __init setup_cpu_features(void) void __init setup_cpu_features(void)
{ {
u32 cwg; u32 cwg;
......
...@@ -505,6 +505,14 @@ static void ctr_read_handler(unsigned int esr, struct pt_regs *regs) ...@@ -505,6 +505,14 @@ static void ctr_read_handler(unsigned int esr, struct pt_regs *regs)
regs->pc += 4; regs->pc += 4;
} }
static void cntvct_read_handler(unsigned int esr, struct pt_regs *regs)
{
int rt = (esr & ESR_ELx_SYS64_ISS_RT_MASK) >> ESR_ELx_SYS64_ISS_RT_SHIFT;
pt_regs_write_reg(regs, rt, arch_counter_get_cntvct());
regs->pc += 4;
}
struct sys64_hook { struct sys64_hook {
unsigned int esr_mask; unsigned int esr_mask;
unsigned int esr_val; unsigned int esr_val;
...@@ -523,6 +531,12 @@ static struct sys64_hook sys64_hooks[] = { ...@@ -523,6 +531,12 @@ static struct sys64_hook sys64_hooks[] = {
.esr_val = ESR_ELx_SYS64_ISS_SYS_CTR_READ, .esr_val = ESR_ELx_SYS64_ISS_SYS_CTR_READ,
.handler = ctr_read_handler, .handler = ctr_read_handler,
}, },
{
/* Trap read access to CNTVCT_EL0 */
.esr_mask = ESR_ELx_SYS64_ISS_SYS_OP_MASK,
.esr_val = ESR_ELx_SYS64_ISS_SYS_CNTVCT,
.handler = cntvct_read_handler,
},
{}, {},
}; };
......
...@@ -230,7 +230,9 @@ static void __init bfin_gptmr0_clockevent_init(struct clock_event_device *evt) ...@@ -230,7 +230,9 @@ static void __init bfin_gptmr0_clockevent_init(struct clock_event_device *evt)
clock_tick = get_sclk(); clock_tick = get_sclk();
evt->mult = div_sc(clock_tick, NSEC_PER_SEC, evt->shift); evt->mult = div_sc(clock_tick, NSEC_PER_SEC, evt->shift);
evt->max_delta_ns = clockevent_delta2ns(-1, evt); evt->max_delta_ns = clockevent_delta2ns(-1, evt);
evt->max_delta_ticks = (unsigned long)-1;
evt->min_delta_ns = clockevent_delta2ns(100, evt); evt->min_delta_ns = clockevent_delta2ns(100, evt);
evt->min_delta_ticks = 100;
evt->cpumask = cpumask_of(0); evt->cpumask = cpumask_of(0);
...@@ -344,7 +346,9 @@ void bfin_coretmr_clockevent_init(void) ...@@ -344,7 +346,9 @@ void bfin_coretmr_clockevent_init(void)
clock_tick = get_cclk() / TIME_SCALE; clock_tick = get_cclk() / TIME_SCALE;
evt->mult = div_sc(clock_tick, NSEC_PER_SEC, evt->shift); evt->mult = div_sc(clock_tick, NSEC_PER_SEC, evt->shift);
evt->max_delta_ns = clockevent_delta2ns(-1, evt); evt->max_delta_ns = clockevent_delta2ns(-1, evt);
evt->max_delta_ticks = (unsigned long)-1;
evt->min_delta_ns = clockevent_delta2ns(100, evt); evt->min_delta_ns = clockevent_delta2ns(100, evt);
evt->min_delta_ticks = 100;
evt->cpumask = cpumask_of(cpu); evt->cpumask = cpumask_of(cpu);
......
...@@ -234,7 +234,9 @@ void __init timer64_init(void) ...@@ -234,7 +234,9 @@ void __init timer64_init(void)
clockevents_calc_mult_shift(cd, c6x_core_freq / TIMER_DIVISOR, 5); clockevents_calc_mult_shift(cd, c6x_core_freq / TIMER_DIVISOR, 5);
cd->max_delta_ns = clockevent_delta2ns(0x7fffffff, cd); cd->max_delta_ns = clockevent_delta2ns(0x7fffffff, cd);
cd->max_delta_ticks = 0x7fffffff;
cd->min_delta_ns = clockevent_delta2ns(250, cd); cd->min_delta_ns = clockevent_delta2ns(250, cd);
cd->min_delta_ticks = 250;
cd->cpumask = cpumask_of(smp_processor_id()); cd->cpumask = cpumask_of(smp_processor_id());
......
...@@ -199,7 +199,9 @@ void __init time_init_deferred(void) ...@@ -199,7 +199,9 @@ void __init time_init_deferred(void)
clockevents_calc_mult_shift(ce_dev, sleep_clk_freq, 4); clockevents_calc_mult_shift(ce_dev, sleep_clk_freq, 4);
ce_dev->max_delta_ns = clockevent_delta2ns(0x7fffffff, ce_dev); ce_dev->max_delta_ns = clockevent_delta2ns(0x7fffffff, ce_dev);
ce_dev->max_delta_ticks = 0x7fffffff;
ce_dev->min_delta_ns = clockevent_delta2ns(0xf, ce_dev); ce_dev->min_delta_ns = clockevent_delta2ns(0xf, ce_dev);
ce_dev->min_delta_ticks = 0xf;
#ifdef CONFIG_SMP #ifdef CONFIG_SMP
setup_percpu_clockdev(); setup_percpu_clockdev();
......
...@@ -149,8 +149,10 @@ void hw_timer_init(irq_handler_t handler) ...@@ -149,8 +149,10 @@ void hw_timer_init(irq_handler_t handler)
cf_pit_clockevent.mult = div_sc(FREQ, NSEC_PER_SEC, 32); cf_pit_clockevent.mult = div_sc(FREQ, NSEC_PER_SEC, 32);
cf_pit_clockevent.max_delta_ns = cf_pit_clockevent.max_delta_ns =
clockevent_delta2ns(0xFFFF, &cf_pit_clockevent); clockevent_delta2ns(0xFFFF, &cf_pit_clockevent);
cf_pit_clockevent.max_delta_ticks = 0xFFFF;
cf_pit_clockevent.min_delta_ns = cf_pit_clockevent.min_delta_ns =
clockevent_delta2ns(0x3f, &cf_pit_clockevent); clockevent_delta2ns(0x3f, &cf_pit_clockevent);
cf_pit_clockevent.min_delta_ticks = 0x3f;
clockevents_register_device(&cf_pit_clockevent); clockevents_register_device(&cf_pit_clockevent);
setup_irq(MCF_IRQ_PIT1, &pit_irq); setup_irq(MCF_IRQ_PIT1, &pit_irq);
......
...@@ -138,7 +138,9 @@ static int __init alchemy_time_init(unsigned int m2int) ...@@ -138,7 +138,9 @@ static int __init alchemy_time_init(unsigned int m2int)
cd->shift = 32; cd->shift = 32;
cd->mult = div_sc(32768, NSEC_PER_SEC, cd->shift); cd->mult = div_sc(32768, NSEC_PER_SEC, cd->shift);
cd->max_delta_ns = clockevent_delta2ns(0xffffffff, cd); cd->max_delta_ns = clockevent_delta2ns(0xffffffff, cd);
cd->min_delta_ns = clockevent_delta2ns(9, cd); /* ~0.28ms */ cd->max_delta_ticks = 0xffffffff;
cd->min_delta_ns = clockevent_delta2ns(9, cd);
cd->min_delta_ticks = 9; /* ~0.28ms */
clockevents_register_device(cd); clockevents_register_device(cd);
setup_irq(m2int, &au1x_rtcmatch2_irqaction); setup_irq(m2int, &au1x_rtcmatch2_irqaction);
......
...@@ -145,7 +145,9 @@ void __init plat_time_init(void) ...@@ -145,7 +145,9 @@ void __init plat_time_init(void)
clockevent_set_clock(&jz4740_clockevent, clk_rate); clockevent_set_clock(&jz4740_clockevent, clk_rate);
jz4740_clockevent.min_delta_ns = clockevent_delta2ns(100, &jz4740_clockevent); jz4740_clockevent.min_delta_ns = clockevent_delta2ns(100, &jz4740_clockevent);
jz4740_clockevent.min_delta_ticks = 100;
jz4740_clockevent.max_delta_ns = clockevent_delta2ns(0xffff, &jz4740_clockevent); jz4740_clockevent.max_delta_ns = clockevent_delta2ns(0xffff, &jz4740_clockevent);
jz4740_clockevent.max_delta_ticks = 0xffff;
jz4740_clockevent.cpumask = cpumask_of(0); jz4740_clockevent.cpumask = cpumask_of(0);
clockevents_register_device(&jz4740_clockevent); clockevents_register_device(&jz4740_clockevent);
......
...@@ -123,7 +123,9 @@ void sb1480_clockevent_init(void) ...@@ -123,7 +123,9 @@ void sb1480_clockevent_init(void)
CLOCK_EVT_FEAT_ONESHOT; CLOCK_EVT_FEAT_ONESHOT;
clockevent_set_clock(cd, V_SCD_TIMER_FREQ); clockevent_set_clock(cd, V_SCD_TIMER_FREQ);
cd->max_delta_ns = clockevent_delta2ns(0x7fffff, cd); cd->max_delta_ns = clockevent_delta2ns(0x7fffff, cd);
cd->max_delta_ticks = 0x7fffff;
cd->min_delta_ns = clockevent_delta2ns(2, cd); cd->min_delta_ns = clockevent_delta2ns(2, cd);
cd->min_delta_ticks = 2;
cd->rating = 200; cd->rating = 200;
cd->irq = irq; cd->irq = irq;
cd->cpumask = cpumask_of(cpu); cd->cpumask = cpumask_of(cpu);
......
...@@ -128,7 +128,9 @@ int __init ds1287_clockevent_init(int irq) ...@@ -128,7 +128,9 @@ int __init ds1287_clockevent_init(int irq)
cd->irq = irq; cd->irq = irq;
clockevent_set_clock(cd, 32768); clockevent_set_clock(cd, 32768);
cd->max_delta_ns = clockevent_delta2ns(0x7fffffff, cd); cd->max_delta_ns = clockevent_delta2ns(0x7fffffff, cd);
cd->max_delta_ticks = 0x7fffffff;
cd->min_delta_ns = clockevent_delta2ns(0x300, cd); cd->min_delta_ns = clockevent_delta2ns(0x300, cd);
cd->min_delta_ticks = 0x300;
cd->cpumask = cpumask_of(0); cd->cpumask = cpumask_of(0);
clockevents_register_device(&ds1287_clockevent); clockevents_register_device(&ds1287_clockevent);
......
...@@ -152,7 +152,9 @@ static int __init gt641xx_timer0_clockevent_init(void) ...@@ -152,7 +152,9 @@ static int __init gt641xx_timer0_clockevent_init(void)
cd->rating = 200 + gt641xx_base_clock / 10000000; cd->rating = 200 + gt641xx_base_clock / 10000000;
clockevent_set_clock(cd, gt641xx_base_clock); clockevent_set_clock(cd, gt641xx_base_clock);
cd->max_delta_ns = clockevent_delta2ns(0x7fffffff, cd); cd->max_delta_ns = clockevent_delta2ns(0x7fffffff, cd);
cd->max_delta_ticks = 0x7fffffff;
cd->min_delta_ns = clockevent_delta2ns(0x300, cd); cd->min_delta_ns = clockevent_delta2ns(0x300, cd);
cd->min_delta_ticks = 0x300;
cd->cpumask = cpumask_of(0); cd->cpumask = cpumask_of(0);
clockevents_register_device(&gt641xx_timer0_clockevent); clockevents_register_device(&gt641xx_timer0_clockevent);
......
...@@ -123,7 +123,9 @@ void sb1250_clockevent_init(void) ...@@ -123,7 +123,9 @@ void sb1250_clockevent_init(void)
CLOCK_EVT_FEAT_ONESHOT; CLOCK_EVT_FEAT_ONESHOT;
clockevent_set_clock(cd, V_SCD_TIMER_FREQ); clockevent_set_clock(cd, V_SCD_TIMER_FREQ);
cd->max_delta_ns = clockevent_delta2ns(0x7fffff, cd); cd->max_delta_ns = clockevent_delta2ns(0x7fffff, cd);
cd->max_delta_ticks = 0x7fffff;
cd->min_delta_ns = clockevent_delta2ns(2, cd); cd->min_delta_ns = clockevent_delta2ns(2, cd);
cd->min_delta_ticks = 2;
cd->rating = 200; cd->rating = 200;
cd->irq = irq; cd->irq = irq;
cd->cpumask = cpumask_of(cpu); cd->cpumask = cpumask_of(cpu);
......
...@@ -196,7 +196,9 @@ void __init txx9_clockevent_init(unsigned long baseaddr, int irq, ...@@ -196,7 +196,9 @@ void __init txx9_clockevent_init(unsigned long baseaddr, int irq,
clockevent_set_clock(cd, TIMER_CLK(imbusclk)); clockevent_set_clock(cd, TIMER_CLK(imbusclk));
cd->max_delta_ns = cd->max_delta_ns =
clockevent_delta2ns(0xffffffff >> (32 - TXX9_TIMER_BITS), cd); clockevent_delta2ns(0xffffffff >> (32 - TXX9_TIMER_BITS), cd);
cd->max_delta_ticks = 0xffffffff >> (32 - TXX9_TIMER_BITS);
cd->min_delta_ns = clockevent_delta2ns(0xf, cd); cd->min_delta_ns = clockevent_delta2ns(0xf, cd);
cd->min_delta_ticks = 0xf;
cd->irq = irq; cd->irq = irq;
cd->cpumask = cpumask_of(0), cd->cpumask = cpumask_of(0),
clockevents_register_device(cd); clockevents_register_device(cd);
......
...@@ -199,7 +199,9 @@ static void __init ls1x_time_init(void) ...@@ -199,7 +199,9 @@ static void __init ls1x_time_init(void)
clockevent_set_clock(cd, mips_hpt_frequency); clockevent_set_clock(cd, mips_hpt_frequency);
cd->max_delta_ns = clockevent_delta2ns(0xffffff, cd); cd->max_delta_ns = clockevent_delta2ns(0xffffff, cd);
cd->max_delta_ticks = 0xffffff;
cd->min_delta_ns = clockevent_delta2ns(0x000300, cd); cd->min_delta_ns = clockevent_delta2ns(0x000300, cd);
cd->min_delta_ticks = 0x000300;
cd->cpumask = cpumask_of(smp_processor_id()); cd->cpumask = cpumask_of(smp_processor_id());
clockevents_register_device(cd); clockevents_register_device(cd);
......
...@@ -123,7 +123,9 @@ void __init setup_mfgpt0_timer(void) ...@@ -123,7 +123,9 @@ void __init setup_mfgpt0_timer(void)
cd->cpumask = cpumask_of(cpu); cd->cpumask = cpumask_of(cpu);
clockevent_set_clock(cd, MFGPT_TICK_RATE); clockevent_set_clock(cd, MFGPT_TICK_RATE);
cd->max_delta_ns = clockevent_delta2ns(0xffff, cd); cd->max_delta_ns = clockevent_delta2ns(0xffff, cd);
cd->max_delta_ticks = 0xffff;
cd->min_delta_ns = clockevent_delta2ns(0xf, cd); cd->min_delta_ns = clockevent_delta2ns(0xf, cd);
cd->min_delta_ticks = 0xf;
/* Enable MFGPT0 Comparator 2 Output to the Interrupt Mapper */ /* Enable MFGPT0 Comparator 2 Output to the Interrupt Mapper */
_wrmsr(DIVIL_MSR_REG(MFGPT_IRQ), 0, 0x100); _wrmsr(DIVIL_MSR_REG(MFGPT_IRQ), 0, 0x100);
......
...@@ -241,7 +241,9 @@ void __init setup_hpet_timer(void) ...@@ -241,7 +241,9 @@ void __init setup_hpet_timer(void)
cd->cpumask = cpumask_of(cpu); cd->cpumask = cpumask_of(cpu);
clockevent_set_clock(cd, HPET_FREQ); clockevent_set_clock(cd, HPET_FREQ);
cd->max_delta_ns = clockevent_delta2ns(0x7fffffff, cd); cd->max_delta_ns = clockevent_delta2ns(0x7fffffff, cd);
cd->max_delta_ticks = 0x7fffffff;
cd->min_delta_ns = clockevent_delta2ns(HPET_MIN_PROG_DELTA, cd); cd->min_delta_ns = clockevent_delta2ns(HPET_MIN_PROG_DELTA, cd);
cd->min_delta_ticks = HPET_MIN_PROG_DELTA;
clockevents_register_device(cd); clockevents_register_device(cd);
setup_irq(HPET_T0_IRQ, &hpet_irq); setup_irq(HPET_T0_IRQ, &hpet_irq);
......
...@@ -21,6 +21,7 @@ ...@@ -21,6 +21,7 @@
#include <linux/i8253.h> #include <linux/i8253.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/kernel_stat.h> #include <linux/kernel_stat.h>
#include <linux/libfdt.h>
#include <linux/math64.h> #include <linux/math64.h>
#include <linux/sched.h> #include <linux/sched.h>
#include <linux/spinlock.h> #include <linux/spinlock.h>
...@@ -207,6 +208,33 @@ static void __init init_rtc(void) ...@@ -207,6 +208,33 @@ static void __init init_rtc(void)
CMOS_WRITE(ctrl & ~RTC_SET, RTC_CONTROL); CMOS_WRITE(ctrl & ~RTC_SET, RTC_CONTROL);
} }
#ifdef CONFIG_CLKSRC_MIPS_GIC
static u32 gic_frequency_dt;
static struct property gic_frequency_prop = {
.name = "clock-frequency",
.length = sizeof(u32),
.value = &gic_frequency_dt,
};
static void update_gic_frequency_dt(void)
{
struct device_node *node;
gic_frequency_dt = cpu_to_be32(gic_frequency);
node = of_find_compatible_node(NULL, NULL, "mti,gic-timer");
if (!node) {
pr_err("mti,gic-timer device node not found\n");
return;
}
if (of_update_property(node, &gic_frequency_prop) < 0)
pr_err("error updating gic frequency property\n");
}
#endif
void __init plat_time_init(void) void __init plat_time_init(void)
{ {
unsigned int prid = read_c0_prid() & (PRID_COMP_MASK | PRID_IMP_MASK); unsigned int prid = read_c0_prid() & (PRID_COMP_MASK | PRID_IMP_MASK);
...@@ -236,7 +264,8 @@ void __init plat_time_init(void) ...@@ -236,7 +264,8 @@ void __init plat_time_init(void)
printk("GIC frequency %d.%02d MHz\n", freq/1000000, printk("GIC frequency %d.%02d MHz\n", freq/1000000,
(freq%1000000)*100/1000000); (freq%1000000)*100/1000000);
#ifdef CONFIG_CLKSRC_MIPS_GIC #ifdef CONFIG_CLKSRC_MIPS_GIC
gic_clocksource_init(gic_frequency); update_gic_frequency_dt();
clocksource_probe();
#endif #endif
} }
#endif #endif
......
...@@ -129,7 +129,9 @@ static int __init ralink_systick_init(struct device_node *np) ...@@ -129,7 +129,9 @@ static int __init ralink_systick_init(struct device_node *np)
systick.dev.name = np->name; systick.dev.name = np->name;
clockevents_calc_mult_shift(&systick.dev, SYSTICK_FREQ, 60); clockevents_calc_mult_shift(&systick.dev, SYSTICK_FREQ, 60);
systick.dev.max_delta_ns = clockevent_delta2ns(0x7fff, &systick.dev); systick.dev.max_delta_ns = clockevent_delta2ns(0x7fff, &systick.dev);
systick.dev.max_delta_ticks = 0x7fff;
systick.dev.min_delta_ns = clockevent_delta2ns(0x3, &systick.dev); systick.dev.min_delta_ns = clockevent_delta2ns(0x3, &systick.dev);
systick.dev.min_delta_ticks = 0x3;
systick.dev.irq = irq_of_parse_and_map(np, 0); systick.dev.irq = irq_of_parse_and_map(np, 0);
if (!systick.dev.irq) { if (!systick.dev.irq) {
pr_err("%s: request_irq failed", np->name); pr_err("%s: request_irq failed", np->name);
......
...@@ -113,7 +113,9 @@ void hub_rt_clock_event_init(void) ...@@ -113,7 +113,9 @@ void hub_rt_clock_event_init(void)
cd->features = CLOCK_EVT_FEAT_ONESHOT; cd->features = CLOCK_EVT_FEAT_ONESHOT;
clockevent_set_clock(cd, CYCLES_PER_SEC); clockevent_set_clock(cd, CYCLES_PER_SEC);
cd->max_delta_ns = clockevent_delta2ns(0xfffffffffffff, cd); cd->max_delta_ns = clockevent_delta2ns(0xfffffffffffff, cd);
cd->max_delta_ticks = 0xfffffffffffff;
cd->min_delta_ns = clockevent_delta2ns(0x300, cd); cd->min_delta_ns = clockevent_delta2ns(0x300, cd);
cd->min_delta_ticks = 0x300;
cd->rating = 200; cd->rating = 200;
cd->irq = irq; cd->irq = irq;
cd->cpumask = cpumask_of(cpu); cd->cpumask = cpumask_of(cpu);
......
...@@ -98,7 +98,9 @@ int __init init_clockevents(void) ...@@ -98,7 +98,9 @@ int __init init_clockevents(void)
/* Calculate the min / max delta */ /* Calculate the min / max delta */
cd->max_delta_ns = clockevent_delta2ns(TMJCBR_MAX, cd); cd->max_delta_ns = clockevent_delta2ns(TMJCBR_MAX, cd);
cd->max_delta_ticks = TMJCBR_MAX;
cd->min_delta_ns = clockevent_delta2ns(100, cd); cd->min_delta_ns = clockevent_delta2ns(100, cd);
cd->min_delta_ticks = 100;
cd->rating = 200; cd->rating = 200;
cd->cpumask = cpumask_of(smp_processor_id()); cd->cpumask = cpumask_of(smp_processor_id());
......
...@@ -995,8 +995,10 @@ static void __init init_decrementer_clockevent(void) ...@@ -995,8 +995,10 @@ static void __init init_decrementer_clockevent(void)
decrementer_clockevent.max_delta_ns = decrementer_clockevent.max_delta_ns =
clockevent_delta2ns(decrementer_max, &decrementer_clockevent); clockevent_delta2ns(decrementer_max, &decrementer_clockevent);
decrementer_clockevent.max_delta_ticks = decrementer_max;
decrementer_clockevent.min_delta_ns = decrementer_clockevent.min_delta_ns =
clockevent_delta2ns(2, &decrementer_clockevent); clockevent_delta2ns(2, &decrementer_clockevent);
decrementer_clockevent.min_delta_ticks = 2;
register_decrementer_clockevent(cpu); register_decrementer_clockevent(cpu);
} }
......
...@@ -158,7 +158,9 @@ void init_cpu_timer(void) ...@@ -158,7 +158,9 @@ void init_cpu_timer(void)
cd->mult = 16777; cd->mult = 16777;
cd->shift = 12; cd->shift = 12;
cd->min_delta_ns = 1; cd->min_delta_ns = 1;
cd->min_delta_ticks = 1;
cd->max_delta_ns = LONG_MAX; cd->max_delta_ns = LONG_MAX;
cd->max_delta_ticks = ULONG_MAX;
cd->rating = 400; cd->rating = 400;
cd->cpumask = cpumask_of(cpu); cd->cpumask = cpumask_of(cpu);
cd->set_next_event = s390_next_event; cd->set_next_event = s390_next_event;
......
...@@ -81,8 +81,10 @@ void __init time_init(void) ...@@ -81,8 +81,10 @@ void __init time_init(void)
score_clockevent.shift); score_clockevent.shift);
score_clockevent.max_delta_ns = clockevent_delta2ns((u32)~0, score_clockevent.max_delta_ns = clockevent_delta2ns((u32)~0,
&score_clockevent); &score_clockevent);
score_clockevent.max_delta_ticks = (u32)~0;
score_clockevent.min_delta_ns = clockevent_delta2ns(50, score_clockevent.min_delta_ns = clockevent_delta2ns(50,
&score_clockevent) + 1; &score_clockevent) + 1;
score_clockevent.min_delta_ticks = 50;
score_clockevent.cpumask = cpumask_of(0); score_clockevent.cpumask = cpumask_of(0);
clockevents_register_device(&score_clockevent); clockevents_register_device(&score_clockevent);
} }
...@@ -228,7 +228,9 @@ void register_percpu_ce(int cpu) ...@@ -228,7 +228,9 @@ void register_percpu_ce(int cpu)
ce->mult = div_sc(sparc_config.clock_rate, NSEC_PER_SEC, ce->mult = div_sc(sparc_config.clock_rate, NSEC_PER_SEC,
ce->shift); ce->shift);
ce->max_delta_ns = clockevent_delta2ns(sparc_config.clock_rate, ce); ce->max_delta_ns = clockevent_delta2ns(sparc_config.clock_rate, ce);
ce->max_delta_ticks = (unsigned long)sparc_config.clock_rate;
ce->min_delta_ns = clockevent_delta2ns(100, ce); ce->min_delta_ns = clockevent_delta2ns(100, ce);
ce->min_delta_ticks = 100;
clockevents_register_device(ce); clockevents_register_device(ce);
} }
......
...@@ -796,8 +796,10 @@ void __init time_init(void) ...@@ -796,8 +796,10 @@ void __init time_init(void)
sparc64_clockevent.max_delta_ns = sparc64_clockevent.max_delta_ns =
clockevent_delta2ns(0x7fffffffffffffffUL, &sparc64_clockevent); clockevent_delta2ns(0x7fffffffffffffffUL, &sparc64_clockevent);
sparc64_clockevent.max_delta_ticks = 0x7fffffffffffffffUL;
sparc64_clockevent.min_delta_ns = sparc64_clockevent.min_delta_ns =
clockevent_delta2ns(0xF, &sparc64_clockevent); clockevent_delta2ns(0xF, &sparc64_clockevent);
sparc64_clockevent.min_delta_ticks = 0xF;
printk("clockevent: mult[%x] shift[%d]\n", printk("clockevent: mult[%x] shift[%d]\n",
sparc64_clockevent.mult, sparc64_clockevent.shift); sparc64_clockevent.mult, sparc64_clockevent.shift);
......
...@@ -155,6 +155,8 @@ static DEFINE_PER_CPU(struct clock_event_device, tile_timer) = { ...@@ -155,6 +155,8 @@ static DEFINE_PER_CPU(struct clock_event_device, tile_timer) = {
.name = "tile timer", .name = "tile timer",
.features = CLOCK_EVT_FEAT_ONESHOT, .features = CLOCK_EVT_FEAT_ONESHOT,
.min_delta_ns = 1000, .min_delta_ns = 1000,
.min_delta_ticks = 1,
.max_delta_ticks = MAX_TICK,
.rating = 100, .rating = 100,
.irq = -1, .irq = -1,
.set_next_event = tile_timer_set_next_event, .set_next_event = tile_timer_set_next_event,
......
...@@ -65,7 +65,9 @@ static struct clock_event_device timer_clockevent = { ...@@ -65,7 +65,9 @@ static struct clock_event_device timer_clockevent = {
.set_next_event = itimer_next_event, .set_next_event = itimer_next_event,
.shift = 0, .shift = 0,
.max_delta_ns = 0xffffffff, .max_delta_ns = 0xffffffff,
.min_delta_ns = TIMER_MIN_DELTA, //microsecond resolution should be enough for anyone, same as 640K RAM .max_delta_ticks = 0xffffffff,
.min_delta_ns = TIMER_MIN_DELTA,
.min_delta_ticks = TIMER_MIN_DELTA, // microsecond resolution should be enough for anyone, same as 640K RAM
.irq = 0, .irq = 0,
.mult = 1, .mult = 1,
}; };
......
...@@ -91,8 +91,10 @@ void __init time_init(void) ...@@ -91,8 +91,10 @@ void __init time_init(void)
ckevt_puv3_osmr0.max_delta_ns = ckevt_puv3_osmr0.max_delta_ns =
clockevent_delta2ns(0x7fffffff, &ckevt_puv3_osmr0); clockevent_delta2ns(0x7fffffff, &ckevt_puv3_osmr0);
ckevt_puv3_osmr0.max_delta_ticks = 0x7fffffff;
ckevt_puv3_osmr0.min_delta_ns = ckevt_puv3_osmr0.min_delta_ns =
clockevent_delta2ns(MIN_OSCR_DELTA * 2, &ckevt_puv3_osmr0) + 1; clockevent_delta2ns(MIN_OSCR_DELTA * 2, &ckevt_puv3_osmr0) + 1;
ckevt_puv3_osmr0.min_delta_ticks = MIN_OSCR_DELTA * 2;
ckevt_puv3_osmr0.cpumask = cpumask_of(0); ckevt_puv3_osmr0.cpumask = cpumask_of(0);
setup_irq(IRQ_TIMER0, &puv3_timer_irq); setup_irq(IRQ_TIMER0, &puv3_timer_irq);
......
...@@ -731,8 +731,10 @@ static int __init calibrate_APIC_clock(void) ...@@ -731,8 +731,10 @@ static int __init calibrate_APIC_clock(void)
TICK_NSEC, lapic_clockevent.shift); TICK_NSEC, lapic_clockevent.shift);
lapic_clockevent.max_delta_ns = lapic_clockevent.max_delta_ns =
clockevent_delta2ns(0x7FFFFF, &lapic_clockevent); clockevent_delta2ns(0x7FFFFF, &lapic_clockevent);
lapic_clockevent.max_delta_ticks = 0x7FFFFF;
lapic_clockevent.min_delta_ns = lapic_clockevent.min_delta_ns =
clockevent_delta2ns(0xF, &lapic_clockevent); clockevent_delta2ns(0xF, &lapic_clockevent);
lapic_clockevent.min_delta_ticks = 0xF;
lapic_clockevent.features &= ~CLOCK_EVT_FEAT_DUMMY; lapic_clockevent.features &= ~CLOCK_EVT_FEAT_DUMMY;
return 0; return 0;
} }
...@@ -778,8 +780,10 @@ static int __init calibrate_APIC_clock(void) ...@@ -778,8 +780,10 @@ static int __init calibrate_APIC_clock(void)
lapic_clockevent.shift); lapic_clockevent.shift);
lapic_clockevent.max_delta_ns = lapic_clockevent.max_delta_ns =
clockevent_delta2ns(0x7FFFFFFF, &lapic_clockevent); clockevent_delta2ns(0x7FFFFFFF, &lapic_clockevent);
lapic_clockevent.max_delta_ticks = 0x7FFFFFFF;
lapic_clockevent.min_delta_ns = lapic_clockevent.min_delta_ns =
clockevent_delta2ns(0xF, &lapic_clockevent); clockevent_delta2ns(0xF, &lapic_clockevent);
lapic_clockevent.min_delta_ticks = 0xF;
lapic_timer_frequency = (delta * APIC_DIVISOR) / LAPIC_CAL_LOOPS; lapic_timer_frequency = (delta * APIC_DIVISOR) / LAPIC_CAL_LOOPS;
......
...@@ -994,7 +994,9 @@ static struct clock_event_device lguest_clockevent = { ...@@ -994,7 +994,9 @@ static struct clock_event_device lguest_clockevent = {
.mult = 1, .mult = 1,
.shift = 0, .shift = 0,
.min_delta_ns = LG_CLOCK_MIN_DELTA, .min_delta_ns = LG_CLOCK_MIN_DELTA,
.min_delta_ticks = LG_CLOCK_MIN_DELTA,
.max_delta_ns = LG_CLOCK_MAX_DELTA, .max_delta_ns = LG_CLOCK_MAX_DELTA,
.max_delta_ticks = LG_CLOCK_MAX_DELTA,
}; };
/* /*
......
...@@ -390,9 +390,11 @@ static __init int uv_rtc_setup_clock(void) ...@@ -390,9 +390,11 @@ static __init int uv_rtc_setup_clock(void)
clock_event_device_uv.min_delta_ns = NSEC_PER_SEC / clock_event_device_uv.min_delta_ns = NSEC_PER_SEC /
sn_rtc_cycles_per_second; sn_rtc_cycles_per_second;
clock_event_device_uv.min_delta_ticks = 1;
clock_event_device_uv.max_delta_ns = clocksource_uv.mask * clock_event_device_uv.max_delta_ns = clocksource_uv.mask *
(NSEC_PER_SEC / sn_rtc_cycles_per_second); (NSEC_PER_SEC / sn_rtc_cycles_per_second);
clock_event_device_uv.max_delta_ticks = clocksource_uv.mask;
rc = schedule_on_each_cpu(uv_rtc_register_clockevents); rc = schedule_on_each_cpu(uv_rtc_register_clockevents);
if (rc) { if (rc) {
......
...@@ -209,7 +209,9 @@ static const struct clock_event_device xen_timerop_clockevent = { ...@@ -209,7 +209,9 @@ static const struct clock_event_device xen_timerop_clockevent = {
.features = CLOCK_EVT_FEAT_ONESHOT, .features = CLOCK_EVT_FEAT_ONESHOT,
.max_delta_ns = 0xffffffff, .max_delta_ns = 0xffffffff,
.max_delta_ticks = 0xffffffff,
.min_delta_ns = TIMER_SLOP, .min_delta_ns = TIMER_SLOP,
.min_delta_ticks = TIMER_SLOP,
.mult = 1, .mult = 1,
.shift = 0, .shift = 0,
...@@ -268,7 +270,9 @@ static const struct clock_event_device xen_vcpuop_clockevent = { ...@@ -268,7 +270,9 @@ static const struct clock_event_device xen_vcpuop_clockevent = {
.features = CLOCK_EVT_FEAT_ONESHOT, .features = CLOCK_EVT_FEAT_ONESHOT,
.max_delta_ns = 0xffffffff, .max_delta_ns = 0xffffffff,
.max_delta_ticks = 0xffffffff,
.min_delta_ns = TIMER_SLOP, .min_delta_ns = TIMER_SLOP,
.min_delta_ticks = TIMER_SLOP,
.mult = 1, .mult = 1,
.shift = 0, .shift = 0,
......
...@@ -4,3 +4,6 @@ ...@@ -4,3 +4,6 @@
config ACPI_IORT config ACPI_IORT
bool bool
config ACPI_GTDT
bool
obj-$(CONFIG_ACPI_IORT) += iort.o obj-$(CONFIG_ACPI_IORT) += iort.o
obj-$(CONFIG_ACPI_GTDT) += gtdt.o
This diff is collapsed.
...@@ -478,18 +478,18 @@ static int sgi_clock_period; ...@@ -478,18 +478,18 @@ static int sgi_clock_period;
static struct timespec sgi_clock_offset; static struct timespec sgi_clock_offset;
static int sgi_clock_period; static int sgi_clock_period;
static int sgi_clock_get(clockid_t clockid, struct timespec *tp) static int sgi_clock_get(clockid_t clockid, struct timespec64 *tp)
{ {
u64 nsec; u64 nsec;
nsec = rtc_time() * sgi_clock_period nsec = rtc_time() * sgi_clock_period
+ sgi_clock_offset.tv_nsec; + sgi_clock_offset.tv_nsec;
*tp = ns_to_timespec(nsec); *tp = ns_to_timespec64(nsec);
tp->tv_sec += sgi_clock_offset.tv_sec; tp->tv_sec += sgi_clock_offset.tv_sec;
return 0; return 0;
}; };
static int sgi_clock_set(const clockid_t clockid, const struct timespec *tp) static int sgi_clock_set(const clockid_t clockid, const struct timespec64 *tp)
{ {
u64 nsec; u64 nsec;
...@@ -657,7 +657,7 @@ static int sgi_timer_del(struct k_itimer *timr) ...@@ -657,7 +657,7 @@ static int sgi_timer_del(struct k_itimer *timr)
} }
/* Assumption: it_lock is already held with irq's disabled */ /* Assumption: it_lock is already held with irq's disabled */
static void sgi_timer_get(struct k_itimer *timr, struct itimerspec *cur_setting) static void sgi_timer_get(struct k_itimer *timr, struct itimerspec64 *cur_setting)
{ {
if (timr->it.mmtimer.clock == TIMER_OFF) { if (timr->it.mmtimer.clock == TIMER_OFF) {
...@@ -668,14 +668,14 @@ static void sgi_timer_get(struct k_itimer *timr, struct itimerspec *cur_setting) ...@@ -668,14 +668,14 @@ static void sgi_timer_get(struct k_itimer *timr, struct itimerspec *cur_setting)
return; return;
} }
cur_setting->it_interval = ns_to_timespec(timr->it.mmtimer.incr * sgi_clock_period); cur_setting->it_interval = ns_to_timespec64(timr->it.mmtimer.incr * sgi_clock_period);
cur_setting->it_value = ns_to_timespec((timr->it.mmtimer.expires - rtc_time()) * sgi_clock_period); cur_setting->it_value = ns_to_timespec64((timr->it.mmtimer.expires - rtc_time()) * sgi_clock_period);
} }
static int sgi_timer_set(struct k_itimer *timr, int flags, static int sgi_timer_set(struct k_itimer *timr, int flags,
struct itimerspec * new_setting, struct itimerspec64 *new_setting,
struct itimerspec * old_setting) struct itimerspec64 *old_setting)
{ {
unsigned long when, period, irqflags; unsigned long when, period, irqflags;
int err = 0; int err = 0;
...@@ -687,8 +687,8 @@ static int sgi_timer_set(struct k_itimer *timr, int flags, ...@@ -687,8 +687,8 @@ static int sgi_timer_set(struct k_itimer *timr, int flags,
sgi_timer_get(timr, old_setting); sgi_timer_get(timr, old_setting);
sgi_timer_del(timr); sgi_timer_del(timr);
when = timespec_to_ns(&new_setting->it_value); when = timespec64_to_ns(&new_setting->it_value);
period = timespec_to_ns(&new_setting->it_interval); period = timespec64_to_ns(&new_setting->it_interval);
if (when == 0) if (when == 0)
/* Clear timer */ /* Clear timer */
...@@ -699,11 +699,11 @@ static int sgi_timer_set(struct k_itimer *timr, int flags, ...@@ -699,11 +699,11 @@ static int sgi_timer_set(struct k_itimer *timr, int flags,
return -ENOMEM; return -ENOMEM;
if (flags & TIMER_ABSTIME) { if (flags & TIMER_ABSTIME) {
struct timespec n; struct timespec64 n;
unsigned long now; unsigned long now;
getnstimeofday(&n); getnstimeofday64(&n);
now = timespec_to_ns(&n); now = timespec64_to_ns(&n);
if (when > now) if (when > now)
when -= now; when -= now;
else else
...@@ -765,7 +765,7 @@ static int sgi_timer_set(struct k_itimer *timr, int flags, ...@@ -765,7 +765,7 @@ static int sgi_timer_set(struct k_itimer *timr, int flags,
return err; return err;
} }
static int sgi_clock_getres(const clockid_t which_clock, struct timespec *tp) static int sgi_clock_getres(const clockid_t which_clock, struct timespec64 *tp)
{ {
tp->tv_sec = 0; tp->tv_sec = 0;
tp->tv_nsec = sgi_clock_period; tp->tv_nsec = sgi_clock_period;
......
...@@ -67,20 +67,22 @@ config DW_APB_TIMER_OF ...@@ -67,20 +67,22 @@ config DW_APB_TIMER_OF
select DW_APB_TIMER select DW_APB_TIMER
select CLKSRC_OF select CLKSRC_OF
config GEMINI_TIMER config FTTMR010_TIMER
bool "Cortina Gemini timer driver" if COMPILE_TEST bool "Faraday Technology timer driver" if COMPILE_TEST
depends on GENERIC_CLOCKEVENTS depends on GENERIC_CLOCKEVENTS
depends on HAS_IOMEM depends on HAS_IOMEM
select CLKSRC_MMIO select CLKSRC_MMIO
select CLKSRC_OF select CLKSRC_OF
select MFD_SYSCON select MFD_SYSCON
help help
Enables support for the Gemini timer Enables support for the Faraday Technology timer block
FTTMR010.
config ROCKCHIP_TIMER config ROCKCHIP_TIMER
bool "Rockchip timer driver" if COMPILE_TEST bool "Rockchip timer driver" if COMPILE_TEST
depends on ARM || ARM64 depends on ARM || ARM64
select CLKSRC_OF select CLKSRC_OF
select CLKSRC_MMIO
help help
Enables the support for the rockchip timer driver. Enables the support for the rockchip timer driver.
...@@ -366,6 +368,17 @@ config HISILICON_ERRATUM_161010101 ...@@ -366,6 +368,17 @@ config HISILICON_ERRATUM_161010101
161010101. The workaround will be active if the hisilicon,erratum-161010101 161010101. The workaround will be active if the hisilicon,erratum-161010101
property is found in the timer node. property is found in the timer node.
config ARM64_ERRATUM_858921
bool "Workaround for Cortex-A73 erratum 858921"
default y
select ARM_ARCH_TIMER_OOL_WORKAROUND
depends on ARM_ARCH_TIMER && ARM64
help
This option enables a workaround applicable to Cortex-A73
(all versions), whose counter may return incorrect values.
The workaround will be dynamically enabled when an affected
core is detected.
config ARM_GLOBAL_TIMER config ARM_GLOBAL_TIMER
bool "Support for the ARM global timer" if COMPILE_TEST bool "Support for the ARM global timer" if COMPILE_TEST
select CLKSRC_OF if OF select CLKSRC_OF if OF
......
...@@ -17,7 +17,7 @@ obj-$(CONFIG_CLKSRC_MMIO) += mmio.o ...@@ -17,7 +17,7 @@ obj-$(CONFIG_CLKSRC_MMIO) += mmio.o
obj-$(CONFIG_DIGICOLOR_TIMER) += timer-digicolor.o obj-$(CONFIG_DIGICOLOR_TIMER) += timer-digicolor.o
obj-$(CONFIG_DW_APB_TIMER) += dw_apb_timer.o obj-$(CONFIG_DW_APB_TIMER) += dw_apb_timer.o
obj-$(CONFIG_DW_APB_TIMER_OF) += dw_apb_timer_of.o obj-$(CONFIG_DW_APB_TIMER_OF) += dw_apb_timer_of.o
obj-$(CONFIG_GEMINI_TIMER) += timer-gemini.o obj-$(CONFIG_FTTMR010_TIMER) += timer-fttmr010.o
obj-$(CONFIG_ROCKCHIP_TIMER) += rockchip_timer.o obj-$(CONFIG_ROCKCHIP_TIMER) += rockchip_timer.o
obj-$(CONFIG_CLKSRC_NOMADIK_MTU) += nomadik-mtu.o obj-$(CONFIG_CLKSRC_NOMADIK_MTU) += nomadik-mtu.o
obj-$(CONFIG_CLKSRC_DBX500_PRCMU) += clksrc-dbx500-prcmu.o obj-$(CONFIG_CLKSRC_DBX500_PRCMU) += clksrc-dbx500-prcmu.o
......
...@@ -37,7 +37,7 @@ static int noinline arc_get_timer_clk(struct device_node *node) ...@@ -37,7 +37,7 @@ static int noinline arc_get_timer_clk(struct device_node *node)
clk = of_clk_get(node, 0); clk = of_clk_get(node, 0);
if (IS_ERR(clk)) { if (IS_ERR(clk)) {
pr_err("timer missing clk"); pr_err("timer missing clk\n");
return PTR_ERR(clk); return PTR_ERR(clk);
} }
...@@ -89,7 +89,7 @@ static int __init arc_cs_setup_gfrc(struct device_node *node) ...@@ -89,7 +89,7 @@ static int __init arc_cs_setup_gfrc(struct device_node *node)
READ_BCR(ARC_REG_MCIP_BCR, mp); READ_BCR(ARC_REG_MCIP_BCR, mp);
if (!mp.gfrc) { if (!mp.gfrc) {
pr_warn("Global-64-bit-Ctr clocksource not detected"); pr_warn("Global-64-bit-Ctr clocksource not detected\n");
return -ENXIO; return -ENXIO;
} }
...@@ -140,13 +140,13 @@ static int __init arc_cs_setup_rtc(struct device_node *node) ...@@ -140,13 +140,13 @@ static int __init arc_cs_setup_rtc(struct device_node *node)
READ_BCR(ARC_REG_TIMERS_BCR, timer); READ_BCR(ARC_REG_TIMERS_BCR, timer);
if (!timer.rtc) { if (!timer.rtc) {
pr_warn("Local-64-bit-Ctr clocksource not detected"); pr_warn("Local-64-bit-Ctr clocksource not detected\n");
return -ENXIO; return -ENXIO;
} }
/* Local to CPU hence not usable in SMP */ /* Local to CPU hence not usable in SMP */
if (IS_ENABLED(CONFIG_SMP)) { if (IS_ENABLED(CONFIG_SMP)) {
pr_warn("Local-64-bit-Ctr not usable in SMP"); pr_warn("Local-64-bit-Ctr not usable in SMP\n");
return -EINVAL; return -EINVAL;
} }
...@@ -290,13 +290,13 @@ static int __init arc_clockevent_setup(struct device_node *node) ...@@ -290,13 +290,13 @@ static int __init arc_clockevent_setup(struct device_node *node)
arc_timer_irq = irq_of_parse_and_map(node, 0); arc_timer_irq = irq_of_parse_and_map(node, 0);
if (arc_timer_irq <= 0) { if (arc_timer_irq <= 0) {
pr_err("clockevent: missing irq"); pr_err("clockevent: missing irq\n");
return -EINVAL; return -EINVAL;
} }
ret = arc_get_timer_clk(node); ret = arc_get_timer_clk(node);
if (ret) { if (ret) {
pr_err("clockevent: missing clk"); pr_err("clockevent: missing clk\n");
return ret; return ret;
} }
...@@ -313,7 +313,7 @@ static int __init arc_clockevent_setup(struct device_node *node) ...@@ -313,7 +313,7 @@ static int __init arc_clockevent_setup(struct device_node *node)
arc_timer_starting_cpu, arc_timer_starting_cpu,
arc_timer_dying_cpu); arc_timer_dying_cpu);
if (ret) { if (ret) {
pr_err("Failed to setup hotplug state"); pr_err("Failed to setup hotplug state\n");
return ret; return ret;
} }
return 0; return 0;
......
This diff is collapsed.
...@@ -193,7 +193,7 @@ static int __init asm9260_timer_init(struct device_node *np) ...@@ -193,7 +193,7 @@ static int __init asm9260_timer_init(struct device_node *np)
priv.base = of_io_request_and_map(np, 0, np->name); priv.base = of_io_request_and_map(np, 0, np->name);
if (IS_ERR(priv.base)) { if (IS_ERR(priv.base)) {
pr_err("%s: unable to map resource", np->name); pr_err("%s: unable to map resource\n", np->name);
return PTR_ERR(priv.base); return PTR_ERR(priv.base);
} }
......
...@@ -89,13 +89,13 @@ static int __init bcm2835_timer_init(struct device_node *node) ...@@ -89,13 +89,13 @@ static int __init bcm2835_timer_init(struct device_node *node)
base = of_iomap(node, 0); base = of_iomap(node, 0);
if (!base) { if (!base) {
pr_err("Can't remap registers"); pr_err("Can't remap registers\n");
return -ENXIO; return -ENXIO;
} }
ret = of_property_read_u32(node, "clock-frequency", &freq); ret = of_property_read_u32(node, "clock-frequency", &freq);
if (ret) { if (ret) {
pr_err("Can't read clock-frequency"); pr_err("Can't read clock-frequency\n");
goto err_iounmap; goto err_iounmap;
} }
...@@ -107,7 +107,7 @@ static int __init bcm2835_timer_init(struct device_node *node) ...@@ -107,7 +107,7 @@ static int __init bcm2835_timer_init(struct device_node *node)
irq = irq_of_parse_and_map(node, DEFAULT_TIMER); irq = irq_of_parse_and_map(node, DEFAULT_TIMER);
if (irq <= 0) { if (irq <= 0) {
pr_err("Can't parse IRQ"); pr_err("Can't parse IRQ\n");
ret = -EINVAL; ret = -EINVAL;
goto err_iounmap; goto err_iounmap;
} }
......
...@@ -179,7 +179,7 @@ static int __init kona_timer_init(struct device_node *node) ...@@ -179,7 +179,7 @@ static int __init kona_timer_init(struct device_node *node)
} else if (!of_property_read_u32(node, "clock-frequency", &freq)) { } else if (!of_property_read_u32(node, "clock-frequency", &freq)) {
arch_timer_rate = freq; arch_timer_rate = freq;
} else { } else {
pr_err("Kona Timer v1 unable to determine clock-frequency"); pr_err("Kona Timer v1 unable to determine clock-frequency\n");
return -EINVAL; return -EINVAL;
} }
......
...@@ -40,7 +40,7 @@ void __init clocksource_probe(void) ...@@ -40,7 +40,7 @@ void __init clocksource_probe(void)
ret = init_func_ret(np); ret = init_func_ret(np);
if (ret) { if (ret) {
pr_err("Failed to initialize '%s': %d", pr_err("Failed to initialize '%s': %d\n",
of_node_full_name(np), ret); of_node_full_name(np), ret);
continue; continue;
} }
......
...@@ -101,7 +101,7 @@ static irqreturn_t dw_apb_clockevent_irq(int irq, void *data) ...@@ -101,7 +101,7 @@ static irqreturn_t dw_apb_clockevent_irq(int irq, void *data)
struct dw_apb_clock_event_device *dw_ced = ced_to_dw_apb_ced(evt); struct dw_apb_clock_event_device *dw_ced = ced_to_dw_apb_ced(evt);
if (!evt->event_handler) { if (!evt->event_handler) {
pr_info("Spurious APBT timer interrupt %d", irq); pr_info("Spurious APBT timer interrupt %d\n", irq);
return IRQ_NONE; return IRQ_NONE;
} }
...@@ -257,7 +257,9 @@ dw_apb_clockevent_init(int cpu, const char *name, unsigned rating, ...@@ -257,7 +257,9 @@ dw_apb_clockevent_init(int cpu, const char *name, unsigned rating,
clockevents_calc_mult_shift(&dw_ced->ced, freq, APBT_MIN_PERIOD); clockevents_calc_mult_shift(&dw_ced->ced, freq, APBT_MIN_PERIOD);
dw_ced->ced.max_delta_ns = clockevent_delta2ns(0x7fffffff, dw_ced->ced.max_delta_ns = clockevent_delta2ns(0x7fffffff,
&dw_ced->ced); &dw_ced->ced);
dw_ced->ced.max_delta_ticks = 0x7fffffff;
dw_ced->ced.min_delta_ns = clockevent_delta2ns(5000, &dw_ced->ced); dw_ced->ced.min_delta_ns = clockevent_delta2ns(5000, &dw_ced->ced);
dw_ced->ced.min_delta_ticks = 5000;
dw_ced->ced.cpumask = cpumask_of(cpu); dw_ced->ced.cpumask = cpumask_of(cpu);
dw_ced->ced.features = CLOCK_EVT_FEAT_PERIODIC | dw_ced->ced.features = CLOCK_EVT_FEAT_PERIODIC |
CLOCK_EVT_FEAT_ONESHOT | CLOCK_EVT_FEAT_DYNIRQ; CLOCK_EVT_FEAT_ONESHOT | CLOCK_EVT_FEAT_DYNIRQ;
......
...@@ -78,15 +78,12 @@ static int em_sti_enable(struct em_sti_priv *p) ...@@ -78,15 +78,12 @@ static int em_sti_enable(struct em_sti_priv *p)
int ret; int ret;
/* enable clock */ /* enable clock */
ret = clk_prepare_enable(p->clk); ret = clk_enable(p->clk);
if (ret) { if (ret) {
dev_err(&p->pdev->dev, "cannot enable clock\n"); dev_err(&p->pdev->dev, "cannot enable clock\n");
return ret; return ret;
} }
/* configure channel, periodic mode and maximum timeout */
p->rate = clk_get_rate(p->clk);
/* reset the counter */ /* reset the counter */
em_sti_write(p, STI_SET_H, 0x40000000); em_sti_write(p, STI_SET_H, 0x40000000);
em_sti_write(p, STI_SET_L, 0x00000000); em_sti_write(p, STI_SET_L, 0x00000000);
...@@ -107,7 +104,7 @@ static void em_sti_disable(struct em_sti_priv *p) ...@@ -107,7 +104,7 @@ static void em_sti_disable(struct em_sti_priv *p)
em_sti_write(p, STI_INTENCLR, 3); em_sti_write(p, STI_INTENCLR, 3);
/* stop clock */ /* stop clock */
clk_disable_unprepare(p->clk); clk_disable(p->clk);
} }
static u64 em_sti_count(struct em_sti_priv *p) static u64 em_sti_count(struct em_sti_priv *p)
...@@ -205,13 +202,9 @@ static u64 em_sti_clocksource_read(struct clocksource *cs) ...@@ -205,13 +202,9 @@ static u64 em_sti_clocksource_read(struct clocksource *cs)
static int em_sti_clocksource_enable(struct clocksource *cs) static int em_sti_clocksource_enable(struct clocksource *cs)
{ {
int ret;
struct em_sti_priv *p = cs_to_em_sti(cs); struct em_sti_priv *p = cs_to_em_sti(cs);
ret = em_sti_start(p, USER_CLOCKSOURCE); return em_sti_start(p, USER_CLOCKSOURCE);
if (!ret)
__clocksource_update_freq_hz(cs, p->rate);
return ret;
} }
static void em_sti_clocksource_disable(struct clocksource *cs) static void em_sti_clocksource_disable(struct clocksource *cs)
...@@ -240,8 +233,7 @@ static int em_sti_register_clocksource(struct em_sti_priv *p) ...@@ -240,8 +233,7 @@ static int em_sti_register_clocksource(struct em_sti_priv *p)
dev_info(&p->pdev->dev, "used as clock source\n"); dev_info(&p->pdev->dev, "used as clock source\n");
/* Register with dummy 1 Hz value, gets updated in ->enable() */ clocksource_register_hz(cs, p->rate);
clocksource_register_hz(cs, 1);
return 0; return 0;
} }
...@@ -263,7 +255,6 @@ static int em_sti_clock_event_set_oneshot(struct clock_event_device *ced) ...@@ -263,7 +255,6 @@ static int em_sti_clock_event_set_oneshot(struct clock_event_device *ced)
dev_info(&p->pdev->dev, "used for oneshot clock events\n"); dev_info(&p->pdev->dev, "used for oneshot clock events\n");
em_sti_start(p, USER_CLOCKEVENT); em_sti_start(p, USER_CLOCKEVENT);
clockevents_config(&p->ced, p->rate);
return 0; return 0;
} }
...@@ -294,8 +285,7 @@ static void em_sti_register_clockevent(struct em_sti_priv *p) ...@@ -294,8 +285,7 @@ static void em_sti_register_clockevent(struct em_sti_priv *p)
dev_info(&p->pdev->dev, "used for clock events\n"); dev_info(&p->pdev->dev, "used for clock events\n");
/* Register with dummy 1 Hz value, gets updated in ->set_state_oneshot() */ clockevents_config_and_register(ced, p->rate, 2, 0xffffffff);
clockevents_config_and_register(ced, 1, 2, 0xffffffff);
} }
static int em_sti_probe(struct platform_device *pdev) static int em_sti_probe(struct platform_device *pdev)
...@@ -303,6 +293,7 @@ static int em_sti_probe(struct platform_device *pdev) ...@@ -303,6 +293,7 @@ static int em_sti_probe(struct platform_device *pdev)
struct em_sti_priv *p; struct em_sti_priv *p;
struct resource *res; struct resource *res;
int irq; int irq;
int ret;
p = devm_kzalloc(&pdev->dev, sizeof(*p), GFP_KERNEL); p = devm_kzalloc(&pdev->dev, sizeof(*p), GFP_KERNEL);
if (p == NULL) if (p == NULL)
...@@ -323,6 +314,13 @@ static int em_sti_probe(struct platform_device *pdev) ...@@ -323,6 +314,13 @@ static int em_sti_probe(struct platform_device *pdev)
if (IS_ERR(p->base)) if (IS_ERR(p->base))
return PTR_ERR(p->base); return PTR_ERR(p->base);
if (devm_request_irq(&pdev->dev, irq, em_sti_interrupt,
IRQF_TIMER | IRQF_IRQPOLL | IRQF_NOBALANCING,
dev_name(&pdev->dev), p)) {
dev_err(&pdev->dev, "failed to request low IRQ\n");
return -ENOENT;
}
/* get hold of clock */ /* get hold of clock */
p->clk = devm_clk_get(&pdev->dev, "sclk"); p->clk = devm_clk_get(&pdev->dev, "sclk");
if (IS_ERR(p->clk)) { if (IS_ERR(p->clk)) {
...@@ -330,12 +328,20 @@ static int em_sti_probe(struct platform_device *pdev) ...@@ -330,12 +328,20 @@ static int em_sti_probe(struct platform_device *pdev)
return PTR_ERR(p->clk); return PTR_ERR(p->clk);
} }
if (devm_request_irq(&pdev->dev, irq, em_sti_interrupt, ret = clk_prepare(p->clk);
IRQF_TIMER | IRQF_IRQPOLL | IRQF_NOBALANCING, if (ret < 0) {
dev_name(&pdev->dev), p)) { dev_err(&pdev->dev, "cannot prepare clock\n");
dev_err(&pdev->dev, "failed to request low IRQ\n"); return ret;
return -ENOENT; }
ret = clk_enable(p->clk);
if (ret < 0) {
dev_err(&p->pdev->dev, "cannot enable clock\n");
clk_unprepare(p->clk);
return ret;
} }
p->rate = clk_get_rate(p->clk);
clk_disable(p->clk);
raw_spin_lock_init(&p->lock); raw_spin_lock_init(&p->lock);
em_sti_register_clockevent(p); em_sti_register_clockevent(p);
......
...@@ -101,15 +101,7 @@ static inline struct timer8_priv *ced_to_priv(struct clock_event_device *ced) ...@@ -101,15 +101,7 @@ static inline struct timer8_priv *ced_to_priv(struct clock_event_device *ced)
static void timer8_clock_event_start(struct timer8_priv *p, unsigned long delta) static void timer8_clock_event_start(struct timer8_priv *p, unsigned long delta)
{ {
struct clock_event_device *ced = &p->ced;
timer8_start(p); timer8_start(p);
ced->shift = 32;
ced->mult = div_sc(p->rate, NSEC_PER_SEC, ced->shift);
ced->max_delta_ns = clockevent_delta2ns(0xffff, ced);
ced->min_delta_ns = clockevent_delta2ns(0x0001, ced);
timer8_set_next(p, delta); timer8_set_next(p, delta);
} }
......
...@@ -133,13 +133,13 @@ static int __init meson6_timer_init(struct device_node *node) ...@@ -133,13 +133,13 @@ static int __init meson6_timer_init(struct device_node *node)
timer_base = of_io_request_and_map(node, 0, "meson6-timer"); timer_base = of_io_request_and_map(node, 0, "meson6-timer");
if (IS_ERR(timer_base)) { if (IS_ERR(timer_base)) {
pr_err("Can't map registers"); pr_err("Can't map registers\n");
return -ENXIO; return -ENXIO;
} }
irq = irq_of_parse_and_map(node, 0); irq = irq_of_parse_and_map(node, 0);
if (irq <= 0) { if (irq <= 0) {
pr_err("Can't parse IRQ"); pr_err("Can't parse IRQ\n");
return -EINVAL; return -EINVAL;
} }
......
...@@ -114,7 +114,9 @@ static int arch_timer_starting_cpu(unsigned int cpu) ...@@ -114,7 +114,9 @@ static int arch_timer_starting_cpu(unsigned int cpu)
clk->mult = div_sc(hwtimer_freq, NSEC_PER_SEC, clk->shift); clk->mult = div_sc(hwtimer_freq, NSEC_PER_SEC, clk->shift);
clk->max_delta_ns = clockevent_delta2ns(0x7fffffff, clk); clk->max_delta_ns = clockevent_delta2ns(0x7fffffff, clk);
clk->max_delta_ticks = 0x7fffffff;
clk->min_delta_ns = clockevent_delta2ns(0xf, clk); clk->min_delta_ns = clockevent_delta2ns(0xf, clk);
clk->min_delta_ticks = 0xf;
clk->cpumask = cpumask_of(cpu); clk->cpumask = cpumask_of(cpu);
clockevents_register_device(clk); clockevents_register_device(clk);
......
...@@ -154,19 +154,6 @@ static int __init __gic_clocksource_init(void) ...@@ -154,19 +154,6 @@ static int __init __gic_clocksource_init(void)
return ret; return ret;
} }
void __init gic_clocksource_init(unsigned int frequency)
{
gic_frequency = frequency;
gic_timer_irq = MIPS_GIC_IRQ_BASE +
GIC_LOCAL_TO_HWIRQ(GIC_LOCAL_INT_COMPARE);
__gic_clocksource_init();
gic_clockevent_init();
/* And finally start the counter */
gic_start_count();
}
static int __init gic_clocksource_of_init(struct device_node *node) static int __init gic_clocksource_of_init(struct device_node *node)
{ {
struct clk *clk; struct clk *clk;
...@@ -174,7 +161,7 @@ static int __init gic_clocksource_of_init(struct device_node *node) ...@@ -174,7 +161,7 @@ static int __init gic_clocksource_of_init(struct device_node *node)
if (!gic_present || !node->parent || if (!gic_present || !node->parent ||
!of_device_is_compatible(node->parent, "mti,gic")) { !of_device_is_compatible(node->parent, "mti,gic")) {
pr_warn("No DT definition for the mips gic driver"); pr_warn("No DT definition for the mips gic driver\n");
return -ENXIO; return -ENXIO;
} }
......
...@@ -260,25 +260,25 @@ static int __init nmdk_timer_of_init(struct device_node *node) ...@@ -260,25 +260,25 @@ static int __init nmdk_timer_of_init(struct device_node *node)
base = of_iomap(node, 0); base = of_iomap(node, 0);
if (!base) { if (!base) {
pr_err("Can't remap registers"); pr_err("Can't remap registers\n");
return -ENXIO; return -ENXIO;
} }
pclk = of_clk_get_by_name(node, "apb_pclk"); pclk = of_clk_get_by_name(node, "apb_pclk");
if (IS_ERR(pclk)) { if (IS_ERR(pclk)) {
pr_err("could not get apb_pclk"); pr_err("could not get apb_pclk\n");
return PTR_ERR(pclk); return PTR_ERR(pclk);
} }
clk = of_clk_get_by_name(node, "timclk"); clk = of_clk_get_by_name(node, "timclk");
if (IS_ERR(clk)) { if (IS_ERR(clk)) {
pr_err("could not get timclk"); pr_err("could not get timclk\n");
return PTR_ERR(clk); return PTR_ERR(clk);
} }
irq = irq_of_parse_and_map(node, 0); irq = irq_of_parse_and_map(node, 0);
if (irq <= 0) { if (irq <= 0) {
pr_err("Can't parse IRQ"); pr_err("Can't parse IRQ\n");
return -EINVAL; return -EINVAL;
} }
......
...@@ -51,7 +51,9 @@ static struct clock_event_device numachip2_clockevent = { ...@@ -51,7 +51,9 @@ static struct clock_event_device numachip2_clockevent = {
.mult = 1, .mult = 1,
.shift = 0, .shift = 0,
.min_delta_ns = 1250, .min_delta_ns = 1250,
.min_delta_ticks = 1250,
.max_delta_ns = LONG_MAX, .max_delta_ns = LONG_MAX,
.max_delta_ticks = LONG_MAX,
}; };
static void numachip_timer_interrupt(void) static void numachip_timer_interrupt(void)
......
...@@ -166,14 +166,14 @@ static int __init pxa_timer_common_init(int irq, unsigned long clock_tick_rate) ...@@ -166,14 +166,14 @@ static int __init pxa_timer_common_init(int irq, unsigned long clock_tick_rate)
ret = setup_irq(irq, &pxa_ost0_irq); ret = setup_irq(irq, &pxa_ost0_irq);
if (ret) { if (ret) {
pr_err("Failed to setup irq"); pr_err("Failed to setup irq\n");
return ret; return ret;
} }
ret = clocksource_mmio_init(timer_base + OSCR, "oscr0", clock_tick_rate, 200, ret = clocksource_mmio_init(timer_base + OSCR, "oscr0", clock_tick_rate, 200,
32, clocksource_mmio_readl_up); 32, clocksource_mmio_readl_up);
if (ret) { if (ret) {
pr_err("Failed to init clocksource"); pr_err("Failed to init clocksource\n");
return ret; return ret;
} }
...@@ -203,7 +203,7 @@ static int __init pxa_timer_dt_init(struct device_node *np) ...@@ -203,7 +203,7 @@ static int __init pxa_timer_dt_init(struct device_node *np)
ret = clk_prepare_enable(clk); ret = clk_prepare_enable(clk);
if (ret) { if (ret) {
pr_crit("Failed to prepare clock"); pr_crit("Failed to prepare clock\n");
return ret; return ret;
} }
......
...@@ -11,6 +11,8 @@ ...@@ -11,6 +11,8 @@
#include <linux/clockchips.h> #include <linux/clockchips.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/interrupt.h> #include <linux/interrupt.h>
#include <linux/sched_clock.h>
#include <linux/slab.h>
#include <linux/of.h> #include <linux/of.h>
#include <linux/of_address.h> #include <linux/of_address.h>
#include <linux/of_irq.h> #include <linux/of_irq.h>
...@@ -19,6 +21,8 @@ ...@@ -19,6 +21,8 @@
#define TIMER_LOAD_COUNT0 0x00 #define TIMER_LOAD_COUNT0 0x00
#define TIMER_LOAD_COUNT1 0x04 #define TIMER_LOAD_COUNT1 0x04
#define TIMER_CURRENT_VALUE0 0x08
#define TIMER_CURRENT_VALUE1 0x0C
#define TIMER_CONTROL_REG3288 0x10 #define TIMER_CONTROL_REG3288 0x10
#define TIMER_CONTROL_REG3399 0x1c #define TIMER_CONTROL_REG3399 0x1c
#define TIMER_INT_STATUS 0x18 #define TIMER_INT_STATUS 0x18
...@@ -29,103 +33,118 @@ ...@@ -29,103 +33,118 @@
#define TIMER_MODE_USER_DEFINED_COUNT (1 << 1) #define TIMER_MODE_USER_DEFINED_COUNT (1 << 1)
#define TIMER_INT_UNMASK (1 << 2) #define TIMER_INT_UNMASK (1 << 2)
struct bc_timer { struct rk_timer {
struct clock_event_device ce;
void __iomem *base; void __iomem *base;
void __iomem *ctrl; void __iomem *ctrl;
struct clk *clk;
struct clk *pclk;
u32 freq; u32 freq;
int irq;
}; };
static struct bc_timer bc_timer; struct rk_clkevt {
struct clock_event_device ce;
struct rk_timer timer;
};
static inline struct bc_timer *rk_timer(struct clock_event_device *ce) static struct rk_clkevt *rk_clkevt;
{ static struct rk_timer *rk_clksrc;
return container_of(ce, struct bc_timer, ce);
}
static inline void __iomem *rk_base(struct clock_event_device *ce) static inline struct rk_timer *rk_timer(struct clock_event_device *ce)
{ {
return rk_timer(ce)->base; return &container_of(ce, struct rk_clkevt, ce)->timer;
} }
static inline void __iomem *rk_ctrl(struct clock_event_device *ce) static inline void rk_timer_disable(struct rk_timer *timer)
{ {
return rk_timer(ce)->ctrl; writel_relaxed(TIMER_DISABLE, timer->ctrl);
} }
static inline void rk_timer_disable(struct clock_event_device *ce) static inline void rk_timer_enable(struct rk_timer *timer, u32 flags)
{ {
writel_relaxed(TIMER_DISABLE, rk_ctrl(ce)); writel_relaxed(TIMER_ENABLE | flags, timer->ctrl);
}
static inline void rk_timer_enable(struct clock_event_device *ce, u32 flags)
{
writel_relaxed(TIMER_ENABLE | TIMER_INT_UNMASK | flags,
rk_ctrl(ce));
} }
static void rk_timer_update_counter(unsigned long cycles, static void rk_timer_update_counter(unsigned long cycles,
struct clock_event_device *ce) struct rk_timer *timer)
{ {
writel_relaxed(cycles, rk_base(ce) + TIMER_LOAD_COUNT0); writel_relaxed(cycles, timer->base + TIMER_LOAD_COUNT0);
writel_relaxed(0, rk_base(ce) + TIMER_LOAD_COUNT1); writel_relaxed(0, timer->base + TIMER_LOAD_COUNT1);
} }
static void rk_timer_interrupt_clear(struct clock_event_device *ce) static void rk_timer_interrupt_clear(struct rk_timer *timer)
{ {
writel_relaxed(1, rk_base(ce) + TIMER_INT_STATUS); writel_relaxed(1, timer->base + TIMER_INT_STATUS);
} }
static inline int rk_timer_set_next_event(unsigned long cycles, static inline int rk_timer_set_next_event(unsigned long cycles,
struct clock_event_device *ce) struct clock_event_device *ce)
{ {
rk_timer_disable(ce); struct rk_timer *timer = rk_timer(ce);
rk_timer_update_counter(cycles, ce);
rk_timer_enable(ce, TIMER_MODE_USER_DEFINED_COUNT); rk_timer_disable(timer);
rk_timer_update_counter(cycles, timer);
rk_timer_enable(timer, TIMER_MODE_USER_DEFINED_COUNT |
TIMER_INT_UNMASK);
return 0; return 0;
} }
static int rk_timer_shutdown(struct clock_event_device *ce) static int rk_timer_shutdown(struct clock_event_device *ce)
{ {
rk_timer_disable(ce); struct rk_timer *timer = rk_timer(ce);
rk_timer_disable(timer);
return 0; return 0;
} }
static int rk_timer_set_periodic(struct clock_event_device *ce) static int rk_timer_set_periodic(struct clock_event_device *ce)
{ {
rk_timer_disable(ce); struct rk_timer *timer = rk_timer(ce);
rk_timer_update_counter(rk_timer(ce)->freq / HZ - 1, ce);
rk_timer_enable(ce, TIMER_MODE_FREE_RUNNING); rk_timer_disable(timer);
rk_timer_update_counter(timer->freq / HZ - 1, timer);
rk_timer_enable(timer, TIMER_MODE_FREE_RUNNING | TIMER_INT_UNMASK);
return 0; return 0;
} }
static irqreturn_t rk_timer_interrupt(int irq, void *dev_id) static irqreturn_t rk_timer_interrupt(int irq, void *dev_id)
{ {
struct clock_event_device *ce = dev_id; struct clock_event_device *ce = dev_id;
struct rk_timer *timer = rk_timer(ce);
rk_timer_interrupt_clear(ce); rk_timer_interrupt_clear(timer);
if (clockevent_state_oneshot(ce)) if (clockevent_state_oneshot(ce))
rk_timer_disable(ce); rk_timer_disable(timer);
ce->event_handler(ce); ce->event_handler(ce);
return IRQ_HANDLED; return IRQ_HANDLED;
} }
static int __init rk_timer_init(struct device_node *np, u32 ctrl_reg) static u64 notrace rk_timer_sched_read(void)
{
return ~readl_relaxed(rk_clksrc->base + TIMER_CURRENT_VALUE0);
}
static int __init
rk_timer_probe(struct rk_timer *timer, struct device_node *np)
{ {
struct clock_event_device *ce = &bc_timer.ce;
struct clk *timer_clk; struct clk *timer_clk;
struct clk *pclk; struct clk *pclk;
int ret = -EINVAL, irq; int ret = -EINVAL, irq;
u32 ctrl_reg = TIMER_CONTROL_REG3288;
bc_timer.base = of_iomap(np, 0); timer->base = of_iomap(np, 0);
if (!bc_timer.base) { if (!timer->base) {
pr_err("Failed to get base address for '%s'\n", TIMER_NAME); pr_err("Failed to get base address for '%s'\n", TIMER_NAME);
return -ENXIO; return -ENXIO;
} }
bc_timer.ctrl = bc_timer.base + ctrl_reg;
if (of_device_is_compatible(np, "rockchip,rk3399-timer"))
ctrl_reg = TIMER_CONTROL_REG3399;
timer->ctrl = timer->base + ctrl_reg;
pclk = of_clk_get_by_name(np, "pclk"); pclk = of_clk_get_by_name(np, "pclk");
if (IS_ERR(pclk)) { if (IS_ERR(pclk)) {
...@@ -139,6 +158,7 @@ static int __init rk_timer_init(struct device_node *np, u32 ctrl_reg) ...@@ -139,6 +158,7 @@ static int __init rk_timer_init(struct device_node *np, u32 ctrl_reg)
pr_err("Failed to enable pclk for '%s'\n", TIMER_NAME); pr_err("Failed to enable pclk for '%s'\n", TIMER_NAME);
goto out_unmap; goto out_unmap;
} }
timer->pclk = pclk;
timer_clk = of_clk_get_by_name(np, "timer"); timer_clk = of_clk_get_by_name(np, "timer");
if (IS_ERR(timer_clk)) { if (IS_ERR(timer_clk)) {
...@@ -152,8 +172,9 @@ static int __init rk_timer_init(struct device_node *np, u32 ctrl_reg) ...@@ -152,8 +172,9 @@ static int __init rk_timer_init(struct device_node *np, u32 ctrl_reg)
pr_err("Failed to enable timer clock\n"); pr_err("Failed to enable timer clock\n");
goto out_timer_clk; goto out_timer_clk;
} }
timer->clk = timer_clk;
bc_timer.freq = clk_get_rate(timer_clk); timer->freq = clk_get_rate(timer_clk);
irq = irq_of_parse_and_map(np, 0); irq = irq_of_parse_and_map(np, 0);
if (!irq) { if (!irq) {
...@@ -161,51 +182,126 @@ static int __init rk_timer_init(struct device_node *np, u32 ctrl_reg) ...@@ -161,51 +182,126 @@ static int __init rk_timer_init(struct device_node *np, u32 ctrl_reg)
pr_err("Failed to map interrupts for '%s'\n", TIMER_NAME); pr_err("Failed to map interrupts for '%s'\n", TIMER_NAME);
goto out_irq; goto out_irq;
} }
timer->irq = irq;
rk_timer_interrupt_clear(timer);
rk_timer_disable(timer);
return 0;
out_irq:
clk_disable_unprepare(timer_clk);
out_timer_clk:
clk_disable_unprepare(pclk);
out_unmap:
iounmap(timer->base);
return ret;
}
static void __init rk_timer_cleanup(struct rk_timer *timer)
{
clk_disable_unprepare(timer->clk);
clk_disable_unprepare(timer->pclk);
iounmap(timer->base);
}
static int __init rk_clkevt_init(struct device_node *np)
{
struct clock_event_device *ce;
int ret = -EINVAL;
rk_clkevt = kzalloc(sizeof(struct rk_clkevt), GFP_KERNEL);
if (!rk_clkevt) {
ret = -ENOMEM;
goto out;
}
ret = rk_timer_probe(&rk_clkevt->timer, np);
if (ret)
goto out_probe;
ce = &rk_clkevt->ce;
ce->name = TIMER_NAME; ce->name = TIMER_NAME;
ce->features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT | ce->features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT |
CLOCK_EVT_FEAT_DYNIRQ; CLOCK_EVT_FEAT_DYNIRQ;
ce->set_next_event = rk_timer_set_next_event; ce->set_next_event = rk_timer_set_next_event;
ce->set_state_shutdown = rk_timer_shutdown; ce->set_state_shutdown = rk_timer_shutdown;
ce->set_state_periodic = rk_timer_set_periodic; ce->set_state_periodic = rk_timer_set_periodic;
ce->irq = irq; ce->irq = rk_clkevt->timer.irq;
ce->cpumask = cpu_possible_mask; ce->cpumask = cpu_possible_mask;
ce->rating = 250; ce->rating = 250;
rk_timer_interrupt_clear(ce); ret = request_irq(rk_clkevt->timer.irq, rk_timer_interrupt, IRQF_TIMER,
rk_timer_disable(ce); TIMER_NAME, ce);
ret = request_irq(irq, rk_timer_interrupt, IRQF_TIMER, TIMER_NAME, ce);
if (ret) { if (ret) {
pr_err("Failed to initialize '%s': %d\n", TIMER_NAME, ret); pr_err("Failed to initialize '%s': %d\n",
TIMER_NAME, ret);
goto out_irq; goto out_irq;
} }
clockevents_config_and_register(ce, bc_timer.freq, 1, UINT_MAX); clockevents_config_and_register(&rk_clkevt->ce,
rk_clkevt->timer.freq, 1, UINT_MAX);
return 0; return 0;
out_irq: out_irq:
clk_disable_unprepare(timer_clk); rk_timer_cleanup(&rk_clkevt->timer);
out_timer_clk: out_probe:
clk_disable_unprepare(pclk); kfree(rk_clkevt);
out_unmap: out:
iounmap(bc_timer.base); /* Leave rk_clkevt not NULL to prevent future init */
rk_clkevt = ERR_PTR(ret);
return ret; return ret;
} }
static int __init rk3288_timer_init(struct device_node *np) static int __init rk_clksrc_init(struct device_node *np)
{ {
return rk_timer_init(np, TIMER_CONTROL_REG3288); int ret = -EINVAL;
rk_clksrc = kzalloc(sizeof(struct rk_timer), GFP_KERNEL);
if (!rk_clksrc) {
ret = -ENOMEM;
goto out;
}
ret = rk_timer_probe(rk_clksrc, np);
if (ret)
goto out_probe;
rk_timer_update_counter(UINT_MAX, rk_clksrc);
rk_timer_enable(rk_clksrc, 0);
ret = clocksource_mmio_init(rk_clksrc->base + TIMER_CURRENT_VALUE0,
TIMER_NAME, rk_clksrc->freq, 250, 32,
clocksource_mmio_readl_down);
if (ret) {
pr_err("Failed to register clocksource");
goto out_clocksource;
}
sched_clock_register(rk_timer_sched_read, 32, rk_clksrc->freq);
return 0;
out_clocksource:
rk_timer_cleanup(rk_clksrc);
out_probe:
kfree(rk_clksrc);
out:
/* Leave rk_clksrc not NULL to prevent future init */
rk_clksrc = ERR_PTR(ret);
return ret;
} }
static int __init rk3399_timer_init(struct device_node *np) static int __init rk_timer_init(struct device_node *np)
{ {
return rk_timer_init(np, TIMER_CONTROL_REG3399); if (!rk_clkevt)
return rk_clkevt_init(np);
if (!rk_clksrc)
return rk_clksrc_init(np);
pr_err("Too many timer definitions for '%s'\n", TIMER_NAME);
return -EINVAL;
} }
CLOCKSOURCE_OF_DECLARE(rk3288_timer, "rockchip,rk3288-timer", CLOCKSOURCE_OF_DECLARE(rk3288_timer, "rockchip,rk3288-timer", rk_timer_init);
rk3288_timer_init); CLOCKSOURCE_OF_DECLARE(rk3399_timer, "rockchip,rk3399-timer", rk_timer_init);
CLOCKSOURCE_OF_DECLARE(rk3399_timer, "rockchip,rk3399-timer",
rk3399_timer_init);
...@@ -385,7 +385,7 @@ static int __init _samsung_pwm_clocksource_init(void) ...@@ -385,7 +385,7 @@ static int __init _samsung_pwm_clocksource_init(void)
mask = ~pwm.variant.output_mask & ((1 << SAMSUNG_PWM_NUM) - 1); mask = ~pwm.variant.output_mask & ((1 << SAMSUNG_PWM_NUM) - 1);
channel = fls(mask) - 1; channel = fls(mask) - 1;
if (channel < 0) { if (channel < 0) {
pr_crit("failed to find PWM channel for clocksource"); pr_crit("failed to find PWM channel for clocksource\n");
return -EINVAL; return -EINVAL;
} }
pwm.source_id = channel; pwm.source_id = channel;
...@@ -393,7 +393,7 @@ static int __init _samsung_pwm_clocksource_init(void) ...@@ -393,7 +393,7 @@ static int __init _samsung_pwm_clocksource_init(void)
mask &= ~(1 << channel); mask &= ~(1 << channel);
channel = fls(mask) - 1; channel = fls(mask) - 1;
if (channel < 0) { if (channel < 0) {
pr_crit("failed to find PWM channel for clock event"); pr_crit("failed to find PWM channel for clock event\n");
return -EINVAL; return -EINVAL;
} }
pwm.event_id = channel; pwm.event_id = channel;
...@@ -448,7 +448,7 @@ static int __init samsung_pwm_alloc(struct device_node *np, ...@@ -448,7 +448,7 @@ static int __init samsung_pwm_alloc(struct device_node *np,
pwm.timerclk = of_clk_get_by_name(np, "timers"); pwm.timerclk = of_clk_get_by_name(np, "timers");
if (IS_ERR(pwm.timerclk)) { if (IS_ERR(pwm.timerclk)) {
pr_crit("failed to get timers clock for timer"); pr_crit("failed to get timers clock for timer\n");
return PTR_ERR(pwm.timerclk); return PTR_ERR(pwm.timerclk);
} }
......
...@@ -103,7 +103,6 @@ struct sh_cmt_channel { ...@@ -103,7 +103,6 @@ struct sh_cmt_channel {
unsigned long match_value; unsigned long match_value;
unsigned long next_match_value; unsigned long next_match_value;
unsigned long max_match_value; unsigned long max_match_value;
unsigned long rate;
raw_spinlock_t lock; raw_spinlock_t lock;
struct clock_event_device ced; struct clock_event_device ced;
struct clocksource cs; struct clocksource cs;
...@@ -118,6 +117,7 @@ struct sh_cmt_device { ...@@ -118,6 +117,7 @@ struct sh_cmt_device {
void __iomem *mapbase; void __iomem *mapbase;
struct clk *clk; struct clk *clk;
unsigned long rate;
raw_spinlock_t lock; /* Protect the shared start/stop register */ raw_spinlock_t lock; /* Protect the shared start/stop register */
...@@ -320,7 +320,7 @@ static void sh_cmt_start_stop_ch(struct sh_cmt_channel *ch, int start) ...@@ -320,7 +320,7 @@ static void sh_cmt_start_stop_ch(struct sh_cmt_channel *ch, int start)
raw_spin_unlock_irqrestore(&ch->cmt->lock, flags); raw_spin_unlock_irqrestore(&ch->cmt->lock, flags);
} }
static int sh_cmt_enable(struct sh_cmt_channel *ch, unsigned long *rate) static int sh_cmt_enable(struct sh_cmt_channel *ch)
{ {
int k, ret; int k, ret;
...@@ -340,11 +340,9 @@ static int sh_cmt_enable(struct sh_cmt_channel *ch, unsigned long *rate) ...@@ -340,11 +340,9 @@ static int sh_cmt_enable(struct sh_cmt_channel *ch, unsigned long *rate)
/* configure channel, periodic mode and maximum timeout */ /* configure channel, periodic mode and maximum timeout */
if (ch->cmt->info->width == 16) { if (ch->cmt->info->width == 16) {
*rate = clk_get_rate(ch->cmt->clk) / 512;
sh_cmt_write_cmcsr(ch, SH_CMT16_CMCSR_CMIE | sh_cmt_write_cmcsr(ch, SH_CMT16_CMCSR_CMIE |
SH_CMT16_CMCSR_CKS512); SH_CMT16_CMCSR_CKS512);
} else { } else {
*rate = clk_get_rate(ch->cmt->clk) / 8;
sh_cmt_write_cmcsr(ch, SH_CMT32_CMCSR_CMM | sh_cmt_write_cmcsr(ch, SH_CMT32_CMCSR_CMM |
SH_CMT32_CMCSR_CMTOUT_IE | SH_CMT32_CMCSR_CMTOUT_IE |
SH_CMT32_CMCSR_CMR_IRQ | SH_CMT32_CMCSR_CMR_IRQ |
...@@ -572,7 +570,7 @@ static int sh_cmt_start(struct sh_cmt_channel *ch, unsigned long flag) ...@@ -572,7 +570,7 @@ static int sh_cmt_start(struct sh_cmt_channel *ch, unsigned long flag)
raw_spin_lock_irqsave(&ch->lock, flags); raw_spin_lock_irqsave(&ch->lock, flags);
if (!(ch->flags & (FLAG_CLOCKEVENT | FLAG_CLOCKSOURCE))) if (!(ch->flags & (FLAG_CLOCKEVENT | FLAG_CLOCKSOURCE)))
ret = sh_cmt_enable(ch, &ch->rate); ret = sh_cmt_enable(ch);
if (ret) if (ret)
goto out; goto out;
...@@ -640,10 +638,9 @@ static int sh_cmt_clocksource_enable(struct clocksource *cs) ...@@ -640,10 +638,9 @@ static int sh_cmt_clocksource_enable(struct clocksource *cs)
ch->total_cycles = 0; ch->total_cycles = 0;
ret = sh_cmt_start(ch, FLAG_CLOCKSOURCE); ret = sh_cmt_start(ch, FLAG_CLOCKSOURCE);
if (!ret) { if (!ret)
__clocksource_update_freq_hz(cs, ch->rate);
ch->cs_enabled = true; ch->cs_enabled = true;
}
return ret; return ret;
} }
...@@ -697,8 +694,7 @@ static int sh_cmt_register_clocksource(struct sh_cmt_channel *ch, ...@@ -697,8 +694,7 @@ static int sh_cmt_register_clocksource(struct sh_cmt_channel *ch,
dev_info(&ch->cmt->pdev->dev, "ch%u: used as clock source\n", dev_info(&ch->cmt->pdev->dev, "ch%u: used as clock source\n",
ch->index); ch->index);
/* Register with dummy 1 Hz value, gets updated in ->enable() */ clocksource_register_hz(cs, ch->cmt->rate);
clocksource_register_hz(cs, 1);
return 0; return 0;
} }
...@@ -709,19 +705,10 @@ static struct sh_cmt_channel *ced_to_sh_cmt(struct clock_event_device *ced) ...@@ -709,19 +705,10 @@ static struct sh_cmt_channel *ced_to_sh_cmt(struct clock_event_device *ced)
static void sh_cmt_clock_event_start(struct sh_cmt_channel *ch, int periodic) static void sh_cmt_clock_event_start(struct sh_cmt_channel *ch, int periodic)
{ {
struct clock_event_device *ced = &ch->ced;
sh_cmt_start(ch, FLAG_CLOCKEVENT); sh_cmt_start(ch, FLAG_CLOCKEVENT);
/* TODO: calculate good shift from rate and counter bit width */
ced->shift = 32;
ced->mult = div_sc(ch->rate, NSEC_PER_SEC, ced->shift);
ced->max_delta_ns = clockevent_delta2ns(ch->max_match_value, ced);
ced->min_delta_ns = clockevent_delta2ns(0x1f, ced);
if (periodic) if (periodic)
sh_cmt_set_next(ch, ((ch->rate + HZ/2) / HZ) - 1); sh_cmt_set_next(ch, ((ch->cmt->rate + HZ/2) / HZ) - 1);
else else
sh_cmt_set_next(ch, ch->max_match_value); sh_cmt_set_next(ch, ch->max_match_value);
} }
...@@ -824,6 +811,14 @@ static int sh_cmt_register_clockevent(struct sh_cmt_channel *ch, ...@@ -824,6 +811,14 @@ static int sh_cmt_register_clockevent(struct sh_cmt_channel *ch,
ced->suspend = sh_cmt_clock_event_suspend; ced->suspend = sh_cmt_clock_event_suspend;
ced->resume = sh_cmt_clock_event_resume; ced->resume = sh_cmt_clock_event_resume;
/* TODO: calculate good shift from rate and counter bit width */
ced->shift = 32;
ced->mult = div_sc(ch->cmt->rate, NSEC_PER_SEC, ced->shift);
ced->max_delta_ns = clockevent_delta2ns(ch->max_match_value, ced);
ced->max_delta_ticks = ch->max_match_value;
ced->min_delta_ns = clockevent_delta2ns(0x1f, ced);
ced->min_delta_ticks = 0x1f;
dev_info(&ch->cmt->pdev->dev, "ch%u: used for clock events\n", dev_info(&ch->cmt->pdev->dev, "ch%u: used for clock events\n",
ch->index); ch->index);
clockevents_register_device(ced); clockevents_register_device(ced);
...@@ -996,6 +991,18 @@ static int sh_cmt_setup(struct sh_cmt_device *cmt, struct platform_device *pdev) ...@@ -996,6 +991,18 @@ static int sh_cmt_setup(struct sh_cmt_device *cmt, struct platform_device *pdev)
if (ret < 0) if (ret < 0)
goto err_clk_put; goto err_clk_put;
/* Determine clock rate. */
ret = clk_enable(cmt->clk);
if (ret < 0)
goto err_clk_unprepare;
if (cmt->info->width == 16)
cmt->rate = clk_get_rate(cmt->clk) / 512;
else
cmt->rate = clk_get_rate(cmt->clk) / 8;
clk_disable(cmt->clk);
/* Map the memory resource(s). */ /* Map the memory resource(s). */
ret = sh_cmt_map_memory(cmt); ret = sh_cmt_map_memory(cmt);
if (ret < 0) if (ret < 0)
......
...@@ -46,7 +46,6 @@ struct sh_tmu_channel { ...@@ -46,7 +46,6 @@ struct sh_tmu_channel {
void __iomem *base; void __iomem *base;
int irq; int irq;
unsigned long rate;
unsigned long periodic; unsigned long periodic;
struct clock_event_device ced; struct clock_event_device ced;
struct clocksource cs; struct clocksource cs;
...@@ -59,6 +58,7 @@ struct sh_tmu_device { ...@@ -59,6 +58,7 @@ struct sh_tmu_device {
void __iomem *mapbase; void __iomem *mapbase;
struct clk *clk; struct clk *clk;
unsigned long rate;
enum sh_tmu_model model; enum sh_tmu_model model;
...@@ -165,7 +165,6 @@ static int __sh_tmu_enable(struct sh_tmu_channel *ch) ...@@ -165,7 +165,6 @@ static int __sh_tmu_enable(struct sh_tmu_channel *ch)
sh_tmu_write(ch, TCNT, 0xffffffff); sh_tmu_write(ch, TCNT, 0xffffffff);
/* configure channel to parent clock / 4, irq off */ /* configure channel to parent clock / 4, irq off */
ch->rate = clk_get_rate(ch->tmu->clk) / 4;
sh_tmu_write(ch, TCR, TCR_TPSC_CLK4); sh_tmu_write(ch, TCR, TCR_TPSC_CLK4);
/* enable channel */ /* enable channel */
...@@ -271,10 +270,8 @@ static int sh_tmu_clocksource_enable(struct clocksource *cs) ...@@ -271,10 +270,8 @@ static int sh_tmu_clocksource_enable(struct clocksource *cs)
return 0; return 0;
ret = sh_tmu_enable(ch); ret = sh_tmu_enable(ch);
if (!ret) { if (!ret)
__clocksource_update_freq_hz(cs, ch->rate);
ch->cs_enabled = true; ch->cs_enabled = true;
}
return ret; return ret;
} }
...@@ -334,8 +331,7 @@ static int sh_tmu_register_clocksource(struct sh_tmu_channel *ch, ...@@ -334,8 +331,7 @@ static int sh_tmu_register_clocksource(struct sh_tmu_channel *ch,
dev_info(&ch->tmu->pdev->dev, "ch%u: used as clock source\n", dev_info(&ch->tmu->pdev->dev, "ch%u: used as clock source\n",
ch->index); ch->index);
/* Register with dummy 1 Hz value, gets updated in ->enable() */ clocksource_register_hz(cs, ch->tmu->rate);
clocksource_register_hz(cs, 1);
return 0; return 0;
} }
...@@ -346,14 +342,10 @@ static struct sh_tmu_channel *ced_to_sh_tmu(struct clock_event_device *ced) ...@@ -346,14 +342,10 @@ static struct sh_tmu_channel *ced_to_sh_tmu(struct clock_event_device *ced)
static void sh_tmu_clock_event_start(struct sh_tmu_channel *ch, int periodic) static void sh_tmu_clock_event_start(struct sh_tmu_channel *ch, int periodic)
{ {
struct clock_event_device *ced = &ch->ced;
sh_tmu_enable(ch); sh_tmu_enable(ch);
clockevents_config(ced, ch->rate);
if (periodic) { if (periodic) {
ch->periodic = (ch->rate + HZ/2) / HZ; ch->periodic = (ch->tmu->rate + HZ/2) / HZ;
sh_tmu_set_next(ch, ch->periodic, 1); sh_tmu_set_next(ch, ch->periodic, 1);
} }
} }
...@@ -435,7 +427,7 @@ static void sh_tmu_register_clockevent(struct sh_tmu_channel *ch, ...@@ -435,7 +427,7 @@ static void sh_tmu_register_clockevent(struct sh_tmu_channel *ch,
dev_info(&ch->tmu->pdev->dev, "ch%u: used for clock events\n", dev_info(&ch->tmu->pdev->dev, "ch%u: used for clock events\n",
ch->index); ch->index);
clockevents_config_and_register(ced, 1, 0x300, 0xffffffff); clockevents_config_and_register(ced, ch->tmu->rate, 0x300, 0xffffffff);
ret = request_irq(ch->irq, sh_tmu_interrupt, ret = request_irq(ch->irq, sh_tmu_interrupt,
IRQF_TIMER | IRQF_IRQPOLL | IRQF_NOBALANCING, IRQF_TIMER | IRQF_IRQPOLL | IRQF_NOBALANCING,
...@@ -561,6 +553,14 @@ static int sh_tmu_setup(struct sh_tmu_device *tmu, struct platform_device *pdev) ...@@ -561,6 +553,14 @@ static int sh_tmu_setup(struct sh_tmu_device *tmu, struct platform_device *pdev)
if (ret < 0) if (ret < 0)
goto err_clk_put; goto err_clk_put;
/* Determine clock rate. */
ret = clk_enable(tmu->clk);
if (ret < 0)
goto err_clk_unprepare;
tmu->rate = clk_get_rate(tmu->clk) / 4;
clk_disable(tmu->clk);
/* Map the memory resource. */ /* Map the memory resource. */
ret = sh_tmu_map_memory(tmu); ret = sh_tmu_map_memory(tmu);
if (ret < 0) { if (ret < 0) {
......
...@@ -159,25 +159,25 @@ static int __init sun4i_timer_init(struct device_node *node) ...@@ -159,25 +159,25 @@ static int __init sun4i_timer_init(struct device_node *node)
timer_base = of_iomap(node, 0); timer_base = of_iomap(node, 0);
if (!timer_base) { if (!timer_base) {
pr_crit("Can't map registers"); pr_crit("Can't map registers\n");
return -ENXIO; return -ENXIO;
} }
irq = irq_of_parse_and_map(node, 0); irq = irq_of_parse_and_map(node, 0);
if (irq <= 0) { if (irq <= 0) {
pr_crit("Can't parse IRQ"); pr_crit("Can't parse IRQ\n");
return -EINVAL; return -EINVAL;
} }
clk = of_clk_get(node, 0); clk = of_clk_get(node, 0);
if (IS_ERR(clk)) { if (IS_ERR(clk)) {
pr_crit("Can't get timer clock"); pr_crit("Can't get timer clock\n");
return PTR_ERR(clk); return PTR_ERR(clk);
} }
ret = clk_prepare_enable(clk); ret = clk_prepare_enable(clk);
if (ret) { if (ret) {
pr_err("Failed to prepare clock"); pr_err("Failed to prepare clock\n");
return ret; return ret;
} }
...@@ -200,7 +200,7 @@ static int __init sun4i_timer_init(struct device_node *node) ...@@ -200,7 +200,7 @@ static int __init sun4i_timer_init(struct device_node *node)
ret = clocksource_mmio_init(timer_base + TIMER_CNTVAL_REG(1), node->name, ret = clocksource_mmio_init(timer_base + TIMER_CNTVAL_REG(1), node->name,
rate, 350, 32, clocksource_mmio_readl_down); rate, 350, 32, clocksource_mmio_readl_down);
if (ret) { if (ret) {
pr_err("Failed to register clocksource"); pr_err("Failed to register clocksource\n");
return ret; return ret;
} }
......
...@@ -245,7 +245,7 @@ static int __init tegra20_init_rtc(struct device_node *np) ...@@ -245,7 +245,7 @@ static int __init tegra20_init_rtc(struct device_node *np)
rtc_base = of_iomap(np, 0); rtc_base = of_iomap(np, 0);
if (!rtc_base) { if (!rtc_base) {
pr_err("Can't map RTC registers"); pr_err("Can't map RTC registers\n");
return -ENXIO; return -ENXIO;
} }
......
...@@ -247,13 +247,13 @@ static int __init armada_370_xp_timer_common_init(struct device_node *np) ...@@ -247,13 +247,13 @@ static int __init armada_370_xp_timer_common_init(struct device_node *np)
timer_base = of_iomap(np, 0); timer_base = of_iomap(np, 0);
if (!timer_base) { if (!timer_base) {
pr_err("Failed to iomap"); pr_err("Failed to iomap\n");
return -ENXIO; return -ENXIO;
} }
local_base = of_iomap(np, 1); local_base = of_iomap(np, 1);
if (!local_base) { if (!local_base) {
pr_err("Failed to iomap"); pr_err("Failed to iomap\n");
return -ENXIO; return -ENXIO;
} }
...@@ -298,7 +298,7 @@ static int __init armada_370_xp_timer_common_init(struct device_node *np) ...@@ -298,7 +298,7 @@ static int __init armada_370_xp_timer_common_init(struct device_node *np)
"armada_370_xp_clocksource", "armada_370_xp_clocksource",
timer_clk, 300, 32, clocksource_mmio_readl_down); timer_clk, 300, 32, clocksource_mmio_readl_down);
if (res) { if (res) {
pr_err("Failed to initialize clocksource mmio"); pr_err("Failed to initialize clocksource mmio\n");
return res; return res;
} }
...@@ -315,7 +315,7 @@ static int __init armada_370_xp_timer_common_init(struct device_node *np) ...@@ -315,7 +315,7 @@ static int __init armada_370_xp_timer_common_init(struct device_node *np)
armada_370_xp_evt); armada_370_xp_evt);
/* Immediately configure the timer on the boot CPU */ /* Immediately configure the timer on the boot CPU */
if (res) { if (res) {
pr_err("Failed to request percpu irq"); pr_err("Failed to request percpu irq\n");
return res; return res;
} }
...@@ -324,7 +324,7 @@ static int __init armada_370_xp_timer_common_init(struct device_node *np) ...@@ -324,7 +324,7 @@ static int __init armada_370_xp_timer_common_init(struct device_node *np)
armada_370_xp_timer_starting_cpu, armada_370_xp_timer_starting_cpu,
armada_370_xp_timer_dying_cpu); armada_370_xp_timer_dying_cpu);
if (res) { if (res) {
pr_err("Failed to setup hotplug state and timer"); pr_err("Failed to setup hotplug state and timer\n");
return res; return res;
} }
...@@ -339,7 +339,7 @@ static int __init armada_xp_timer_init(struct device_node *np) ...@@ -339,7 +339,7 @@ static int __init armada_xp_timer_init(struct device_node *np)
int ret; int ret;
if (IS_ERR(clk)) { if (IS_ERR(clk)) {
pr_err("Failed to get clock"); pr_err("Failed to get clock\n");
return PTR_ERR(clk); return PTR_ERR(clk);
} }
...@@ -375,7 +375,7 @@ static int __init armada_375_timer_init(struct device_node *np) ...@@ -375,7 +375,7 @@ static int __init armada_375_timer_init(struct device_node *np)
/* Must have at least a clock */ /* Must have at least a clock */
if (IS_ERR(clk)) { if (IS_ERR(clk)) {
pr_err("Failed to get clock"); pr_err("Failed to get clock\n");
return PTR_ERR(clk); return PTR_ERR(clk);
} }
...@@ -399,7 +399,7 @@ static int __init armada_370_timer_init(struct device_node *np) ...@@ -399,7 +399,7 @@ static int __init armada_370_timer_init(struct device_node *np)
clk = of_clk_get(np, 0); clk = of_clk_get(np, 0);
if (IS_ERR(clk)) { if (IS_ERR(clk)) {
pr_err("Failed to get clock"); pr_err("Failed to get clock\n");
return PTR_ERR(clk); return PTR_ERR(clk);
} }
......
...@@ -235,7 +235,7 @@ static int __init efm32_clockevent_init(struct device_node *np) ...@@ -235,7 +235,7 @@ static int __init efm32_clockevent_init(struct device_node *np)
ret = setup_irq(irq, &efm32_clock_event_irq); ret = setup_irq(irq, &efm32_clock_event_irq);
if (ret) { if (ret) {
pr_err("Failed setup irq"); pr_err("Failed setup irq\n");
goto err_setup_irq; goto err_setup_irq;
} }
......
...@@ -15,6 +15,7 @@ ...@@ -15,6 +15,7 @@
#include <linux/bitops.h> #include <linux/bitops.h>
#include <linux/clk.h> #include <linux/clk.h>
#include <linux/clockchips.h> #include <linux/clockchips.h>
#include <linux/delay.h>
#include <linux/interrupt.h> #include <linux/interrupt.h>
#include <linux/of_address.h> #include <linux/of_address.h>
#include <linux/of_irq.h> #include <linux/of_irq.h>
...@@ -36,6 +37,21 @@ ...@@ -36,6 +37,21 @@
static void __iomem *timer_base; static void __iomem *timer_base;
static unsigned long notrace orion_read_timer(void)
{
return ~readl(timer_base + TIMER0_VAL);
}
static struct delay_timer orion_delay_timer = {
.read_current_timer = orion_read_timer,
};
static void orion_delay_timer_init(unsigned long rate)
{
orion_delay_timer.freq = rate;
register_current_timer_delay(&orion_delay_timer);
}
/* /*
* Free-running clocksource handling. * Free-running clocksource handling.
*/ */
...@@ -106,6 +122,7 @@ static struct irqaction orion_clkevt_irq = { ...@@ -106,6 +122,7 @@ static struct irqaction orion_clkevt_irq = {
static int __init orion_timer_init(struct device_node *np) static int __init orion_timer_init(struct device_node *np)
{ {
unsigned long rate;
struct clk *clk; struct clk *clk;
int irq, ret; int irq, ret;
...@@ -124,7 +141,7 @@ static int __init orion_timer_init(struct device_node *np) ...@@ -124,7 +141,7 @@ static int __init orion_timer_init(struct device_node *np)
ret = clk_prepare_enable(clk); ret = clk_prepare_enable(clk);
if (ret) { if (ret) {
pr_err("Failed to prepare clock"); pr_err("Failed to prepare clock\n");
return ret; return ret;
} }
...@@ -135,6 +152,8 @@ static int __init orion_timer_init(struct device_node *np) ...@@ -135,6 +152,8 @@ static int __init orion_timer_init(struct device_node *np)
return -EINVAL; return -EINVAL;
} }
rate = clk_get_rate(clk);
/* setup timer0 as free-running clocksource */ /* setup timer0 as free-running clocksource */
writel(~0, timer_base + TIMER0_VAL); writel(~0, timer_base + TIMER0_VAL);
writel(~0, timer_base + TIMER0_RELOAD); writel(~0, timer_base + TIMER0_RELOAD);
...@@ -142,15 +161,15 @@ static int __init orion_timer_init(struct device_node *np) ...@@ -142,15 +161,15 @@ static int __init orion_timer_init(struct device_node *np)
TIMER0_RELOAD_EN | TIMER0_EN, TIMER0_RELOAD_EN | TIMER0_EN,
TIMER0_RELOAD_EN | TIMER0_EN); TIMER0_RELOAD_EN | TIMER0_EN);
ret = clocksource_mmio_init(timer_base + TIMER0_VAL, "orion_clocksource", ret = clocksource_mmio_init(timer_base + TIMER0_VAL,
clk_get_rate(clk), 300, 32, "orion_clocksource", rate, 300, 32,
clocksource_mmio_readl_down); clocksource_mmio_readl_down);
if (ret) { if (ret) {
pr_err("Failed to initialize mmio timer"); pr_err("Failed to initialize mmio timer\n");
return ret; return ret;
} }
sched_clock_register(orion_read_sched_clock, 32, clk_get_rate(clk)); sched_clock_register(orion_read_sched_clock, 32, rate);
/* setup timer1 as clockevent timer */ /* setup timer1 as clockevent timer */
ret = setup_irq(irq, &orion_clkevt_irq); ret = setup_irq(irq, &orion_clkevt_irq);
...@@ -162,9 +181,12 @@ static int __init orion_timer_init(struct device_node *np) ...@@ -162,9 +181,12 @@ static int __init orion_timer_init(struct device_node *np)
ticks_per_jiffy = (clk_get_rate(clk) + HZ/2) / HZ; ticks_per_jiffy = (clk_get_rate(clk) + HZ/2) / HZ;
orion_clkevt.cpumask = cpumask_of(0); orion_clkevt.cpumask = cpumask_of(0);
orion_clkevt.irq = irq; orion_clkevt.irq = irq;
clockevents_config_and_register(&orion_clkevt, clk_get_rate(clk), clockevents_config_and_register(&orion_clkevt, rate,
ORION_ONESHOT_MIN, ORION_ONESHOT_MAX); ORION_ONESHOT_MIN, ORION_ONESHOT_MAX);
orion_delay_timer_init(rate);
return 0; return 0;
} }
CLOCKSOURCE_OF_DECLARE(orion_timer, "marvell,orion-timer", orion_timer_init); CLOCKSOURCE_OF_DECLARE(orion_timer, "marvell,orion-timer", orion_timer_init);
...@@ -192,7 +192,9 @@ static int sirfsoc_local_timer_starting_cpu(unsigned int cpu) ...@@ -192,7 +192,9 @@ static int sirfsoc_local_timer_starting_cpu(unsigned int cpu)
ce->set_next_event = sirfsoc_timer_set_next_event; ce->set_next_event = sirfsoc_timer_set_next_event;
clockevents_calc_mult_shift(ce, atlas7_timer_rate, 60); clockevents_calc_mult_shift(ce, atlas7_timer_rate, 60);
ce->max_delta_ns = clockevent_delta2ns(-2, ce); ce->max_delta_ns = clockevent_delta2ns(-2, ce);
ce->max_delta_ticks = (unsigned long)-2;
ce->min_delta_ns = clockevent_delta2ns(2, ce); ce->min_delta_ns = clockevent_delta2ns(2, ce);
ce->min_delta_ticks = 2;
ce->cpumask = cpumask_of(cpu); ce->cpumask = cpumask_of(cpu);
action->dev_id = ce; action->dev_id = ce;
......
...@@ -226,7 +226,7 @@ static int __init at91sam926x_pit_dt_init(struct device_node *node) ...@@ -226,7 +226,7 @@ static int __init at91sam926x_pit_dt_init(struct device_node *node)
ret = clocksource_register_hz(&data->clksrc, pit_rate); ret = clocksource_register_hz(&data->clksrc, pit_rate);
if (ret) { if (ret) {
pr_err("Failed to register clocksource"); pr_err("Failed to register clocksource\n");
return ret; return ret;
} }
......
...@@ -161,19 +161,19 @@ static int __init digicolor_timer_init(struct device_node *node) ...@@ -161,19 +161,19 @@ static int __init digicolor_timer_init(struct device_node *node)
*/ */
dc_timer_dev.base = of_iomap(node, 0); dc_timer_dev.base = of_iomap(node, 0);
if (!dc_timer_dev.base) { if (!dc_timer_dev.base) {
pr_err("Can't map registers"); pr_err("Can't map registers\n");
return -ENXIO; return -ENXIO;
} }
irq = irq_of_parse_and_map(node, dc_timer_dev.timer_id); irq = irq_of_parse_and_map(node, dc_timer_dev.timer_id);
if (irq <= 0) { if (irq <= 0) {
pr_err("Can't parse IRQ"); pr_err("Can't parse IRQ\n");
return -EINVAL; return -EINVAL;
} }
clk = of_clk_get(node, 0); clk = of_clk_get(node, 0);
if (IS_ERR(clk)) { if (IS_ERR(clk)) {
pr_err("Can't get timer clock"); pr_err("Can't get timer clock\n");
return PTR_ERR(clk); return PTR_ERR(clk);
} }
clk_prepare_enable(clk); clk_prepare_enable(clk);
......
/* /*
* Gemini timer driver * Faraday Technology FTTMR010 timer driver
* Copyright (C) 2017 Linus Walleij <linus.walleij@linaro.org> * Copyright (C) 2017 Linus Walleij <linus.walleij@linaro.org>
* *
* Based on a rewrite of arch/arm/mach-gemini/timer.c: * Based on a rewrite of arch/arm/mach-gemini/timer.c:
...@@ -16,17 +16,7 @@ ...@@ -16,17 +16,7 @@
#include <linux/clockchips.h> #include <linux/clockchips.h>
#include <linux/clocksource.h> #include <linux/clocksource.h>
#include <linux/sched_clock.h> #include <linux/sched_clock.h>
#include <linux/clk.h>
/*
* Relevant registers in the global syscon
*/
#define GLOBAL_STATUS 0x04
#define CPU_AHB_RATIO_MASK (0x3 << 18)
#define CPU_AHB_1_1 (0x0 << 18)
#define CPU_AHB_3_2 (0x1 << 18)
#define CPU_AHB_24_13 (0x2 << 18)
#define CPU_AHB_2_1 (0x3 << 18)
#define REG_TO_AHB_SPEED(reg) ((((reg) >> 15) & 0x7) * 10 + 130)
/* /*
* Register definitions for the timers * Register definitions for the timers
...@@ -77,12 +67,12 @@ ...@@ -77,12 +67,12 @@
static unsigned int tick_rate; static unsigned int tick_rate;
static void __iomem *base; static void __iomem *base;
static u64 notrace gemini_read_sched_clock(void) static u64 notrace fttmr010_read_sched_clock(void)
{ {
return readl(base + TIMER3_COUNT); return readl(base + TIMER3_COUNT);
} }
static int gemini_timer_set_next_event(unsigned long cycles, static int fttmr010_timer_set_next_event(unsigned long cycles,
struct clock_event_device *evt) struct clock_event_device *evt)
{ {
u32 cr; u32 cr;
...@@ -96,7 +86,7 @@ static int gemini_timer_set_next_event(unsigned long cycles, ...@@ -96,7 +86,7 @@ static int gemini_timer_set_next_event(unsigned long cycles,
return 0; return 0;
} }
static int gemini_timer_shutdown(struct clock_event_device *evt) static int fttmr010_timer_shutdown(struct clock_event_device *evt)
{ {
u32 cr; u32 cr;
...@@ -127,7 +117,7 @@ static int gemini_timer_shutdown(struct clock_event_device *evt) ...@@ -127,7 +117,7 @@ static int gemini_timer_shutdown(struct clock_event_device *evt)
return 0; return 0;
} }
static int gemini_timer_set_periodic(struct clock_event_device *evt) static int fttmr010_timer_set_periodic(struct clock_event_device *evt)
{ {
u32 period = DIV_ROUND_CLOSEST(tick_rate, HZ); u32 period = DIV_ROUND_CLOSEST(tick_rate, HZ);
u32 cr; u32 cr;
...@@ -158,54 +148,40 @@ static int gemini_timer_set_periodic(struct clock_event_device *evt) ...@@ -158,54 +148,40 @@ static int gemini_timer_set_periodic(struct clock_event_device *evt)
} }
/* Use TIMER1 as clock event */ /* Use TIMER1 as clock event */
static struct clock_event_device gemini_clockevent = { static struct clock_event_device fttmr010_clockevent = {
.name = "TIMER1", .name = "TIMER1",
/* Reasonably fast and accurate clock event */ /* Reasonably fast and accurate clock event */
.rating = 300, .rating = 300,
.shift = 32, .shift = 32,
.features = CLOCK_EVT_FEAT_PERIODIC | .features = CLOCK_EVT_FEAT_PERIODIC |
CLOCK_EVT_FEAT_ONESHOT, CLOCK_EVT_FEAT_ONESHOT,
.set_next_event = gemini_timer_set_next_event, .set_next_event = fttmr010_timer_set_next_event,
.set_state_shutdown = gemini_timer_shutdown, .set_state_shutdown = fttmr010_timer_shutdown,
.set_state_periodic = gemini_timer_set_periodic, .set_state_periodic = fttmr010_timer_set_periodic,
.set_state_oneshot = gemini_timer_shutdown, .set_state_oneshot = fttmr010_timer_shutdown,
.tick_resume = gemini_timer_shutdown, .tick_resume = fttmr010_timer_shutdown,
}; };
/* /*
* IRQ handler for the timer * IRQ handler for the timer
*/ */
static irqreturn_t gemini_timer_interrupt(int irq, void *dev_id) static irqreturn_t fttmr010_timer_interrupt(int irq, void *dev_id)
{ {
struct clock_event_device *evt = &gemini_clockevent; struct clock_event_device *evt = &fttmr010_clockevent;
evt->event_handler(evt); evt->event_handler(evt);
return IRQ_HANDLED; return IRQ_HANDLED;
} }
static struct irqaction gemini_timer_irq = { static struct irqaction fttmr010_timer_irq = {
.name = "Gemini Timer Tick", .name = "Faraday FTTMR010 Timer Tick",
.flags = IRQF_TIMER, .flags = IRQF_TIMER,
.handler = gemini_timer_interrupt, .handler = fttmr010_timer_interrupt,
}; };
static int __init gemini_timer_of_init(struct device_node *np) static int __init fttmr010_timer_common_init(struct device_node *np)
{ {
static struct regmap *map;
int irq; int irq;
int ret;
u32 val;
map = syscon_regmap_lookup_by_phandle(np, "syscon");
if (IS_ERR(map)) {
pr_err("Can't get regmap for syscon handle");
return -ENODEV;
}
ret = regmap_read(map, GLOBAL_STATUS, &val);
if (ret) {
pr_err("Can't read syscon status register");
return -ENXIO;
}
base = of_iomap(np, 0); base = of_iomap(np, 0);
if (!base) { if (!base) {
...@@ -219,26 +195,6 @@ static int __init gemini_timer_of_init(struct device_node *np) ...@@ -219,26 +195,6 @@ static int __init gemini_timer_of_init(struct device_node *np)
return -EINVAL; return -EINVAL;
} }
tick_rate = REG_TO_AHB_SPEED(val) * 1000000;
printk(KERN_INFO "Bus: %dMHz", tick_rate / 1000000);
tick_rate /= 6; /* APB bus run AHB*(1/6) */
switch (val & CPU_AHB_RATIO_MASK) {
case CPU_AHB_1_1:
printk(KERN_CONT "(1/1)\n");
break;
case CPU_AHB_3_2:
printk(KERN_CONT "(3/2)\n");
break;
case CPU_AHB_24_13:
printk(KERN_CONT "(24/13)\n");
break;
case CPU_AHB_2_1:
printk(KERN_CONT "(2/1)\n");
break;
}
/* /*
* Reset the interrupt mask and status * Reset the interrupt mask and status
*/ */
...@@ -255,9 +211,9 @@ static int __init gemini_timer_of_init(struct device_node *np) ...@@ -255,9 +211,9 @@ static int __init gemini_timer_of_init(struct device_node *np)
writel(0, base + TIMER3_MATCH1); writel(0, base + TIMER3_MATCH1);
writel(0, base + TIMER3_MATCH2); writel(0, base + TIMER3_MATCH2);
clocksource_mmio_init(base + TIMER3_COUNT, clocksource_mmio_init(base + TIMER3_COUNT,
"gemini_clocksource", tick_rate, "fttmr010_clocksource", tick_rate,
300, 32, clocksource_mmio_readl_up); 300, 32, clocksource_mmio_readl_up);
sched_clock_register(gemini_read_sched_clock, 32, tick_rate); sched_clock_register(fttmr010_read_sched_clock, 32, tick_rate);
/* /*
* Setup clockevent timer (interrupt-driven.) * Setup clockevent timer (interrupt-driven.)
...@@ -266,12 +222,82 @@ static int __init gemini_timer_of_init(struct device_node *np) ...@@ -266,12 +222,82 @@ static int __init gemini_timer_of_init(struct device_node *np)
writel(0, base + TIMER1_LOAD); writel(0, base + TIMER1_LOAD);
writel(0, base + TIMER1_MATCH1); writel(0, base + TIMER1_MATCH1);
writel(0, base + TIMER1_MATCH2); writel(0, base + TIMER1_MATCH2);
setup_irq(irq, &gemini_timer_irq); setup_irq(irq, &fttmr010_timer_irq);
gemini_clockevent.cpumask = cpumask_of(0); fttmr010_clockevent.cpumask = cpumask_of(0);
clockevents_config_and_register(&gemini_clockevent, tick_rate, clockevents_config_and_register(&fttmr010_clockevent, tick_rate,
1, 0xffffffff); 1, 0xffffffff);
return 0; return 0;
} }
CLOCKSOURCE_OF_DECLARE(nomadik_mtu, "cortina,gemini-timer",
gemini_timer_of_init); static int __init fttmr010_timer_of_init(struct device_node *np)
{
/*
* These implementations require a clock reference.
* FIXME: we currently only support clocking using PCLK
* and using EXTCLK is not supported in the driver.
*/
struct clk *clk;
clk = of_clk_get_by_name(np, "PCLK");
if (IS_ERR(clk)) {
pr_err("could not get PCLK");
return PTR_ERR(clk);
}
tick_rate = clk_get_rate(clk);
return fttmr010_timer_common_init(np);
}
CLOCKSOURCE_OF_DECLARE(fttmr010, "faraday,fttmr010", fttmr010_timer_of_init);
/*
* Gemini-specific: relevant registers in the global syscon
*/
#define GLOBAL_STATUS 0x04
#define CPU_AHB_RATIO_MASK (0x3 << 18)
#define CPU_AHB_1_1 (0x0 << 18)
#define CPU_AHB_3_2 (0x1 << 18)
#define CPU_AHB_24_13 (0x2 << 18)
#define CPU_AHB_2_1 (0x3 << 18)
#define REG_TO_AHB_SPEED(reg) ((((reg) >> 15) & 0x7) * 10 + 130)
static int __init gemini_timer_of_init(struct device_node *np)
{
static struct regmap *map;
int ret;
u32 val;
map = syscon_regmap_lookup_by_phandle(np, "syscon");
if (IS_ERR(map)) {
pr_err("Can't get regmap for syscon handle\n");
return -ENODEV;
}
ret = regmap_read(map, GLOBAL_STATUS, &val);
if (ret) {
pr_err("Can't read syscon status register\n");
return -ENXIO;
}
tick_rate = REG_TO_AHB_SPEED(val) * 1000000;
pr_info("Bus: %dMHz ", tick_rate / 1000000);
tick_rate /= 6; /* APB bus run AHB*(1/6) */
switch (val & CPU_AHB_RATIO_MASK) {
case CPU_AHB_1_1:
pr_cont("(1/1)\n");
break;
case CPU_AHB_3_2:
pr_cont("(3/2)\n");
break;
case CPU_AHB_24_13:
pr_cont("(24/13)\n");
break;
case CPU_AHB_2_1:
pr_cont("(2/1)\n");
break;
}
return fttmr010_timer_common_init(np);
}
CLOCKSOURCE_OF_DECLARE(gemini, "cortina,gemini-timer", gemini_timer_of_init);
...@@ -200,7 +200,7 @@ static int __init integrator_ap_timer_init_of(struct device_node *node) ...@@ -200,7 +200,7 @@ static int __init integrator_ap_timer_init_of(struct device_node *node)
err = of_property_read_string(of_aliases, err = of_property_read_string(of_aliases,
"arm,timer-primary", &path); "arm,timer-primary", &path);
if (err) { if (err) {
pr_warn("Failed to read property"); pr_warn("Failed to read property\n");
return err; return err;
} }
...@@ -209,7 +209,7 @@ static int __init integrator_ap_timer_init_of(struct device_node *node) ...@@ -209,7 +209,7 @@ static int __init integrator_ap_timer_init_of(struct device_node *node)
err = of_property_read_string(of_aliases, err = of_property_read_string(of_aliases,
"arm,timer-secondary", &path); "arm,timer-secondary", &path);
if (err) { if (err) {
pr_warn("Failed to read property"); pr_warn("Failed to read property\n");
return err; return err;
} }
......
...@@ -55,7 +55,7 @@ static int __init nps_get_timer_clk(struct device_node *node, ...@@ -55,7 +55,7 @@ static int __init nps_get_timer_clk(struct device_node *node,
*clk = of_clk_get(node, 0); *clk = of_clk_get(node, 0);
ret = PTR_ERR_OR_ZERO(*clk); ret = PTR_ERR_OR_ZERO(*clk);
if (ret) { if (ret) {
pr_err("timer missing clk"); pr_err("timer missing clk\n");
return ret; return ret;
} }
...@@ -247,7 +247,7 @@ static int __init nps_setup_clockevent(struct device_node *node) ...@@ -247,7 +247,7 @@ static int __init nps_setup_clockevent(struct device_node *node)
nps_timer0_irq = irq_of_parse_and_map(node, 0); nps_timer0_irq = irq_of_parse_and_map(node, 0);
if (nps_timer0_irq <= 0) { if (nps_timer0_irq <= 0) {
pr_err("clockevent: missing irq"); pr_err("clockevent: missing irq\n");
return -EINVAL; return -EINVAL;
} }
...@@ -270,7 +270,7 @@ static int __init nps_setup_clockevent(struct device_node *node) ...@@ -270,7 +270,7 @@ static int __init nps_setup_clockevent(struct device_node *node)
nps_timer_starting_cpu, nps_timer_starting_cpu,
nps_timer_dying_cpu); nps_timer_dying_cpu);
if (ret) { if (ret) {
pr_err("Failed to setup hotplug state"); pr_err("Failed to setup hotplug state\n");
clk_disable_unprepare(clk); clk_disable_unprepare(clk);
free_percpu_irq(nps_timer0_irq, &nps_clockevent_device); free_percpu_irq(nps_timer0_irq, &nps_clockevent_device);
return ret; return ret;
......
...@@ -196,20 +196,20 @@ static int __init sirfsoc_prima2_timer_init(struct device_node *np) ...@@ -196,20 +196,20 @@ static int __init sirfsoc_prima2_timer_init(struct device_node *np)
clk = of_clk_get(np, 0); clk = of_clk_get(np, 0);
if (IS_ERR(clk)) { if (IS_ERR(clk)) {
pr_err("Failed to get clock"); pr_err("Failed to get clock\n");
return PTR_ERR(clk); return PTR_ERR(clk);
} }
ret = clk_prepare_enable(clk); ret = clk_prepare_enable(clk);
if (ret) { if (ret) {
pr_err("Failed to enable clock"); pr_err("Failed to enable clock\n");
return ret; return ret;
} }
rate = clk_get_rate(clk); rate = clk_get_rate(clk);
if (rate < PRIMA2_CLOCK_FREQ || rate % PRIMA2_CLOCK_FREQ) { if (rate < PRIMA2_CLOCK_FREQ || rate % PRIMA2_CLOCK_FREQ) {
pr_err("Invalid clock rate"); pr_err("Invalid clock rate\n");
return -EINVAL; return -EINVAL;
} }
...@@ -229,7 +229,7 @@ static int __init sirfsoc_prima2_timer_init(struct device_node *np) ...@@ -229,7 +229,7 @@ static int __init sirfsoc_prima2_timer_init(struct device_node *np)
ret = clocksource_register_hz(&sirfsoc_clocksource, PRIMA2_CLOCK_FREQ); ret = clocksource_register_hz(&sirfsoc_clocksource, PRIMA2_CLOCK_FREQ);
if (ret) { if (ret) {
pr_err("Failed to register clocksource"); pr_err("Failed to register clocksource\n");
return ret; return ret;
} }
...@@ -237,7 +237,7 @@ static int __init sirfsoc_prima2_timer_init(struct device_node *np) ...@@ -237,7 +237,7 @@ static int __init sirfsoc_prima2_timer_init(struct device_node *np)
ret = setup_irq(sirfsoc_timer_irq.irq, &sirfsoc_timer_irq); ret = setup_irq(sirfsoc_timer_irq.irq, &sirfsoc_timer_irq);
if (ret) { if (ret) {
pr_err("Failed to setup irq"); pr_err("Failed to setup irq\n");
return ret; return ret;
} }
......
...@@ -299,13 +299,13 @@ static int __init integrator_cp_of_init(struct device_node *np) ...@@ -299,13 +299,13 @@ static int __init integrator_cp_of_init(struct device_node *np)
base = of_iomap(np, 0); base = of_iomap(np, 0);
if (!base) { if (!base) {
pr_err("Failed to iomap"); pr_err("Failed to iomap\n");
return -ENXIO; return -ENXIO;
} }
clk = of_clk_get(np, 0); clk = of_clk_get(np, 0);
if (IS_ERR(clk)) { if (IS_ERR(clk)) {
pr_err("Failed to get clock"); pr_err("Failed to get clock\n");
return PTR_ERR(clk); return PTR_ERR(clk);
} }
......
...@@ -332,19 +332,19 @@ static int __init sun5i_timer_init(struct device_node *node) ...@@ -332,19 +332,19 @@ static int __init sun5i_timer_init(struct device_node *node)
timer_base = of_io_request_and_map(node, 0, of_node_full_name(node)); timer_base = of_io_request_and_map(node, 0, of_node_full_name(node));
if (IS_ERR(timer_base)) { if (IS_ERR(timer_base)) {
pr_err("Can't map registers"); pr_err("Can't map registers\n");
return PTR_ERR(timer_base);; return PTR_ERR(timer_base);;
} }
irq = irq_of_parse_and_map(node, 0); irq = irq_of_parse_and_map(node, 0);
if (irq <= 0) { if (irq <= 0) {
pr_err("Can't parse IRQ"); pr_err("Can't parse IRQ\n");
return -EINVAL; return -EINVAL;
} }
clk = of_clk_get(node, 0); clk = of_clk_get(node, 0);
if (IS_ERR(clk)) { if (IS_ERR(clk)) {
pr_err("Can't get timer clock"); pr_err("Can't get timer clock\n");
return PTR_ERR(clk); return PTR_ERR(clk);
} }
......
...@@ -165,7 +165,7 @@ static int __init pit_timer_init(struct device_node *np) ...@@ -165,7 +165,7 @@ static int __init pit_timer_init(struct device_node *np)
timer_base = of_iomap(np, 0); timer_base = of_iomap(np, 0);
if (!timer_base) { if (!timer_base) {
pr_err("Failed to iomap"); pr_err("Failed to iomap\n");
return -ENXIO; return -ENXIO;
} }
......
...@@ -97,30 +97,26 @@ static s32 scaled_ppm_to_ppb(long ppm) ...@@ -97,30 +97,26 @@ static s32 scaled_ppm_to_ppb(long ppm)
/* posix clock implementation */ /* posix clock implementation */
static int ptp_clock_getres(struct posix_clock *pc, struct timespec *tp) static int ptp_clock_getres(struct posix_clock *pc, struct timespec64 *tp)
{ {
tp->tv_sec = 0; tp->tv_sec = 0;
tp->tv_nsec = 1; tp->tv_nsec = 1;
return 0; return 0;
} }
static int ptp_clock_settime(struct posix_clock *pc, const struct timespec *tp) static int ptp_clock_settime(struct posix_clock *pc, const struct timespec64 *tp)
{ {
struct ptp_clock *ptp = container_of(pc, struct ptp_clock, clock); struct ptp_clock *ptp = container_of(pc, struct ptp_clock, clock);
struct timespec64 ts = timespec_to_timespec64(*tp);
return ptp->info->settime64(ptp->info, &ts); return ptp->info->settime64(ptp->info, tp);
} }
static int ptp_clock_gettime(struct posix_clock *pc, struct timespec *tp) static int ptp_clock_gettime(struct posix_clock *pc, struct timespec64 *tp)
{ {
struct ptp_clock *ptp = container_of(pc, struct ptp_clock, clock); struct ptp_clock *ptp = container_of(pc, struct ptp_clock, clock);
struct timespec64 ts;
int err; int err;
err = ptp->info->gettime64(ptp->info, &ts); err = ptp->info->gettime64(ptp->info, tp);
if (!err)
*tp = timespec64_to_timespec(ts);
return err; return err;
} }
...@@ -133,7 +129,7 @@ static int ptp_clock_adjtime(struct posix_clock *pc, struct timex *tx) ...@@ -133,7 +129,7 @@ static int ptp_clock_adjtime(struct posix_clock *pc, struct timex *tx)
ops = ptp->info; ops = ptp->info;
if (tx->modes & ADJ_SETOFFSET) { if (tx->modes & ADJ_SETOFFSET) {
struct timespec ts; struct timespec64 ts;
ktime_t kt; ktime_t kt;
s64 delta; s64 delta;
...@@ -146,7 +142,7 @@ static int ptp_clock_adjtime(struct posix_clock *pc, struct timex *tx) ...@@ -146,7 +142,7 @@ static int ptp_clock_adjtime(struct posix_clock *pc, struct timex *tx)
if ((unsigned long) ts.tv_nsec >= NSEC_PER_SEC) if ((unsigned long) ts.tv_nsec >= NSEC_PER_SEC)
return -EINVAL; return -EINVAL;
kt = timespec_to_ktime(ts); kt = timespec64_to_ktime(ts);
delta = ktime_to_ns(kt); delta = ktime_to_ns(kt);
err = ops->adjtime(ops, delta); err = ops->adjtime(ops, delta);
} else if (tx->modes & ADJ_FREQUENCY) { } else if (tx->modes & ADJ_FREQUENCY) {
......
...@@ -16,9 +16,13 @@ ...@@ -16,9 +16,13 @@
#ifndef __CLKSOURCE_ARM_ARCH_TIMER_H #ifndef __CLKSOURCE_ARM_ARCH_TIMER_H
#define __CLKSOURCE_ARM_ARCH_TIMER_H #define __CLKSOURCE_ARM_ARCH_TIMER_H
#include <linux/bitops.h>
#include <linux/timecounter.h> #include <linux/timecounter.h>
#include <linux/types.h> #include <linux/types.h>
#define ARCH_TIMER_TYPE_CP15 BIT(0)
#define ARCH_TIMER_TYPE_MEM BIT(1)
#define ARCH_TIMER_CTRL_ENABLE (1 << 0) #define ARCH_TIMER_CTRL_ENABLE (1 << 0)
#define ARCH_TIMER_CTRL_IT_MASK (1 << 1) #define ARCH_TIMER_CTRL_IT_MASK (1 << 1)
#define ARCH_TIMER_CTRL_IT_STAT (1 << 2) #define ARCH_TIMER_CTRL_IT_STAT (1 << 2)
...@@ -34,11 +38,27 @@ enum arch_timer_reg { ...@@ -34,11 +38,27 @@ enum arch_timer_reg {
ARCH_TIMER_REG_TVAL, ARCH_TIMER_REG_TVAL,
}; };
enum arch_timer_ppi_nr {
ARCH_TIMER_PHYS_SECURE_PPI,
ARCH_TIMER_PHYS_NONSECURE_PPI,
ARCH_TIMER_VIRT_PPI,
ARCH_TIMER_HYP_PPI,
ARCH_TIMER_MAX_TIMER_PPI
};
enum arch_timer_spi_nr {
ARCH_TIMER_PHYS_SPI,
ARCH_TIMER_VIRT_SPI,
ARCH_TIMER_MAX_TIMER_SPI
};
#define ARCH_TIMER_PHYS_ACCESS 0 #define ARCH_TIMER_PHYS_ACCESS 0
#define ARCH_TIMER_VIRT_ACCESS 1 #define ARCH_TIMER_VIRT_ACCESS 1
#define ARCH_TIMER_MEM_PHYS_ACCESS 2 #define ARCH_TIMER_MEM_PHYS_ACCESS 2
#define ARCH_TIMER_MEM_VIRT_ACCESS 3 #define ARCH_TIMER_MEM_VIRT_ACCESS 3
#define ARCH_TIMER_MEM_MAX_FRAMES 8
#define ARCH_TIMER_USR_PCT_ACCESS_EN (1 << 0) /* physical counter */ #define ARCH_TIMER_USR_PCT_ACCESS_EN (1 << 0) /* physical counter */
#define ARCH_TIMER_USR_VCT_ACCESS_EN (1 << 1) /* virtual counter */ #define ARCH_TIMER_USR_VCT_ACCESS_EN (1 << 1) /* virtual counter */
#define ARCH_TIMER_VIRT_EVT_EN (1 << 2) #define ARCH_TIMER_VIRT_EVT_EN (1 << 2)
...@@ -54,6 +74,20 @@ struct arch_timer_kvm_info { ...@@ -54,6 +74,20 @@ struct arch_timer_kvm_info {
int virtual_irq; int virtual_irq;
}; };
struct arch_timer_mem_frame {
bool valid;
phys_addr_t cntbase;
size_t size;
int phys_irq;
int virt_irq;
};
struct arch_timer_mem {
phys_addr_t cntctlbase;
size_t size;
struct arch_timer_mem_frame frame[ARCH_TIMER_MEM_MAX_FRAMES];
};
#ifdef CONFIG_ARM_ARCH_TIMER #ifdef CONFIG_ARM_ARCH_TIMER
extern u32 arch_timer_get_rate(void); extern u32 arch_timer_get_rate(void);
......
...@@ -591,6 +591,13 @@ enum acpi_reconfig_event { ...@@ -591,6 +591,13 @@ enum acpi_reconfig_event {
int acpi_reconfig_notifier_register(struct notifier_block *nb); int acpi_reconfig_notifier_register(struct notifier_block *nb);
int acpi_reconfig_notifier_unregister(struct notifier_block *nb); int acpi_reconfig_notifier_unregister(struct notifier_block *nb);
#ifdef CONFIG_ACPI_GTDT
int acpi_gtdt_init(struct acpi_table_header *table, int *platform_timer_count);
int acpi_gtdt_map_ppi(int type);
bool acpi_gtdt_c3stop(int type);
int acpi_arch_timer_mem_init(struct arch_timer_mem *timer_mem, int *timer_count);
#endif
#else /* !CONFIG_ACPI */ #else /* !CONFIG_ACPI */
#define acpi_disabled 1 #define acpi_disabled 1
......
...@@ -182,7 +182,6 @@ extern u64 clockevent_delta2ns(unsigned long latch, struct clock_event_device *e ...@@ -182,7 +182,6 @@ extern u64 clockevent_delta2ns(unsigned long latch, struct clock_event_device *e
extern void clockevents_register_device(struct clock_event_device *dev); extern void clockevents_register_device(struct clock_event_device *dev);
extern int clockevents_unbind_device(struct clock_event_device *ced, int cpu); extern int clockevents_unbind_device(struct clock_event_device *ced, int cpu);
extern void clockevents_config(struct clock_event_device *dev, u32 freq);
extern void clockevents_config_and_register(struct clock_event_device *dev, extern void clockevents_config_and_register(struct clock_event_device *dev,
u32 freq, unsigned long min_delta, u32 freq, unsigned long min_delta,
unsigned long max_delta); unsigned long max_delta);
......
...@@ -120,7 +120,7 @@ struct clocksource { ...@@ -120,7 +120,7 @@ struct clocksource {
#define CLOCK_SOURCE_RESELECT 0x100 #define CLOCK_SOURCE_RESELECT 0x100
/* simplify initialization of mask field */ /* simplify initialization of mask field */
#define CLOCKSOURCE_MASK(bits) (u64)((bits) < 64 ? ((1ULL<<(bits))-1) : -1) #define CLOCKSOURCE_MASK(bits) GENMASK_ULL((bits) - 1, 0)
static inline u32 clocksource_freq2mult(u32 freq, u32 shift_constant, u64 from) static inline u32 clocksource_freq2mult(u32 freq, u32 shift_constant, u64 from)
{ {
......
...@@ -276,8 +276,6 @@ static inline int hrtimer_is_hres_active(struct hrtimer *timer) ...@@ -276,8 +276,6 @@ static inline int hrtimer_is_hres_active(struct hrtimer *timer)
return timer->base->cpu_base->hres_active; return timer->base->cpu_base->hres_active;
} }
extern void hrtimer_peek_ahead_timers(void);
/* /*
* The resolution of the clocks. The resolution value is returned in * The resolution of the clocks. The resolution value is returned in
* the clock_getres() system call to give application programmers an * the clock_getres() system call to give application programmers an
...@@ -300,8 +298,6 @@ extern unsigned int hrtimer_resolution; ...@@ -300,8 +298,6 @@ extern unsigned int hrtimer_resolution;
#define hrtimer_resolution (unsigned int)LOW_RES_NSEC #define hrtimer_resolution (unsigned int)LOW_RES_NSEC
static inline void hrtimer_peek_ahead_timers(void) { }
static inline int hrtimer_is_hres_active(struct hrtimer *timer) static inline int hrtimer_is_hres_active(struct hrtimer *timer)
{ {
return 0; return 0;
...@@ -456,7 +452,7 @@ static inline u64 hrtimer_forward_now(struct hrtimer *timer, ...@@ -456,7 +452,7 @@ static inline u64 hrtimer_forward_now(struct hrtimer *timer,
} }
/* Precise sleep: */ /* Precise sleep: */
extern long hrtimer_nanosleep(struct timespec *rqtp, extern long hrtimer_nanosleep(struct timespec64 *rqtp,
struct timespec __user *rmtp, struct timespec __user *rmtp,
const enum hrtimer_mode mode, const enum hrtimer_mode mode,
const clockid_t clockid); const clockid_t clockid);
......
...@@ -258,7 +258,6 @@ extern unsigned int gic_present; ...@@ -258,7 +258,6 @@ extern unsigned int gic_present;
extern void gic_init(unsigned long gic_base_addr, extern void gic_init(unsigned long gic_base_addr,
unsigned long gic_addrspace_size, unsigned int cpu_vec, unsigned long gic_addrspace_size, unsigned int cpu_vec,
unsigned int irqbase); unsigned int irqbase);
extern void gic_clocksource_init(unsigned int);
extern u64 gic_read_count(void); extern u64 gic_read_count(void);
extern unsigned int gic_get_count_width(void); extern unsigned int gic_get_count_width(void);
extern u64 gic_read_compare(void); extern u64 gic_read_compare(void);
......
...@@ -59,23 +59,23 @@ struct posix_clock_operations { ...@@ -59,23 +59,23 @@ struct posix_clock_operations {
int (*clock_adjtime)(struct posix_clock *pc, struct timex *tx); int (*clock_adjtime)(struct posix_clock *pc, struct timex *tx);
int (*clock_gettime)(struct posix_clock *pc, struct timespec *ts); int (*clock_gettime)(struct posix_clock *pc, struct timespec64 *ts);
int (*clock_getres) (struct posix_clock *pc, struct timespec *ts); int (*clock_getres) (struct posix_clock *pc, struct timespec64 *ts);
int (*clock_settime)(struct posix_clock *pc, int (*clock_settime)(struct posix_clock *pc,
const struct timespec *ts); const struct timespec64 *ts);
int (*timer_create) (struct posix_clock *pc, struct k_itimer *kit); int (*timer_create) (struct posix_clock *pc, struct k_itimer *kit);
int (*timer_delete) (struct posix_clock *pc, struct k_itimer *kit); int (*timer_delete) (struct posix_clock *pc, struct k_itimer *kit);
void (*timer_gettime)(struct posix_clock *pc, void (*timer_gettime)(struct posix_clock *pc,
struct k_itimer *kit, struct itimerspec *tsp); struct k_itimer *kit, struct itimerspec64 *tsp);
int (*timer_settime)(struct posix_clock *pc, int (*timer_settime)(struct posix_clock *pc,
struct k_itimer *kit, int flags, struct k_itimer *kit, int flags,
struct itimerspec *tsp, struct itimerspec *old); struct itimerspec64 *tsp, struct itimerspec64 *old);
/* /*
* Optional character device methods: * Optional character device methods:
*/ */
......
...@@ -87,22 +87,22 @@ struct k_itimer { ...@@ -87,22 +87,22 @@ struct k_itimer {
}; };
struct k_clock { struct k_clock {
int (*clock_getres) (const clockid_t which_clock, struct timespec *tp); int (*clock_getres) (const clockid_t which_clock, struct timespec64 *tp);
int (*clock_set) (const clockid_t which_clock, int (*clock_set) (const clockid_t which_clock,
const struct timespec *tp); const struct timespec64 *tp);
int (*clock_get) (const clockid_t which_clock, struct timespec * tp); int (*clock_get) (const clockid_t which_clock, struct timespec64 *tp);
int (*clock_adj) (const clockid_t which_clock, struct timex *tx); int (*clock_adj) (const clockid_t which_clock, struct timex *tx);
int (*timer_create) (struct k_itimer *timer); int (*timer_create) (struct k_itimer *timer);
int (*nsleep) (const clockid_t which_clock, int flags, int (*nsleep) (const clockid_t which_clock, int flags,
struct timespec *, struct timespec __user *); struct timespec64 *, struct timespec __user *);
long (*nsleep_restart) (struct restart_block *restart_block); long (*nsleep_restart) (struct restart_block *restart_block);
int (*timer_set) (struct k_itimer * timr, int flags, int (*timer_set) (struct k_itimer *timr, int flags,
struct itimerspec * new_setting, struct itimerspec64 *new_setting,
struct itimerspec * old_setting); struct itimerspec64 *old_setting);
int (*timer_del) (struct k_itimer * timr); int (*timer_del) (struct k_itimer *timr);
#define TIMER_RETRY 1 #define TIMER_RETRY 1
void (*timer_get) (struct k_itimer * timr, void (*timer_get) (struct k_itimer *timr,
struct itimerspec * cur_setting); struct itimerspec64 *cur_setting);
}; };
extern struct k_clock clock_posix_cpu; extern struct k_clock clock_posix_cpu;
......
...@@ -19,21 +19,6 @@ extern void do_gettimeofday(struct timeval *tv); ...@@ -19,21 +19,6 @@ extern void do_gettimeofday(struct timeval *tv);
extern int do_settimeofday64(const struct timespec64 *ts); extern int do_settimeofday64(const struct timespec64 *ts);
extern int do_sys_settimeofday64(const struct timespec64 *tv, extern int do_sys_settimeofday64(const struct timespec64 *tv,
const struct timezone *tz); const struct timezone *tz);
static inline int do_sys_settimeofday(const struct timespec *tv,
const struct timezone *tz)
{
struct timespec64 ts64;
if (!tv)
return do_sys_settimeofday64(NULL, tz);
if (!timespec_valid(tv))
return -EINVAL;
ts64 = timespec_to_timespec64(*tv);
return do_sys_settimeofday64(&ts64, tz);
}
/* /*
* Kernel time accessors * Kernel time accessors
*/ */
...@@ -273,6 +258,11 @@ static inline void timekeeping_clocktai(struct timespec *ts) ...@@ -273,6 +258,11 @@ static inline void timekeeping_clocktai(struct timespec *ts)
*ts = ktime_to_timespec(ktime_get_clocktai()); *ts = ktime_to_timespec(ktime_get_clocktai());
} }
static inline void timekeeping_clocktai64(struct timespec64 *ts)
{
*ts = ktime_to_timespec64(ktime_get_clocktai());
}
/* /*
* RTC specific * RTC specific
*/ */
......
...@@ -108,8 +108,8 @@ COMPAT_SYSCALL_DEFINE2(gettimeofday, struct compat_timeval __user *, tv, ...@@ -108,8 +108,8 @@ COMPAT_SYSCALL_DEFINE2(gettimeofday, struct compat_timeval __user *, tv,
COMPAT_SYSCALL_DEFINE2(settimeofday, struct compat_timeval __user *, tv, COMPAT_SYSCALL_DEFINE2(settimeofday, struct compat_timeval __user *, tv,
struct timezone __user *, tz) struct timezone __user *, tz)
{ {
struct timespec64 new_ts;
struct timeval user_tv; struct timeval user_tv;
struct timespec new_ts;
struct timezone new_tz; struct timezone new_tz;
if (tv) { if (tv) {
...@@ -123,7 +123,7 @@ COMPAT_SYSCALL_DEFINE2(settimeofday, struct compat_timeval __user *, tv, ...@@ -123,7 +123,7 @@ COMPAT_SYSCALL_DEFINE2(settimeofday, struct compat_timeval __user *, tv,
return -EFAULT; return -EFAULT;
} }
return do_sys_settimeofday(tv ? &new_ts : NULL, tz ? &new_tz : NULL); return do_sys_settimeofday64(tv ? &new_ts : NULL, tz ? &new_tz : NULL);
} }
static int __compat_get_timeval(struct timeval *tv, const struct compat_timeval __user *ctv) static int __compat_get_timeval(struct timeval *tv, const struct compat_timeval __user *ctv)
...@@ -240,18 +240,20 @@ COMPAT_SYSCALL_DEFINE2(nanosleep, struct compat_timespec __user *, rqtp, ...@@ -240,18 +240,20 @@ COMPAT_SYSCALL_DEFINE2(nanosleep, struct compat_timespec __user *, rqtp,
struct compat_timespec __user *, rmtp) struct compat_timespec __user *, rmtp)
{ {
struct timespec tu, rmt; struct timespec tu, rmt;
struct timespec64 tu64;
mm_segment_t oldfs; mm_segment_t oldfs;
long ret; long ret;
if (compat_get_timespec(&tu, rqtp)) if (compat_get_timespec(&tu, rqtp))
return -EFAULT; return -EFAULT;
if (!timespec_valid(&tu)) tu64 = timespec_to_timespec64(tu);
if (!timespec64_valid(&tu64))
return -EINVAL; return -EINVAL;
oldfs = get_fs(); oldfs = get_fs();
set_fs(KERNEL_DS); set_fs(KERNEL_DS);
ret = hrtimer_nanosleep(&tu, ret = hrtimer_nanosleep(&tu64,
rmtp ? (struct timespec __user *)&rmt : NULL, rmtp ? (struct timespec __user *)&rmt : NULL,
HRTIMER_MODE_REL, CLOCK_MONOTONIC); HRTIMER_MODE_REL, CLOCK_MONOTONIC);
set_fs(oldfs); set_fs(oldfs);
......
...@@ -1176,6 +1176,8 @@ static struct ctl_table kern_table[] = { ...@@ -1176,6 +1176,8 @@ static struct ctl_table kern_table[] = {
.maxlen = sizeof(unsigned int), .maxlen = sizeof(unsigned int),
.mode = 0644, .mode = 0644,
.proc_handler = timer_migration_handler, .proc_handler = timer_migration_handler,
.extra1 = &zero,
.extra2 = &one,
}, },
#endif #endif
#ifdef CONFIG_BPF_SYSCALL #ifdef CONFIG_BPF_SYSCALL
......
...@@ -541,7 +541,7 @@ static enum alarmtimer_restart alarm_handle_timer(struct alarm *alarm, ...@@ -541,7 +541,7 @@ static enum alarmtimer_restart alarm_handle_timer(struct alarm *alarm,
* *
* Returns the granularity of underlying alarm base clock * Returns the granularity of underlying alarm base clock
*/ */
static int alarm_clock_getres(const clockid_t which_clock, struct timespec *tp) static int alarm_clock_getres(const clockid_t which_clock, struct timespec64 *tp)
{ {
if (!alarmtimer_get_rtcdev()) if (!alarmtimer_get_rtcdev())
return -EINVAL; return -EINVAL;
...@@ -558,14 +558,14 @@ static int alarm_clock_getres(const clockid_t which_clock, struct timespec *tp) ...@@ -558,14 +558,14 @@ static int alarm_clock_getres(const clockid_t which_clock, struct timespec *tp)
* *
* Provides the underlying alarm base time. * Provides the underlying alarm base time.
*/ */
static int alarm_clock_get(clockid_t which_clock, struct timespec *tp) static int alarm_clock_get(clockid_t which_clock, struct timespec64 *tp)
{ {
struct alarm_base *base = &alarm_bases[clock2alarm(which_clock)]; struct alarm_base *base = &alarm_bases[clock2alarm(which_clock)];
if (!alarmtimer_get_rtcdev()) if (!alarmtimer_get_rtcdev())
return -EINVAL; return -EINVAL;
*tp = ktime_to_timespec(base->gettime()); *tp = ktime_to_timespec64(base->gettime());
return 0; return 0;
} }
...@@ -598,19 +598,19 @@ static int alarm_timer_create(struct k_itimer *new_timer) ...@@ -598,19 +598,19 @@ static int alarm_timer_create(struct k_itimer *new_timer)
* Copies out the current itimerspec data * Copies out the current itimerspec data
*/ */
static void alarm_timer_get(struct k_itimer *timr, static void alarm_timer_get(struct k_itimer *timr,
struct itimerspec *cur_setting) struct itimerspec64 *cur_setting)
{ {
ktime_t relative_expiry_time = ktime_t relative_expiry_time =
alarm_expires_remaining(&(timr->it.alarm.alarmtimer)); alarm_expires_remaining(&(timr->it.alarm.alarmtimer));
if (ktime_to_ns(relative_expiry_time) > 0) { if (ktime_to_ns(relative_expiry_time) > 0) {
cur_setting->it_value = ktime_to_timespec(relative_expiry_time); cur_setting->it_value = ktime_to_timespec64(relative_expiry_time);
} else { } else {
cur_setting->it_value.tv_sec = 0; cur_setting->it_value.tv_sec = 0;
cur_setting->it_value.tv_nsec = 0; cur_setting->it_value.tv_nsec = 0;
} }
cur_setting->it_interval = ktime_to_timespec(timr->it.alarm.interval); cur_setting->it_interval = ktime_to_timespec64(timr->it.alarm.interval);
} }
/** /**
...@@ -640,8 +640,8 @@ static int alarm_timer_del(struct k_itimer *timr) ...@@ -640,8 +640,8 @@ static int alarm_timer_del(struct k_itimer *timr)
* Sets the timer to new_setting, and starts the timer. * Sets the timer to new_setting, and starts the timer.
*/ */
static int alarm_timer_set(struct k_itimer *timr, int flags, static int alarm_timer_set(struct k_itimer *timr, int flags,
struct itimerspec *new_setting, struct itimerspec64 *new_setting,
struct itimerspec *old_setting) struct itimerspec64 *old_setting)
{ {
ktime_t exp; ktime_t exp;
...@@ -659,8 +659,8 @@ static int alarm_timer_set(struct k_itimer *timr, int flags, ...@@ -659,8 +659,8 @@ static int alarm_timer_set(struct k_itimer *timr, int flags,
return TIMER_RETRY; return TIMER_RETRY;
/* start the timer */ /* start the timer */
timr->it.alarm.interval = timespec_to_ktime(new_setting->it_interval); timr->it.alarm.interval = timespec64_to_ktime(new_setting->it_interval);
exp = timespec_to_ktime(new_setting->it_value); exp = timespec64_to_ktime(new_setting->it_value);
/* Convert (if necessary) to absolute time */ /* Convert (if necessary) to absolute time */
if (flags != TIMER_ABSTIME) { if (flags != TIMER_ABSTIME) {
ktime_t now; ktime_t now;
...@@ -790,13 +790,14 @@ static long __sched alarm_timer_nsleep_restart(struct restart_block *restart) ...@@ -790,13 +790,14 @@ static long __sched alarm_timer_nsleep_restart(struct restart_block *restart)
* Handles clock_nanosleep calls against _ALARM clockids * Handles clock_nanosleep calls against _ALARM clockids
*/ */
static int alarm_timer_nsleep(const clockid_t which_clock, int flags, static int alarm_timer_nsleep(const clockid_t which_clock, int flags,
struct timespec *tsreq, struct timespec __user *rmtp) struct timespec64 *tsreq,
struct timespec __user *rmtp)
{ {
enum alarmtimer_type type = clock2alarm(which_clock); enum alarmtimer_type type = clock2alarm(which_clock);
struct restart_block *restart;
struct alarm alarm; struct alarm alarm;
ktime_t exp; ktime_t exp;
int ret = 0; int ret = 0;
struct restart_block *restart;
if (!alarmtimer_get_rtcdev()) if (!alarmtimer_get_rtcdev())
return -ENOTSUPP; return -ENOTSUPP;
...@@ -809,7 +810,7 @@ static int alarm_timer_nsleep(const clockid_t which_clock, int flags, ...@@ -809,7 +810,7 @@ static int alarm_timer_nsleep(const clockid_t which_clock, int flags,
alarm_init(&alarm, type, alarmtimer_nsleep_wakeup); alarm_init(&alarm, type, alarmtimer_nsleep_wakeup);
exp = timespec_to_ktime(*tsreq); exp = timespec64_to_ktime(*tsreq);
/* Convert (if necessary) to absolute time */ /* Convert (if necessary) to absolute time */
if (flags != TIMER_ABSTIME) { if (flags != TIMER_ABSTIME) {
ktime_t now = alarm_bases[type].gettime(); ktime_t now = alarm_bases[type].gettime();
......
...@@ -468,7 +468,7 @@ void clockevents_register_device(struct clock_event_device *dev) ...@@ -468,7 +468,7 @@ void clockevents_register_device(struct clock_event_device *dev)
} }
EXPORT_SYMBOL_GPL(clockevents_register_device); EXPORT_SYMBOL_GPL(clockevents_register_device);
void clockevents_config(struct clock_event_device *dev, u32 freq) static void clockevents_config(struct clock_event_device *dev, u32 freq)
{ {
u64 sec; u64 sec;
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment