From ce3d4a4111a5f7e6b4e74bceae5faa6ce388e8ec Mon Sep 17 00:00:00 2001 From: John Crispin Date: Sun, 14 Jul 2013 23:08:11 +0200 Subject: [PATCH 05/53] MIPS: use set_mode() to enable/disable the cevt-r4k irq Signed-off-by: John Crispin --- arch/mips/kernel/cevt-r4k.c | 43 +++++++++++++++++++++++++++++++++++++ arch/mips/ralink/Kconfig | 5 +++++ 2 files changed, 48 insertions(+) --- a/arch/mips/kernel/cevt-r4k.c +++ b/arch/mips/kernel/cevt-r4k.c @@ -16,6 +16,31 @@ #include #include +#ifdef CONFIG_CEVT_SYSTICK_QUIRK +static int mips_state_oneshot(struct clock_event_device *evt) +{ + unsigned long flags = IRQF_PERCPU | IRQF_TIMER | IRQF_SHARED; + if (!cp0_timer_irq_installed) { + cp0_timer_irq_installed = 1; + if (request_irq(evt->irq, c0_compare_interrupt, flags, "timer", + c0_compare_interrupt)) + pr_err("Failed to request irq %d (timer)\n", evt->irq); + } + + return 0; +} + +static int mips_state_shutdown(struct clock_event_device *evt) +{ + if (cp0_timer_irq_installed) { + cp0_timer_irq_installed = 0; + free_irq(evt->irq, NULL); + } + + return 0; +} +#endif + static int mips_next_event(unsigned long delta, struct clock_event_device *evt) { @@ -292,7 +317,9 @@ core_initcall(r4k_register_cpufreq_notif int r4k_clockevent_init(void) { +#ifndef CONFIG_CEVT_SYSTICK_QUIRK unsigned long flags = IRQF_PERCPU | IRQF_TIMER | IRQF_SHARED; +#endif unsigned int cpu = smp_processor_id(); struct clock_event_device *cd; unsigned int irq, min_delta; @@ -303,6 +330,15 @@ int r4k_clockevent_init(void) if (!c0_compare_int_usable()) return -ENXIO; +#ifdef CONFIG_CEVT_SYSTICK_QUIRK + /* + * With vectored interrupts things are getting platform specific. + * get_c0_compare_int is a hook to allow a platform to return the + * interrupt number of its liking. + */ + irq = get_c0_compare_int(); +#endif + cd = &per_cpu(mips_clockevent_device, cpu); cd->name = "MIPS"; @@ -314,11 +350,17 @@ int r4k_clockevent_init(void) cd->rating = 300; cd->cpumask = cpumask_of(cpu); +#ifdef CONFIG_CEVT_SYSTICK_QUIRK + cd->irq = irq; + cd->set_state_shutdown = mips_state_shutdown; + cd->set_state_oneshot = mips_state_oneshot; +#endif cd->set_next_event = mips_next_event; cd->event_handler = mips_event_handler; clockevents_config_and_register(cd, mips_hpt_frequency, min_delta, 0x7fffffff); +#ifndef CONFIG_CEVT_SYSTICK_QUIRK if (cp0_timer_irq_installed) return 0; @@ -334,6 +376,7 @@ int r4k_clockevent_init(void) if (request_irq(irq, c0_compare_interrupt, flags, "timer", c0_compare_interrupt)) pr_err("Failed to request irq %d (timer)\n", irq); +#endif return 0; } --- a/arch/mips/ralink/Kconfig +++ b/arch/mips/ralink/Kconfig @@ -1,12 +1,17 @@ # SPDX-License-Identifier: GPL-2.0 if RALINK +config CEVT_SYSTICK_QUIRK + bool + default n + config CLKEVT_RT3352 bool depends on SOC_RT305X || SOC_MT7620 default y select TIMER_OF select CLKSRC_MMIO + select CEVT_SYSTICK_QUIRK config RALINK_ILL_ACC bool