summaryrefslogtreecommitdiff
path: root/drivers/staging/greybus/gpio.c
diff options
context:
space:
mode:
authorJohan Hovold <johan@hovoldconsulting.com>2015-05-26 15:29:25 +0200
committerGreg Kroah-Hartman <gregkh@google.com>2015-05-26 15:27:39 -0700
commit1409c4d6a841b00f3b4bdf010808a81eda6b7727 (patch)
treeca1c3df7bd48f38d28779010a98205e42871873e /drivers/staging/greybus/gpio.c
parent25f11ed965bb57b6e25d5464a8cd8b3657319056 (diff)
greybus: gpio: fix interrupt protocol
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>
Diffstat (limited to 'drivers/staging/greybus/gpio.c')
-rw-r--r--drivers/staging/greybus/gpio.c2
1 files changed, 1 insertions, 1 deletions
diff --git a/drivers/staging/greybus/gpio.c b/drivers/staging/greybus/gpio.c
index 6cf3bb151f61..8dad9e579881 100644
--- a/drivers/staging/greybus/gpio.c
+++ b/drivers/staging/greybus/gpio.c
@@ -672,7 +672,7 @@ static int gb_gpio_connection_init(struct gb_connection *connection)
}
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;