irq.c 2.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  1. /*
  2. * Copyright (C) 2013 Altera Corporation
  3. * Copyright (C) 2011 Tobias Klauser <tklauser@distanz.ch>
  4. * Copyright (C) 2008 Thomas Chou <thomas@wytron.com.tw>
  5. *
  6. * based on irq.c from m68k which is:
  7. *
  8. * Copyright (C) 2007 Greg Ungerer <gerg@snapgear.com>
  9. *
  10. * This program is free software; you can redistribute it and/or modify
  11. * it under the terms of the GNU General Public License as published by
  12. * the Free Software Foundation; either version 2 of the License, or
  13. * (at your option) any later version.
  14. *
  15. * This program is distributed in the hope that it will be useful,
  16. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  17. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  18. * GNU General Public License for more details.
  19. *
  20. * You should have received a copy of the GNU General Public License
  21. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  22. *
  23. */
  24. #include <linux/init.h>
  25. #include <linux/interrupt.h>
  26. #include <linux/of.h>
  27. static u32 ienable;
  28. asmlinkage void do_IRQ(int hwirq, struct pt_regs *regs)
  29. {
  30. struct pt_regs *oldregs = set_irq_regs(regs);
  31. int irq;
  32. irq_enter();
  33. irq = irq_find_mapping(NULL, hwirq);
  34. generic_handle_irq(irq);
  35. irq_exit();
  36. set_irq_regs(oldregs);
  37. }
  38. static void chip_unmask(struct irq_data *d)
  39. {
  40. ienable |= (1 << d->hwirq);
  41. WRCTL(CTL_IENABLE, ienable);
  42. }
  43. static void chip_mask(struct irq_data *d)
  44. {
  45. ienable &= ~(1 << d->hwirq);
  46. WRCTL(CTL_IENABLE, ienable);
  47. }
  48. static struct irq_chip m_irq_chip = {
  49. .name = "NIOS2-INTC",
  50. .irq_unmask = chip_unmask,
  51. .irq_mask = chip_mask,
  52. };
  53. static int irq_map(struct irq_domain *h, unsigned int virq,
  54. irq_hw_number_t hw_irq_num)
  55. {
  56. irq_set_chip_and_handler(virq, &m_irq_chip, handle_level_irq);
  57. return 0;
  58. }
  59. static struct irq_domain_ops irq_ops = {
  60. .map = irq_map,
  61. .xlate = irq_domain_xlate_onecell,
  62. };
  63. void __init init_IRQ(void)
  64. {
  65. struct irq_domain *domain;
  66. struct device_node *node;
  67. node = of_find_compatible_node(NULL, NULL, "altr,nios2-1.0");
  68. if (!node)
  69. node = of_find_compatible_node(NULL, NULL, "altr,nios2-1.1");
  70. BUG_ON(!node);
  71. domain = irq_domain_add_linear(node, NIOS2_CPU_NR_IRQS, &irq_ops, NULL);
  72. BUG_ON(!domain);
  73. irq_set_default_host(domain);
  74. of_node_put(node);
  75. /* Load the initial ienable value */
  76. ienable = RDCTL(CTL_IENABLE);
  77. }