summaryrefslogtreecommitdiff
path: root/drivers/staging/greybus/gpio.c
diff options
context:
space:
mode:
authorJohan Hovold <johan@hovoldconsulting.com>2015-03-27 12:45:49 +0100
committerGreg Kroah-Hartman <greg@kroah.com>2015-03-30 15:20:34 +0200
commit973ccfd62686a2331f43b0053de052d958f50d31 (patch)
tree64bac22afe54717e27c9dcd738421713db87b193 /drivers/staging/greybus/gpio.c
parentd0eb755aeef092f27b3dd2a4c90616f613541f56 (diff)
greybus: operation: refactor response handling
Send response to incoming requests from the operation request handler rather than in every protocol request_recv callback. This simplifies request_recv error handling and allows for further code reuse. Note that if we ever get protocols that need to hold off sending responses we could implement this by letting them return a special value (after acquiring the necessary operation references) to suppress the response from being sent by greybus core. Signed-off-by: Johan Hovold <johan@hovoldconsulting.com> Reviewed-by: Alex Elder <elder@linaro.org> Signed-off-by: Greg Kroah-Hartman <greg@kroah.com>
Diffstat (limited to 'drivers/staging/greybus/gpio.c')
-rw-r--r--drivers/staging/greybus/gpio.c29
1 files changed, 8 insertions, 21 deletions
diff --git a/drivers/staging/greybus/gpio.c b/drivers/staging/greybus/gpio.c
index 9a34fc5a52b8..20917bf6479f 100644
--- a/drivers/staging/greybus/gpio.c
+++ b/drivers/staging/greybus/gpio.c
@@ -394,7 +394,7 @@ static int gb_gpio_irq_set_type(struct irq_data *d, unsigned int type)
return ret;
}
-static void gb_gpio_request_recv(u8 type, struct gb_operation *op)
+static int gb_gpio_request_recv(u8 type, struct gb_operation *op)
{
struct gb_connection *connection = op->connection;
struct gb_gpio_controller *ggc = connection->private;
@@ -402,41 +402,35 @@ static void gb_gpio_request_recv(u8 type, struct gb_operation *op)
struct gb_gpio_irq_event_request *event;
int irq;
struct irq_desc *desc;
- int ret;
- int status;
if (type != GB_GPIO_TYPE_IRQ_EVENT) {
dev_err(&connection->dev,
"unsupported unsolicited request: %u\n", type);
- status = -EINVAL;
- goto send_response;
+ return -EINVAL;
}
request = op->request;
if (request->payload_size < sizeof(*event)) {
dev_err(ggc->chip.dev, "short event received\n");
- status = -EINVAL;
- goto send_response;
+ return -EINVAL;
}
event = request->payload;
if (event->which > ggc->line_max) {
dev_err(ggc->chip.dev, "invalid hw irq: %d\n", event->which);
- status = -EINVAL;
- goto send_response;
+ return -EINVAL;
}
+
irq = gpio_to_irq(ggc->chip.base + event->which);
if (irq < 0) {
dev_err(ggc->chip.dev, "failed to map irq\n");
- status = -EINVAL;
- goto send_response;
+ return -EINVAL;
}
desc = irq_to_desc(irq);
if (!desc) {
dev_err(ggc->chip.dev, "failed to look up irq\n");
- status = -EINVAL;
- goto send_response;
+ return -EINVAL;
}
/* Dispatch interrupt */
@@ -444,14 +438,7 @@ static void gb_gpio_request_recv(u8 type, struct gb_operation *op)
handle_simple_irq(irq, desc);
local_irq_enable();
- status = 0;
-send_response:
- ret = gb_operation_response_send(op, status);
- if (ret) {
- dev_err(ggc->chip.dev,
- "failed to send response status %d: %d\n",
- status, ret);
- }
+ return 0;
}
static int gb_gpio_request(struct gpio_chip *chip, unsigned offset)