mirror of
https://github.com/torvalds/linux.git
synced 2026-06-07 14:04:54 +02:00
Revert "Revert "clocksource/drivers/timer-ti-dm: Handle dra7 timer wrap errata i940""
This reverts commit cb23d3ef63.
Bring back the commit in 5.10.38 that broke the kabi.
Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
Change-Id: Icaf7981dd39bc96ba917c7010d8ea728e6f62a4b
This commit is contained in:
parent
e86d688e51
commit
f92f904d55
|
|
@ -1168,7 +1168,7 @@ timer2: timer@0 {
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
target-module@34000 { /* 0x48034000, ap 7 46.0 */
|
timer3_target: target-module@34000 { /* 0x48034000, ap 7 46.0 */
|
||||||
compatible = "ti,sysc-omap4-timer", "ti,sysc";
|
compatible = "ti,sysc-omap4-timer", "ti,sysc";
|
||||||
reg = <0x34000 0x4>,
|
reg = <0x34000 0x4>,
|
||||||
<0x34010 0x4>;
|
<0x34010 0x4>;
|
||||||
|
|
@ -1195,7 +1195,7 @@ timer3: timer@0 {
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
target-module@36000 { /* 0x48036000, ap 9 4e.0 */
|
timer4_target: target-module@36000 { /* 0x48036000, ap 9 4e.0 */
|
||||||
compatible = "ti,sysc-omap4-timer", "ti,sysc";
|
compatible = "ti,sysc-omap4-timer", "ti,sysc";
|
||||||
reg = <0x36000 0x4>,
|
reg = <0x36000 0x4>,
|
||||||
<0x36010 0x4>;
|
<0x36010 0x4>;
|
||||||
|
|
|
||||||
|
|
@ -46,6 +46,7 @@ aliases {
|
||||||
|
|
||||||
timer {
|
timer {
|
||||||
compatible = "arm,armv7-timer";
|
compatible = "arm,armv7-timer";
|
||||||
|
status = "disabled"; /* See ARM architected timer wrap erratum i940 */
|
||||||
interrupts = <GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>,
|
interrupts = <GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>,
|
||||||
<GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>,
|
<GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>,
|
||||||
<GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>,
|
<GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>,
|
||||||
|
|
@ -1090,3 +1091,22 @@ timer@0 {
|
||||||
assigned-clock-parents = <&sys_32k_ck>;
|
assigned-clock-parents = <&sys_32k_ck>;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* Local timers, see ARM architected timer wrap erratum i940 */
|
||||||
|
&timer3_target {
|
||||||
|
ti,no-reset-on-init;
|
||||||
|
ti,no-idle;
|
||||||
|
timer@0 {
|
||||||
|
assigned-clocks = <&l4per_clkctrl DRA7_L4PER_TIMER3_CLKCTRL 24>;
|
||||||
|
assigned-clock-parents = <&timer_sys_clk_div>;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
&timer4_target {
|
||||||
|
ti,no-reset-on-init;
|
||||||
|
ti,no-idle;
|
||||||
|
timer@0 {
|
||||||
|
assigned-clocks = <&l4per_clkctrl DRA7_L4PER_TIMER4_CLKCTRL 24>;
|
||||||
|
assigned-clock-parents = <&timer_sys_clk_div>;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@
|
||||||
#include <linux/clk.h>
|
#include <linux/clk.h>
|
||||||
#include <linux/clocksource.h>
|
#include <linux/clocksource.h>
|
||||||
#include <linux/clockchips.h>
|
#include <linux/clockchips.h>
|
||||||
|
#include <linux/cpuhotplug.h>
|
||||||
#include <linux/interrupt.h>
|
#include <linux/interrupt.h>
|
||||||
#include <linux/io.h>
|
#include <linux/io.h>
|
||||||
#include <linux/iopoll.h>
|
#include <linux/iopoll.h>
|
||||||
|
|
@ -630,6 +631,78 @@ static int __init dmtimer_clockevent_init(struct device_node *np)
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Dmtimer as percpu timer. See dra7 ARM architected timer wrap erratum i940 */
|
||||||
|
static DEFINE_PER_CPU(struct dmtimer_clockevent, dmtimer_percpu_timer);
|
||||||
|
|
||||||
|
static int __init dmtimer_percpu_timer_init(struct device_node *np, int cpu)
|
||||||
|
{
|
||||||
|
struct dmtimer_clockevent *clkevt;
|
||||||
|
int error;
|
||||||
|
|
||||||
|
if (!cpu_possible(cpu))
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
if (!of_property_read_bool(np->parent, "ti,no-reset-on-init") ||
|
||||||
|
!of_property_read_bool(np->parent, "ti,no-idle"))
|
||||||
|
pr_warn("Incomplete dtb for percpu dmtimer %pOF\n", np->parent);
|
||||||
|
|
||||||
|
clkevt = per_cpu_ptr(&dmtimer_percpu_timer, cpu);
|
||||||
|
|
||||||
|
error = dmtimer_clkevt_init_common(clkevt, np, CLOCK_EVT_FEAT_ONESHOT,
|
||||||
|
cpumask_of(cpu), "percpu-dmtimer",
|
||||||
|
500);
|
||||||
|
if (error)
|
||||||
|
return error;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* See TRM for timer internal resynch latency */
|
||||||
|
static int omap_dmtimer_starting_cpu(unsigned int cpu)
|
||||||
|
{
|
||||||
|
struct dmtimer_clockevent *clkevt = per_cpu_ptr(&dmtimer_percpu_timer, cpu);
|
||||||
|
struct clock_event_device *dev = &clkevt->dev;
|
||||||
|
struct dmtimer_systimer *t = &clkevt->t;
|
||||||
|
|
||||||
|
clockevents_config_and_register(dev, t->rate, 3, ULONG_MAX);
|
||||||
|
irq_force_affinity(dev->irq, cpumask_of(cpu));
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int __init dmtimer_percpu_timer_startup(void)
|
||||||
|
{
|
||||||
|
struct dmtimer_clockevent *clkevt = per_cpu_ptr(&dmtimer_percpu_timer, 0);
|
||||||
|
struct dmtimer_systimer *t = &clkevt->t;
|
||||||
|
|
||||||
|
if (t->sysc) {
|
||||||
|
cpuhp_setup_state(CPUHP_AP_TI_GP_TIMER_STARTING,
|
||||||
|
"clockevents/omap/gptimer:starting",
|
||||||
|
omap_dmtimer_starting_cpu, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
subsys_initcall(dmtimer_percpu_timer_startup);
|
||||||
|
|
||||||
|
static int __init dmtimer_percpu_quirk_init(struct device_node *np, u32 pa)
|
||||||
|
{
|
||||||
|
struct device_node *arm_timer;
|
||||||
|
|
||||||
|
arm_timer = of_find_compatible_node(NULL, NULL, "arm,armv7-timer");
|
||||||
|
if (of_device_is_available(arm_timer)) {
|
||||||
|
pr_warn_once("ARM architected timer wrap issue i940 detected\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pa == 0x48034000) /* dra7 dmtimer3 */
|
||||||
|
return dmtimer_percpu_timer_init(np, 0);
|
||||||
|
else if (pa == 0x48036000) /* dra7 dmtimer4 */
|
||||||
|
return dmtimer_percpu_timer_init(np, 1);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/* Clocksource */
|
/* Clocksource */
|
||||||
static struct dmtimer_clocksource *
|
static struct dmtimer_clocksource *
|
||||||
to_dmtimer_clocksource(struct clocksource *cs)
|
to_dmtimer_clocksource(struct clocksource *cs)
|
||||||
|
|
@ -763,6 +836,9 @@ static int __init dmtimer_systimer_init(struct device_node *np)
|
||||||
if (clockevent == pa)
|
if (clockevent == pa)
|
||||||
return dmtimer_clockevent_init(np);
|
return dmtimer_clockevent_init(np);
|
||||||
|
|
||||||
|
if (of_machine_is_compatible("ti,dra7"))
|
||||||
|
return dmtimer_percpu_quirk_init(np, pa);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -135,6 +135,7 @@ enum cpuhp_state {
|
||||||
CPUHP_AP_RISCV_TIMER_STARTING,
|
CPUHP_AP_RISCV_TIMER_STARTING,
|
||||||
CPUHP_AP_CLINT_TIMER_STARTING,
|
CPUHP_AP_CLINT_TIMER_STARTING,
|
||||||
CPUHP_AP_CSKY_TIMER_STARTING,
|
CPUHP_AP_CSKY_TIMER_STARTING,
|
||||||
|
CPUHP_AP_TI_GP_TIMER_STARTING,
|
||||||
CPUHP_AP_HYPERV_TIMER_STARTING,
|
CPUHP_AP_HYPERV_TIMER_STARTING,
|
||||||
CPUHP_AP_KVM_STARTING,
|
CPUHP_AP_KVM_STARTING,
|
||||||
CPUHP_AP_KVM_ARM_VGIC_INIT_STARTING,
|
CPUHP_AP_KVM_ARM_VGIC_INIT_STARTING,
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user