irq.c 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128
  1. /* $Id: irq.c,v 1.1.2.4 2002/11/04 20:33:56 lethal Exp $
  2. *
  3. * arch/sh/boards/cqreek/irq.c
  4. *
  5. * Copyright (C) 2000 Niibe Yutaka
  6. *
  7. * CqREEK IDE/ISA Bridge Support.
  8. *
  9. */
  10. #include <linux/irq.h>
  11. #include <linux/init.h>
  12. #include <asm/cqreek/cqreek.h>
  13. #include <asm/io.h>
  14. #include <asm/io_generic.h>
  15. #include <asm/irq.h>
  16. #include <asm/machvec.h>
  17. #include <asm/machvec_init.h>
  18. #include <asm/rtc.h>
  19. struct cqreek_irq_data {
  20. unsigned short mask_port; /* Port of Interrupt Mask Register */
  21. unsigned short stat_port; /* Port of Interrupt Status Register */
  22. unsigned short bit; /* Value of the bit */
  23. };
  24. static struct cqreek_irq_data cqreek_irq_data[NR_IRQS];
  25. static void disable_cqreek_irq(unsigned int irq)
  26. {
  27. unsigned long flags;
  28. unsigned short mask;
  29. unsigned short mask_port = cqreek_irq_data[irq].mask_port;
  30. unsigned short bit = cqreek_irq_data[irq].bit;
  31. local_irq_save(flags);
  32. /* Disable IRQ */
  33. mask = inw(mask_port) & ~bit;
  34. outw_p(mask, mask_port);
  35. local_irq_restore(flags);
  36. }
  37. static void enable_cqreek_irq(unsigned int irq)
  38. {
  39. unsigned long flags;
  40. unsigned short mask;
  41. unsigned short mask_port = cqreek_irq_data[irq].mask_port;
  42. unsigned short bit = cqreek_irq_data[irq].bit;
  43. local_irq_save(flags);
  44. /* Enable IRQ */
  45. mask = inw(mask_port) | bit;
  46. outw_p(mask, mask_port);
  47. local_irq_restore(flags);
  48. }
  49. static void mask_and_ack_cqreek(unsigned int irq)
  50. {
  51. unsigned short stat_port = cqreek_irq_data[irq].stat_port;
  52. unsigned short bit = cqreek_irq_data[irq].bit;
  53. disable_cqreek_irq(irq);
  54. /* Clear IRQ (it might be edge IRQ) */
  55. inw(stat_port);
  56. outw_p(bit, stat_port);
  57. }
  58. static void end_cqreek_irq(unsigned int irq)
  59. {
  60. if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
  61. enable_cqreek_irq(irq);
  62. }
  63. static unsigned int startup_cqreek_irq(unsigned int irq)
  64. {
  65. enable_cqreek_irq(irq);
  66. return 0;
  67. }
  68. static void shutdown_cqreek_irq(unsigned int irq)
  69. {
  70. disable_cqreek_irq(irq);
  71. }
  72. static struct hw_interrupt_type cqreek_irq_type = {
  73. .typename = "CqREEK-IRQ",
  74. .startup = startup_cqreek_irq,
  75. .shutdown = shutdown_cqreek_irq,
  76. .enable = enable_cqreek_irq,
  77. .disable = disable_cqreek_irq,
  78. .ack = mask_and_ack_cqreek,
  79. .end = end_cqreek_irq
  80. };
  81. int cqreek_has_ide, cqreek_has_isa;
  82. /* XXX: This is just for test for my NE2000 ISA board
  83. What we really need is virtualized IRQ and demultiplexer like HP600 port */
  84. void __init init_cqreek_IRQ(void)
  85. {
  86. if (cqreek_has_ide) {
  87. cqreek_irq_data[14].mask_port = BRIDGE_IDE_INTR_MASK;
  88. cqreek_irq_data[14].stat_port = BRIDGE_IDE_INTR_STAT;
  89. cqreek_irq_data[14].bit = 1;
  90. irq_desc[14].handler = &cqreek_irq_type;
  91. irq_desc[14].status = IRQ_DISABLED;
  92. irq_desc[14].action = 0;
  93. irq_desc[14].depth = 1;
  94. disable_cqreek_irq(14);
  95. }
  96. if (cqreek_has_isa) {
  97. cqreek_irq_data[10].mask_port = BRIDGE_ISA_INTR_MASK;
  98. cqreek_irq_data[10].stat_port = BRIDGE_ISA_INTR_STAT;
  99. cqreek_irq_data[10].bit = (1 << 10);
  100. /* XXX: Err... we may need demultiplexer for ISA irq... */
  101. irq_desc[10].handler = &cqreek_irq_type;
  102. irq_desc[10].status = IRQ_DISABLED;
  103. irq_desc[10].action = 0;
  104. irq_desc[10].depth = 1;
  105. disable_cqreek_irq(10);
  106. }
  107. }