mirror of
https://github.com/armbian/linux-cix.git
synced 2026-01-06 12:30:45 -08:00
Merge branch 'timers-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull core timer updates from Thomas Gleixner:
"Timers and timekeeping updates:
- A large overhaul of the posix CPU timer code which is a preparation
for moving the CPU timer expiry out into task work so it can be
properly accounted on the task/process.
An update to the bogus permission checks will come later during the
merge window as feedback was not complete before heading of for
travel.
- Switch the timerqueue code to use cached rbtrees and get rid of the
homebrewn caching of the leftmost node.
- Consolidate hrtimer_init() + hrtimer_init_sleeper() calls into a
single function
- Implement the separation of hrtimers to be forced to expire in hard
interrupt context even when PREEMPT_RT is enabled and mark the
affected timers accordingly.
- Implement a mechanism for hrtimers and the timer wheel to protect
RT against priority inversion and live lock issues when a (hr)timer
which should be canceled is currently executing the callback.
Instead of infinitely spinning, the task which tries to cancel the
timer blocks on a per cpu base expiry lock which is held and
released by the (hr)timer expiry code.
- Enable the Hyper-V TSC page based sched_clock for Hyper-V guests
resulting in faster access to timekeeping functions.
- Updates to various clocksource/clockevent drivers and their device
tree bindings.
- The usual small improvements all over the place"
* 'timers-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: (101 commits)
posix-cpu-timers: Fix permission check regression
posix-cpu-timers: Always clear head pointer on dequeue
hrtimer: Add a missing bracket and hide `migration_base' on !SMP
posix-cpu-timers: Make expiry_active check actually work correctly
posix-timers: Unbreak CONFIG_POSIX_TIMERS=n build
tick: Mark sched_timer to expire in hard interrupt context
hrtimer: Add kernel doc annotation for HRTIMER_MODE_HARD
x86/hyperv: Hide pv_ops access for CONFIG_PARAVIRT=n
posix-cpu-timers: Utilize timerqueue for storage
posix-cpu-timers: Move state tracking to struct posix_cputimers
posix-cpu-timers: Deduplicate rlimit handling
posix-cpu-timers: Remove pointless comparisons
posix-cpu-timers: Get rid of 64bit divisions
posix-cpu-timers: Consolidate timer expiry further
posix-cpu-timers: Get rid of zero checks
rlimit: Rewrite non-sensical RLIMIT_CPU comment
posix-cpu-timers: Respect INFINITY for hard RTTIME limit
posix-cpu-timers: Switch thread group sampling to array
posix-cpu-timers: Restructure expiry array
posix-cpu-timers: Remove cputime_expires
...
This commit is contained in:
@@ -0,0 +1,102 @@
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/timer/allwinner,sun4i-a10-timer.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Allwinner A10 Timer Device Tree Bindings
|
||||
|
||||
maintainers:
|
||||
- Chen-Yu Tsai <wens@csie.org>
|
||||
- Maxime Ripard <maxime.ripard@bootlin.com>
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
enum:
|
||||
- allwinner,sun4i-a10-timer
|
||||
- allwinner,sun8i-a23-timer
|
||||
- allwinner,sun8i-v3s-timer
|
||||
- allwinner,suniv-f1c100s-timer
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
interrupts:
|
||||
description:
|
||||
List of timers interrupts
|
||||
|
||||
clocks:
|
||||
maxItems: 1
|
||||
|
||||
allOf:
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
items:
|
||||
const: allwinner,sun4i-a10-timer
|
||||
|
||||
then:
|
||||
properties:
|
||||
interrupts:
|
||||
minItems: 6
|
||||
maxItems: 6
|
||||
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
items:
|
||||
const: allwinner,sun8i-a23-timer
|
||||
|
||||
then:
|
||||
properties:
|
||||
interrupts:
|
||||
minItems: 2
|
||||
maxItems: 2
|
||||
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
items:
|
||||
const: allwinner,sun8i-v3s-timer
|
||||
|
||||
then:
|
||||
properties:
|
||||
interrupts:
|
||||
minItems: 3
|
||||
maxItems: 3
|
||||
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
items:
|
||||
const: allwinner,suniv-f1c100s-timer
|
||||
|
||||
then:
|
||||
properties:
|
||||
interrupts:
|
||||
minItems: 3
|
||||
maxItems: 3
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- interrupts
|
||||
- clocks
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
timer {
|
||||
compatible = "allwinner,sun4i-a10-timer";
|
||||
reg = <0x01c20c00 0x400>;
|
||||
interrupts = <22>,
|
||||
<23>,
|
||||
<24>,
|
||||
<25>,
|
||||
<67>,
|
||||
<68>;
|
||||
clocks = <&osc>;
|
||||
};
|
||||
|
||||
...
|
||||
@@ -1,19 +0,0 @@
|
||||
Allwinner A1X SoCs Timer Controller
|
||||
|
||||
Required properties:
|
||||
|
||||
- compatible : should be one of the following:
|
||||
"allwinner,sun4i-a10-timer"
|
||||
"allwinner,suniv-f1c100s-timer"
|
||||
- reg : Specifies base physical address and size of the registers.
|
||||
- interrupts : The interrupt of the first timer
|
||||
- clocks: phandle to the source clock (usually a 24 MHz fixed clock)
|
||||
|
||||
Example:
|
||||
|
||||
timer {
|
||||
compatible = "allwinner,sun4i-a10-timer";
|
||||
reg = <0x01c20c00 0x400>;
|
||||
interrupts = <22>;
|
||||
clocks = <&osc>;
|
||||
};
|
||||
@@ -1,26 +0,0 @@
|
||||
Allwinner SoCs High Speed Timer Controller
|
||||
|
||||
Required properties:
|
||||
|
||||
- compatible : should be "allwinner,sun5i-a13-hstimer" or
|
||||
"allwinner,sun7i-a20-hstimer"
|
||||
- reg : Specifies base physical address and size of the registers.
|
||||
- interrupts : The interrupts of these timers (2 for the sun5i IP, 4 for the sun7i
|
||||
one)
|
||||
- clocks: phandle to the source clock (usually the AHB clock)
|
||||
|
||||
Optional properties:
|
||||
- resets: phandle to a reset controller asserting the timer
|
||||
|
||||
Example:
|
||||
|
||||
timer@1c60000 {
|
||||
compatible = "allwinner,sun7i-a20-hstimer";
|
||||
reg = <0x01c60000 0x1000>;
|
||||
interrupts = <0 51 1>,
|
||||
<0 52 1>,
|
||||
<0 53 1>,
|
||||
<0 54 1>;
|
||||
clocks = <&ahb1_gates 19>;
|
||||
resets = <&ahb1rst 19>;
|
||||
};
|
||||
@@ -0,0 +1,79 @@
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/timer/allwinner,sun5i-a13-hstimer.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Allwinner A13 High-Speed Timer Device Tree Bindings
|
||||
|
||||
maintainers:
|
||||
- Chen-Yu Tsai <wens@csie.org>
|
||||
- Maxime Ripard <maxime.ripard@bootlin.com>
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
oneOf:
|
||||
- const: allwinner,sun5i-a13-hstimer
|
||||
- const: allwinner,sun7i-a20-hstimer
|
||||
- items:
|
||||
- const: allwinner,sun6i-a31-hstimer
|
||||
- const: allwinner,sun7i-a20-hstimer
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
interrupts:
|
||||
minItems: 2
|
||||
maxItems: 4
|
||||
items:
|
||||
- description: Timer 0 Interrupt
|
||||
- description: Timer 1 Interrupt
|
||||
- description: Timer 2 Interrupt
|
||||
- description: Timer 3 Interrupt
|
||||
|
||||
clocks:
|
||||
maxItems: 1
|
||||
|
||||
resets:
|
||||
maxItems: 1
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- interrupts
|
||||
- clocks
|
||||
|
||||
if:
|
||||
properties:
|
||||
compatible:
|
||||
items:
|
||||
const: allwinner,sun5i-a13-hstimer
|
||||
|
||||
then:
|
||||
properties:
|
||||
interrupts:
|
||||
minItems: 2
|
||||
maxItems: 2
|
||||
|
||||
else:
|
||||
properties:
|
||||
interrupts:
|
||||
minItems: 4
|
||||
maxItems: 4
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
timer@1c60000 {
|
||||
compatible = "allwinner,sun7i-a20-hstimer";
|
||||
reg = <0x01c60000 0x1000>;
|
||||
interrupts = <0 51 1>,
|
||||
<0 52 1>,
|
||||
<0 53 1>,
|
||||
<0 54 1>;
|
||||
clocks = <&ahb1_gates 19>;
|
||||
resets = <&ahb1rst 19>;
|
||||
};
|
||||
|
||||
...
|
||||
@@ -12,16 +12,13 @@ datasheets.
|
||||
Required Properties:
|
||||
|
||||
- compatible: must contain one or more of the following:
|
||||
- "renesas,cmt-48-sh73a0" for the sh73A0 48-bit CMT
|
||||
(CMT1)
|
||||
- "renesas,cmt-48-r8a7740" for the r8a7740 48-bit CMT
|
||||
(CMT1)
|
||||
- "renesas,cmt-48" for all non-second generation 48-bit CMT
|
||||
(CMT1 on sh73a0 and r8a7740)
|
||||
This is a fallback for the above renesas,cmt-48-* entries.
|
||||
|
||||
- "renesas,r8a73a4-cmt0" for the 32-bit CMT0 device included in r8a73a4.
|
||||
- "renesas,r8a73a4-cmt1" for the 48-bit CMT1 device included in r8a73a4.
|
||||
- "renesas,r8a7740-cmt0" for the 32-bit CMT0 device included in r8a7740.
|
||||
- "renesas,r8a7740-cmt1" for the 48-bit CMT1 device included in r8a7740.
|
||||
- "renesas,r8a7740-cmt2" for the 32-bit CMT2 device included in r8a7740.
|
||||
- "renesas,r8a7740-cmt3" for the 32-bit CMT3 device included in r8a7740.
|
||||
- "renesas,r8a7740-cmt4" for the 32-bit CMT4 device included in r8a7740.
|
||||
- "renesas,r8a7743-cmt0" for the 32-bit CMT0 device included in r8a7743.
|
||||
- "renesas,r8a7743-cmt1" for the 48-bit CMT1 device included in r8a7743.
|
||||
- "renesas,r8a7744-cmt0" for the 32-bit CMT0 device included in r8a7744.
|
||||
@@ -31,29 +28,38 @@ Required Properties:
|
||||
- "renesas,r8a77470-cmt0" for the 32-bit CMT0 device included in r8a77470.
|
||||
- "renesas,r8a77470-cmt1" for the 48-bit CMT1 device included in r8a77470.
|
||||
- "renesas,r8a774a1-cmt0" for the 32-bit CMT0 device included in r8a774a1.
|
||||
- "renesas,r8a774a1-cmt1" for the 48-bit CMT1 device included in r8a774a1.
|
||||
- "renesas,r8a774a1-cmt1" for the 48-bit CMT devices included in r8a774a1.
|
||||
- "renesas,r8a774c0-cmt0" for the 32-bit CMT0 device included in r8a774c0.
|
||||
- "renesas,r8a774c0-cmt1" for the 48-bit CMT1 device included in r8a774c0.
|
||||
- "renesas,r8a774c0-cmt1" for the 48-bit CMT devices included in r8a774c0.
|
||||
- "renesas,r8a7790-cmt0" for the 32-bit CMT0 device included in r8a7790.
|
||||
- "renesas,r8a7790-cmt1" for the 48-bit CMT1 device included in r8a7790.
|
||||
- "renesas,r8a7791-cmt0" for the 32-bit CMT0 device included in r8a7791.
|
||||
- "renesas,r8a7791-cmt1" for the 48-bit CMT1 device included in r8a7791.
|
||||
- "renesas,r8a7792-cmt0" for the 32-bit CMT0 device included in r8a7792.
|
||||
- "renesas,r8a7792-cmt1" for the 48-bit CMT1 device included in r8a7792.
|
||||
- "renesas,r8a7793-cmt0" for the 32-bit CMT0 device included in r8a7793.
|
||||
- "renesas,r8a7793-cmt1" for the 48-bit CMT1 device included in r8a7793.
|
||||
- "renesas,r8a7794-cmt0" for the 32-bit CMT0 device included in r8a7794.
|
||||
- "renesas,r8a7794-cmt1" for the 48-bit CMT1 device included in r8a7794.
|
||||
- "renesas,r8a7795-cmt0" for the 32-bit CMT0 device included in r8a7795.
|
||||
- "renesas,r8a7795-cmt1" for the 48-bit CMT1 device included in r8a7795.
|
||||
- "renesas,r8a7795-cmt1" for the 48-bit CMT devices included in r8a7795.
|
||||
- "renesas,r8a7796-cmt0" for the 32-bit CMT0 device included in r8a7796.
|
||||
- "renesas,r8a7796-cmt1" for the 48-bit CMT1 device included in r8a7796.
|
||||
- "renesas,r8a7796-cmt1" for the 48-bit CMT devices included in r8a7796.
|
||||
- "renesas,r8a77965-cmt0" for the 32-bit CMT0 device included in r8a77965.
|
||||
- "renesas,r8a77965-cmt1" for the 48-bit CMT1 device included in r8a77965.
|
||||
- "renesas,r8a77965-cmt1" for the 48-bit CMT devices included in r8a77965.
|
||||
- "renesas,r8a77970-cmt0" for the 32-bit CMT0 device included in r8a77970.
|
||||
- "renesas,r8a77970-cmt1" for the 48-bit CMT1 device included in r8a77970.
|
||||
- "renesas,r8a77970-cmt1" for the 48-bit CMT devices included in r8a77970.
|
||||
- "renesas,r8a77980-cmt0" for the 32-bit CMT0 device included in r8a77980.
|
||||
- "renesas,r8a77980-cmt1" for the 48-bit CMT1 device included in r8a77980.
|
||||
- "renesas,r8a77980-cmt1" for the 48-bit CMT devices included in r8a77980.
|
||||
- "renesas,r8a77990-cmt0" for the 32-bit CMT0 device included in r8a77990.
|
||||
- "renesas,r8a77990-cmt1" for the 48-bit CMT1 device included in r8a77990.
|
||||
- "renesas,r8a77990-cmt1" for the 48-bit CMT devices included in r8a77990.
|
||||
- "renesas,r8a77995-cmt0" for the 32-bit CMT0 device included in r8a77995.
|
||||
- "renesas,r8a77995-cmt1" for the 48-bit CMT devices included in r8a77995.
|
||||
- "renesas,sh73a0-cmt0" for the 32-bit CMT0 device included in sh73a0.
|
||||
- "renesas,sh73a0-cmt1" for the 48-bit CMT1 device included in sh73a0.
|
||||
- "renesas,sh73a0-cmt2" for the 32-bit CMT2 device included in sh73a0.
|
||||
- "renesas,sh73a0-cmt3" for the 32-bit CMT3 device included in sh73a0.
|
||||
- "renesas,sh73a0-cmt4" for the 32-bit CMT4 device included in sh73a0.
|
||||
|
||||
- "renesas,rcar-gen2-cmt0" for 32-bit CMT0 devices included in R-Car Gen2
|
||||
and RZ/G1.
|
||||
@@ -63,7 +69,7 @@ Required Properties:
|
||||
listed above.
|
||||
- "renesas,rcar-gen3-cmt0" for 32-bit CMT0 devices included in R-Car Gen3
|
||||
and RZ/G2.
|
||||
- "renesas,rcar-gen3-cmt1" for 48-bit CMT1 devices included in R-Car Gen3
|
||||
- "renesas,rcar-gen3-cmt1" for 48-bit CMT devices included in R-Car Gen3
|
||||
and RZ/G2.
|
||||
These are fallbacks for R-Car Gen3 and RZ/G2 entries listed
|
||||
above.
|
||||
|
||||
@@ -546,6 +546,14 @@
|
||||
#pwm-cells = <2>;
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
system_counter: timer@306a0000 {
|
||||
compatible = "nxp,sysctr-timer";
|
||||
reg = <0x306a0000 0x20000>;
|
||||
interrupts = <GIC_SPI 47 IRQ_TYPE_LEVEL_HIGH>;
|
||||
clocks = <&osc_24m>;
|
||||
clock-names = "per";
|
||||
};
|
||||
};
|
||||
|
||||
aips3: bus@30800000 {
|
||||
|
||||
@@ -651,6 +651,14 @@
|
||||
#pwm-cells = <2>;
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
system_counter: timer@306a0000 {
|
||||
compatible = "nxp,sysctr-timer";
|
||||
reg = <0x306a0000 0x20000>;
|
||||
interrupts = <GIC_SPI 47 IRQ_TYPE_LEVEL_HIGH>;
|
||||
clocks = <&osc_25m>;
|
||||
clock-names = "per";
|
||||
};
|
||||
};
|
||||
|
||||
bus@30800000 { /* AIPS3 */
|
||||
|
||||
@@ -122,7 +122,7 @@ static vm_fault_t vvar_fault(const struct vm_special_mapping *sm,
|
||||
|
||||
if (tsc_pg && vclock_was_used(VCLOCK_HVCLOCK))
|
||||
return vmf_insert_pfn(vma, vmf->address,
|
||||
vmalloc_to_pfn(tsc_pg));
|
||||
virt_to_phys(tsc_pg) >> PAGE_SHIFT);
|
||||
}
|
||||
|
||||
return VM_FAULT_SIGBUS;
|
||||
|
||||
@@ -315,8 +315,6 @@ void __init hyperv_init(void)
|
||||
|
||||
x86_init.pci.arch_init = hv_pci_init;
|
||||
|
||||
/* Register Hyper-V specific clocksource */
|
||||
hv_init_clocksource();
|
||||
return;
|
||||
|
||||
remove_cpuhp_state:
|
||||
|
||||
@@ -51,7 +51,7 @@ extern struct pvclock_vsyscall_time_info pvclock_page
|
||||
__attribute__((visibility("hidden")));
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_HYPERV_TSCPAGE
|
||||
#ifdef CONFIG_HYPERV_TIMER
|
||||
extern struct ms_hyperv_tsc_page hvclock_page
|
||||
__attribute__((visibility("hidden")));
|
||||
#endif
|
||||
@@ -228,7 +228,7 @@ static u64 vread_pvclock(void)
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_HYPERV_TSCPAGE
|
||||
#ifdef CONFIG_HYPERV_TIMER
|
||||
static u64 vread_hvclock(void)
|
||||
{
|
||||
return hv_read_tsc_page(&hvclock_page);
|
||||
@@ -251,7 +251,7 @@ static inline u64 __arch_get_hw_counter(s32 clock_mode)
|
||||
return vread_pvclock();
|
||||
}
|
||||
#endif
|
||||
#ifdef CONFIG_HYPERV_TSCPAGE
|
||||
#ifdef CONFIG_HYPERV_TIMER
|
||||
if (clock_mode == VCLOCK_HVCLOCK) {
|
||||
barrier();
|
||||
return vread_hvclock();
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
#include <asm/timer.h>
|
||||
#include <asm/reboot.h>
|
||||
#include <asm/nmi.h>
|
||||
#include <clocksource/hyperv_timer.h>
|
||||
|
||||
struct ms_hyperv_info ms_hyperv;
|
||||
EXPORT_SYMBOL_GPL(ms_hyperv);
|
||||
@@ -338,6 +339,15 @@ static void __init ms_hyperv_init_platform(void)
|
||||
x2apic_phys = 1;
|
||||
# endif
|
||||
|
||||
/* Register Hyper-V specific clocksource */
|
||||
hv_init_clocksource();
|
||||
#endif
|
||||
}
|
||||
|
||||
void hv_setup_sched_clock(void *sched_clock)
|
||||
{
|
||||
#ifdef CONFIG_PARAVIRT
|
||||
pv_ops.time.sched_clock = sched_clock;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -1598,7 +1598,7 @@ static void start_sw_tscdeadline(struct kvm_lapic *apic)
|
||||
likely(ns > apic->lapic_timer.timer_advance_ns)) {
|
||||
expire = ktime_add_ns(now, ns);
|
||||
expire = ktime_sub_ns(expire, ktimer->timer_advance_ns);
|
||||
hrtimer_start(&ktimer->timer, expire, HRTIMER_MODE_ABS);
|
||||
hrtimer_start(&ktimer->timer, expire, HRTIMER_MODE_ABS_HARD);
|
||||
} else
|
||||
apic_timer_expired(apic);
|
||||
|
||||
@@ -2299,7 +2299,7 @@ int kvm_create_lapic(struct kvm_vcpu *vcpu, int timer_advance_ns)
|
||||
apic->vcpu = vcpu;
|
||||
|
||||
hrtimer_init(&apic->lapic_timer.timer, CLOCK_MONOTONIC,
|
||||
HRTIMER_MODE_ABS);
|
||||
HRTIMER_MODE_ABS_HARD);
|
||||
apic->lapic_timer.timer.function = apic_timer_fn;
|
||||
if (timer_advance_ns == -1) {
|
||||
apic->lapic_timer.timer_advance_ns = LAPIC_TIMER_ADVANCE_ADJUST_INIT;
|
||||
@@ -2484,7 +2484,7 @@ void __kvm_migrate_apic_timer(struct kvm_vcpu *vcpu)
|
||||
|
||||
timer = &vcpu->arch.apic->lapic_timer.timer;
|
||||
if (hrtimer_cancel(timer))
|
||||
hrtimer_start_expires(timer, HRTIMER_MODE_ABS);
|
||||
hrtimer_start_expires(timer, HRTIMER_MODE_ABS_HARD);
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -3411,15 +3411,14 @@ static bool blk_mq_poll_hybrid_sleep(struct request_queue *q,
|
||||
kt = nsecs;
|
||||
|
||||
mode = HRTIMER_MODE_REL;
|
||||
hrtimer_init_on_stack(&hs.timer, CLOCK_MONOTONIC, mode);
|
||||
hrtimer_init_sleeper_on_stack(&hs, CLOCK_MONOTONIC, mode);
|
||||
hrtimer_set_expires(&hs.timer, kt);
|
||||
|
||||
hrtimer_init_sleeper(&hs, current);
|
||||
do {
|
||||
if (blk_mq_rq_state(rq) == MQ_RQ_COMPLETE)
|
||||
break;
|
||||
set_current_state(TASK_UNINTERRUPTIBLE);
|
||||
hrtimer_start_expires(&hs.timer, mode);
|
||||
hrtimer_sleeper_start_expires(&hs, mode);
|
||||
if (hs.task)
|
||||
io_schedule();
|
||||
hrtimer_cancel(&hs.timer);
|
||||
|
||||
@@ -429,7 +429,7 @@ config ATMEL_ST
|
||||
|
||||
config ATMEL_TCB_CLKSRC
|
||||
bool "Atmel TC Block timer driver" if COMPILE_TEST
|
||||
depends on HAS_IOMEM
|
||||
depends on ARM && HAS_IOMEM
|
||||
select TIMER_OF if OF
|
||||
help
|
||||
Support for Timer Counter Blocks on Atmel SoCs.
|
||||
|
||||
@@ -291,10 +291,8 @@ static int em_sti_probe(struct platform_device *pdev)
|
||||
platform_set_drvdata(pdev, p);
|
||||
|
||||
irq = platform_get_irq(pdev, 0);
|
||||
if (irq < 0) {
|
||||
dev_err(&pdev->dev, "failed to get irq\n");
|
||||
if (irq < 0)
|
||||
return irq;
|
||||
}
|
||||
|
||||
/* map memory, let base point to the STI instance */
|
||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
#include <asm/mshyperv.h>
|
||||
|
||||
static struct clock_event_device __percpu *hv_clock_event;
|
||||
static u64 hv_sched_clock_offset __ro_after_init;
|
||||
|
||||
/*
|
||||
* If false, we're using the old mechanism for stimer0 interrupts
|
||||
@@ -212,19 +213,17 @@ EXPORT_SYMBOL_GPL(hv_stimer_global_cleanup);
|
||||
struct clocksource *hyperv_cs;
|
||||
EXPORT_SYMBOL_GPL(hyperv_cs);
|
||||
|
||||
#ifdef CONFIG_HYPERV_TSCPAGE
|
||||
|
||||
static struct ms_hyperv_tsc_page *tsc_pg;
|
||||
static struct ms_hyperv_tsc_page tsc_pg __aligned(PAGE_SIZE);
|
||||
|
||||
struct ms_hyperv_tsc_page *hv_get_tsc_page(void)
|
||||
{
|
||||
return tsc_pg;
|
||||
return &tsc_pg;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(hv_get_tsc_page);
|
||||
|
||||
static u64 notrace read_hv_sched_clock_tsc(void)
|
||||
static u64 notrace read_hv_clock_tsc(struct clocksource *arg)
|
||||
{
|
||||
u64 current_tick = hv_read_tsc_page(tsc_pg);
|
||||
u64 current_tick = hv_read_tsc_page(&tsc_pg);
|
||||
|
||||
if (current_tick == U64_MAX)
|
||||
hv_get_time_ref_count(current_tick);
|
||||
@@ -232,9 +231,9 @@ static u64 notrace read_hv_sched_clock_tsc(void)
|
||||
return current_tick;
|
||||
}
|
||||
|
||||
static u64 read_hv_clock_tsc(struct clocksource *arg)
|
||||
static u64 read_hv_sched_clock_tsc(void)
|
||||
{
|
||||
return read_hv_sched_clock_tsc();
|
||||
return read_hv_clock_tsc(NULL) - hv_sched_clock_offset;
|
||||
}
|
||||
|
||||
static struct clocksource hyperv_cs_tsc = {
|
||||
@@ -244,9 +243,8 @@ static struct clocksource hyperv_cs_tsc = {
|
||||
.mask = CLOCKSOURCE_MASK(64),
|
||||
.flags = CLOCK_SOURCE_IS_CONTINUOUS,
|
||||
};
|
||||
#endif
|
||||
|
||||
static u64 notrace read_hv_sched_clock_msr(void)
|
||||
static u64 notrace read_hv_clock_msr(struct clocksource *arg)
|
||||
{
|
||||
u64 current_tick;
|
||||
/*
|
||||
@@ -258,9 +256,9 @@ static u64 notrace read_hv_sched_clock_msr(void)
|
||||
return current_tick;
|
||||
}
|
||||
|
||||
static u64 read_hv_clock_msr(struct clocksource *arg)
|
||||
static u64 read_hv_sched_clock_msr(void)
|
||||
{
|
||||
return read_hv_sched_clock_msr();
|
||||
return read_hv_clock_msr(NULL) - hv_sched_clock_offset;
|
||||
}
|
||||
|
||||
static struct clocksource hyperv_cs_msr = {
|
||||
@@ -271,7 +269,6 @@ static struct clocksource hyperv_cs_msr = {
|
||||
.flags = CLOCK_SOURCE_IS_CONTINUOUS,
|
||||
};
|
||||
|
||||
#ifdef CONFIG_HYPERV_TSCPAGE
|
||||
static bool __init hv_init_tsc_clocksource(void)
|
||||
{
|
||||
u64 tsc_msr;
|
||||
@@ -280,12 +277,8 @@ static bool __init hv_init_tsc_clocksource(void)
|
||||
if (!(ms_hyperv.features & HV_MSR_REFERENCE_TSC_AVAILABLE))
|
||||
return false;
|
||||
|
||||
tsc_pg = vmalloc(PAGE_SIZE);
|
||||
if (!tsc_pg)
|
||||
return false;
|
||||
|
||||
hyperv_cs = &hyperv_cs_tsc;
|
||||
phys_addr = page_to_phys(vmalloc_to_page(tsc_pg));
|
||||
phys_addr = virt_to_phys(&tsc_pg);
|
||||
|
||||
/*
|
||||
* The Hyper-V TLFS specifies to preserve the value of reserved
|
||||
@@ -302,17 +295,11 @@ static bool __init hv_init_tsc_clocksource(void)
|
||||
hv_set_clocksource_vdso(hyperv_cs_tsc);
|
||||
clocksource_register_hz(&hyperv_cs_tsc, NSEC_PER_SEC/100);
|
||||
|
||||
/* sched_clock_register is needed on ARM64 but is a no-op on x86 */
|
||||
sched_clock_register(read_hv_sched_clock_tsc, 64, HV_CLOCK_HZ);
|
||||
hv_sched_clock_offset = hyperv_cs->read(hyperv_cs);
|
||||
hv_setup_sched_clock(read_hv_sched_clock_tsc);
|
||||
|
||||
return true;
|
||||
}
|
||||
#else
|
||||
static bool __init hv_init_tsc_clocksource(void)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
void __init hv_init_clocksource(void)
|
||||
{
|
||||
@@ -333,7 +320,7 @@ void __init hv_init_clocksource(void)
|
||||
hyperv_cs = &hyperv_cs_msr;
|
||||
clocksource_register_hz(&hyperv_cs_msr, NSEC_PER_SEC/100);
|
||||
|
||||
/* sched_clock_register is needed on ARM64 but is a no-op on x86 */
|
||||
sched_clock_register(read_hv_sched_clock_msr, 64, HV_CLOCK_HZ);
|
||||
hv_sched_clock_offset = hyperv_cs->read(hyperv_cs);
|
||||
hv_setup_sched_clock(read_hv_sched_clock_msr);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(hv_init_clocksource);
|
||||
|
||||
@@ -221,7 +221,7 @@ static int __init ostm_init(struct device_node *np)
|
||||
}
|
||||
|
||||
rate = clk_get_rate(ostm_clk);
|
||||
ostm->ticks_per_jiffy = (rate + HZ / 2) / HZ;
|
||||
ostm->ticks_per_jiffy = DIV_ROUND_CLOSEST(rate, HZ);
|
||||
|
||||
/*
|
||||
* First probed device will be used as system clocksource. Any
|
||||
|
||||
@@ -776,11 +776,8 @@ static int sh_cmt_register_clockevent(struct sh_cmt_channel *ch,
|
||||
int ret;
|
||||
|
||||
irq = platform_get_irq(ch->cmt->pdev, ch->index);
|
||||
if (irq < 0) {
|
||||
dev_err(&ch->cmt->pdev->dev, "ch%u: failed to get irq\n",
|
||||
ch->index);
|
||||
if (irq < 0)
|
||||
return irq;
|
||||
}
|
||||
|
||||
ret = request_irq(irq, sh_cmt_interrupt,
|
||||
IRQF_TIMER | IRQF_IRQPOLL | IRQF_NOBALANCING,
|
||||
@@ -921,12 +918,24 @@ static const struct platform_device_id sh_cmt_id_table[] = {
|
||||
MODULE_DEVICE_TABLE(platform, sh_cmt_id_table);
|
||||
|
||||
static const struct of_device_id sh_cmt_of_table[] __maybe_unused = {
|
||||
{ .compatible = "renesas,cmt-48", .data = &sh_cmt_info[SH_CMT_48BIT] },
|
||||
{
|
||||
/* deprecated, preserved for backward compatibility */
|
||||
.compatible = "renesas,cmt-48",
|
||||
.data = &sh_cmt_info[SH_CMT_48BIT]
|
||||
},
|
||||
{
|
||||
/* deprecated, preserved for backward compatibility */
|
||||
.compatible = "renesas,cmt-48-gen2",
|
||||
.data = &sh_cmt_info[SH_CMT0_RCAR_GEN2]
|
||||
},
|
||||
{
|
||||
.compatible = "renesas,r8a7740-cmt1",
|
||||
.data = &sh_cmt_info[SH_CMT_48BIT]
|
||||
},
|
||||
{
|
||||
.compatible = "renesas,sh73a0-cmt1",
|
||||
.data = &sh_cmt_info[SH_CMT_48BIT]
|
||||
},
|
||||
{
|
||||
.compatible = "renesas,rcar-gen2-cmt0",
|
||||
.data = &sh_cmt_info[SH_CMT0_RCAR_GEN2]
|
||||
|
||||
@@ -462,11 +462,8 @@ static int sh_tmu_channel_setup(struct sh_tmu_channel *ch, unsigned int index,
|
||||
ch->base = tmu->mapbase + 8 + ch->index * 12;
|
||||
|
||||
ch->irq = platform_get_irq(tmu->pdev, index);
|
||||
if (ch->irq < 0) {
|
||||
dev_err(&tmu->pdev->dev, "ch%u: failed to get irq\n",
|
||||
ch->index);
|
||||
if (ch->irq < 0)
|
||||
return ch->irq;
|
||||
}
|
||||
|
||||
ch->cs_enabled = false;
|
||||
ch->enable_count = 0;
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
#include <linux/irq.h>
|
||||
|
||||
#include <linux/clk.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/ioport.h>
|
||||
#include <linux/io.h>
|
||||
@@ -125,6 +126,18 @@ static u64 notrace tc_sched_clock_read32(void)
|
||||
return tc_get_cycles32(&clksrc);
|
||||
}
|
||||
|
||||
static struct delay_timer tc_delay_timer;
|
||||
|
||||
static unsigned long tc_delay_timer_read(void)
|
||||
{
|
||||
return tc_get_cycles(&clksrc);
|
||||
}
|
||||
|
||||
static unsigned long notrace tc_delay_timer_read32(void)
|
||||
{
|
||||
return tc_get_cycles32(&clksrc);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_GENERIC_CLOCKEVENTS
|
||||
|
||||
struct tc_clkevt_device {
|
||||
@@ -432,6 +445,7 @@ static int __init tcb_clksrc_init(struct device_node *node)
|
||||
/* setup ony channel 0 */
|
||||
tcb_setup_single_chan(&tc, best_divisor_idx);
|
||||
tc_sched_clock = tc_sched_clock_read32;
|
||||
tc_delay_timer.read_current_timer = tc_delay_timer_read32;
|
||||
} else {
|
||||
/* we have three clocks no matter what the
|
||||
* underlying platform supports.
|
||||
@@ -444,6 +458,7 @@ static int __init tcb_clksrc_init(struct device_node *node)
|
||||
/* setup both channel 0 & 1 */
|
||||
tcb_setup_dual_chan(&tc, best_divisor_idx);
|
||||
tc_sched_clock = tc_sched_clock_read;
|
||||
tc_delay_timer.read_current_timer = tc_delay_timer_read;
|
||||
}
|
||||
|
||||
/* and away we go! */
|
||||
@@ -458,6 +473,9 @@ static int __init tcb_clksrc_init(struct device_node *node)
|
||||
|
||||
sched_clock_register(tc_sched_clock, 32, divided_rate);
|
||||
|
||||
tc_delay_timer.freq = divided_rate;
|
||||
register_current_timer_delay(&tc_delay_timer);
|
||||
|
||||
return 0;
|
||||
|
||||
err_unregister_clksrc:
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user