xref: /openbmc/linux/drivers/gpio/gpio-tegra186.c (revision 550987be)
1 /*
2  * Copyright (c) 2016-2017 NVIDIA Corporation
3  *
4  * Author: Thierry Reding <treding@nvidia.com>
5  *
6  * This software is licensed under the terms of the GNU General Public
7  * License version 2, as published by the Free Software Foundation, and
8  * may be copied, distributed, and modified under those terms.
9  */
10 
11 #include <linux/gpio/driver.h>
12 #include <linux/interrupt.h>
13 #include <linux/irq.h>
14 #include <linux/module.h>
15 #include <linux/of_device.h>
16 #include <linux/platform_device.h>
17 
18 #include <dt-bindings/gpio/tegra186-gpio.h>
19 
20 #define TEGRA186_GPIO_ENABLE_CONFIG 0x00
21 #define  TEGRA186_GPIO_ENABLE_CONFIG_ENABLE BIT(0)
22 #define  TEGRA186_GPIO_ENABLE_CONFIG_OUT BIT(1)
23 #define  TEGRA186_GPIO_ENABLE_CONFIG_TRIGGER_TYPE_NONE (0x0 << 2)
24 #define  TEGRA186_GPIO_ENABLE_CONFIG_TRIGGER_TYPE_LEVEL (0x1 << 2)
25 #define  TEGRA186_GPIO_ENABLE_CONFIG_TRIGGER_TYPE_SINGLE_EDGE (0x2 << 2)
26 #define  TEGRA186_GPIO_ENABLE_CONFIG_TRIGGER_TYPE_DOUBLE_EDGE (0x3 << 2)
27 #define  TEGRA186_GPIO_ENABLE_CONFIG_TRIGGER_TYPE_MASK (0x3 << 2)
28 #define  TEGRA186_GPIO_ENABLE_CONFIG_TRIGGER_LEVEL BIT(4)
29 #define  TEGRA186_GPIO_ENABLE_CONFIG_INTERRUPT BIT(6)
30 
31 #define TEGRA186_GPIO_DEBOUNCE_CONTROL 0x04
32 #define  TEGRA186_GPIO_DEBOUNCE_CONTROL_THRESHOLD(x) ((x) & 0xff)
33 
34 #define TEGRA186_GPIO_INPUT 0x08
35 #define  TEGRA186_GPIO_INPUT_HIGH BIT(0)
36 
37 #define TEGRA186_GPIO_OUTPUT_CONTROL 0x0c
38 #define  TEGRA186_GPIO_OUTPUT_CONTROL_FLOATED BIT(0)
39 
40 #define TEGRA186_GPIO_OUTPUT_VALUE 0x10
41 #define  TEGRA186_GPIO_OUTPUT_VALUE_HIGH BIT(0)
42 
43 #define TEGRA186_GPIO_INTERRUPT_CLEAR 0x14
44 
45 #define TEGRA186_GPIO_INTERRUPT_STATUS(x) (0x100 + (x) * 4)
46 
47 struct tegra_gpio_port {
48 	const char *name;
49 	unsigned int offset;
50 	unsigned int pins;
51 	unsigned int irq;
52 };
53 
54 struct tegra_gpio_soc {
55 	const struct tegra_gpio_port *ports;
56 	unsigned int num_ports;
57 	const char *name;
58 };
59 
60 struct tegra_gpio {
61 	struct gpio_chip gpio;
62 	struct irq_chip intc;
63 	unsigned int num_irq;
64 	unsigned int *irq;
65 
66 	const struct tegra_gpio_soc *soc;
67 
68 	void __iomem *base;
69 };
70 
71 static const struct tegra_gpio_port *
72 tegra186_gpio_get_port(struct tegra_gpio *gpio, unsigned int *pin)
73 {
74 	unsigned int start = 0, i;
75 
76 	for (i = 0; i < gpio->soc->num_ports; i++) {
77 		const struct tegra_gpio_port *port = &gpio->soc->ports[i];
78 
79 		if (*pin >= start && *pin < start + port->pins) {
80 			*pin -= start;
81 			return port;
82 		}
83 
84 		start += port->pins;
85 	}
86 
87 	return NULL;
88 }
89 
90 static void __iomem *tegra186_gpio_get_base(struct tegra_gpio *gpio,
91 					    unsigned int pin)
92 {
93 	const struct tegra_gpio_port *port;
94 
95 	port = tegra186_gpio_get_port(gpio, &pin);
96 	if (!port)
97 		return NULL;
98 
99 	return gpio->base + port->offset + pin * 0x20;
100 }
101 
102 static int tegra186_gpio_get_direction(struct gpio_chip *chip,
103 				       unsigned int offset)
104 {
105 	struct tegra_gpio *gpio = gpiochip_get_data(chip);
106 	void __iomem *base;
107 	u32 value;
108 
109 	base = tegra186_gpio_get_base(gpio, offset);
110 	if (WARN_ON(base == NULL))
111 		return -ENODEV;
112 
113 	value = readl(base + TEGRA186_GPIO_ENABLE_CONFIG);
114 	if (value & TEGRA186_GPIO_ENABLE_CONFIG_OUT)
115 		return 0;
116 
117 	return 1;
118 }
119 
120 static int tegra186_gpio_direction_input(struct gpio_chip *chip,
121 					 unsigned int offset)
122 {
123 	struct tegra_gpio *gpio = gpiochip_get_data(chip);
124 	void __iomem *base;
125 	u32 value;
126 
127 	base = tegra186_gpio_get_base(gpio, offset);
128 	if (WARN_ON(base == NULL))
129 		return -ENODEV;
130 
131 	value = readl(base + TEGRA186_GPIO_OUTPUT_CONTROL);
132 	value |= TEGRA186_GPIO_OUTPUT_CONTROL_FLOATED;
133 	writel(value, base + TEGRA186_GPIO_OUTPUT_CONTROL);
134 
135 	value = readl(base + TEGRA186_GPIO_ENABLE_CONFIG);
136 	value |= TEGRA186_GPIO_ENABLE_CONFIG_ENABLE;
137 	value &= ~TEGRA186_GPIO_ENABLE_CONFIG_OUT;
138 	writel(value, base + TEGRA186_GPIO_ENABLE_CONFIG);
139 
140 	return 0;
141 }
142 
143 static int tegra186_gpio_direction_output(struct gpio_chip *chip,
144 					  unsigned int offset, int level)
145 {
146 	struct tegra_gpio *gpio = gpiochip_get_data(chip);
147 	void __iomem *base;
148 	u32 value;
149 
150 	/* configure output level first */
151 	chip->set(chip, offset, level);
152 
153 	base = tegra186_gpio_get_base(gpio, offset);
154 	if (WARN_ON(base == NULL))
155 		return -EINVAL;
156 
157 	/* set the direction */
158 	value = readl(base + TEGRA186_GPIO_OUTPUT_CONTROL);
159 	value &= ~TEGRA186_GPIO_OUTPUT_CONTROL_FLOATED;
160 	writel(value, base + TEGRA186_GPIO_OUTPUT_CONTROL);
161 
162 	value = readl(base + TEGRA186_GPIO_ENABLE_CONFIG);
163 	value |= TEGRA186_GPIO_ENABLE_CONFIG_ENABLE;
164 	value |= TEGRA186_GPIO_ENABLE_CONFIG_OUT;
165 	writel(value, base + TEGRA186_GPIO_ENABLE_CONFIG);
166 
167 	return 0;
168 }
169 
170 static int tegra186_gpio_get(struct gpio_chip *chip, unsigned int offset)
171 {
172 	struct tegra_gpio *gpio = gpiochip_get_data(chip);
173 	void __iomem *base;
174 	u32 value;
175 
176 	base = tegra186_gpio_get_base(gpio, offset);
177 	if (WARN_ON(base == NULL))
178 		return -ENODEV;
179 
180 	value = readl(base + TEGRA186_GPIO_ENABLE_CONFIG);
181 	if (value & TEGRA186_GPIO_ENABLE_CONFIG_OUT)
182 		value = readl(base + TEGRA186_GPIO_OUTPUT_VALUE);
183 	else
184 		value = readl(base + TEGRA186_GPIO_INPUT);
185 
186 	return value & BIT(0);
187 }
188 
189 static void tegra186_gpio_set(struct gpio_chip *chip, unsigned int offset,
190 			      int level)
191 {
192 	struct tegra_gpio *gpio = gpiochip_get_data(chip);
193 	void __iomem *base;
194 	u32 value;
195 
196 	base = tegra186_gpio_get_base(gpio, offset);
197 	if (WARN_ON(base == NULL))
198 		return;
199 
200 	value = readl(base + TEGRA186_GPIO_OUTPUT_VALUE);
201 	if (level == 0)
202 		value &= ~TEGRA186_GPIO_OUTPUT_VALUE_HIGH;
203 	else
204 		value |= TEGRA186_GPIO_OUTPUT_VALUE_HIGH;
205 
206 	writel(value, base + TEGRA186_GPIO_OUTPUT_VALUE);
207 }
208 
209 static int tegra186_gpio_of_xlate(struct gpio_chip *chip,
210 				  const struct of_phandle_args *spec,
211 				  u32 *flags)
212 {
213 	struct tegra_gpio *gpio = gpiochip_get_data(chip);
214 	unsigned int port, pin, i, offset = 0;
215 
216 	if (WARN_ON(chip->of_gpio_n_cells < 2))
217 		return -EINVAL;
218 
219 	if (WARN_ON(spec->args_count < chip->of_gpio_n_cells))
220 		return -EINVAL;
221 
222 	port = spec->args[0] / 8;
223 	pin = spec->args[0] % 8;
224 
225 	if (port >= gpio->soc->num_ports) {
226 		dev_err(chip->parent, "invalid port number: %u\n", port);
227 		return -EINVAL;
228 	}
229 
230 	for (i = 0; i < port; i++)
231 		offset += gpio->soc->ports[i].pins;
232 
233 	if (flags)
234 		*flags = spec->args[1];
235 
236 	return offset + pin;
237 }
238 
239 static void tegra186_irq_ack(struct irq_data *data)
240 {
241 	struct tegra_gpio *gpio = irq_data_get_irq_chip_data(data);
242 	void __iomem *base;
243 
244 	base = tegra186_gpio_get_base(gpio, data->hwirq);
245 	if (WARN_ON(base == NULL))
246 		return;
247 
248 	writel(1, base + TEGRA186_GPIO_INTERRUPT_CLEAR);
249 }
250 
251 static void tegra186_irq_mask(struct irq_data *data)
252 {
253 	struct tegra_gpio *gpio = irq_data_get_irq_chip_data(data);
254 	void __iomem *base;
255 	u32 value;
256 
257 	base = tegra186_gpio_get_base(gpio, data->hwirq);
258 	if (WARN_ON(base == NULL))
259 		return;
260 
261 	value = readl(base + TEGRA186_GPIO_ENABLE_CONFIG);
262 	value &= ~TEGRA186_GPIO_ENABLE_CONFIG_INTERRUPT;
263 	writel(value, base + TEGRA186_GPIO_ENABLE_CONFIG);
264 }
265 
266 static void tegra186_irq_unmask(struct irq_data *data)
267 {
268 	struct tegra_gpio *gpio = irq_data_get_irq_chip_data(data);
269 	void __iomem *base;
270 	u32 value;
271 
272 	base = tegra186_gpio_get_base(gpio, data->hwirq);
273 	if (WARN_ON(base == NULL))
274 		return;
275 
276 	value = readl(base + TEGRA186_GPIO_ENABLE_CONFIG);
277 	value |= TEGRA186_GPIO_ENABLE_CONFIG_INTERRUPT;
278 	writel(value, base + TEGRA186_GPIO_ENABLE_CONFIG);
279 }
280 
281 static int tegra186_irq_set_type(struct irq_data *data, unsigned int flow)
282 {
283 	struct tegra_gpio *gpio = irq_data_get_irq_chip_data(data);
284 	void __iomem *base;
285 	u32 value;
286 
287 	base = tegra186_gpio_get_base(gpio, data->hwirq);
288 	if (WARN_ON(base == NULL))
289 		return -ENODEV;
290 
291 	value = readl(base + TEGRA186_GPIO_ENABLE_CONFIG);
292 	value &= ~TEGRA186_GPIO_ENABLE_CONFIG_TRIGGER_TYPE_MASK;
293 	value &= ~TEGRA186_GPIO_ENABLE_CONFIG_TRIGGER_LEVEL;
294 
295 	switch (flow & IRQ_TYPE_SENSE_MASK) {
296 	case IRQ_TYPE_NONE:
297 		break;
298 
299 	case IRQ_TYPE_EDGE_RISING:
300 		value |= TEGRA186_GPIO_ENABLE_CONFIG_TRIGGER_TYPE_SINGLE_EDGE;
301 		value |= TEGRA186_GPIO_ENABLE_CONFIG_TRIGGER_LEVEL;
302 		break;
303 
304 	case IRQ_TYPE_EDGE_FALLING:
305 		value |= TEGRA186_GPIO_ENABLE_CONFIG_TRIGGER_TYPE_SINGLE_EDGE;
306 		break;
307 
308 	case IRQ_TYPE_EDGE_BOTH:
309 		value |= TEGRA186_GPIO_ENABLE_CONFIG_TRIGGER_TYPE_DOUBLE_EDGE;
310 		break;
311 
312 	case IRQ_TYPE_LEVEL_HIGH:
313 		value |= TEGRA186_GPIO_ENABLE_CONFIG_TRIGGER_TYPE_LEVEL;
314 		value |= TEGRA186_GPIO_ENABLE_CONFIG_TRIGGER_LEVEL;
315 		break;
316 
317 	case IRQ_TYPE_LEVEL_LOW:
318 		value |= TEGRA186_GPIO_ENABLE_CONFIG_TRIGGER_TYPE_LEVEL;
319 		break;
320 
321 	default:
322 		return -EINVAL;
323 	}
324 
325 	writel(value, base + TEGRA186_GPIO_ENABLE_CONFIG);
326 
327 	if ((flow & IRQ_TYPE_EDGE_BOTH) == 0)
328 		irq_set_handler_locked(data, handle_level_irq);
329 	else
330 		irq_set_handler_locked(data, handle_edge_irq);
331 
332 	return 0;
333 }
334 
335 static void tegra186_gpio_irq(struct irq_desc *desc)
336 {
337 	struct tegra_gpio *gpio = irq_desc_get_handler_data(desc);
338 	struct irq_domain *domain = gpio->gpio.irq.domain;
339 	struct irq_chip *chip = irq_desc_get_chip(desc);
340 	unsigned int parent = irq_desc_get_irq(desc);
341 	unsigned int i, offset = 0;
342 
343 	chained_irq_enter(chip, desc);
344 
345 	for (i = 0; i < gpio->soc->num_ports; i++) {
346 		const struct tegra_gpio_port *port = &gpio->soc->ports[i];
347 		void __iomem *base = gpio->base + port->offset;
348 		unsigned int pin, irq;
349 		unsigned long value;
350 
351 		/* skip ports that are not associated with this controller */
352 		if (parent != gpio->irq[port->irq])
353 			goto skip;
354 
355 		value = readl(base + TEGRA186_GPIO_INTERRUPT_STATUS(1));
356 
357 		for_each_set_bit(pin, &value, port->pins) {
358 			irq = irq_find_mapping(domain, offset + pin);
359 			if (WARN_ON(irq == 0))
360 				continue;
361 
362 			generic_handle_irq(irq);
363 		}
364 
365 skip:
366 		offset += port->pins;
367 	}
368 
369 	chained_irq_exit(chip, desc);
370 }
371 
372 static int tegra186_gpio_irq_domain_xlate(struct irq_domain *domain,
373 					  struct device_node *np,
374 					  const u32 *spec, unsigned int size,
375 					  unsigned long *hwirq,
376 					  unsigned int *type)
377 {
378 	struct tegra_gpio *gpio = gpiochip_get_data(domain->host_data);
379 	unsigned int port, pin, i, offset = 0;
380 
381 	if (size < 2)
382 		return -EINVAL;
383 
384 	port = spec[0] / 8;
385 	pin = spec[0] % 8;
386 
387 	if (port >= gpio->soc->num_ports) {
388 		dev_err(gpio->gpio.parent, "invalid port number: %u\n", port);
389 		return -EINVAL;
390 	}
391 
392 	for (i = 0; i < port; i++)
393 		offset += gpio->soc->ports[i].pins;
394 
395 	*type = spec[1] & IRQ_TYPE_SENSE_MASK;
396 	*hwirq = offset + pin;
397 
398 	return 0;
399 }
400 
401 static const struct irq_domain_ops tegra186_gpio_irq_domain_ops = {
402 	.map = gpiochip_irq_map,
403 	.unmap = gpiochip_irq_unmap,
404 	.xlate = tegra186_gpio_irq_domain_xlate,
405 };
406 
407 static int tegra186_gpio_probe(struct platform_device *pdev)
408 {
409 	unsigned int i, j, offset;
410 	struct gpio_irq_chip *irq;
411 	struct tegra_gpio *gpio;
412 	struct resource *res;
413 	char **names;
414 	int err;
415 
416 	gpio = devm_kzalloc(&pdev->dev, sizeof(*gpio), GFP_KERNEL);
417 	if (!gpio)
418 		return -ENOMEM;
419 
420 	gpio->soc = of_device_get_match_data(&pdev->dev);
421 
422 	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "gpio");
423 	gpio->base = devm_ioremap_resource(&pdev->dev, res);
424 	if (IS_ERR(gpio->base))
425 		return PTR_ERR(gpio->base);
426 
427 	err = platform_irq_count(pdev);
428 	if (err < 0)
429 		return err;
430 
431 	gpio->num_irq = err;
432 
433 	gpio->irq = devm_kcalloc(&pdev->dev, gpio->num_irq, sizeof(*gpio->irq),
434 				 GFP_KERNEL);
435 	if (!gpio->irq)
436 		return -ENOMEM;
437 
438 	for (i = 0; i < gpio->num_irq; i++) {
439 		err = platform_get_irq(pdev, i);
440 		if (err < 0)
441 			return err;
442 
443 		gpio->irq[i] = err;
444 	}
445 
446 	gpio->gpio.label = gpio->soc->name;
447 	gpio->gpio.parent = &pdev->dev;
448 
449 	gpio->gpio.get_direction = tegra186_gpio_get_direction;
450 	gpio->gpio.direction_input = tegra186_gpio_direction_input;
451 	gpio->gpio.direction_output = tegra186_gpio_direction_output;
452 	gpio->gpio.get = tegra186_gpio_get,
453 	gpio->gpio.set = tegra186_gpio_set;
454 
455 	gpio->gpio.base = -1;
456 
457 	for (i = 0; i < gpio->soc->num_ports; i++)
458 		gpio->gpio.ngpio += gpio->soc->ports[i].pins;
459 
460 	names = devm_kcalloc(gpio->gpio.parent, gpio->gpio.ngpio,
461 			     sizeof(*names), GFP_KERNEL);
462 	if (!names)
463 		return -ENOMEM;
464 
465 	for (i = 0, offset = 0; i < gpio->soc->num_ports; i++) {
466 		const struct tegra_gpio_port *port = &gpio->soc->ports[i];
467 		char *name;
468 
469 		for (j = 0; j < port->pins; j++) {
470 			name = devm_kasprintf(gpio->gpio.parent, GFP_KERNEL,
471 					      "P%s.%02x", port->name, j);
472 			if (!name)
473 				return -ENOMEM;
474 
475 			names[offset + j] = name;
476 		}
477 
478 		offset += port->pins;
479 	}
480 
481 	gpio->gpio.names = (const char * const *)names;
482 
483 	gpio->gpio.of_node = pdev->dev.of_node;
484 	gpio->gpio.of_gpio_n_cells = 2;
485 	gpio->gpio.of_xlate = tegra186_gpio_of_xlate;
486 
487 	gpio->intc.name = pdev->dev.of_node->name;
488 	gpio->intc.irq_ack = tegra186_irq_ack;
489 	gpio->intc.irq_mask = tegra186_irq_mask;
490 	gpio->intc.irq_unmask = tegra186_irq_unmask;
491 	gpio->intc.irq_set_type = tegra186_irq_set_type;
492 
493 	irq = &gpio->gpio.irq;
494 	irq->chip = &gpio->intc;
495 	irq->domain_ops = &tegra186_gpio_irq_domain_ops;
496 	irq->handler = handle_simple_irq;
497 	irq->default_type = IRQ_TYPE_NONE;
498 	irq->parent_handler = tegra186_gpio_irq;
499 	irq->parent_handler_data = gpio;
500 	irq->num_parents = gpio->num_irq;
501 	irq->parents = gpio->irq;
502 
503 	irq->map = devm_kcalloc(&pdev->dev, gpio->gpio.ngpio,
504 				sizeof(*irq->map), GFP_KERNEL);
505 	if (!irq->map)
506 		return -ENOMEM;
507 
508 	for (i = 0, offset = 0; i < gpio->soc->num_ports; i++) {
509 		const struct tegra_gpio_port *port = &gpio->soc->ports[i];
510 
511 		for (j = 0; j < port->pins; j++)
512 			irq->map[offset + j] = irq->parents[port->irq];
513 
514 		offset += port->pins;
515 	}
516 
517 	platform_set_drvdata(pdev, gpio);
518 
519 	err = devm_gpiochip_add_data(&pdev->dev, &gpio->gpio, gpio);
520 	if (err < 0)
521 		return err;
522 
523 	return 0;
524 }
525 
526 static int tegra186_gpio_remove(struct platform_device *pdev)
527 {
528 	return 0;
529 }
530 
531 #define TEGRA_MAIN_GPIO_PORT(port, base, count, controller)	\
532 	[TEGRA_MAIN_GPIO_PORT_##port] = {			\
533 		.name = #port,					\
534 		.offset = base,					\
535 		.pins = count,					\
536 		.irq = controller,				\
537 	}
538 
539 static const struct tegra_gpio_port tegra186_main_ports[] = {
540 	TEGRA_MAIN_GPIO_PORT( A, 0x2000, 7, 2),
541 	TEGRA_MAIN_GPIO_PORT( B, 0x3000, 7, 3),
542 	TEGRA_MAIN_GPIO_PORT( C, 0x3200, 7, 3),
543 	TEGRA_MAIN_GPIO_PORT( D, 0x3400, 6, 3),
544 	TEGRA_MAIN_GPIO_PORT( E, 0x2200, 8, 2),
545 	TEGRA_MAIN_GPIO_PORT( F, 0x2400, 6, 2),
546 	TEGRA_MAIN_GPIO_PORT( G, 0x4200, 6, 4),
547 	TEGRA_MAIN_GPIO_PORT( H, 0x1000, 7, 1),
548 	TEGRA_MAIN_GPIO_PORT( I, 0x0800, 8, 0),
549 	TEGRA_MAIN_GPIO_PORT( J, 0x5000, 8, 5),
550 	TEGRA_MAIN_GPIO_PORT( K, 0x5200, 1, 5),
551 	TEGRA_MAIN_GPIO_PORT( L, 0x1200, 8, 1),
552 	TEGRA_MAIN_GPIO_PORT( M, 0x5600, 6, 5),
553 	TEGRA_MAIN_GPIO_PORT( N, 0x0000, 7, 0),
554 	TEGRA_MAIN_GPIO_PORT( O, 0x0200, 4, 0),
555 	TEGRA_MAIN_GPIO_PORT( P, 0x4000, 7, 4),
556 	TEGRA_MAIN_GPIO_PORT( Q, 0x0400, 6, 0),
557 	TEGRA_MAIN_GPIO_PORT( R, 0x0a00, 6, 0),
558 	TEGRA_MAIN_GPIO_PORT( T, 0x0600, 4, 0),
559 	TEGRA_MAIN_GPIO_PORT( X, 0x1400, 8, 1),
560 	TEGRA_MAIN_GPIO_PORT( Y, 0x1600, 7, 1),
561 	TEGRA_MAIN_GPIO_PORT(BB, 0x2600, 2, 2),
562 	TEGRA_MAIN_GPIO_PORT(CC, 0x5400, 4, 5),
563 };
564 
565 static const struct tegra_gpio_soc tegra186_main_soc = {
566 	.num_ports = ARRAY_SIZE(tegra186_main_ports),
567 	.ports = tegra186_main_ports,
568 	.name = "tegra186-gpio",
569 };
570 
571 #define TEGRA_AON_GPIO_PORT(port, base, count, controller)	\
572 	[TEGRA_AON_GPIO_PORT_##port] = {			\
573 		.name = #port,					\
574 		.offset = base,					\
575 		.pins = count,					\
576 		.irq = controller,				\
577 	}
578 
579 static const struct tegra_gpio_port tegra186_aon_ports[] = {
580 	TEGRA_AON_GPIO_PORT( S, 0x0200, 5, 0),
581 	TEGRA_AON_GPIO_PORT( U, 0x0400, 6, 0),
582 	TEGRA_AON_GPIO_PORT( V, 0x0800, 8, 0),
583 	TEGRA_AON_GPIO_PORT( W, 0x0a00, 8, 0),
584 	TEGRA_AON_GPIO_PORT( Z, 0x0e00, 4, 0),
585 	TEGRA_AON_GPIO_PORT(AA, 0x0c00, 8, 0),
586 	TEGRA_AON_GPIO_PORT(EE, 0x0600, 3, 0),
587 	TEGRA_AON_GPIO_PORT(FF, 0x0000, 5, 0),
588 };
589 
590 static const struct tegra_gpio_soc tegra186_aon_soc = {
591 	.num_ports = ARRAY_SIZE(tegra186_aon_ports),
592 	.ports = tegra186_aon_ports,
593 	.name = "tegra186-gpio-aon",
594 };
595 
596 static const struct of_device_id tegra186_gpio_of_match[] = {
597 	{
598 		.compatible = "nvidia,tegra186-gpio",
599 		.data = &tegra186_main_soc
600 	}, {
601 		.compatible = "nvidia,tegra186-gpio-aon",
602 		.data = &tegra186_aon_soc
603 	}, {
604 		/* sentinel */
605 	}
606 };
607 
608 static struct platform_driver tegra186_gpio_driver = {
609 	.driver = {
610 		.name = "tegra186-gpio",
611 		.of_match_table = tegra186_gpio_of_match,
612 	},
613 	.probe = tegra186_gpio_probe,
614 	.remove = tegra186_gpio_remove,
615 };
616 module_platform_driver(tegra186_gpio_driver);
617 
618 MODULE_DESCRIPTION("NVIDIA Tegra186 GPIO controller driver");
619 MODULE_AUTHOR("Thierry Reding <treding@nvidia.com>");
620 MODULE_LICENSE("GPL v2");
621