source: GPL/trunk/lib32/irq.c@ 76

Last change on this file since 76 was 76, checked in by vladest, 19 years ago

Latest ALSA patches
HDA patches
Patch for Intel from Rudy's
Fixes locks on NM256 chipsets
Fixes PM on Maestro3 chipsets

File size: 7.3 KB
Line 
1/* $Id: irq.c,v 1.1.1.1 2003/07/02 13:57:02 eleph Exp $ */
2/*
3 * OS/2 implementation of Linux irq kernel services
4 *
5 * (C) 2000-2002 InnoTek Systemberatung GmbH
6 * (C) 2000-2001 Sander van Leeuwen (sandervl@xs4all.nl)
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License as
10 * published by the Free Software Foundation; either version 2 of
11 * the License, or (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public
19 * License along with this program; if not, write to the Free
20 * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139,
21 * USA.
22 *
23 */
24
25#include "linux.h"
26#include <linux/init.h>
27#include <linux/poll.h>
28#include <asm/uaccess.h>
29#include <asm/hardirq.h>
30
31#define LINUX
32#include <ossidc.h>
33#include <ossidc32.h>
34#include <osspci.h>
35#include <dbgos2.h>
36#include "irqos2.h"
37
38
39BOOL fInInterrupt = FALSE;
40extern BOOL fSuspended; //pci.c
41
42
43//******************************************************************************
44//******************************************************************************
45
46static IRQ_SLOT arSlots[MAX_IRQ_SLOTS] = { 0 };
47static ULONG eoiIrq[255] = {0};
48
49
50//******************************************************************************
51//******************************************************************************
52static IRQ_SLOT *FindSlot(unsigned irq)
53{
54 IRQ_SLOT *pSlot;
55
56 for( pSlot = arSlots; pSlot != &arSlots[MAX_IRQ_SLOTS]; pSlot++ )
57 {
58 if( pSlot->irqNo == irq ) return pSlot;
59 }
60
61 return NULL;
62}
63
64
65//******************************************************************************
66//******************************************************************************
67
68int request_irq(unsigned int irq,
69 int (near *handler)(int, void *, struct pt_regs *),
70 unsigned long x0, const char *x1, void *x2)
71{
72 IRQ_SLOT *pSlot = FindSlot(irq);
73 unsigned u, uSlotNo = (unsigned)-1;
74 if( !pSlot )
75 {
76 // find empty slot
77 for( uSlotNo = 0; uSlotNo < MAX_IRQ_SLOTS; uSlotNo++ )
78 {
79 if( arSlots[uSlotNo].flHandlers == 0 )
80 {
81 pSlot = &arSlots[uSlotNo]; break;
82 }
83 }
84
85 }
86
87 if( pSlot )
88 {
89 if(RMRequestIRQ(/*hResMgr,*/ irq, (x0 & SA_SHIRQ) != 0) == FALSE) {
90 dprintf(("RMRequestIRQ failed for irq %d", irq));
91 // return 0;
92 }
93
94 for( u = 0; u < MAX_SHAREDIRQS; u++ )
95 {
96 if( pSlot->irqHandlers[u].handler == NULL )
97 {
98 pSlot->irqNo = irq;
99 pSlot->irqHandlers[u].handler = handler;
100 pSlot->irqHandlers[u].x0 = x0;
101 pSlot->irqHandlers[u].x1 = (char *)x1;
102 pSlot->irqHandlers[u].x2 = x2;
103
104 if( pSlot->flHandlers != 0 ||
105 ALSA_SetIrq(irq, uSlotNo, (x0 & SA_SHIRQ) != 0) )
106 {
107 pSlot->flHandlers |= 1 << u;
108 return 0;
109 }
110
111 break;
112 }
113 }
114 }
115
116 dprintf(("request_irq: Unable to register irq handler for irq %d\n", irq));
117 return 1;
118}
119
120
121//******************************************************************************
122//******************************************************************************
123void free_irq(unsigned int irq, void *userdata)
124{
125 unsigned u;
126 IRQ_SLOT *pSlot;
127
128 if( (pSlot = FindSlot(irq)) != NULL )
129 {
130 for( u = 0; u < MAX_SHAREDIRQS; u++ )
131 {
132 if( pSlot->irqHandlers[u].x2 == userdata )
133 {
134 pSlot->flHandlers &= ~(1 << u);
135 if( pSlot->flHandlers == 0 )
136 {
137 ALSA_FreeIrq(pSlot->irqNo);
138 pSlot->irqNo = 0;
139 // pSlot->fEOI = 0;
140 }
141
142 pSlot->irqHandlers[u].handler = NULL;
143 pSlot->irqHandlers[u].x0 = 0;
144 pSlot->irqHandlers[u].x1 = NULL;
145 pSlot->irqHandlers[u].x2 = NULL;
146
147 return;
148
149 }
150 }
151 }
152}
153
154
155//******************************************************************************
156//******************************************************************************
157void eoi_irq(unsigned int irq)
158{
159 /*(void)irq; */
160 /*
161 IRQ_SLOT *pSlot = FindSlot(irq);
162
163 if( pSlot ) pSlot->fEOI = 1;
164 */
165 eoiIrq[irq]++;
166}
167
168
169//******************************************************************************
170//******************************************************************************
171BOOL process_interrupt(ULONG ulSlotNo, ULONG *pulIrq)
172{
173 unsigned u;
174 int rc;
175 IRQ_SLOT *pSlot;
176
177#ifdef DEBUG
178 dprintf(("enter int proc %d %d",ulSlotNo, *pulIrq));
179#endif
180
181 if(fSuspended)
182 {//If our device is suspended, then we can't receive interrupts, so it must
183 //be for some other device
184 //Don't pass it to the linux handler as the device doesn't respond as expected
185 //when suspended
186#ifdef DEBUG
187 dprintf(("Slot %d IRQ %d suspended",ulSlotNo, *pulIrq));
188#endif
189 return FALSE;
190 }
191
192 if( ulSlotNo < MAX_IRQ_SLOTS )
193 {
194 pSlot = &arSlots[ulSlotNo];
195
196 for( u = 0; u < MAX_SHAREDIRQS; u++ )
197 {
198 if(pSlot && pSlot->irqHandlers[u].handler )
199 {
200 fInInterrupt = TRUE;
201 rc = pSlot->irqHandlers[u].handler(pSlot->irqNo,
202 pSlot->irqHandlers[u].x2, 0);
203 if (rc == 1) eoi_irq(pSlot->irqNo);
204 rc = (eoiIrq[pSlot->irqNo] > 0);
205 fInInterrupt = FALSE;
206
207 if( rc /*== 1 || pSlot->fEOI*/ ) {
208
209 *pulIrq = pSlot->irqNo;
210 // pSlot->fEOI = 0;
211
212 //ok, this interrupt was intended for us; notify the 16 bits MMPM/2 driver
213 OSS32_ProcessIRQ();
214#ifdef DEBUG
215 dprintf(("exit(1) int proc %d %d",ulSlotNo, *pulIrq));
216#endif
217 eoiIrq[pSlot->irqNo] = 0;
218 return TRUE;
219 }
220 }
221 }
222 }
223#ifdef DEBUG
224 dprintf(("exit(0) int proc %d %d",ulSlotNo, *pulIrq));
225#endif
226
227 return FALSE;
228}
229
230
231//******************************************************************************
232//******************************************************************************
233int in_interrupt()
234{
235 return fInInterrupt;
236}
237
238
239//******************************************************************************
240//******************************************************************************
241void disable_irq(int irq)
242{
243 dprintf(("disable_irq %d NOT implemented", irq));
244}
245
246//******************************************************************************
247//******************************************************************************
248
Note: See TracBrowser for help on using the repository browser.