setup_hd64461.c
上传用户:lgb322
上传日期:2013-02-24
资源大小:30529k
文件大小:3k
源码类别:

嵌入式Linux

开发平台:

Unix_Linux

  1. /*
  2.  * $Id: setup_hd64461.c,v 1.9 2001/07/15 23:26:56 gniibe Exp $
  3.  * Copyright (C) 2000 YAEGASHI Takeshi
  4.  * Hitachi HD64461 companion chip support
  5.  */
  6. #include <linux/config.h>
  7. #include <linux/sched.h>
  8. #include <linux/kernel.h>
  9. #include <linux/param.h>
  10. #include <linux/interrupt.h>
  11. #include <linux/init.h>
  12. #include <linux/irq.h>
  13. #include <asm/io.h>
  14. #include <asm/irq.h>
  15. #include <asm/hd64461.h>
  16. static void disable_hd64461_irq(unsigned int irq)
  17. {
  18. unsigned long flags;
  19. unsigned short nimr;
  20. unsigned short mask = 1 << (irq - HD64461_IRQBASE);
  21. save_and_cli(flags);
  22. nimr = inw(HD64461_NIMR);
  23. nimr |= mask;
  24. outw(nimr, HD64461_NIMR);
  25. restore_flags(flags);
  26. }
  27. static void enable_hd64461_irq(unsigned int irq)
  28. {
  29. unsigned long flags;
  30. unsigned short nimr;
  31. unsigned short mask = 1 << (irq - HD64461_IRQBASE);
  32. save_and_cli(flags);
  33. nimr = inw(HD64461_NIMR);
  34. nimr &= ~mask;
  35. outw(nimr, HD64461_NIMR);
  36. restore_flags(flags);
  37. }
  38. static void mask_and_ack_hd64461(unsigned int irq)
  39. {
  40. disable_hd64461_irq(irq);
  41. #ifdef CONFIG_HD64461_ENABLER
  42. if (irq == HD64461_IRQBASE + 13)
  43. outb(0x00, HD64461_PCC1CSCR);
  44. #endif
  45. }
  46. static void end_hd64461_irq(unsigned int irq)
  47. {
  48. if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
  49. enable_hd64461_irq(irq);
  50. }
  51. static unsigned int startup_hd64461_irq(unsigned int irq)
  52. enable_hd64461_irq(irq);
  53. return 0;
  54. }
  55. static void shutdown_hd64461_irq(unsigned int irq)
  56. {
  57. disable_hd64461_irq(irq);
  58. }
  59. static struct hw_interrupt_type hd64461_irq_type = {
  60. "HD64461-IRQ",
  61. startup_hd64461_irq,
  62. shutdown_hd64461_irq,
  63. enable_hd64461_irq,
  64. disable_hd64461_irq,
  65. mask_and_ack_hd64461,
  66. end_hd64461_irq
  67. };
  68. static void hd64461_interrupt(int irq, void *dev_id, struct pt_regs *regs)
  69. {
  70. printk(KERN_INFO
  71.        "HD64461: spurious interrupt, nirr: 0x%x nimr: 0x%xn",
  72.        inw(HD64461_NIRR), inw(HD64461_NIMR));
  73. }
  74. int hd64461_irq_demux(int irq)
  75. {
  76. if (irq == CONFIG_HD64461_IRQ) {
  77. unsigned short bit;
  78. unsigned short nirr = inw(HD64461_NIRR);
  79. unsigned short nimr = inw(HD64461_NIMR);
  80. nirr &= ~nimr;
  81. for (bit = 1, irq = 0; irq < 16; bit <<= 1, irq++)
  82. if (nirr & bit) break;
  83. if (irq == 16) irq = CONFIG_HD64461_IRQ;
  84. else irq += HD64461_IRQBASE;
  85. }
  86. return __irq_demux(irq);
  87. }
  88. static struct irqaction irq0  = { hd64461_interrupt, SA_INTERRUPT, 0, "HD64461", NULL, NULL};
  89. int __init setup_hd64461(void)
  90. {
  91. int i;
  92. if (!MACH_HD64461)
  93. return 0;
  94. printk(KERN_INFO "HD64461 configured at 0x%x on irq %d(mapped into %d to %d)n",
  95.        CONFIG_HD64461_IOBASE, CONFIG_HD64461_IRQ,
  96.        HD64461_IRQBASE, HD64461_IRQBASE+15);
  97. #if defined(CONFIG_CPU_SUBTYPE_SH7709) /* Should be at processor specific part.. */
  98. outw(0x2240, INTC_ICR1);
  99. #endif
  100. outw(0xffff, HD64461_NIMR);
  101. for (i = HD64461_IRQBASE; i < HD64461_IRQBASE + 16; i++) {
  102. irq_desc[i].handler = &hd64461_irq_type;
  103. }
  104. setup_irq(CONFIG_HD64461_IRQ, &irq0);
  105. #ifdef CONFIG_HD64461_ENABLER
  106. printk(KERN_INFO "HD64461: enabling PCMCIA devicesn");
  107. outb(0x4c, HD64461_PCC1CSCIER);
  108. outb(0x00, HD64461_PCC1CSCR);
  109. #endif
  110. return 0;
  111. }
  112. module_init(setup_hd64461);