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