static irqreturn_t quad8_irq_handler()

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;
}