aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSean Wang <sean.wang@mediatek.com>2018-05-20 13:01:48 -0400
committerLinus Walleij <linus.walleij@linaro.org>2018-05-24 03:37:21 -0400
commite46df235b4e605aa4e7609a27c118a1cccd4ff9a (patch)
tree9af4bf24920c267f5ff6bd0e99aa2a8272bfcd45
parent6ee6fbde42f41fda10b610f81bbba7b3afea513f (diff)
pinctrl: mediatek: refactor EINT related code for all MediaTek pinctrl can fit
This patch is in preparation for adding EINT support to MT7622 pinctrl, and the refactoring doesn't alter any existent logic. A reason we have to refactor EINT code pieces into a generic way is that currently, they're tightly coupled with a certain type of MediaTek pinctrl would cause a grown in a very bad way as there is different types of pinctrl devices getting to join. Therefore, it is an essential or urgent thing that EINT code pieces are refactored to eliminate any dependencies across GPIO and EINT as possible. Additional structure mtk_eint_[xt, hw, regs] are being introduced for indicating how maps being designed between GPIO and EINT hw number, how to set and get GPIO state for a certain EINT pin, what characteristic on a EINT device is present on various SoCs. Signed-off-by: Sean Wang <sean.wang@mediatek.com> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
-rw-r--r--drivers/pinctrl/mediatek/Kconfig6
-rw-r--r--drivers/pinctrl/mediatek/Makefile1
-rw-r--r--drivers/pinctrl/mediatek/mtk-eint.c492
-rw-r--r--drivers/pinctrl/mediatek/mtk-eint.h107
-rw-r--r--drivers/pinctrl/mediatek/pinctrl-mt2701.c12
-rw-r--r--drivers/pinctrl/mediatek/pinctrl-mt2712.c12
-rw-r--r--drivers/pinctrl/mediatek/pinctrl-mt8127.c12
-rw-r--r--drivers/pinctrl/mediatek/pinctrl-mt8135.c12
-rw-r--r--drivers/pinctrl/mediatek/pinctrl-mt8173.c12
-rw-r--r--drivers/pinctrl/mediatek/pinctrl-mtk-common.c604
-rw-r--r--drivers/pinctrl/mediatek/pinctrl-mtk-common.h13
11 files changed, 756 insertions, 527 deletions
diff --git a/drivers/pinctrl/mediatek/Kconfig b/drivers/pinctrl/mediatek/Kconfig
index 862c5dbc6977..310db425a94b 100644
--- a/drivers/pinctrl/mediatek/Kconfig
+++ b/drivers/pinctrl/mediatek/Kconfig
@@ -1,12 +1,18 @@
1menu "MediaTek pinctrl drivers" 1menu "MediaTek pinctrl drivers"
2 depends on ARCH_MEDIATEK || COMPILE_TEST 2 depends on ARCH_MEDIATEK || COMPILE_TEST
3 3
4config EINT_MTK
5 bool "MediaTek External Interrupt Support"
6 depends on PINCTRL_MTK || COMPILE_TEST
7 select IRQ_DOMAIN
8
4config PINCTRL_MTK 9config PINCTRL_MTK
5 bool 10 bool
6 depends on OF 11 depends on OF
7 select PINMUX 12 select PINMUX
8 select GENERIC_PINCONF 13 select GENERIC_PINCONF
9 select GPIOLIB 14 select GPIOLIB
15 select EINT_MTK
10 select OF_GPIO 16 select OF_GPIO
11 17
12# For ARMv7 SoCs 18# For ARMv7 SoCs
diff --git a/drivers/pinctrl/mediatek/Makefile b/drivers/pinctrl/mediatek/Makefile
index 7959e773533f..3de7156df345 100644
--- a/drivers/pinctrl/mediatek/Makefile
+++ b/drivers/pinctrl/mediatek/Makefile
@@ -1,5 +1,6 @@
1# SPDX-License-Identifier: GPL-2.0 1# SPDX-License-Identifier: GPL-2.0
2# Core 2# Core
3obj-$(CONFIG_EINT_MTK) += mtk-eint.o
3obj-$(CONFIG_PINCTRL_MTK) += pinctrl-mtk-common.o 4obj-$(CONFIG_PINCTRL_MTK) += pinctrl-mtk-common.o
4 5
5# SoC Drivers 6# SoC Drivers
diff --git a/drivers/pinctrl/mediatek/mtk-eint.c b/drivers/pinctrl/mediatek/mtk-eint.c
new file mode 100644
index 000000000000..30f3316747e2
--- /dev/null
+++ b/drivers/pinctrl/mediatek/mtk-eint.c
@@ -0,0 +1,492 @@
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.h>
15#include <linux/io.h>
16#include <linux/irqdomain.h>
17#include <linux/of_irq.h>
18#include <linux/platform_device.h>
19
20#include "mtk-eint.h"
21
22#define MTK_EINT_EDGE_SENSITIVE 0
23#define MTK_EINT_LEVEL_SENSITIVE 1
24#define MTK_EINT_DBNC_SET_DBNC_BITS 4
25#define MTK_EINT_DBNC_RST_BIT (0x1 << 1)
26#define MTK_EINT_DBNC_SET_EN (0x1 << 0)
27
28static const struct mtk_eint_regs mtk_generic_eint_regs = {
29 .stat = 0x000,
30 .ack = 0x040,
31 .mask = 0x080,
32 .mask_set = 0x0c0,
33 .mask_clr = 0x100,
34 .sens = 0x140,
35 .sens_set = 0x180,
36 .sens_clr = 0x1c0,
37 .soft = 0x200,
38 .soft_set = 0x240,
39 .soft_clr = 0x280,
40 .pol = 0x300,
41 .pol_set = 0x340,
42 .pol_clr = 0x380,
43 .dom_en = 0x400,
44 .dbnc_ctrl = 0x500,
45 .dbnc_set = 0x600,
46 .dbnc_clr = 0x700,
47};
48
49static void __iomem *mtk_eint_get_offset(struct mtk_eint *eint,
50 unsigned int eint_num,
51 unsigned int offset)
52{
53 unsigned int eint_base = 0;
54 void __iomem *reg;
55
56 if (eint_num >= eint->hw->ap_num)
57 eint_base = eint->hw->ap_num;
58
59 reg = eint->base + offset + ((eint_num - eint_base) / 32) * 4;
60
61 return reg;
62}
63
64static unsigned int mtk_eint_can_en_debounce(struct mtk_eint *eint,
65 unsigned int eint_num)
66{
67 unsigned int sens;
68 unsigned int bit = BIT(eint_num % 32);
69 void __iomem *reg = mtk_eint_get_offset(eint, eint_num,
70 eint->regs->sens);
71
72 if (readl(reg) & bit)
73 sens = MTK_EINT_LEVEL_SENSITIVE;
74 else
75 sens = MTK_EINT_EDGE_SENSITIVE;
76
77 if (eint_num < eint->hw->db_cnt && sens != MTK_EINT_EDGE_SENSITIVE)
78 return 1;
79 else
80 return 0;
81}
82
83static int mtk_eint_flip_edge(struct mtk_eint *eint, int hwirq)
84{
85 int start_level, curr_level;
86 unsigned int reg_offset;
87 u32 mask = BIT(hwirq & 0x1f);
88 u32 port = (hwirq >> 5) & eint->hw->port_mask;
89 void __iomem *reg = eint->base + (port << 2);
90
91 curr_level = eint->gpio_xlate->get_gpio_state(eint->pctl, hwirq);
92
93 do {
94 start_level = curr_level;
95 if (start_level)
96 reg_offset = eint->regs->pol_clr;
97 else
98 reg_offset = eint->regs->pol_set;
99 writel(mask, reg + reg_offset);
100
101 curr_level = eint->gpio_xlate->get_gpio_state(eint->pctl,
102 hwirq);
103 } while (start_level != curr_level);
104
105 return start_level;
106}
107
108static void mtk_eint_mask(struct irq_data *d)
109{
110 struct mtk_eint *eint = irq_data_get_irq_chip_data(d);
111 u32 mask = BIT(d->hwirq & 0x1f);
112 void __iomem *reg = mtk_eint_get_offset(eint, d->hwirq,
113 eint->regs->mask_set);
114
115 writel(mask, reg);
116}
117
118static void mtk_eint_unmask(struct irq_data *d)
119{
120 struct mtk_eint *eint = irq_data_get_irq_chip_data(d);
121 u32 mask = BIT(d->hwirq & 0x1f);
122 void __iomem *reg = mtk_eint_get_offset(eint, d->hwirq,
123 eint->regs->mask_clr);
124
125 writel(mask, reg);
126
127 if (eint->dual_edge[d->hwirq])
128 mtk_eint_flip_edge(eint, d->hwirq);
129}
130
131static unsigned int mtk_eint_get_mask(struct mtk_eint *eint,
132 unsigned int eint_num)
133{
134 unsigned int bit = BIT(eint_num % 32);
135 void __iomem *reg = mtk_eint_get_offset(eint, eint_num,
136 eint->regs->mask);
137
138 return !!(readl(reg) & bit);
139}
140
141static void mtk_eint_ack(struct irq_data *d)
142{
143 struct mtk_eint *eint = irq_data_get_irq_chip_data(d);
144 u32 mask = BIT(d->hwirq & 0x1f);
145 void __iomem *reg = mtk_eint_get_offset(eint, d->hwirq,
146 eint->regs->ack);
147
148 writel(mask, reg);
149}
150
151static int mtk_eint_set_type(struct irq_data *d, unsigned int type)
152{
153 struct mtk_eint *eint = irq_data_get_irq_chip_data(d);
154 u32 mask = BIT(d->hwirq & 0x1f);
155 void __iomem *reg;
156
157 if (((type & IRQ_TYPE_EDGE_BOTH) && (type & IRQ_TYPE_LEVEL_MASK)) ||
158 ((type & IRQ_TYPE_LEVEL_MASK) == IRQ_TYPE_LEVEL_MASK)) {
159 dev_err(eint->dev,
160 "Can't configure IRQ%d (EINT%lu) for type 0x%X\n",
161 d->irq, d->hwirq, type);
162 return -EINVAL;
163 }
164
165 if ((type & IRQ_TYPE_EDGE_BOTH) == IRQ_TYPE_EDGE_BOTH)
166 eint->dual_edge[d->hwirq] = 1;
167 else
168 eint->dual_edge[d->hwirq] = 0;
169
170 if (type & (IRQ_TYPE_LEVEL_LOW | IRQ_TYPE_EDGE_FALLING)) {
171 reg = mtk_eint_get_offset(eint, d->hwirq, eint->regs->pol_clr);
172 writel(mask, reg);
173 } else {
174 reg = mtk_eint_get_offset(eint, d->hwirq, eint->regs->pol_set);
175 writel(mask, reg);
176 }
177
178 if (type & (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING)) {
179 reg = mtk_eint_get_offset(eint, d->hwirq, eint->regs->sens_clr);
180 writel(mask, reg);
181 } else {
182 reg = mtk_eint_get_offset(eint, d->hwirq, eint->regs->sens_set);
183 writel(mask, reg);
184 }
185
186 if (eint->dual_edge[d->hwirq])
187 mtk_eint_flip_edge(eint, d->hwirq);
188
189 return 0;
190}
191
192static int mtk_eint_irq_set_wake(struct irq_data *d, unsigned int on)
193{
194 struct mtk_eint *eint = irq_data_get_irq_chip_data(d);
195 int shift = d->hwirq & 0x1f;
196 int reg = d->hwirq >> 5;
197
198 if (on)
199 eint->wake_mask[reg] |= BIT(shift);
200 else
201 eint->wake_mask[reg] &= ~BIT(shift);
202
203 return 0;
204}
205
206static void mtk_eint_chip_write_mask(const struct mtk_eint *eint,
207 void __iomem *base, u32 *buf)
208{
209 int port;
210 void __iomem *reg;
211
212 for (port = 0; port < eint->hw->ports; port++) {
213 reg = base + (port << 2);
214 writel_relaxed(~buf[port], reg + eint->regs->mask_set);
215 writel_relaxed(buf[port], reg + eint->regs->mask_clr);
216 }
217}
218
219static void mtk_eint_chip_read_mask(const struct mtk_eint *eint,
220 void __iomem *base, u32 *buf)
221{
222 int port;
223 void __iomem *reg;
224
225 for (port = 0; port < eint->hw->ports; port++) {
226 reg = base + eint->regs->mask + (port << 2);
227 buf[port] = ~readl_relaxed(reg);
228 /* Mask is 0 when irq is enabled, and 1 when disabled. */
229 }
230}
231
232static int mtk_eint_irq_request_resources(struct irq_data *d)
233{
234 struct mtk_eint *eint = irq_data_get_irq_chip_data(d);
235 struct gpio_chip *gpio_c;
236 unsigned int gpio_n;
237 int err;
238
239 err = eint->gpio_xlate->get_gpio_n(eint->pctl, d->hwirq,
240 &gpio_n, &gpio_c);
241 if (err < 0) {
242 dev_err(eint->dev, "Can not find pin\n");
243 return err;
244 }
245
246 err = gpiochip_lock_as_irq(gpio_c, gpio_n);
247 if (err < 0) {
248 dev_err(eint->dev, "unable to lock HW IRQ %lu for IRQ\n",
249 irqd_to_hwirq(d));
250 return err;
251 }
252
253 err = eint->gpio_xlate->set_gpio_as_eint(eint->pctl, d->hwirq);
254 if (err < 0) {
255 dev_err(eint->dev, "Can not eint mode\n");
256 return err;
257 }
258
259 return 0;
260}
261
262static void mtk_eint_irq_release_resources(struct irq_data *d)
263{
264 struct mtk_eint *eint = irq_data_get_irq_chip_data(d);
265 struct gpio_chip *gpio_c;
266 unsigned int gpio_n;
267
268 eint->gpio_xlate->get_gpio_n(eint->pctl, d->hwirq, &gpio_n,
269 &gpio_c);
270
271 gpiochip_unlock_as_irq(gpio_c, gpio_n);
272}
273
274static struct irq_chip mtk_eint_irq_chip = {
275 .name = "mt-eint",
276 .irq_disable = mtk_eint_mask,
277 .irq_mask = mtk_eint_mask,
278 .irq_unmask = mtk_eint_unmask,
279 .irq_ack = mtk_eint_ack,
280 .irq_set_type = mtk_eint_set_type,
281 .irq_set_wake = mtk_eint_irq_set_wake,
282 .irq_request_resources = mtk_eint_irq_request_resources,
283 .irq_release_resources = mtk_eint_irq_release_resources,
284};
285
286static unsigned int mtk_eint_hw_init(struct mtk_eint *eint)
287{
288 void __iomem *reg = eint->base + eint->regs->dom_en;
289 unsigned int i;
290
291 for (i = 0; i < eint->hw->ap_num; i += 32) {
292 writel(0xffffffff, reg);
293 reg += 4;
294 }
295
296 return 0;
297}
298
299static inline void
300mtk_eint_debounce_process(struct mtk_eint *eint, int index)
301{
302 unsigned int rst, ctrl_offset;
303 unsigned int bit, dbnc;
304
305 ctrl_offset = (index / 4) * 4 + eint->regs->dbnc_ctrl;
306 dbnc = readl(eint->base + ctrl_offset);
307 bit = MTK_EINT_DBNC_SET_EN << ((index % 4) * 8);
308 if ((bit & dbnc) > 0) {
309 ctrl_offset = (index / 4) * 4 + eint->regs->dbnc_set;
310 rst = MTK_EINT_DBNC_RST_BIT << ((index % 4) * 8);
311 writel(rst, eint->base + ctrl_offset);
312 }
313}
314
315static void mtk_eint_irq_handler(struct irq_desc *desc)
316{
317 struct irq_chip *chip = irq_desc_get_chip(desc);
318 struct mtk_eint *eint = irq_desc_get_handler_data(desc);
319 unsigned int status, eint_num;
320 int offset, index, virq;
321 void __iomem *reg = mtk_eint_get_offset(eint, 0, eint->regs->stat);
322 int dual_edge, start_level, curr_level;
323
324 chained_irq_enter(chip, desc);
325 for (eint_num = 0; eint_num < eint->hw->ap_num; eint_num += 32,
326 reg += 4) {
327 status = readl(reg);
328 while (status) {
329 offset = __ffs(status);
330 index = eint_num + offset;
331 virq = irq_find_mapping(eint->domain, index);
332 status &= ~BIT(offset);
333
334 dual_edge = eint->dual_edge[index];
335 if (dual_edge) {
336 /*
337 * Clear soft-irq in case we raised it last
338 * time.
339 */
340 writel(BIT(offset), reg - eint->regs->stat +
341 eint->regs->soft_clr);
342
343 start_level =
344 eint->gpio_xlate->get_gpio_state(eint->pctl,
345 index);
346 }
347
348 generic_handle_irq(virq);
349
350 if (dual_edge) {
351 curr_level = mtk_eint_flip_edge(eint, index);
352
353 /*
354 * If level changed, we might lost one edge
355 * interrupt, raised it through soft-irq.
356 */
357 if (start_level != curr_level)
358 writel(BIT(offset), reg -
359 eint->regs->stat +
360 eint->regs->soft_set);
361 }
362
363 if (index < eint->hw->db_cnt)
364 mtk_eint_debounce_process(eint, index);
365 }
366 }
367 chained_irq_exit(chip, desc);
368}
369
370int mtk_eint_do_suspend(struct mtk_eint *eint)
371{
372 mtk_eint_chip_read_mask(eint, eint->base, eint->cur_mask);
373 mtk_eint_chip_write_mask(eint, eint->base, eint->wake_mask);
374
375 return 0;
376}
377
378int mtk_eint_do_resume(struct mtk_eint *eint)
379{
380 mtk_eint_chip_write_mask(eint, eint->base, eint->cur_mask);
381
382 return 0;
383}
384
385int mtk_eint_set_debounce(struct mtk_eint *eint, unsigned long eint_num,
386 unsigned int debounce)
387{
388 int virq, eint_offset;
389 unsigned int set_offset, bit, clr_bit, clr_offset, rst, i, unmask,
390 dbnc;
391 static const unsigned int debounce_time[] = {500, 1000, 16000, 32000,
392 64000, 128000, 256000};
393 struct irq_data *d;
394
395 virq = irq_find_mapping(eint->domain, eint_num);
396 eint_offset = (eint_num % 4) * 8;
397 d = irq_get_irq_data(virq);
398
399 set_offset = (eint_num / 4) * 4 + eint->regs->dbnc_set;
400 clr_offset = (eint_num / 4) * 4 + eint->regs->dbnc_clr;
401
402 if (!mtk_eint_can_en_debounce(eint, eint_num))
403 return -EINVAL;
404
405 dbnc = ARRAY_SIZE(debounce_time);
406 for (i = 0; i < ARRAY_SIZE(debounce_time); i++) {
407 if (debounce <= debounce_time[i]) {
408 dbnc = i;
409 break;
410 }
411 }
412
413 if (!mtk_eint_get_mask(eint, eint_num)) {
414 mtk_eint_mask(d);
415 unmask = 1;
416 } else {
417 unmask = 0;
418 }
419
420 clr_bit = 0xff << eint_offset;
421 writel(clr_bit, eint->base + clr_offset);
422
423 bit = ((dbnc << MTK_EINT_DBNC_SET_DBNC_BITS) | MTK_EINT_DBNC_SET_EN) <<
424 eint_offset;
425 rst = MTK_EINT_DBNC_RST_BIT << eint_offset;
426 writel(rst | bit, eint->base + set_offset);
427
428 /*
429 * Delay a while (more than 2T) to wait for hw debounce counter reset
430 * work correctly.
431 */
432 udelay(1);
433 if (unmask == 1)
434 mtk_eint_unmask(d);
435
436 return 0;
437}
438
439int mtk_eint_find_irq(struct mtk_eint *eint, unsigned long eint_n)
440{
441 int irq;
442
443 irq = irq_find_mapping(eint->domain, eint_n);
444 if (!irq)
445 return -EINVAL;
446
447 return irq;
448}
449
450int mtk_eint_do_init(struct mtk_eint *eint)
451{
452 int i;
453
454 /* If clients don't assign a specific regs, let's use generic one */
455 if (!eint->regs)
456 eint->regs = &mtk_generic_eint_regs;
457
458 eint->wake_mask = devm_kcalloc(eint->dev, eint->hw->ports,
459 sizeof(*eint->wake_mask), GFP_KERNEL);
460 if (!eint->wake_mask)
461 return -ENOMEM;
462
463 eint->cur_mask = devm_kcalloc(eint->dev, eint->hw->ports,
464 sizeof(*eint->cur_mask), GFP_KERNEL);
465 if (!eint->cur_mask)
466 return -ENOMEM;
467
468 eint->dual_edge = devm_kcalloc(eint->dev, eint->hw->ap_num,
469 sizeof(int), GFP_KERNEL);
470 if (!eint->dual_edge)
471 return -ENOMEM;
472
473 eint->domain = irq_domain_add_linear(eint->dev->of_node,
474 eint->hw->ap_num,
475 &irq_domain_simple_ops, NULL);
476 if (!eint->domain)
477 return -ENOMEM;
478
479 mtk_eint_hw_init(eint);
480 for (i = 0; i < eint->hw->ap_num; i++) {
481 int virq = irq_create_mapping(eint->domain, i);
482
483 irq_set_chip_and_handler(virq, &mtk_eint_irq_chip,
484 handle_level_irq);
485 irq_set_chip_data(virq, eint);
486 }
487
488 irq_set_chained_handler_and_data(eint->irq, mtk_eint_irq_handler,
489 eint);
490
491 return 0;
492}
diff --git a/drivers/pinctrl/mediatek/mtk-eint.h b/drivers/pinctrl/mediatek/mtk-eint.h
new file mode 100644
index 000000000000..55b4d5f47e77
--- /dev/null
+++ b/drivers/pinctrl/mediatek/mtk-eint.h
@@ -0,0 +1,107 @@
1/* SPDX-License-Identifier: GPL-2.0 */
2/*
3 * Copyright (C) 2014-2018 MediaTek Inc.
4 *
5 * Author: Maoguang Meng <maoguang.meng@mediatek.com>
6 * Sean Wang <sean.wang@mediatek.com>
7 *
8 */
9#ifndef __MTK_EINT_H
10#define __MTK_EINT_H
11
12#include <linux/irqdomain.h>
13
14struct mtk_eint_regs {
15 unsigned int stat;
16 unsigned int ack;
17 unsigned int mask;
18 unsigned int mask_set;
19 unsigned int mask_clr;
20 unsigned int sens;
21 unsigned int sens_set;
22 unsigned int sens_clr;
23 unsigned int soft;
24 unsigned int soft_set;
25 unsigned int soft_clr;
26 unsigned int pol;
27 unsigned int pol_set;
28 unsigned int pol_clr;
29 unsigned int dom_en;
30 unsigned int dbnc_ctrl;
31 unsigned int dbnc_set;
32 unsigned int dbnc_clr;
33};
34
35struct mtk_eint_hw {
36 const char *name;
37 u8 port_mask;
38 u8 ports;
39 unsigned int ap_num;
40 unsigned int db_cnt;
41};
42
43struct mtk_eint;
44
45struct mtk_eint_xt {
46 int (*get_gpio_n)(void *data, unsigned long eint_n,
47 unsigned int *gpio_n,
48 struct gpio_chip **gpio_chip);
49 int (*get_gpio_state)(void *data, unsigned long eint_n);
50 int (*set_gpio_as_eint)(void *data, unsigned long eint_n);
51};
52
53struct mtk_eint {
54 struct device *dev;
55 void __iomem *base;
56 struct irq_domain *domain;
57 int irq;
58
59 int *dual_edge;
60 u32 *wake_mask;
61 u32 *cur_mask;
62
63 /* Used to fit into various EINT device */
64 const struct mtk_eint_hw *hw;
65 const struct mtk_eint_regs *regs;
66
67 /* Used to fit into various pinctrl device */
68 void *pctl;
69 const struct mtk_eint_xt *gpio_xlate;
70};
71
72#if IS_ENABLED(CONFIG_EINT_MTK)
73int mtk_eint_do_init(struct mtk_eint *eint);
74int mtk_eint_do_suspend(struct mtk_eint *eint);
75int mtk_eint_do_resume(struct mtk_eint *eint);
76int mtk_eint_set_debounce(struct mtk_eint *eint, unsigned long eint_n,
77 unsigned int debounce);
78int mtk_eint_find_irq(struct mtk_eint *eint, unsigned long eint_n);
79
80#else
81static inline int mtk_eint_do_init(struct mtk_eint *eint)
82{
83 return -EOPNOTSUPP;
84}
85
86static inline int mtk_eint_do_suspend(struct mtk_eint *eint)
87{
88 return -EOPNOTSUPP;
89}
90
91static inline int mtk_eint_do_resume(struct mtk_eint *eint)
92{
93 return -EOPNOTSUPP;
94}
95
96int mtk_eint_set_debounce(struct mtk_eint *eint, unsigned long eint_n,
97 unsigned int debounce)
98{
99 return -EOPNOTSUPP;
100}
101
102int mtk_eint_find_irq(struct mtk_eint *eint, unsigned long eint_n)
103{
104 return -EOPNOTSUPP;
105}
106#endif
107#endif /* __MTK_EINT_H */
diff --git a/drivers/pinctrl/mediatek/pinctrl-mt2701.c b/drivers/pinctrl/mediatek/pinctrl-mt2701.c
index f86f3b379607..e0963c615686 100644
--- a/drivers/pinctrl/mediatek/pinctrl-mt2701.c
+++ b/drivers/pinctrl/mediatek/pinctrl-mt2701.c
@@ -531,8 +531,14 @@ static const struct mtk_pinctrl_devdata mt2701_pinctrl_data = {
531 .port_shf = 4, 531 .port_shf = 4,
532 .port_mask = 0x1f, 532 .port_mask = 0x1f,
533 .port_align = 4, 533 .port_align = 4,
534 .eint_offsets = { 534 .eint_hw = {
535 .name = "mt2701_eint", 535 .name = "mt2701_eint",
536 .port_mask = 6,
537 .ports = 6,
538 .ap_num = 169,
539 .db_cnt = 16,
540 },
541 .eint_regs = {
536 .stat = 0x000, 542 .stat = 0x000,
537 .ack = 0x040, 543 .ack = 0x040,
538 .mask = 0x080, 544 .mask = 0x080,
@@ -551,11 +557,7 @@ static const struct mtk_pinctrl_devdata mt2701_pinctrl_data = {
551 .dbnc_ctrl = 0x500, 557 .dbnc_ctrl = 0x500,
552 .dbnc_set = 0x600, 558 .dbnc_set = 0x600,
553 .dbnc_clr = 0x700, 559 .dbnc_clr = 0x700,
554 .port_mask = 6,
555 .ports = 6,
556 }, 560 },
557 .ap_num = 169,
558 .db_cnt = 16,
559}; 561};
560 562
561static int mt2701_pinctrl_probe(struct platform_device *pdev) 563static int mt2701_pinctrl_probe(struct platform_device *pdev)
diff --git a/drivers/pinctrl/mediatek/pinctrl-mt2712.c b/drivers/pinctrl/mediatek/pinctrl-mt2712.c
index 81e11f9e70f1..02aff2802224 100644
--- a/drivers/pinctrl/mediatek/pinctrl-mt2712.c
+++ b/drivers/pinctrl/mediatek/pinctrl-mt2712.c
@@ -576,8 +576,14 @@ static const struct mtk_pinctrl_devdata mt2712_pinctrl_data = {
576 .port_shf = 4, 576 .port_shf = 4,
577 .port_mask = 0xf, 577 .port_mask = 0xf,
578 .port_align = 4, 578 .port_align = 4,
579 .eint_offsets = { 579 .eint_hw = {
580 .name = "mt2712_eint", 580 .name = "mt2712_eint",
581 .port_mask = 0xf,
582 .ports = 8,
583 .ap_num = 229,
584 .db_cnt = 40,
585 },
586 .eint_regs = {
581 .stat = 0x000, 587 .stat = 0x000,
582 .ack = 0x040, 588 .ack = 0x040,
583 .mask = 0x080, 589 .mask = 0x080,
@@ -596,11 +602,7 @@ static const struct mtk_pinctrl_devdata mt2712_pinctrl_data = {
596 .dbnc_ctrl = 0x500, 602 .dbnc_ctrl = 0x500,
597 .dbnc_set = 0x600, 603 .dbnc_set = 0x600,
598 .dbnc_clr = 0x700, 604 .dbnc_clr = 0x700,
599 .port_mask = 0xf,
600 .ports = 8,
601 }, 605 },
602 .ap_num = 229,
603 .db_cnt = 40,
604}; 606};
605 607
606static int mt2712_pinctrl_probe(struct platform_device *pdev) 608static int mt2712_pinctrl_probe(struct platform_device *pdev)
diff --git a/drivers/pinctrl/mediatek/pinctrl-mt8127.c b/drivers/pinctrl/mediatek/pinctrl-mt8127.c
index d76491574841..71f6258ea96c 100644
--- a/drivers/pinctrl/mediatek/pinctrl-mt8127.c
+++ b/drivers/pinctrl/mediatek/pinctrl-mt8127.c
@@ -300,8 +300,14 @@ static const struct mtk_pinctrl_devdata mt8127_pinctrl_data = {
300 .port_shf = 4, 300 .port_shf = 4,
301 .port_mask = 0xf, 301 .port_mask = 0xf,
302 .port_align = 4, 302 .port_align = 4,
303 .eint_offsets = { 303 .eint_hw = {
304 .name = "mt8127_eint", 304 .name = "mt8127_eint",
305 .port_mask = 7,
306 .ports = 6,
307 .ap_num = 143,
308 .db_cnt = 16,
309 },
310 .eint_regs = {
305 .stat = 0x000, 311 .stat = 0x000,
306 .ack = 0x040, 312 .ack = 0x040,
307 .mask = 0x080, 313 .mask = 0x080,
@@ -320,11 +326,7 @@ static const struct mtk_pinctrl_devdata mt8127_pinctrl_data = {
320 .dbnc_ctrl = 0x500, 326 .dbnc_ctrl = 0x500,
321 .dbnc_set = 0x600, 327 .dbnc_set = 0x600,
322 .dbnc_clr = 0x700, 328 .dbnc_clr = 0x700,
323 .port_mask = 7,
324 .ports = 6,
325 }, 329 },
326 .ap_num = 143,
327 .db_cnt = 16,
328}; 330};
329 331
330static int mt8127_pinctrl_probe(struct platform_device *pdev) 332static int mt8127_pinctrl_probe(struct platform_device *pdev)
diff --git a/drivers/pinctrl/mediatek/pinctrl-mt8135.c b/drivers/pinctrl/mediatek/pinctrl-mt8135.c
index d8c645f16f21..fdfa357d681f 100644
--- a/drivers/pinctrl/mediatek/pinctrl-mt8135.c
+++ b/drivers/pinctrl/mediatek/pinctrl-mt8135.c
@@ -313,8 +313,14 @@ static const struct mtk_pinctrl_devdata mt8135_pinctrl_data = {
313 .port_shf = 4, 313 .port_shf = 4,
314 .port_mask = 0xf, 314 .port_mask = 0xf,
315 .port_align = 4, 315 .port_align = 4,
316 .eint_offsets = { 316 .eint_hw = {
317 .name = "mt8135_eint", 317 .name = "mt8135_eint",
318 .port_mask = 7,
319 .ports = 6,
320 .ap_num = 192,
321 .db_cnt = 16,
322 },
323 .eint_regs = {
318 .stat = 0x000, 324 .stat = 0x000,
319 .ack = 0x040, 325 .ack = 0x040,
320 .mask = 0x080, 326 .mask = 0x080,
@@ -333,11 +339,7 @@ static const struct mtk_pinctrl_devdata mt8135_pinctrl_data = {
333 .dbnc_ctrl = 0x500, 339 .dbnc_ctrl = 0x500,
334 .dbnc_set = 0x600, 340 .dbnc_set = 0x600,
335 .dbnc_clr = 0x700, 341 .dbnc_clr = 0x700,
336 .port_mask = 7,
337 .ports = 6,
338 }, 342 },
339 .ap_num = 192,
340 .db_cnt = 16,
341}; 343};
342 344
343static int mt8135_pinctrl_probe(struct platform_device *pdev) 345static int mt8135_pinctrl_probe(struct platform_device *pdev)
diff --git a/drivers/pinctrl/mediatek/pinctrl-mt8173.c b/drivers/pinctrl/mediatek/pinctrl-mt8173.c
index 8bfd427b9135..1466c95fde87 100644
--- a/drivers/pinctrl/mediatek/pinctrl-mt8173.c
+++ b/drivers/pinctrl/mediatek/pinctrl-mt8173.c
@@ -340,8 +340,14 @@ static const struct mtk_pinctrl_devdata mt8173_pinctrl_data = {
340 .port_shf = 4, 340 .port_shf = 4,
341 .port_mask = 0xf, 341 .port_mask = 0xf,
342 .port_align = 4, 342 .port_align = 4,
343 .eint_offsets = { 343 .eint_hw = {
344 .name = "mt8173_eint", 344 .name = "mt8173_eint",
345 .port_mask = 7,
346 .ports = 6,
347 .ap_num = 224,
348 .db_cnt = 16,
349 },
350 .eint_regs = {
345 .stat = 0x000, 351 .stat = 0x000,
346 .ack = 0x040, 352 .ack = 0x040,
347 .mask = 0x080, 353 .mask = 0x080,
@@ -360,11 +366,7 @@ static const struct mtk_pinctrl_devdata mt8173_pinctrl_data = {
360 .dbnc_ctrl = 0x500, 366 .dbnc_ctrl = 0x500,
361 .dbnc_set = 0x600, 367 .dbnc_set = 0x600,
362 .dbnc_clr = 0x700, 368 .dbnc_clr = 0x700,
363 .port_mask = 7,
364 .ports = 6,
365 }, 369 },
366 .ap_num = 224,
367 .db_cnt = 16,
368}; 370};
369 371
370static int mt8173_pinctrl_probe(struct platform_device *pdev) 372static int mt8173_pinctrl_probe(struct platform_device *pdev)
diff --git a/drivers/pinctrl/mediatek/pinctrl-mtk-common.c b/drivers/pinctrl/mediatek/pinctrl-mtk-common.c
index c3975a04d1cd..11e0d0fdf43b 100644
--- a/drivers/pinctrl/mediatek/pinctrl-mtk-common.c
+++ b/drivers/pinctrl/mediatek/pinctrl-mtk-common.c
@@ -38,6 +38,7 @@
38#include "../core.h" 38#include "../core.h"
39#include "../pinconf.h" 39#include "../pinconf.h"
40#include "../pinctrl-utils.h" 40#include "../pinctrl-utils.h"
41#include "mtk-eint.h"
41#include "pinctrl-mtk-common.h" 42#include "pinctrl-mtk-common.h"
42 43
43#define MAX_GPIO_MODE_PER_REG 5 44#define MAX_GPIO_MODE_PER_REG 5
@@ -831,243 +832,38 @@ static int mtk_gpio_get(struct gpio_chip *chip, unsigned offset)
831 832
832static int mtk_gpio_to_irq(struct gpio_chip *chip, unsigned offset) 833static int mtk_gpio_to_irq(struct gpio_chip *chip, unsigned offset)
833{ 834{
834 const struct mtk_desc_pin *pin;
835 struct mtk_pinctrl *pctl = gpiochip_get_data(chip); 835 struct mtk_pinctrl *pctl = gpiochip_get_data(chip);
836 int irq;
837
838 pin = pctl->devdata->pins + offset;
839 if (pin->eint.eintnum == NO_EINT_SUPPORT)
840 return -EINVAL;
841
842 irq = irq_find_mapping(pctl->domain, pin->eint.eintnum);
843 if (!irq)
844 return -EINVAL;
845
846 return irq;
847}
848
849static int mtk_pinctrl_irq_request_resources(struct irq_data *d)
850{
851 struct mtk_pinctrl *pctl = irq_data_get_irq_chip_data(d);
852 const struct mtk_desc_pin *pin;
853 int ret;
854
855 pin = mtk_find_pin_by_eint_num(pctl, d->hwirq);
856
857 if (!pin) {
858 dev_err(pctl->dev, "Can not find pin\n");
859 return -EINVAL;
860 }
861
862 ret = gpiochip_lock_as_irq(pctl->chip, pin->pin.number);
863 if (ret) {
864 dev_err(pctl->dev, "unable to lock HW IRQ %lu for IRQ\n",
865 irqd_to_hwirq(d));
866 return ret;
867 }
868
869 /* set mux to INT mode */
870 mtk_pmx_set_mode(pctl->pctl_dev, pin->pin.number, pin->eint.eintmux);
871 /* set gpio direction to input */
872 mtk_pmx_gpio_set_direction(pctl->pctl_dev, NULL, pin->pin.number, true);
873 /* set input-enable */
874 mtk_pconf_set_ies_smt(pctl, pin->pin.number, 1, PIN_CONFIG_INPUT_ENABLE);
875
876 return 0;
877}
878
879static void mtk_pinctrl_irq_release_resources(struct irq_data *d)
880{
881 struct mtk_pinctrl *pctl = irq_data_get_irq_chip_data(d);
882 const struct mtk_desc_pin *pin;
883
884 pin = mtk_find_pin_by_eint_num(pctl, d->hwirq);
885
886 if (!pin) {
887 dev_err(pctl->dev, "Can not find pin\n");
888 return;
889 }
890
891 gpiochip_unlock_as_irq(pctl->chip, pin->pin.number);
892}
893
894static void __iomem *mtk_eint_get_offset(struct mtk_pinctrl *pctl,
895 unsigned int eint_num, unsigned int offset)
896{
897 unsigned int eint_base = 0;
898 void __iomem *reg;
899
900 if (eint_num >= pctl->devdata->ap_num)
901 eint_base = pctl->devdata->ap_num;
902
903 reg = pctl->eint_reg_base + offset + ((eint_num - eint_base) / 32) * 4;
904
905 return reg;
906}
907
908/*
909 * mtk_can_en_debounce: Check the EINT number is able to enable debounce or not
910 * @eint_num: the EINT number to setmtk_pinctrl
911 */
912static unsigned int mtk_eint_can_en_debounce(struct mtk_pinctrl *pctl,
913 unsigned int eint_num)
914{
915 unsigned int sens;
916 unsigned int bit = BIT(eint_num % 32);
917 const struct mtk_eint_offsets *eint_offsets =
918 &pctl->devdata->eint_offsets;
919
920 void __iomem *reg = mtk_eint_get_offset(pctl, eint_num,
921 eint_offsets->sens);
922
923 if (readl(reg) & bit)
924 sens = MT_LEVEL_SENSITIVE;
925 else
926 sens = MT_EDGE_SENSITIVE;
927
928 if ((eint_num < pctl->devdata->db_cnt) && (sens != MT_EDGE_SENSITIVE))
929 return 1;
930 else
931 return 0;
932}
933
934/*
935 * mtk_eint_get_mask: To get the eint mask
936 * @eint_num: the EINT number to get
937 */
938static unsigned int mtk_eint_get_mask(struct mtk_pinctrl *pctl,
939 unsigned int eint_num)
940{
941 unsigned int bit = BIT(eint_num % 32);
942 const struct mtk_eint_offsets *eint_offsets =
943 &pctl->devdata->eint_offsets;
944
945 void __iomem *reg = mtk_eint_get_offset(pctl, eint_num,
946 eint_offsets->mask);
947
948 return !!(readl(reg) & bit);
949}
950
951static int mtk_eint_flip_edge(struct mtk_pinctrl *pctl, int hwirq)
952{
953 int start_level, curr_level;
954 unsigned int reg_offset;
955 const struct mtk_eint_offsets *eint_offsets = &(pctl->devdata->eint_offsets);
956 u32 mask = BIT(hwirq & 0x1f);
957 u32 port = (hwirq >> 5) & eint_offsets->port_mask;
958 void __iomem *reg = pctl->eint_reg_base + (port << 2);
959 const struct mtk_desc_pin *pin;
960
961 pin = mtk_find_pin_by_eint_num(pctl, hwirq);
962 curr_level = mtk_gpio_get(pctl->chip, pin->pin.number);
963 do {
964 start_level = curr_level;
965 if (start_level)
966 reg_offset = eint_offsets->pol_clr;
967 else
968 reg_offset = eint_offsets->pol_set;
969 writel(mask, reg + reg_offset);
970
971 curr_level = mtk_gpio_get(pctl->chip, pin->pin.number);
972 } while (start_level != curr_level);
973
974 return start_level;
975}
976
977static void mtk_eint_mask(struct irq_data *d)
978{
979 struct mtk_pinctrl *pctl = irq_data_get_irq_chip_data(d);
980 const struct mtk_eint_offsets *eint_offsets =
981 &pctl->devdata->eint_offsets;
982 u32 mask = BIT(d->hwirq & 0x1f);
983 void __iomem *reg = mtk_eint_get_offset(pctl, d->hwirq,
984 eint_offsets->mask_set);
985
986 writel(mask, reg);
987}
988
989static void mtk_eint_unmask(struct irq_data *d)
990{
991 struct mtk_pinctrl *pctl = irq_data_get_irq_chip_data(d);
992 const struct mtk_eint_offsets *eint_offsets =
993 &pctl->devdata->eint_offsets;
994 u32 mask = BIT(d->hwirq & 0x1f);
995 void __iomem *reg = mtk_eint_get_offset(pctl, d->hwirq,
996 eint_offsets->mask_clr);
997
998 writel(mask, reg);
999
1000 if (pctl->eint_dual_edges[d->hwirq])
1001 mtk_eint_flip_edge(pctl, d->hwirq);
1002}
1003
1004static int mtk_gpio_set_debounce(struct gpio_chip *chip, unsigned offset,
1005 unsigned debounce)
1006{
1007 struct mtk_pinctrl *pctl = dev_get_drvdata(chip->parent);
1008 int eint_num, virq, eint_offset;
1009 unsigned int set_offset, bit, clr_bit, clr_offset, rst, i, unmask, dbnc;
1010 static const unsigned int debounce_time[] = {500, 1000, 16000, 32000, 64000,
1011 128000, 256000};
1012 const struct mtk_desc_pin *pin; 836 const struct mtk_desc_pin *pin;
1013 struct irq_data *d; 837 unsigned long eint_n;
1014 838
1015 pin = pctl->devdata->pins + offset; 839 pin = pctl->devdata->pins + offset;
1016 if (pin->eint.eintnum == NO_EINT_SUPPORT) 840 if (pin->eint.eintnum == NO_EINT_SUPPORT)
1017 return -EINVAL; 841 return -EINVAL;
1018 842
1019 eint_num = pin->eint.eintnum; 843 eint_n = pin->eint.eintnum;
1020 virq = irq_find_mapping(pctl->domain, eint_num);
1021 eint_offset = (eint_num % 4) * 8;
1022 d = irq_get_irq_data(virq);
1023
1024 set_offset = (eint_num / 4) * 4 + pctl->devdata->eint_offsets.dbnc_set;
1025 clr_offset = (eint_num / 4) * 4 + pctl->devdata->eint_offsets.dbnc_clr;
1026 if (!mtk_eint_can_en_debounce(pctl, eint_num))
1027 return -ENOSYS;
1028
1029 dbnc = ARRAY_SIZE(debounce_time);
1030 for (i = 0; i < ARRAY_SIZE(debounce_time); i++) {
1031 if (debounce <= debounce_time[i]) {
1032 dbnc = i;
1033 break;
1034 }
1035 }
1036 844
1037 if (!mtk_eint_get_mask(pctl, eint_num)) { 845 return mtk_eint_find_irq(pctl->eint, eint_n);
1038 mtk_eint_mask(d);
1039 unmask = 1;
1040 } else {
1041 unmask = 0;
1042 }
1043
1044 clr_bit = 0xff << eint_offset;
1045 writel(clr_bit, pctl->eint_reg_base + clr_offset);
1046
1047 bit = ((dbnc << EINT_DBNC_SET_DBNC_BITS) | EINT_DBNC_SET_EN) <<
1048 eint_offset;
1049 rst = EINT_DBNC_RST_BIT << eint_offset;
1050 writel(rst | bit, pctl->eint_reg_base + set_offset);
1051
1052 /* Delay a while (more than 2T) to wait for hw debounce counter reset
1053 work correctly */
1054 udelay(1);
1055 if (unmask == 1)
1056 mtk_eint_unmask(d);
1057
1058 return 0;
1059} 846}
1060 847
1061static int mtk_gpio_set_config(struct gpio_chip *chip, unsigned offset, 848static int mtk_gpio_set_config(struct gpio_chip *chip, unsigned offset,
1062 unsigned long config) 849 unsigned long config)
1063{ 850{
851 struct mtk_pinctrl *pctl = gpiochip_get_data(chip);
852 const struct mtk_desc_pin *pin;
853 unsigned long eint_n;
1064 u32 debounce; 854 u32 debounce;
1065 855
1066 if (pinconf_to_config_param(config) != PIN_CONFIG_INPUT_DEBOUNCE) 856 if (pinconf_to_config_param(config) != PIN_CONFIG_INPUT_DEBOUNCE)
1067 return -ENOTSUPP; 857 return -ENOTSUPP;
1068 858
859 pin = pctl->devdata->pins + offset;
860 if (pin->eint.eintnum == NO_EINT_SUPPORT)
861 return -EINVAL;
862
1069 debounce = pinconf_to_config_argument(config); 863 debounce = pinconf_to_config_argument(config);
1070 return mtk_gpio_set_debounce(chip, offset, debounce); 864 eint_n = pin->eint.eintnum;
865
866 return mtk_eint_set_debounce(pctl->eint, eint_n, debounce);
1071} 867}
1072 868
1073static const struct gpio_chip mtk_gpio_chip = { 869static const struct gpio_chip mtk_gpio_chip = {
@@ -1084,117 +880,18 @@ static const struct gpio_chip mtk_gpio_chip = {
1084 .of_gpio_n_cells = 2, 880 .of_gpio_n_cells = 2,
1085}; 881};
1086 882
1087static int mtk_eint_set_type(struct irq_data *d,
1088 unsigned int type)
1089{
1090 struct mtk_pinctrl *pctl = irq_data_get_irq_chip_data(d);
1091 const struct mtk_eint_offsets *eint_offsets =
1092 &pctl->devdata->eint_offsets;
1093 u32 mask = BIT(d->hwirq & 0x1f);
1094 void __iomem *reg;
1095
1096 if (((type & IRQ_TYPE_EDGE_BOTH) && (type & IRQ_TYPE_LEVEL_MASK)) ||
1097 ((type & IRQ_TYPE_LEVEL_MASK) == IRQ_TYPE_LEVEL_MASK)) {
1098 dev_err(pctl->dev, "Can't configure IRQ%d (EINT%lu) for type 0x%X\n",
1099 d->irq, d->hwirq, type);
1100 return -EINVAL;
1101 }
1102
1103 if ((type & IRQ_TYPE_EDGE_BOTH) == IRQ_TYPE_EDGE_BOTH)
1104 pctl->eint_dual_edges[d->hwirq] = 1;
1105 else
1106 pctl->eint_dual_edges[d->hwirq] = 0;
1107
1108 if (type & (IRQ_TYPE_LEVEL_LOW | IRQ_TYPE_EDGE_FALLING)) {
1109 reg = mtk_eint_get_offset(pctl, d->hwirq,
1110 eint_offsets->pol_clr);
1111 writel(mask, reg);
1112 } else {
1113 reg = mtk_eint_get_offset(pctl, d->hwirq,
1114 eint_offsets->pol_set);
1115 writel(mask, reg);
1116 }
1117
1118 if (type & (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING)) {
1119 reg = mtk_eint_get_offset(pctl, d->hwirq,
1120 eint_offsets->sens_clr);
1121 writel(mask, reg);
1122 } else {
1123 reg = mtk_eint_get_offset(pctl, d->hwirq,
1124 eint_offsets->sens_set);
1125 writel(mask, reg);
1126 }
1127
1128 if (pctl->eint_dual_edges[d->hwirq])
1129 mtk_eint_flip_edge(pctl, d->hwirq);
1130
1131 return 0;
1132}
1133
1134static int mtk_eint_irq_set_wake(struct irq_data *d, unsigned int on)
1135{
1136 struct mtk_pinctrl *pctl = irq_data_get_irq_chip_data(d);
1137 int shift = d->hwirq & 0x1f;
1138 int reg = d->hwirq >> 5;
1139
1140 if (on)
1141 pctl->wake_mask[reg] |= BIT(shift);
1142 else
1143 pctl->wake_mask[reg] &= ~BIT(shift);
1144
1145 return 0;
1146}
1147
1148static void mtk_eint_chip_write_mask(const struct mtk_eint_offsets *chip,
1149 void __iomem *eint_reg_base, u32 *buf)
1150{
1151 int port;
1152 void __iomem *reg;
1153
1154 for (port = 0; port < chip->ports; port++) {
1155 reg = eint_reg_base + (port << 2);
1156 writel_relaxed(~buf[port], reg + chip->mask_set);
1157 writel_relaxed(buf[port], reg + chip->mask_clr);
1158 }
1159}
1160
1161static void mtk_eint_chip_read_mask(const struct mtk_eint_offsets *chip,
1162 void __iomem *eint_reg_base, u32 *buf)
1163{
1164 int port;
1165 void __iomem *reg;
1166
1167 for (port = 0; port < chip->ports; port++) {
1168 reg = eint_reg_base + chip->mask + (port << 2);
1169 buf[port] = ~readl_relaxed(reg);
1170 /* Mask is 0 when irq is enabled, and 1 when disabled. */
1171 }
1172}
1173
1174static int mtk_eint_suspend(struct device *device) 883static int mtk_eint_suspend(struct device *device)
1175{ 884{
1176 void __iomem *reg;
1177 struct mtk_pinctrl *pctl = dev_get_drvdata(device); 885 struct mtk_pinctrl *pctl = dev_get_drvdata(device);
1178 const struct mtk_eint_offsets *eint_offsets =
1179 &pctl->devdata->eint_offsets;
1180 886
1181 reg = pctl->eint_reg_base; 887 return mtk_eint_do_suspend(pctl->eint);
1182 mtk_eint_chip_read_mask(eint_offsets, reg, pctl->cur_mask);
1183 mtk_eint_chip_write_mask(eint_offsets, reg, pctl->wake_mask);
1184
1185 return 0;
1186} 888}
1187 889
1188static int mtk_eint_resume(struct device *device) 890static int mtk_eint_resume(struct device *device)
1189{ 891{
1190 struct mtk_pinctrl *pctl = dev_get_drvdata(device); 892 struct mtk_pinctrl *pctl = dev_get_drvdata(device);
1191 const struct mtk_eint_offsets *eint_offsets =
1192 &pctl->devdata->eint_offsets;
1193 893
1194 mtk_eint_chip_write_mask(eint_offsets, 894 return mtk_eint_do_resume(pctl->eint);
1195 pctl->eint_reg_base, pctl->cur_mask);
1196
1197 return 0;
1198} 895}
1199 896
1200const struct dev_pm_ops mtk_eint_pm_ops = { 897const struct dev_pm_ops mtk_eint_pm_ops = {
@@ -1202,117 +899,6 @@ const struct dev_pm_ops mtk_eint_pm_ops = {
1202 .resume_noirq = mtk_eint_resume, 899 .resume_noirq = mtk_eint_resume,
1203}; 900};
1204 901
1205static void mtk_eint_ack(struct irq_data *d)
1206{
1207 struct mtk_pinctrl *pctl = irq_data_get_irq_chip_data(d);
1208 const struct mtk_eint_offsets *eint_offsets =
1209 &pctl->devdata->eint_offsets;
1210 u32 mask = BIT(d->hwirq & 0x1f);
1211 void __iomem *reg = mtk_eint_get_offset(pctl, d->hwirq,
1212 eint_offsets->ack);
1213
1214 writel(mask, reg);
1215}
1216
1217static struct irq_chip mtk_pinctrl_irq_chip = {
1218 .name = "mt-eint",
1219 .irq_disable = mtk_eint_mask,
1220 .irq_mask = mtk_eint_mask,
1221 .irq_unmask = mtk_eint_unmask,
1222 .irq_ack = mtk_eint_ack,
1223 .irq_set_type = mtk_eint_set_type,
1224 .irq_set_wake = mtk_eint_irq_set_wake,
1225 .irq_request_resources = mtk_pinctrl_irq_request_resources,
1226 .irq_release_resources = mtk_pinctrl_irq_release_resources,
1227};
1228
1229static unsigned int mtk_eint_init(struct mtk_pinctrl *pctl)
1230{
1231 const struct mtk_eint_offsets *eint_offsets =
1232 &pctl->devdata->eint_offsets;
1233 void __iomem *reg = pctl->eint_reg_base + eint_offsets->dom_en;
1234 unsigned int i;
1235
1236 for (i = 0; i < pctl->devdata->ap_num; i += 32) {
1237 writel(0xffffffff, reg);
1238 reg += 4;
1239 }
1240 return 0;
1241}
1242
1243static inline void
1244mtk_eint_debounce_process(struct mtk_pinctrl *pctl, int index)
1245{
1246 unsigned int rst, ctrl_offset;
1247 unsigned int bit, dbnc;
1248 const struct mtk_eint_offsets *eint_offsets =
1249 &pctl->devdata->eint_offsets;
1250
1251 ctrl_offset = (index / 4) * 4 + eint_offsets->dbnc_ctrl;
1252 dbnc = readl(pctl->eint_reg_base + ctrl_offset);
1253 bit = EINT_DBNC_SET_EN << ((index % 4) * 8);
1254 if ((bit & dbnc) > 0) {
1255 ctrl_offset = (index / 4) * 4 + eint_offsets->dbnc_set;
1256 rst = EINT_DBNC_RST_BIT << ((index % 4) * 8);
1257 writel(rst, pctl->eint_reg_base + ctrl_offset);
1258 }
1259}
1260
1261static void mtk_eint_irq_handler(struct irq_desc *desc)
1262{
1263 struct irq_chip *chip = irq_desc_get_chip(desc);
1264 struct mtk_pinctrl *pctl = irq_desc_get_handler_data(desc);
1265 unsigned int status, eint_num;
1266 int offset, index, virq;
1267 const struct mtk_eint_offsets *eint_offsets =
1268 &pctl->devdata->eint_offsets;
1269 void __iomem *reg = mtk_eint_get_offset(pctl, 0, eint_offsets->stat);
1270 int dual_edges, start_level, curr_level;
1271 const struct mtk_desc_pin *pin;
1272
1273 chained_irq_enter(chip, desc);
1274 for (eint_num = 0;
1275 eint_num < pctl->devdata->ap_num;
1276 eint_num += 32, reg += 4) {
1277 status = readl(reg);
1278 while (status) {
1279 offset = __ffs(status);
1280 index = eint_num + offset;
1281 virq = irq_find_mapping(pctl->domain, index);
1282 status &= ~BIT(offset);
1283
1284 dual_edges = pctl->eint_dual_edges[index];
1285 if (dual_edges) {
1286 /* Clear soft-irq in case we raised it
1287 last time */
1288 writel(BIT(offset), reg - eint_offsets->stat +
1289 eint_offsets->soft_clr);
1290
1291 pin = mtk_find_pin_by_eint_num(pctl, index);
1292 start_level = mtk_gpio_get(pctl->chip,
1293 pin->pin.number);
1294 }
1295
1296 generic_handle_irq(virq);
1297
1298 if (dual_edges) {
1299 curr_level = mtk_eint_flip_edge(pctl, index);
1300
1301 /* If level changed, we might lost one edge
1302 interrupt, raised it through soft-irq */
1303 if (start_level != curr_level)
1304 writel(BIT(offset), reg -
1305 eint_offsets->stat +
1306 eint_offsets->soft_set);
1307 }
1308
1309 if (index < pctl->devdata->db_cnt)
1310 mtk_eint_debounce_process(pctl , index);
1311 }
1312 }
1313 chained_irq_exit(chip, desc);
1314}
1315
1316static int mtk_pctrl_build_state(struct platform_device *pdev) 902static int mtk_pctrl_build_state(struct platform_device *pdev)
1317{ 903{
1318 struct mtk_pinctrl *pctl = platform_get_drvdata(pdev); 904 struct mtk_pinctrl *pctl = platform_get_drvdata(pdev);
@@ -1345,6 +931,97 @@ static int mtk_pctrl_build_state(struct platform_device *pdev)
1345 return 0; 931 return 0;
1346} 932}
1347 933
934static int
935mtk_xt_get_gpio_n(void *data, unsigned long eint_n, unsigned int *gpio_n,
936 struct gpio_chip **gpio_chip)
937{
938 struct mtk_pinctrl *pctl = (struct mtk_pinctrl *)data;
939 const struct mtk_desc_pin *pin;
940
941 pin = mtk_find_pin_by_eint_num(pctl, eint_n);
942 if (!pin)
943 return -EINVAL;
944
945 *gpio_chip = pctl->chip;
946 *gpio_n = pin->pin.number;
947
948 return 0;
949}
950
951static int mtk_xt_get_gpio_state(void *data, unsigned long eint_n)
952{
953 struct mtk_pinctrl *pctl = (struct mtk_pinctrl *)data;
954 const struct mtk_desc_pin *pin;
955
956 pin = mtk_find_pin_by_eint_num(pctl, eint_n);
957 if (!pin)
958 return -EINVAL;
959
960 return mtk_gpio_get(pctl->chip, pin->pin.number);
961}
962
963static int mtk_xt_set_gpio_as_eint(void *data, unsigned long eint_n)
964{
965 struct mtk_pinctrl *pctl = (struct mtk_pinctrl *)data;
966 const struct mtk_desc_pin *pin;
967
968 pin = mtk_find_pin_by_eint_num(pctl, eint_n);
969 if (!pin)
970 return -EINVAL;
971
972 /* set mux to INT mode */
973 mtk_pmx_set_mode(pctl->pctl_dev, pin->pin.number, pin->eint.eintmux);
974 /* set gpio direction to input */
975 mtk_pmx_gpio_set_direction(pctl->pctl_dev, NULL, pin->pin.number,
976 true);
977 /* set input-enable */
978 mtk_pconf_set_ies_smt(pctl, pin->pin.number, 1,
979 PIN_CONFIG_INPUT_ENABLE);
980
981 return 0;
982}
983
984static const struct mtk_eint_xt mtk_eint_xt = {
985 .get_gpio_n = mtk_xt_get_gpio_n,
986 .get_gpio_state = mtk_xt_get_gpio_state,
987 .set_gpio_as_eint = mtk_xt_set_gpio_as_eint,
988};
989
990static int mtk_eint_init(struct mtk_pinctrl *pctl, struct platform_device *pdev)
991{
992 struct device_node *np = pdev->dev.of_node;
993 struct resource *res;
994
995 if (!of_property_read_bool(np, "interrupt-controller"))
996 return -ENODEV;
997
998 pctl->eint = devm_kzalloc(pctl->dev, sizeof(*pctl->eint), GFP_KERNEL);
999 if (!pctl->eint)
1000 return -ENOMEM;
1001
1002 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1003 if (!res) {
1004 dev_err(&pdev->dev, "Unable to get eint resource\n");
1005 return -ENODEV;
1006 }
1007
1008 pctl->eint->base = devm_ioremap_resource(&pdev->dev, res);
1009 if (IS_ERR(pctl->eint->base))
1010 return PTR_ERR(pctl->eint->base);
1011
1012 pctl->eint->irq = irq_of_parse_and_map(np, 0);
1013 if (!pctl->eint->irq)
1014 return -EINVAL;
1015
1016 pctl->eint->dev = &pdev->dev;
1017 pctl->eint->regs = &pctl->devdata->eint_regs;
1018 pctl->eint->hw = &pctl->devdata->eint_hw;
1019 pctl->eint->pctl = pctl;
1020 pctl->eint->gpio_xlate = &mtk_eint_xt;
1021
1022 return mtk_eint_do_init(pctl->eint);
1023}
1024
1348int mtk_pctrl_init(struct platform_device *pdev, 1025int mtk_pctrl_init(struct platform_device *pdev,
1349 const struct mtk_pinctrl_devdata *data, 1026 const struct mtk_pinctrl_devdata *data,
1350 struct regmap *regmap) 1027 struct regmap *regmap)
@@ -1353,8 +1030,7 @@ int mtk_pctrl_init(struct platform_device *pdev,
1353 struct mtk_pinctrl *pctl; 1030 struct mtk_pinctrl *pctl;
1354 struct device_node *np = pdev->dev.of_node, *node; 1031 struct device_node *np = pdev->dev.of_node, *node;
1355 struct property *prop; 1032 struct property *prop;
1356 struct resource *res; 1033 int ret, i;
1357 int i, ret, irq, ports_buf;
1358 1034
1359 pctl = devm_kzalloc(&pdev->dev, sizeof(*pctl), GFP_KERNEL); 1035 pctl = devm_kzalloc(&pdev->dev, sizeof(*pctl), GFP_KERNEL);
1360 if (!pctl) 1036 if (!pctl)
@@ -1441,70 +1117,10 @@ int mtk_pctrl_init(struct platform_device *pdev,
1441 goto chip_error; 1117 goto chip_error;
1442 } 1118 }
1443 1119
1444 if (!of_property_read_bool(np, "interrupt-controller")) 1120 ret = mtk_eint_init(pctl, pdev);
1445 return 0; 1121 if (ret)
1446
1447 /* Get EINT register base from dts. */
1448 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1449 if (!res) {
1450 dev_err(&pdev->dev, "Unable to get Pinctrl resource\n");
1451 ret = -EINVAL;
1452 goto chip_error;
1453 }
1454
1455 pctl->eint_reg_base = devm_ioremap_resource(&pdev->dev, res);
1456 if (IS_ERR(pctl->eint_reg_base)) {
1457 ret = -EINVAL;
1458 goto chip_error;
1459 }
1460
1461 ports_buf = pctl->devdata->eint_offsets.ports;
1462 pctl->wake_mask = devm_kcalloc(&pdev->dev, ports_buf,
1463 sizeof(*pctl->wake_mask), GFP_KERNEL);
1464 if (!pctl->wake_mask) {
1465 ret = -ENOMEM;
1466 goto chip_error;
1467 }
1468
1469 pctl->cur_mask = devm_kcalloc(&pdev->dev, ports_buf,
1470 sizeof(*pctl->cur_mask), GFP_KERNEL);
1471 if (!pctl->cur_mask) {
1472 ret = -ENOMEM;
1473 goto chip_error;
1474 }
1475
1476 pctl->eint_dual_edges = devm_kcalloc(&pdev->dev, pctl->devdata->ap_num,
1477 sizeof(int), GFP_KERNEL);
1478 if (!pctl->eint_dual_edges) {
1479 ret = -ENOMEM;
1480 goto chip_error;
1481 }
1482
1483 irq = irq_of_parse_and_map(np, 0);
1484 if (!irq) {
1485 dev_err(&pdev->dev, "couldn't parse and map irq\n");
1486 ret = -EINVAL;
1487 goto chip_error;
1488 }
1489
1490 pctl->domain = irq_domain_add_linear(np,
1491 pctl->devdata->ap_num, &irq_domain_simple_ops, NULL);
1492 if (!pctl->domain) {
1493 dev_err(&pdev->dev, "Couldn't register IRQ domain\n");
1494 ret = -ENOMEM;
1495 goto chip_error; 1122 goto chip_error;
1496 }
1497
1498 mtk_eint_init(pctl);
1499 for (i = 0; i < pctl->devdata->ap_num; i++) {
1500 int virq = irq_create_mapping(pctl->domain, i);
1501
1502 irq_set_chip_and_handler(virq, &mtk_pinctrl_irq_chip,
1503 handle_level_irq);
1504 irq_set_chip_data(virq, pctl);
1505 }
1506 1123
1507 irq_set_chained_handler_and_data(irq, mtk_eint_irq_handler, pctl);
1508 return 0; 1124 return 0;
1509 1125
1510chip_error: 1126chip_error:
diff --git a/drivers/pinctrl/mediatek/pinctrl-mtk-common.h b/drivers/pinctrl/mediatek/pinctrl-mtk-common.h
index 8543bc478a1e..346e3dbe800b 100644
--- a/drivers/pinctrl/mediatek/pinctrl-mtk-common.h
+++ b/drivers/pinctrl/mediatek/pinctrl-mtk-common.h
@@ -19,6 +19,8 @@
19#include <linux/regmap.h> 19#include <linux/regmap.h>
20#include <linux/pinctrl/pinconf-generic.h> 20#include <linux/pinctrl/pinconf-generic.h>
21 21
22#include "mtk-eint.h"
23
22#define NO_EINT_SUPPORT 255 24#define NO_EINT_SUPPORT 255
23#define MT_EDGE_SENSITIVE 0 25#define MT_EDGE_SENSITIVE 0
24#define MT_LEVEL_SENSITIVE 1 26#define MT_LEVEL_SENSITIVE 1
@@ -258,9 +260,8 @@ struct mtk_pinctrl_devdata {
258 unsigned char port_shf; 260 unsigned char port_shf;
259 unsigned char port_mask; 261 unsigned char port_mask;
260 unsigned char port_align; 262 unsigned char port_align;
261 struct mtk_eint_offsets eint_offsets; 263 struct mtk_eint_hw eint_hw;
262 unsigned int ap_num; 264 struct mtk_eint_regs eint_regs;
263 unsigned int db_cnt;
264}; 265};
265 266
266struct mtk_pinctrl { 267struct mtk_pinctrl {
@@ -274,11 +275,7 @@ struct mtk_pinctrl {
274 const char **grp_names; 275 const char **grp_names;
275 struct pinctrl_dev *pctl_dev; 276 struct pinctrl_dev *pctl_dev;
276 const struct mtk_pinctrl_devdata *devdata; 277 const struct mtk_pinctrl_devdata *devdata;
277 void __iomem *eint_reg_base; 278 struct mtk_eint *eint;
278 struct irq_domain *domain;
279 int *eint_dual_edges;
280 u32 *wake_mask;
281 u32 *cur_mask;
282}; 279};
283 280
284int mtk_pctrl_init(struct platform_device *pdev, 281int mtk_pctrl_init(struct platform_device *pdev,