irqmgr.c 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  1. /*
  2. **********************************************************************
  3. * irqmgr.c - IRQ manager for emu10k1 driver
  4. * Copyright 1999, 2000 Creative Labs, Inc.
  5. *
  6. **********************************************************************
  7. *
  8. * Date Author Summary of changes
  9. * ---- ------ ------------------
  10. * October 20, 1999 Bertrand Lee base code release
  11. *
  12. **********************************************************************
  13. *
  14. * This program is free software; you can redistribute it and/or
  15. * modify it under the terms of the GNU General Public License as
  16. * published by the Free Software Foundation; either version 2 of
  17. * the License, or (at your option) any later version.
  18. *
  19. * This program is distributed in the hope that it will be useful,
  20. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  21. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  22. * GNU General Public License for more details.
  23. *
  24. * You should have received a copy of the GNU General Public
  25. * License along with this program; if not, write to the Free
  26. * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139,
  27. * USA.
  28. *
  29. **********************************************************************
  30. */
  31. #include "hwaccess.h"
  32. #include "8010.h"
  33. #include "cardmi.h"
  34. #include "cardmo.h"
  35. #include "irqmgr.h"
  36. /* Interrupt handler */
  37. irqreturn_t emu10k1_interrupt(int irq, void *dev_id, struct pt_regs *regs)
  38. {
  39. struct emu10k1_card *card = (struct emu10k1_card *) dev_id;
  40. u32 irqstatus, irqstatus_tmp;
  41. int handled = 0;
  42. DPD(4, "emu10k1_interrupt called, irq = %u\n", irq);
  43. /*
  44. ** NOTE :
  45. ** We do a 'while loop' here cos on certain machines, with both
  46. ** playback and recording going on at the same time, IRQs will
  47. ** stop coming in after a while. Checking IPND indeed shows that
  48. ** there are interrupts pending but the PIC says no IRQs pending.
  49. ** I suspect that some boards need edge-triggered IRQs but are not
  50. ** getting that condition if we don't completely clear the IPND
  51. ** (make sure no more interrupts are pending).
  52. ** - Eric
  53. */
  54. while ((irqstatus = inl(card->iobase + IPR))) {
  55. DPD(4, "irq status %#x\n", irqstatus);
  56. irqstatus_tmp = irqstatus;
  57. if (irqstatus & IRQTYPE_TIMER) {
  58. emu10k1_timer_irqhandler(card);
  59. irqstatus &= ~IRQTYPE_TIMER;
  60. }
  61. if (irqstatus & IRQTYPE_DSP) {
  62. emu10k1_dsp_irqhandler(card);
  63. irqstatus &= ~IRQTYPE_DSP;
  64. }
  65. if (irqstatus & IRQTYPE_MPUIN) {
  66. emu10k1_mpuin_irqhandler(card);
  67. irqstatus &= ~IRQTYPE_MPUIN;
  68. }
  69. if (irqstatus & IRQTYPE_MPUOUT) {
  70. emu10k1_mpuout_irqhandler(card);
  71. irqstatus &= ~IRQTYPE_MPUOUT;
  72. }
  73. if (irqstatus & IPR_MUTE) {
  74. emu10k1_mute_irqhandler(card);
  75. irqstatus &=~IPR_MUTE;
  76. }
  77. if (irqstatus & IPR_VOLINCR) {
  78. emu10k1_volincr_irqhandler(card);
  79. irqstatus &=~IPR_VOLINCR;
  80. }
  81. if (irqstatus & IPR_VOLDECR) {
  82. emu10k1_voldecr_irqhandler(card);
  83. irqstatus &=~IPR_VOLDECR;
  84. }
  85. if (irqstatus){
  86. printk(KERN_ERR "emu10k1: Warning, unhandled interrupt: %#08x\n", irqstatus);
  87. //make sure any interrupts we don't handle are disabled:
  88. emu10k1_irq_disable(card, ~(INTE_MIDIRXENABLE | INTE_MIDITXENABLE | INTE_INTERVALTIMERENB |
  89. INTE_VOLDECRENABLE | INTE_VOLINCRENABLE | INTE_MUTEENABLE |
  90. INTE_FXDSPENABLE));
  91. }
  92. /* acknowledge interrupt */
  93. outl(irqstatus_tmp, card->iobase + IPR);
  94. handled = 1;
  95. }
  96. return IRQ_RETVAL(handled);
  97. }