1/* 2 * S3C24XX specific support for Samsung pinctrl/gpiolib driver. 3 * 4 * Copyright (c) 2013 Heiko Stuebner <heiko@sntech.de> 5 * 6 * This program is free software; you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License as published by 8 * the Free Software Foundation; either version 2 of the License, or 9 * (at your option) any later version. 10 * 11 * This file contains the SamsungS3C24XX specific information required by the 12 * Samsung pinctrl/gpiolib driver. It also includes the implementation of 13 * external gpio and wakeup interrupt support. 14 */ 15 16#include <linux/module.h> 17#include <linux/device.h> 18#include <linux/interrupt.h> 19#include <linux/irqdomain.h> 20#include <linux/irq.h> 21#include <linux/of_irq.h> 22#include <linux/irqchip/chained_irq.h> 23#include <linux/io.h> 24#include <linux/slab.h> 25#include <linux/err.h> 26 27#include "pinctrl-samsung.h" 28 29#define NUM_EINT 24 30#define NUM_EINT_IRQ 6 31#define EINT_MAX_PER_GROUP 8 32 33#define EINTPEND_REG 0xa8 34#define EINTMASK_REG 0xa4 35 36#define EINT_GROUP(i) ((int)((i) / EINT_MAX_PER_GROUP)) 37#define EINT_REG(i) ((EINT_GROUP(i) * 4) + 0x88) 38#define EINT_OFFS(i) ((i) % EINT_MAX_PER_GROUP * 4) 39 40#define EINT_LEVEL_LOW 0 41#define EINT_LEVEL_HIGH 1 42#define EINT_EDGE_FALLING 2 43#define EINT_EDGE_RISING 4 44#define EINT_EDGE_BOTH 6 45#define EINT_MASK 0xf 46 47static const struct samsung_pin_bank_type bank_type_1bit = { 48 .fld_width = { 1, 1, }, 49 .reg_offset = { 0x00, 0x04, }, 50}; 51 52static const struct samsung_pin_bank_type bank_type_2bit = { 53 .fld_width = { 2, 1, 2, }, 54 .reg_offset = { 0x00, 0x04, 0x08, }, 55}; 56 57#define PIN_BANK_A(pins, reg, id) \ 58 { \ 59 .type = &bank_type_1bit, \ 60 .pctl_offset = reg, \ 61 .nr_pins = pins, \ 62 .eint_type = EINT_TYPE_NONE, \ 63 .name = id \ 64 } 65 66#define PIN_BANK_2BIT(pins, reg, id) \ 67 { \ 68 .type = &bank_type_2bit, \ 69 .pctl_offset = reg, \ 70 .nr_pins = pins, \ 71 .eint_type = EINT_TYPE_NONE, \ 72 .name = id \ 73 } 74 75#define PIN_BANK_2BIT_EINTW(pins, reg, id, eoffs, emask)\ 76 { \ 77 .type = &bank_type_2bit, \ 78 .pctl_offset = reg, \ 79 .nr_pins = pins, \ 80 .eint_type = EINT_TYPE_WKUP, \ 81 .eint_func = 2, \ 82 .eint_mask = emask, \ 83 .eint_offset = eoffs, \ 84 .name = id \ 85 } 86 87/** 88 * struct s3c24xx_eint_data: EINT common data 89 * @drvdata: pin controller driver data 90 * @domains: IRQ domains of particular EINT interrupts 91 * @parents: mapped parent irqs in the main interrupt controller 92 */ 93struct s3c24xx_eint_data { 94 struct samsung_pinctrl_drv_data *drvdata; 95 struct irq_domain *domains[NUM_EINT]; 96 int parents[NUM_EINT_IRQ]; 97}; 98 99/** 100 * struct s3c24xx_eint_domain_data: per irq-domain data 101 * @bank: pin bank related to the domain 102 * @eint_data: common data 103 * eint0_3_parent_only: live eints 0-3 only in the main intc 104 */ 105struct s3c24xx_eint_domain_data { 106 struct samsung_pin_bank *bank; 107 struct s3c24xx_eint_data *eint_data; 108 bool eint0_3_parent_only; 109}; 110 111static int s3c24xx_eint_get_trigger(unsigned int type) 112{ 113 switch (type) { 114 case IRQ_TYPE_EDGE_RISING: 115 return EINT_EDGE_RISING; 116 break; 117 case IRQ_TYPE_EDGE_FALLING: 118 return EINT_EDGE_FALLING; 119 break; 120 case IRQ_TYPE_EDGE_BOTH: 121 return EINT_EDGE_BOTH; 122 break; 123 case IRQ_TYPE_LEVEL_HIGH: 124 return EINT_LEVEL_HIGH; 125 break; 126 case IRQ_TYPE_LEVEL_LOW: 127 return EINT_LEVEL_LOW; 128 break; 129 default: 130 return -EINVAL; 131 } 132} 133 134static void s3c24xx_eint_set_handler(unsigned int irq, unsigned int type) 135{ 136 /* Edge- and level-triggered interrupts need different handlers */ 137 if (type & IRQ_TYPE_EDGE_BOTH) 138 __irq_set_handler_locked(irq, handle_edge_irq); 139 else 140 __irq_set_handler_locked(irq, handle_level_irq); 141} 142 143static void s3c24xx_eint_set_function(struct samsung_pinctrl_drv_data *d, 144 struct samsung_pin_bank *bank, int pin) 145{ 146 const struct samsung_pin_bank_type *bank_type = bank->type; 147 unsigned long flags; 148 void __iomem *reg; 149 u8 shift; 150 u32 mask; 151 u32 val; 152 153 /* Make sure that pin is configured as interrupt */ 154 reg = d->virt_base + bank->pctl_offset; 155 shift = pin * bank_type->fld_width[PINCFG_TYPE_FUNC]; 156 mask = (1 << bank_type->fld_width[PINCFG_TYPE_FUNC]) - 1; 157 158 spin_lock_irqsave(&bank->slock, flags); 159 160 val = readl(reg); 161 val &= ~(mask << shift); 162 val |= bank->eint_func << shift; 163 writel(val, reg); 164 165 spin_unlock_irqrestore(&bank->slock, flags); 166} 167 168static int s3c24xx_eint_type(struct irq_data *data, unsigned int type) 169{ 170 struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(data); 171 struct samsung_pinctrl_drv_data *d = bank->drvdata; 172 int index = bank->eint_offset + data->hwirq; 173 void __iomem *reg; 174 int trigger; 175 u8 shift; 176 u32 val; 177 178 trigger = s3c24xx_eint_get_trigger(type); 179 if (trigger < 0) { 180 dev_err(d->dev, "unsupported external interrupt type\n"); 181 return -EINVAL; 182 } 183 184 s3c24xx_eint_set_handler(data->irq, type); 185 186 /* Set up interrupt trigger */ 187 reg = d->virt_base + EINT_REG(index); 188 shift = EINT_OFFS(index); 189 190 val = readl(reg); 191 val &= ~(EINT_MASK << shift); 192 val |= trigger << shift; 193 writel(val, reg); 194 195 s3c24xx_eint_set_function(d, bank, data->hwirq); 196 197 return 0; 198} 199 200/* Handling of EINTs 0-3 on all except S3C2412 and S3C2413 */ 201 202static void s3c2410_eint0_3_ack(struct irq_data *data) 203{ 204 struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(data); 205 struct s3c24xx_eint_domain_data *ddata = bank->irq_domain->host_data; 206 struct s3c24xx_eint_data *eint_data = ddata->eint_data; 207 int parent_irq = eint_data->parents[data->hwirq]; 208 struct irq_chip *parent_chip = irq_get_chip(parent_irq); 209 210 parent_chip->irq_ack(irq_get_irq_data(parent_irq)); 211} 212 213static void s3c2410_eint0_3_mask(struct irq_data *data) 214{ 215 struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(data); 216 struct s3c24xx_eint_domain_data *ddata = bank->irq_domain->host_data; 217 struct s3c24xx_eint_data *eint_data = ddata->eint_data; 218 int parent_irq = eint_data->parents[data->hwirq]; 219 struct irq_chip *parent_chip = irq_get_chip(parent_irq); 220 221 parent_chip->irq_mask(irq_get_irq_data(parent_irq)); 222} 223 224static void s3c2410_eint0_3_unmask(struct irq_data *data) 225{ 226 struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(data); 227 struct s3c24xx_eint_domain_data *ddata = bank->irq_domain->host_data; 228 struct s3c24xx_eint_data *eint_data = ddata->eint_data; 229 int parent_irq = eint_data->parents[data->hwirq]; 230 struct irq_chip *parent_chip = irq_get_chip(parent_irq); 231 232 parent_chip->irq_unmask(irq_get_irq_data(parent_irq)); 233} 234 235static struct irq_chip s3c2410_eint0_3_chip = { 236 .name = "s3c2410-eint0_3", 237 .irq_ack = s3c2410_eint0_3_ack, 238 .irq_mask = s3c2410_eint0_3_mask, 239 .irq_unmask = s3c2410_eint0_3_unmask, 240 .irq_set_type = s3c24xx_eint_type, 241}; 242 243static void s3c2410_demux_eint0_3(unsigned int irq, struct irq_desc *desc) 244{ 245 struct irq_data *data = irq_desc_get_irq_data(desc); 246 struct s3c24xx_eint_data *eint_data = irq_get_handler_data(irq); 247 unsigned int virq; 248 249 /* the first 4 eints have a simple 1 to 1 mapping */ 250 virq = irq_linear_revmap(eint_data->domains[data->hwirq], data->hwirq); 251 /* Something must be really wrong if an unmapped EINT is unmasked */ 252 BUG_ON(!virq); 253 254 generic_handle_irq(virq); 255} 256 257/* Handling of EINTs 0-3 on S3C2412 and S3C2413 */ 258 259static void s3c2412_eint0_3_ack(struct irq_data *data) 260{ 261 struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(data); 262 struct samsung_pinctrl_drv_data *d = bank->drvdata; 263 264 unsigned long bitval = 1UL << data->hwirq; 265 writel(bitval, d->virt_base + EINTPEND_REG); 266} 267 268static void s3c2412_eint0_3_mask(struct irq_data *data) 269{ 270 struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(data); 271 struct samsung_pinctrl_drv_data *d = bank->drvdata; 272 unsigned long mask; 273 274 mask = readl(d->virt_base + EINTMASK_REG); 275 mask |= (1UL << data->hwirq); 276 writel(mask, d->virt_base + EINTMASK_REG); 277} 278 279static void s3c2412_eint0_3_unmask(struct irq_data *data) 280{ 281 struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(data); 282 struct samsung_pinctrl_drv_data *d = bank->drvdata; 283 unsigned long mask; 284 285 mask = readl(d->virt_base + EINTMASK_REG); 286 mask &= ~(1UL << data->hwirq); 287 writel(mask, d->virt_base + EINTMASK_REG); 288} 289 290static struct irq_chip s3c2412_eint0_3_chip = { 291 .name = "s3c2412-eint0_3", 292 .irq_ack = s3c2412_eint0_3_ack, 293 .irq_mask = s3c2412_eint0_3_mask, 294 .irq_unmask = s3c2412_eint0_3_unmask, 295 .irq_set_type = s3c24xx_eint_type, 296}; 297 298static void s3c2412_demux_eint0_3(unsigned int irq, struct irq_desc *desc) 299{ 300 struct irq_chip *chip = irq_get_chip(irq); 301 struct irq_data *data = irq_desc_get_irq_data(desc); 302 struct s3c24xx_eint_data *eint_data = irq_get_handler_data(irq); 303 unsigned int virq; 304 305 chained_irq_enter(chip, desc); 306 307 /* the first 4 eints have a simple 1 to 1 mapping */ 308 virq = irq_linear_revmap(eint_data->domains[data->hwirq], data->hwirq); 309 /* Something must be really wrong if an unmapped EINT is unmasked */ 310 BUG_ON(!virq); 311 312 generic_handle_irq(virq); 313 314 chained_irq_exit(chip, desc); 315} 316 317/* Handling of all other eints */ 318 319static void s3c24xx_eint_ack(struct irq_data *data) 320{ 321 struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(data); 322 struct samsung_pinctrl_drv_data *d = bank->drvdata; 323 unsigned char index = bank->eint_offset + data->hwirq; 324 325 writel(1UL << index, d->virt_base + EINTPEND_REG); 326} 327 328static void s3c24xx_eint_mask(struct irq_data *data) 329{ 330 struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(data); 331 struct samsung_pinctrl_drv_data *d = bank->drvdata; 332 unsigned char index = bank->eint_offset + data->hwirq; 333 unsigned long mask; 334 335 mask = readl(d->virt_base + EINTMASK_REG); 336 mask |= (1UL << index); 337 writel(mask, d->virt_base + EINTMASK_REG); 338} 339 340static void s3c24xx_eint_unmask(struct irq_data *data) 341{ 342 struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(data); 343 struct samsung_pinctrl_drv_data *d = bank->drvdata; 344 unsigned char index = bank->eint_offset + data->hwirq; 345 unsigned long mask; 346 347 mask = readl(d->virt_base + EINTMASK_REG); 348 mask &= ~(1UL << index); 349 writel(mask, d->virt_base + EINTMASK_REG); 350} 351 352static struct irq_chip s3c24xx_eint_chip = { 353 .name = "s3c-eint", 354 .irq_ack = s3c24xx_eint_ack, 355 .irq_mask = s3c24xx_eint_mask, 356 .irq_unmask = s3c24xx_eint_unmask, 357 .irq_set_type = s3c24xx_eint_type, 358}; 359 360static inline void s3c24xx_demux_eint(unsigned int irq, struct irq_desc *desc, 361 u32 offset, u32 range) 362{ 363 struct irq_chip *chip = irq_get_chip(irq); 364 struct s3c24xx_eint_data *data = irq_get_handler_data(irq); 365 struct samsung_pinctrl_drv_data *d = data->drvdata; 366 unsigned int pend, mask; 367 368 chained_irq_enter(chip, desc); 369 370 pend = readl(d->virt_base + EINTPEND_REG); 371 mask = readl(d->virt_base + EINTMASK_REG); 372 373 pend &= ~mask; 374 pend &= range; 375 376 while (pend) { 377 unsigned int virq; 378 379 irq = __ffs(pend); 380 pend &= ~(1 << irq); 381 virq = irq_linear_revmap(data->domains[irq], irq - offset); 382 /* Something is really wrong if an unmapped EINT is unmasked */ 383 BUG_ON(!virq); 384 385 generic_handle_irq(virq); 386 } 387 388 chained_irq_exit(chip, desc); 389} 390 391static void s3c24xx_demux_eint4_7(unsigned int irq, struct irq_desc *desc) 392{ 393 s3c24xx_demux_eint(irq, desc, 0, 0xf0); 394} 395 396static void s3c24xx_demux_eint8_23(unsigned int irq, struct irq_desc *desc) 397{ 398 s3c24xx_demux_eint(irq, desc, 8, 0xffff00); 399} 400 401static irq_flow_handler_t s3c2410_eint_handlers[NUM_EINT_IRQ] = { 402 s3c2410_demux_eint0_3, 403 s3c2410_demux_eint0_3, 404 s3c2410_demux_eint0_3, 405 s3c2410_demux_eint0_3, 406 s3c24xx_demux_eint4_7, 407 s3c24xx_demux_eint8_23, 408}; 409 410static irq_flow_handler_t s3c2412_eint_handlers[NUM_EINT_IRQ] = { 411 s3c2412_demux_eint0_3, 412 s3c2412_demux_eint0_3, 413 s3c2412_demux_eint0_3, 414 s3c2412_demux_eint0_3, 415 s3c24xx_demux_eint4_7, 416 s3c24xx_demux_eint8_23, 417}; 418 419static int s3c24xx_gpf_irq_map(struct irq_domain *h, unsigned int virq, 420 irq_hw_number_t hw) 421{ 422 struct s3c24xx_eint_domain_data *ddata = h->host_data; 423 struct samsung_pin_bank *bank = ddata->bank; 424 425 if (!(bank->eint_mask & (1 << (bank->eint_offset + hw)))) 426 return -EINVAL; 427 428 if (hw <= 3) { 429 if (ddata->eint0_3_parent_only) 430 irq_set_chip_and_handler(virq, &s3c2410_eint0_3_chip, 431 handle_edge_irq); 432 else 433 irq_set_chip_and_handler(virq, &s3c2412_eint0_3_chip, 434 handle_edge_irq); 435 } else { 436 irq_set_chip_and_handler(virq, &s3c24xx_eint_chip, 437 handle_edge_irq); 438 } 439 irq_set_chip_data(virq, bank); 440 set_irq_flags(virq, IRQF_VALID); 441 return 0; 442} 443 444static const struct irq_domain_ops s3c24xx_gpf_irq_ops = { 445 .map = s3c24xx_gpf_irq_map, 446 .xlate = irq_domain_xlate_twocell, 447}; 448 449static int s3c24xx_gpg_irq_map(struct irq_domain *h, unsigned int virq, 450 irq_hw_number_t hw) 451{ 452 struct s3c24xx_eint_domain_data *ddata = h->host_data; 453 struct samsung_pin_bank *bank = ddata->bank; 454 455 if (!(bank->eint_mask & (1 << (bank->eint_offset + hw)))) 456 return -EINVAL; 457 458 irq_set_chip_and_handler(virq, &s3c24xx_eint_chip, handle_edge_irq); 459 irq_set_chip_data(virq, bank); 460 set_irq_flags(virq, IRQF_VALID); 461 return 0; 462} 463 464static const struct irq_domain_ops s3c24xx_gpg_irq_ops = { 465 .map = s3c24xx_gpg_irq_map, 466 .xlate = irq_domain_xlate_twocell, 467}; 468 469static const struct of_device_id s3c24xx_eint_irq_ids[] = { 470 { .compatible = "samsung,s3c2410-wakeup-eint", .data = (void *)1 }, 471 { .compatible = "samsung,s3c2412-wakeup-eint", .data = (void *)0 }, 472 { } 473}; 474 475static int s3c24xx_eint_init(struct samsung_pinctrl_drv_data *d) 476{ 477 struct device *dev = d->dev; 478 const struct of_device_id *match; 479 struct device_node *eint_np = NULL; 480 struct device_node *np; 481 struct samsung_pin_bank *bank; 482 struct s3c24xx_eint_data *eint_data; 483 const struct irq_domain_ops *ops; 484 unsigned int i; 485 bool eint0_3_parent_only; 486 irq_flow_handler_t *handlers; 487 488 for_each_child_of_node(dev->of_node, np) { 489 match = of_match_node(s3c24xx_eint_irq_ids, np); 490 if (match) { 491 eint_np = np; 492 eint0_3_parent_only = (bool)match->data; 493 break; 494 } 495 } 496 if (!eint_np) 497 return -ENODEV; 498 499 eint_data = devm_kzalloc(dev, sizeof(*eint_data), GFP_KERNEL); 500 if (!eint_data) 501 return -ENOMEM; 502 503 eint_data->drvdata = d; 504 505 handlers = eint0_3_parent_only ? s3c2410_eint_handlers 506 : s3c2412_eint_handlers; 507 for (i = 0; i < NUM_EINT_IRQ; ++i) { 508 unsigned int irq; 509 510 irq = irq_of_parse_and_map(eint_np, i); 511 if (!irq) { 512 dev_err(dev, "failed to get wakeup EINT IRQ %d\n", i); 513 return -ENXIO; 514 } 515 516 eint_data->parents[i] = irq; 517 irq_set_chained_handler(irq, handlers[i]); 518 irq_set_handler_data(irq, eint_data); 519 } 520 521 bank = d->pin_banks; 522 for (i = 0; i < d->nr_banks; ++i, ++bank) { 523 struct s3c24xx_eint_domain_data *ddata; 524 unsigned int mask; 525 unsigned int irq; 526 unsigned int pin; 527 528 if (bank->eint_type != EINT_TYPE_WKUP) 529 continue; 530 531 ddata = devm_kzalloc(dev, sizeof(*ddata), GFP_KERNEL); 532 if (!ddata) 533 return -ENOMEM; 534 535 ddata->bank = bank; 536 ddata->eint_data = eint_data; 537 ddata->eint0_3_parent_only = eint0_3_parent_only; 538 539 ops = (bank->eint_offset == 0) ? &s3c24xx_gpf_irq_ops 540 : &s3c24xx_gpg_irq_ops; 541 542 bank->irq_domain = irq_domain_add_linear(bank->of_node, 543 bank->nr_pins, ops, ddata); 544 if (!bank->irq_domain) { 545 dev_err(dev, "wkup irq domain add failed\n"); 546 return -ENXIO; 547 } 548 549 irq = bank->eint_offset; 550 mask = bank->eint_mask; 551 for (pin = 0; mask; ++pin, mask >>= 1) { 552 if (irq >= NUM_EINT) 553 break; 554 if (!(mask & 1)) 555 continue; 556 eint_data->domains[irq] = bank->irq_domain; 557 ++irq; 558 } 559 } 560 561 return 0; 562} 563 564static const struct samsung_pin_bank_data s3c2412_pin_banks[] __initconst = { 565 PIN_BANK_A(23, 0x000, "gpa"), 566 PIN_BANK_2BIT(11, 0x010, "gpb"), 567 PIN_BANK_2BIT(16, 0x020, "gpc"), 568 PIN_BANK_2BIT(16, 0x030, "gpd"), 569 PIN_BANK_2BIT(16, 0x040, "gpe"), 570 PIN_BANK_2BIT_EINTW(8, 0x050, "gpf", 0, 0xff), 571 PIN_BANK_2BIT_EINTW(16, 0x060, "gpg", 8, 0xffff00), 572 PIN_BANK_2BIT(11, 0x070, "gph"), 573 PIN_BANK_2BIT(13, 0x080, "gpj"), 574}; 575 576const struct samsung_pin_ctrl s3c2412_pin_ctrl[] __initconst = { 577 { 578 .pin_banks = s3c2412_pin_banks, 579 .nr_banks = ARRAY_SIZE(s3c2412_pin_banks), 580 .eint_wkup_init = s3c24xx_eint_init, 581 }, 582}; 583 584static const struct samsung_pin_bank_data s3c2416_pin_banks[] __initconst = { 585 PIN_BANK_A(27, 0x000, "gpa"), 586 PIN_BANK_2BIT(11, 0x010, "gpb"), 587 PIN_BANK_2BIT(16, 0x020, "gpc"), 588 PIN_BANK_2BIT(16, 0x030, "gpd"), 589 PIN_BANK_2BIT(16, 0x040, "gpe"), 590 PIN_BANK_2BIT_EINTW(8, 0x050, "gpf", 0, 0xff), 591 PIN_BANK_2BIT_EINTW(8, 0x060, "gpg", 8, 0xff00), 592 PIN_BANK_2BIT(15, 0x070, "gph"), 593 PIN_BANK_2BIT(16, 0x0e0, "gpk"), 594 PIN_BANK_2BIT(14, 0x0f0, "gpl"), 595 PIN_BANK_2BIT(2, 0x100, "gpm"), 596}; 597 598const struct samsung_pin_ctrl s3c2416_pin_ctrl[] __initconst = { 599 { 600 .pin_banks = s3c2416_pin_banks, 601 .nr_banks = ARRAY_SIZE(s3c2416_pin_banks), 602 .eint_wkup_init = s3c24xx_eint_init, 603 }, 604}; 605 606static const struct samsung_pin_bank_data s3c2440_pin_banks[] __initconst = { 607 PIN_BANK_A(25, 0x000, "gpa"), 608 PIN_BANK_2BIT(11, 0x010, "gpb"), 609 PIN_BANK_2BIT(16, 0x020, "gpc"), 610 PIN_BANK_2BIT(16, 0x030, "gpd"), 611 PIN_BANK_2BIT(16, 0x040, "gpe"), 612 PIN_BANK_2BIT_EINTW(8, 0x050, "gpf", 0, 0xff), 613 PIN_BANK_2BIT_EINTW(16, 0x060, "gpg", 8, 0xffff00), 614 PIN_BANK_2BIT(11, 0x070, "gph"), 615 PIN_BANK_2BIT(13, 0x0d0, "gpj"), 616}; 617 618const struct samsung_pin_ctrl s3c2440_pin_ctrl[] __initconst = { 619 { 620 .pin_banks = s3c2440_pin_banks, 621 .nr_banks = ARRAY_SIZE(s3c2440_pin_banks), 622 .eint_wkup_init = s3c24xx_eint_init, 623 }, 624}; 625 626static const struct samsung_pin_bank_data s3c2450_pin_banks[] __initconst = { 627 PIN_BANK_A(28, 0x000, "gpa"), 628 PIN_BANK_2BIT(11, 0x010, "gpb"), 629 PIN_BANK_2BIT(16, 0x020, "gpc"), 630 PIN_BANK_2BIT(16, 0x030, "gpd"), 631 PIN_BANK_2BIT(16, 0x040, "gpe"), 632 PIN_BANK_2BIT_EINTW(8, 0x050, "gpf", 0, 0xff), 633 PIN_BANK_2BIT_EINTW(16, 0x060, "gpg", 8, 0xffff00), 634 PIN_BANK_2BIT(15, 0x070, "gph"), 635 PIN_BANK_2BIT(16, 0x0d0, "gpj"), 636 PIN_BANK_2BIT(16, 0x0e0, "gpk"), 637 PIN_BANK_2BIT(15, 0x0f0, "gpl"), 638 PIN_BANK_2BIT(2, 0x100, "gpm"), 639}; 640 641const struct samsung_pin_ctrl s3c2450_pin_ctrl[] __initconst = { 642 { 643 .pin_banks = s3c2450_pin_banks, 644 .nr_banks = ARRAY_SIZE(s3c2450_pin_banks), 645 .eint_wkup_init = s3c24xx_eint_init, 646 }, 647}; 648