The current interrupt implementation uses the simple irq-flow handler,
which means that the interrupt subsystem makes no irq-chip callbacks
when handling an interrupt. Specifically, no end-of-interrupt message is
sent when the threaded handler has run. This means that we may currently
re-enable an interrupt before it has been serviced (i.e. the irq-event
operation may complete before the threaded handler has run).
The simple flow handler also silently drops a second interrupt arriving
while a handler is running. This means that we may lose a second edge
interrupt with the current firmware.
Switch to a new one-shot interrupt protocol, where the primary handler
(firmware) always masks and acks an interrupt before sending an event to
the AP. The AP is responsible for unmasking the interrupt when it has
been handled. By having the firmware ack an edge interrupt before
sending the event, a second edge interrupt will no longer get lost.
This one-shot protocol can be implemented in the kernel by using the
level irq-flow handler, one-shot interrupts with threaded handlers and
bus-lock synchronisation for slow buses. Note that the same flow handler
is used for both edge and level interrupts.
Signed-off-by: Johan Hovold <johan@hovoldconsulting.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
}
ret = gb_gpio_irqchip_add(gpio, irqc, 0,
- handle_simple_irq, IRQ_TYPE_NONE);
+ handle_level_irq, IRQ_TYPE_NONE);
if (ret) {
dev_err(&connection->dev, "failed to add irq chip: %d\n", ret);
goto irqchip_err;
struct gb_gpio_irq_event_request {
__u8 which;
};
-/* irq event response has no payload */
+/* irq event has no response */
/* PWM */