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