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                int ret;
 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                ret = generic_handle_domain_irq(data->domains[group], pin);
 435                /*
 436                 * Something must be really wrong if an unmapped EINT
 437                 * was unmasked...
 438                 */
 439                BUG_ON(ret);
 440        } while (1);
 441
 442        chained_irq_exit(chip, desc);
 443}
 444
 445/**
 446 * s3c64xx_eint_gpio_init() - setup handling of external gpio interrupts.
 447 * @d: driver data of samsung pinctrl driver.
 448 */
 449static int s3c64xx_eint_gpio_init(struct samsung_pinctrl_drv_data *d)
 450{
 451        struct s3c64xx_eint_gpio_data *data;
 452        struct samsung_pin_bank *bank;
 453        struct device *dev = d->dev;
 454        unsigned int nr_domains;
 455        unsigned int i;
 456
 457        if (!d->irq) {
 458                dev_err(dev, "irq number not available\n");
 459                return -EINVAL;
 460        }
 461
 462        nr_domains = 0;
 463        bank = d->pin_banks;
 464        for (i = 0; i < d->nr_banks; ++i, ++bank) {
 465                unsigned int nr_eints;
 466                unsigned int mask;
 467
 468                if (bank->eint_type != EINT_TYPE_GPIO)
 469                        continue;
 470
 471                mask = bank->eint_mask;
 472                nr_eints = fls(mask);
 473
 474                bank->irq_domain = irq_domain_add_linear(bank->of_node,
 475                                        nr_eints, &s3c64xx_gpio_irqd_ops, bank);
 476                if (!bank->irq_domain) {
 477                        dev_err(dev, "gpio irq domain add failed\n");
 478                        return -ENXIO;
 479                }
 480
 481                ++nr_domains;
 482        }
 483
 484        data = devm_kzalloc(dev, struct_size(data, domains, nr_domains),
 485                            GFP_KERNEL);
 486        if (!data)
 487                return -ENOMEM;
 488        data->drvdata = d;
 489
 490        bank = d->pin_banks;
 491        nr_domains = 0;
 492        for (i = 0; i < d->nr_banks; ++i, ++bank) {
 493                if (bank->eint_type != EINT_TYPE_GPIO)
 494                        continue;
 495
 496                data->domains[nr_domains++] = bank->irq_domain;
 497        }
 498
 499        irq_set_chained_handler_and_data(d->irq, s3c64xx_eint_gpio_irq, data);
 500
 501        return 0;
 502}
 503
 504/*
 505 * Functions for configuration of EINT0 wake-up interrupts
 506 */
 507
 508static inline void s3c64xx_eint0_irq_set_mask(struct irq_data *irqd, bool mask)
 509{
 510        struct s3c64xx_eint0_domain_data *ddata =
 511                                        irq_data_get_irq_chip_data(irqd);
 512        struct samsung_pinctrl_drv_data *d = ddata->bank->drvdata;
 513        u32 val;
 514
 515        val = readl(d->virt_base + EINT0MASK_REG);
 516        if (mask)
 517                val |= 1 << ddata->eints[irqd->hwirq];
 518        else
 519                val &= ~(1 << ddata->eints[irqd->hwirq]);
 520        writel(val, d->virt_base + EINT0MASK_REG);
 521}
 522
 523static void s3c64xx_eint0_irq_unmask(struct irq_data *irqd)
 524{
 525        s3c64xx_eint0_irq_set_mask(irqd, false);
 526}
 527
 528static void s3c64xx_eint0_irq_mask(struct irq_data *irqd)
 529{
 530        s3c64xx_eint0_irq_set_mask(irqd, true);
 531}
 532
 533static void s3c64xx_eint0_irq_ack(struct irq_data *irqd)
 534{
 535        struct s3c64xx_eint0_domain_data *ddata =
 536                                        irq_data_get_irq_chip_data(irqd);
 537        struct samsung_pinctrl_drv_data *d = ddata->bank->drvdata;
 538
 539        writel(1 << ddata->eints[irqd->hwirq],
 540                                        d->virt_base + EINT0PEND_REG);
 541}
 542
 543static int s3c64xx_eint0_irq_set_type(struct irq_data *irqd, unsigned int type)
 544{
 545        struct s3c64xx_eint0_domain_data *ddata =
 546                                        irq_data_get_irq_chip_data(irqd);
 547        struct samsung_pin_bank *bank = ddata->bank;
 548        struct samsung_pinctrl_drv_data *d = bank->drvdata;
 549        void __iomem *reg;
 550        int trigger;
 551        u8 shift;
 552        u32 val;
 553
 554        trigger = s3c64xx_irq_get_trigger(type);
 555        if (trigger < 0) {
 556                pr_err("unsupported external interrupt type\n");
 557                return -EINVAL;
 558        }
 559
 560        s3c64xx_irq_set_handler(irqd, type);
 561
 562        /* Set up interrupt trigger */
 563        reg = d->virt_base + EINT0CON0_REG;
 564        shift = ddata->eints[irqd->hwirq];
 565        if (shift >= EINT_MAX_PER_REG) {
 566                reg += 4;
 567                shift -= EINT_MAX_PER_REG;
 568        }
 569        shift = EINT_CON_LEN * (shift / 2);
 570
 571        val = readl(reg);
 572        val &= ~(EINT_CON_MASK << shift);
 573        val |= trigger << shift;
 574        writel(val, reg);
 575
 576        s3c64xx_irq_set_function(d, bank, irqd->hwirq);
 577
 578        return 0;
 579}
 580
 581/*
 582 * irq_chip for wakeup interrupts
 583 */
 584static struct irq_chip s3c64xx_eint0_irq_chip = {
 585        .name           = "EINT0",
 586        .irq_unmask     = s3c64xx_eint0_irq_unmask,
 587        .irq_mask       = s3c64xx_eint0_irq_mask,
 588        .irq_ack        = s3c64xx_eint0_irq_ack,
 589        .irq_set_type   = s3c64xx_eint0_irq_set_type,
 590};
 591
 592static inline void s3c64xx_irq_demux_eint(struct irq_desc *desc, u32 range)
 593{
 594        struct irq_chip *chip = irq_desc_get_chip(desc);
 595        struct s3c64xx_eint0_data *data = irq_desc_get_handler_data(desc);
 596        struct samsung_pinctrl_drv_data *drvdata = data->drvdata;
 597        unsigned int pend, mask;
 598
 599        chained_irq_enter(chip, desc);
 600
 601        pend = readl(drvdata->virt_base + EINT0PEND_REG);
 602        mask = readl(drvdata->virt_base + EINT0MASK_REG);
 603
 604        pend = pend & range & ~mask;
 605        pend &= range;
 606
 607        while (pend) {
 608                unsigned int irq;
 609                int ret;
 610
 611                irq = fls(pend) - 1;
 612                pend &= ~(1 << irq);
 613                ret = generic_handle_domain_irq(data->domains[irq], data->pins[irq]);
 614                /*
 615                 * Something must be really wrong if an unmapped EINT
 616                 * was unmasked...
 617                 */
 618                BUG_ON(ret);
 619        }
 620
 621        chained_irq_exit(chip, desc);
 622}
 623
 624static void s3c64xx_demux_eint0_3(struct irq_desc *desc)
 625{
 626        s3c64xx_irq_demux_eint(desc, 0xf);
 627}
 628
 629static void s3c64xx_demux_eint4_11(struct irq_desc *desc)
 630{
 631        s3c64xx_irq_demux_eint(desc, 0xff0);
 632}
 633
 634static void s3c64xx_demux_eint12_19(struct irq_desc *desc)
 635{
 636        s3c64xx_irq_demux_eint(desc, 0xff000);
 637}
 638
 639static void s3c64xx_demux_eint20_27(struct irq_desc *desc)
 640{
 641        s3c64xx_irq_demux_eint(desc, 0xff00000);
 642}
 643
 644static irq_flow_handler_t s3c64xx_eint0_handlers[NUM_EINT0_IRQ] = {
 645        s3c64xx_demux_eint0_3,
 646        s3c64xx_demux_eint4_11,
 647        s3c64xx_demux_eint12_19,
 648        s3c64xx_demux_eint20_27,
 649};
 650
 651static int s3c64xx_eint0_irq_map(struct irq_domain *h, unsigned int virq,
 652                                        irq_hw_number_t hw)
 653{
 654        struct s3c64xx_eint0_domain_data *ddata = h->host_data;
 655        struct samsung_pin_bank *bank = ddata->bank;
 656
 657        if (!(bank->eint_mask & (1 << hw)))
 658                return -EINVAL;
 659
 660        irq_set_chip_and_handler(virq,
 661                                &s3c64xx_eint0_irq_chip, handle_level_irq);
 662        irq_set_chip_data(virq, ddata);
 663
 664        return 0;
 665}
 666
 667/*
 668 * irq domain callbacks for external wakeup interrupt controller.
 669 */
 670static const struct irq_domain_ops s3c64xx_eint0_irqd_ops = {
 671        .map    = s3c64xx_eint0_irq_map,
 672        .xlate  = irq_domain_xlate_twocell,
 673};
 674
 675/* list of external wakeup controllers supported */
 676static const struct of_device_id s3c64xx_eint0_irq_ids[] = {
 677        { .compatible = "samsung,s3c64xx-wakeup-eint", },
 678        { }
 679};
 680
 681/**
 682 * s3c64xx_eint_eint0_init() - setup handling of external wakeup interrupts.
 683 * @d: driver data of samsung pinctrl driver.
 684 */
 685static int s3c64xx_eint_eint0_init(struct samsung_pinctrl_drv_data *d)
 686{
 687        struct device *dev = d->dev;
 688        struct device_node *eint0_np = NULL;
 689        struct device_node *np;
 690        struct samsung_pin_bank *bank;
 691        struct s3c64xx_eint0_data *data;
 692        unsigned int i;
 693
 694        for_each_child_of_node(dev->of_node, np) {
 695                if (of_match_node(s3c64xx_eint0_irq_ids, np)) {
 696                        eint0_np = np;
 697                        break;
 698                }
 699        }
 700        if (!eint0_np)
 701                return -ENODEV;
 702
 703        data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
 704        if (!data) {
 705                of_node_put(eint0_np);
 706                return -ENOMEM;
 707        }
 708        data->drvdata = d;
 709
 710        for (i = 0; i < NUM_EINT0_IRQ; ++i) {
 711                unsigned int irq;
 712
 713                irq = irq_of_parse_and_map(eint0_np, i);
 714                if (!irq) {
 715                        dev_err(dev, "failed to get wakeup EINT IRQ %d\n", i);
 716                        of_node_put(eint0_np);
 717                        return -ENXIO;
 718                }
 719
 720                irq_set_chained_handler_and_data(irq,
 721                                                 s3c64xx_eint0_handlers[i],
 722                                                 data);
 723        }
 724        of_node_put(eint0_np);
 725
 726        bank = d->pin_banks;
 727        for (i = 0; i < d->nr_banks; ++i, ++bank) {
 728                struct s3c64xx_eint0_domain_data *ddata;
 729                unsigned int nr_eints;
 730                unsigned int mask;
 731                unsigned int irq;
 732                unsigned int pin;
 733
 734                if (bank->eint_type != EINT_TYPE_WKUP)
 735                        continue;
 736
 737                mask = bank->eint_mask;
 738                nr_eints = fls(mask);
 739
 740                ddata = devm_kzalloc(dev,
 741                                sizeof(*ddata) + nr_eints, GFP_KERNEL);
 742                if (!ddata)
 743                        return -ENOMEM;
 744                ddata->bank = bank;
 745
 746                bank->irq_domain = irq_domain_add_linear(bank->of_node,
 747                                nr_eints, &s3c64xx_eint0_irqd_ops, ddata);
 748                if (!bank->irq_domain) {
 749                        dev_err(dev, "wkup irq domain add failed\n");
 750                        return -ENXIO;
 751                }
 752
 753                irq = bank->eint_offset;
 754                mask = bank->eint_mask;
 755                for (pin = 0; mask; ++pin, mask >>= 1) {
 756                        if (!(mask & 1))
 757                                continue;
 758                        data->domains[irq] = bank->irq_domain;
 759                        data->pins[irq] = pin;
 760                        ddata->eints[pin] = irq;
 761                        ++irq;
 762                }
 763        }
 764
 765        return 0;
 766}
 767
 768/* pin banks of s3c64xx pin-controller 0 */
 769static const struct samsung_pin_bank_data s3c64xx_pin_banks0[] __initconst = {
 770        PIN_BANK_4BIT_EINTG(8, 0x000, "gpa", 0),
 771        PIN_BANK_4BIT_EINTG(7, 0x020, "gpb", 8),
 772        PIN_BANK_4BIT_EINTG(8, 0x040, "gpc", 16),
 773        PIN_BANK_4BIT_EINTG(5, 0x060, "gpd", 32),
 774        PIN_BANK_4BIT(5, 0x080, "gpe"),
 775        PIN_BANK_2BIT_EINTG(16, 0x0a0, "gpf", 48, 0x3fff),
 776        PIN_BANK_4BIT_EINTG(7, 0x0c0, "gpg", 64),
 777        PIN_BANK_4BIT2_EINTG(10, 0x0e0, "gph", 80),
 778        PIN_BANK_2BIT(16, 0x100, "gpi"),
 779        PIN_BANK_2BIT(12, 0x120, "gpj"),
 780        PIN_BANK_4BIT2_ALIVE(16, 0x800, "gpk"),
 781        PIN_BANK_4BIT2_EINTW(15, 0x810, "gpl", 16, 0x7f00),
 782        PIN_BANK_4BIT_EINTW(6, 0x820, "gpm", 23, 0x1f),
 783        PIN_BANK_2BIT_EINTW(16, 0x830, "gpn", 0),
 784        PIN_BANK_2BIT_EINTG(16, 0x140, "gpo", 96, 0xffff),
 785        PIN_BANK_2BIT_EINTG(15, 0x160, "gpp", 112, 0x7fff),
 786        PIN_BANK_2BIT_EINTG(9, 0x180, "gpq", 128, 0x1ff),
 787};
 788
 789/*
 790 * Samsung pinctrl driver data for S3C64xx SoC. S3C64xx SoC includes
 791 * one gpio/pin-mux/pinconfig controller.
 792 */
 793static const struct samsung_pin_ctrl s3c64xx_pin_ctrl[] __initconst = {
 794        {
 795                /* pin-controller instance 1 data */
 796                .pin_banks      = s3c64xx_pin_banks0,
 797                .nr_banks       = ARRAY_SIZE(s3c64xx_pin_banks0),
 798                .eint_gpio_init = s3c64xx_eint_gpio_init,
 799                .eint_wkup_init = s3c64xx_eint_eint0_init,
 800        },
 801};
 802
 803const struct samsung_pinctrl_of_match_data s3c64xx_of_data __initconst = {
 804        .ctrl           = s3c64xx_pin_ctrl,
 805        .num_ctrl       = ARRAY_SIZE(s3c64xx_pin_ctrl),
 806};
 807