irq.c 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
  1. /*
  2. * linux/arch/sh/boards/se/7722/irq.c
  3. *
  4. * Copyright (C) 2007 Nobuhiro Iwamatsu
  5. *
  6. * Hitachi UL SolutionEngine 7722 Support.
  7. *
  8. * This file is subject to the terms and conditions of the GNU General Public
  9. * License. See the file "COPYING" in the main directory of this archive
  10. * for more details.
  11. */
  12. #include <linux/init.h>
  13. #include <linux/irq.h>
  14. #include <linux/interrupt.h>
  15. #include <asm/irq.h>
  16. #include <asm/io.h>
  17. #include <asm/se7722.h>
  18. #define INTC_INTMSK0 0xFFD00044
  19. #define INTC_INTMSKCLR0 0xFFD00064
  20. struct se7722_data {
  21. unsigned char irq;
  22. unsigned char ipr_idx;
  23. unsigned char shift;
  24. unsigned short priority;
  25. unsigned long addr;
  26. };
  27. static void disable_se7722_irq(unsigned int irq)
  28. {
  29. struct se7722_data *p = get_irq_chip_data(irq);
  30. ctrl_outw( ctrl_inw( p->addr ) | p->priority , p->addr );
  31. }
  32. static void enable_se7722_irq(unsigned int irq)
  33. {
  34. struct se7722_data *p = get_irq_chip_data(irq);
  35. ctrl_outw( ctrl_inw( p->addr ) & ~p->priority , p->addr );
  36. }
  37. static struct irq_chip se7722_irq_chip __read_mostly = {
  38. .name = "SE7722",
  39. .mask = disable_se7722_irq,
  40. .unmask = enable_se7722_irq,
  41. .mask_ack = disable_se7722_irq,
  42. };
  43. static struct se7722_data ipr_irq_table[] = {
  44. /* irq ,idx,sft, priority , addr */
  45. { MRSHPC_IRQ0 , 0 , 0 , MRSHPC_BIT0 , IRQ01_MASK } ,
  46. { MRSHPC_IRQ1 , 0 , 0 , MRSHPC_BIT1 , IRQ01_MASK } ,
  47. { MRSHPC_IRQ2 , 0 , 0 , MRSHPC_BIT2 , IRQ01_MASK } ,
  48. { MRSHPC_IRQ3 , 0 , 0 , MRSHPC_BIT3 , IRQ01_MASK } ,
  49. { SMC_IRQ , 0 , 0 , SMC_BIT , IRQ01_MASK } ,
  50. { EXT_IRQ , 0 , 0 , EXT_BIT , IRQ01_MASK } ,
  51. };
  52. int se7722_irq_demux(int irq)
  53. {
  54. if ((irq == IRQ0_IRQ)||(irq == IRQ1_IRQ)) {
  55. volatile unsigned short intv =
  56. *(volatile unsigned short *)IRQ01_STS;
  57. if (irq == IRQ0_IRQ){
  58. if(intv & SMC_BIT ) {
  59. return SMC_IRQ;
  60. } else if(intv & USB_BIT) {
  61. return USB_IRQ;
  62. } else {
  63. printk("intv =%04x\n", intv);
  64. return SMC_IRQ;
  65. }
  66. } else if(irq == IRQ1_IRQ){
  67. if(intv & MRSHPC_BIT0) {
  68. return MRSHPC_IRQ0;
  69. } else if(intv & MRSHPC_BIT1) {
  70. return MRSHPC_IRQ1;
  71. } else if(intv & MRSHPC_BIT2) {
  72. return MRSHPC_IRQ2;
  73. } else if(intv & MRSHPC_BIT3) {
  74. return MRSHPC_IRQ3;
  75. } else {
  76. printk("BIT_EXTENTION =%04x\n", intv);
  77. return EXT_IRQ;
  78. }
  79. }
  80. }
  81. return irq;
  82. }
  83. /*
  84. * Initialize IRQ setting
  85. */
  86. void __init init_se7722_IRQ(void)
  87. {
  88. int i = 0;
  89. ctrl_outw(0x2000, 0xb03fffec); /* mrshpc irq enable */
  90. ctrl_outl((3 << ((7 - 0) * 4))|(3 << ((7 - 1) * 4)), INTC_INTPRI0); /* irq0 pri=3,irq1,pri=3 */
  91. ctrl_outw((2 << ((7 - 0) * 2))|(2 << ((7 - 1) * 2)), INTC_ICR1); /* irq0,1 low-level irq */
  92. for (i = 0; i < ARRAY_SIZE(ipr_irq_table); i++) {
  93. disable_irq_nosync(ipr_irq_table[i].irq);
  94. set_irq_chip_and_handler_name( ipr_irq_table[i].irq, &se7722_irq_chip,
  95. handle_level_irq, "level");
  96. set_irq_chip_data( ipr_irq_table[i].irq, &ipr_irq_table[i] );
  97. disable_se7722_irq(ipr_irq_table[i].irq);
  98. }
  99. }