1 // SPDX-License-Identifier: GPL-2.0+
3 // Exynos specific support for Samsung pinctrl/gpiolib driver with eint support.
5 // Copyright (c) 2012 Samsung Electronics Co., Ltd.
6 // http://www.samsung.com
7 // Copyright (c) 2012 Linaro Ltd
8 // http://www.linaro.org
10 // Author: Thomas Abraham <thomas.ab@samsung.com>
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.
16 #include <linux/device.h>
17 #include <linux/interrupt.h>
18 #include <linux/irqdomain.h>
19 #include <linux/irq.h>
20 #include <linux/irqchip/chained_irq.h>
22 #include <linux/of_irq.h>
23 #include <linux/slab.h>
24 #include <linux/spinlock.h>
25 #include <linux/regmap.h>
26 #include <linux/err.h>
27 #include <linux/soc/samsung/exynos-pmu.h>
28 #include <linux/soc/samsung/exynos-regs-pmu.h>
30 #include <dt-bindings/pinctrl/samsung.h>
32 #include "pinctrl-samsung.h"
33 #include "pinctrl-exynos.h"
35 struct exynos_irq_chip
{
41 u32
*eint_wake_mask_value
;
42 u32 eint_wake_mask_reg
;
43 void (*set_eint_wakeup_mask
)(struct samsung_pinctrl_drv_data
*drvdata
,
44 struct exynos_irq_chip
*irq_chip
);
47 static inline struct exynos_irq_chip
*to_exynos_irq_chip(struct irq_chip
*chip
)
49 return container_of(chip
, struct exynos_irq_chip
, chip
);
52 static void exynos_irq_mask(struct irq_data
*irqd
)
54 struct irq_chip
*chip
= irq_data_get_irq_chip(irqd
);
55 struct exynos_irq_chip
*our_chip
= to_exynos_irq_chip(chip
);
56 struct samsung_pin_bank
*bank
= irq_data_get_irq_chip_data(irqd
);
57 unsigned long reg_mask
= our_chip
->eint_mask
+ bank
->eint_offset
;
61 spin_lock_irqsave(&bank
->slock
, flags
);
63 mask
= readl(bank
->eint_base
+ reg_mask
);
64 mask
|= 1 << irqd
->hwirq
;
65 writel(mask
, bank
->eint_base
+ reg_mask
);
67 spin_unlock_irqrestore(&bank
->slock
, flags
);
70 static void exynos_irq_ack(struct irq_data
*irqd
)
72 struct irq_chip
*chip
= irq_data_get_irq_chip(irqd
);
73 struct exynos_irq_chip
*our_chip
= to_exynos_irq_chip(chip
);
74 struct samsung_pin_bank
*bank
= irq_data_get_irq_chip_data(irqd
);
75 unsigned long reg_pend
= our_chip
->eint_pend
+ bank
->eint_offset
;
77 writel(1 << irqd
->hwirq
, bank
->eint_base
+ reg_pend
);
80 static void exynos_irq_unmask(struct irq_data
*irqd
)
82 struct irq_chip
*chip
= irq_data_get_irq_chip(irqd
);
83 struct exynos_irq_chip
*our_chip
= to_exynos_irq_chip(chip
);
84 struct samsung_pin_bank
*bank
= irq_data_get_irq_chip_data(irqd
);
85 unsigned long reg_mask
= our_chip
->eint_mask
+ bank
->eint_offset
;
90 * Ack level interrupts right before unmask
92 * If we don't do this we'll get a double-interrupt. Level triggered
93 * interrupts must not fire an interrupt if the level is not
94 * _currently_ active, even if it was active while the interrupt was
97 if (irqd_get_trigger_type(irqd
) & IRQ_TYPE_LEVEL_MASK
)
100 spin_lock_irqsave(&bank
->slock
, flags
);
102 mask
= readl(bank
->eint_base
+ reg_mask
);
103 mask
&= ~(1 << irqd
->hwirq
);
104 writel(mask
, bank
->eint_base
+ reg_mask
);
106 spin_unlock_irqrestore(&bank
->slock
, flags
);
109 static int exynos_irq_set_type(struct irq_data
*irqd
, unsigned int type
)
111 struct irq_chip
*chip
= irq_data_get_irq_chip(irqd
);
112 struct exynos_irq_chip
*our_chip
= to_exynos_irq_chip(chip
);
113 struct samsung_pin_bank
*bank
= irq_data_get_irq_chip_data(irqd
);
114 unsigned int shift
= EXYNOS_EINT_CON_LEN
* irqd
->hwirq
;
115 unsigned int con
, trig_type
;
116 unsigned long reg_con
= our_chip
->eint_con
+ bank
->eint_offset
;
119 case IRQ_TYPE_EDGE_RISING
:
120 trig_type
= EXYNOS_EINT_EDGE_RISING
;
122 case IRQ_TYPE_EDGE_FALLING
:
123 trig_type
= EXYNOS_EINT_EDGE_FALLING
;
125 case IRQ_TYPE_EDGE_BOTH
:
126 trig_type
= EXYNOS_EINT_EDGE_BOTH
;
128 case IRQ_TYPE_LEVEL_HIGH
:
129 trig_type
= EXYNOS_EINT_LEVEL_HIGH
;
131 case IRQ_TYPE_LEVEL_LOW
:
132 trig_type
= EXYNOS_EINT_LEVEL_LOW
;
135 pr_err("unsupported external interrupt type\n");
139 if (type
& IRQ_TYPE_EDGE_BOTH
)
140 irq_set_handler_locked(irqd
, handle_edge_irq
);
142 irq_set_handler_locked(irqd
, handle_level_irq
);
144 con
= readl(bank
->eint_base
+ reg_con
);
145 con
&= ~(EXYNOS_EINT_CON_MASK
<< shift
);
146 con
|= trig_type
<< shift
;
147 writel(con
, bank
->eint_base
+ reg_con
);
152 static int exynos_irq_request_resources(struct irq_data
*irqd
)
154 struct samsung_pin_bank
*bank
= irq_data_get_irq_chip_data(irqd
);
155 const struct samsung_pin_bank_type
*bank_type
= bank
->type
;
156 unsigned long reg_con
, flags
;
157 unsigned int shift
, mask
, con
;
160 ret
= gpiochip_lock_as_irq(&bank
->gpio_chip
, irqd
->hwirq
);
162 dev_err(bank
->gpio_chip
.parent
,
163 "unable to lock pin %s-%lu IRQ\n",
164 bank
->name
, irqd
->hwirq
);
168 reg_con
= bank
->pctl_offset
+ bank_type
->reg_offset
[PINCFG_TYPE_FUNC
];
169 shift
= irqd
->hwirq
* bank_type
->fld_width
[PINCFG_TYPE_FUNC
];
170 mask
= (1 << bank_type
->fld_width
[PINCFG_TYPE_FUNC
]) - 1;
172 spin_lock_irqsave(&bank
->slock
, flags
);
174 con
= readl(bank
->pctl_base
+ reg_con
);
175 con
&= ~(mask
<< shift
);
176 con
|= EXYNOS_PIN_FUNC_EINT
<< shift
;
177 writel(con
, bank
->pctl_base
+ reg_con
);
179 spin_unlock_irqrestore(&bank
->slock
, flags
);
184 static void exynos_irq_release_resources(struct irq_data
*irqd
)
186 struct samsung_pin_bank
*bank
= irq_data_get_irq_chip_data(irqd
);
187 const struct samsung_pin_bank_type
*bank_type
= bank
->type
;
188 unsigned long reg_con
, flags
;
189 unsigned int shift
, mask
, con
;
191 reg_con
= bank
->pctl_offset
+ bank_type
->reg_offset
[PINCFG_TYPE_FUNC
];
192 shift
= irqd
->hwirq
* bank_type
->fld_width
[PINCFG_TYPE_FUNC
];
193 mask
= (1 << bank_type
->fld_width
[PINCFG_TYPE_FUNC
]) - 1;
195 spin_lock_irqsave(&bank
->slock
, flags
);
197 con
= readl(bank
->pctl_base
+ reg_con
);
198 con
&= ~(mask
<< shift
);
199 con
|= EXYNOS_PIN_FUNC_INPUT
<< shift
;
200 writel(con
, bank
->pctl_base
+ reg_con
);
202 spin_unlock_irqrestore(&bank
->slock
, flags
);
204 gpiochip_unlock_as_irq(&bank
->gpio_chip
, irqd
->hwirq
);
208 * irq_chip for gpio interrupts.
210 static const struct exynos_irq_chip exynos_gpio_irq_chip __initconst
= {
212 .name
= "exynos_gpio_irq_chip",
213 .irq_unmask
= exynos_irq_unmask
,
214 .irq_mask
= exynos_irq_mask
,
215 .irq_ack
= exynos_irq_ack
,
216 .irq_set_type
= exynos_irq_set_type
,
217 .irq_request_resources
= exynos_irq_request_resources
,
218 .irq_release_resources
= exynos_irq_release_resources
,
220 .eint_con
= EXYNOS_GPIO_ECON_OFFSET
,
221 .eint_mask
= EXYNOS_GPIO_EMASK_OFFSET
,
222 .eint_pend
= EXYNOS_GPIO_EPEND_OFFSET
,
223 /* eint_wake_mask_value not used */
226 static int exynos_eint_irq_map(struct irq_domain
*h
, unsigned int virq
,
229 struct samsung_pin_bank
*b
= h
->host_data
;
231 irq_set_chip_data(virq
, b
);
232 irq_set_chip_and_handler(virq
, &b
->irq_chip
->chip
,
238 * irq domain callbacks for external gpio and wakeup interrupt controllers.
240 static const struct irq_domain_ops exynos_eint_irqd_ops
= {
241 .map
= exynos_eint_irq_map
,
242 .xlate
= irq_domain_xlate_twocell
,
245 static irqreturn_t
exynos_eint_gpio_irq(int irq
, void *data
)
247 struct samsung_pinctrl_drv_data
*d
= data
;
248 struct samsung_pin_bank
*bank
= d
->pin_banks
;
249 unsigned int svc
, group
, pin
, virq
;
251 svc
= readl(bank
->eint_base
+ EXYNOS_SVC_OFFSET
);
252 group
= EXYNOS_SVC_GROUP(svc
);
253 pin
= svc
& EXYNOS_SVC_NUM_MASK
;
259 virq
= irq_linear_revmap(bank
->irq_domain
, pin
);
262 generic_handle_irq(virq
);
266 struct exynos_eint_gpio_save
{
274 * exynos_eint_gpio_init() - setup handling of external gpio interrupts.
275 * @d: driver data of samsung pinctrl driver.
277 __init
int exynos_eint_gpio_init(struct samsung_pinctrl_drv_data
*d
)
279 struct samsung_pin_bank
*bank
;
280 struct device
*dev
= d
->dev
;
285 dev_err(dev
, "irq number not available\n");
289 ret
= devm_request_irq(dev
, d
->irq
, exynos_eint_gpio_irq
,
290 0, dev_name(dev
), d
);
292 dev_err(dev
, "irq request failed\n");
297 for (i
= 0; i
< d
->nr_banks
; ++i
, ++bank
) {
298 if (bank
->eint_type
!= EINT_TYPE_GPIO
)
301 bank
->irq_chip
= devm_kmemdup(dev
, &exynos_gpio_irq_chip
,
302 sizeof(*bank
->irq_chip
), GFP_KERNEL
);
303 if (!bank
->irq_chip
) {
307 bank
->irq_chip
->chip
.name
= bank
->name
;
309 bank
->irq_domain
= irq_domain_add_linear(bank
->of_node
,
310 bank
->nr_pins
, &exynos_eint_irqd_ops
, bank
);
311 if (!bank
->irq_domain
) {
312 dev_err(dev
, "gpio irq domain add failed\n");
317 bank
->soc_priv
= devm_kzalloc(d
->dev
,
318 sizeof(struct exynos_eint_gpio_save
), GFP_KERNEL
);
319 if (!bank
->soc_priv
) {
320 irq_domain_remove(bank
->irq_domain
);
330 for (--i
, --bank
; i
>= 0; --i
, --bank
) {
331 if (bank
->eint_type
!= EINT_TYPE_GPIO
)
333 irq_domain_remove(bank
->irq_domain
);
339 static int exynos_wkup_irq_set_wake(struct irq_data
*irqd
, unsigned int on
)
341 struct irq_chip
*chip
= irq_data_get_irq_chip(irqd
);
342 struct exynos_irq_chip
*our_chip
= to_exynos_irq_chip(chip
);
343 struct samsung_pin_bank
*bank
= irq_data_get_irq_chip_data(irqd
);
344 unsigned long bit
= 1UL << (2 * bank
->eint_offset
+ irqd
->hwirq
);
346 pr_info("wake %s for irq %d\n", on
? "enabled" : "disabled", irqd
->irq
);
349 *our_chip
->eint_wake_mask_value
|= bit
;
351 *our_chip
->eint_wake_mask_value
&= ~bit
;
357 exynos_pinctrl_set_eint_wakeup_mask(struct samsung_pinctrl_drv_data
*drvdata
,
358 struct exynos_irq_chip
*irq_chip
)
360 struct regmap
*pmu_regs
;
362 if (!drvdata
->retention_ctrl
|| !drvdata
->retention_ctrl
->priv
) {
363 dev_warn(drvdata
->dev
,
364 "No retention data configured bank with external wakeup interrupt. Wake-up mask will not be set.\n");
368 pmu_regs
= drvdata
->retention_ctrl
->priv
;
369 dev_info(drvdata
->dev
,
370 "Setting external wakeup interrupt mask: 0x%x\n",
371 *irq_chip
->eint_wake_mask_value
);
373 regmap_write(pmu_regs
, irq_chip
->eint_wake_mask_reg
,
374 *irq_chip
->eint_wake_mask_value
);
378 s5pv210_pinctrl_set_eint_wakeup_mask(struct samsung_pinctrl_drv_data
*drvdata
,
379 struct exynos_irq_chip
*irq_chip
)
382 void __iomem
*clk_base
;
384 if (!drvdata
->retention_ctrl
|| !drvdata
->retention_ctrl
->priv
) {
385 dev_warn(drvdata
->dev
,
386 "No retention data configured bank with external wakeup interrupt. Wake-up mask will not be set.\n");
391 clk_base
= (void __iomem
*) drvdata
->retention_ctrl
->priv
;
393 __raw_writel(*irq_chip
->eint_wake_mask_value
,
394 clk_base
+ irq_chip
->eint_wake_mask_reg
);
397 static u32 eint_wake_mask_value
= EXYNOS_EINT_WAKEUP_MASK_DISABLED
;
399 * irq_chip for wakeup interrupts
401 static const struct exynos_irq_chip s5pv210_wkup_irq_chip __initconst
= {
403 .name
= "s5pv210_wkup_irq_chip",
404 .irq_unmask
= exynos_irq_unmask
,
405 .irq_mask
= exynos_irq_mask
,
406 .irq_ack
= exynos_irq_ack
,
407 .irq_set_type
= exynos_irq_set_type
,
408 .irq_set_wake
= exynos_wkup_irq_set_wake
,
409 .irq_request_resources
= exynos_irq_request_resources
,
410 .irq_release_resources
= exynos_irq_release_resources
,
412 .eint_con
= EXYNOS_WKUP_ECON_OFFSET
,
413 .eint_mask
= EXYNOS_WKUP_EMASK_OFFSET
,
414 .eint_pend
= EXYNOS_WKUP_EPEND_OFFSET
,
415 .eint_wake_mask_value
= &eint_wake_mask_value
,
416 /* Only differences with exynos4210_wkup_irq_chip: */
417 .eint_wake_mask_reg
= S5PV210_EINT_WAKEUP_MASK
,
418 .set_eint_wakeup_mask
= s5pv210_pinctrl_set_eint_wakeup_mask
,
421 static const struct exynos_irq_chip exynos4210_wkup_irq_chip __initconst
= {
423 .name
= "exynos4210_wkup_irq_chip",
424 .irq_unmask
= exynos_irq_unmask
,
425 .irq_mask
= exynos_irq_mask
,
426 .irq_ack
= exynos_irq_ack
,
427 .irq_set_type
= exynos_irq_set_type
,
428 .irq_set_wake
= exynos_wkup_irq_set_wake
,
429 .irq_request_resources
= exynos_irq_request_resources
,
430 .irq_release_resources
= exynos_irq_release_resources
,
432 .eint_con
= EXYNOS_WKUP_ECON_OFFSET
,
433 .eint_mask
= EXYNOS_WKUP_EMASK_OFFSET
,
434 .eint_pend
= EXYNOS_WKUP_EPEND_OFFSET
,
435 .eint_wake_mask_value
= &eint_wake_mask_value
,
436 .eint_wake_mask_reg
= EXYNOS_EINT_WAKEUP_MASK
,
437 .set_eint_wakeup_mask
= exynos_pinctrl_set_eint_wakeup_mask
,
440 static const struct exynos_irq_chip exynos7_wkup_irq_chip __initconst
= {
442 .name
= "exynos7_wkup_irq_chip",
443 .irq_unmask
= exynos_irq_unmask
,
444 .irq_mask
= exynos_irq_mask
,
445 .irq_ack
= exynos_irq_ack
,
446 .irq_set_type
= exynos_irq_set_type
,
447 .irq_set_wake
= exynos_wkup_irq_set_wake
,
448 .irq_request_resources
= exynos_irq_request_resources
,
449 .irq_release_resources
= exynos_irq_release_resources
,
451 .eint_con
= EXYNOS7_WKUP_ECON_OFFSET
,
452 .eint_mask
= EXYNOS7_WKUP_EMASK_OFFSET
,
453 .eint_pend
= EXYNOS7_WKUP_EPEND_OFFSET
,
454 .eint_wake_mask_value
= &eint_wake_mask_value
,
455 .eint_wake_mask_reg
= EXYNOS5433_EINT_WAKEUP_MASK
,
456 .set_eint_wakeup_mask
= exynos_pinctrl_set_eint_wakeup_mask
,
459 /* list of external wakeup controllers supported */
460 static const struct of_device_id exynos_wkup_irq_ids
[] = {
461 { .compatible
= "samsung,s5pv210-wakeup-eint",
462 .data
= &s5pv210_wkup_irq_chip
},
463 { .compatible
= "samsung,exynos4210-wakeup-eint",
464 .data
= &exynos4210_wkup_irq_chip
},
465 { .compatible
= "samsung,exynos7-wakeup-eint",
466 .data
= &exynos7_wkup_irq_chip
},
470 /* interrupt handler for wakeup interrupts 0..15 */
471 static void exynos_irq_eint0_15(struct irq_desc
*desc
)
473 struct exynos_weint_data
*eintd
= irq_desc_get_handler_data(desc
);
474 struct samsung_pin_bank
*bank
= eintd
->bank
;
475 struct irq_chip
*chip
= irq_desc_get_chip(desc
);
478 chained_irq_enter(chip
, desc
);
480 eint_irq
= irq_linear_revmap(bank
->irq_domain
, eintd
->irq
);
481 generic_handle_irq(eint_irq
);
483 chained_irq_exit(chip
, desc
);
486 static inline void exynos_irq_demux_eint(unsigned long pend
,
487 struct irq_domain
*domain
)
493 generic_handle_irq(irq_find_mapping(domain
, irq
));
498 /* interrupt handler for wakeup interrupt 16 */
499 static void exynos_irq_demux_eint16_31(struct irq_desc
*desc
)
501 struct irq_chip
*chip
= irq_desc_get_chip(desc
);
502 struct exynos_muxed_weint_data
*eintd
= irq_desc_get_handler_data(desc
);
507 chained_irq_enter(chip
, desc
);
509 for (i
= 0; i
< eintd
->nr_banks
; ++i
) {
510 struct samsung_pin_bank
*b
= eintd
->banks
[i
];
511 pend
= readl(b
->eint_base
+ b
->irq_chip
->eint_pend
513 mask
= readl(b
->eint_base
+ b
->irq_chip
->eint_mask
515 exynos_irq_demux_eint(pend
& ~mask
, b
->irq_domain
);
518 chained_irq_exit(chip
, desc
);
522 * exynos_eint_wkup_init() - setup handling of external wakeup interrupts.
523 * @d: driver data of samsung pinctrl driver.
525 __init
int exynos_eint_wkup_init(struct samsung_pinctrl_drv_data
*d
)
527 struct device
*dev
= d
->dev
;
528 struct device_node
*wkup_np
= NULL
;
529 struct device_node
*np
;
530 struct samsung_pin_bank
*bank
;
531 struct exynos_weint_data
*weint_data
;
532 struct exynos_muxed_weint_data
*muxed_data
;
533 const struct exynos_irq_chip
*irq_chip
;
534 unsigned int muxed_banks
= 0;
538 for_each_child_of_node(dev
->of_node
, np
) {
539 const struct of_device_id
*match
;
541 match
= of_match_node(exynos_wkup_irq_ids
, np
);
543 irq_chip
= match
->data
;
552 for (i
= 0; i
< d
->nr_banks
; ++i
, ++bank
) {
553 if (bank
->eint_type
!= EINT_TYPE_WKUP
)
556 bank
->irq_chip
= devm_kmemdup(dev
, irq_chip
, sizeof(*irq_chip
),
558 if (!bank
->irq_chip
) {
559 of_node_put(wkup_np
);
562 bank
->irq_chip
->chip
.name
= bank
->name
;
564 bank
->irq_domain
= irq_domain_add_linear(bank
->of_node
,
565 bank
->nr_pins
, &exynos_eint_irqd_ops
, bank
);
566 if (!bank
->irq_domain
) {
567 dev_err(dev
, "wkup irq domain add failed\n");
568 of_node_put(wkup_np
);
572 if (!of_find_property(bank
->of_node
, "interrupts", NULL
)) {
573 bank
->eint_type
= EINT_TYPE_WKUP_MUX
;
578 weint_data
= devm_kcalloc(dev
,
579 bank
->nr_pins
, sizeof(*weint_data
),
582 of_node_put(wkup_np
);
586 for (idx
= 0; idx
< bank
->nr_pins
; ++idx
) {
587 irq
= irq_of_parse_and_map(bank
->of_node
, idx
);
589 dev_err(dev
, "irq number for eint-%s-%d not found\n",
593 weint_data
[idx
].irq
= idx
;
594 weint_data
[idx
].bank
= bank
;
595 irq_set_chained_handler_and_data(irq
,
602 of_node_put(wkup_np
);
606 irq
= irq_of_parse_and_map(wkup_np
, 0);
607 of_node_put(wkup_np
);
609 dev_err(dev
, "irq number for muxed EINTs not found\n");
613 muxed_data
= devm_kzalloc(dev
, sizeof(*muxed_data
)
614 + muxed_banks
*sizeof(struct samsung_pin_bank
*), GFP_KERNEL
);
618 irq_set_chained_handler_and_data(irq
, exynos_irq_demux_eint16_31
,
623 for (i
= 0; i
< d
->nr_banks
; ++i
, ++bank
) {
624 if (bank
->eint_type
!= EINT_TYPE_WKUP_MUX
)
627 muxed_data
->banks
[idx
++] = bank
;
629 muxed_data
->nr_banks
= muxed_banks
;
634 static void exynos_pinctrl_suspend_bank(
635 struct samsung_pinctrl_drv_data
*drvdata
,
636 struct samsung_pin_bank
*bank
)
638 struct exynos_eint_gpio_save
*save
= bank
->soc_priv
;
639 void __iomem
*regs
= bank
->eint_base
;
641 save
->eint_con
= readl(regs
+ EXYNOS_GPIO_ECON_OFFSET
642 + bank
->eint_offset
);
643 save
->eint_fltcon0
= readl(regs
+ EXYNOS_GPIO_EFLTCON_OFFSET
644 + 2 * bank
->eint_offset
);
645 save
->eint_fltcon1
= readl(regs
+ EXYNOS_GPIO_EFLTCON_OFFSET
646 + 2 * bank
->eint_offset
+ 4);
647 save
->eint_mask
= readl(regs
+ bank
->irq_chip
->eint_mask
648 + bank
->eint_offset
);
650 pr_debug("%s: save con %#010x\n", bank
->name
, save
->eint_con
);
651 pr_debug("%s: save fltcon0 %#010x\n", bank
->name
, save
->eint_fltcon0
);
652 pr_debug("%s: save fltcon1 %#010x\n", bank
->name
, save
->eint_fltcon1
);
653 pr_debug("%s: save mask %#010x\n", bank
->name
, save
->eint_mask
);
656 void exynos_pinctrl_suspend(struct samsung_pinctrl_drv_data
*drvdata
)
658 struct samsung_pin_bank
*bank
= drvdata
->pin_banks
;
659 struct exynos_irq_chip
*irq_chip
= NULL
;
662 for (i
= 0; i
< drvdata
->nr_banks
; ++i
, ++bank
) {
663 if (bank
->eint_type
== EINT_TYPE_GPIO
)
664 exynos_pinctrl_suspend_bank(drvdata
, bank
);
665 else if (bank
->eint_type
== EINT_TYPE_WKUP
) {
667 irq_chip
= bank
->irq_chip
;
668 irq_chip
->set_eint_wakeup_mask(drvdata
,
675 static void exynos_pinctrl_resume_bank(
676 struct samsung_pinctrl_drv_data
*drvdata
,
677 struct samsung_pin_bank
*bank
)
679 struct exynos_eint_gpio_save
*save
= bank
->soc_priv
;
680 void __iomem
*regs
= bank
->eint_base
;
682 pr_debug("%s: con %#010x => %#010x\n", bank
->name
,
683 readl(regs
+ EXYNOS_GPIO_ECON_OFFSET
684 + bank
->eint_offset
), save
->eint_con
);
685 pr_debug("%s: fltcon0 %#010x => %#010x\n", bank
->name
,
686 readl(regs
+ EXYNOS_GPIO_EFLTCON_OFFSET
687 + 2 * bank
->eint_offset
), save
->eint_fltcon0
);
688 pr_debug("%s: fltcon1 %#010x => %#010x\n", bank
->name
,
689 readl(regs
+ EXYNOS_GPIO_EFLTCON_OFFSET
690 + 2 * bank
->eint_offset
+ 4), save
->eint_fltcon1
);
691 pr_debug("%s: mask %#010x => %#010x\n", bank
->name
,
692 readl(regs
+ bank
->irq_chip
->eint_mask
693 + bank
->eint_offset
), save
->eint_mask
);
695 writel(save
->eint_con
, regs
+ EXYNOS_GPIO_ECON_OFFSET
696 + bank
->eint_offset
);
697 writel(save
->eint_fltcon0
, regs
+ EXYNOS_GPIO_EFLTCON_OFFSET
698 + 2 * bank
->eint_offset
);
699 writel(save
->eint_fltcon1
, regs
+ EXYNOS_GPIO_EFLTCON_OFFSET
700 + 2 * bank
->eint_offset
+ 4);
701 writel(save
->eint_mask
, regs
+ bank
->irq_chip
->eint_mask
702 + bank
->eint_offset
);
705 void exynos_pinctrl_resume(struct samsung_pinctrl_drv_data
*drvdata
)
707 struct samsung_pin_bank
*bank
= drvdata
->pin_banks
;
710 for (i
= 0; i
< drvdata
->nr_banks
; ++i
, ++bank
)
711 if (bank
->eint_type
== EINT_TYPE_GPIO
)
712 exynos_pinctrl_resume_bank(drvdata
, bank
);
715 static void exynos_retention_enable(struct samsung_pinctrl_drv_data
*drvdata
)
717 if (drvdata
->retention_ctrl
->refcnt
)
718 atomic_inc(drvdata
->retention_ctrl
->refcnt
);
721 static void exynos_retention_disable(struct samsung_pinctrl_drv_data
*drvdata
)
723 struct samsung_retention_ctrl
*ctrl
= drvdata
->retention_ctrl
;
724 struct regmap
*pmu_regs
= ctrl
->priv
;
727 if (ctrl
->refcnt
&& !atomic_dec_and_test(ctrl
->refcnt
))
730 for (i
= 0; i
< ctrl
->nr_regs
; i
++)
731 regmap_write(pmu_regs
, ctrl
->regs
[i
], ctrl
->value
);
734 struct samsung_retention_ctrl
*
735 exynos_retention_init(struct samsung_pinctrl_drv_data
*drvdata
,
736 const struct samsung_retention_data
*data
)
738 struct samsung_retention_ctrl
*ctrl
;
739 struct regmap
*pmu_regs
;
742 ctrl
= devm_kzalloc(drvdata
->dev
, sizeof(*ctrl
), GFP_KERNEL
);
744 return ERR_PTR(-ENOMEM
);
746 pmu_regs
= exynos_get_pmu_regmap();
747 if (IS_ERR(pmu_regs
))
748 return ERR_CAST(pmu_regs
);
750 ctrl
->priv
= pmu_regs
;
751 ctrl
->regs
= data
->regs
;
752 ctrl
->nr_regs
= data
->nr_regs
;
753 ctrl
->value
= data
->value
;
754 ctrl
->refcnt
= data
->refcnt
;
755 ctrl
->enable
= exynos_retention_enable
;
756 ctrl
->disable
= exynos_retention_disable
;
758 /* Ensure that retention is disabled on driver init */
759 for (i
= 0; i
< ctrl
->nr_regs
; i
++)
760 regmap_write(pmu_regs
, ctrl
->regs
[i
], ctrl
->value
);