irq.c 1.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667
  1. // SPDX-License-Identifier: GPL-2.0
  2. /*
  3. * Copyright (C) 2012 Regents of the University of California
  4. * Copyright (C) 2017 SiFive
  5. * Copyright (C) 2018 Christoph Hellwig
  6. */
  7. #include <linux/interrupt.h>
  8. #include <linux/irqchip.h>
  9. #include <linux/irqdomain.h>
  10. #include <linux/seq_file.h>
  11. #include <asm/smp.h>
  12. /*
  13. * Possible interrupt causes:
  14. */
  15. #define INTERRUPT_CAUSE_SOFTWARE 1
  16. #define INTERRUPT_CAUSE_TIMER 5
  17. #define INTERRUPT_CAUSE_EXTERNAL 9
  18. /*
  19. * The high order bit of the trap cause register is always set for
  20. * interrupts, which allows us to differentiate them from exceptions
  21. * quickly. The INTERRUPT_CAUSE_* macros don't contain that bit, so we
  22. * need to mask it off.
  23. */
  24. #define INTERRUPT_CAUSE_FLAG (1UL << (__riscv_xlen - 1))
  25. int arch_show_interrupts(struct seq_file *p, int prec)
  26. {
  27. show_ipi_stats(p, prec);
  28. return 0;
  29. }
  30. asmlinkage void __irq_entry do_IRQ(struct pt_regs *regs)
  31. {
  32. struct pt_regs *old_regs = set_irq_regs(regs);
  33. irq_enter();
  34. switch (regs->scause & ~INTERRUPT_CAUSE_FLAG) {
  35. case INTERRUPT_CAUSE_TIMER:
  36. riscv_timer_interrupt();
  37. break;
  38. #ifdef CONFIG_SMP
  39. case INTERRUPT_CAUSE_SOFTWARE:
  40. /*
  41. * We only use software interrupts to pass IPIs, so if a non-SMP
  42. * system gets one, then we don't know what to do.
  43. */
  44. riscv_software_interrupt();
  45. break;
  46. #endif
  47. case INTERRUPT_CAUSE_EXTERNAL:
  48. handle_arch_irq(regs);
  49. break;
  50. default:
  51. panic("unexpected interrupt cause");
  52. }
  53. irq_exit();
  54. set_irq_regs(old_regs);
  55. }
  56. void __init init_IRQ(void)
  57. {
  58. irqchip_init();
  59. }