Merge tag 'pinctrl-v6.10-1' of git://git.kernel.org/pub/scm/linux/kernel/git/linusw...
[linux-2.6-block.git] / drivers / pinctrl / samsung / pinctrl-exynos.c
CommitLineData
221173a3
KK
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.
43b169db 15
f9c74474 16#include <linux/clk.h>
43b169db
TA
17#include <linux/device.h>
18#include <linux/interrupt.h>
19#include <linux/irqdomain.h>
20#include <linux/irq.h>
de88cbb7 21#include <linux/irqchip/chained_irq.h>
cfa76ddf 22#include <linux/of.h>
43b169db 23#include <linux/of_irq.h>
43b169db 24#include <linux/slab.h>
19846950 25#include <linux/spinlock.h>
07731019 26#include <linux/regmap.h>
43b169db 27#include <linux/err.h>
07731019 28#include <linux/soc/samsung/exynos-pmu.h>
a8be2af0 29#include <linux/soc/samsung/exynos-regs-pmu.h>
43b169db 30
43b169db
TA
31#include "pinctrl-samsung.h"
32#include "pinctrl-exynos.h"
33
2e4a4fda
TF
34struct exynos_irq_chip {
35 struct irq_chip chip;
36
37 u32 eint_con;
38 u32 eint_mask;
39 u32 eint_pend;
85745c87 40 u32 *eint_wake_mask_value;
a8be2af0 41 u32 eint_wake_mask_reg;
b577a279
JB
42 void (*set_eint_wakeup_mask)(struct samsung_pinctrl_drv_data *drvdata,
43 struct exynos_irq_chip *irq_chip);
2e4a4fda
TF
44};
45
46static inline struct exynos_irq_chip *to_exynos_irq_chip(struct irq_chip *chip)
47{
48 return container_of(chip, struct exynos_irq_chip, chip);
49}
499147c9 50
2e4a4fda 51static void exynos_irq_mask(struct irq_data *irqd)
43b169db 52{
2e4a4fda
TF
53 struct irq_chip *chip = irq_data_get_irq_chip(irqd);
54 struct exynos_irq_chip *our_chip = to_exynos_irq_chip(chip);
595be726 55 struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(irqd);
884fdaa5 56 unsigned long reg_mask;
fa0c10a5 57 unsigned int mask;
5ae8cf79
DA
58 unsigned long flags;
59
884fdaa5
JK
60 if (bank->eint_mask_offset)
61 reg_mask = bank->pctl_offset + bank->eint_mask_offset;
62 else
63 reg_mask = our_chip->eint_mask + bank->eint_offset;
64
f9c74474
AD
65 if (clk_enable(bank->drvdata->pclk)) {
66 dev_err(bank->gpio_chip.parent,
67 "unable to enable clock for masking IRQ\n");
68 return;
69 }
70
1f306ecb 71 raw_spin_lock_irqsave(&bank->slock, flags);
43b169db 72
8b1bd11c 73 mask = readl(bank->eint_base + reg_mask);
5ace03fb 74 mask |= 1 << irqd->hwirq;
8b1bd11c 75 writel(mask, bank->eint_base + reg_mask);
5ae8cf79 76
1f306ecb 77 raw_spin_unlock_irqrestore(&bank->slock, flags);
f9c74474
AD
78
79 clk_disable(bank->drvdata->pclk);
43b169db
TA
80}
81
2e4a4fda 82static void exynos_irq_ack(struct irq_data *irqd)
43b169db 83{
2e4a4fda
TF
84 struct irq_chip *chip = irq_data_get_irq_chip(irqd);
85 struct exynos_irq_chip *our_chip = to_exynos_irq_chip(chip);
595be726 86 struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(irqd);
884fdaa5
JK
87 unsigned long reg_pend;
88
89 if (bank->eint_pend_offset)
90 reg_pend = bank->pctl_offset + bank->eint_pend_offset;
91 else
92 reg_pend = our_chip->eint_pend + bank->eint_offset;
43b169db 93
f9c74474
AD
94 if (clk_enable(bank->drvdata->pclk)) {
95 dev_err(bank->gpio_chip.parent,
96 "unable to enable clock to ack IRQ\n");
97 return;
98 }
99
8b1bd11c 100 writel(1 << irqd->hwirq, bank->eint_base + reg_pend);
f9c74474
AD
101
102 clk_disable(bank->drvdata->pclk);
43b169db
TA
103}
104
2e4a4fda 105static void exynos_irq_unmask(struct irq_data *irqd)
43b169db 106{
2e4a4fda
TF
107 struct irq_chip *chip = irq_data_get_irq_chip(irqd);
108 struct exynos_irq_chip *our_chip = to_exynos_irq_chip(chip);
595be726 109 struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(irqd);
884fdaa5 110 unsigned long reg_mask;
fa0c10a5 111 unsigned int mask;
5ae8cf79 112 unsigned long flags;
43b169db 113
5a68e7a7
DA
114 /*
115 * Ack level interrupts right before unmask
116 *
117 * If we don't do this we'll get a double-interrupt. Level triggered
118 * interrupts must not fire an interrupt if the level is not
119 * _currently_ active, even if it was active while the interrupt was
120 * masked.
121 */
122 if (irqd_get_trigger_type(irqd) & IRQ_TYPE_LEVEL_MASK)
2e4a4fda 123 exynos_irq_ack(irqd);
5a68e7a7 124
884fdaa5
JK
125 if (bank->eint_mask_offset)
126 reg_mask = bank->pctl_offset + bank->eint_mask_offset;
127 else
128 reg_mask = our_chip->eint_mask + bank->eint_offset;
129
f9c74474
AD
130 if (clk_enable(bank->drvdata->pclk)) {
131 dev_err(bank->gpio_chip.parent,
132 "unable to enable clock for unmasking IRQ\n");
133 return;
134 }
135
1f306ecb 136 raw_spin_lock_irqsave(&bank->slock, flags);
43b169db 137
8b1bd11c 138 mask = readl(bank->eint_base + reg_mask);
5ace03fb 139 mask &= ~(1 << irqd->hwirq);
8b1bd11c 140 writel(mask, bank->eint_base + reg_mask);
5ae8cf79 141
1f306ecb 142 raw_spin_unlock_irqrestore(&bank->slock, flags);
f9c74474
AD
143
144 clk_disable(bank->drvdata->pclk);
43b169db
TA
145}
146
2e4a4fda 147static int exynos_irq_set_type(struct irq_data *irqd, unsigned int type)
43b169db 148{
2e4a4fda
TF
149 struct irq_chip *chip = irq_data_get_irq_chip(irqd);
150 struct exynos_irq_chip *our_chip = to_exynos_irq_chip(chip);
595be726 151 struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(irqd);
f6a8249f 152 unsigned int shift = EXYNOS_EINT_CON_LEN * irqd->hwirq;
43b169db 153 unsigned int con, trig_type;
884fdaa5 154 unsigned long reg_con;
f9c74474 155 int ret;
43b169db
TA
156
157 switch (type) {
158 case IRQ_TYPE_EDGE_RISING:
159 trig_type = EXYNOS_EINT_EDGE_RISING;
160 break;
161 case IRQ_TYPE_EDGE_FALLING:
162 trig_type = EXYNOS_EINT_EDGE_FALLING;
163 break;
164 case IRQ_TYPE_EDGE_BOTH:
165 trig_type = EXYNOS_EINT_EDGE_BOTH;
166 break;
167 case IRQ_TYPE_LEVEL_HIGH:
168 trig_type = EXYNOS_EINT_LEVEL_HIGH;
169 break;
170 case IRQ_TYPE_LEVEL_LOW:
171 trig_type = EXYNOS_EINT_LEVEL_LOW;
172 break;
173 default:
174 pr_err("unsupported external interrupt type\n");
175 return -EINVAL;
176 }
177
178 if (type & IRQ_TYPE_EDGE_BOTH)
40ec168a 179 irq_set_handler_locked(irqd, handle_edge_irq);
43b169db 180 else
40ec168a 181 irq_set_handler_locked(irqd, handle_level_irq);
43b169db 182
884fdaa5
JK
183 if (bank->eint_con_offset)
184 reg_con = bank->pctl_offset + bank->eint_con_offset;
185 else
186 reg_con = our_chip->eint_con + bank->eint_offset;
187
f9c74474
AD
188 ret = clk_enable(bank->drvdata->pclk);
189 if (ret) {
190 dev_err(bank->gpio_chip.parent,
191 "unable to enable clock for configuring IRQ type\n");
192 return ret;
193 }
194
8b1bd11c 195 con = readl(bank->eint_base + reg_con);
43b169db
TA
196 con &= ~(EXYNOS_EINT_CON_MASK << shift);
197 con |= trig_type << shift;
8b1bd11c 198 writel(con, bank->eint_base + reg_con);
ee2f573c 199
f9c74474
AD
200 clk_disable(bank->drvdata->pclk);
201
f6a8249f
TF
202 return 0;
203}
204
b77f5ef8
YN
205static int exynos_irq_set_affinity(struct irq_data *irqd,
206 const struct cpumask *dest, bool force)
207{
208 struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(irqd);
209 struct samsung_pinctrl_drv_data *d = bank->drvdata;
210 struct irq_data *parent = irq_get_irq_data(d->irq);
211
212 if (parent)
213 return parent->chip->irq_set_affinity(parent, dest, force);
214
215 return -EINVAL;
216}
217
f6a8249f
TF
218static int exynos_irq_request_resources(struct irq_data *irqd)
219{
f6a8249f 220 struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(irqd);
94ce944b 221 const struct samsung_pin_bank_type *bank_type = bank->type;
bbed85f4
KK
222 unsigned long reg_con, flags;
223 unsigned int shift, mask, con;
f6a8249f
TF
224 int ret;
225
e3a2e878 226 ret = gpiochip_lock_as_irq(&bank->gpio_chip, irqd->hwirq);
f6a8249f 227 if (ret) {
58383c78
LW
228 dev_err(bank->gpio_chip.parent,
229 "unable to lock pin %s-%lu IRQ\n",
f6a8249f
TF
230 bank->name, irqd->hwirq);
231 return ret;
232 }
233
43fc9e7f 234 reg_con = bank->pctl_offset + bank_type->reg_offset[PINCFG_TYPE_FUNC];
f6a8249f 235 shift = irqd->hwirq * bank_type->fld_width[PINCFG_TYPE_FUNC];
499147c9 236 mask = (1 << bank_type->fld_width[PINCFG_TYPE_FUNC]) - 1;
ee2f573c 237
f9c74474
AD
238 ret = clk_enable(bank->drvdata->pclk);
239 if (ret) {
240 dev_err(bank->gpio_chip.parent,
241 "unable to enable clock for configuring pin %s-%lu\n",
242 bank->name, irqd->hwirq);
243 return ret;
244 }
245
1f306ecb 246 raw_spin_lock_irqsave(&bank->slock, flags);
19846950 247
af0b0baa 248 con = readl(bank->pctl_base + reg_con);
ee2f573c 249 con &= ~(mask << shift);
3eb12bce 250 con |= EXYNOS_PIN_CON_FUNC_EINT << shift;
af0b0baa 251 writel(con, bank->pctl_base + reg_con);
ee2f573c 252
1f306ecb 253 raw_spin_unlock_irqrestore(&bank->slock, flags);
19846950 254
f9c74474
AD
255 clk_disable(bank->drvdata->pclk);
256
43b169db
TA
257 return 0;
258}
259
f6a8249f
TF
260static void exynos_irq_release_resources(struct irq_data *irqd)
261{
f6a8249f 262 struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(irqd);
94ce944b 263 const struct samsung_pin_bank_type *bank_type = bank->type;
bbed85f4
KK
264 unsigned long reg_con, flags;
265 unsigned int shift, mask, con;
f6a8249f
TF
266
267 reg_con = bank->pctl_offset + bank_type->reg_offset[PINCFG_TYPE_FUNC];
268 shift = irqd->hwirq * bank_type->fld_width[PINCFG_TYPE_FUNC];
269 mask = (1 << bank_type->fld_width[PINCFG_TYPE_FUNC]) - 1;
270
f9c74474
AD
271 if (clk_enable(bank->drvdata->pclk)) {
272 dev_err(bank->gpio_chip.parent,
273 "unable to enable clock for deconfiguring pin %s-%lu\n",
274 bank->name, irqd->hwirq);
275 return;
276 }
277
1f306ecb 278 raw_spin_lock_irqsave(&bank->slock, flags);
f6a8249f 279
af0b0baa 280 con = readl(bank->pctl_base + reg_con);
f6a8249f 281 con &= ~(mask << shift);
3eb12bce 282 con |= PIN_CON_FUNC_INPUT << shift;
af0b0baa 283 writel(con, bank->pctl_base + reg_con);
f6a8249f 284
1f306ecb 285 raw_spin_unlock_irqrestore(&bank->slock, flags);
f6a8249f 286
f9c74474
AD
287 clk_disable(bank->drvdata->pclk);
288
e3a2e878 289 gpiochip_unlock_as_irq(&bank->gpio_chip, irqd->hwirq);
f6a8249f
TF
290}
291
43b169db
TA
292/*
293 * irq_chip for gpio interrupts.
294 */
85745c87 295static const struct exynos_irq_chip exynos_gpio_irq_chip __initconst = {
2e4a4fda
TF
296 .chip = {
297 .name = "exynos_gpio_irq_chip",
298 .irq_unmask = exynos_irq_unmask,
299 .irq_mask = exynos_irq_mask,
300 .irq_ack = exynos_irq_ack,
301 .irq_set_type = exynos_irq_set_type,
b77f5ef8 302 .irq_set_affinity = exynos_irq_set_affinity,
f6a8249f
TF
303 .irq_request_resources = exynos_irq_request_resources,
304 .irq_release_resources = exynos_irq_release_resources,
2e4a4fda
TF
305 },
306 .eint_con = EXYNOS_GPIO_ECON_OFFSET,
307 .eint_mask = EXYNOS_GPIO_EMASK_OFFSET,
308 .eint_pend = EXYNOS_GPIO_EPEND_OFFSET,
a8be2af0 309 /* eint_wake_mask_value not used */
43b169db
TA
310};
311
6f5e41bd 312static int exynos_eint_irq_map(struct irq_domain *h, unsigned int virq,
43b169db
TA
313 irq_hw_number_t hw)
314{
595be726 315 struct samsung_pin_bank *b = h->host_data;
43b169db 316
595be726 317 irq_set_chip_data(virq, b);
0d3d30db 318 irq_set_chip_and_handler(virq, &b->irq_chip->chip,
43b169db 319 handle_level_irq);
43b169db
TA
320 return 0;
321}
322
43b169db 323/*
6f5e41bd 324 * irq domain callbacks for external gpio and wakeup interrupt controllers.
43b169db 325 */
6f5e41bd
AK
326static const struct irq_domain_ops exynos_eint_irqd_ops = {
327 .map = exynos_eint_irq_map,
43b169db
TA
328 .xlate = irq_domain_xlate_twocell,
329};
330
331static irqreturn_t exynos_eint_gpio_irq(int irq, void *data)
332{
333 struct samsung_pinctrl_drv_data *d = data;
1bf00d7a 334 struct samsung_pin_bank *bank = d->pin_banks;
a9cb09b7
MZ
335 unsigned int svc, group, pin;
336 int ret;
43b169db 337
f9c74474
AD
338 if (clk_enable(bank->drvdata->pclk)) {
339 dev_err(bank->gpio_chip.parent,
340 "unable to enable clock for handling IRQ\n");
341 return IRQ_NONE;
342 }
343
6cf96df7
JK
344 if (bank->eint_con_offset)
345 svc = readl(bank->eint_base + EXYNOSAUTO_SVC_OFFSET);
346 else
347 svc = readl(bank->eint_base + EXYNOS_SVC_OFFSET);
f9c74474
AD
348
349 clk_disable(bank->drvdata->pclk);
350
43b169db
TA
351 group = EXYNOS_SVC_GROUP(svc);
352 pin = svc & EXYNOS_SVC_NUM_MASK;
353
354 if (!group)
355 return IRQ_HANDLED;
356 bank += (group - 1);
357
a9cb09b7
MZ
358 ret = generic_handle_domain_irq(bank->irq_domain, pin);
359 if (ret)
43b169db 360 return IRQ_NONE;
a9cb09b7 361
43b169db
TA
362 return IRQ_HANDLED;
363}
364
7ccbc60c
TF
365struct exynos_eint_gpio_save {
366 u32 eint_con;
367 u32 eint_fltcon0;
368 u32 eint_fltcon1;
f354157a 369 u32 eint_mask;
7ccbc60c
TF
370};
371
43b169db
TA
372/*
373 * exynos_eint_gpio_init() - setup handling of external gpio interrupts.
374 * @d: driver data of samsung pinctrl driver.
375 */
85745c87 376__init int exynos_eint_gpio_init(struct samsung_pinctrl_drv_data *d)
43b169db 377{
595be726 378 struct samsung_pin_bank *bank;
43b169db 379 struct device *dev = d->dev;
7ccbc60c
TF
380 int ret;
381 int i;
43b169db
TA
382
383 if (!d->irq) {
384 dev_err(dev, "irq number not available\n");
385 return -EINVAL;
386 }
387
388 ret = devm_request_irq(dev, d->irq, exynos_eint_gpio_irq,
389 0, dev_name(dev), d);
390 if (ret) {
391 dev_err(dev, "irq request failed\n");
392 return -ENXIO;
393 }
394
1bf00d7a
TF
395 bank = d->pin_banks;
396 for (i = 0; i < d->nr_banks; ++i, ++bank) {
595be726
TF
397 if (bank->eint_type != EINT_TYPE_GPIO)
398 continue;
85745c87
MS
399
400 bank->irq_chip = devm_kmemdup(dev, &exynos_gpio_irq_chip,
401 sizeof(*bank->irq_chip), GFP_KERNEL);
402 if (!bank->irq_chip) {
403 ret = -ENOMEM;
404 goto err_domains;
405 }
406 bank->irq_chip->chip.name = bank->name;
407
492fca28 408 bank->irq_domain = irq_domain_create_linear(bank->fwnode,
6f5e41bd 409 bank->nr_pins, &exynos_eint_irqd_ops, bank);
595be726
TF
410 if (!bank->irq_domain) {
411 dev_err(dev, "gpio irq domain add failed\n");
7ccbc60c
TF
412 ret = -ENXIO;
413 goto err_domains;
414 }
415
416 bank->soc_priv = devm_kzalloc(d->dev,
417 sizeof(struct exynos_eint_gpio_save), GFP_KERNEL);
418 if (!bank->soc_priv) {
419 irq_domain_remove(bank->irq_domain);
420 ret = -ENOMEM;
421 goto err_domains;
595be726 422 }
0d3d30db 423
43b169db
TA
424 }
425
426 return 0;
7ccbc60c
TF
427
428err_domains:
429 for (--i, --bank; i >= 0; --i, --bank) {
430 if (bank->eint_type != EINT_TYPE_GPIO)
431 continue;
432 irq_domain_remove(bank->irq_domain);
433 }
434
435 return ret;
43b169db
TA
436}
437
ad350cd9
TF
438static int exynos_wkup_irq_set_wake(struct irq_data *irqd, unsigned int on)
439{
a8be2af0
KK
440 struct irq_chip *chip = irq_data_get_irq_chip(irqd);
441 struct exynos_irq_chip *our_chip = to_exynos_irq_chip(chip);
ad350cd9
TF
442 struct samsung_pin_bank *bank = irq_data_get_irq_chip_data(irqd);
443 unsigned long bit = 1UL << (2 * bank->eint_offset + irqd->hwirq);
444
3652dc07
MJ
445 pr_info("wake %s for irq %u (%s-%lu)\n", on ? "enabled" : "disabled",
446 irqd->irq, bank->name, irqd->hwirq);
ad350cd9
TF
447
448 if (!on)
85745c87 449 *our_chip->eint_wake_mask_value |= bit;
ad350cd9 450 else
85745c87 451 *our_chip->eint_wake_mask_value &= ~bit;
ad350cd9
TF
452
453 return 0;
454}
455
b577a279
JB
456static void
457exynos_pinctrl_set_eint_wakeup_mask(struct samsung_pinctrl_drv_data *drvdata,
458 struct exynos_irq_chip *irq_chip)
459{
460 struct regmap *pmu_regs;
461
462 if (!drvdata->retention_ctrl || !drvdata->retention_ctrl->priv) {
463 dev_warn(drvdata->dev,
464 "No retention data configured bank with external wakeup interrupt. Wake-up mask will not be set.\n");
465 return;
466 }
467
468 pmu_regs = drvdata->retention_ctrl->priv;
469 dev_info(drvdata->dev,
470 "Setting external wakeup interrupt mask: 0x%x\n",
85745c87 471 *irq_chip->eint_wake_mask_value);
b577a279
JB
472
473 regmap_write(pmu_regs, irq_chip->eint_wake_mask_reg,
85745c87 474 *irq_chip->eint_wake_mask_value);
b577a279
JB
475}
476
477static void
478s5pv210_pinctrl_set_eint_wakeup_mask(struct samsung_pinctrl_drv_data *drvdata,
479 struct exynos_irq_chip *irq_chip)
480
481{
482 void __iomem *clk_base;
483
484 if (!drvdata->retention_ctrl || !drvdata->retention_ctrl->priv) {
485 dev_warn(drvdata->dev,
486 "No retention data configured bank with external wakeup interrupt. Wake-up mask will not be set.\n");
487 return;
488 }
489
490
491 clk_base = (void __iomem *) drvdata->retention_ctrl->priv;
492
85745c87 493 __raw_writel(*irq_chip->eint_wake_mask_value,
b577a279
JB
494 clk_base + irq_chip->eint_wake_mask_reg);
495}
496
85745c87 497static u32 eint_wake_mask_value = EXYNOS_EINT_WAKEUP_MASK_DISABLED;
43b169db
TA
498/*
499 * irq_chip for wakeup interrupts
500 */
bb928dfd
KK
501static const struct exynos_irq_chip s5pv210_wkup_irq_chip __initconst = {
502 .chip = {
503 .name = "s5pv210_wkup_irq_chip",
504 .irq_unmask = exynos_irq_unmask,
505 .irq_mask = exynos_irq_mask,
506 .irq_ack = exynos_irq_ack,
507 .irq_set_type = exynos_irq_set_type,
508 .irq_set_wake = exynos_wkup_irq_set_wake,
509 .irq_request_resources = exynos_irq_request_resources,
510 .irq_release_resources = exynos_irq_release_resources,
511 },
512 .eint_con = EXYNOS_WKUP_ECON_OFFSET,
513 .eint_mask = EXYNOS_WKUP_EMASK_OFFSET,
514 .eint_pend = EXYNOS_WKUP_EPEND_OFFSET,
85745c87 515 .eint_wake_mask_value = &eint_wake_mask_value,
b577a279 516 /* Only differences with exynos4210_wkup_irq_chip: */
a8be2af0 517 .eint_wake_mask_reg = S5PV210_EINT_WAKEUP_MASK,
b577a279 518 .set_eint_wakeup_mask = s5pv210_pinctrl_set_eint_wakeup_mask,
bb928dfd
KK
519};
520
71b96c3a 521static const struct exynos_irq_chip exynos4210_wkup_irq_chip __initconst = {
2e4a4fda 522 .chip = {
14c255d3 523 .name = "exynos4210_wkup_irq_chip",
2e4a4fda
TF
524 .irq_unmask = exynos_irq_unmask,
525 .irq_mask = exynos_irq_mask,
526 .irq_ack = exynos_irq_ack,
527 .irq_set_type = exynos_irq_set_type,
528 .irq_set_wake = exynos_wkup_irq_set_wake,
f6a8249f
TF
529 .irq_request_resources = exynos_irq_request_resources,
530 .irq_release_resources = exynos_irq_release_resources,
2e4a4fda
TF
531 },
532 .eint_con = EXYNOS_WKUP_ECON_OFFSET,
533 .eint_mask = EXYNOS_WKUP_EMASK_OFFSET,
534 .eint_pend = EXYNOS_WKUP_EPEND_OFFSET,
85745c87 535 .eint_wake_mask_value = &eint_wake_mask_value,
a8be2af0 536 .eint_wake_mask_reg = EXYNOS_EINT_WAKEUP_MASK,
b577a279 537 .set_eint_wakeup_mask = exynos_pinctrl_set_eint_wakeup_mask,
43b169db
TA
538};
539
71b96c3a 540static const struct exynos_irq_chip exynos7_wkup_irq_chip __initconst = {
14c255d3
AK
541 .chip = {
542 .name = "exynos7_wkup_irq_chip",
543 .irq_unmask = exynos_irq_unmask,
544 .irq_mask = exynos_irq_mask,
545 .irq_ack = exynos_irq_ack,
546 .irq_set_type = exynos_irq_set_type,
547 .irq_set_wake = exynos_wkup_irq_set_wake,
548 .irq_request_resources = exynos_irq_request_resources,
549 .irq_release_resources = exynos_irq_release_resources,
550 },
551 .eint_con = EXYNOS7_WKUP_ECON_OFFSET,
552 .eint_mask = EXYNOS7_WKUP_EMASK_OFFSET,
553 .eint_pend = EXYNOS7_WKUP_EPEND_OFFSET,
85745c87 554 .eint_wake_mask_value = &eint_wake_mask_value,
a8be2af0 555 .eint_wake_mask_reg = EXYNOS5433_EINT_WAKEUP_MASK,
b577a279 556 .set_eint_wakeup_mask = exynos_pinctrl_set_eint_wakeup_mask,
14c255d3
AK
557};
558
6cf96df7
JK
559static const struct exynos_irq_chip exynosautov920_wkup_irq_chip __initconst = {
560 .chip = {
561 .name = "exynosautov920_wkup_irq_chip",
562 .irq_unmask = exynos_irq_unmask,
563 .irq_mask = exynos_irq_mask,
564 .irq_ack = exynos_irq_ack,
565 .irq_set_type = exynos_irq_set_type,
566 .irq_set_wake = exynos_wkup_irq_set_wake,
567 .irq_request_resources = exynos_irq_request_resources,
568 .irq_release_resources = exynos_irq_release_resources,
569 },
570 .eint_wake_mask_value = &eint_wake_mask_value,
571 .eint_wake_mask_reg = EXYNOS5433_EINT_WAKEUP_MASK,
572 .set_eint_wakeup_mask = exynos_pinctrl_set_eint_wakeup_mask,
573};
574
14c255d3
AK
575/* list of external wakeup controllers supported */
576static const struct of_device_id exynos_wkup_irq_ids[] = {
bb928dfd
KK
577 { .compatible = "samsung,s5pv210-wakeup-eint",
578 .data = &s5pv210_wkup_irq_chip },
14c255d3
AK
579 { .compatible = "samsung,exynos4210-wakeup-eint",
580 .data = &exynos4210_wkup_irq_chip },
581 { .compatible = "samsung,exynos7-wakeup-eint",
582 .data = &exynos7_wkup_irq_chip },
832ae134
KK
583 { .compatible = "samsung,exynos850-wakeup-eint",
584 .data = &exynos7_wkup_irq_chip },
585 { .compatible = "samsung,exynosautov9-wakeup-eint",
586 .data = &exynos7_wkup_irq_chip },
6cf96df7
JK
587 { .compatible = "samsung,exynosautov920-wakeup-eint",
588 .data = &exynosautov920_wkup_irq_chip },
14c255d3
AK
589 { }
590};
591
43b169db 592/* interrupt handler for wakeup interrupts 0..15 */
bd0b9ac4 593static void exynos_irq_eint0_15(struct irq_desc *desc)
43b169db 594{
5663bb27 595 struct exynos_weint_data *eintd = irq_desc_get_handler_data(desc);
a04b07c0 596 struct samsung_pin_bank *bank = eintd->bank;
5663bb27 597 struct irq_chip *chip = irq_desc_get_chip(desc);
43b169db
TA
598
599 chained_irq_enter(chip, desc);
43b169db 600
a9cb09b7 601 generic_handle_domain_irq(bank->irq_domain, eintd->irq);
26fecf0b 602
43b169db
TA
603 chained_irq_exit(chip, desc);
604}
605
fa0c10a5 606static inline void exynos_irq_demux_eint(unsigned int pend,
a04b07c0 607 struct irq_domain *domain)
43b169db
TA
608{
609 unsigned int irq;
610
611 while (pend) {
612 irq = fls(pend) - 1;
a9cb09b7 613 generic_handle_domain_irq(domain, irq);
43b169db
TA
614 pend &= ~(1 << irq);
615 }
616}
617
618/* interrupt handler for wakeup interrupt 16 */
bd0b9ac4 619static void exynos_irq_demux_eint16_31(struct irq_desc *desc)
43b169db 620{
5663bb27
JL
621 struct irq_chip *chip = irq_desc_get_chip(desc);
622 struct exynos_muxed_weint_data *eintd = irq_desc_get_handler_data(desc);
fa0c10a5
KK
623 unsigned int pend;
624 unsigned int mask;
a04b07c0 625 int i;
43b169db
TA
626
627 chained_irq_enter(chip, desc);
a04b07c0 628
f9c74474
AD
629 /*
630 * just enable the clock once here, to avoid an enable/disable dance for
631 * each bank.
632 */
633 if (eintd->nr_banks) {
634 struct samsung_pin_bank *b = eintd->banks[0];
635
636 if (clk_enable(b->drvdata->pclk)) {
637 dev_err(b->gpio_chip.parent,
638 "unable to enable clock for pending IRQs\n");
639 return;
640 }
641 }
642
a04b07c0
TF
643 for (i = 0; i < eintd->nr_banks; ++i) {
644 struct samsung_pin_bank *b = eintd->banks[i];
8b1bd11c 645 pend = readl(b->eint_base + b->irq_chip->eint_pend
2e4a4fda 646 + b->eint_offset);
8b1bd11c 647 mask = readl(b->eint_base + b->irq_chip->eint_mask
2e4a4fda 648 + b->eint_offset);
a04b07c0
TF
649 exynos_irq_demux_eint(pend & ~mask, b->irq_domain);
650 }
651
f9c74474
AD
652 if (eintd->nr_banks)
653 clk_disable(eintd->banks[0]->drvdata->pclk);
654
43b169db
TA
655 chained_irq_exit(chip, desc);
656}
657
43b169db
TA
658/*
659 * exynos_eint_wkup_init() - setup handling of external wakeup interrupts.
660 * @d: driver data of samsung pinctrl driver.
661 */
85745c87 662__init int exynos_eint_wkup_init(struct samsung_pinctrl_drv_data *d)
43b169db
TA
663{
664 struct device *dev = d->dev;
c3ad056b
TF
665 struct device_node *wkup_np = NULL;
666 struct device_node *np;
a04b07c0 667 struct samsung_pin_bank *bank;
43b169db 668 struct exynos_weint_data *weint_data;
a04b07c0 669 struct exynos_muxed_weint_data *muxed_data;
85745c87 670 const struct exynos_irq_chip *irq_chip;
a04b07c0
TF
671 unsigned int muxed_banks = 0;
672 unsigned int i;
43b169db
TA
673 int idx, irq;
674
c3ad056b 675 for_each_child_of_node(dev->of_node, np) {
14c255d3
AK
676 const struct of_device_id *match;
677
678 match = of_match_node(exynos_wkup_irq_ids, np);
679 if (match) {
85745c87 680 irq_chip = match->data;
c3ad056b
TF
681 wkup_np = np;
682 break;
683 }
43b169db 684 }
c3ad056b
TF
685 if (!wkup_np)
686 return -ENODEV;
43b169db 687
1bf00d7a
TF
688 bank = d->pin_banks;
689 for (i = 0; i < d->nr_banks; ++i, ++bank) {
a04b07c0
TF
690 if (bank->eint_type != EINT_TYPE_WKUP)
691 continue;
43b169db 692
85745c87
MS
693 bank->irq_chip = devm_kmemdup(dev, irq_chip, sizeof(*irq_chip),
694 GFP_KERNEL);
695 if (!bank->irq_chip) {
696 of_node_put(wkup_np);
697 return -ENOMEM;
698 }
699 bank->irq_chip->chip.name = bank->name;
700
492fca28 701 bank->irq_domain = irq_domain_create_linear(bank->fwnode,
6f5e41bd 702 bank->nr_pins, &exynos_eint_irqd_ops, bank);
a04b07c0
TF
703 if (!bank->irq_domain) {
704 dev_err(dev, "wkup irq domain add failed\n");
5c7f48dd 705 of_node_put(wkup_np);
a04b07c0
TF
706 return -ENXIO;
707 }
43b169db 708
492fca28 709 if (!fwnode_property_present(bank->fwnode, "interrupts")) {
a04b07c0
TF
710 bank->eint_type = EINT_TYPE_WKUP_MUX;
711 ++muxed_banks;
712 continue;
713 }
43b169db 714
a86854d0
KC
715 weint_data = devm_kcalloc(dev,
716 bank->nr_pins, sizeof(*weint_data),
717 GFP_KERNEL);
5c7f48dd
KK
718 if (!weint_data) {
719 of_node_put(wkup_np);
a04b07c0 720 return -ENOMEM;
5c7f48dd 721 }
43b169db 722
a04b07c0 723 for (idx = 0; idx < bank->nr_pins; ++idx) {
492fca28 724 irq = irq_of_parse_and_map(to_of_node(bank->fwnode), idx);
a04b07c0
TF
725 if (!irq) {
726 dev_err(dev, "irq number for eint-%s-%d not found\n",
727 bank->name, idx);
728 continue;
729 }
730 weint_data[idx].irq = idx;
731 weint_data[idx].bank = bank;
c21f7849
TG
732 irq_set_chained_handler_and_data(irq,
733 exynos_irq_eint0_15,
734 &weint_data[idx]);
43b169db
TA
735 }
736 }
a04b07c0 737
5c7f48dd
KK
738 if (!muxed_banks) {
739 of_node_put(wkup_np);
a04b07c0 740 return 0;
5c7f48dd 741 }
a04b07c0
TF
742
743 irq = irq_of_parse_and_map(wkup_np, 0);
5c7f48dd 744 of_node_put(wkup_np);
a04b07c0
TF
745 if (!irq) {
746 dev_err(dev, "irq number for muxed EINTs not found\n");
747 return 0;
748 }
749
750 muxed_data = devm_kzalloc(dev, sizeof(*muxed_data)
751 + muxed_banks*sizeof(struct samsung_pin_bank *), GFP_KERNEL);
fa5c0f46 752 if (!muxed_data)
a04b07c0 753 return -ENOMEM;
4e1e2111 754 muxed_data->nr_banks = muxed_banks;
a04b07c0 755
bb56fc35
TG
756 irq_set_chained_handler_and_data(irq, exynos_irq_demux_eint16_31,
757 muxed_data);
a04b07c0 758
1bf00d7a 759 bank = d->pin_banks;
a04b07c0 760 idx = 0;
1bf00d7a 761 for (i = 0; i < d->nr_banks; ++i, ++bank) {
a04b07c0
TF
762 if (bank->eint_type != EINT_TYPE_WKUP_MUX)
763 continue;
764
765 muxed_data->banks[idx++] = bank;
766 }
a04b07c0 767
43b169db
TA
768 return 0;
769}
770
7ccbc60c
TF
771static void exynos_pinctrl_suspend_bank(
772 struct samsung_pinctrl_drv_data *drvdata,
773 struct samsung_pin_bank *bank)
774{
775 struct exynos_eint_gpio_save *save = bank->soc_priv;
1b09c2b8 776 const void __iomem *regs = bank->eint_base;
7ccbc60c 777
f9c74474
AD
778 if (clk_enable(bank->drvdata->pclk)) {
779 dev_err(bank->gpio_chip.parent,
780 "unable to enable clock for saving state\n");
781 return;
782 }
783
7ccbc60c
TF
784 save->eint_con = readl(regs + EXYNOS_GPIO_ECON_OFFSET
785 + bank->eint_offset);
786 save->eint_fltcon0 = readl(regs + EXYNOS_GPIO_EFLTCON_OFFSET
787 + 2 * bank->eint_offset);
788 save->eint_fltcon1 = readl(regs + EXYNOS_GPIO_EFLTCON_OFFSET
789 + 2 * bank->eint_offset + 4);
f354157a
JB
790 save->eint_mask = readl(regs + bank->irq_chip->eint_mask
791 + bank->eint_offset);
7ccbc60c 792
f9c74474
AD
793 clk_disable(bank->drvdata->pclk);
794
7ccbc60c
TF
795 pr_debug("%s: save con %#010x\n", bank->name, save->eint_con);
796 pr_debug("%s: save fltcon0 %#010x\n", bank->name, save->eint_fltcon0);
797 pr_debug("%s: save fltcon1 %#010x\n", bank->name, save->eint_fltcon1);
f354157a 798 pr_debug("%s: save mask %#010x\n", bank->name, save->eint_mask);
7ccbc60c
TF
799}
800
884fdaa5
JK
801static void exynosauto_pinctrl_suspend_bank(struct samsung_pinctrl_drv_data *drvdata,
802 struct samsung_pin_bank *bank)
803{
804 struct exynos_eint_gpio_save *save = bank->soc_priv;
1b09c2b8 805 const void __iomem *regs = bank->eint_base;
884fdaa5 806
f9c74474
AD
807 if (clk_enable(bank->drvdata->pclk)) {
808 dev_err(bank->gpio_chip.parent,
809 "unable to enable clock for saving state\n");
810 return;
811 }
812
884fdaa5
JK
813 save->eint_con = readl(regs + bank->pctl_offset + bank->eint_con_offset);
814 save->eint_mask = readl(regs + bank->pctl_offset + bank->eint_mask_offset);
815
f9c74474
AD
816 clk_disable(bank->drvdata->pclk);
817
884fdaa5
JK
818 pr_debug("%s: save con %#010x\n", bank->name, save->eint_con);
819 pr_debug("%s: save mask %#010x\n", bank->name, save->eint_mask);
820}
821
cfa76ddf 822void exynos_pinctrl_suspend(struct samsung_pinctrl_drv_data *drvdata)
7ccbc60c 823{
1bf00d7a 824 struct samsung_pin_bank *bank = drvdata->pin_banks;
a8be2af0 825 struct exynos_irq_chip *irq_chip = NULL;
7ccbc60c
TF
826 int i;
827
a8be2af0 828 for (i = 0; i < drvdata->nr_banks; ++i, ++bank) {
884fdaa5
JK
829 if (bank->eint_type == EINT_TYPE_GPIO) {
830 if (bank->eint_con_offset)
831 exynosauto_pinctrl_suspend_bank(drvdata, bank);
832 else
833 exynos_pinctrl_suspend_bank(drvdata, bank);
834 }
a8be2af0
KK
835 else if (bank->eint_type == EINT_TYPE_WKUP) {
836 if (!irq_chip) {
837 irq_chip = bank->irq_chip;
b577a279
JB
838 irq_chip->set_eint_wakeup_mask(drvdata,
839 irq_chip);
a8be2af0
KK
840 }
841 }
842 }
7ccbc60c
TF
843}
844
845static void exynos_pinctrl_resume_bank(
846 struct samsung_pinctrl_drv_data *drvdata,
847 struct samsung_pin_bank *bank)
848{
849 struct exynos_eint_gpio_save *save = bank->soc_priv;
8b1bd11c 850 void __iomem *regs = bank->eint_base;
7ccbc60c 851
f9c74474
AD
852 if (clk_enable(bank->drvdata->pclk)) {
853 dev_err(bank->gpio_chip.parent,
854 "unable to enable clock for restoring state\n");
855 return;
856 }
857
7ccbc60c
TF
858 pr_debug("%s: con %#010x => %#010x\n", bank->name,
859 readl(regs + EXYNOS_GPIO_ECON_OFFSET
860 + bank->eint_offset), save->eint_con);
861 pr_debug("%s: fltcon0 %#010x => %#010x\n", bank->name,
862 readl(regs + EXYNOS_GPIO_EFLTCON_OFFSET
863 + 2 * bank->eint_offset), save->eint_fltcon0);
864 pr_debug("%s: fltcon1 %#010x => %#010x\n", bank->name,
865 readl(regs + EXYNOS_GPIO_EFLTCON_OFFSET
866 + 2 * bank->eint_offset + 4), save->eint_fltcon1);
f354157a
JB
867 pr_debug("%s: mask %#010x => %#010x\n", bank->name,
868 readl(regs + bank->irq_chip->eint_mask
869 + bank->eint_offset), save->eint_mask);
7ccbc60c
TF
870
871 writel(save->eint_con, regs + EXYNOS_GPIO_ECON_OFFSET
872 + bank->eint_offset);
873 writel(save->eint_fltcon0, regs + EXYNOS_GPIO_EFLTCON_OFFSET
874 + 2 * bank->eint_offset);
875 writel(save->eint_fltcon1, regs + EXYNOS_GPIO_EFLTCON_OFFSET
876 + 2 * bank->eint_offset + 4);
f354157a
JB
877 writel(save->eint_mask, regs + bank->irq_chip->eint_mask
878 + bank->eint_offset);
f9c74474
AD
879
880 clk_disable(bank->drvdata->pclk);
7ccbc60c
TF
881}
882
884fdaa5
JK
883static void exynosauto_pinctrl_resume_bank(struct samsung_pinctrl_drv_data *drvdata,
884 struct samsung_pin_bank *bank)
885{
886 struct exynos_eint_gpio_save *save = bank->soc_priv;
887 void __iomem *regs = bank->eint_base;
888
f9c74474
AD
889 if (clk_enable(bank->drvdata->pclk)) {
890 dev_err(bank->gpio_chip.parent,
891 "unable to enable clock for restoring state\n");
892 return;
893 }
894
884fdaa5
JK
895 pr_debug("%s: con %#010x => %#010x\n", bank->name,
896 readl(regs + bank->pctl_offset + bank->eint_con_offset), save->eint_con);
897 pr_debug("%s: mask %#010x => %#010x\n", bank->name,
898 readl(regs + bank->pctl_offset + bank->eint_mask_offset), save->eint_mask);
899
900 writel(save->eint_con, regs + bank->pctl_offset + bank->eint_con_offset);
901 writel(save->eint_mask, regs + bank->pctl_offset + bank->eint_mask_offset);
f9c74474
AD
902
903 clk_disable(bank->drvdata->pclk);
884fdaa5
JK
904}
905
cfa76ddf 906void exynos_pinctrl_resume(struct samsung_pinctrl_drv_data *drvdata)
7ccbc60c 907{
1bf00d7a 908 struct samsung_pin_bank *bank = drvdata->pin_banks;
7ccbc60c
TF
909 int i;
910
1bf00d7a 911 for (i = 0; i < drvdata->nr_banks; ++i, ++bank)
884fdaa5
JK
912 if (bank->eint_type == EINT_TYPE_GPIO) {
913 if (bank->eint_con_offset)
914 exynosauto_pinctrl_resume_bank(drvdata, bank);
915 else
916 exynos_pinctrl_resume_bank(drvdata, bank);
917 }
7ccbc60c
TF
918}
919
07731019
MS
920static void exynos_retention_enable(struct samsung_pinctrl_drv_data *drvdata)
921{
922 if (drvdata->retention_ctrl->refcnt)
923 atomic_inc(drvdata->retention_ctrl->refcnt);
924}
925
926static void exynos_retention_disable(struct samsung_pinctrl_drv_data *drvdata)
927{
928 struct samsung_retention_ctrl *ctrl = drvdata->retention_ctrl;
929 struct regmap *pmu_regs = ctrl->priv;
930 int i;
931
932 if (ctrl->refcnt && !atomic_dec_and_test(ctrl->refcnt))
933 return;
934
935 for (i = 0; i < ctrl->nr_regs; i++)
936 regmap_write(pmu_regs, ctrl->regs[i], ctrl->value);
937}
938
cfa76ddf 939struct samsung_retention_ctrl *
07731019
MS
940exynos_retention_init(struct samsung_pinctrl_drv_data *drvdata,
941 const struct samsung_retention_data *data)
942{
943 struct samsung_retention_ctrl *ctrl;
944 struct regmap *pmu_regs;
8fe9bf07 945 int i;
07731019
MS
946
947 ctrl = devm_kzalloc(drvdata->dev, sizeof(*ctrl), GFP_KERNEL);
948 if (!ctrl)
949 return ERR_PTR(-ENOMEM);
950
951 pmu_regs = exynos_get_pmu_regmap();
952 if (IS_ERR(pmu_regs))
953 return ERR_CAST(pmu_regs);
954
955 ctrl->priv = pmu_regs;
956 ctrl->regs = data->regs;
957 ctrl->nr_regs = data->nr_regs;
958 ctrl->value = data->value;
959 ctrl->refcnt = data->refcnt;
960 ctrl->enable = exynos_retention_enable;
961 ctrl->disable = exynos_retention_disable;
962
8fe9bf07
MS
963 /* Ensure that retention is disabled on driver init */
964 for (i = 0; i < ctrl->nr_regs; i++)
965 regmap_write(pmu_regs, ctrl->regs[i], ctrl->value);
966
07731019
MS
967 return ctrl;
968}