![Matt Redfearn](/assets/img/avatar_default.png)
The GIC supports running in External Interrupt Controller (EIC) mode, and will signal this via cpu_has_veic if enabled in hardware. Currently the generic kernel will panic if cpu_has_veic is set - but the GIC can legitimately set this flag if either configured to boot in EIC mode, or if the GIC driver enables this mode. Make the kernel not panic in this case, and instead just check if the GIC is present. If so, use it's CPU local interrupt routing functions. If an EIC is present, but it is not the GIC, then the kernel does not know how to get the VIRQ for the CPU local interrupts and should panic. Support for alternative EICs being present is needed here for the generic kernel to support them. Suggested-by: Paul Burton <paul.burton@mips.com> Signed-off-by: Matt Redfearn <matt.redfearn@mips.com> Cc: Ralf Baechle <ralf@linux-mips.org> Cc: linux-mips@linux-mips.org Patchwork: https://patchwork.linux-mips.org/patch/18191/ Signed-off-by: James Hogan <jhogan@kernel.org>
66 lines
1.5 KiB
C
66 lines
1.5 KiB
C
/*
|
|
* Copyright (C) 2016 Imagination Technologies
|
|
* Author: Paul Burton <paul.burton@mips.com>
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify it
|
|
* under the terms of the GNU General Public License as published by the
|
|
* Free Software Foundation; either version 2 of the License, or (at your
|
|
* option) any later version.
|
|
*/
|
|
|
|
#include <linux/clk.h>
|
|
#include <linux/clk-provider.h>
|
|
#include <linux/clocksource.h>
|
|
#include <linux/init.h>
|
|
#include <linux/types.h>
|
|
|
|
#include <asm/irq.h>
|
|
#include <asm/mips-cps.h>
|
|
#include <asm/time.h>
|
|
|
|
int get_c0_fdc_int(void)
|
|
{
|
|
int mips_cpu_fdc_irq;
|
|
|
|
if (mips_gic_present())
|
|
mips_cpu_fdc_irq = gic_get_c0_fdc_int();
|
|
else if (cpu_has_veic)
|
|
panic("Unimplemented!");
|
|
else if (cp0_fdc_irq >= 0)
|
|
mips_cpu_fdc_irq = MIPS_CPU_IRQ_BASE + cp0_fdc_irq;
|
|
else
|
|
mips_cpu_fdc_irq = -1;
|
|
|
|
return mips_cpu_fdc_irq;
|
|
}
|
|
|
|
int get_c0_perfcount_int(void)
|
|
{
|
|
int mips_cpu_perf_irq;
|
|
|
|
if (mips_gic_present())
|
|
mips_cpu_perf_irq = gic_get_c0_perfcount_int();
|
|
else if (cpu_has_veic)
|
|
panic("Unimplemented!");
|
|
else if (cp0_perfcount_irq >= 0)
|
|
mips_cpu_perf_irq = MIPS_CPU_IRQ_BASE + cp0_perfcount_irq;
|
|
else
|
|
mips_cpu_perf_irq = -1;
|
|
|
|
return mips_cpu_perf_irq;
|
|
}
|
|
|
|
unsigned int get_c0_compare_int(void)
|
|
{
|
|
int mips_cpu_timer_irq;
|
|
|
|
if (mips_gic_present())
|
|
mips_cpu_timer_irq = gic_get_c0_compare_int();
|
|
else if (cpu_has_veic)
|
|
panic("Unimplemented!");
|
|
else
|
|
mips_cpu_timer_irq = MIPS_CPU_IRQ_BASE + cp0_compare_irq;
|
|
|
|
return mips_cpu_timer_irq;
|
|
}
|