diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2017-11-13 12:12:00 -0800 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2017-11-13 12:12:00 -0800 |
| commit | f3573b8f902c507c721999cc669fbb7e045081b8 (patch) | |
| tree | 703d1d7e58d50dfbf7a9c4810710acf393166a57 /arch/openrisc/kernel/time.c | |
| parent | 9e09d05cfe7df9efa7bbca7d679af534a616026e (diff) | |
| parent | 610f01b9a88a9ef8b506709a825c17395c56a62a (diff) | |
| download | kernel_replicant_linux-f3573b8f902c507c721999cc669fbb7e045081b8.tar.gz kernel_replicant_linux-f3573b8f902c507c721999cc669fbb7e045081b8.tar.bz2 kernel_replicant_linux-f3573b8f902c507c721999cc669fbb7e045081b8.zip | |
Merge tag 'for-linus' of git://github.com/openrisc/linux
Pull OpenRISC updates from Stafford Horne:
"The OpenRISC work is a bit more interesting this time, adding SMP
support and a few general cleanups.
Small Things:
- Move OpenRISC docs into Documentation and clean them up
- Document previously undocumented devicetree bindings
- Update the or1ksim dts to use stdout-path
OpenRISC SMP support details:
- First the "use shadow registers" and "define CPU_BIG_ENDIAN as
true" get the architecture ready for SMP.
- The "add 1 and 2 byte cmpxchg support" and "use qspinlocks and
qrwlocks" add the SMP locking infrastructure as needed. Using the
qspinlocks and qrwlocks as suggested by Peter Z while reviewing the
original spinlocks implementation.
- The "support for ompic" adds a new irqchip device which is used for
IPI communication to support SMP.
- The "initial SMP support" adds smp.c and makes changes to all of
the necessary data-structures to be per-cpu.
The remaining patches are bug fixes and debug helpers which I wanted
to keep separate from the "initial SMP support" in order to allow them
to be reviewed on their own. This includes:
- add cacheflush support to fix icache aliasing
- fix initial preempt state for secondary cpu tasks
- sleep instead of spin on secondary wait
- support framepointers and STACKTRACE_SUPPORT
- enable LOCKDEP_SUPPORT and irqflags tracing
- timer sync: Add tick timer sync logic
- fix possible deadlock in timer sync, pointed out by mips guys
Note: the irqchip patch was reviewed with Marc and we agreed to push
it together with these patches"
* tag 'for-linus' of git://github.com/openrisc/linux:
openrisc: fix possible deadlock scenario during timer sync
openrisc: pass endianness info to sparse
openrisc: add tick timer multi-core sync logic
openrisc: enable LOCKDEP_SUPPORT and irqflags tracing
openrisc: support framepointers and STACKTRACE_SUPPORT
openrisc: add simple_smp dts and defconfig for simulators
openrisc: add cacheflush support to fix icache aliasing
openrisc: sleep instead of spin on secondary wait
openrisc: fix initial preempt state for secondary cpu tasks
openrisc: initial SMP support
irqchip: add initial support for ompic
dt-bindings: add openrisc to vendor prefixes list
openrisc: use qspinlocks and qrwlocks
openrisc: add 1 and 2 byte cmpxchg support
openrisc: use shadow registers to save regs on exception
dt-bindings: openrisc: Add OpenRISC platform SoC
Documentation: openrisc: Updates to README
Documentation: Move OpenRISC docs out of arch/
MAINTAINERS: Add OpenRISC pic maintainer
openrisc: dts: or1ksim: Add stdout-path
Diffstat (limited to 'arch/openrisc/kernel/time.c')
| -rw-r--r-- | arch/openrisc/kernel/time.c | 66 |
1 files changed, 44 insertions, 22 deletions
diff --git a/arch/openrisc/kernel/time.c b/arch/openrisc/kernel/time.c index 687c11d048d7..6baecea27080 100644 --- a/arch/openrisc/kernel/time.c +++ b/arch/openrisc/kernel/time.c @@ -27,8 +27,14 @@ #include <asm/cpuinfo.h> -static int openrisc_timer_set_next_event(unsigned long delta, - struct clock_event_device *dev) +/* Test the timer ticks to count, used in sync routine */ +inline void openrisc_timer_set(unsigned long count) +{ + mtspr(SPR_TTCR, count); +} + +/* Set the timer to trigger in delta cycles */ +inline void openrisc_timer_set_next(unsigned long delta) { u32 c; @@ -44,7 +50,12 @@ static int openrisc_timer_set_next_event(unsigned long delta, * Keep timer in continuous mode always. */ mtspr(SPR_TTMR, SPR_TTMR_CR | SPR_TTMR_IE | c); +} +static int openrisc_timer_set_next_event(unsigned long delta, + struct clock_event_device *dev) +{ + openrisc_timer_set_next(delta); return 0; } @@ -53,13 +64,32 @@ static int openrisc_timer_set_next_event(unsigned long delta, * timers) we cannot enable the PERIODIC feature. The tick timer can run using * one-shot events, so no problem. */ +DEFINE_PER_CPU(struct clock_event_device, clockevent_openrisc_timer); -static struct clock_event_device clockevent_openrisc_timer = { - .name = "openrisc_timer_clockevent", - .features = CLOCK_EVT_FEAT_ONESHOT, - .rating = 300, - .set_next_event = openrisc_timer_set_next_event, -}; +void openrisc_clockevent_init(void) +{ + unsigned int cpu = smp_processor_id(); + struct clock_event_device *evt = + &per_cpu(clockevent_openrisc_timer, cpu); + struct cpuinfo_or1k *cpuinfo = &cpuinfo_or1k[cpu]; + + mtspr(SPR_TTMR, SPR_TTMR_CR); + +#ifdef CONFIG_SMP + evt->broadcast = tick_broadcast; +#endif + evt->name = "openrisc_timer_clockevent", + evt->features = CLOCK_EVT_FEAT_ONESHOT, + evt->rating = 300, + evt->set_next_event = openrisc_timer_set_next_event, + + evt->cpumask = cpumask_of(cpu); + + /* We only have 28 bits */ + clockevents_config_and_register(evt, cpuinfo->clock_frequency, + 100, 0x0fffffff); + +} static inline void timer_ack(void) { @@ -83,7 +113,9 @@ static inline void timer_ack(void) irqreturn_t __irq_entry timer_interrupt(struct pt_regs *regs) { struct pt_regs *old_regs = set_irq_regs(regs); - struct clock_event_device *evt = &clockevent_openrisc_timer; + unsigned int cpu = smp_processor_id(); + struct clock_event_device *evt = + &per_cpu(clockevent_openrisc_timer, cpu); timer_ack(); @@ -99,24 +131,12 @@ irqreturn_t __irq_entry timer_interrupt(struct pt_regs *regs) return IRQ_HANDLED; } -static __init void openrisc_clockevent_init(void) -{ - clockevent_openrisc_timer.cpumask = cpumask_of(0); - - /* We only have 28 bits */ - clockevents_config_and_register(&clockevent_openrisc_timer, - cpuinfo.clock_frequency, - 100, 0x0fffffff); - -} - /** * Clocksource: Based on OpenRISC timer/counter * * This sets up the OpenRISC Tick Timer as a clock source. The tick timer * is 32 bits wide and runs at the CPU clock frequency. */ - static u64 openrisc_timer_read(struct clocksource *cs) { return (u64) mfspr(SPR_TTCR); @@ -132,7 +152,9 @@ static struct clocksource openrisc_timer = { static int __init openrisc_timer_init(void) { - if (clocksource_register_hz(&openrisc_timer, cpuinfo.clock_frequency)) + struct cpuinfo_or1k *cpuinfo = &cpuinfo_or1k[smp_processor_id()]; + + if (clocksource_register_hz(&openrisc_timer, cpuinfo->clock_frequency)) panic("failed to register clocksource"); /* Enable the incrementer: 'continuous' mode with interrupt disabled */ |
