irq.c 2.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  1. /*
  2. * arch/arm/mach-ns9xxx/irq.c
  3. *
  4. * Copyright (C) 2006,2007 by Digi International Inc.
  5. * All rights reserved.
  6. *
  7. * This program is free software; you can redistribute it and/or modify it
  8. * under the terms of the GNU General Public License version 2 as published by
  9. * the Free Software Foundation.
  10. */
  11. #include <linux/interrupt.h>
  12. #include <asm/mach/irq.h>
  13. #include <asm/mach-types.h>
  14. #include <asm/arch-ns9xxx/regs-sys.h>
  15. #include <asm/arch-ns9xxx/irqs.h>
  16. #include <asm/arch-ns9xxx/board.h>
  17. #include "generic.h"
  18. static void ns9xxx_ack_irq_timer(unsigned int irq)
  19. {
  20. u32 tc = SYS_TC(irq - IRQ_TIMER0);
  21. REGSET(tc, SYS_TCx, INTC, SET);
  22. SYS_TC(irq - IRQ_TIMER0) = tc;
  23. REGSET(tc, SYS_TCx, INTC, UNSET);
  24. SYS_TC(irq - IRQ_TIMER0) = tc;
  25. }
  26. void (*ns9xxx_ack_irq_functions[NR_IRQS])(unsigned int) = {
  27. [IRQ_TIMER0] = ns9xxx_ack_irq_timer,
  28. [IRQ_TIMER1] = ns9xxx_ack_irq_timer,
  29. [IRQ_TIMER2] = ns9xxx_ack_irq_timer,
  30. [IRQ_TIMER3] = ns9xxx_ack_irq_timer,
  31. };
  32. static void ns9xxx_mask_irq(unsigned int irq)
  33. {
  34. /* XXX: better use cpp symbols */
  35. SYS_IC(irq / 4) &= ~(1 << (7 + 8 * (3 - (irq & 3))));
  36. }
  37. static void ns9xxx_ack_irq(unsigned int irq)
  38. {
  39. if (!ns9xxx_ack_irq_functions[irq]) {
  40. printk(KERN_ERR "no ack function for irq %u\n", irq);
  41. BUG();
  42. }
  43. ns9xxx_ack_irq_functions[irq](irq);
  44. SYS_ISRADDR = 0;
  45. }
  46. static void ns9xxx_maskack_irq(unsigned int irq)
  47. {
  48. ns9xxx_mask_irq(irq);
  49. ns9xxx_ack_irq(irq);
  50. }
  51. static void ns9xxx_unmask_irq(unsigned int irq)
  52. {
  53. /* XXX: better use cpp symbols */
  54. SYS_IC(irq / 4) |= 1 << (7 + 8 * (3 - (irq & 3)));
  55. }
  56. static struct irq_chip ns9xxx_chip = {
  57. .ack = ns9xxx_ack_irq,
  58. .mask = ns9xxx_mask_irq,
  59. .mask_ack = ns9xxx_maskack_irq,
  60. .unmask = ns9xxx_unmask_irq,
  61. };
  62. void __init ns9xxx_init_irq(void)
  63. {
  64. int i;
  65. /* disable all IRQs */
  66. for (i = 0; i < 8; ++i)
  67. SYS_IC(i) = (4 * i) << 24 | (4 * i + 1) << 16 |
  68. (4 * i + 2) << 8 | (4 * i + 3);
  69. /* simple interrupt prio table:
  70. * prio(x) < prio(y) <=> x < y
  71. */
  72. for (i = 0; i < 32; ++i)
  73. SYS_IVA(i) = i;
  74. for (i = IRQ_WATCHDOG; i <= IRQ_EXT3; ++i) {
  75. set_irq_chip(i, &ns9xxx_chip);
  76. set_irq_handler(i, handle_level_irq);
  77. set_irq_flags(i, IRQF_VALID);
  78. }
  79. }