in 104-quad-8.c [1083:1124]
static irqreturn_t quad8_irq_handler(int irq, void *private)
{
struct counter_device *counter = private;
struct quad8 *const priv = counter_priv(counter);
const unsigned long base = priv->base;
unsigned long irq_status;
unsigned long channel;
u8 event;
irq_status = inb(base + QUAD8_REG_INTERRUPT_STATUS);
if (!irq_status)
return IRQ_NONE;
for_each_set_bit(channel, &irq_status, QUAD8_NUM_COUNTERS) {
switch (priv->irq_trigger[channel]) {
case QUAD8_EVENT_CARRY:
event = COUNTER_EVENT_OVERFLOW;
break;
case QUAD8_EVENT_COMPARE:
event = COUNTER_EVENT_THRESHOLD;
break;
case QUAD8_EVENT_CARRY_BORROW:
event = COUNTER_EVENT_OVERFLOW_UNDERFLOW;
break;
case QUAD8_EVENT_INDEX:
event = COUNTER_EVENT_INDEX;
break;
default:
/* should never reach this path */
WARN_ONCE(true, "invalid interrupt trigger function %u configured for channel %lu\n",
priv->irq_trigger[channel], channel);
continue;
}
counter_push_event(counter, event, channel);
}
/* Clear pending interrupts on device */
outb(QUAD8_CHAN_OP_ENABLE_INTERRUPT_FUNC, base + QUAD8_REG_CHAN_OP);
return IRQ_HANDLED;
}