Staging: meilhaus: Remove long-deprecated SA_* interrupt macros.
[pandora-kernel.git] / drivers / staging / meilhaus / me1400_ext_irq.c
1 /**
2  * @file me1400_ext_irq.c
3  *
4  * @brief ME-1400 external interrupt subdevice instance.
5  * @note Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
6  * @author Guenter Gebhardt
7  * @author Krzysztof Gantzke    (k.gantzke@meilhaus.de)
8  */
9
10 /*
11  * Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
12  *
13  * This file is free software; you can redistribute it and/or modify
14  * it under the terms of the GNU General Public License as published by
15  * the Free Software Foundation; either version 2 of the License, or
16  * (at your option) any later version.
17  *
18  * This program is distributed in the hope that it will be useful,
19  * but WITHOUT ANY WARRANTY; without even the implied warranty of
20  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21  * GNU General Public License for more details.
22  *
23  * You should have received a copy of the GNU General Public License
24  * along with this program; if not, write to the Free Software
25  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
26  */
27
28 #ifndef __KERNEL__
29 #  define __KERNEL__
30 #endif
31
32 /*
33  * Includes
34  */
35 #include <linux/version.h>
36 #include <linux/module.h>
37
38 #include <linux/slab.h>
39 #include <linux/spinlock.h>
40 #include <linux/io.h>
41 #include <linux/types.h>
42 #include <linux/interrupt.h>
43
44 #include "medefines.h"
45 #include "meinternal.h"
46 #include "meerror.h"
47 #include "medebug.h"
48 #include "meids.h"
49
50 #include "me1400_ext_irq.h"
51 #include "me1400_ext_irq_reg.h"
52
53 /*
54  * Defines
55  */
56 #define ME1400_EXT_IRQ_MAGIC_NUMBER     0x1401  /**< The magic number of the class structure. */
57 #define ME1400_EXT_IRQ_NUMBER_CHANNELS 1        /**< One channel per counter. */
58
59 /*
60  * Functions
61  */
62
63 static int me1400_ext_irq_io_irq_start(struct me_subdevice *subdevice,
64                                        struct file *filep,
65                                        int channel,
66                                        int irq_source,
67                                        int irq_edge, int irq_arg, int flags)
68 {
69         me1400_ext_irq_subdevice_t *instance;
70         unsigned long cpu_flags;
71         uint8_t tmp;
72
73         PDEBUG("executed.\n");
74
75         instance = (me1400_ext_irq_subdevice_t *) subdevice;
76
77         if (flags & ~ME_IO_IRQ_START_DIO_BIT) {
78                 PERROR("Invalid flag specified.\n");
79                 return ME_ERRNO_INVALID_FLAGS;
80         }
81
82         if (channel) {
83                 PERROR("Invalid channel.\n");
84                 return ME_ERRNO_INVALID_CHANNEL;
85         }
86
87         if (irq_source != ME_IRQ_SOURCE_DIO_LINE) {
88                 PERROR("Invalid irq source.\n");
89                 return ME_ERRNO_INVALID_IRQ_SOURCE;
90         }
91
92         if (irq_edge != ME_IRQ_EDGE_RISING) {
93                 PERROR("Invalid irq edge.\n");
94                 return ME_ERRNO_INVALID_IRQ_EDGE;
95         }
96
97         ME_SUBDEVICE_ENTER;
98
99         spin_lock_irqsave(&instance->subdevice_lock, cpu_flags);
100
101         spin_lock(instance->clk_src_reg_lock);
102 //                      // Enable IRQ on PLX
103 //                      tmp = inb(instance->plx_intcs_reg) | (PLX_LOCAL_INT1_EN | PLX_LOCAL_INT1_POL | PLX_PCI_INT_EN);
104 //                      outb(tmp, instance->plx_intcs_reg);
105 //                      PDEBUG_REG("ctrl_reg outb(PLX:0x%lX)=0x%x\n", instance->plx_intcs_reg, tmp);
106
107         // Enable IRQ
108         switch (instance->device_id) {
109         case PCI_DEVICE_ID_MEILHAUS_ME140C:
110         case PCI_DEVICE_ID_MEILHAUS_ME140D:
111                 tmp = inb(instance->ctrl_reg);
112                 tmp |= ME1400CD_EXT_IRQ_CLK_EN;
113                 outb(tmp, instance->ctrl_reg);
114                 PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n",
115                            instance->reg_base,
116                            instance->ctrl_reg - instance->reg_base, tmp);
117                 break;
118
119         default:
120                 outb(ME1400AB_EXT_IRQ_IRQ_EN, instance->ctrl_reg);
121                 PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n",
122                            instance->reg_base,
123                            instance->ctrl_reg - instance->reg_base,
124                            ME1400AB_EXT_IRQ_IRQ_EN);
125                 break;
126         }
127         spin_unlock(instance->clk_src_reg_lock);
128         instance->rised = 0;
129         spin_unlock_irqrestore(&instance->subdevice_lock, cpu_flags);
130
131         ME_SUBDEVICE_EXIT;
132
133         return ME_ERRNO_SUCCESS;
134 }
135
136 static int me1400_ext_irq_io_irq_wait(struct me_subdevice *subdevice,
137                                       struct file *filep,
138                                       int channel,
139                                       int *irq_count,
140                                       int *value, int time_out, int flags)
141 {
142         me1400_ext_irq_subdevice_t *instance;
143         unsigned long cpu_flags;
144         long t = 0;
145         int err = ME_ERRNO_SUCCESS;
146
147         PDEBUG("executed.\n");
148
149         instance = (me1400_ext_irq_subdevice_t *) subdevice;
150
151         if (flags) {
152                 PERROR("Invalid flag specified.\n");
153                 return ME_ERRNO_INVALID_FLAGS;
154         }
155
156         if (channel) {
157                 PERROR("Invalid channel.\n");
158                 return ME_ERRNO_INVALID_CHANNEL;
159         }
160
161         if (time_out < 0) {
162                 PERROR("Invalid time out.\n");
163                 return ME_ERRNO_INVALID_TIMEOUT;
164         }
165
166         if (time_out) {
167                 /* Convert to ticks */
168                 t = (time_out * HZ) / 1000;
169
170                 if (t == 0)
171                         t = 1;
172         }
173
174         ME_SUBDEVICE_ENTER;
175
176         if (instance->rised <= 0) {
177                 instance->rised = 0;
178                 if (time_out) {
179                         t = wait_event_interruptible_timeout(instance->
180                                                              wait_queue,
181                                                              (instance->rised !=
182                                                               0), t);
183
184                         if (t == 0) {
185                                 PERROR("Wait on interrupt timed out.\n");
186                                 err = ME_ERRNO_TIMEOUT;
187                         }
188                 } else {
189                         wait_event_interruptible(instance->wait_queue,
190                                                  (instance->rised != 0));
191                 }
192
193                 if (instance->rised < 0) {
194                         PERROR("Wait on interrupt aborted by user.\n");
195                         err = ME_ERRNO_CANCELLED;
196                 }
197         }
198
199         if (signal_pending(current)) {
200                 PERROR("Wait on interrupt aborted by signal.\n");
201                 err = ME_ERRNO_SIGNAL;
202         }
203
204         spin_lock_irqsave(&instance->subdevice_lock, cpu_flags);
205         instance->rised = 0;
206         *irq_count = instance->n;
207         *value = 1;
208         spin_unlock_irqrestore(&instance->subdevice_lock, cpu_flags);
209
210         ME_SUBDEVICE_EXIT;
211
212         return err;
213 }
214
215 static int me1400_ext_irq_io_irq_stop(struct me_subdevice *subdevice,
216                                       struct file *filep,
217                                       int channel, int flags)
218 {
219         me1400_ext_irq_subdevice_t *instance;
220         unsigned long cpu_flags;
221         uint8_t tmp;
222         int err = ME_ERRNO_SUCCESS;
223
224         PDEBUG("executed.\n");
225
226         instance = (me1400_ext_irq_subdevice_t *) subdevice;
227
228         if (flags) {
229                 PERROR("Invalid flag specified.\n");
230                 return ME_ERRNO_INVALID_FLAGS;
231         }
232
233         if (channel) {
234                 PERROR("Invalid channel.\n");
235                 return ME_ERRNO_INVALID_CHANNEL;
236         }
237
238         ME_SUBDEVICE_ENTER;
239
240         spin_lock_irqsave(&instance->subdevice_lock, cpu_flags);
241         spin_lock(instance->clk_src_reg_lock);
242 //                      // Disable IRQ on PLX
243 //                      tmp = inb(instance->plx_intcs_reg) & ( ~(PLX_LOCAL_INT1_EN | PLX_LOCAL_INT1_POL | PLX_PCI_INT_EN));
244 //                      outb(tmp, instance->plx_intcs_reg);
245 //                      PDEBUG_REG("ctrl_reg outb(PLX:0x%lX)=0x%x\n", instance->plx_intcs_reg, tmp);
246
247         switch (instance->device_id) {
248         case PCI_DEVICE_ID_MEILHAUS_ME140C:
249         case PCI_DEVICE_ID_MEILHAUS_ME140D:
250                 tmp = inb(instance->ctrl_reg);
251                 tmp &= ~ME1400CD_EXT_IRQ_CLK_EN;
252                 outb(tmp, instance->ctrl_reg);
253                 PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n",
254                            instance->reg_base,
255                            instance->ctrl_reg - instance->reg_base, tmp);
256
257                 break;
258
259         default:
260                 outb(0x00, instance->ctrl_reg);
261                 PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n",
262                            instance->reg_base,
263                            instance->ctrl_reg - instance->reg_base, 0x00);
264                 break;
265         }
266         spin_unlock(instance->clk_src_reg_lock);
267         instance->rised = -1;
268         spin_unlock_irqrestore(&instance->subdevice_lock, cpu_flags);
269         wake_up_interruptible_all(&instance->wait_queue);
270
271         ME_SUBDEVICE_EXIT;
272
273         return err;
274 }
275
276 static int me1400_ext_irq_io_reset_subdevice(struct me_subdevice *subdevice,
277                                              struct file *filep, int flags)
278 {
279         me1400_ext_irq_subdevice_t *instance =
280             (me1400_ext_irq_subdevice_t *) subdevice;
281
282         PDEBUG("executed.\n");
283
284         if (flags) {
285                 PERROR("Invalid flag specified.\n");
286                 return ME_ERRNO_INVALID_FLAGS;
287         }
288
289         instance->n = 0;
290         return me1400_ext_irq_io_irq_stop(subdevice, filep, 0, flags);
291 }
292
293 static int me1400_ext_irq_query_number_channels(struct me_subdevice *subdevice,
294                                                 int *number)
295 {
296         PDEBUG("executed.\n");
297         *number = ME1400_EXT_IRQ_NUMBER_CHANNELS;
298         return ME_ERRNO_SUCCESS;
299 }
300
301 static int me1400_ext_irq_query_subdevice_type(struct me_subdevice *subdevice,
302                                                int *type, int *subtype)
303 {
304         PDEBUG("executed.\n");
305         *type = ME_TYPE_EXT_IRQ;
306         *subtype = ME_SUBTYPE_SINGLE;
307         return ME_ERRNO_SUCCESS;
308 }
309
310 static int me1400_ext_irq_query_subdevice_caps(struct me_subdevice *subdevice,
311                                                int *caps)
312 {
313         PDEBUG("executed.\n");
314         *caps = ME_CAPS_EXT_IRQ_EDGE_RISING;
315         return ME_ERRNO_SUCCESS;
316 }
317
318 static int me1400_ext_irq_query_subdevice_caps_args(struct me_subdevice
319                                                     *subdevice, int cap,
320                                                     int *args, int count)
321 {
322         PDEBUG("executed.\n");
323         return ME_ERRNO_NOT_SUPPORTED;
324 }
325
326 static irqreturn_t me1400_ext_irq_isr(int irq, void *dev_id)
327 {
328         me1400_ext_irq_subdevice_t *instance;
329         uint32_t status;
330         uint8_t tmp;
331
332         instance = (me1400_ext_irq_subdevice_t *) dev_id;
333
334         if (irq != instance->irq) {
335                 PERROR("Incorrect interrupt num: %d.\n", irq);
336                 return IRQ_NONE;
337         }
338
339         spin_lock(&instance->subdevice_lock);
340         status = inl(instance->plx_intcs_reg);
341 //              if (!((status & PLX_LOCAL_INT1_STATE) && (status & PLX_LOCAL_INT1_EN) && (status & PLX_PCI_INT_EN)))
342         if ((status &
343              (PLX_LOCAL_INT1_STATE | PLX_LOCAL_INT1_EN | PLX_PCI_INT_EN)) !=
344             (PLX_LOCAL_INT1_STATE | PLX_LOCAL_INT1_EN | PLX_PCI_INT_EN)) {
345                 spin_unlock(&instance->subdevice_lock);
346                 PINFO("%ld Shared interrupt. %s(): irq_status_reg=0x%04X\n",
347                       jiffies, __func__, status);
348                 return IRQ_NONE;
349         }
350
351         inl(instance->ctrl_reg);
352
353         PDEBUG("executed.\n");
354
355         instance->n++;
356         instance->rised = 1;
357
358         switch (instance->device_id) {
359
360         case PCI_DEVICE_ID_MEILHAUS_ME140C:
361         case PCI_DEVICE_ID_MEILHAUS_ME140D:
362                 spin_lock(instance->clk_src_reg_lock);
363                 tmp = inb(instance->ctrl_reg);
364                 tmp &= ~ME1400CD_EXT_IRQ_CLK_EN;
365                 outb(tmp, instance->ctrl_reg);
366                 PDEBUG_REG("ctrl_reg outb(0x%lX+0x%lX)=0x%x\n",
367                            instance->reg_base,
368                            instance->ctrl_reg - instance->reg_base, tmp);
369                 tmp |= ME1400CD_EXT_IRQ_CLK_EN;
370                 outb(tmp, instance->ctrl_reg);
371                 PDEBUG_REG("ctrl_reg outb(0x%lX+0x%lX)=0x%x\n",
372                            instance->reg_base,
373                            instance->ctrl_reg - instance->reg_base, tmp);
374                 spin_unlock(instance->clk_src_reg_lock);
375
376                 break;
377
378         default:
379                 outb(0, instance->ctrl_reg);
380                 PDEBUG_REG("ctrl_reg outb(0x%lX+0x%lX)=0x%x\n",
381                            instance->reg_base,
382                            instance->ctrl_reg - instance->reg_base, 0);
383                 outb(ME1400AB_EXT_IRQ_IRQ_EN, instance->ctrl_reg);
384                 PDEBUG_REG("ctrl_reg outb(0x%lX+0x%lX)=0x%x\n",
385                            instance->reg_base,
386                            instance->ctrl_reg - instance->reg_base,
387                            ME1400AB_EXT_IRQ_IRQ_EN);
388                 break;
389         }
390
391         spin_unlock(&instance->subdevice_lock);
392         wake_up_interruptible_all(&instance->wait_queue);
393
394         return IRQ_HANDLED;
395 }
396
397 static void me1400_ext_irq_destructor(struct me_subdevice *subdevice)
398 {
399         me1400_ext_irq_subdevice_t *instance;
400         uint8_t tmp;
401
402         PDEBUG("executed.\n");
403
404         instance = (me1400_ext_irq_subdevice_t *) subdevice;
405
406         // Disable IRQ on PLX
407         tmp =
408             inb(instance->
409                 plx_intcs_reg) & (~(PLX_LOCAL_INT1_EN | PLX_LOCAL_INT1_POL |
410                                     PLX_PCI_INT_EN));
411         outb(tmp, instance->plx_intcs_reg);
412         PDEBUG_REG("ctrl_reg outb(plx:0x%lX)=0x%x\n", instance->plx_intcs_reg,
413                    tmp);
414
415         free_irq(instance->irq, (void *)instance);
416         me_subdevice_deinit(&instance->base);
417         kfree(instance);
418 }
419
420 me1400_ext_irq_subdevice_t *me1400_ext_irq_constructor(uint32_t device_id,
421                                                        uint32_t plx_reg_base,
422                                                        uint32_t me1400_reg_base,
423                                                        spinlock_t *
424                                                        clk_src_reg_lock,
425                                                        int irq)
426 {
427         me1400_ext_irq_subdevice_t *subdevice;
428         int err;
429         uint8_t tmp;
430
431         PDEBUG("executed.\n");
432
433         /* Allocate memory for subdevice instance */
434         subdevice = kmalloc(sizeof(me1400_ext_irq_subdevice_t), GFP_KERNEL);
435
436         if (!subdevice) {
437                 PERROR("Cannot get memory for 1400_ext_irq instance.\n");
438                 return NULL;
439         }
440
441         memset(subdevice, 0, sizeof(me1400_ext_irq_subdevice_t));
442
443         /* Initialize subdevice base class */
444         err = me_subdevice_init(&subdevice->base);
445
446         if (err) {
447                 PERROR("Cannot initialize subdevice base class instance.\n");
448                 kfree(subdevice);
449                 return NULL;
450         }
451         // Initialize spin locks.
452         spin_lock_init(&subdevice->subdevice_lock);
453         subdevice->clk_src_reg_lock = clk_src_reg_lock;
454
455         /* Initialize wait queue */
456         init_waitqueue_head(&subdevice->wait_queue);
457
458         subdevice->irq = irq;
459
460         err = request_irq(irq, me1400_ext_irq_isr,
461                           IRQF_DISABLED | IRQF_SHARED,
462                           ME1400_NAME, (void *)subdevice);
463
464         if (err) {
465                 PERROR("Can't get irq.\n");
466                 me_subdevice_deinit(&subdevice->base);
467                 kfree(subdevice);
468                 return NULL;
469         }
470         PINFO("Registered irq=%d.\n", subdevice->irq);
471
472         /* Initialize registers */
473         subdevice->plx_intcs_reg = plx_reg_base + PLX_INTCSR_REG;
474         subdevice->ctrl_reg = me1400_reg_base + ME1400AB_EXT_IRQ_CTRL_REG;
475 #ifdef MEDEBUG_DEBUG_REG
476         subdevice->reg_base = me1400_reg_base;
477 #endif
478
479         // Enable IRQ on PLX
480         tmp =
481             inb(subdevice->
482                 plx_intcs_reg) | (PLX_LOCAL_INT1_EN | PLX_LOCAL_INT1_POL |
483                                   PLX_PCI_INT_EN);
484         outb(tmp, subdevice->plx_intcs_reg);
485         PDEBUG_REG("ctrl_reg outb(Pplx:0x%lX)=0x%x\n", subdevice->plx_intcs_reg,
486                    tmp);
487
488         /* Initialize the subdevice methods */
489         subdevice->base.me_subdevice_io_irq_start = me1400_ext_irq_io_irq_start;
490         subdevice->base.me_subdevice_io_irq_wait = me1400_ext_irq_io_irq_wait;
491         subdevice->base.me_subdevice_io_irq_stop = me1400_ext_irq_io_irq_stop;
492         subdevice->base.me_subdevice_io_reset_subdevice =
493             me1400_ext_irq_io_reset_subdevice;
494         subdevice->base.me_subdevice_query_number_channels =
495             me1400_ext_irq_query_number_channels;
496         subdevice->base.me_subdevice_query_subdevice_type =
497             me1400_ext_irq_query_subdevice_type;
498         subdevice->base.me_subdevice_query_subdevice_caps =
499             me1400_ext_irq_query_subdevice_caps;
500         subdevice->base.me_subdevice_query_subdevice_caps_args =
501             me1400_ext_irq_query_subdevice_caps_args;
502         subdevice->base.me_subdevice_destructor = me1400_ext_irq_destructor;
503
504         subdevice->rised = 0;
505         subdevice->n = 0;
506
507         return subdevice;
508 }