root/drivers/pinctrl/samsung/pinctrl-s3c64xx.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. s3c64xx_irq_get_trigger
  2. s3c64xx_irq_set_handler
  3. s3c64xx_irq_set_function
  4. s3c64xx_gpio_irq_set_mask
  5. s3c64xx_gpio_irq_unmask
  6. s3c64xx_gpio_irq_mask
  7. s3c64xx_gpio_irq_ack
  8. s3c64xx_gpio_irq_set_type
  9. s3c64xx_gpio_irq_map
  10. s3c64xx_eint_gpio_irq
  11. s3c64xx_eint_gpio_init
  12. s3c64xx_eint0_irq_set_mask
  13. s3c64xx_eint0_irq_unmask
  14. s3c64xx_eint0_irq_mask
  15. s3c64xx_eint0_irq_ack
  16. s3c64xx_eint0_irq_set_type
  17. s3c64xx_irq_demux_eint
  18. s3c64xx_demux_eint0_3
  19. s3c64xx_demux_eint4_11
  20. s3c64xx_demux_eint12_19
  21. s3c64xx_demux_eint20_27
  22. s3c64xx_eint0_irq_map
  23. s3c64xx_eint_eint0_init

   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 
  66 static 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 
  71 static const struct samsung_pin_bank_type bank_type_4bit_alive = {
  72         .fld_width = { 4, 1, 2, },
  73         .reg_offset = { 0x00, 0x04, 0x08, },
  74 };
  75 
  76 static 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 
  81 static const struct samsung_pin_bank_type bank_type_4bit2_alive = {
  82         .fld_width = { 4, 1, 2, },
  83         .reg_offset = { 0x00, 0x08, 0x0c, },
  84 };
  85 
  86 static 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 
  91 static 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  */
 201 struct 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  */
 212 struct 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  */
 222 struct 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 
 231 static 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 
 258 static 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 
 267 static 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         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         spin_unlock_irqrestore(&bank->slock, flags);
 297 }
 298 
 299 /*
 300  * Functions for EINT GPIO configuration (EINT groups 1-9)
 301  */
 302 
 303 static 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 
 319 static void s3c64xx_gpio_irq_unmask(struct irq_data *irqd)
 320 {
 321         s3c64xx_gpio_irq_set_mask(irqd, false);
 322 }
 323 
 324 static void s3c64xx_gpio_irq_mask(struct irq_data *irqd)
 325 {
 326         s3c64xx_gpio_irq_set_mask(irqd, true);
 327 }
 328 
 329 static 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 
 339 static 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  */
 374 static 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 
 382 static 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  */
 400 static const struct irq_domain_ops s3c64xx_gpio_irqd_ops = {
 401         .map    = s3c64xx_gpio_irq_map,
 402         .xlate  = irq_domain_xlate_twocell,
 403 };
 404 
 405 static 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  */
 451 static 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 
 510 static 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 
 525 static void s3c64xx_eint0_irq_unmask(struct irq_data *irqd)
 526 {
 527         s3c64xx_eint0_irq_set_mask(irqd, false);
 528 }
 529 
 530 static void s3c64xx_eint0_irq_mask(struct irq_data *irqd)
 531 {
 532         s3c64xx_eint0_irq_set_mask(irqd, true);
 533 }
 534 
 535 static 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 
 545 static 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  */
 586 static 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 
 594 static 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 
 627 static void s3c64xx_demux_eint0_3(struct irq_desc *desc)
 628 {
 629         s3c64xx_irq_demux_eint(desc, 0xf);
 630 }
 631 
 632 static void s3c64xx_demux_eint4_11(struct irq_desc *desc)
 633 {
 634         s3c64xx_irq_demux_eint(desc, 0xff0);
 635 }
 636 
 637 static void s3c64xx_demux_eint12_19(struct irq_desc *desc)
 638 {
 639         s3c64xx_irq_demux_eint(desc, 0xff000);
 640 }
 641 
 642 static void s3c64xx_demux_eint20_27(struct irq_desc *desc)
 643 {
 644         s3c64xx_irq_demux_eint(desc, 0xff00000);
 645 }
 646 
 647 static 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 
 654 static 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  */
 673 static 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 */
 679 static 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  */
 688 static 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 */
 772 static 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  */
 796 static 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 
 806 const struct samsung_pinctrl_of_match_data s3c64xx_of_data __initconst = {
 807         .ctrl           = s3c64xx_pin_ctrl,
 808         .num_ctrl       = ARRAY_SIZE(s3c64xx_pin_ctrl),
 809 };

/* [<][>][^][v][top][bottom][index][help] */