2018-08-04 08:23:16 +00:00
|
|
|
// SPDX-License-Identifier: GPL-2.0
|
2017-07-11 01:00:26 +00:00
|
|
|
/*
|
|
|
|
* Copyright (C) 2012 Regents of the University of California
|
|
|
|
* Copyright (C) 2017 SiFive
|
2018-08-04 08:23:16 +00:00
|
|
|
* Copyright (C) 2018 Christoph Hellwig
|
2017-07-11 01:00:26 +00:00
|
|
|
*/
|
|
|
|
|
|
|
|
#include <linux/interrupt.h>
|
|
|
|
#include <linux/irqchip.h>
|
|
|
|
#include <linux/irqdomain.h>
|
2018-10-02 19:15:07 +00:00
|
|
|
#include <linux/seq_file.h>
|
|
|
|
#include <asm/smp.h>
|
2017-07-11 01:00:26 +00:00
|
|
|
|
2018-10-02 19:15:07 +00:00
|
|
|
int arch_show_interrupts(struct seq_file *p, int prec)
|
|
|
|
{
|
|
|
|
show_ipi_stats(p, prec);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2019-10-18 05:20:05 +00:00
|
|
|
asmlinkage __visible void __irq_entry do_IRQ(struct pt_regs *regs)
|
2018-08-04 08:23:16 +00:00
|
|
|
{
|
2020-06-01 09:15:38 +00:00
|
|
|
struct pt_regs *old_regs;
|
2018-08-04 08:23:16 +00:00
|
|
|
|
2019-10-28 12:10:32 +00:00
|
|
|
switch (regs->cause & ~CAUSE_IRQ_FLAG) {
|
2019-12-20 11:09:49 +00:00
|
|
|
case RV_IRQ_TIMER:
|
2020-06-01 09:15:38 +00:00
|
|
|
old_regs = set_irq_regs(regs);
|
|
|
|
irq_enter();
|
2018-08-04 08:23:19 +00:00
|
|
|
riscv_timer_interrupt();
|
2020-06-01 09:15:38 +00:00
|
|
|
irq_exit();
|
|
|
|
set_irq_regs(old_regs);
|
2018-08-04 08:23:19 +00:00
|
|
|
break;
|
2018-08-04 08:23:16 +00:00
|
|
|
#ifdef CONFIG_SMP
|
2019-12-20 11:09:49 +00:00
|
|
|
case RV_IRQ_SOFT:
|
2018-08-04 08:23:16 +00:00
|
|
|
/*
|
|
|
|
* We only use software interrupts to pass IPIs, so if a non-SMP
|
|
|
|
* system gets one, then we don't know what to do.
|
|
|
|
*/
|
2020-06-01 09:15:38 +00:00
|
|
|
handle_IPI(regs);
|
2018-08-04 08:23:16 +00:00
|
|
|
break;
|
|
|
|
#endif
|
2019-12-20 11:09:49 +00:00
|
|
|
case RV_IRQ_EXT:
|
2020-06-01 09:15:38 +00:00
|
|
|
old_regs = set_irq_regs(regs);
|
|
|
|
irq_enter();
|
2018-08-04 08:23:16 +00:00
|
|
|
handle_arch_irq(regs);
|
2020-06-01 09:15:38 +00:00
|
|
|
irq_exit();
|
|
|
|
set_irq_regs(old_regs);
|
2018-08-04 08:23:16 +00:00
|
|
|
break;
|
|
|
|
default:
|
2019-10-28 12:10:32 +00:00
|
|
|
pr_alert("unexpected interrupt cause 0x%lx", regs->cause);
|
2019-04-15 09:14:41 +00:00
|
|
|
BUG();
|
2018-08-04 08:23:16 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-07-11 01:00:26 +00:00
|
|
|
void __init init_IRQ(void)
|
|
|
|
{
|
|
|
|
irqchip_init();
|
|
|
|
}
|