Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0+
0002 //
0003 // S3C24XX specific support for Samsung pinctrl/gpiolib driver.
0004 //
0005 // Copyright (c) 2013 Heiko Stuebner <heiko@sntech.de>
0006 //
0007 // This file contains the SamsungS3C24XX specific information required by the
0008 // Samsung pinctrl/gpiolib driver. It also includes the implementation of
0009 // external gpio and wakeup interrupt support.
0010 
0011 #include <linux/init.h>
0012 #include <linux/device.h>
0013 #include <linux/interrupt.h>
0014 #include <linux/irqdomain.h>
0015 #include <linux/irq.h>
0016 #include <linux/of_irq.h>
0017 #include <linux/irqchip/chained_irq.h>
0018 #include <linux/io.h>
0019 #include <linux/slab.h>
0020 #include <linux/err.h>
0021 
0022 #include "pinctrl-samsung.h"
0023 
0024 #define NUM_EINT    24
0025 #define NUM_EINT_IRQ    6
0026 #define EINT_MAX_PER_GROUP  8
0027 
0028 #define EINTPEND_REG    0xa8
0029 #define EINTMASK_REG    0xa4
0030 
0031 #define EINT_GROUP(i)       ((int)((i) / EINT_MAX_PER_GROUP))
0032 #define EINT_REG(i)     ((EINT_GROUP(i) * 4) + 0x88)
0033 #define EINT_OFFS(i)        ((i) % EINT_MAX_PER_GROUP * 4)
0034 
0035 #define EINT_LEVEL_LOW      0
0036 #define EINT_LEVEL_HIGH     1
0037 #define EINT_EDGE_FALLING   2
0038 #define EINT_EDGE_RISING    4
0039 #define EINT_EDGE_BOTH      6
0040 #define EINT_MASK       0xf
0041 
0042 static const struct samsung_pin_bank_type bank_type_1bit = {
0043     .fld_width = { 1, 1, },
0044     .reg_offset = { 0x00, 0x04, },
0045 };
0046 
0047 static const struct samsung_pin_bank_type bank_type_2bit = {
0048     .fld_width = { 2, 1, 2, },
0049     .reg_offset = { 0x00, 0x04, 0x08, },
0050 };
0051 
0052 #define PIN_BANK_A(pins, reg, id)       \
0053     {                       \
0054         .type       = &bank_type_1bit,  \
0055         .pctl_offset    = reg,          \
0056         .nr_pins    = pins,         \
0057         .eint_type  = EINT_TYPE_NONE,   \
0058         .name       = id            \
0059     }
0060 
0061 #define PIN_BANK_2BIT(pins, reg, id)        \
0062     {                       \
0063         .type       = &bank_type_2bit,  \
0064         .pctl_offset    = reg,          \
0065         .nr_pins    = pins,         \
0066         .eint_type  = EINT_TYPE_NONE,   \
0067         .name       = id            \
0068     }
0069 
0070 #define PIN_BANK_2BIT_EINTW(pins, reg, id, eoffs, emask)\
0071     {                       \
0072         .type       = &bank_type_2bit,  \
0073         .pctl_offset    = reg,          \
0074         .nr_pins    = pins,         \
0075         .eint_type  = EINT_TYPE_WKUP,   \
0076         .eint_func  = 2,            \
0077         .eint_mask  = emask,        \
0078         .eint_offset    = eoffs,        \
0079         .name       = id            \
0080     }
0081 
0082 /**
0083  * struct s3c24xx_eint_data - EINT common data
0084  * @drvdata: pin controller driver data
0085  * @domains: IRQ domains of particular EINT interrupts
0086  * @parents: mapped parent irqs in the main interrupt controller
0087  */
0088 struct s3c24xx_eint_data {
0089     struct samsung_pinctrl_drv_data *drvdata;
0090     struct irq_domain *domains[NUM_EINT];
0091     int parents[NUM_EINT_IRQ];
0092 };
0093 
0094 /**
0095  * struct s3c24xx_eint_domain_data - per irq-domain data
0096  * @bank: pin bank related to the domain
0097  * @eint_data: common data
0098  * @eint0_3_parent_only: live eints 0-3 only in the main intc
0099  */
0100 struct s3c24xx_eint_domain_data {
0101     struct samsung_pin_bank *bank;
0102     struct s3c24xx_eint_data *eint_data;
0103     bool eint0_3_parent_only;
0104 };
0105 
0106 static int s3c24xx_eint_get_trigger(unsigned int type)
0107 {
0108     switch (type) {
0109     case IRQ_TYPE_EDGE_RISING:
0110         return EINT_EDGE_RISING;
0111     case IRQ_TYPE_EDGE_FALLING:
0112         return EINT_EDGE_FALLING;
0113     case IRQ_TYPE_EDGE_BOTH:
0114         return EINT_EDGE_BOTH;
0115     case IRQ_TYPE_LEVEL_HIGH:
0116         return EINT_LEVEL_HIGH;
0117     case IRQ_TYPE_LEVEL_LOW:
0118         return EINT_LEVEL_LOW;
0119     default:
0120         return -EINVAL;
0121     }
0122 }
0123 
0124 static void s3c24xx_eint_set_handler(struct irq_data *d, unsigned int type)
0125 {
0126     /* Edge- and level-triggered interrupts need different handlers */
0127     if (type & IRQ_TYPE_EDGE_BOTH)
0128         irq_set_handler_locked(d, handle_edge_irq);
0129     else
0130         irq_set_handler_locked(d, handle_level_irq);
0131 }
0132 
0133 static void s3c24xx_eint_set_function(struct samsung_pinctrl_drv_data *d,
0134                     struct samsung_pin_bank *bank, int pin)
0135 {
0136     const struct samsung_pin_bank_type *bank_type = bank->type;
0137     unsigned long flags;
0138     void __iomem *reg;
0139     u8 shift;
0140     u32 mask;
0141     u32 val;
0142 
0143     /* Make sure that pin is configured as interrupt */
0144     reg = d->virt_base + bank->pctl_offset;
0145     shift = pin * bank_type->fld_width[PINCFG_TYPE_FUNC];
0146     mask = (1 << bank_type->fld_width[PINCFG_TYPE_FUNC]) - 1;
0147 
0148     raw_spin_lock_irqsave(&bank->slock, flags);
0149 
0150     val = readl(reg);
0151     val &= ~(mask << shift);
0152     val |= bank->eint_func << shift;
0153     writel(val, reg);
0154 
0155     raw_spin_unlock_irqrestore(&bank->slock, flags);
0156 }
0157 
0158 static int s3c24xx_eint_type(struct irq_data *data, unsigned int type)
0159 {
0160     struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(data);
0161     struct samsung_pinctrl_drv_data *d = bank->drvdata;
0162     int index = bank->eint_offset + data->hwirq;
0163     void __iomem *reg;
0164     int trigger;
0165     u8 shift;
0166     u32 val;
0167 
0168     trigger = s3c24xx_eint_get_trigger(type);
0169     if (trigger < 0) {
0170         dev_err(d->dev, "unsupported external interrupt type\n");
0171         return -EINVAL;
0172     }
0173 
0174     s3c24xx_eint_set_handler(data, type);
0175 
0176     /* Set up interrupt trigger */
0177     reg = d->virt_base + EINT_REG(index);
0178     shift = EINT_OFFS(index);
0179 
0180     val = readl(reg);
0181     val &= ~(EINT_MASK << shift);
0182     val |= trigger << shift;
0183     writel(val, reg);
0184 
0185     s3c24xx_eint_set_function(d, bank, data->hwirq);
0186 
0187     return 0;
0188 }
0189 
0190 /* Handling of EINTs 0-3 on all except S3C2412 and S3C2413 */
0191 
0192 static void s3c2410_eint0_3_ack(struct irq_data *data)
0193 {
0194     struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(data);
0195     struct s3c24xx_eint_domain_data *ddata = bank->irq_domain->host_data;
0196     struct s3c24xx_eint_data *eint_data = ddata->eint_data;
0197     int parent_irq = eint_data->parents[data->hwirq];
0198     struct irq_chip *parent_chip = irq_get_chip(parent_irq);
0199 
0200     parent_chip->irq_ack(irq_get_irq_data(parent_irq));
0201 }
0202 
0203 static void s3c2410_eint0_3_mask(struct irq_data *data)
0204 {
0205     struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(data);
0206     struct s3c24xx_eint_domain_data *ddata = bank->irq_domain->host_data;
0207     struct s3c24xx_eint_data *eint_data = ddata->eint_data;
0208     int parent_irq = eint_data->parents[data->hwirq];
0209     struct irq_chip *parent_chip = irq_get_chip(parent_irq);
0210 
0211     parent_chip->irq_mask(irq_get_irq_data(parent_irq));
0212 }
0213 
0214 static void s3c2410_eint0_3_unmask(struct irq_data *data)
0215 {
0216     struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(data);
0217     struct s3c24xx_eint_domain_data *ddata = bank->irq_domain->host_data;
0218     struct s3c24xx_eint_data *eint_data = ddata->eint_data;
0219     int parent_irq = eint_data->parents[data->hwirq];
0220     struct irq_chip *parent_chip = irq_get_chip(parent_irq);
0221 
0222     parent_chip->irq_unmask(irq_get_irq_data(parent_irq));
0223 }
0224 
0225 static struct irq_chip s3c2410_eint0_3_chip = {
0226     .name       = "s3c2410-eint0_3",
0227     .irq_ack    = s3c2410_eint0_3_ack,
0228     .irq_mask   = s3c2410_eint0_3_mask,
0229     .irq_unmask = s3c2410_eint0_3_unmask,
0230     .irq_set_type   = s3c24xx_eint_type,
0231 };
0232 
0233 static void s3c2410_demux_eint0_3(struct irq_desc *desc)
0234 {
0235     struct irq_data *data = irq_desc_get_irq_data(desc);
0236     struct s3c24xx_eint_data *eint_data = irq_desc_get_handler_data(desc);
0237     int ret;
0238 
0239     /* the first 4 eints have a simple 1 to 1 mapping */
0240     ret = generic_handle_domain_irq(eint_data->domains[data->hwirq], data->hwirq);
0241     /* Something must be really wrong if an unmapped EINT is unmasked */
0242     BUG_ON(ret);
0243 }
0244 
0245 /* Handling of EINTs 0-3 on S3C2412 and S3C2413 */
0246 
0247 static void s3c2412_eint0_3_ack(struct irq_data *data)
0248 {
0249     struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(data);
0250     struct samsung_pinctrl_drv_data *d = bank->drvdata;
0251 
0252     unsigned long bitval = 1UL << data->hwirq;
0253     writel(bitval, d->virt_base + EINTPEND_REG);
0254 }
0255 
0256 static void s3c2412_eint0_3_mask(struct irq_data *data)
0257 {
0258     struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(data);
0259     struct samsung_pinctrl_drv_data *d = bank->drvdata;
0260     unsigned long mask;
0261 
0262     mask = readl(d->virt_base + EINTMASK_REG);
0263     mask |= (1UL << data->hwirq);
0264     writel(mask, d->virt_base + EINTMASK_REG);
0265 }
0266 
0267 static void s3c2412_eint0_3_unmask(struct irq_data *data)
0268 {
0269     struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(data);
0270     struct samsung_pinctrl_drv_data *d = bank->drvdata;
0271     unsigned long mask;
0272 
0273     mask = readl(d->virt_base + EINTMASK_REG);
0274     mask &= ~(1UL << data->hwirq);
0275     writel(mask, d->virt_base + EINTMASK_REG);
0276 }
0277 
0278 static struct irq_chip s3c2412_eint0_3_chip = {
0279     .name       = "s3c2412-eint0_3",
0280     .irq_ack    = s3c2412_eint0_3_ack,
0281     .irq_mask   = s3c2412_eint0_3_mask,
0282     .irq_unmask = s3c2412_eint0_3_unmask,
0283     .irq_set_type   = s3c24xx_eint_type,
0284 };
0285 
0286 static void s3c2412_demux_eint0_3(struct irq_desc *desc)
0287 {
0288     struct s3c24xx_eint_data *eint_data = irq_desc_get_handler_data(desc);
0289     struct irq_data *data = irq_desc_get_irq_data(desc);
0290     struct irq_chip *chip = irq_data_get_irq_chip(data);
0291     int ret;
0292 
0293     chained_irq_enter(chip, desc);
0294 
0295     /* the first 4 eints have a simple 1 to 1 mapping */
0296     ret = generic_handle_domain_irq(eint_data->domains[data->hwirq], data->hwirq);
0297     /* Something must be really wrong if an unmapped EINT is unmasked */
0298     BUG_ON(ret);
0299 
0300     chained_irq_exit(chip, desc);
0301 }
0302 
0303 /* Handling of all other eints */
0304 
0305 static void s3c24xx_eint_ack(struct irq_data *data)
0306 {
0307     struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(data);
0308     struct samsung_pinctrl_drv_data *d = bank->drvdata;
0309     unsigned char index = bank->eint_offset + data->hwirq;
0310 
0311     writel(1UL << index, d->virt_base + EINTPEND_REG);
0312 }
0313 
0314 static void s3c24xx_eint_mask(struct irq_data *data)
0315 {
0316     struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(data);
0317     struct samsung_pinctrl_drv_data *d = bank->drvdata;
0318     unsigned char index = bank->eint_offset + data->hwirq;
0319     unsigned long mask;
0320 
0321     mask = readl(d->virt_base + EINTMASK_REG);
0322     mask |= (1UL << index);
0323     writel(mask, d->virt_base + EINTMASK_REG);
0324 }
0325 
0326 static void s3c24xx_eint_unmask(struct irq_data *data)
0327 {
0328     struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(data);
0329     struct samsung_pinctrl_drv_data *d = bank->drvdata;
0330     unsigned char index = bank->eint_offset + data->hwirq;
0331     unsigned long mask;
0332 
0333     mask = readl(d->virt_base + EINTMASK_REG);
0334     mask &= ~(1UL << index);
0335     writel(mask, d->virt_base + EINTMASK_REG);
0336 }
0337 
0338 static struct irq_chip s3c24xx_eint_chip = {
0339     .name       = "s3c-eint",
0340     .irq_ack    = s3c24xx_eint_ack,
0341     .irq_mask   = s3c24xx_eint_mask,
0342     .irq_unmask = s3c24xx_eint_unmask,
0343     .irq_set_type   = s3c24xx_eint_type,
0344 };
0345 
0346 static inline void s3c24xx_demux_eint(struct irq_desc *desc,
0347                       u32 offset, u32 range)
0348 {
0349     struct s3c24xx_eint_data *data = irq_desc_get_handler_data(desc);
0350     struct irq_chip *chip = irq_desc_get_chip(desc);
0351     struct samsung_pinctrl_drv_data *d = data->drvdata;
0352     unsigned int pend, mask;
0353 
0354     chained_irq_enter(chip, desc);
0355 
0356     pend = readl(d->virt_base + EINTPEND_REG);
0357     mask = readl(d->virt_base + EINTMASK_REG);
0358 
0359     pend &= ~mask;
0360     pend &= range;
0361 
0362     while (pend) {
0363         unsigned int irq;
0364         int ret;
0365 
0366         irq = __ffs(pend);
0367         pend &= ~(1 << irq);
0368         ret = generic_handle_domain_irq(data->domains[irq], irq - offset);
0369         /* Something is really wrong if an unmapped EINT is unmasked */
0370         BUG_ON(ret);
0371     }
0372 
0373     chained_irq_exit(chip, desc);
0374 }
0375 
0376 static void s3c24xx_demux_eint4_7(struct irq_desc *desc)
0377 {
0378     s3c24xx_demux_eint(desc, 0, 0xf0);
0379 }
0380 
0381 static void s3c24xx_demux_eint8_23(struct irq_desc *desc)
0382 {
0383     s3c24xx_demux_eint(desc, 8, 0xffff00);
0384 }
0385 
0386 static irq_flow_handler_t s3c2410_eint_handlers[NUM_EINT_IRQ] = {
0387     s3c2410_demux_eint0_3,
0388     s3c2410_demux_eint0_3,
0389     s3c2410_demux_eint0_3,
0390     s3c2410_demux_eint0_3,
0391     s3c24xx_demux_eint4_7,
0392     s3c24xx_demux_eint8_23,
0393 };
0394 
0395 static irq_flow_handler_t s3c2412_eint_handlers[NUM_EINT_IRQ] = {
0396     s3c2412_demux_eint0_3,
0397     s3c2412_demux_eint0_3,
0398     s3c2412_demux_eint0_3,
0399     s3c2412_demux_eint0_3,
0400     s3c24xx_demux_eint4_7,
0401     s3c24xx_demux_eint8_23,
0402 };
0403 
0404 static int s3c24xx_gpf_irq_map(struct irq_domain *h, unsigned int virq,
0405                     irq_hw_number_t hw)
0406 {
0407     struct s3c24xx_eint_domain_data *ddata = h->host_data;
0408     struct samsung_pin_bank *bank = ddata->bank;
0409 
0410     if (!(bank->eint_mask & (1 << (bank->eint_offset + hw))))
0411         return -EINVAL;
0412 
0413     if (hw <= 3) {
0414         if (ddata->eint0_3_parent_only)
0415             irq_set_chip_and_handler(virq, &s3c2410_eint0_3_chip,
0416                          handle_edge_irq);
0417         else
0418             irq_set_chip_and_handler(virq, &s3c2412_eint0_3_chip,
0419                          handle_edge_irq);
0420     } else {
0421         irq_set_chip_and_handler(virq, &s3c24xx_eint_chip,
0422                      handle_edge_irq);
0423     }
0424     irq_set_chip_data(virq, bank);
0425     return 0;
0426 }
0427 
0428 static const struct irq_domain_ops s3c24xx_gpf_irq_ops = {
0429     .map    = s3c24xx_gpf_irq_map,
0430     .xlate  = irq_domain_xlate_twocell,
0431 };
0432 
0433 static int s3c24xx_gpg_irq_map(struct irq_domain *h, unsigned int virq,
0434                     irq_hw_number_t hw)
0435 {
0436     struct s3c24xx_eint_domain_data *ddata = h->host_data;
0437     struct samsung_pin_bank *bank = ddata->bank;
0438 
0439     if (!(bank->eint_mask & (1 << (bank->eint_offset + hw))))
0440         return -EINVAL;
0441 
0442     irq_set_chip_and_handler(virq, &s3c24xx_eint_chip, handle_edge_irq);
0443     irq_set_chip_data(virq, bank);
0444     return 0;
0445 }
0446 
0447 static const struct irq_domain_ops s3c24xx_gpg_irq_ops = {
0448     .map    = s3c24xx_gpg_irq_map,
0449     .xlate  = irq_domain_xlate_twocell,
0450 };
0451 
0452 static const struct of_device_id s3c24xx_eint_irq_ids[] = {
0453     { .compatible = "samsung,s3c2410-wakeup-eint", .data = (void *)1 },
0454     { .compatible = "samsung,s3c2412-wakeup-eint", .data = (void *)0 },
0455     { }
0456 };
0457 
0458 static int s3c24xx_eint_init(struct samsung_pinctrl_drv_data *d)
0459 {
0460     struct device *dev = d->dev;
0461     const struct of_device_id *match;
0462     struct device_node *eint_np = NULL;
0463     struct device_node *np;
0464     struct samsung_pin_bank *bank;
0465     struct s3c24xx_eint_data *eint_data;
0466     const struct irq_domain_ops *ops;
0467     unsigned int i;
0468     bool eint0_3_parent_only;
0469     irq_flow_handler_t *handlers;
0470 
0471     for_each_child_of_node(dev->of_node, np) {
0472         match = of_match_node(s3c24xx_eint_irq_ids, np);
0473         if (match) {
0474             eint_np = np;
0475             eint0_3_parent_only = (bool)match->data;
0476             break;
0477         }
0478     }
0479     if (!eint_np)
0480         return -ENODEV;
0481 
0482     eint_data = devm_kzalloc(dev, sizeof(*eint_data), GFP_KERNEL);
0483     if (!eint_data) {
0484         of_node_put(eint_np);
0485         return -ENOMEM;
0486     }
0487 
0488     eint_data->drvdata = d;
0489 
0490     handlers = eint0_3_parent_only ? s3c2410_eint_handlers
0491                        : s3c2412_eint_handlers;
0492     for (i = 0; i < NUM_EINT_IRQ; ++i) {
0493         unsigned int irq;
0494 
0495         irq = irq_of_parse_and_map(eint_np, i);
0496         if (!irq) {
0497             dev_err(dev, "failed to get wakeup EINT IRQ %d\n", i);
0498             of_node_put(eint_np);
0499             return -ENXIO;
0500         }
0501 
0502         eint_data->parents[i] = irq;
0503         irq_set_chained_handler_and_data(irq, handlers[i], eint_data);
0504     }
0505     of_node_put(eint_np);
0506 
0507     bank = d->pin_banks;
0508     for (i = 0; i < d->nr_banks; ++i, ++bank) {
0509         struct s3c24xx_eint_domain_data *ddata;
0510         unsigned int mask;
0511         unsigned int irq;
0512         unsigned int pin;
0513 
0514         if (bank->eint_type != EINT_TYPE_WKUP)
0515             continue;
0516 
0517         ddata = devm_kzalloc(dev, sizeof(*ddata), GFP_KERNEL);
0518         if (!ddata)
0519             return -ENOMEM;
0520 
0521         ddata->bank = bank;
0522         ddata->eint_data = eint_data;
0523         ddata->eint0_3_parent_only = eint0_3_parent_only;
0524 
0525         ops = (bank->eint_offset == 0) ? &s3c24xx_gpf_irq_ops
0526                            : &s3c24xx_gpg_irq_ops;
0527 
0528         bank->irq_domain = irq_domain_create_linear(bank->fwnode,
0529                 bank->nr_pins, ops, ddata);
0530         if (!bank->irq_domain) {
0531             dev_err(dev, "wkup irq domain add failed\n");
0532             return -ENXIO;
0533         }
0534 
0535         irq = bank->eint_offset;
0536         mask = bank->eint_mask;
0537         for (pin = 0; mask; ++pin, mask >>= 1) {
0538             if (irq >= NUM_EINT)
0539                 break;
0540             if (!(mask & 1))
0541                 continue;
0542             eint_data->domains[irq] = bank->irq_domain;
0543             ++irq;
0544         }
0545     }
0546 
0547     return 0;
0548 }
0549 
0550 static const struct samsung_pin_bank_data s3c2412_pin_banks[] __initconst = {
0551     PIN_BANK_A(23, 0x000, "gpa"),
0552     PIN_BANK_2BIT(11, 0x010, "gpb"),
0553     PIN_BANK_2BIT(16, 0x020, "gpc"),
0554     PIN_BANK_2BIT(16, 0x030, "gpd"),
0555     PIN_BANK_2BIT(16, 0x040, "gpe"),
0556     PIN_BANK_2BIT_EINTW(8, 0x050, "gpf", 0, 0xff),
0557     PIN_BANK_2BIT_EINTW(16, 0x060, "gpg", 8, 0xffff00),
0558     PIN_BANK_2BIT(11, 0x070, "gph"),
0559     PIN_BANK_2BIT(13, 0x080, "gpj"),
0560 };
0561 
0562 static const struct samsung_pin_ctrl s3c2412_pin_ctrl[] __initconst = {
0563     {
0564         .pin_banks  = s3c2412_pin_banks,
0565         .nr_banks   = ARRAY_SIZE(s3c2412_pin_banks),
0566         .eint_wkup_init = s3c24xx_eint_init,
0567     },
0568 };
0569 
0570 const struct samsung_pinctrl_of_match_data s3c2412_of_data __initconst = {
0571     .ctrl       = s3c2412_pin_ctrl,
0572     .num_ctrl   = ARRAY_SIZE(s3c2412_pin_ctrl),
0573 };
0574 
0575 static const struct samsung_pin_bank_data s3c2416_pin_banks[] __initconst = {
0576     PIN_BANK_A(27, 0x000, "gpa"),
0577     PIN_BANK_2BIT(11, 0x010, "gpb"),
0578     PIN_BANK_2BIT(16, 0x020, "gpc"),
0579     PIN_BANK_2BIT(16, 0x030, "gpd"),
0580     PIN_BANK_2BIT(16, 0x040, "gpe"),
0581     PIN_BANK_2BIT_EINTW(8, 0x050, "gpf", 0, 0xff),
0582     PIN_BANK_2BIT_EINTW(8, 0x060, "gpg", 8, 0xff00),
0583     PIN_BANK_2BIT(15, 0x070, "gph"),
0584     PIN_BANK_2BIT(16, 0x0e0, "gpk"),
0585     PIN_BANK_2BIT(14, 0x0f0, "gpl"),
0586     PIN_BANK_2BIT(2, 0x100, "gpm"),
0587 };
0588 
0589 static const struct samsung_pin_ctrl s3c2416_pin_ctrl[] __initconst = {
0590     {
0591         .pin_banks  = s3c2416_pin_banks,
0592         .nr_banks   = ARRAY_SIZE(s3c2416_pin_banks),
0593         .eint_wkup_init = s3c24xx_eint_init,
0594     },
0595 };
0596 
0597 const struct samsung_pinctrl_of_match_data s3c2416_of_data __initconst = {
0598     .ctrl       = s3c2416_pin_ctrl,
0599     .num_ctrl   = ARRAY_SIZE(s3c2416_pin_ctrl),
0600 };
0601 
0602 static const struct samsung_pin_bank_data s3c2440_pin_banks[] __initconst = {
0603     PIN_BANK_A(25, 0x000, "gpa"),
0604     PIN_BANK_2BIT(11, 0x010, "gpb"),
0605     PIN_BANK_2BIT(16, 0x020, "gpc"),
0606     PIN_BANK_2BIT(16, 0x030, "gpd"),
0607     PIN_BANK_2BIT(16, 0x040, "gpe"),
0608     PIN_BANK_2BIT_EINTW(8, 0x050, "gpf", 0, 0xff),
0609     PIN_BANK_2BIT_EINTW(16, 0x060, "gpg", 8, 0xffff00),
0610     PIN_BANK_2BIT(11, 0x070, "gph"),
0611     PIN_BANK_2BIT(13, 0x0d0, "gpj"),
0612 };
0613 
0614 static const struct samsung_pin_ctrl s3c2440_pin_ctrl[] __initconst = {
0615     {
0616         .pin_banks  = s3c2440_pin_banks,
0617         .nr_banks   = ARRAY_SIZE(s3c2440_pin_banks),
0618         .eint_wkup_init = s3c24xx_eint_init,
0619     },
0620 };
0621 
0622 const struct samsung_pinctrl_of_match_data s3c2440_of_data __initconst = {
0623     .ctrl       = s3c2440_pin_ctrl,
0624     .num_ctrl   = ARRAY_SIZE(s3c2440_pin_ctrl),
0625 };
0626 
0627 static const struct samsung_pin_bank_data s3c2450_pin_banks[] __initconst = {
0628     PIN_BANK_A(28, 0x000, "gpa"),
0629     PIN_BANK_2BIT(11, 0x010, "gpb"),
0630     PIN_BANK_2BIT(16, 0x020, "gpc"),
0631     PIN_BANK_2BIT(16, 0x030, "gpd"),
0632     PIN_BANK_2BIT(16, 0x040, "gpe"),
0633     PIN_BANK_2BIT_EINTW(8, 0x050, "gpf", 0, 0xff),
0634     PIN_BANK_2BIT_EINTW(16, 0x060, "gpg", 8, 0xffff00),
0635     PIN_BANK_2BIT(15, 0x070, "gph"),
0636     PIN_BANK_2BIT(16, 0x0d0, "gpj"),
0637     PIN_BANK_2BIT(16, 0x0e0, "gpk"),
0638     PIN_BANK_2BIT(15, 0x0f0, "gpl"),
0639     PIN_BANK_2BIT(2, 0x100, "gpm"),
0640 };
0641 
0642 static const struct samsung_pin_ctrl s3c2450_pin_ctrl[] __initconst = {
0643     {
0644         .pin_banks  = s3c2450_pin_banks,
0645         .nr_banks   = ARRAY_SIZE(s3c2450_pin_banks),
0646         .eint_wkup_init = s3c24xx_eint_init,
0647     },
0648 };
0649 
0650 const struct samsung_pinctrl_of_match_data s3c2450_of_data __initconst = {
0651     .ctrl       = s3c2450_pin_ctrl,
0652     .num_ctrl   = ARRAY_SIZE(s3c2450_pin_ctrl),
0653 };