linux/drivers/pinctrl/mediatek/mtk-eint.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0
   2// Copyright (c) 2014-2018 MediaTek Inc.
   3
   4/*
   5 * Library for MediaTek External Interrupt Support
   6 *
   7 * Author: Maoguang Meng <maoguang.meng@mediatek.com>
   8 *         Sean Wang <sean.wang@mediatek.com>
   9 *
  10 */
  11
  12#include <linux/delay.h>
  13#include <linux/err.h>
  14#include <linux/gpio/driver.h>
  15#include <linux/io.h>
  16#include <linux/irqchip/chained_irq.h>
  17#include <linux/irqdomain.h>
  18#include <linux/module.h>
  19#include <linux/of_irq.h>
  20#include <linux/platform_device.h>
  21
  22#include "mtk-eint.h"
  23
  24#define MTK_EINT_EDGE_SENSITIVE           0
  25#define MTK_EINT_LEVEL_SENSITIVE          1
  26#define MTK_EINT_DBNC_SET_DBNC_BITS       4
  27#define MTK_EINT_DBNC_RST_BIT             (0x1 << 1)
  28#define MTK_EINT_DBNC_SET_EN              (0x1 << 0)
  29
  30static const struct mtk_eint_regs mtk_generic_eint_regs = {
  31        .stat      = 0x000,
  32        .ack       = 0x040,
  33        .mask      = 0x080,
  34        .mask_set  = 0x0c0,
  35        .mask_clr  = 0x100,
  36        .sens      = 0x140,
  37        .sens_set  = 0x180,
  38        .sens_clr  = 0x1c0,
  39        .soft      = 0x200,
  40        .soft_set  = 0x240,
  41        .soft_clr  = 0x280,
  42        .pol       = 0x300,
  43        .pol_set   = 0x340,
  44        .pol_clr   = 0x380,
  45        .dom_en    = 0x400,
  46        .dbnc_ctrl = 0x500,
  47        .dbnc_set  = 0x600,
  48        .dbnc_clr  = 0x700,
  49};
  50
  51static void __iomem *mtk_eint_get_offset(struct mtk_eint *eint,
  52                                         unsigned int eint_num,
  53                                         unsigned int offset)
  54{
  55        unsigned int eint_base = 0;
  56        void __iomem *reg;
  57
  58        if (eint_num >= eint->hw->ap_num)
  59                eint_base = eint->hw->ap_num;
  60
  61        reg = eint->base + offset + ((eint_num - eint_base) / 32) * 4;
  62
  63        return reg;
  64}
  65
  66static unsigned int mtk_eint_can_en_debounce(struct mtk_eint *eint,
  67                                             unsigned int eint_num)
  68{
  69        unsigned int sens;
  70        unsigned int bit = BIT(eint_num % 32);
  71        void __iomem *reg = mtk_eint_get_offset(eint, eint_num,
  72                                                eint->regs->sens);
  73
  74        if (readl(reg) & bit)
  75                sens = MTK_EINT_LEVEL_SENSITIVE;
  76        else
  77                sens = MTK_EINT_EDGE_SENSITIVE;
  78
  79        if (eint_num < eint->hw->db_cnt && sens != MTK_EINT_EDGE_SENSITIVE)
  80                return 1;
  81        else
  82                return 0;
  83}
  84
  85static int mtk_eint_flip_edge(struct mtk_eint *eint, int hwirq)
  86{
  87        int start_level, curr_level;
  88        unsigned int reg_offset;
  89        u32 mask = BIT(hwirq & 0x1f);
  90        u32 port = (hwirq >> 5) & eint->hw->port_mask;
  91        void __iomem *reg = eint->base + (port << 2);
  92
  93        curr_level = eint->gpio_xlate->get_gpio_state(eint->pctl, hwirq);
  94
  95        do {
  96                start_level = curr_level;
  97                if (start_level)
  98                        reg_offset = eint->regs->pol_clr;
  99                else
 100                        reg_offset = eint->regs->pol_set;
 101                writel(mask, reg + reg_offset);
 102
 103                curr_level = eint->gpio_xlate->get_gpio_state(eint->pctl,
 104                                                              hwirq);
 105        } while (start_level != curr_level);
 106
 107        return start_level;
 108}
 109
 110static void mtk_eint_mask(struct irq_data *d)
 111{
 112        struct mtk_eint *eint = irq_data_get_irq_chip_data(d);
 113        u32 mask = BIT(d->hwirq & 0x1f);
 114        void __iomem *reg = mtk_eint_get_offset(eint, d->hwirq,
 115                                                eint->regs->mask_set);
 116
 117        eint->cur_mask[d->hwirq >> 5] &= ~mask;
 118
 119        writel(mask, reg);
 120}
 121
 122static void mtk_eint_unmask(struct irq_data *d)
 123{
 124        struct mtk_eint *eint = irq_data_get_irq_chip_data(d);
 125        u32 mask = BIT(d->hwirq & 0x1f);
 126        void __iomem *reg = mtk_eint_get_offset(eint, d->hwirq,
 127                                                eint->regs->mask_clr);
 128
 129        eint->cur_mask[d->hwirq >> 5] |= mask;
 130
 131        writel(mask, reg);
 132
 133        if (eint->dual_edge[d->hwirq])
 134                mtk_eint_flip_edge(eint, d->hwirq);
 135}
 136
 137static unsigned int mtk_eint_get_mask(struct mtk_eint *eint,
 138                                      unsigned int eint_num)
 139{
 140        unsigned int bit = BIT(eint_num % 32);
 141        void __iomem *reg = mtk_eint_get_offset(eint, eint_num,
 142                                                eint->regs->mask);
 143
 144        return !!(readl(reg) & bit);
 145}
 146
 147static void mtk_eint_ack(struct irq_data *d)
 148{
 149        struct mtk_eint *eint = irq_data_get_irq_chip_data(d);
 150        u32 mask = BIT(d->hwirq & 0x1f);
 151        void __iomem *reg = mtk_eint_get_offset(eint, d->hwirq,
 152                                                eint->regs->ack);
 153
 154        writel(mask, reg);
 155}
 156
 157static int mtk_eint_set_type(struct irq_data *d, unsigned int type)
 158{
 159        struct mtk_eint *eint = irq_data_get_irq_chip_data(d);
 160        bool masked;
 161        u32 mask = BIT(d->hwirq & 0x1f);
 162        void __iomem *reg;
 163
 164        if (((type & IRQ_TYPE_EDGE_BOTH) && (type & IRQ_TYPE_LEVEL_MASK)) ||
 165            ((type & IRQ_TYPE_LEVEL_MASK) == IRQ_TYPE_LEVEL_MASK)) {
 166                dev_err(eint->dev,
 167                        "Can't configure IRQ%d (EINT%lu) for type 0x%X\n",
 168                        d->irq, d->hwirq, type);
 169                return -EINVAL;
 170        }
 171
 172        if ((type & IRQ_TYPE_EDGE_BOTH) == IRQ_TYPE_EDGE_BOTH)
 173                eint->dual_edge[d->hwirq] = 1;
 174        else
 175                eint->dual_edge[d->hwirq] = 0;
 176
 177        if (!mtk_eint_get_mask(eint, d->hwirq)) {
 178                mtk_eint_mask(d);
 179                masked = false;
 180        } else {
 181                masked = true;
 182        }
 183
 184        if (type & (IRQ_TYPE_LEVEL_LOW | IRQ_TYPE_EDGE_FALLING)) {
 185                reg = mtk_eint_get_offset(eint, d->hwirq, eint->regs->pol_clr);
 186                writel(mask, reg);
 187        } else {
 188                reg = mtk_eint_get_offset(eint, d->hwirq, eint->regs->pol_set);
 189                writel(mask, reg);
 190        }
 191
 192        if (type & (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING)) {
 193                reg = mtk_eint_get_offset(eint, d->hwirq, eint->regs->sens_clr);
 194                writel(mask, reg);
 195        } else {
 196                reg = mtk_eint_get_offset(eint, d->hwirq, eint->regs->sens_set);
 197                writel(mask, reg);
 198        }
 199
 200        mtk_eint_ack(d);
 201        if (!masked)
 202                mtk_eint_unmask(d);
 203
 204        return 0;
 205}
 206
 207static int mtk_eint_irq_set_wake(struct irq_data *d, unsigned int on)
 208{
 209        struct mtk_eint *eint = irq_data_get_irq_chip_data(d);
 210        int shift = d->hwirq & 0x1f;
 211        int reg = d->hwirq >> 5;
 212
 213        if (on)
 214                eint->wake_mask[reg] |= BIT(shift);
 215        else
 216                eint->wake_mask[reg] &= ~BIT(shift);
 217
 218        return 0;
 219}
 220
 221static void mtk_eint_chip_write_mask(const struct mtk_eint *eint,
 222                                     void __iomem *base, u32 *buf)
 223{
 224        int port;
 225        void __iomem *reg;
 226
 227        for (port = 0; port < eint->hw->ports; port++) {
 228                reg = base + (port << 2);
 229                writel_relaxed(~buf[port], reg + eint->regs->mask_set);
 230                writel_relaxed(buf[port], reg + eint->regs->mask_clr);
 231        }
 232}
 233
 234static int mtk_eint_irq_request_resources(struct irq_data *d)
 235{
 236        struct mtk_eint *eint = irq_data_get_irq_chip_data(d);
 237        struct gpio_chip *gpio_c;
 238        unsigned int gpio_n;
 239        int err;
 240
 241        err = eint->gpio_xlate->get_gpio_n(eint->pctl, d->hwirq,
 242                                           &gpio_n, &gpio_c);
 243        if (err < 0) {
 244                dev_err(eint->dev, "Can not find pin\n");
 245                return err;
 246        }
 247
 248        err = gpiochip_lock_as_irq(gpio_c, gpio_n);
 249        if (err < 0) {
 250                dev_err(eint->dev, "unable to lock HW IRQ %lu for IRQ\n",
 251                        irqd_to_hwirq(d));
 252                return err;
 253        }
 254
 255        err = eint->gpio_xlate->set_gpio_as_eint(eint->pctl, d->hwirq);
 256        if (err < 0) {
 257                dev_err(eint->dev, "Can not eint mode\n");
 258                return err;
 259        }
 260
 261        return 0;
 262}
 263
 264static void mtk_eint_irq_release_resources(struct irq_data *d)
 265{
 266        struct mtk_eint *eint = irq_data_get_irq_chip_data(d);
 267        struct gpio_chip *gpio_c;
 268        unsigned int gpio_n;
 269
 270        eint->gpio_xlate->get_gpio_n(eint->pctl, d->hwirq, &gpio_n,
 271                                     &gpio_c);
 272
 273        gpiochip_unlock_as_irq(gpio_c, gpio_n);
 274}
 275
 276static struct irq_chip mtk_eint_irq_chip = {
 277        .name = "mt-eint",
 278        .irq_disable = mtk_eint_mask,
 279        .irq_mask = mtk_eint_mask,
 280        .irq_unmask = mtk_eint_unmask,
 281        .irq_ack = mtk_eint_ack,
 282        .irq_set_type = mtk_eint_set_type,
 283        .irq_set_wake = mtk_eint_irq_set_wake,
 284        .irq_request_resources = mtk_eint_irq_request_resources,
 285        .irq_release_resources = mtk_eint_irq_release_resources,
 286};
 287
 288static unsigned int mtk_eint_hw_init(struct mtk_eint *eint)
 289{
 290        void __iomem *reg = eint->base + eint->regs->dom_en;
 291        unsigned int i;
 292
 293        for (i = 0; i < eint->hw->ap_num; i += 32) {
 294                writel(0xffffffff, reg);
 295                reg += 4;
 296        }
 297
 298        return 0;
 299}
 300
 301static inline void
 302mtk_eint_debounce_process(struct mtk_eint *eint, int index)
 303{
 304        unsigned int rst, ctrl_offset;
 305        unsigned int bit, dbnc;
 306
 307        ctrl_offset = (index / 4) * 4 + eint->regs->dbnc_ctrl;
 308        dbnc = readl(eint->base + ctrl_offset);
 309        bit = MTK_EINT_DBNC_SET_EN << ((index % 4) * 8);
 310        if ((bit & dbnc) > 0) {
 311                ctrl_offset = (index / 4) * 4 + eint->regs->dbnc_set;
 312                rst = MTK_EINT_DBNC_RST_BIT << ((index % 4) * 8);
 313                writel(rst, eint->base + ctrl_offset);
 314        }
 315}
 316
 317static void mtk_eint_irq_handler(struct irq_desc *desc)
 318{
 319        struct irq_chip *chip = irq_desc_get_chip(desc);
 320        struct mtk_eint *eint = irq_desc_get_handler_data(desc);
 321        unsigned int status, eint_num;
 322        int offset, mask_offset, index;
 323        void __iomem *reg =  mtk_eint_get_offset(eint, 0, eint->regs->stat);
 324        int dual_edge, start_level, curr_level;
 325
 326        chained_irq_enter(chip, desc);
 327        for (eint_num = 0; eint_num < eint->hw->ap_num; eint_num += 32,
 328             reg += 4) {
 329                status = readl(reg);
 330                while (status) {
 331                        offset = __ffs(status);
 332                        mask_offset = eint_num >> 5;
 333                        index = eint_num + offset;
 334                        status &= ~BIT(offset);
 335
 336                        /*
 337                         * If we get an interrupt on pin that was only required
 338                         * for wake (but no real interrupt requested), mask the
 339                         * interrupt (as would mtk_eint_resume do anyway later
 340                         * in the resume sequence).
 341                         */
 342                        if (eint->wake_mask[mask_offset] & BIT(offset) &&
 343                            !(eint->cur_mask[mask_offset] & BIT(offset))) {
 344                                writel_relaxed(BIT(offset), reg -
 345                                        eint->regs->stat +
 346                                        eint->regs->mask_set);
 347                        }
 348
 349                        dual_edge = eint->dual_edge[index];
 350                        if (dual_edge) {
 351                                /*
 352                                 * Clear soft-irq in case we raised it last
 353                                 * time.
 354                                 */
 355                                writel(BIT(offset), reg - eint->regs->stat +
 356                                       eint->regs->soft_clr);
 357
 358                                start_level =
 359                                eint->gpio_xlate->get_gpio_state(eint->pctl,
 360                                                                 index);
 361                        }
 362
 363                        generic_handle_domain_irq(eint->domain, index);
 364
 365                        if (dual_edge) {
 366                                curr_level = mtk_eint_flip_edge(eint, index);
 367
 368                                /*
 369                                 * If level changed, we might lost one edge
 370                                 * interrupt, raised it through soft-irq.
 371                                 */
 372                                if (start_level != curr_level)
 373                                        writel(BIT(offset), reg -
 374                                               eint->regs->stat +
 375                                               eint->regs->soft_set);
 376                        }
 377
 378                        if (index < eint->hw->db_cnt)
 379                                mtk_eint_debounce_process(eint, index);
 380                }
 381        }
 382        chained_irq_exit(chip, desc);
 383}
 384
 385int mtk_eint_do_suspend(struct mtk_eint *eint)
 386{
 387        mtk_eint_chip_write_mask(eint, eint->base, eint->wake_mask);
 388
 389        return 0;
 390}
 391EXPORT_SYMBOL_GPL(mtk_eint_do_suspend);
 392
 393int mtk_eint_do_resume(struct mtk_eint *eint)
 394{
 395        mtk_eint_chip_write_mask(eint, eint->base, eint->cur_mask);
 396
 397        return 0;
 398}
 399EXPORT_SYMBOL_GPL(mtk_eint_do_resume);
 400
 401int mtk_eint_set_debounce(struct mtk_eint *eint, unsigned long eint_num,
 402                          unsigned int debounce)
 403{
 404        int virq, eint_offset;
 405        unsigned int set_offset, bit, clr_bit, clr_offset, rst, i, unmask,
 406                     dbnc;
 407        static const unsigned int debounce_time[] = {500, 1000, 16000, 32000,
 408                                                     64000, 128000, 256000};
 409        struct irq_data *d;
 410
 411        virq = irq_find_mapping(eint->domain, eint_num);
 412        eint_offset = (eint_num % 4) * 8;
 413        d = irq_get_irq_data(virq);
 414
 415        set_offset = (eint_num / 4) * 4 + eint->regs->dbnc_set;
 416        clr_offset = (eint_num / 4) * 4 + eint->regs->dbnc_clr;
 417
 418        if (!mtk_eint_can_en_debounce(eint, eint_num))
 419                return -EINVAL;
 420
 421        dbnc = ARRAY_SIZE(debounce_time);
 422        for (i = 0; i < ARRAY_SIZE(debounce_time); i++) {
 423                if (debounce <= debounce_time[i]) {
 424                        dbnc = i;
 425                        break;
 426                }
 427        }
 428
 429        if (!mtk_eint_get_mask(eint, eint_num)) {
 430                mtk_eint_mask(d);
 431                unmask = 1;
 432        } else {
 433                unmask = 0;
 434        }
 435
 436        clr_bit = 0xff << eint_offset;
 437        writel(clr_bit, eint->base + clr_offset);
 438
 439        bit = ((dbnc << MTK_EINT_DBNC_SET_DBNC_BITS) | MTK_EINT_DBNC_SET_EN) <<
 440                eint_offset;
 441        rst = MTK_EINT_DBNC_RST_BIT << eint_offset;
 442        writel(rst | bit, eint->base + set_offset);
 443
 444        /*
 445         * Delay a while (more than 2T) to wait for hw debounce counter reset
 446         * work correctly.
 447         */
 448        udelay(1);
 449        if (unmask == 1)
 450                mtk_eint_unmask(d);
 451
 452        return 0;
 453}
 454EXPORT_SYMBOL_GPL(mtk_eint_set_debounce);
 455
 456int mtk_eint_find_irq(struct mtk_eint *eint, unsigned long eint_n)
 457{
 458        int irq;
 459
 460        irq = irq_find_mapping(eint->domain, eint_n);
 461        if (!irq)
 462                return -EINVAL;
 463
 464        return irq;
 465}
 466EXPORT_SYMBOL_GPL(mtk_eint_find_irq);
 467
 468int mtk_eint_do_init(struct mtk_eint *eint)
 469{
 470        int i;
 471
 472        /* If clients don't assign a specific regs, let's use generic one */
 473        if (!eint->regs)
 474                eint->regs = &mtk_generic_eint_regs;
 475
 476        eint->wake_mask = devm_kcalloc(eint->dev, eint->hw->ports,
 477                                       sizeof(*eint->wake_mask), GFP_KERNEL);
 478        if (!eint->wake_mask)
 479                return -ENOMEM;
 480
 481        eint->cur_mask = devm_kcalloc(eint->dev, eint->hw->ports,
 482                                      sizeof(*eint->cur_mask), GFP_KERNEL);
 483        if (!eint->cur_mask)
 484                return -ENOMEM;
 485
 486        eint->dual_edge = devm_kcalloc(eint->dev, eint->hw->ap_num,
 487                                       sizeof(int), GFP_KERNEL);
 488        if (!eint->dual_edge)
 489                return -ENOMEM;
 490
 491        eint->domain = irq_domain_add_linear(eint->dev->of_node,
 492                                             eint->hw->ap_num,
 493                                             &irq_domain_simple_ops, NULL);
 494        if (!eint->domain)
 495                return -ENOMEM;
 496
 497        mtk_eint_hw_init(eint);
 498        for (i = 0; i < eint->hw->ap_num; i++) {
 499                int virq = irq_create_mapping(eint->domain, i);
 500
 501                irq_set_chip_and_handler(virq, &mtk_eint_irq_chip,
 502                                         handle_level_irq);
 503                irq_set_chip_data(virq, eint);
 504        }
 505
 506        irq_set_chained_handler_and_data(eint->irq, mtk_eint_irq_handler,
 507                                         eint);
 508
 509        return 0;
 510}
 511EXPORT_SYMBOL_GPL(mtk_eint_do_init);
 512
 513MODULE_LICENSE("GPL v2");
 514MODULE_DESCRIPTION("MediaTek EINT Driver");
 515