aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pinctrl/pinctrl-exynos.c
diff options
context:
space:
mode:
authorThomas Abraham <thomas.abraham@linaro.org>2012-09-06 17:07:19 -0400
committerKukjin Kim <kgene.kim@samsung.com>2012-09-06 17:07:19 -0400
commit43b169db184184e1df8dea198d454a06602c5150 (patch)
tree48cb4bcd88dafdf3565b5831d98bcb3767846d52 /drivers/pinctrl/pinctrl-exynos.c
parent30574f0db1b16fedf705cb792099f8a3171598eb (diff)
pinctrl: add exynos4210 specific extensions for samsung pinctrl driver
Add information about the Exynos4210 pin banks and driver data which is used by the Samsung pinctrl driver. In addition to this, the support for external gpio and wakeup interrupt support is included and hooked up with the Samsung pinctrl driver. Signed-off-by: Thomas Abraham <thomas.abraham@linaro.org> Reviewed-by: Linus Walleij <linus.walleij@linaro.org> Signed-off-by: Kukjin Kim <kgene.kim@samsung.com>
Diffstat (limited to 'drivers/pinctrl/pinctrl-exynos.c')
-rw-r--r--drivers/pinctrl/pinctrl-exynos.c560
1 files changed, 560 insertions, 0 deletions
diff --git a/drivers/pinctrl/pinctrl-exynos.c b/drivers/pinctrl/pinctrl-exynos.c
new file mode 100644
index 000000000000..447818d9851b
--- /dev/null
+++ b/drivers/pinctrl/pinctrl-exynos.c
@@ -0,0 +1,560 @@
1/*
2 * Exynos specific support for Samsung pinctrl/gpiolib driver with eint support.
3 *
4 * Copyright (c) 2012 Samsung Electronics Co., Ltd.
5 * http://www.samsung.com
6 * Copyright (c) 2012 Linaro Ltd
7 * http://www.linaro.org
8 *
9 * Author: Thomas Abraham <thomas.ab@samsung.com>
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
15 *
16 * This file contains the Samsung Exynos specific information required by the
17 * the Samsung pinctrl/gpiolib driver. It also includes the implementation of
18 * external gpio and wakeup interrupt support.
19 */
20
21#include <linux/module.h>
22#include <linux/device.h>
23#include <linux/interrupt.h>
24#include <linux/irqdomain.h>
25#include <linux/irq.h>
26#include <linux/of_irq.h>
27#include <linux/io.h>
28#include <linux/slab.h>
29#include <linux/err.h>
30
31#include <asm/mach/irq.h>
32
33#include "pinctrl-samsung.h"
34#include "pinctrl-exynos.h"
35
36/* list of external wakeup controllers supported */
37static const struct of_device_id exynos_wkup_irq_ids[] = {
38 { .compatible = "samsung,exynos4210-wakeup-eint", },
39};
40
41static void exynos_gpio_irq_unmask(struct irq_data *irqd)
42{
43 struct samsung_pinctrl_drv_data *d = irqd->domain->host_data;
44 struct exynos_geint_data *edata = irq_data_get_irq_handler_data(irqd);
45 unsigned long reg_mask = d->ctrl->geint_mask + edata->eint_offset;
46 unsigned long mask;
47
48 mask = readl(d->virt_base + reg_mask);
49 mask &= ~(1 << edata->pin);
50 writel(mask, d->virt_base + reg_mask);
51}
52
53static void exynos_gpio_irq_mask(struct irq_data *irqd)
54{
55 struct samsung_pinctrl_drv_data *d = irqd->domain->host_data;
56 struct exynos_geint_data *edata = irq_data_get_irq_handler_data(irqd);
57 unsigned long reg_mask = d->ctrl->geint_mask + edata->eint_offset;
58 unsigned long mask;
59
60 mask = readl(d->virt_base + reg_mask);
61 mask |= ~(1 << edata->pin);
62 writel(mask, d->virt_base + reg_mask);
63}
64
65static void exynos_gpio_irq_ack(struct irq_data *irqd)
66{
67 struct samsung_pinctrl_drv_data *d = irqd->domain->host_data;
68 struct exynos_geint_data *edata = irq_data_get_irq_handler_data(irqd);
69 unsigned long reg_pend = d->ctrl->geint_pend + edata->eint_offset;
70
71 writel(1 << edata->pin, d->virt_base + reg_pend);
72}
73
74static int exynos_gpio_irq_set_type(struct irq_data *irqd, unsigned int type)
75{
76 struct samsung_pinctrl_drv_data *d = irqd->domain->host_data;
77 struct samsung_pin_ctrl *ctrl = d->ctrl;
78 struct exynos_geint_data *edata = irq_data_get_irq_handler_data(irqd);
79 unsigned int shift = EXYNOS_EINT_CON_LEN * edata->pin;
80 unsigned int con, trig_type;
81 unsigned long reg_con = ctrl->geint_con + edata->eint_offset;
82
83 switch (type) {
84 case IRQ_TYPE_EDGE_RISING:
85 trig_type = EXYNOS_EINT_EDGE_RISING;
86 break;
87 case IRQ_TYPE_EDGE_FALLING:
88 trig_type = EXYNOS_EINT_EDGE_FALLING;
89 break;
90 case IRQ_TYPE_EDGE_BOTH:
91 trig_type = EXYNOS_EINT_EDGE_BOTH;
92 break;
93 case IRQ_TYPE_LEVEL_HIGH:
94 trig_type = EXYNOS_EINT_LEVEL_HIGH;
95 break;
96 case IRQ_TYPE_LEVEL_LOW:
97 trig_type = EXYNOS_EINT_LEVEL_LOW;
98 break;
99 default:
100 pr_err("unsupported external interrupt type\n");
101 return -EINVAL;
102 }
103
104 if (type & IRQ_TYPE_EDGE_BOTH)
105 __irq_set_handler_locked(irqd->irq, handle_edge_irq);
106 else
107 __irq_set_handler_locked(irqd->irq, handle_level_irq);
108
109 con = readl(d->virt_base + reg_con);
110 con &= ~(EXYNOS_EINT_CON_MASK << shift);
111 con |= trig_type << shift;
112 writel(con, d->virt_base + reg_con);
113 return 0;
114}
115
116/*
117 * irq_chip for gpio interrupts.
118 */
119static struct irq_chip exynos_gpio_irq_chip = {
120 .name = "exynos_gpio_irq_chip",
121 .irq_unmask = exynos_gpio_irq_unmask,
122 .irq_mask = exynos_gpio_irq_mask,
123 .irq_ack = exynos_gpio_irq_ack,
124 .irq_set_type = exynos_gpio_irq_set_type,
125};
126
127/*
128 * given a controller-local external gpio interrupt number, prepare the handler
129 * data for it.
130 */
131static struct exynos_geint_data *exynos_get_eint_data(irq_hw_number_t hw,
132 struct samsung_pinctrl_drv_data *d)
133{
134 struct samsung_pin_bank *bank = d->ctrl->pin_banks;
135 struct exynos_geint_data *eint_data;
136 unsigned int nr_banks = d->ctrl->nr_banks, idx;
137 unsigned int irq_base = 0, eint_offset = 0;
138
139 if (hw >= d->ctrl->nr_gint) {
140 dev_err(d->dev, "unsupported ext-gpio interrupt\n");
141 return NULL;
142 }
143
144 for (idx = 0; idx < nr_banks; idx++, bank++) {
145 if (bank->eint_type != EINT_TYPE_GPIO)
146 continue;
147 if ((hw >= irq_base) && (hw < (irq_base + bank->nr_pins)))
148 break;
149 irq_base += bank->nr_pins;
150 eint_offset += 4;
151 }
152
153 if (idx == nr_banks) {
154 dev_err(d->dev, "pin bank not found for ext-gpio interrupt\n");
155 return NULL;
156 }
157
158 eint_data = devm_kzalloc(d->dev, sizeof(*eint_data), GFP_KERNEL);
159 if (!eint_data) {
160 dev_err(d->dev, "no memory for eint-gpio data\n");
161 return NULL;
162 }
163
164 eint_data->bank = bank;
165 eint_data->pin = hw - irq_base;
166 eint_data->eint_offset = eint_offset;
167 return eint_data;
168}
169
170static int exynos_gpio_irq_map(struct irq_domain *h, unsigned int virq,
171 irq_hw_number_t hw)
172{
173 struct samsung_pinctrl_drv_data *d = h->host_data;
174 struct exynos_geint_data *eint_data;
175
176 eint_data = exynos_get_eint_data(hw, d);
177 if (!eint_data)
178 return -EINVAL;
179
180 irq_set_handler_data(virq, eint_data);
181 irq_set_chip_data(virq, h->host_data);
182 irq_set_chip_and_handler(virq, &exynos_gpio_irq_chip,
183 handle_level_irq);
184 set_irq_flags(virq, IRQF_VALID);
185 return 0;
186}
187
188static void exynos_gpio_irq_unmap(struct irq_domain *h, unsigned int virq)
189{
190 struct samsung_pinctrl_drv_data *d = h->host_data;
191 struct exynos_geint_data *eint_data;
192
193 eint_data = irq_get_handler_data(virq);
194 devm_kfree(d->dev, eint_data);
195}
196
197/*
198 * irq domain callbacks for external gpio interrupt controller.
199 */
200static const struct irq_domain_ops exynos_gpio_irqd_ops = {
201 .map = exynos_gpio_irq_map,
202 .unmap = exynos_gpio_irq_unmap,
203 .xlate = irq_domain_xlate_twocell,
204};
205
206static irqreturn_t exynos_eint_gpio_irq(int irq, void *data)
207{
208 struct samsung_pinctrl_drv_data *d = data;
209 struct samsung_pin_ctrl *ctrl = d->ctrl;
210 struct samsung_pin_bank *bank = ctrl->pin_banks;
211 unsigned int svc, group, pin, virq;
212
213 svc = readl(d->virt_base + ctrl->svc);
214 group = EXYNOS_SVC_GROUP(svc);
215 pin = svc & EXYNOS_SVC_NUM_MASK;
216
217 if (!group)
218 return IRQ_HANDLED;
219 bank += (group - 1);
220
221 virq = irq_linear_revmap(d->gpio_irqd, bank->irq_base + pin);
222 if (!virq)
223 return IRQ_NONE;
224 generic_handle_irq(virq);
225 return IRQ_HANDLED;
226}
227
228/*
229 * exynos_eint_gpio_init() - setup handling of external gpio interrupts.
230 * @d: driver data of samsung pinctrl driver.
231 */
232static int exynos_eint_gpio_init(struct samsung_pinctrl_drv_data *d)
233{
234 struct device *dev = d->dev;
235 unsigned int ret;
236
237 if (!d->irq) {
238 dev_err(dev, "irq number not available\n");
239 return -EINVAL;
240 }
241
242 ret = devm_request_irq(dev, d->irq, exynos_eint_gpio_irq,
243 0, dev_name(dev), d);
244 if (ret) {
245 dev_err(dev, "irq request failed\n");
246 return -ENXIO;
247 }
248
249 d->gpio_irqd = irq_domain_add_linear(dev->of_node, d->ctrl->nr_gint,
250 &exynos_gpio_irqd_ops, d);
251 if (!d->gpio_irqd) {
252 dev_err(dev, "gpio irq domain allocation failed\n");
253 return -ENXIO;
254 }
255
256 return 0;
257}
258
259static void exynos_wkup_irq_unmask(struct irq_data *irqd)
260{
261 struct samsung_pinctrl_drv_data *d = irq_data_get_irq_chip_data(irqd);
262 unsigned int bank = irqd->hwirq / EXYNOS_EINT_MAX_PER_BANK;
263 unsigned int pin = irqd->hwirq & (EXYNOS_EINT_MAX_PER_BANK - 1);
264 unsigned long reg_mask = d->ctrl->weint_mask + (bank << 2);
265 unsigned long mask;
266
267 mask = readl(d->virt_base + reg_mask);
268 mask &= ~(1 << pin);
269 writel(mask, d->virt_base + reg_mask);
270}
271
272static void exynos_wkup_irq_mask(struct irq_data *irqd)
273{
274 struct samsung_pinctrl_drv_data *d = irq_data_get_irq_chip_data(irqd);
275 unsigned int bank = irqd->hwirq / EXYNOS_EINT_MAX_PER_BANK;
276 unsigned int pin = irqd->hwirq & (EXYNOS_EINT_MAX_PER_BANK - 1);
277 unsigned long reg_mask = d->ctrl->weint_mask + (bank << 2);
278 unsigned long mask;
279
280 mask = readl(d->virt_base + reg_mask);
281 mask &= ~(1 << pin);
282 writel(mask, d->virt_base + reg_mask);
283}
284
285static void exynos_wkup_irq_ack(struct irq_data *irqd)
286{
287 struct samsung_pinctrl_drv_data *d = irq_data_get_irq_chip_data(irqd);
288 unsigned int bank = irqd->hwirq / EXYNOS_EINT_MAX_PER_BANK;
289 unsigned int pin = irqd->hwirq & (EXYNOS_EINT_MAX_PER_BANK - 1);
290 unsigned long pend = d->ctrl->weint_pend + (bank << 2);
291
292 writel(1 << pin, d->virt_base + pend);
293}
294
295static int exynos_wkup_irq_set_type(struct irq_data *irqd, unsigned int type)
296{
297 struct samsung_pinctrl_drv_data *d = irq_data_get_irq_chip_data(irqd);
298 unsigned int bank = irqd->hwirq / EXYNOS_EINT_MAX_PER_BANK;
299 unsigned int pin = irqd->hwirq & (EXYNOS_EINT_MAX_PER_BANK - 1);
300 unsigned long reg_con = d->ctrl->weint_con + (bank << 2);
301 unsigned long shift = EXYNOS_EINT_CON_LEN * pin;
302 unsigned long con, trig_type;
303
304 switch (type) {
305 case IRQ_TYPE_EDGE_RISING:
306 trig_type = EXYNOS_EINT_EDGE_RISING;
307 break;
308 case IRQ_TYPE_EDGE_FALLING:
309 trig_type = EXYNOS_EINT_EDGE_FALLING;
310 break;
311 case IRQ_TYPE_EDGE_BOTH:
312 trig_type = EXYNOS_EINT_EDGE_BOTH;
313 break;
314 case IRQ_TYPE_LEVEL_HIGH:
315 trig_type = EXYNOS_EINT_LEVEL_HIGH;
316 break;
317 case IRQ_TYPE_LEVEL_LOW:
318 trig_type = EXYNOS_EINT_LEVEL_LOW;
319 break;
320 default:
321 pr_err("unsupported external interrupt type\n");
322 return -EINVAL;
323 }
324
325 if (type & IRQ_TYPE_EDGE_BOTH)
326 __irq_set_handler_locked(irqd->irq, handle_edge_irq);
327 else
328 __irq_set_handler_locked(irqd->irq, handle_level_irq);
329
330 con = readl(d->virt_base + reg_con);
331 con &= ~(EXYNOS_EINT_CON_MASK << shift);
332 con |= trig_type << shift;
333 writel(con, d->virt_base + reg_con);
334 return 0;
335}
336
337/*
338 * irq_chip for wakeup interrupts
339 */
340static struct irq_chip exynos_wkup_irq_chip = {
341 .name = "exynos_wkup_irq_chip",
342 .irq_unmask = exynos_wkup_irq_unmask,
343 .irq_mask = exynos_wkup_irq_mask,
344 .irq_ack = exynos_wkup_irq_ack,
345 .irq_set_type = exynos_wkup_irq_set_type,
346};
347
348/* interrupt handler for wakeup interrupts 0..15 */
349static void exynos_irq_eint0_15(unsigned int irq, struct irq_desc *desc)
350{
351 struct exynos_weint_data *eintd = irq_get_handler_data(irq);
352 struct irq_chip *chip = irq_get_chip(irq);
353 int eint_irq;
354
355 chained_irq_enter(chip, desc);
356 chip->irq_mask(&desc->irq_data);
357
358 if (chip->irq_ack)
359 chip->irq_ack(&desc->irq_data);
360
361 eint_irq = irq_linear_revmap(eintd->domain, eintd->irq);
362 generic_handle_irq(eint_irq);
363 chip->irq_unmask(&desc->irq_data);
364 chained_irq_exit(chip, desc);
365}
366
367static void exynos_irq_demux_eint(int irq_base, unsigned long pend,
368 struct irq_domain *domain)
369{
370 unsigned int irq;
371
372 while (pend) {
373 irq = fls(pend) - 1;
374 generic_handle_irq(irq_find_mapping(domain, irq_base + irq));
375 pend &= ~(1 << irq);
376 }
377}
378
379/* interrupt handler for wakeup interrupt 16 */
380static void exynos_irq_demux_eint16_31(unsigned int irq, struct irq_desc *desc)
381{
382 struct irq_chip *chip = irq_get_chip(irq);
383 struct exynos_weint_data *eintd = irq_get_handler_data(irq);
384 struct samsung_pinctrl_drv_data *d = eintd->domain->host_data;
385 unsigned long pend;
386
387 chained_irq_enter(chip, desc);
388 pend = readl(d->virt_base + d->ctrl->weint_pend + 0x8);
389 exynos_irq_demux_eint(16, pend, eintd->domain);
390 pend = readl(d->virt_base + d->ctrl->weint_pend + 0xC);
391 exynos_irq_demux_eint(24, pend, eintd->domain);
392 chained_irq_exit(chip, desc);
393}
394
395static int exynos_wkup_irq_map(struct irq_domain *h, unsigned int virq,
396 irq_hw_number_t hw)
397{
398 irq_set_chip_and_handler(virq, &exynos_wkup_irq_chip, handle_level_irq);
399 irq_set_chip_data(virq, h->host_data);
400 set_irq_flags(virq, IRQF_VALID);
401 return 0;
402}
403
404/*
405 * irq domain callbacks for external wakeup interrupt controller.
406 */
407static const struct irq_domain_ops exynos_wkup_irqd_ops = {
408 .map = exynos_wkup_irq_map,
409 .xlate = irq_domain_xlate_twocell,
410};
411
412/*
413 * exynos_eint_wkup_init() - setup handling of external wakeup interrupts.
414 * @d: driver data of samsung pinctrl driver.
415 */
416static int exynos_eint_wkup_init(struct samsung_pinctrl_drv_data *d)
417{
418 struct device *dev = d->dev;
419 struct device_node *wkup_np;
420 struct exynos_weint_data *weint_data;
421 int idx, irq;
422
423 wkup_np = of_find_matching_node(dev->of_node, exynos_wkup_irq_ids);
424 if (!wkup_np) {
425 dev_err(dev, "wakeup controller node not found\n");
426 return -ENODEV;
427 }
428
429 d->wkup_irqd = irq_domain_add_linear(wkup_np, d->ctrl->nr_wint,
430 &exynos_wkup_irqd_ops, d);
431 if (!d->gpio_irqd) {
432 dev_err(dev, "wakeup irq domain allocation failed\n");
433 return -ENXIO;
434 }
435
436 weint_data = devm_kzalloc(dev, sizeof(*weint_data) * 17, GFP_KERNEL);
437 if (!weint_data) {
438 dev_err(dev, "could not allocate memory for weint_data\n");
439 return -ENOMEM;
440 }
441
442 irq = irq_of_parse_and_map(wkup_np, 16);
443 if (irq) {
444 weint_data[16].domain = d->wkup_irqd;
445 irq_set_chained_handler(irq, exynos_irq_demux_eint16_31);
446 irq_set_handler_data(irq, &weint_data[16]);
447 } else {
448 dev_err(dev, "irq number for EINT16-32 not found\n");
449 }
450
451 for (idx = 0; idx < 16; idx++) {
452 weint_data[idx].domain = d->wkup_irqd;
453 weint_data[idx].irq = idx;
454
455 irq = irq_of_parse_and_map(wkup_np, idx);
456 if (irq) {
457 irq_set_handler_data(irq, &weint_data[idx]);
458 irq_set_chained_handler(irq, exynos_irq_eint0_15);
459 } else {
460 dev_err(dev, "irq number for eint-%x not found\n", idx);
461 }
462 }
463 return 0;
464}
465
466/* pin banks of exynos4210 pin-controller 0 */
467static struct samsung_pin_bank exynos4210_pin_banks0[] = {
468 EXYNOS_PIN_BANK_EINTG(0x000, EXYNOS4210_GPIO_A0, "gpa0"),
469 EXYNOS_PIN_BANK_EINTG(0x020, EXYNOS4210_GPIO_A1, "gpa1"),
470 EXYNOS_PIN_BANK_EINTG(0x040, EXYNOS4210_GPIO_B, "gpb"),
471 EXYNOS_PIN_BANK_EINTG(0x060, EXYNOS4210_GPIO_C0, "gpc0"),
472 EXYNOS_PIN_BANK_EINTG(0x080, EXYNOS4210_GPIO_C1, "gpc1"),
473 EXYNOS_PIN_BANK_EINTG(0x0A0, EXYNOS4210_GPIO_D0, "gpd0"),
474 EXYNOS_PIN_BANK_EINTG(0x0C0, EXYNOS4210_GPIO_D1, "gpd1"),
475 EXYNOS_PIN_BANK_EINTG(0x0E0, EXYNOS4210_GPIO_E0, "gpe0"),
476 EXYNOS_PIN_BANK_EINTG(0x100, EXYNOS4210_GPIO_E1, "gpe1"),
477 EXYNOS_PIN_BANK_EINTG(0x120, EXYNOS4210_GPIO_E2, "gpe2"),
478 EXYNOS_PIN_BANK_EINTG(0x140, EXYNOS4210_GPIO_E3, "gpe3"),
479 EXYNOS_PIN_BANK_EINTG(0x160, EXYNOS4210_GPIO_E4, "gpe4"),
480 EXYNOS_PIN_BANK_EINTG(0x180, EXYNOS4210_GPIO_F0, "gpf0"),
481 EXYNOS_PIN_BANK_EINTG(0x1A0, EXYNOS4210_GPIO_F1, "gpf1"),
482 EXYNOS_PIN_BANK_EINTG(0x1C0, EXYNOS4210_GPIO_F2, "gpf2"),
483 EXYNOS_PIN_BANK_EINTG(0x1E0, EXYNOS4210_GPIO_F3, "gpf3"),
484};
485
486/* pin banks of exynos4210 pin-controller 1 */
487static struct samsung_pin_bank exynos4210_pin_banks1[] = {
488 EXYNOS_PIN_BANK_EINTG(0x000, EXYNOS4210_GPIO_J0, "gpj0"),
489 EXYNOS_PIN_BANK_EINTG(0x020, EXYNOS4210_GPIO_J1, "gpj1"),
490 EXYNOS_PIN_BANK_EINTG(0x040, EXYNOS4210_GPIO_K0, "gpk0"),
491 EXYNOS_PIN_BANK_EINTG(0x060, EXYNOS4210_GPIO_K1, "gpk1"),
492 EXYNOS_PIN_BANK_EINTG(0x080, EXYNOS4210_GPIO_K2, "gpk2"),
493 EXYNOS_PIN_BANK_EINTG(0x0A0, EXYNOS4210_GPIO_K3, "gpk3"),
494 EXYNOS_PIN_BANK_EINTG(0x0C0, EXYNOS4210_GPIO_L0, "gpl0"),
495 EXYNOS_PIN_BANK_EINTG(0x0E0, EXYNOS4210_GPIO_L1, "gpl1"),
496 EXYNOS_PIN_BANK_EINTG(0x100, EXYNOS4210_GPIO_L2, "gpl2"),
497 EXYNOS_PIN_BANK_EINTN(0x120, EXYNOS4210_GPIO_Y0, "gpy0"),
498 EXYNOS_PIN_BANK_EINTN(0x140, EXYNOS4210_GPIO_Y1, "gpy1"),
499 EXYNOS_PIN_BANK_EINTN(0x160, EXYNOS4210_GPIO_Y2, "gpy2"),
500 EXYNOS_PIN_BANK_EINTN(0x180, EXYNOS4210_GPIO_Y3, "gpy3"),
501 EXYNOS_PIN_BANK_EINTN(0x1A0, EXYNOS4210_GPIO_Y4, "gpy4"),
502 EXYNOS_PIN_BANK_EINTN(0x1C0, EXYNOS4210_GPIO_Y5, "gpy5"),
503 EXYNOS_PIN_BANK_EINTN(0x1E0, EXYNOS4210_GPIO_Y6, "gpy6"),
504 EXYNOS_PIN_BANK_EINTN(0xC00, EXYNOS4210_GPIO_X0, "gpx0"),
505 EXYNOS_PIN_BANK_EINTN(0xC20, EXYNOS4210_GPIO_X1, "gpx1"),
506 EXYNOS_PIN_BANK_EINTN(0xC40, EXYNOS4210_GPIO_X2, "gpx2"),
507 EXYNOS_PIN_BANK_EINTN(0xC60, EXYNOS4210_GPIO_X3, "gpx3"),
508};
509
510/* pin banks of exynos4210 pin-controller 2 */
511static struct samsung_pin_bank exynos4210_pin_banks2[] = {
512 EXYNOS_PIN_BANK_EINTN(0x000, EXYNOS4210_GPIO_Z, "gpz"),
513};
514
515/*
516 * Samsung pinctrl driver data for Exynos4210 SoC. Exynos4210 SoC includes
517 * three gpio/pin-mux/pinconfig controllers.
518 */
519struct samsung_pin_ctrl exynos4210_pin_ctrl[] = {
520 {
521 /* pin-controller instance 0 data */
522 .pin_banks = exynos4210_pin_banks0,
523 .nr_banks = ARRAY_SIZE(exynos4210_pin_banks0),
524 .base = EXYNOS4210_GPIO_A0_START,
525 .nr_pins = EXYNOS4210_GPIOA_NR_PINS,
526 .nr_gint = EXYNOS4210_GPIOA_NR_GINT,
527 .geint_con = EXYNOS_GPIO_ECON_OFFSET,
528 .geint_mask = EXYNOS_GPIO_EMASK_OFFSET,
529 .geint_pend = EXYNOS_GPIO_EPEND_OFFSET,
530 .svc = EXYNOS_SVC_OFFSET,
531 .eint_gpio_init = exynos_eint_gpio_init,
532 .label = "exynos4210-gpio-ctrl0",
533 }, {
534 /* pin-controller instance 1 data */
535 .pin_banks = exynos4210_pin_banks1,
536 .nr_banks = ARRAY_SIZE(exynos4210_pin_banks1),
537 .base = EXYNOS4210_GPIOA_NR_PINS,
538 .nr_pins = EXYNOS4210_GPIOB_NR_PINS,
539 .nr_gint = EXYNOS4210_GPIOB_NR_GINT,
540 .nr_wint = 32,
541 .geint_con = EXYNOS_GPIO_ECON_OFFSET,
542 .geint_mask = EXYNOS_GPIO_EMASK_OFFSET,
543 .geint_pend = EXYNOS_GPIO_EPEND_OFFSET,
544 .weint_con = EXYNOS_WKUP_ECON_OFFSET,
545 .weint_mask = EXYNOS_WKUP_EMASK_OFFSET,
546 .weint_pend = EXYNOS_WKUP_EPEND_OFFSET,
547 .svc = EXYNOS_SVC_OFFSET,
548 .eint_gpio_init = exynos_eint_gpio_init,
549 .eint_wkup_init = exynos_eint_wkup_init,
550 .label = "exynos4210-gpio-ctrl1",
551 }, {
552 /* pin-controller instance 2 data */
553 .pin_banks = exynos4210_pin_banks2,
554 .nr_banks = ARRAY_SIZE(exynos4210_pin_banks2),
555 .base = EXYNOS4210_GPIOA_NR_PINS +
556 EXYNOS4210_GPIOB_NR_PINS,
557 .nr_pins = EXYNOS4210_GPIOC_NR_PINS,
558 .label = "exynos4210-gpio-ctrl2",
559 },
560};