2 * @file me1400_ext_irq.c
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)
11 * Copyright (C) 2007 Meilhaus Electronic GmbH (support@meilhaus.de)
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.
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.
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.
35 #include <linux/version.h>
36 #include <linux/module.h>
38 #include <linux/slab.h>
39 #include <linux/spinlock.h>
41 #include <linux/types.h>
42 #include <linux/interrupt.h>
44 #include "medefines.h"
45 #include "meinternal.h"
50 #include "me1400_ext_irq.h"
51 #include "me1400_ext_irq_reg.h"
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. */
63 static int me1400_ext_irq_io_irq_start(struct me_subdevice *subdevice,
67 int irq_edge, int irq_arg, int flags)
69 me1400_ext_irq_subdevice_t *instance;
70 unsigned long cpu_flags;
73 PDEBUG("executed.\n");
75 instance = (me1400_ext_irq_subdevice_t *) subdevice;
77 if (flags & ~ME_IO_IRQ_START_DIO_BIT) {
78 PERROR("Invalid flag specified.\n");
79 return ME_ERRNO_INVALID_FLAGS;
83 PERROR("Invalid channel.\n");
84 return ME_ERRNO_INVALID_CHANNEL;
87 if (irq_source != ME_IRQ_SOURCE_DIO_LINE) {
88 PERROR("Invalid irq source.\n");
89 return ME_ERRNO_INVALID_IRQ_SOURCE;
92 if (irq_edge != ME_IRQ_EDGE_RISING) {
93 PERROR("Invalid irq edge.\n");
94 return ME_ERRNO_INVALID_IRQ_EDGE;
99 spin_lock_irqsave(&instance->subdevice_lock, cpu_flags);
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);
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",
116 instance->ctrl_reg - instance->reg_base, tmp);
120 outb(ME1400AB_EXT_IRQ_IRQ_EN, instance->ctrl_reg);
121 PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n",
123 instance->ctrl_reg - instance->reg_base,
124 ME1400AB_EXT_IRQ_IRQ_EN);
127 spin_unlock(instance->clk_src_reg_lock);
129 spin_unlock_irqrestore(&instance->subdevice_lock, cpu_flags);
133 return ME_ERRNO_SUCCESS;
136 static int me1400_ext_irq_io_irq_wait(struct me_subdevice *subdevice,
140 int *value, int time_out, int flags)
142 me1400_ext_irq_subdevice_t *instance;
143 unsigned long cpu_flags;
145 int err = ME_ERRNO_SUCCESS;
147 PDEBUG("executed.\n");
149 instance = (me1400_ext_irq_subdevice_t *) subdevice;
152 PERROR("Invalid flag specified.\n");
153 return ME_ERRNO_INVALID_FLAGS;
157 PERROR("Invalid channel.\n");
158 return ME_ERRNO_INVALID_CHANNEL;
162 PERROR("Invalid time out.\n");
163 return ME_ERRNO_INVALID_TIMEOUT;
167 /* Convert to ticks */
168 t = (time_out * HZ) / 1000;
176 if (instance->rised <= 0) {
179 t = wait_event_interruptible_timeout(instance->
185 PERROR("Wait on interrupt timed out.\n");
186 err = ME_ERRNO_TIMEOUT;
189 wait_event_interruptible(instance->wait_queue,
190 (instance->rised != 0));
193 if (instance->rised < 0) {
194 PERROR("Wait on interrupt aborted by user.\n");
195 err = ME_ERRNO_CANCELLED;
199 if (signal_pending(current)) {
200 PERROR("Wait on interrupt aborted by signal.\n");
201 err = ME_ERRNO_SIGNAL;
204 spin_lock_irqsave(&instance->subdevice_lock, cpu_flags);
206 *irq_count = instance->n;
208 spin_unlock_irqrestore(&instance->subdevice_lock, cpu_flags);
215 static int me1400_ext_irq_io_irq_stop(struct me_subdevice *subdevice,
217 int channel, int flags)
219 me1400_ext_irq_subdevice_t *instance;
220 unsigned long cpu_flags;
222 int err = ME_ERRNO_SUCCESS;
224 PDEBUG("executed.\n");
226 instance = (me1400_ext_irq_subdevice_t *) subdevice;
229 PERROR("Invalid flag specified.\n");
230 return ME_ERRNO_INVALID_FLAGS;
234 PERROR("Invalid channel.\n");
235 return ME_ERRNO_INVALID_CHANNEL;
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);
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",
255 instance->ctrl_reg - instance->reg_base, tmp);
260 outb(0x00, instance->ctrl_reg);
261 PDEBUG_REG("ctrl_reg outl(0x%lX+0x%lX)=0x%x\n",
263 instance->ctrl_reg - instance->reg_base, 0x00);
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);
276 static int me1400_ext_irq_io_reset_subdevice(struct me_subdevice *subdevice,
277 struct file *filep, int flags)
279 me1400_ext_irq_subdevice_t *instance =
280 (me1400_ext_irq_subdevice_t *) subdevice;
282 PDEBUG("executed.\n");
285 PERROR("Invalid flag specified.\n");
286 return ME_ERRNO_INVALID_FLAGS;
290 return me1400_ext_irq_io_irq_stop(subdevice, filep, 0, flags);
293 static int me1400_ext_irq_query_number_channels(struct me_subdevice *subdevice,
296 PDEBUG("executed.\n");
297 *number = ME1400_EXT_IRQ_NUMBER_CHANNELS;
298 return ME_ERRNO_SUCCESS;
301 static int me1400_ext_irq_query_subdevice_type(struct me_subdevice *subdevice,
302 int *type, int *subtype)
304 PDEBUG("executed.\n");
305 *type = ME_TYPE_EXT_IRQ;
306 *subtype = ME_SUBTYPE_SINGLE;
307 return ME_ERRNO_SUCCESS;
310 static int me1400_ext_irq_query_subdevice_caps(struct me_subdevice *subdevice,
313 PDEBUG("executed.\n");
314 *caps = ME_CAPS_EXT_IRQ_EDGE_RISING;
315 return ME_ERRNO_SUCCESS;
318 static int me1400_ext_irq_query_subdevice_caps_args(struct me_subdevice
320 int *args, int count)
322 PDEBUG("executed.\n");
323 return ME_ERRNO_NOT_SUPPORTED;
326 static irqreturn_t me1400_ext_irq_isr(int irq, void *dev_id)
328 me1400_ext_irq_subdevice_t *instance;
332 instance = (me1400_ext_irq_subdevice_t *) dev_id;
334 if (irq != instance->irq) {
335 PERROR("Incorrect interrupt num: %d.\n", irq);
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)))
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);
351 inl(instance->ctrl_reg);
353 PDEBUG("executed.\n");
358 switch (instance->device_id) {
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",
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",
373 instance->ctrl_reg - instance->reg_base, tmp);
374 spin_unlock(instance->clk_src_reg_lock);
379 outb(0, instance->ctrl_reg);
380 PDEBUG_REG("ctrl_reg outb(0x%lX+0x%lX)=0x%x\n",
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",
386 instance->ctrl_reg - instance->reg_base,
387 ME1400AB_EXT_IRQ_IRQ_EN);
391 spin_unlock(&instance->subdevice_lock);
392 wake_up_interruptible_all(&instance->wait_queue);
397 static void me1400_ext_irq_destructor(struct me_subdevice *subdevice)
399 me1400_ext_irq_subdevice_t *instance;
402 PDEBUG("executed.\n");
404 instance = (me1400_ext_irq_subdevice_t *) subdevice;
406 // Disable IRQ on PLX
409 plx_intcs_reg) & (~(PLX_LOCAL_INT1_EN | PLX_LOCAL_INT1_POL |
411 outb(tmp, instance->plx_intcs_reg);
412 PDEBUG_REG("ctrl_reg outb(plx:0x%lX)=0x%x\n", instance->plx_intcs_reg,
415 free_irq(instance->irq, (void *)instance);
416 me_subdevice_deinit(&instance->base);
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,
427 me1400_ext_irq_subdevice_t *subdevice;
431 PDEBUG("executed.\n");
433 /* Allocate memory for subdevice instance */
434 subdevice = kmalloc(sizeof(me1400_ext_irq_subdevice_t), GFP_KERNEL);
437 PERROR("Cannot get memory for 1400_ext_irq instance.\n");
441 memset(subdevice, 0, sizeof(me1400_ext_irq_subdevice_t));
443 /* Initialize subdevice base class */
444 err = me_subdevice_init(&subdevice->base);
447 PERROR("Cannot initialize subdevice base class instance.\n");
451 // Initialize spin locks.
452 spin_lock_init(&subdevice->subdevice_lock);
453 subdevice->clk_src_reg_lock = clk_src_reg_lock;
455 /* Initialize wait queue */
456 init_waitqueue_head(&subdevice->wait_queue);
458 subdevice->irq = irq;
460 err = request_irq(irq, me1400_ext_irq_isr,
462 IRQF_DISABLED | IRQF_SHARED,
464 SA_INTERRUPT | SA_SHIRQ,
466 ME1400_NAME, (void *)subdevice);
469 PERROR("Can't get irq.\n");
470 me_subdevice_deinit(&subdevice->base);
474 PINFO("Registered irq=%d.\n", subdevice->irq);
476 /* Initialize registers */
477 subdevice->plx_intcs_reg = plx_reg_base + PLX_INTCSR_REG;
478 subdevice->ctrl_reg = me1400_reg_base + ME1400AB_EXT_IRQ_CTRL_REG;
479 #ifdef MEDEBUG_DEBUG_REG
480 subdevice->reg_base = me1400_reg_base;
486 plx_intcs_reg) | (PLX_LOCAL_INT1_EN | PLX_LOCAL_INT1_POL |
488 outb(tmp, subdevice->plx_intcs_reg);
489 PDEBUG_REG("ctrl_reg outb(Pplx:0x%lX)=0x%x\n", subdevice->plx_intcs_reg,
492 /* Initialize the subdevice methods */
493 subdevice->base.me_subdevice_io_irq_start = me1400_ext_irq_io_irq_start;
494 subdevice->base.me_subdevice_io_irq_wait = me1400_ext_irq_io_irq_wait;
495 subdevice->base.me_subdevice_io_irq_stop = me1400_ext_irq_io_irq_stop;
496 subdevice->base.me_subdevice_io_reset_subdevice =
497 me1400_ext_irq_io_reset_subdevice;
498 subdevice->base.me_subdevice_query_number_channels =
499 me1400_ext_irq_query_number_channels;
500 subdevice->base.me_subdevice_query_subdevice_type =
501 me1400_ext_irq_query_subdevice_type;
502 subdevice->base.me_subdevice_query_subdevice_caps =
503 me1400_ext_irq_query_subdevice_caps;
504 subdevice->base.me_subdevice_query_subdevice_caps_args =
505 me1400_ext_irq_query_subdevice_caps_args;
506 subdevice->base.me_subdevice_destructor = me1400_ext_irq_destructor;
508 subdevice->rised = 0;