irq_asic.c 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117
  1. /*
  2. * Portions copyright (C) 2005-2009 Scientific Atlanta
  3. * Portions copyright (C) 2009 Cisco Systems, Inc.
  4. *
  5. * Modified from arch/mips/kernel/irq-rm7000.c:
  6. * Copyright (C) 2003 Ralf Baechle
  7. *
  8. * This program is free software; you can redistribute it and/or modify it
  9. * under the terms of the GNU General Public License as published by the
  10. * Free Software Foundation; either version 2 of the License, or (at your
  11. * option) any later version.
  12. */
  13. #include <linux/init.h>
  14. #include <linux/interrupt.h>
  15. #include <linux/kernel.h>
  16. #include <linux/irq.h>
  17. #include <asm/irq_cpu.h>
  18. #include <asm/mipsregs.h>
  19. #include <asm/system.h>
  20. #include <asm/mach-powertv/asic_regs.h>
  21. static inline void unmask_asic_irq(unsigned int irq)
  22. {
  23. unsigned long enable_bit;
  24. enable_bit = (1 << (irq & 0x1f));
  25. switch (irq >> 5) {
  26. case 0:
  27. asic_write(asic_read(ien_int_0) | enable_bit, ien_int_0);
  28. break;
  29. case 1:
  30. asic_write(asic_read(ien_int_1) | enable_bit, ien_int_1);
  31. break;
  32. case 2:
  33. asic_write(asic_read(ien_int_2) | enable_bit, ien_int_2);
  34. break;
  35. case 3:
  36. asic_write(asic_read(ien_int_3) | enable_bit, ien_int_3);
  37. break;
  38. default:
  39. BUG();
  40. }
  41. }
  42. static inline void mask_asic_irq(unsigned int irq)
  43. {
  44. unsigned long disable_mask;
  45. disable_mask = ~(1 << (irq & 0x1f));
  46. switch (irq >> 5) {
  47. case 0:
  48. asic_write(asic_read(ien_int_0) & disable_mask, ien_int_0);
  49. break;
  50. case 1:
  51. asic_write(asic_read(ien_int_1) & disable_mask, ien_int_1);
  52. break;
  53. case 2:
  54. asic_write(asic_read(ien_int_2) & disable_mask, ien_int_2);
  55. break;
  56. case 3:
  57. asic_write(asic_read(ien_int_3) & disable_mask, ien_int_3);
  58. break;
  59. default:
  60. BUG();
  61. }
  62. }
  63. static struct irq_chip asic_irq_chip = {
  64. .name = "ASIC Level",
  65. .ack = mask_asic_irq,
  66. .mask = mask_asic_irq,
  67. .mask_ack = mask_asic_irq,
  68. .unmask = unmask_asic_irq,
  69. .eoi = unmask_asic_irq,
  70. };
  71. void __init asic_irq_init(void)
  72. {
  73. int i;
  74. /* set priority to 0 */
  75. write_c0_status(read_c0_status() & ~(0x0000fc00));
  76. asic_write(0, ien_int_0);
  77. asic_write(0, ien_int_1);
  78. asic_write(0, ien_int_2);
  79. asic_write(0, ien_int_3);
  80. asic_write(0x0fffffff, int_level_3_3);
  81. asic_write(0xffffffff, int_level_3_2);
  82. asic_write(0xffffffff, int_level_3_1);
  83. asic_write(0xffffffff, int_level_3_0);
  84. asic_write(0xffffffff, int_level_2_3);
  85. asic_write(0xffffffff, int_level_2_2);
  86. asic_write(0xffffffff, int_level_2_1);
  87. asic_write(0xffffffff, int_level_2_0);
  88. asic_write(0xffffffff, int_level_1_3);
  89. asic_write(0xffffffff, int_level_1_2);
  90. asic_write(0xffffffff, int_level_1_1);
  91. asic_write(0xffffffff, int_level_1_0);
  92. asic_write(0xffffffff, int_level_0_3);
  93. asic_write(0xffffffff, int_level_0_2);
  94. asic_write(0xffffffff, int_level_0_1);
  95. asic_write(0xffffffff, int_level_0_0);
  96. asic_write(0xf, int_int_scan);
  97. /*
  98. * Initialize interrupt handlers.
  99. */
  100. for (i = 0; i < NR_IRQS; i++)
  101. set_irq_chip_and_handler(i, &asic_irq_chip, handle_level_irq);
  102. }