From 1409c4d6a841b00f3b4bdf010808a81eda6b7727 Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Tue, 26 May 2015 15:29:25 +0200 Subject: [PATCH] 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 Signed-off-by: Greg Kroah-Hartman --- drivers/staging/greybus/gpio.c | 2 +- drivers/staging/greybus/greybus_protocols.h | 2 +- 2 files changed, 2 insertions(+), 2 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; diff --git a/drivers/staging/greybus/greybus_protocols.h b/drivers/staging/greybus/greybus_protocols.h index 0fd42bc44161..81ec3b246cc6 100644 --- a/drivers/staging/greybus/greybus_protocols.h +++ b/drivers/staging/greybus/greybus_protocols.h @@ -206,7 +206,7 @@ struct gb_gpio_irq_unmask_request { struct gb_gpio_irq_event_request { __u8 which; }; -/* irq event response has no payload */ +/* irq event has no response */ /* PWM */ -- 2.39.5