irq.c 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  1. /*
  2. * Copyright (C) Telechips, Inc.
  3. * Copyright (C) 2009-2010 Hans J. Koch <hjk@linutronix.de>
  4. *
  5. * Licensed under the terms of the GNU GPL version 2.
  6. */
  7. #include <linux/init.h>
  8. #include <linux/interrupt.h>
  9. #include <linux/io.h>
  10. #include <asm/irq.h>
  11. #include <asm/mach/irq.h>
  12. #include <mach/tcc8k-regs.h>
  13. #include <mach/irqs.h>
  14. #include "common.h"
  15. /* Disable IRQ */
  16. static void tcc8000_mask_ack_irq0(struct irq_data *d)
  17. {
  18. PIC0_IEN &= ~(1 << d->irq);
  19. PIC0_CREQ |= (1 << d->irq);
  20. }
  21. static void tcc8000_mask_ack_irq1(struct irq_data *d)
  22. {
  23. PIC1_IEN &= ~(1 << (d->irq - 32));
  24. PIC1_CREQ |= (1 << (d->irq - 32));
  25. }
  26. static void tcc8000_mask_irq0(struct irq_data *d)
  27. {
  28. PIC0_IEN &= ~(1 << d->irq);
  29. }
  30. static void tcc8000_mask_irq1(struct irq_data *d)
  31. {
  32. PIC1_IEN &= ~(1 << (d->irq - 32));
  33. }
  34. static void tcc8000_ack_irq0(struct irq_data *d)
  35. {
  36. PIC0_CREQ |= (1 << d->irq);
  37. }
  38. static void tcc8000_ack_irq1(struct irq_data *d)
  39. {
  40. PIC1_CREQ |= (1 << (d->irq - 32));
  41. }
  42. /* Enable IRQ */
  43. static void tcc8000_unmask_irq0(struct irq_data *d)
  44. {
  45. PIC0_IEN |= (1 << d->irq);
  46. PIC0_INTOEN |= (1 << d->irq);
  47. }
  48. static void tcc8000_unmask_irq1(struct irq_data *d)
  49. {
  50. PIC1_IEN |= (1 << (d->irq - 32));
  51. PIC1_INTOEN |= (1 << (d->irq - 32));
  52. }
  53. static struct irq_chip tcc8000_irq_chip0 = {
  54. .name = "tcc_irq0",
  55. .irq_mask = tcc8000_mask_irq0,
  56. .irq_ack = tcc8000_ack_irq0,
  57. .irq_mask_ack = tcc8000_mask_ack_irq0,
  58. .irq_unmask = tcc8000_unmask_irq0,
  59. };
  60. static struct irq_chip tcc8000_irq_chip1 = {
  61. .name = "tcc_irq1",
  62. .irq_mask = tcc8000_mask_irq1,
  63. .irq_ack = tcc8000_ack_irq1,
  64. .irq_mask_ack = tcc8000_mask_ack_irq1,
  65. .irq_unmask = tcc8000_unmask_irq1,
  66. };
  67. void __init tcc8k_init_irq(void)
  68. {
  69. int irqno;
  70. /* Mask and clear all interrupts */
  71. PIC0_IEN = 0x00000000;
  72. PIC0_CREQ = 0xffffffff;
  73. PIC1_IEN = 0x00000000;
  74. PIC1_CREQ = 0xffffffff;
  75. PIC0_MEN0 = 0x00000003;
  76. PIC1_MEN1 = 0x00000003;
  77. PIC1_MEN = 0x00000003;
  78. /* let all IRQs be level triggered */
  79. PIC0_TMODE = 0xffffffff;
  80. PIC1_TMODE = 0xffffffff;
  81. /* all IRQs are IRQs (not FIQs) */
  82. PIC0_IRQSEL = 0xffffffff;
  83. PIC1_IRQSEL = 0xffffffff;
  84. for (irqno = 0; irqno < NR_IRQS; irqno++) {
  85. if (irqno < 32)
  86. irq_set_chip(irqno, &tcc8000_irq_chip0);
  87. else
  88. irq_set_chip(irqno, &tcc8000_irq_chip1);
  89. irq_set_handler(irqno, handle_level_irq);
  90. set_irq_flags(irqno, IRQF_VALID);
  91. }
  92. }