linux/drivers/pinctrl/samsung/pinctrl-exynos.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0+
   2//
   3// Exynos specific support for Samsung pinctrl/gpiolib driver with eint support.
   4//
   5// Copyright (c) 2012 Samsung Electronics Co., Ltd.
   6//              http://www.samsung.com
   7// Copyright (c) 2012 Linaro Ltd
   8//              http://www.linaro.org
   9//
  10// Author: Thomas Abraham <thomas.ab@samsung.com>
  11//
  12// This file contains the Samsung Exynos specific information required by the
  13// the Samsung pinctrl/gpiolib driver. It also includes the implementation of
  14// external gpio and wakeup interrupt support.
  15
  16#include <linux/device.h>
  17#include <linux/interrupt.h>
  18#include <linux/irqdomain.h>
  19#include <linux/irq.h>
  20#include <linux/irqchip/chained_irq.h>
  21#include <linux/of.h>
  22#include <linux/of_irq.h>
  23#include <linux/slab.h>
  24#include <linux/spinlock.h>
  25#include <linux/regmap.h>
  26#include <linux/err.h>
  27#include <linux/soc/samsung/exynos-pmu.h>
  28
  29#include <dt-bindings/pinctrl/samsung.h>
  30
  31#include "pinctrl-samsung.h"
  32#include "pinctrl-exynos.h"
  33
  34struct exynos_irq_chip {
  35        struct irq_chip chip;
  36
  37        u32 eint_con;
  38        u32 eint_mask;
  39        u32 eint_pend;
  40};
  41
  42static inline struct exynos_irq_chip *to_exynos_irq_chip(struct irq_chip *chip)
  43{
  44        return container_of(chip, struct exynos_irq_chip, chip);
  45}
  46
  47static void exynos_irq_mask(struct irq_data *irqd)
  48{
  49        struct irq_chip *chip = irq_data_get_irq_chip(irqd);
  50        struct exynos_irq_chip *our_chip = to_exynos_irq_chip(chip);
  51        struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(irqd);
  52        unsigned long reg_mask = our_chip->eint_mask + bank->eint_offset;
  53        unsigned long mask;
  54        unsigned long flags;
  55
  56        spin_lock_irqsave(&bank->slock, flags);
  57
  58        mask = readl(bank->eint_base + reg_mask);
  59        mask |= 1 << irqd->hwirq;
  60        writel(mask, bank->eint_base + reg_mask);
  61
  62        spin_unlock_irqrestore(&bank->slock, flags);
  63}
  64
  65static void exynos_irq_ack(struct irq_data *irqd)
  66{
  67        struct irq_chip *chip = irq_data_get_irq_chip(irqd);
  68        struct exynos_irq_chip *our_chip = to_exynos_irq_chip(chip);
  69        struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(irqd);
  70        unsigned long reg_pend = our_chip->eint_pend + bank->eint_offset;
  71
  72        writel(1 << irqd->hwirq, bank->eint_base + reg_pend);
  73}
  74
  75static void exynos_irq_unmask(struct irq_data *irqd)
  76{
  77        struct irq_chip *chip = irq_data_get_irq_chip(irqd);
  78        struct exynos_irq_chip *our_chip = to_exynos_irq_chip(chip);
  79        struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(irqd);
  80        unsigned long reg_mask = our_chip->eint_mask + bank->eint_offset;
  81        unsigned long mask;
  82        unsigned long flags;
  83
  84        /*
  85         * Ack level interrupts right before unmask
  86         *
  87         * If we don't do this we'll get a double-interrupt.  Level triggered
  88         * interrupts must not fire an interrupt if the level is not
  89         * _currently_ active, even if it was active while the interrupt was
  90         * masked.
  91         */
  92        if (irqd_get_trigger_type(irqd) & IRQ_TYPE_LEVEL_MASK)
  93                exynos_irq_ack(irqd);
  94
  95        spin_lock_irqsave(&bank->slock, flags);
  96
  97        mask = readl(bank->eint_base + reg_mask);
  98        mask &= ~(1 << irqd->hwirq);
  99        writel(mask, bank->eint_base + reg_mask);
 100
 101        spin_unlock_irqrestore(&bank->slock, flags);
 102}
 103
 104static int exynos_irq_set_type(struct irq_data *irqd, unsigned int type)
 105{
 106        struct irq_chip *chip = irq_data_get_irq_chip(irqd);
 107        struct exynos_irq_chip *our_chip = to_exynos_irq_chip(chip);
 108        struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(irqd);
 109        unsigned int shift = EXYNOS_EINT_CON_LEN * irqd->hwirq;
 110        unsigned int con, trig_type;
 111        unsigned long reg_con = our_chip->eint_con + bank->eint_offset;
 112
 113        switch (type) {
 114        case IRQ_TYPE_EDGE_RISING:
 115                trig_type = EXYNOS_EINT_EDGE_RISING;
 116                break;
 117        case IRQ_TYPE_EDGE_FALLING:
 118                trig_type = EXYNOS_EINT_EDGE_FALLING;
 119                break;
 120        case IRQ_TYPE_EDGE_BOTH:
 121                trig_type = EXYNOS_EINT_EDGE_BOTH;
 122                break;
 123        case IRQ_TYPE_LEVEL_HIGH:
 124                trig_type = EXYNOS_EINT_LEVEL_HIGH;
 125                break;
 126        case IRQ_TYPE_LEVEL_LOW:
 127                trig_type = EXYNOS_EINT_LEVEL_LOW;
 128                break;
 129        default:
 130                pr_err("unsupported external interrupt type\n");
 131                return -EINVAL;
 132        }
 133
 134        if (type & IRQ_TYPE_EDGE_BOTH)
 135                irq_set_handler_locked(irqd, handle_edge_irq);
 136        else
 137                irq_set_handler_locked(irqd, handle_level_irq);
 138
 139        con = readl(bank->eint_base + reg_con);
 140        con &= ~(EXYNOS_EINT_CON_MASK << shift);
 141        con |= trig_type << shift;
 142        writel(con, bank->eint_base + reg_con);
 143
 144        return 0;
 145}
 146
 147static int exynos_irq_request_resources(struct irq_data *irqd)
 148{
 149        struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(irqd);
 150        const struct samsung_pin_bank_type *bank_type = bank->type;
 151        unsigned long reg_con, flags;
 152        unsigned int shift, mask, con;
 153        int ret;
 154
 155        ret = gpiochip_lock_as_irq(&bank->gpio_chip, irqd->hwirq);
 156        if (ret) {
 157                dev_err(bank->gpio_chip.parent,
 158                        "unable to lock pin %s-%lu IRQ\n",
 159                        bank->name, irqd->hwirq);
 160                return ret;
 161        }
 162
 163        reg_con = bank->pctl_offset + bank_type->reg_offset[PINCFG_TYPE_FUNC];
 164        shift = irqd->hwirq * bank_type->fld_width[PINCFG_TYPE_FUNC];
 165        mask = (1 << bank_type->fld_width[PINCFG_TYPE_FUNC]) - 1;
 166
 167        spin_lock_irqsave(&bank->slock, flags);
 168
 169        con = readl(bank->pctl_base + reg_con);
 170        con &= ~(mask << shift);
 171        con |= EXYNOS_PIN_FUNC_EINT << shift;
 172        writel(con, bank->pctl_base + reg_con);
 173
 174        spin_unlock_irqrestore(&bank->slock, flags);
 175
 176        return 0;
 177}
 178
 179static void exynos_irq_release_resources(struct irq_data *irqd)
 180{
 181        struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(irqd);
 182        const struct samsung_pin_bank_type *bank_type = bank->type;
 183        unsigned long reg_con, flags;
 184        unsigned int shift, mask, con;
 185
 186        reg_con = bank->pctl_offset + bank_type->reg_offset[PINCFG_TYPE_FUNC];
 187        shift = irqd->hwirq * bank_type->fld_width[PINCFG_TYPE_FUNC];
 188        mask = (1 << bank_type->fld_width[PINCFG_TYPE_FUNC]) - 1;
 189
 190        spin_lock_irqsave(&bank->slock, flags);
 191
 192        con = readl(bank->pctl_base + reg_con);
 193        con &= ~(mask << shift);
 194        con |= EXYNOS_PIN_FUNC_INPUT << shift;
 195        writel(con, bank->pctl_base + reg_con);
 196
 197        spin_unlock_irqrestore(&bank->slock, flags);
 198
 199        gpiochip_unlock_as_irq(&bank->gpio_chip, irqd->hwirq);
 200}
 201
 202/*
 203 * irq_chip for gpio interrupts.
 204 */
 205static struct exynos_irq_chip exynos_gpio_irq_chip = {
 206        .chip = {
 207                .name = "exynos_gpio_irq_chip",
 208                .irq_unmask = exynos_irq_unmask,
 209                .irq_mask = exynos_irq_mask,
 210                .irq_ack = exynos_irq_ack,
 211                .irq_set_type = exynos_irq_set_type,
 212                .irq_request_resources = exynos_irq_request_resources,
 213                .irq_release_resources = exynos_irq_release_resources,
 214        },
 215        .eint_con = EXYNOS_GPIO_ECON_OFFSET,
 216        .eint_mask = EXYNOS_GPIO_EMASK_OFFSET,
 217        .eint_pend = EXYNOS_GPIO_EPEND_OFFSET,
 218};
 219
 220static int exynos_eint_irq_map(struct irq_domain *h, unsigned int virq,
 221                                        irq_hw_number_t hw)
 222{
 223        struct samsung_pin_bank *b = h->host_data;
 224
 225        irq_set_chip_data(virq, b);
 226        irq_set_chip_and_handler(virq, &b->irq_chip->chip,
 227                                        handle_level_irq);
 228        return 0;
 229}
 230
 231/*
 232 * irq domain callbacks for external gpio and wakeup interrupt controllers.
 233 */
 234static const struct irq_domain_ops exynos_eint_irqd_ops = {
 235        .map    = exynos_eint_irq_map,
 236        .xlate  = irq_domain_xlate_twocell,
 237};
 238
 239static irqreturn_t exynos_eint_gpio_irq(int irq, void *data)
 240{
 241        struct samsung_pinctrl_drv_data *d = data;
 242        struct samsung_pin_bank *bank = d->pin_banks;
 243        unsigned int svc, group, pin, virq;
 244
 245        svc = readl(bank->eint_base + EXYNOS_SVC_OFFSET);
 246        group = EXYNOS_SVC_GROUP(svc);
 247        pin = svc & EXYNOS_SVC_NUM_MASK;
 248
 249        if (!group)
 250                return IRQ_HANDLED;
 251        bank += (group - 1);
 252
 253        virq = irq_linear_revmap(bank->irq_domain, pin);
 254        if (!virq)
 255                return IRQ_NONE;
 256        generic_handle_irq(virq);
 257        return IRQ_HANDLED;
 258}
 259
 260struct exynos_eint_gpio_save {
 261        u32 eint_con;
 262        u32 eint_fltcon0;
 263        u32 eint_fltcon1;
 264};
 265
 266/*
 267 * exynos_eint_gpio_init() - setup handling of external gpio interrupts.
 268 * @d: driver data of samsung pinctrl driver.
 269 */
 270int exynos_eint_gpio_init(struct samsung_pinctrl_drv_data *d)
 271{
 272        struct samsung_pin_bank *bank;
 273        struct device *dev = d->dev;
 274        int ret;
 275        int i;
 276
 277        if (!d->irq) {
 278                dev_err(dev, "irq number not available\n");
 279                return -EINVAL;
 280        }
 281
 282        ret = devm_request_irq(dev, d->irq, exynos_eint_gpio_irq,
 283                                        0, dev_name(dev), d);
 284        if (ret) {
 285                dev_err(dev, "irq request failed\n");
 286                return -ENXIO;
 287        }
 288
 289        bank = d->pin_banks;
 290        for (i = 0; i < d->nr_banks; ++i, ++bank) {
 291                if (bank->eint_type != EINT_TYPE_GPIO)
 292                        continue;
 293                bank->irq_domain = irq_domain_add_linear(bank->of_node,
 294                                bank->nr_pins, &exynos_eint_irqd_ops, bank);
 295                if (!bank->irq_domain) {
 296                        dev_err(dev, "gpio irq domain add failed\n");
 297                        ret = -ENXIO;
 298                        goto err_domains;
 299                }
 300
 301                bank->soc_priv = devm_kzalloc(d->dev,
 302                        sizeof(struct exynos_eint_gpio_save), GFP_KERNEL);
 303                if (!bank->soc_priv) {
 304                        irq_domain_remove(bank->irq_domain);
 305                        ret = -ENOMEM;
 306                        goto err_domains;
 307                }
 308
 309                bank->irq_chip = &exynos_gpio_irq_chip;
 310        }
 311
 312        return 0;
 313
 314err_domains:
 315        for (--i, --bank; i >= 0; --i, --bank) {
 316                if (bank->eint_type != EINT_TYPE_GPIO)
 317                        continue;
 318                irq_domain_remove(bank->irq_domain);
 319        }
 320
 321        return ret;
 322}
 323
 324static u32 exynos_eint_wake_mask = 0xffffffff;
 325
 326u32 exynos_get_eint_wake_mask(void)
 327{
 328        return exynos_eint_wake_mask;
 329}
 330
 331static int exynos_wkup_irq_set_wake(struct irq_data *irqd, unsigned int on)
 332{
 333        struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(irqd);
 334        unsigned long bit = 1UL << (2 * bank->eint_offset + irqd->hwirq);
 335
 336        pr_info("wake %s for irq %d\n", on ? "enabled" : "disabled", irqd->irq);
 337
 338        if (!on)
 339                exynos_eint_wake_mask |= bit;
 340        else
 341                exynos_eint_wake_mask &= ~bit;
 342
 343        return 0;
 344}
 345
 346/*
 347 * irq_chip for wakeup interrupts
 348 */
 349static const struct exynos_irq_chip exynos4210_wkup_irq_chip __initconst = {
 350        .chip = {
 351                .name = "exynos4210_wkup_irq_chip",
 352                .irq_unmask = exynos_irq_unmask,
 353                .irq_mask = exynos_irq_mask,
 354                .irq_ack = exynos_irq_ack,
 355                .irq_set_type = exynos_irq_set_type,
 356                .irq_set_wake = exynos_wkup_irq_set_wake,
 357                .irq_request_resources = exynos_irq_request_resources,
 358                .irq_release_resources = exynos_irq_release_resources,
 359        },
 360        .eint_con = EXYNOS_WKUP_ECON_OFFSET,
 361        .eint_mask = EXYNOS_WKUP_EMASK_OFFSET,
 362        .eint_pend = EXYNOS_WKUP_EPEND_OFFSET,
 363};
 364
 365static const struct exynos_irq_chip exynos7_wkup_irq_chip __initconst = {
 366        .chip = {
 367                .name = "exynos7_wkup_irq_chip",
 368                .irq_unmask = exynos_irq_unmask,
 369                .irq_mask = exynos_irq_mask,
 370                .irq_ack = exynos_irq_ack,
 371                .irq_set_type = exynos_irq_set_type,
 372                .irq_set_wake = exynos_wkup_irq_set_wake,
 373                .irq_request_resources = exynos_irq_request_resources,
 374                .irq_release_resources = exynos_irq_release_resources,
 375        },
 376        .eint_con = EXYNOS7_WKUP_ECON_OFFSET,
 377        .eint_mask = EXYNOS7_WKUP_EMASK_OFFSET,
 378        .eint_pend = EXYNOS7_WKUP_EPEND_OFFSET,
 379};
 380
 381/* list of external wakeup controllers supported */
 382static const struct of_device_id exynos_wkup_irq_ids[] = {
 383        { .compatible = "samsung,exynos4210-wakeup-eint",
 384                        .data = &exynos4210_wkup_irq_chip },
 385        { .compatible = "samsung,exynos7-wakeup-eint",
 386                        .data = &exynos7_wkup_irq_chip },
 387        { }
 388};
 389
 390/* interrupt handler for wakeup interrupts 0..15 */
 391static void exynos_irq_eint0_15(struct irq_desc *desc)
 392{
 393        struct exynos_weint_data *eintd = irq_desc_get_handler_data(desc);
 394        struct samsung_pin_bank *bank = eintd->bank;
 395        struct irq_chip *chip = irq_desc_get_chip(desc);
 396        int eint_irq;
 397
 398        chained_irq_enter(chip, desc);
 399
 400        eint_irq = irq_linear_revmap(bank->irq_domain, eintd->irq);
 401        generic_handle_irq(eint_irq);
 402
 403        chained_irq_exit(chip, desc);
 404}
 405
 406static inline void exynos_irq_demux_eint(unsigned long pend,
 407                                                struct irq_domain *domain)
 408{
 409        unsigned int irq;
 410
 411        while (pend) {
 412                irq = fls(pend) - 1;
 413                generic_handle_irq(irq_find_mapping(domain, irq));
 414                pend &= ~(1 << irq);
 415        }
 416}
 417
 418/* interrupt handler for wakeup interrupt 16 */
 419static void exynos_irq_demux_eint16_31(struct irq_desc *desc)
 420{
 421        struct irq_chip *chip = irq_desc_get_chip(desc);
 422        struct exynos_muxed_weint_data *eintd = irq_desc_get_handler_data(desc);
 423        unsigned long pend;
 424        unsigned long mask;
 425        int i;
 426
 427        chained_irq_enter(chip, desc);
 428
 429        for (i = 0; i < eintd->nr_banks; ++i) {
 430                struct samsung_pin_bank *b = eintd->banks[i];
 431                pend = readl(b->eint_base + b->irq_chip->eint_pend
 432                                + b->eint_offset);
 433                mask = readl(b->eint_base + b->irq_chip->eint_mask
 434                                + b->eint_offset);
 435                exynos_irq_demux_eint(pend & ~mask, b->irq_domain);
 436        }
 437
 438        chained_irq_exit(chip, desc);
 439}
 440
 441/*
 442 * exynos_eint_wkup_init() - setup handling of external wakeup interrupts.
 443 * @d: driver data of samsung pinctrl driver.
 444 */
 445int exynos_eint_wkup_init(struct samsung_pinctrl_drv_data *d)
 446{
 447        struct device *dev = d->dev;
 448        struct device_node *wkup_np = NULL;
 449        struct device_node *np;
 450        struct samsung_pin_bank *bank;
 451        struct exynos_weint_data *weint_data;
 452        struct exynos_muxed_weint_data *muxed_data;
 453        struct exynos_irq_chip *irq_chip;
 454        unsigned int muxed_banks = 0;
 455        unsigned int i;
 456        int idx, irq;
 457
 458        for_each_child_of_node(dev->of_node, np) {
 459                const struct of_device_id *match;
 460
 461                match = of_match_node(exynos_wkup_irq_ids, np);
 462                if (match) {
 463                        irq_chip = kmemdup(match->data,
 464                                sizeof(*irq_chip), GFP_KERNEL);
 465                        if (!irq_chip)
 466                                return -ENOMEM;
 467                        wkup_np = np;
 468                        break;
 469                }
 470        }
 471        if (!wkup_np)
 472                return -ENODEV;
 473
 474        bank = d->pin_banks;
 475        for (i = 0; i < d->nr_banks; ++i, ++bank) {
 476                if (bank->eint_type != EINT_TYPE_WKUP)
 477                        continue;
 478
 479                bank->irq_domain = irq_domain_add_linear(bank->of_node,
 480                                bank->nr_pins, &exynos_eint_irqd_ops, bank);
 481                if (!bank->irq_domain) {
 482                        dev_err(dev, "wkup irq domain add failed\n");
 483                        return -ENXIO;
 484                }
 485
 486                bank->irq_chip = irq_chip;
 487
 488                if (!of_find_property(bank->of_node, "interrupts", NULL)) {
 489                        bank->eint_type = EINT_TYPE_WKUP_MUX;
 490                        ++muxed_banks;
 491                        continue;
 492                }
 493
 494                weint_data = devm_kzalloc(dev, bank->nr_pins
 495                                        * sizeof(*weint_data), GFP_KERNEL);
 496                if (!weint_data)
 497                        return -ENOMEM;
 498
 499                for (idx = 0; idx < bank->nr_pins; ++idx) {
 500                        irq = irq_of_parse_and_map(bank->of_node, idx);
 501                        if (!irq) {
 502                                dev_err(dev, "irq number for eint-%s-%d not found\n",
 503                                                        bank->name, idx);
 504                                continue;
 505                        }
 506                        weint_data[idx].irq = idx;
 507                        weint_data[idx].bank = bank;
 508                        irq_set_chained_handler_and_data(irq,
 509                                                         exynos_irq_eint0_15,
 510                                                         &weint_data[idx]);
 511                }
 512        }
 513
 514        if (!muxed_banks)
 515                return 0;
 516
 517        irq = irq_of_parse_and_map(wkup_np, 0);
 518        if (!irq) {
 519                dev_err(dev, "irq number for muxed EINTs not found\n");
 520                return 0;
 521        }
 522
 523        muxed_data = devm_kzalloc(dev, sizeof(*muxed_data)
 524                + muxed_banks*sizeof(struct samsung_pin_bank *), GFP_KERNEL);
 525        if (!muxed_data)
 526                return -ENOMEM;
 527
 528        irq_set_chained_handler_and_data(irq, exynos_irq_demux_eint16_31,
 529                                         muxed_data);
 530
 531        bank = d->pin_banks;
 532        idx = 0;
 533        for (i = 0; i < d->nr_banks; ++i, ++bank) {
 534                if (bank->eint_type != EINT_TYPE_WKUP_MUX)
 535                        continue;
 536
 537                muxed_data->banks[idx++] = bank;
 538        }
 539        muxed_data->nr_banks = muxed_banks;
 540
 541        return 0;
 542}
 543
 544static void exynos_pinctrl_suspend_bank(
 545                                struct samsung_pinctrl_drv_data *drvdata,
 546                                struct samsung_pin_bank *bank)
 547{
 548        struct exynos_eint_gpio_save *save = bank->soc_priv;
 549        void __iomem *regs = bank->eint_base;
 550
 551        save->eint_con = readl(regs + EXYNOS_GPIO_ECON_OFFSET
 552                                                + bank->eint_offset);
 553        save->eint_fltcon0 = readl(regs + EXYNOS_GPIO_EFLTCON_OFFSET
 554                                                + 2 * bank->eint_offset);
 555        save->eint_fltcon1 = readl(regs + EXYNOS_GPIO_EFLTCON_OFFSET
 556                                                + 2 * bank->eint_offset + 4);
 557
 558        pr_debug("%s: save     con %#010x\n", bank->name, save->eint_con);
 559        pr_debug("%s: save fltcon0 %#010x\n", bank->name, save->eint_fltcon0);
 560        pr_debug("%s: save fltcon1 %#010x\n", bank->name, save->eint_fltcon1);
 561}
 562
 563void exynos_pinctrl_suspend(struct samsung_pinctrl_drv_data *drvdata)
 564{
 565        struct samsung_pin_bank *bank = drvdata->pin_banks;
 566        int i;
 567
 568        for (i = 0; i < drvdata->nr_banks; ++i, ++bank)
 569                if (bank->eint_type == EINT_TYPE_GPIO)
 570                        exynos_pinctrl_suspend_bank(drvdata, bank);
 571}
 572
 573static void exynos_pinctrl_resume_bank(
 574                                struct samsung_pinctrl_drv_data *drvdata,
 575                                struct samsung_pin_bank *bank)
 576{
 577        struct exynos_eint_gpio_save *save = bank->soc_priv;
 578        void __iomem *regs = bank->eint_base;
 579
 580        pr_debug("%s:     con %#010x => %#010x\n", bank->name,
 581                        readl(regs + EXYNOS_GPIO_ECON_OFFSET
 582                        + bank->eint_offset), save->eint_con);
 583        pr_debug("%s: fltcon0 %#010x => %#010x\n", bank->name,
 584                        readl(regs + EXYNOS_GPIO_EFLTCON_OFFSET
 585                        + 2 * bank->eint_offset), save->eint_fltcon0);
 586        pr_debug("%s: fltcon1 %#010x => %#010x\n", bank->name,
 587                        readl(regs + EXYNOS_GPIO_EFLTCON_OFFSET
 588                        + 2 * bank->eint_offset + 4), save->eint_fltcon1);
 589
 590        writel(save->eint_con, regs + EXYNOS_GPIO_ECON_OFFSET
 591                                                + bank->eint_offset);
 592        writel(save->eint_fltcon0, regs + EXYNOS_GPIO_EFLTCON_OFFSET
 593                                                + 2 * bank->eint_offset);
 594        writel(save->eint_fltcon1, regs + EXYNOS_GPIO_EFLTCON_OFFSET
 595                                                + 2 * bank->eint_offset + 4);
 596}
 597
 598void exynos_pinctrl_resume(struct samsung_pinctrl_drv_data *drvdata)
 599{
 600        struct samsung_pin_bank *bank = drvdata->pin_banks;
 601        int i;
 602
 603        for (i = 0; i < drvdata->nr_banks; ++i, ++bank)
 604                if (bank->eint_type == EINT_TYPE_GPIO)
 605                        exynos_pinctrl_resume_bank(drvdata, bank);
 606}
 607
 608static void exynos_retention_enable(struct samsung_pinctrl_drv_data *drvdata)
 609{
 610        if (drvdata->retention_ctrl->refcnt)
 611                atomic_inc(drvdata->retention_ctrl->refcnt);
 612}
 613
 614static void exynos_retention_disable(struct samsung_pinctrl_drv_data *drvdata)
 615{
 616        struct samsung_retention_ctrl *ctrl = drvdata->retention_ctrl;
 617        struct regmap *pmu_regs = ctrl->priv;
 618        int i;
 619
 620        if (ctrl->refcnt && !atomic_dec_and_test(ctrl->refcnt))
 621                return;
 622
 623        for (i = 0; i < ctrl->nr_regs; i++)
 624                regmap_write(pmu_regs, ctrl->regs[i], ctrl->value);
 625}
 626
 627struct samsung_retention_ctrl *
 628exynos_retention_init(struct samsung_pinctrl_drv_data *drvdata,
 629                      const struct samsung_retention_data *data)
 630{
 631        struct samsung_retention_ctrl *ctrl;
 632        struct regmap *pmu_regs;
 633        int i;
 634
 635        ctrl = devm_kzalloc(drvdata->dev, sizeof(*ctrl), GFP_KERNEL);
 636        if (!ctrl)
 637                return ERR_PTR(-ENOMEM);
 638
 639        pmu_regs = exynos_get_pmu_regmap();
 640        if (IS_ERR(pmu_regs))
 641                return ERR_CAST(pmu_regs);
 642
 643        ctrl->priv = pmu_regs;
 644        ctrl->regs = data->regs;
 645        ctrl->nr_regs = data->nr_regs;
 646        ctrl->value = data->value;
 647        ctrl->refcnt = data->refcnt;
 648        ctrl->enable = exynos_retention_enable;
 649        ctrl->disable = exynos_retention_disable;
 650
 651        /* Ensure that retention is disabled on driver init */
 652        for (i = 0; i < ctrl->nr_regs; i++)
 653                regmap_write(pmu_regs, ctrl->regs[i], ctrl->value);
 654
 655        return ctrl;
 656}
 657