linux/drivers/pinctrl/samsung/pinctrl-s3c64xx.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0+
   2//
   3// S3C64xx specific support for pinctrl-samsung driver.
   4//
   5// Copyright (c) 2013 Tomasz Figa <tomasz.figa@gmail.com>
   6//
   7// Based on pinctrl-exynos.c, please see the file for original copyrights.
   8//
   9// This file contains the Samsung S3C64xx specific information required by the
  10// the Samsung pinctrl/gpiolib driver. It also includes the implementation of
  11// external gpio and wakeup interrupt support.
  12
  13#include <linux/init.h>
  14#include <linux/device.h>
  15#include <linux/interrupt.h>
  16#include <linux/irqdomain.h>
  17#include <linux/irq.h>
  18#include <linux/of_irq.h>
  19#include <linux/io.h>
  20#include <linux/irqchip/chained_irq.h>
  21#include <linux/slab.h>
  22#include <linux/err.h>
  23
  24#include "pinctrl-samsung.h"
  25
  26#define NUM_EINT0               28
  27#define NUM_EINT0_IRQ           4
  28#define EINT_MAX_PER_REG        16
  29#define EINT_MAX_PER_GROUP      16
  30
  31/* External GPIO and wakeup interrupt related definitions */
  32#define SVC_GROUP_SHIFT         4
  33#define SVC_GROUP_MASK          0xf
  34#define SVC_NUM_MASK            0xf
  35#define SVC_GROUP(x)            ((x >> SVC_GROUP_SHIFT) & \
  36                                                SVC_GROUP_MASK)
  37
  38#define EINT12CON_REG           0x200
  39#define EINT12MASK_REG          0x240
  40#define EINT12PEND_REG          0x260
  41
  42#define EINT_OFFS(i)            ((i) % (2 * EINT_MAX_PER_GROUP))
  43#define EINT_GROUP(i)           ((i) / EINT_MAX_PER_GROUP)
  44#define EINT_REG(g)             (4 * ((g) / 2))
  45
  46#define EINTCON_REG(i)          (EINT12CON_REG + EINT_REG(EINT_GROUP(i)))
  47#define EINTMASK_REG(i)         (EINT12MASK_REG + EINT_REG(EINT_GROUP(i)))
  48#define EINTPEND_REG(i)         (EINT12PEND_REG + EINT_REG(EINT_GROUP(i)))
  49
  50#define SERVICE_REG             0x284
  51#define SERVICEPEND_REG         0x288
  52
  53#define EINT0CON0_REG           0x900
  54#define EINT0MASK_REG           0x920
  55#define EINT0PEND_REG           0x924
  56
  57/* S3C64xx specific external interrupt trigger types */
  58#define EINT_LEVEL_LOW          0
  59#define EINT_LEVEL_HIGH         1
  60#define EINT_EDGE_FALLING       2
  61#define EINT_EDGE_RISING        4
  62#define EINT_EDGE_BOTH          6
  63#define EINT_CON_MASK           0xF
  64#define EINT_CON_LEN            4
  65
  66static const struct samsung_pin_bank_type bank_type_4bit_off = {
  67        .fld_width = { 4, 1, 2, 0, 2, 2, },
  68        .reg_offset = { 0x00, 0x04, 0x08, 0, 0x0c, 0x10, },
  69};
  70
  71static const struct samsung_pin_bank_type bank_type_4bit_alive = {
  72        .fld_width = { 4, 1, 2, },
  73        .reg_offset = { 0x00, 0x04, 0x08, },
  74};
  75
  76static const struct samsung_pin_bank_type bank_type_4bit2_off = {
  77        .fld_width = { 4, 1, 2, 0, 2, 2, },
  78        .reg_offset = { 0x00, 0x08, 0x0c, 0, 0x10, 0x14, },
  79};
  80
  81static const struct samsung_pin_bank_type bank_type_4bit2_alive = {
  82        .fld_width = { 4, 1, 2, },
  83        .reg_offset = { 0x00, 0x08, 0x0c, },
  84};
  85
  86static const struct samsung_pin_bank_type bank_type_2bit_off = {
  87        .fld_width = { 2, 1, 2, 0, 2, 2, },
  88        .reg_offset = { 0x00, 0x04, 0x08, 0, 0x0c, 0x10, },
  89};
  90
  91static const struct samsung_pin_bank_type bank_type_2bit_alive = {
  92        .fld_width = { 2, 1, 2, },
  93        .reg_offset = { 0x00, 0x04, 0x08, },
  94};
  95
  96#define PIN_BANK_4BIT(pins, reg, id)                    \
  97        {                                               \
  98                .type           = &bank_type_4bit_off,  \
  99                .pctl_offset    = reg,                  \
 100                .nr_pins        = pins,                 \
 101                .eint_type      = EINT_TYPE_NONE,       \
 102                .name           = id                    \
 103        }
 104
 105#define PIN_BANK_4BIT_EINTG(pins, reg, id, eoffs)       \
 106        {                                               \
 107                .type           = &bank_type_4bit_off,  \
 108                .pctl_offset    = reg,                  \
 109                .nr_pins        = pins,                 \
 110                .eint_type      = EINT_TYPE_GPIO,       \
 111                .eint_func      = 7,                    \
 112                .eint_mask      = (1 << (pins)) - 1,    \
 113                .eint_offset    = eoffs,                \
 114                .name           = id                    \
 115        }
 116
 117#define PIN_BANK_4BIT_EINTW(pins, reg, id, eoffs, emask) \
 118        {                                               \
 119                .type           = &bank_type_4bit_alive,\
 120                .pctl_offset    = reg,                  \
 121                .nr_pins        = pins,                 \
 122                .eint_type      = EINT_TYPE_WKUP,       \
 123                .eint_func      = 3,                    \
 124                .eint_mask      = emask,                \
 125                .eint_offset    = eoffs,                \
 126                .name           = id                    \
 127        }
 128
 129#define PIN_BANK_4BIT2_EINTG(pins, reg, id, eoffs)      \
 130        {                                               \
 131                .type           = &bank_type_4bit2_off, \
 132                .pctl_offset    = reg,                  \
 133                .nr_pins        = pins,                 \
 134                .eint_type      = EINT_TYPE_GPIO,       \
 135                .eint_func      = 7,                    \
 136                .eint_mask      = (1 << (pins)) - 1,    \
 137                .eint_offset    = eoffs,                \
 138                .name           = id                    \
 139        }
 140
 141#define PIN_BANK_4BIT2_EINTW(pins, reg, id, eoffs, emask) \
 142        {                                               \
 143                .type           = &bank_type_4bit2_alive,\
 144                .pctl_offset    = reg,                  \
 145                .nr_pins        = pins,                 \
 146                .eint_type      = EINT_TYPE_WKUP,       \
 147                .eint_func      = 3,                    \
 148                .eint_mask      = emask,                \
 149                .eint_offset    = eoffs,                \
 150                .name           = id                    \
 151        }
 152
 153#define PIN_BANK_4BIT2_ALIVE(pins, reg, id)             \
 154        {                                               \
 155                .type           = &bank_type_4bit2_alive,\
 156                .pctl_offset    = reg,                  \
 157                .nr_pins        = pins,                 \
 158                .eint_type      = EINT_TYPE_NONE,       \
 159                .name           = id                    \
 160        }
 161
 162#define PIN_BANK_2BIT(pins, reg, id)                    \
 163        {                                               \
 164                .type           = &bank_type_2bit_off,  \
 165                .pctl_offset    = reg,                  \
 166                .nr_pins        = pins,                 \
 167                .eint_type      = EINT_TYPE_NONE,       \
 168                .name           = id                    \
 169        }
 170
 171#define PIN_BANK_2BIT_EINTG(pins, reg, id, eoffs, emask) \
 172        {                                               \
 173                .type           = &bank_type_2bit_off,  \
 174                .pctl_offset    = reg,                  \
 175                .nr_pins        = pins,                 \
 176                .eint_type      = EINT_TYPE_GPIO,       \
 177                .eint_func      = 3,                    \
 178                .eint_mask      = emask,                \
 179                .eint_offset    = eoffs,                \
 180                .name           = id                    \
 181        }
 182
 183#define PIN_BANK_2BIT_EINTW(pins, reg, id, eoffs)       \
 184        {                                               \
 185                .type           = &bank_type_2bit_alive,\
 186                .pctl_offset    = reg,                  \
 187                .nr_pins        = pins,                 \
 188                .eint_type      = EINT_TYPE_WKUP,       \
 189                .eint_func      = 2,                    \
 190                .eint_mask      = (1 << (pins)) - 1,    \
 191                .eint_offset    = eoffs,                \
 192                .name           = id                    \
 193        }
 194
 195/**
 196 * struct s3c64xx_eint0_data - EINT0 common data
 197 * @drvdata: pin controller driver data
 198 * @domains: IRQ domains of particular EINT0 interrupts
 199 * @pins: pin offsets inside of banks of particular EINT0 interrupts
 200 */
 201struct s3c64xx_eint0_data {
 202        struct samsung_pinctrl_drv_data *drvdata;
 203        struct irq_domain *domains[NUM_EINT0];
 204        u8 pins[NUM_EINT0];
 205};
 206
 207/**
 208 * struct s3c64xx_eint0_domain_data - EINT0 per-domain data
 209 * @bank: pin bank related to the domain
 210 * @eints: EINT0 interrupts related to the domain
 211 */
 212struct s3c64xx_eint0_domain_data {
 213        struct samsung_pin_bank *bank;
 214        u8 eints[];
 215};
 216
 217/**
 218 * struct s3c64xx_eint_gpio_data - GPIO EINT data
 219 * @drvdata: pin controller driver data
 220 * @domains: array of domains related to EINT interrupt groups
 221 */
 222struct s3c64xx_eint_gpio_data {
 223        struct samsung_pinctrl_drv_data *drvdata;
 224        struct irq_domain *domains[];
 225};
 226
 227/*
 228 * Common functions for S3C64xx EINT configuration
 229 */
 230
 231static int s3c64xx_irq_get_trigger(unsigned int type)
 232{
 233        int trigger;
 234
 235        switch (type) {
 236        case IRQ_TYPE_EDGE_RISING:
 237                trigger = EINT_EDGE_RISING;
 238                break;
 239        case IRQ_TYPE_EDGE_FALLING:
 240                trigger = EINT_EDGE_FALLING;
 241                break;
 242        case IRQ_TYPE_EDGE_BOTH:
 243                trigger = EINT_EDGE_BOTH;
 244                break;
 245        case IRQ_TYPE_LEVEL_HIGH:
 246                trigger = EINT_LEVEL_HIGH;
 247                break;
 248        case IRQ_TYPE_LEVEL_LOW:
 249                trigger = EINT_LEVEL_LOW;
 250                break;
 251        default:
 252                return -EINVAL;
 253        }
 254
 255        return trigger;
 256}
 257
 258static void s3c64xx_irq_set_handler(struct irq_data *d, unsigned int type)
 259{
 260        /* Edge- and level-triggered interrupts need different handlers */
 261        if (type & IRQ_TYPE_EDGE_BOTH)
 262                irq_set_handler_locked(d, handle_edge_irq);
 263        else
 264                irq_set_handler_locked(d, handle_level_irq);
 265}
 266
 267static void s3c64xx_irq_set_function(struct samsung_pinctrl_drv_data *d,
 268                                        struct samsung_pin_bank *bank, int pin)
 269{
 270        const struct samsung_pin_bank_type *bank_type = bank->type;
 271        unsigned long flags;
 272        void __iomem *reg;
 273        u8 shift;
 274        u32 mask;
 275        u32 val;
 276
 277        /* Make sure that pin is configured as interrupt */
 278        reg = d->virt_base + bank->pctl_offset;
 279        shift = pin;
 280        if (bank_type->fld_width[PINCFG_TYPE_FUNC] * shift >= 32) {
 281                /* 4-bit bank type with 2 con regs */
 282                reg += 4;
 283                shift -= 8;
 284        }
 285
 286        shift = shift * bank_type->fld_width[PINCFG_TYPE_FUNC];
 287        mask = (1 << bank_type->fld_width[PINCFG_TYPE_FUNC]) - 1;
 288
 289        raw_spin_lock_irqsave(&bank->slock, flags);
 290
 291        val = readl(reg);
 292        val &= ~(mask << shift);
 293        val |= bank->eint_func << shift;
 294        writel(val, reg);
 295
 296        raw_spin_unlock_irqrestore(&bank->slock, flags);
 297}
 298
 299/*
 300 * Functions for EINT GPIO configuration (EINT groups 1-9)
 301 */
 302
 303static inline void s3c64xx_gpio_irq_set_mask(struct irq_data *irqd, bool mask)
 304{
 305        struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(irqd);
 306        struct samsung_pinctrl_drv_data *d = bank->drvdata;
 307        unsigned char index = EINT_OFFS(bank->eint_offset) + irqd->hwirq;
 308        void __iomem *reg = d->virt_base + EINTMASK_REG(bank->eint_offset);
 309        u32 val;
 310
 311        val = readl(reg);
 312        if (mask)
 313                val |= 1 << index;
 314        else
 315                val &= ~(1 << index);
 316        writel(val, reg);
 317}
 318
 319static void s3c64xx_gpio_irq_unmask(struct irq_data *irqd)
 320{
 321        s3c64xx_gpio_irq_set_mask(irqd, false);
 322}
 323
 324static void s3c64xx_gpio_irq_mask(struct irq_data *irqd)
 325{
 326        s3c64xx_gpio_irq_set_mask(irqd, true);
 327}
 328
 329static void s3c64xx_gpio_irq_ack(struct irq_data *irqd)
 330{
 331        struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(irqd);
 332        struct samsung_pinctrl_drv_data *d = bank->drvdata;
 333        unsigned char index = EINT_OFFS(bank->eint_offset) + irqd->hwirq;
 334        void __iomem *reg = d->virt_base + EINTPEND_REG(bank->eint_offset);
 335
 336        writel(1 << index, reg);
 337}
 338
 339static int s3c64xx_gpio_irq_set_type(struct irq_data *irqd, unsigned int type)
 340{
 341        struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(irqd);
 342        struct samsung_pinctrl_drv_data *d = bank->drvdata;
 343        void __iomem *reg;
 344        int trigger;
 345        u8 shift;
 346        u32 val;
 347
 348        trigger = s3c64xx_irq_get_trigger(type);
 349        if (trigger < 0) {
 350                pr_err("unsupported external interrupt type\n");
 351                return -EINVAL;
 352        }
 353
 354        s3c64xx_irq_set_handler(irqd, type);
 355
 356        /* Set up interrupt trigger */
 357        reg = d->virt_base + EINTCON_REG(bank->eint_offset);
 358        shift = EINT_OFFS(bank->eint_offset) + irqd->hwirq;
 359        shift = 4 * (shift / 4); /* 4 EINTs per trigger selector */
 360
 361        val = readl(reg);
 362        val &= ~(EINT_CON_MASK << shift);
 363        val |= trigger << shift;
 364        writel(val, reg);
 365
 366        s3c64xx_irq_set_function(d, bank, irqd->hwirq);
 367
 368        return 0;
 369}
 370
 371/*
 372 * irq_chip for gpio interrupts.
 373 */
 374static struct irq_chip s3c64xx_gpio_irq_chip = {
 375        .name           = "GPIO",
 376        .irq_unmask     = s3c64xx_gpio_irq_unmask,
 377        .irq_mask       = s3c64xx_gpio_irq_mask,
 378        .irq_ack        = s3c64xx_gpio_irq_ack,
 379        .irq_set_type   = s3c64xx_gpio_irq_set_type,
 380};
 381
 382static int s3c64xx_gpio_irq_map(struct irq_domain *h, unsigned int virq,
 383                                        irq_hw_number_t hw)
 384{
 385        struct samsung_pin_bank *bank = h->host_data;
 386
 387        if (!(bank->eint_mask & (1 << hw)))
 388                return -EINVAL;
 389
 390        irq_set_chip_and_handler(virq,
 391                                &s3c64xx_gpio_irq_chip, handle_level_irq);
 392        irq_set_chip_data(virq, bank);
 393
 394        return 0;
 395}
 396
 397/*
 398 * irq domain callbacks for external gpio interrupt controller.
 399 */
 400static const struct irq_domain_ops s3c64xx_gpio_irqd_ops = {
 401        .map    = s3c64xx_gpio_irq_map,
 402        .xlate  = irq_domain_xlate_twocell,
 403};
 404
 405static void s3c64xx_eint_gpio_irq(struct irq_desc *desc)
 406{
 407        struct irq_chip *chip = irq_desc_get_chip(desc);
 408        struct s3c64xx_eint_gpio_data *data = irq_desc_get_handler_data(desc);
 409        struct samsung_pinctrl_drv_data *drvdata = data->drvdata;
 410
 411        chained_irq_enter(chip, desc);
 412
 413        do {
 414                unsigned int svc;
 415                unsigned int group;
 416                unsigned int pin;
 417                unsigned int virq;
 418
 419                svc = readl(drvdata->virt_base + SERVICE_REG);
 420                group = SVC_GROUP(svc);
 421                pin = svc & SVC_NUM_MASK;
 422
 423                if (!group)
 424                        break;
 425
 426                /* Group 1 is used for two pin banks */
 427                if (group == 1) {
 428                        if (pin < 8)
 429                                group = 0;
 430                        else
 431                                pin -= 8;
 432                }
 433
 434                virq = irq_linear_revmap(data->domains[group], pin);
 435                /*
 436                 * Something must be really wrong if an unmapped EINT
 437                 * was unmasked...
 438                 */
 439                BUG_ON(!virq);
 440
 441                generic_handle_irq(virq);
 442        } while (1);
 443
 444        chained_irq_exit(chip, desc);
 445}
 446
 447/**
 448 * s3c64xx_eint_gpio_init() - setup handling of external gpio interrupts.
 449 * @d: driver data of samsung pinctrl driver.
 450 */
 451static int s3c64xx_eint_gpio_init(struct samsung_pinctrl_drv_data *d)
 452{
 453        struct s3c64xx_eint_gpio_data *data;
 454        struct samsung_pin_bank *bank;
 455        struct device *dev = d->dev;
 456        unsigned int nr_domains;
 457        unsigned int i;
 458
 459        if (!d->irq) {
 460                dev_err(dev, "irq number not available\n");
 461                return -EINVAL;
 462        }
 463
 464        nr_domains = 0;
 465        bank = d->pin_banks;
 466        for (i = 0; i < d->nr_banks; ++i, ++bank) {
 467                unsigned int nr_eints;
 468                unsigned int mask;
 469
 470                if (bank->eint_type != EINT_TYPE_GPIO)
 471                        continue;
 472
 473                mask = bank->eint_mask;
 474                nr_eints = fls(mask);
 475
 476                bank->irq_domain = irq_domain_add_linear(bank->of_node,
 477                                        nr_eints, &s3c64xx_gpio_irqd_ops, bank);
 478                if (!bank->irq_domain) {
 479                        dev_err(dev, "gpio irq domain add failed\n");
 480                        return -ENXIO;
 481                }
 482
 483                ++nr_domains;
 484        }
 485
 486        data = devm_kzalloc(dev, struct_size(data, domains, nr_domains),
 487                            GFP_KERNEL);
 488        if (!data)
 489                return -ENOMEM;
 490        data->drvdata = d;
 491
 492        bank = d->pin_banks;
 493        nr_domains = 0;
 494        for (i = 0; i < d->nr_banks; ++i, ++bank) {
 495                if (bank->eint_type != EINT_TYPE_GPIO)
 496                        continue;
 497
 498                data->domains[nr_domains++] = bank->irq_domain;
 499        }
 500
 501        irq_set_chained_handler_and_data(d->irq, s3c64xx_eint_gpio_irq, data);
 502
 503        return 0;
 504}
 505
 506/*
 507 * Functions for configuration of EINT0 wake-up interrupts
 508 */
 509
 510static inline void s3c64xx_eint0_irq_set_mask(struct irq_data *irqd, bool mask)
 511{
 512        struct s3c64xx_eint0_domain_data *ddata =
 513                                        irq_data_get_irq_chip_data(irqd);
 514        struct samsung_pinctrl_drv_data *d = ddata->bank->drvdata;
 515        u32 val;
 516
 517        val = readl(d->virt_base + EINT0MASK_REG);
 518        if (mask)
 519                val |= 1 << ddata->eints[irqd->hwirq];
 520        else
 521                val &= ~(1 << ddata->eints[irqd->hwirq]);
 522        writel(val, d->virt_base + EINT0MASK_REG);
 523}
 524
 525static void s3c64xx_eint0_irq_unmask(struct irq_data *irqd)
 526{
 527        s3c64xx_eint0_irq_set_mask(irqd, false);
 528}
 529
 530static void s3c64xx_eint0_irq_mask(struct irq_data *irqd)
 531{
 532        s3c64xx_eint0_irq_set_mask(irqd, true);
 533}
 534
 535static void s3c64xx_eint0_irq_ack(struct irq_data *irqd)
 536{
 537        struct s3c64xx_eint0_domain_data *ddata =
 538                                        irq_data_get_irq_chip_data(irqd);
 539        struct samsung_pinctrl_drv_data *d = ddata->bank->drvdata;
 540
 541        writel(1 << ddata->eints[irqd->hwirq],
 542                                        d->virt_base + EINT0PEND_REG);
 543}
 544
 545static int s3c64xx_eint0_irq_set_type(struct irq_data *irqd, unsigned int type)
 546{
 547        struct s3c64xx_eint0_domain_data *ddata =
 548                                        irq_data_get_irq_chip_data(irqd);
 549        struct samsung_pin_bank *bank = ddata->bank;
 550        struct samsung_pinctrl_drv_data *d = bank->drvdata;
 551        void __iomem *reg;
 552        int trigger;
 553        u8 shift;
 554        u32 val;
 555
 556        trigger = s3c64xx_irq_get_trigger(type);
 557        if (trigger < 0) {
 558                pr_err("unsupported external interrupt type\n");
 559                return -EINVAL;
 560        }
 561
 562        s3c64xx_irq_set_handler(irqd, type);
 563
 564        /* Set up interrupt trigger */
 565        reg = d->virt_base + EINT0CON0_REG;
 566        shift = ddata->eints[irqd->hwirq];
 567        if (shift >= EINT_MAX_PER_REG) {
 568                reg += 4;
 569                shift -= EINT_MAX_PER_REG;
 570        }
 571        shift = EINT_CON_LEN * (shift / 2);
 572
 573        val = readl(reg);
 574        val &= ~(EINT_CON_MASK << shift);
 575        val |= trigger << shift;
 576        writel(val, reg);
 577
 578        s3c64xx_irq_set_function(d, bank, irqd->hwirq);
 579
 580        return 0;
 581}
 582
 583/*
 584 * irq_chip for wakeup interrupts
 585 */
 586static struct irq_chip s3c64xx_eint0_irq_chip = {
 587        .name           = "EINT0",
 588        .irq_unmask     = s3c64xx_eint0_irq_unmask,
 589        .irq_mask       = s3c64xx_eint0_irq_mask,
 590        .irq_ack        = s3c64xx_eint0_irq_ack,
 591        .irq_set_type   = s3c64xx_eint0_irq_set_type,
 592};
 593
 594static inline void s3c64xx_irq_demux_eint(struct irq_desc *desc, u32 range)
 595{
 596        struct irq_chip *chip = irq_desc_get_chip(desc);
 597        struct s3c64xx_eint0_data *data = irq_desc_get_handler_data(desc);
 598        struct samsung_pinctrl_drv_data *drvdata = data->drvdata;
 599        unsigned int pend, mask;
 600
 601        chained_irq_enter(chip, desc);
 602
 603        pend = readl(drvdata->virt_base + EINT0PEND_REG);
 604        mask = readl(drvdata->virt_base + EINT0MASK_REG);
 605
 606        pend = pend & range & ~mask;
 607        pend &= range;
 608
 609        while (pend) {
 610                unsigned int virq, irq;
 611
 612                irq = fls(pend) - 1;
 613                pend &= ~(1 << irq);
 614                virq = irq_linear_revmap(data->domains[irq], data->pins[irq]);
 615                /*
 616                 * Something must be really wrong if an unmapped EINT
 617                 * was unmasked...
 618                 */
 619                BUG_ON(!virq);
 620
 621                generic_handle_irq(virq);
 622        }
 623
 624        chained_irq_exit(chip, desc);
 625}
 626
 627static void s3c64xx_demux_eint0_3(struct irq_desc *desc)
 628{
 629        s3c64xx_irq_demux_eint(desc, 0xf);
 630}
 631
 632static void s3c64xx_demux_eint4_11(struct irq_desc *desc)
 633{
 634        s3c64xx_irq_demux_eint(desc, 0xff0);
 635}
 636
 637static void s3c64xx_demux_eint12_19(struct irq_desc *desc)
 638{
 639        s3c64xx_irq_demux_eint(desc, 0xff000);
 640}
 641
 642static void s3c64xx_demux_eint20_27(struct irq_desc *desc)
 643{
 644        s3c64xx_irq_demux_eint(desc, 0xff00000);
 645}
 646
 647static irq_flow_handler_t s3c64xx_eint0_handlers[NUM_EINT0_IRQ] = {
 648        s3c64xx_demux_eint0_3,
 649        s3c64xx_demux_eint4_11,
 650        s3c64xx_demux_eint12_19,
 651        s3c64xx_demux_eint20_27,
 652};
 653
 654static int s3c64xx_eint0_irq_map(struct irq_domain *h, unsigned int virq,
 655                                        irq_hw_number_t hw)
 656{
 657        struct s3c64xx_eint0_domain_data *ddata = h->host_data;
 658        struct samsung_pin_bank *bank = ddata->bank;
 659
 660        if (!(bank->eint_mask & (1 << hw)))
 661                return -EINVAL;
 662
 663        irq_set_chip_and_handler(virq,
 664                                &s3c64xx_eint0_irq_chip, handle_level_irq);
 665        irq_set_chip_data(virq, ddata);
 666
 667        return 0;
 668}
 669
 670/*
 671 * irq domain callbacks for external wakeup interrupt controller.
 672 */
 673static const struct irq_domain_ops s3c64xx_eint0_irqd_ops = {
 674        .map    = s3c64xx_eint0_irq_map,
 675        .xlate  = irq_domain_xlate_twocell,
 676};
 677
 678/* list of external wakeup controllers supported */
 679static const struct of_device_id s3c64xx_eint0_irq_ids[] = {
 680        { .compatible = "samsung,s3c64xx-wakeup-eint", },
 681        { }
 682};
 683
 684/**
 685 * s3c64xx_eint_eint0_init() - setup handling of external wakeup interrupts.
 686 * @d: driver data of samsung pinctrl driver.
 687 */
 688static int s3c64xx_eint_eint0_init(struct samsung_pinctrl_drv_data *d)
 689{
 690        struct device *dev = d->dev;
 691        struct device_node *eint0_np = NULL;
 692        struct device_node *np;
 693        struct samsung_pin_bank *bank;
 694        struct s3c64xx_eint0_data *data;
 695        unsigned int i;
 696
 697        for_each_child_of_node(dev->of_node, np) {
 698                if (of_match_node(s3c64xx_eint0_irq_ids, np)) {
 699                        eint0_np = np;
 700                        break;
 701                }
 702        }
 703        if (!eint0_np)
 704                return -ENODEV;
 705
 706        data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
 707        if (!data) {
 708                of_node_put(eint0_np);
 709                return -ENOMEM;
 710        }
 711        data->drvdata = d;
 712
 713        for (i = 0; i < NUM_EINT0_IRQ; ++i) {
 714                unsigned int irq;
 715
 716                irq = irq_of_parse_and_map(eint0_np, i);
 717                if (!irq) {
 718                        dev_err(dev, "failed to get wakeup EINT IRQ %d\n", i);
 719                        of_node_put(eint0_np);
 720                        return -ENXIO;
 721                }
 722
 723                irq_set_chained_handler_and_data(irq,
 724                                                 s3c64xx_eint0_handlers[i],
 725                                                 data);
 726        }
 727        of_node_put(eint0_np);
 728
 729        bank = d->pin_banks;
 730        for (i = 0; i < d->nr_banks; ++i, ++bank) {
 731                struct s3c64xx_eint0_domain_data *ddata;
 732                unsigned int nr_eints;
 733                unsigned int mask;
 734                unsigned int irq;
 735                unsigned int pin;
 736
 737                if (bank->eint_type != EINT_TYPE_WKUP)
 738                        continue;
 739
 740                mask = bank->eint_mask;
 741                nr_eints = fls(mask);
 742
 743                ddata = devm_kzalloc(dev,
 744                                sizeof(*ddata) + nr_eints, GFP_KERNEL);
 745                if (!ddata)
 746                        return -ENOMEM;
 747                ddata->bank = bank;
 748
 749                bank->irq_domain = irq_domain_add_linear(bank->of_node,
 750                                nr_eints, &s3c64xx_eint0_irqd_ops, ddata);
 751                if (!bank->irq_domain) {
 752                        dev_err(dev, "wkup irq domain add failed\n");
 753                        return -ENXIO;
 754                }
 755
 756                irq = bank->eint_offset;
 757                mask = bank->eint_mask;
 758                for (pin = 0; mask; ++pin, mask >>= 1) {
 759                        if (!(mask & 1))
 760                                continue;
 761                        data->domains[irq] = bank->irq_domain;
 762                        data->pins[irq] = pin;
 763                        ddata->eints[pin] = irq;
 764                        ++irq;
 765                }
 766        }
 767
 768        return 0;
 769}
 770
 771/* pin banks of s3c64xx pin-controller 0 */
 772static const struct samsung_pin_bank_data s3c64xx_pin_banks0[] __initconst = {
 773        PIN_BANK_4BIT_EINTG(8, 0x000, "gpa", 0),
 774        PIN_BANK_4BIT_EINTG(7, 0x020, "gpb", 8),
 775        PIN_BANK_4BIT_EINTG(8, 0x040, "gpc", 16),
 776        PIN_BANK_4BIT_EINTG(5, 0x060, "gpd", 32),
 777        PIN_BANK_4BIT(5, 0x080, "gpe"),
 778        PIN_BANK_2BIT_EINTG(16, 0x0a0, "gpf", 48, 0x3fff),
 779        PIN_BANK_4BIT_EINTG(7, 0x0c0, "gpg", 64),
 780        PIN_BANK_4BIT2_EINTG(10, 0x0e0, "gph", 80),
 781        PIN_BANK_2BIT(16, 0x100, "gpi"),
 782        PIN_BANK_2BIT(12, 0x120, "gpj"),
 783        PIN_BANK_4BIT2_ALIVE(16, 0x800, "gpk"),
 784        PIN_BANK_4BIT2_EINTW(15, 0x810, "gpl", 16, 0x7f00),
 785        PIN_BANK_4BIT_EINTW(6, 0x820, "gpm", 23, 0x1f),
 786        PIN_BANK_2BIT_EINTW(16, 0x830, "gpn", 0),
 787        PIN_BANK_2BIT_EINTG(16, 0x140, "gpo", 96, 0xffff),
 788        PIN_BANK_2BIT_EINTG(15, 0x160, "gpp", 112, 0x7fff),
 789        PIN_BANK_2BIT_EINTG(9, 0x180, "gpq", 128, 0x1ff),
 790};
 791
 792/*
 793 * Samsung pinctrl driver data for S3C64xx SoC. S3C64xx SoC includes
 794 * one gpio/pin-mux/pinconfig controller.
 795 */
 796static const struct samsung_pin_ctrl s3c64xx_pin_ctrl[] __initconst = {
 797        {
 798                /* pin-controller instance 1 data */
 799                .pin_banks      = s3c64xx_pin_banks0,
 800                .nr_banks       = ARRAY_SIZE(s3c64xx_pin_banks0),
 801                .eint_gpio_init = s3c64xx_eint_gpio_init,
 802                .eint_wkup_init = s3c64xx_eint_eint0_init,
 803        },
 804};
 805
 806const struct samsung_pinctrl_of_match_data s3c64xx_of_data __initconst = {
 807        .ctrl           = s3c64xx_pin_ctrl,
 808        .num_ctrl       = ARRAY_SIZE(s3c64xx_pin_ctrl),
 809};
 810