blob: 5830dc9b87f3bfabe6034afa88a1e6ab3f2975f0 [file] [log] [blame]
Greg Kroah-Hartmanc16854c2014-08-12 12:00:16 +08001/*
2 * GPIO Greybus driver.
3 *
4 * Copyright 2014 Google Inc.
Alex Eldera46e9672014-12-12 12:08:42 -06005 * Copyright 2014 Linaro Ltd.
Greg Kroah-Hartmanc16854c2014-08-12 12:00:16 +08006 *
7 * Released under the GPLv2 only.
8 */
9
10#include <linux/kernel.h>
11#include <linux/module.h>
12#include <linux/slab.h>
13#include <linux/gpio.h>
Matt Porter036aad92015-02-17 10:48:23 -050014#include <linux/irq.h>
15#include <linux/irqdomain.h>
Johan Hovold25f11ed2015-05-26 15:29:24 +020016#include <linux/mutex.h>
17
Greg Kroah-Hartmanc16854c2014-08-12 12:00:16 +080018#include "greybus.h"
19
Alex Elderbb2e1c92014-10-16 06:35:39 -050020struct gb_gpio_line {
21 /* The following has to be an array of line_max entries */
22 /* --> make them just a flags field */
23 u8 active: 1,
24 direction: 1, /* 0 = output, 1 = input */
25 value: 1; /* 0 = low, 1 = high */
26 u16 debounce_usec;
Johan Hovold25f11ed2015-05-26 15:29:24 +020027
28 u8 irq_type;
29 bool irq_type_pending;
30 bool masked;
31 bool masked_pending;
Greg Kroah-Hartmanc16854c2014-08-12 12:00:16 +080032};
33
Alex Elderbb2e1c92014-10-16 06:35:39 -050034struct gb_gpio_controller {
35 struct gb_connection *connection;
Alex Elderbb2e1c92014-10-16 06:35:39 -050036 u8 line_max; /* max line number */
37 struct gb_gpio_line *lines;
38
39 struct gpio_chip chip;
Matt Porter036aad92015-02-17 10:48:23 -050040 struct irq_chip irqc;
41 struct irq_chip *irqchip;
42 struct irq_domain *irqdomain;
43 unsigned int irq_base;
44 irq_flow_handler_t irq_handler;
45 unsigned int irq_default_type;
Johan Hovold25f11ed2015-05-26 15:29:24 +020046 struct mutex irq_lock;
Alex Elderbb2e1c92014-10-16 06:35:39 -050047};
48#define gpio_chip_to_gb_gpio_controller(chip) \
49 container_of(chip, struct gb_gpio_controller, chip)
Matt Porter036aad92015-02-17 10:48:23 -050050#define irq_data_to_gpio_chip(d) (d->domain->host_data)
Alex Elderbb2e1c92014-10-16 06:35:39 -050051
Greg Kroah-Hartman7d5bbb12014-11-23 17:45:22 -080052static int gb_gpio_line_count_operation(struct gb_gpio_controller *ggc)
53{
54 struct gb_gpio_line_count_response response;
55 int ret;
56
57 ret = gb_operation_sync(ggc->connection, GB_GPIO_TYPE_LINE_COUNT,
58 NULL, 0, &response, sizeof(response));
59 if (!ret)
60 ggc->line_max = response.count;
Alex Elderbb2e1c92014-10-16 06:35:39 -050061 return ret;
62}
63
Greg Kroah-Hartman7d5bbb12014-11-23 17:45:22 -080064static int gb_gpio_activate_operation(struct gb_gpio_controller *ggc, u8 which)
Alex Elderbb2e1c92014-10-16 06:35:39 -050065{
Greg Kroah-Hartman7d5bbb12014-11-23 17:45:22 -080066 struct gb_gpio_activate_request request;
Alex Elderbb2e1c92014-10-16 06:35:39 -050067 int ret;
68
Greg Kroah-Hartman7d5bbb12014-11-23 17:45:22 -080069 request.which = which;
70 ret = gb_operation_sync(ggc->connection, GB_GPIO_TYPE_ACTIVATE,
71 &request, sizeof(request), NULL, 0);
72 if (!ret)
73 ggc->lines[which].active = true;
Alex Elderbb2e1c92014-10-16 06:35:39 -050074 return ret;
75}
76
Johan Hovold86c68162015-03-19 16:51:15 +010077static void gb_gpio_deactivate_operation(struct gb_gpio_controller *ggc,
Alex Elderbb2e1c92014-10-16 06:35:39 -050078 u8 which)
79{
Greg Kroah-Hartman7d5bbb12014-11-23 17:45:22 -080080 struct gb_gpio_deactivate_request request;
Alex Elderbb2e1c92014-10-16 06:35:39 -050081 int ret;
82
Greg Kroah-Hartman7d5bbb12014-11-23 17:45:22 -080083 request.which = which;
84 ret = gb_operation_sync(ggc->connection, GB_GPIO_TYPE_DEACTIVATE,
85 &request, sizeof(request), NULL, 0);
Johan Hovold792c17e2015-03-19 16:55:23 +010086 if (ret) {
87 dev_err(ggc->chip.dev, "failed to deactivate gpio %u\n",
88 which);
89 return;
90 }
91
92 ggc->lines[which].active = false;
Alex Elderbb2e1c92014-10-16 06:35:39 -050093}
94
Greg Kroah-Hartman7d5bbb12014-11-23 17:45:22 -080095static int gb_gpio_get_direction_operation(struct gb_gpio_controller *ggc,
Alex Elderbb2e1c92014-10-16 06:35:39 -050096 u8 which)
97{
Greg Kroah-Hartman7d5bbb12014-11-23 17:45:22 -080098 struct gb_gpio_get_direction_request request;
99 struct gb_gpio_get_direction_response response;
Alex Elderbb2e1c92014-10-16 06:35:39 -0500100 int ret;
Alex Elder23383de2014-11-21 19:29:12 -0600101 u8 direction;
Alex Elderbb2e1c92014-10-16 06:35:39 -0500102
Greg Kroah-Hartman7d5bbb12014-11-23 17:45:22 -0800103 request.which = which;
104 ret = gb_operation_sync(ggc->connection, GB_GPIO_TYPE_GET_DIRECTION,
105 &request, sizeof(request),
106 &response, sizeof(response));
107 if (ret)
108 return ret;
Alex Elderbb2e1c92014-10-16 06:35:39 -0500109
Greg Kroah-Hartman7d5bbb12014-11-23 17:45:22 -0800110 direction = response.direction;
Johan Hovolde5032d82015-03-19 16:51:16 +0100111 if (direction && direction != 1) {
112 dev_warn(ggc->chip.dev,
113 "gpio %u direction was %u (should be 0 or 1)\n",
114 which, direction);
115 }
Greg Kroah-Hartman7d5bbb12014-11-23 17:45:22 -0800116 ggc->lines[which].direction = direction ? 1 : 0;
117 return 0;
Alex Elderbb2e1c92014-10-16 06:35:39 -0500118}
119
Greg Kroah-Hartman7d5bbb12014-11-23 17:45:22 -0800120static int gb_gpio_direction_in_operation(struct gb_gpio_controller *ggc,
Alex Elderbb2e1c92014-10-16 06:35:39 -0500121 u8 which)
122{
Greg Kroah-Hartman7d5bbb12014-11-23 17:45:22 -0800123 struct gb_gpio_direction_in_request request;
Alex Elderbb2e1c92014-10-16 06:35:39 -0500124 int ret;
125
Greg Kroah-Hartman7d5bbb12014-11-23 17:45:22 -0800126 request.which = which;
127 ret = gb_operation_sync(ggc->connection, GB_GPIO_TYPE_DIRECTION_IN,
128 &request, sizeof(request), NULL, 0);
129 if (!ret)
130 ggc->lines[which].direction = 1;
Alex Elderbb2e1c92014-10-16 06:35:39 -0500131 return ret;
132}
133
Greg Kroah-Hartman7d5bbb12014-11-23 17:45:22 -0800134static int gb_gpio_direction_out_operation(struct gb_gpio_controller *ggc,
Alex Elderbb2e1c92014-10-16 06:35:39 -0500135 u8 which, bool value_high)
136{
Greg Kroah-Hartman7d5bbb12014-11-23 17:45:22 -0800137 struct gb_gpio_direction_out_request request;
Alex Elderbb2e1c92014-10-16 06:35:39 -0500138 int ret;
139
Greg Kroah-Hartman7d5bbb12014-11-23 17:45:22 -0800140 request.which = which;
141 request.value = value_high ? 1 : 0;
142 ret = gb_operation_sync(ggc->connection, GB_GPIO_TYPE_DIRECTION_OUT,
143 &request, sizeof(request), NULL, 0);
144 if (!ret)
145 ggc->lines[which].direction = 0;
Alex Elderbb2e1c92014-10-16 06:35:39 -0500146 return ret;
147}
148
Greg Kroah-Hartman7d5bbb12014-11-23 17:45:22 -0800149static int gb_gpio_get_value_operation(struct gb_gpio_controller *ggc,
Alex Elderbb2e1c92014-10-16 06:35:39 -0500150 u8 which)
151{
Greg Kroah-Hartman7d5bbb12014-11-23 17:45:22 -0800152 struct gb_gpio_get_value_request request;
153 struct gb_gpio_get_value_response response;
Alex Elderbb2e1c92014-10-16 06:35:39 -0500154 int ret;
Alex Elder23383de2014-11-21 19:29:12 -0600155 u8 value;
Alex Elderbb2e1c92014-10-16 06:35:39 -0500156
Greg Kroah-Hartman7d5bbb12014-11-23 17:45:22 -0800157 request.which = which;
158 ret = gb_operation_sync(ggc->connection, GB_GPIO_TYPE_GET_VALUE,
159 &request, sizeof(request),
160 &response, sizeof(response));
Johan Hovold792c17e2015-03-19 16:55:23 +0100161 if (ret) {
162 dev_err(ggc->chip.dev, "failed to get value of gpio %u\n",
163 which);
Greg Kroah-Hartman7d5bbb12014-11-23 17:45:22 -0800164 return ret;
Johan Hovold792c17e2015-03-19 16:55:23 +0100165 }
Alex Elderbb2e1c92014-10-16 06:35:39 -0500166
Greg Kroah-Hartman7d5bbb12014-11-23 17:45:22 -0800167 value = response.value;
Johan Hovolde5032d82015-03-19 16:51:16 +0100168 if (value && value != 1) {
169 dev_warn(ggc->chip.dev,
170 "gpio %u value was %u (should be 0 or 1)\n",
171 which, value);
172 }
Greg Kroah-Hartman7d5bbb12014-11-23 17:45:22 -0800173 ggc->lines[which].value = value ? 1 : 0;
174 return 0;
Alex Elderbb2e1c92014-10-16 06:35:39 -0500175}
176
Johan Hovold86c68162015-03-19 16:51:15 +0100177static void gb_gpio_set_value_operation(struct gb_gpio_controller *ggc,
Alex Elderbb2e1c92014-10-16 06:35:39 -0500178 u8 which, bool value_high)
179{
Greg Kroah-Hartman7d5bbb12014-11-23 17:45:22 -0800180 struct gb_gpio_set_value_request request;
Alex Elderbb2e1c92014-10-16 06:35:39 -0500181 int ret;
182
Johan Hovold7bfa0782015-03-19 16:55:22 +0100183 if (ggc->lines[which].direction == 1) {
184 dev_warn(ggc->chip.dev,
185 "refusing to set value of input gpio %u\n", which);
186 return;
187 }
188
Greg Kroah-Hartman7d5bbb12014-11-23 17:45:22 -0800189 request.which = which;
190 request.value = value_high ? 1 : 0;
191 ret = gb_operation_sync(ggc->connection, GB_GPIO_TYPE_SET_VALUE,
192 &request, sizeof(request), NULL, 0);
Johan Hovold792c17e2015-03-19 16:55:23 +0100193 if (ret) {
194 dev_err(ggc->chip.dev, "failed to set value of gpio %u\n",
195 which);
196 return;
197 }
198
199 ggc->lines[which].value = request.value;
Alex Elderbb2e1c92014-10-16 06:35:39 -0500200}
201
Greg Kroah-Hartman7d5bbb12014-11-23 17:45:22 -0800202static int gb_gpio_set_debounce_operation(struct gb_gpio_controller *ggc,
Alex Elderbb2e1c92014-10-16 06:35:39 -0500203 u8 which, u16 debounce_usec)
204{
Greg Kroah-Hartman7d5bbb12014-11-23 17:45:22 -0800205 struct gb_gpio_set_debounce_request request;
Alex Elderbb2e1c92014-10-16 06:35:39 -0500206 int ret;
207
Greg Kroah-Hartman7d5bbb12014-11-23 17:45:22 -0800208 request.which = which;
209 request.usec = cpu_to_le16(debounce_usec);
210 ret = gb_operation_sync(ggc->connection, GB_GPIO_TYPE_SET_DEBOUNCE,
211 &request, sizeof(request), NULL, 0);
212 if (!ret)
213 ggc->lines[which].debounce_usec = debounce_usec;
Alex Elderbb2e1c92014-10-16 06:35:39 -0500214 return ret;
215}
216
Johan Hovold25f11ed2015-05-26 15:29:24 +0200217static void _gb_gpio_irq_mask(struct gb_gpio_controller *ggc, u8 hwirq)
Matt Porter036aad92015-02-17 10:48:23 -0500218{
Matt Porter036aad92015-02-17 10:48:23 -0500219 struct gb_gpio_irq_mask_request request;
220 int ret;
221
Johan Hovold25f11ed2015-05-26 15:29:24 +0200222 request.which = hwirq;
Matt Porter036aad92015-02-17 10:48:23 -0500223 ret = gb_operation_sync(ggc->connection,
224 GB_GPIO_TYPE_IRQ_MASK,
225 &request, sizeof(request), NULL, 0);
226 if (ret)
Johan Hovold25f11ed2015-05-26 15:29:24 +0200227 dev_err(ggc->chip.dev, "failed to mask irq: %d\n", ret);
228}
229
230static void _gb_gpio_irq_unmask(struct gb_gpio_controller *ggc, u8 hwirq)
231{
232 struct gb_gpio_irq_unmask_request request;
233 int ret;
234
235 request.which = hwirq;
236 ret = gb_operation_sync(ggc->connection,
237 GB_GPIO_TYPE_IRQ_UNMASK,
238 &request, sizeof(request), NULL, 0);
239 if (ret)
240 dev_err(ggc->chip.dev, "failed to unmask irq: %d\n", ret);
241}
242
243static void _gb_gpio_irq_set_type(struct gb_gpio_controller *ggc,
244 u8 hwirq, u8 type)
245{
246 struct gb_gpio_irq_type_request request;
247 int ret;
248
249 request.which = hwirq;
250 request.type = type;
251
252 ret = gb_operation_sync(ggc->connection,
253 GB_GPIO_TYPE_IRQ_TYPE,
254 &request, sizeof(request), NULL, 0);
255 if (ret)
256 dev_err(ggc->chip.dev, "failed to set irq type: %d\n", ret);
257}
258
259static void gb_gpio_irq_mask(struct irq_data *d)
260{
261 struct gpio_chip *chip = irq_data_to_gpio_chip(d);
262 struct gb_gpio_controller *ggc = gpio_chip_to_gb_gpio_controller(chip);
263 struct gb_gpio_line *line = &ggc->lines[d->hwirq];
264
265 line->masked = true;
266 line->masked_pending = true;
Matt Porter036aad92015-02-17 10:48:23 -0500267}
268
Johan Hovold0cb918d2015-05-26 15:29:23 +0200269static void gb_gpio_irq_unmask(struct irq_data *d)
Matt Porter036aad92015-02-17 10:48:23 -0500270{
271 struct gpio_chip *chip = irq_data_to_gpio_chip(d);
272 struct gb_gpio_controller *ggc = gpio_chip_to_gb_gpio_controller(chip);
Johan Hovold25f11ed2015-05-26 15:29:24 +0200273 struct gb_gpio_line *line = &ggc->lines[d->hwirq];
Matt Porter036aad92015-02-17 10:48:23 -0500274
Johan Hovold25f11ed2015-05-26 15:29:24 +0200275 line->masked = false;
276 line->masked_pending = true;
Matt Porter036aad92015-02-17 10:48:23 -0500277}
278
279static int gb_gpio_irq_set_type(struct irq_data *d, unsigned int type)
280{
281 struct gpio_chip *chip = irq_data_to_gpio_chip(d);
282 struct gb_gpio_controller *ggc = gpio_chip_to_gb_gpio_controller(chip);
Johan Hovold25f11ed2015-05-26 15:29:24 +0200283 struct gb_gpio_line *line = &ggc->lines[d->hwirq];
Johan Hovold7ba864a2015-05-28 19:03:34 +0200284 u8 irq_type;
Matt Porter036aad92015-02-17 10:48:23 -0500285
286 switch (type) {
287 case IRQ_TYPE_NONE:
Johan Hovold7ba864a2015-05-28 19:03:34 +0200288 irq_type = GB_GPIO_IRQ_TYPE_NONE;
289 break;
Matt Porter036aad92015-02-17 10:48:23 -0500290 case IRQ_TYPE_EDGE_RISING:
Johan Hovold7ba864a2015-05-28 19:03:34 +0200291 irq_type = GB_GPIO_IRQ_TYPE_EDGE_RISING;
292 break;
Matt Porter036aad92015-02-17 10:48:23 -0500293 case IRQ_TYPE_EDGE_FALLING:
Johan Hovold7ba864a2015-05-28 19:03:34 +0200294 irq_type = GB_GPIO_IRQ_TYPE_EDGE_FALLING;
295 break;
Matt Porter036aad92015-02-17 10:48:23 -0500296 case IRQ_TYPE_EDGE_BOTH:
Johan Hovold7ba864a2015-05-28 19:03:34 +0200297 irq_type = GB_GPIO_IRQ_TYPE_EDGE_BOTH;
298 break;
Matt Porter036aad92015-02-17 10:48:23 -0500299 case IRQ_TYPE_LEVEL_LOW:
Johan Hovold7ba864a2015-05-28 19:03:34 +0200300 irq_type = GB_GPIO_IRQ_TYPE_LEVEL_LOW;
301 break;
Matt Porter036aad92015-02-17 10:48:23 -0500302 case IRQ_TYPE_LEVEL_HIGH:
Johan Hovold7ba864a2015-05-28 19:03:34 +0200303 irq_type = GB_GPIO_IRQ_TYPE_LEVEL_HIGH;
Viresh Kumar8de925b2015-05-20 16:32:28 +0530304 break;
Matt Porter036aad92015-02-17 10:48:23 -0500305 default:
Johan Hovolde5032d82015-03-19 16:51:16 +0100306 dev_err(chip->dev, "unsupported irq type: %u\n", type);
Johan Hovold25f11ed2015-05-26 15:29:24 +0200307 return -EINVAL;
Matt Porter036aad92015-02-17 10:48:23 -0500308 }
309
Johan Hovold7ba864a2015-05-28 19:03:34 +0200310 line->irq_type = irq_type;
Johan Hovold25f11ed2015-05-26 15:29:24 +0200311 line->irq_type_pending = true;
312
313 return 0;
314}
315
316static void gb_gpio_irq_bus_lock(struct irq_data *d)
317{
318 struct gpio_chip *chip = irq_data_to_gpio_chip(d);
319 struct gb_gpio_controller *ggc = gpio_chip_to_gb_gpio_controller(chip);
320
321 mutex_lock(&ggc->irq_lock);
322}
323
324static void gb_gpio_irq_bus_sync_unlock(struct irq_data *d)
325{
326 struct gpio_chip *chip = irq_data_to_gpio_chip(d);
327 struct gb_gpio_controller *ggc = gpio_chip_to_gb_gpio_controller(chip);
328 struct gb_gpio_line *line = &ggc->lines[d->hwirq];
329
330 if (line->irq_type_pending) {
331 _gb_gpio_irq_set_type(ggc, d->hwirq, line->irq_type);
332 line->irq_type_pending = false;
333 }
334
335 if (line->masked_pending) {
336 if (line->masked)
337 _gb_gpio_irq_mask(ggc, d->hwirq);
338 else
339 _gb_gpio_irq_unmask(ggc, d->hwirq);
340 line->masked_pending = false;
341 }
342
343 mutex_unlock(&ggc->irq_lock);
Matt Porter036aad92015-02-17 10:48:23 -0500344}
345
Johan Hovold973ccfd2015-03-27 12:45:49 +0100346static int gb_gpio_request_recv(u8 type, struct gb_operation *op)
Matt Porter036aad92015-02-17 10:48:23 -0500347{
Johan Hovolde5032d82015-03-19 16:51:16 +0100348 struct gb_connection *connection = op->connection;
Johan Hovoldfef96a22015-03-27 12:45:43 +0100349 struct gb_gpio_controller *ggc = connection->private;
Matt Porter036aad92015-02-17 10:48:23 -0500350 struct gb_message *request;
351 struct gb_gpio_irq_event_request *event;
352 int irq;
353 struct irq_desc *desc;
Matt Porter036aad92015-02-17 10:48:23 -0500354
355 if (type != GB_GPIO_TYPE_IRQ_EVENT) {
Greg Kroah-Hartmanc7eb46e2015-10-14 11:17:55 -0700356 dev_err(&connection->bundle->dev,
Johan Hovolde5032d82015-03-19 16:51:16 +0100357 "unsupported unsolicited request: %u\n", type);
Johan Hovold973ccfd2015-03-27 12:45:49 +0100358 return -EINVAL;
Matt Porter036aad92015-02-17 10:48:23 -0500359 }
360
Matt Porter036aad92015-02-17 10:48:23 -0500361 request = op->request;
Johan Hovold1842dd82015-03-27 12:45:41 +0100362
363 if (request->payload_size < sizeof(*event)) {
Viresh Kumar782c3b72015-08-06 12:44:51 +0530364 dev_err(ggc->chip.dev, "short event received (%zu < %zu)\n",
365 request->payload_size, sizeof(*event));
Johan Hovold973ccfd2015-03-27 12:45:49 +0100366 return -EINVAL;
Johan Hovold1842dd82015-03-27 12:45:41 +0100367 }
368
Matt Porter036aad92015-02-17 10:48:23 -0500369 event = request->payload;
370 if (event->which > ggc->line_max) {
Johan Hovolde5032d82015-03-19 16:51:16 +0100371 dev_err(ggc->chip.dev, "invalid hw irq: %d\n", event->which);
Johan Hovold973ccfd2015-03-27 12:45:49 +0100372 return -EINVAL;
Matt Porter036aad92015-02-17 10:48:23 -0500373 }
Johan Hovold973ccfd2015-03-27 12:45:49 +0100374
Johan Hovoldec762112015-05-26 15:29:22 +0200375 irq = irq_find_mapping(ggc->irqdomain, event->which);
376 if (!irq) {
377 dev_err(ggc->chip.dev, "failed to find IRQ\n");
Johan Hovold973ccfd2015-03-27 12:45:49 +0100378 return -EINVAL;
Johan Hovold244b5a22015-03-27 12:45:42 +0100379 }
Matt Porter036aad92015-02-17 10:48:23 -0500380 desc = irq_to_desc(irq);
Johan Hovold244b5a22015-03-27 12:45:42 +0100381 if (!desc) {
382 dev_err(ggc->chip.dev, "failed to look up irq\n");
Johan Hovold973ccfd2015-03-27 12:45:49 +0100383 return -EINVAL;
Johan Hovold244b5a22015-03-27 12:45:42 +0100384 }
Matt Porter036aad92015-02-17 10:48:23 -0500385
Matt Porter036aad92015-02-17 10:48:23 -0500386 local_irq_disable();
Rui Miguel Silva3c9426a2015-09-30 11:11:57 +0100387#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 3, 0)
Johan Hovold2611ebe2015-05-26 15:29:21 +0200388 generic_handle_irq_desc(irq, desc);
Greg Kroah-Hartman4ee14412015-09-29 20:39:17 +0200389#else
390 generic_handle_irq_desc(desc);
391#endif
Matt Porter036aad92015-02-17 10:48:23 -0500392 local_irq_enable();
393
Johan Hovold973ccfd2015-03-27 12:45:49 +0100394 return 0;
Matt Porter036aad92015-02-17 10:48:23 -0500395}
396
Alex Elderbb2e1c92014-10-16 06:35:39 -0500397static int gb_gpio_request(struct gpio_chip *chip, unsigned offset)
398{
Johan Hovold8aff1ac2015-03-19 16:51:14 +0100399 struct gb_gpio_controller *ggc = gpio_chip_to_gb_gpio_controller(chip);
Alex Elderbb2e1c92014-10-16 06:35:39 -0500400
Johan Hovold86c68162015-03-19 16:51:15 +0100401 return gb_gpio_activate_operation(ggc, (u8)offset);
Greg Kroah-Hartmanc16854c2014-08-12 12:00:16 +0800402}
403
Alex Elderbb2e1c92014-10-16 06:35:39 -0500404static void gb_gpio_free(struct gpio_chip *chip, unsigned offset)
Greg Kroah-Hartmanc16854c2014-08-12 12:00:16 +0800405{
Johan Hovold8aff1ac2015-03-19 16:51:14 +0100406 struct gb_gpio_controller *ggc = gpio_chip_to_gb_gpio_controller(chip);
Greg Kroah-Hartmanc16854c2014-08-12 12:00:16 +0800407
Johan Hovold86c68162015-03-19 16:51:15 +0100408 gb_gpio_deactivate_operation(ggc, (u8)offset);
Alex Elderbb2e1c92014-10-16 06:35:39 -0500409}
410
411static int gb_gpio_get_direction(struct gpio_chip *chip, unsigned offset)
412{
Johan Hovold8aff1ac2015-03-19 16:51:14 +0100413 struct gb_gpio_controller *ggc = gpio_chip_to_gb_gpio_controller(chip);
Alex Elderbb2e1c92014-10-16 06:35:39 -0500414 u8 which;
415 int ret;
416
Matt Porterff6e0b92014-10-20 06:39:45 -0400417 which = (u8)offset;
Johan Hovold8aff1ac2015-03-19 16:51:14 +0100418 ret = gb_gpio_get_direction_operation(ggc, which);
Alex Elderbb2e1c92014-10-16 06:35:39 -0500419 if (ret)
Johan Hovold86c68162015-03-19 16:51:15 +0100420 return ret;
421
Johan Hovold8aff1ac2015-03-19 16:51:14 +0100422 return ggc->lines[which].direction ? 1 : 0;
Alex Elderbb2e1c92014-10-16 06:35:39 -0500423}
424
425static int gb_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
426{
Johan Hovold8aff1ac2015-03-19 16:51:14 +0100427 struct gb_gpio_controller *ggc = gpio_chip_to_gb_gpio_controller(chip);
Alex Elderbb2e1c92014-10-16 06:35:39 -0500428
Johan Hovold86c68162015-03-19 16:51:15 +0100429 return gb_gpio_direction_in_operation(ggc, (u8)offset);
Alex Elderbb2e1c92014-10-16 06:35:39 -0500430}
431
432static int gb_gpio_direction_output(struct gpio_chip *chip, unsigned offset,
433 int value)
434{
Johan Hovold8aff1ac2015-03-19 16:51:14 +0100435 struct gb_gpio_controller *ggc = gpio_chip_to_gb_gpio_controller(chip);
Alex Elderbb2e1c92014-10-16 06:35:39 -0500436
Johan Hovold86c68162015-03-19 16:51:15 +0100437 return gb_gpio_direction_out_operation(ggc, (u8)offset, !!value);
Alex Elderbb2e1c92014-10-16 06:35:39 -0500438}
439
440static int gb_gpio_get(struct gpio_chip *chip, unsigned offset)
441{
Johan Hovold8aff1ac2015-03-19 16:51:14 +0100442 struct gb_gpio_controller *ggc = gpio_chip_to_gb_gpio_controller(chip);
Alex Elderbb2e1c92014-10-16 06:35:39 -0500443 u8 which;
444 int ret;
445
Matt Porterff6e0b92014-10-20 06:39:45 -0400446 which = (u8)offset;
Johan Hovold8aff1ac2015-03-19 16:51:14 +0100447 ret = gb_gpio_get_value_operation(ggc, which);
Alex Elderbb2e1c92014-10-16 06:35:39 -0500448 if (ret)
449 return ret;
Johan Hovold86c68162015-03-19 16:51:15 +0100450
Johan Hovold8aff1ac2015-03-19 16:51:14 +0100451 return ggc->lines[which].value;
Alex Elderbb2e1c92014-10-16 06:35:39 -0500452}
453
454static void gb_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
455{
Johan Hovold8aff1ac2015-03-19 16:51:14 +0100456 struct gb_gpio_controller *ggc = gpio_chip_to_gb_gpio_controller(chip);
Alex Elderbb2e1c92014-10-16 06:35:39 -0500457
Johan Hovold86c68162015-03-19 16:51:15 +0100458 gb_gpio_set_value_operation(ggc, (u8)offset, !!value);
Alex Elderbb2e1c92014-10-16 06:35:39 -0500459}
460
461static int gb_gpio_set_debounce(struct gpio_chip *chip, unsigned offset,
462 unsigned debounce)
463{
Johan Hovold8aff1ac2015-03-19 16:51:14 +0100464 struct gb_gpio_controller *ggc = gpio_chip_to_gb_gpio_controller(chip);
Alex Elderbb2e1c92014-10-16 06:35:39 -0500465 u16 usec;
Alex Elderbb2e1c92014-10-16 06:35:39 -0500466
Johan Hovoldc2a66102015-03-19 16:51:09 +0100467 if (debounce > U16_MAX)
Alex Elderbb2e1c92014-10-16 06:35:39 -0500468 return -EINVAL;
Johan Hovoldc2a66102015-03-19 16:51:09 +0100469 usec = (u16)debounce;
Alex Elderbb2e1c92014-10-16 06:35:39 -0500470
Johan Hovold86c68162015-03-19 16:51:15 +0100471 return gb_gpio_set_debounce_operation(ggc, (u8)offset, usec);
Alex Elderbb2e1c92014-10-16 06:35:39 -0500472}
473
Johan Hovold8aff1ac2015-03-19 16:51:14 +0100474static int gb_gpio_controller_setup(struct gb_gpio_controller *ggc)
Alex Elderbb2e1c92014-10-16 06:35:39 -0500475{
Alex Elderbb2e1c92014-10-16 06:35:39 -0500476 int ret;
477
Alex Elderbb2e1c92014-10-16 06:35:39 -0500478 /* Now find out how many lines there are */
Johan Hovold8aff1ac2015-03-19 16:51:14 +0100479 ret = gb_gpio_line_count_operation(ggc);
Alex Elderbb2e1c92014-10-16 06:35:39 -0500480 if (ret)
Johan Hovold86c68162015-03-19 16:51:15 +0100481 return ret;
482
Johan Hovold64d2f4e2015-03-19 16:51:17 +0100483 ggc->lines = kcalloc(ggc->line_max + 1, sizeof(*ggc->lines),
484 GFP_KERNEL);
Johan Hovold8aff1ac2015-03-19 16:51:14 +0100485 if (!ggc->lines)
Alex Elderbb2e1c92014-10-16 06:35:39 -0500486 return -ENOMEM;
487
488 return ret;
489}
490
Matt Porter036aad92015-02-17 10:48:23 -0500491/**
492 * gb_gpio_irq_map() - maps an IRQ into a GB gpio irqchip
493 * @d: the irqdomain used by this irqchip
494 * @irq: the global irq number used by this GB gpio irqchip irq
495 * @hwirq: the local IRQ/GPIO line offset on this GB gpio
496 *
497 * This function will set up the mapping for a certain IRQ line on a
498 * GB gpio by assigning the GB gpio as chip data, and using the irqchip
499 * stored inside the GB gpio.
500 */
501static int gb_gpio_irq_map(struct irq_domain *domain, unsigned int irq,
502 irq_hw_number_t hwirq)
503{
504 struct gpio_chip *chip = domain->host_data;
505 struct gb_gpio_controller *ggc = gpio_chip_to_gb_gpio_controller(chip);
506
507 irq_set_chip_data(irq, ggc);
508 irq_set_chip_and_handler(irq, ggc->irqchip, ggc->irq_handler);
Matt Porter036aad92015-02-17 10:48:23 -0500509 irq_set_noprobe(irq);
Matt Porter036aad92015-02-17 10:48:23 -0500510 /*
511 * No set-up of the hardware will happen if IRQ_TYPE_NONE
512 * is passed as default type.
513 */
514 if (ggc->irq_default_type != IRQ_TYPE_NONE)
515 irq_set_irq_type(irq, ggc->irq_default_type);
516
517 return 0;
518}
519
520static void gb_gpio_irq_unmap(struct irq_domain *d, unsigned int irq)
521{
Matt Porter036aad92015-02-17 10:48:23 -0500522 irq_set_chip_and_handler(irq, NULL, NULL);
523 irq_set_chip_data(irq, NULL);
524}
525
526static const struct irq_domain_ops gb_gpio_domain_ops = {
527 .map = gb_gpio_irq_map,
528 .unmap = gb_gpio_irq_unmap,
529};
530
531/**
532 * gb_gpio_irqchip_remove() - removes an irqchip added to a gb_gpio_controller
533 * @ggc: the gb_gpio_controller to remove the irqchip from
534 *
535 * This is called only from gb_gpio_remove()
536 */
537static void gb_gpio_irqchip_remove(struct gb_gpio_controller *ggc)
538{
539 unsigned int offset;
540
541 /* Remove all IRQ mappings and delete the domain */
542 if (ggc->irqdomain) {
543 for (offset = 0; offset < (ggc->line_max + 1); offset++)
544 irq_dispose_mapping(irq_find_mapping(ggc->irqdomain, offset));
545 irq_domain_remove(ggc->irqdomain);
546 }
547
548 if (ggc->irqchip) {
549 ggc->irqchip = NULL;
550 }
551}
552
553
554/**
555 * gb_gpio_irqchip_add() - adds an irqchip to a gpio chip
556 * @chip: the gpio chip to add the irqchip to
557 * @irqchip: the irqchip to add to the adapter
558 * @first_irq: if not dynamically assigned, the base (first) IRQ to
559 * allocate gpio irqs from
560 * @handler: the irq handler to use (often a predefined irq core function)
561 * @type: the default type for IRQs on this irqchip, pass IRQ_TYPE_NONE
562 * to have the core avoid setting up any default type in the hardware.
563 *
564 * This function closely associates a certain irqchip with a certain
565 * gpio chip, providing an irq domain to translate the local IRQs to
566 * global irqs, and making sure that the gpio chip
567 * is passed as chip data to all related functions. Driver callbacks
568 * need to use container_of() to get their local state containers back
569 * from the gpio chip passed as chip data. An irqdomain will be stored
570 * in the gpio chip that shall be used by the driver to handle IRQ number
571 * translation. The gpio chip will need to be initialized and registered
572 * before calling this function.
573 */
574static int gb_gpio_irqchip_add(struct gpio_chip *chip,
575 struct irq_chip *irqchip,
576 unsigned int first_irq,
577 irq_flow_handler_t handler,
578 unsigned int type)
579{
580 struct gb_gpio_controller *ggc;
581 unsigned int offset;
582 unsigned irq_base;
583
584 if (!chip || !irqchip)
585 return -EINVAL;
586
587 ggc = gpio_chip_to_gb_gpio_controller(chip);
588
589 ggc->irqchip = irqchip;
590 ggc->irq_handler = handler;
591 ggc->irq_default_type = type;
592 ggc->irqdomain = irq_domain_add_simple(NULL,
593 ggc->line_max + 1, first_irq,
594 &gb_gpio_domain_ops, chip);
595 if (!ggc->irqdomain) {
596 ggc->irqchip = NULL;
597 return -EINVAL;
598 }
599
600 /*
601 * Prepare the mapping since the irqchip shall be orthogonal to
602 * any gpio calls. If the first_irq was zero, this is
603 * necessary to allocate descriptors for all IRQs.
604 */
605 for (offset = 0; offset < (ggc->line_max + 1); offset++) {
606 irq_base = irq_create_mapping(ggc->irqdomain, offset);
607 if (offset == 0)
608 ggc->irq_base = irq_base;
609 }
610
611 return 0;
612}
613
614static int gb_gpio_to_irq(struct gpio_chip *chip, unsigned offset)
615{
616 struct gb_gpio_controller *ggc = gpio_chip_to_gb_gpio_controller(chip);
617
618 return irq_find_mapping(ggc->irqdomain, offset);
619}
620
Alex Elder3689f972014-10-27 06:04:30 -0500621static int gb_gpio_connection_init(struct gb_connection *connection)
Alex Elderbb2e1c92014-10-16 06:35:39 -0500622{
Johan Hovold8aff1ac2015-03-19 16:51:14 +0100623 struct gb_gpio_controller *ggc;
Alex Elderbb2e1c92014-10-16 06:35:39 -0500624 struct gpio_chip *gpio;
Matt Porter036aad92015-02-17 10:48:23 -0500625 struct irq_chip *irqc;
Alex Elderbb2e1c92014-10-16 06:35:39 -0500626 int ret;
627
Johan Hovold8aff1ac2015-03-19 16:51:14 +0100628 ggc = kzalloc(sizeof(*ggc), GFP_KERNEL);
629 if (!ggc)
Alex Elderbb2e1c92014-10-16 06:35:39 -0500630 return -ENOMEM;
Johan Hovold8aff1ac2015-03-19 16:51:14 +0100631 ggc->connection = connection;
632 connection->private = ggc;
Alex Elderbb2e1c92014-10-16 06:35:39 -0500633
Johan Hovold8aff1ac2015-03-19 16:51:14 +0100634 ret = gb_gpio_controller_setup(ggc);
Alex Elderbb2e1c92014-10-16 06:35:39 -0500635 if (ret)
Johan Hovold35a64f22015-02-13 14:58:04 +0800636 goto err_free_controller;
Alex Elderbb2e1c92014-10-16 06:35:39 -0500637
Johan Hovold8aff1ac2015-03-19 16:51:14 +0100638 irqc = &ggc->irqc;
Johan Hovold0cb918d2015-05-26 15:29:23 +0200639 irqc->irq_mask = gb_gpio_irq_mask;
640 irqc->irq_unmask = gb_gpio_irq_unmask;
Matt Porter036aad92015-02-17 10:48:23 -0500641 irqc->irq_set_type = gb_gpio_irq_set_type;
Johan Hovold25f11ed2015-05-26 15:29:24 +0200642 irqc->irq_bus_lock = gb_gpio_irq_bus_lock;
643 irqc->irq_bus_sync_unlock = gb_gpio_irq_bus_sync_unlock;
Matt Porter036aad92015-02-17 10:48:23 -0500644 irqc->name = "greybus_gpio";
645
Johan Hovold25f11ed2015-05-26 15:29:24 +0200646 mutex_init(&ggc->irq_lock);
647
Johan Hovold8aff1ac2015-03-19 16:51:14 +0100648 gpio = &ggc->chip;
Alex Elderbb2e1c92014-10-16 06:35:39 -0500649
650 gpio->label = "greybus_gpio";
Greg Kroah-Hartmanc7eb46e2015-10-14 11:17:55 -0700651 gpio->dev = &connection->bundle->dev;
Johan Hovold56c2da12015-03-19 16:51:10 +0100652 gpio->owner = THIS_MODULE;
Alex Elderbb2e1c92014-10-16 06:35:39 -0500653
654 gpio->request = gb_gpio_request;
655 gpio->free = gb_gpio_free;
656 gpio->get_direction = gb_gpio_get_direction;
657 gpio->direction_input = gb_gpio_direction_input;
658 gpio->direction_output = gb_gpio_direction_output;
659 gpio->get = gb_gpio_get;
660 gpio->set = gb_gpio_set;
661 gpio->set_debounce = gb_gpio_set_debounce;
Matt Porter036aad92015-02-17 10:48:23 -0500662 gpio->to_irq = gb_gpio_to_irq;
Alex Elderbb2e1c92014-10-16 06:35:39 -0500663 gpio->base = -1; /* Allocate base dynamically */
Johan Hovold8aff1ac2015-03-19 16:51:14 +0100664 gpio->ngpio = ggc->line_max + 1;
Johan Hovold56c2da12015-03-19 16:51:10 +0100665 gpio->can_sleep = true;
Alex Elderbb2e1c92014-10-16 06:35:39 -0500666
667 ret = gpiochip_add(gpio);
668 if (ret) {
Greg Kroah-Hartmanc7eb46e2015-10-14 11:17:55 -0700669 dev_err(&connection->bundle->dev,
670 "failed to add gpio chip: %d\n", ret);
Johan Hovold35a64f22015-02-13 14:58:04 +0800671 goto err_free_lines;
Matt Porter036aad92015-02-17 10:48:23 -0500672 }
673
674 ret = gb_gpio_irqchip_add(gpio, irqc, 0,
Johan Hovold1409c4d2015-05-26 15:29:25 +0200675 handle_level_irq, IRQ_TYPE_NONE);
Matt Porter036aad92015-02-17 10:48:23 -0500676 if (ret) {
Greg Kroah-Hartmanc7eb46e2015-10-14 11:17:55 -0700677 dev_err(&connection->bundle->dev,
678 "failed to add irq chip: %d\n", ret);
Matt Porter036aad92015-02-17 10:48:23 -0500679 goto irqchip_err;
Alex Elderbb2e1c92014-10-16 06:35:39 -0500680 }
Alex Elderbb2e1c92014-10-16 06:35:39 -0500681
682 return 0;
Matt Porter036aad92015-02-17 10:48:23 -0500683
684irqchip_err:
685 gb_gpiochip_remove(gpio);
Johan Hovold35a64f22015-02-13 14:58:04 +0800686err_free_lines:
Johan Hovold8aff1ac2015-03-19 16:51:14 +0100687 kfree(ggc->lines);
Johan Hovold35a64f22015-02-13 14:58:04 +0800688err_free_controller:
Johan Hovold8aff1ac2015-03-19 16:51:14 +0100689 kfree(ggc);
Alex Elderbb2e1c92014-10-16 06:35:39 -0500690 return ret;
691}
692
Alex Elder3689f972014-10-27 06:04:30 -0500693static void gb_gpio_connection_exit(struct gb_connection *connection)
Alex Elderbb2e1c92014-10-16 06:35:39 -0500694{
Johan Hovold8aff1ac2015-03-19 16:51:14 +0100695 struct gb_gpio_controller *ggc = connection->private;
Alex Elderbb2e1c92014-10-16 06:35:39 -0500696
Johan Hovold8aff1ac2015-03-19 16:51:14 +0100697 if (!ggc)
Alex Elder051fb042014-10-16 06:35:24 -0500698 return;
Greg Kroah-Hartmanc16854c2014-08-12 12:00:16 +0800699
Johan Hovold8aff1ac2015-03-19 16:51:14 +0100700 gb_gpio_irqchip_remove(ggc);
701 gb_gpiochip_remove(&ggc->chip);
702 /* kref_put(ggc->connection) */
703 kfree(ggc->lines);
704 kfree(ggc);
Greg Kroah-Hartmanc16854c2014-08-12 12:00:16 +0800705}
706
Alex Elder19d03de2014-11-05 16:12:53 -0600707static struct gb_protocol gpio_protocol = {
Greg Kroah-Hartman7422a1e2014-12-24 13:01:45 -0800708 .name = "gpio",
Alex Elder19d03de2014-11-05 16:12:53 -0600709 .id = GREYBUS_PROTOCOL_GPIO,
Viresh Kumar8590ed32015-08-08 10:25:34 +0530710 .major = GB_GPIO_VERSION_MAJOR,
711 .minor = GB_GPIO_VERSION_MINOR,
Alex Elder5d9fd7e2014-11-05 16:12:54 -0600712 .connection_init = gb_gpio_connection_init,
713 .connection_exit = gb_gpio_connection_exit,
Matt Porter036aad92015-02-17 10:48:23 -0500714 .request_recv = gb_gpio_request_recv,
Alex Elder19d03de2014-11-05 16:12:53 -0600715};
716
Viresh Kumare18822e2015-07-01 12:13:52 +0530717gb_builtin_protocol_driver(gpio_protocol);