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 struct exynos_irq_chip exynos_gpio_irq_chip
= {
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 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
)
300 bank
->irq_domain
= irq_domain_add_linear(bank
->of_node
,
301 bank
->nr_pins
, &exynos_eint_irqd_ops
, bank
);
302 if (!bank
->irq_domain
) {
303 dev_err(dev
, "gpio irq domain add failed\n");
308 bank
->soc_priv
= devm_kzalloc(d
->dev
,
309 sizeof(struct exynos_eint_gpio_save
), GFP_KERNEL
);
310 if (!bank
->soc_priv
) {
311 irq_domain_remove(bank
->irq_domain
);
316 bank
->irq_chip
= &exynos_gpio_irq_chip
;
322 for (--i
, --bank
; i
>= 0; --i
, --bank
) {
323 if (bank
->eint_type
!= EINT_TYPE_GPIO
)
325 irq_domain_remove(bank
->irq_domain
);
331 static u32 exynos_eint_wake_mask
= 0xffffffff;
333 u32
exynos_get_eint_wake_mask(void)
335 return exynos_eint_wake_mask
;
338 static int exynos_wkup_irq_set_wake(struct irq_data
*irqd
, unsigned int on
)
340 struct irq_chip
*chip
= irq_data_get_irq_chip(irqd
);
341 struct exynos_irq_chip
*our_chip
= to_exynos_irq_chip(chip
);
342 struct samsung_pin_bank
*bank
= irq_data_get_irq_chip_data(irqd
);
343 unsigned long bit
= 1UL << (2 * bank
->eint_offset
+ irqd
->hwirq
);
345 pr_info("wake %s for irq %d\n", on
? "enabled" : "disabled", irqd
->irq
);
348 exynos_eint_wake_mask
|= bit
;
350 exynos_eint_wake_mask
&= ~bit
;
351 our_chip
->eint_wake_mask_value
= exynos_eint_wake_mask
;
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
);
398 * irq_chip for wakeup interrupts
400 static const struct exynos_irq_chip s5pv210_wkup_irq_chip __initconst
= {
402 .name
= "s5pv210_wkup_irq_chip",
403 .irq_unmask
= exynos_irq_unmask
,
404 .irq_mask
= exynos_irq_mask
,
405 .irq_ack
= exynos_irq_ack
,
406 .irq_set_type
= exynos_irq_set_type
,
407 .irq_set_wake
= exynos_wkup_irq_set_wake
,
408 .irq_request_resources
= exynos_irq_request_resources
,
409 .irq_release_resources
= exynos_irq_release_resources
,
411 .eint_con
= EXYNOS_WKUP_ECON_OFFSET
,
412 .eint_mask
= EXYNOS_WKUP_EMASK_OFFSET
,
413 .eint_pend
= EXYNOS_WKUP_EPEND_OFFSET
,
414 .eint_wake_mask_value
= EXYNOS_EINT_WAKEUP_MASK_DISABLED
,
415 /* Only differences with exynos4210_wkup_irq_chip: */
416 .eint_wake_mask_reg
= S5PV210_EINT_WAKEUP_MASK
,
417 .set_eint_wakeup_mask
= s5pv210_pinctrl_set_eint_wakeup_mask
,
420 static const struct exynos_irq_chip exynos4210_wkup_irq_chip __initconst
= {
422 .name
= "exynos4210_wkup_irq_chip",
423 .irq_unmask
= exynos_irq_unmask
,
424 .irq_mask
= exynos_irq_mask
,
425 .irq_ack
= exynos_irq_ack
,
426 .irq_set_type
= exynos_irq_set_type
,
427 .irq_set_wake
= exynos_wkup_irq_set_wake
,
428 .irq_request_resources
= exynos_irq_request_resources
,
429 .irq_release_resources
= exynos_irq_release_resources
,
431 .eint_con
= EXYNOS_WKUP_ECON_OFFSET
,
432 .eint_mask
= EXYNOS_WKUP_EMASK_OFFSET
,
433 .eint_pend
= EXYNOS_WKUP_EPEND_OFFSET
,
434 .eint_wake_mask_value
= EXYNOS_EINT_WAKEUP_MASK_DISABLED
,
435 .eint_wake_mask_reg
= EXYNOS_EINT_WAKEUP_MASK
,
436 .set_eint_wakeup_mask
= exynos_pinctrl_set_eint_wakeup_mask
,
439 static const struct exynos_irq_chip exynos7_wkup_irq_chip __initconst
= {
441 .name
= "exynos7_wkup_irq_chip",
442 .irq_unmask
= exynos_irq_unmask
,
443 .irq_mask
= exynos_irq_mask
,
444 .irq_ack
= exynos_irq_ack
,
445 .irq_set_type
= exynos_irq_set_type
,
446 .irq_set_wake
= exynos_wkup_irq_set_wake
,
447 .irq_request_resources
= exynos_irq_request_resources
,
448 .irq_release_resources
= exynos_irq_release_resources
,
450 .eint_con
= EXYNOS7_WKUP_ECON_OFFSET
,
451 .eint_mask
= EXYNOS7_WKUP_EMASK_OFFSET
,
452 .eint_pend
= EXYNOS7_WKUP_EPEND_OFFSET
,
453 .eint_wake_mask_value
= EXYNOS_EINT_WAKEUP_MASK_DISABLED
,
454 .eint_wake_mask_reg
= EXYNOS5433_EINT_WAKEUP_MASK
,
455 .set_eint_wakeup_mask
= exynos_pinctrl_set_eint_wakeup_mask
,
458 /* list of external wakeup controllers supported */
459 static const struct of_device_id exynos_wkup_irq_ids
[] = {
460 { .compatible
= "samsung,s5pv210-wakeup-eint",
461 .data
= &s5pv210_wkup_irq_chip
},
462 { .compatible
= "samsung,exynos4210-wakeup-eint",
463 .data
= &exynos4210_wkup_irq_chip
},
464 { .compatible
= "samsung,exynos7-wakeup-eint",
465 .data
= &exynos7_wkup_irq_chip
},
469 /* interrupt handler for wakeup interrupts 0..15 */
470 static void exynos_irq_eint0_15(struct irq_desc
*desc
)
472 struct exynos_weint_data
*eintd
= irq_desc_get_handler_data(desc
);
473 struct samsung_pin_bank
*bank
= eintd
->bank
;
474 struct irq_chip
*chip
= irq_desc_get_chip(desc
);
477 chained_irq_enter(chip
, desc
);
479 eint_irq
= irq_linear_revmap(bank
->irq_domain
, eintd
->irq
);
480 generic_handle_irq(eint_irq
);
482 chained_irq_exit(chip
, desc
);
485 static inline void exynos_irq_demux_eint(unsigned long pend
,
486 struct irq_domain
*domain
)
492 generic_handle_irq(irq_find_mapping(domain
, irq
));
497 /* interrupt handler for wakeup interrupt 16 */
498 static void exynos_irq_demux_eint16_31(struct irq_desc
*desc
)
500 struct irq_chip
*chip
= irq_desc_get_chip(desc
);
501 struct exynos_muxed_weint_data
*eintd
= irq_desc_get_handler_data(desc
);
506 chained_irq_enter(chip
, desc
);
508 for (i
= 0; i
< eintd
->nr_banks
; ++i
) {
509 struct samsung_pin_bank
*b
= eintd
->banks
[i
];
510 pend
= readl(b
->eint_base
+ b
->irq_chip
->eint_pend
512 mask
= readl(b
->eint_base
+ b
->irq_chip
->eint_mask
514 exynos_irq_demux_eint(pend
& ~mask
, b
->irq_domain
);
517 chained_irq_exit(chip
, desc
);
521 * exynos_eint_wkup_init() - setup handling of external wakeup interrupts.
522 * @d: driver data of samsung pinctrl driver.
524 int exynos_eint_wkup_init(struct samsung_pinctrl_drv_data
*d
)
526 struct device
*dev
= d
->dev
;
527 struct device_node
*wkup_np
= NULL
;
528 struct device_node
*np
;
529 struct samsung_pin_bank
*bank
;
530 struct exynos_weint_data
*weint_data
;
531 struct exynos_muxed_weint_data
*muxed_data
;
532 struct exynos_irq_chip
*irq_chip
;
533 unsigned int muxed_banks
= 0;
537 for_each_child_of_node(dev
->of_node
, np
) {
538 const struct of_device_id
*match
;
540 match
= of_match_node(exynos_wkup_irq_ids
, np
);
542 irq_chip
= kmemdup(match
->data
,
543 sizeof(*irq_chip
), GFP_KERNEL
);
556 for (i
= 0; i
< d
->nr_banks
; ++i
, ++bank
) {
557 if (bank
->eint_type
!= EINT_TYPE_WKUP
)
560 bank
->irq_domain
= irq_domain_add_linear(bank
->of_node
,
561 bank
->nr_pins
, &exynos_eint_irqd_ops
, bank
);
562 if (!bank
->irq_domain
) {
563 dev_err(dev
, "wkup irq domain add failed\n");
564 of_node_put(wkup_np
);
568 bank
->irq_chip
= irq_chip
;
570 if (!of_find_property(bank
->of_node
, "interrupts", NULL
)) {
571 bank
->eint_type
= EINT_TYPE_WKUP_MUX
;
576 weint_data
= devm_kcalloc(dev
,
577 bank
->nr_pins
, sizeof(*weint_data
),
580 of_node_put(wkup_np
);
584 for (idx
= 0; idx
< bank
->nr_pins
; ++idx
) {
585 irq
= irq_of_parse_and_map(bank
->of_node
, idx
);
587 dev_err(dev
, "irq number for eint-%s-%d not found\n",
591 weint_data
[idx
].irq
= idx
;
592 weint_data
[idx
].bank
= bank
;
593 irq_set_chained_handler_and_data(irq
,
600 of_node_put(wkup_np
);
604 irq
= irq_of_parse_and_map(wkup_np
, 0);
605 of_node_put(wkup_np
);
607 dev_err(dev
, "irq number for muxed EINTs not found\n");
611 muxed_data
= devm_kzalloc(dev
, sizeof(*muxed_data
)
612 + muxed_banks
*sizeof(struct samsung_pin_bank
*), GFP_KERNEL
);
616 irq_set_chained_handler_and_data(irq
, exynos_irq_demux_eint16_31
,
621 for (i
= 0; i
< d
->nr_banks
; ++i
, ++bank
) {
622 if (bank
->eint_type
!= EINT_TYPE_WKUP_MUX
)
625 muxed_data
->banks
[idx
++] = bank
;
627 muxed_data
->nr_banks
= muxed_banks
;
632 static void exynos_pinctrl_suspend_bank(
633 struct samsung_pinctrl_drv_data
*drvdata
,
634 struct samsung_pin_bank
*bank
)
636 struct exynos_eint_gpio_save
*save
= bank
->soc_priv
;
637 void __iomem
*regs
= bank
->eint_base
;
639 save
->eint_con
= readl(regs
+ EXYNOS_GPIO_ECON_OFFSET
640 + bank
->eint_offset
);
641 save
->eint_fltcon0
= readl(regs
+ EXYNOS_GPIO_EFLTCON_OFFSET
642 + 2 * bank
->eint_offset
);
643 save
->eint_fltcon1
= readl(regs
+ EXYNOS_GPIO_EFLTCON_OFFSET
644 + 2 * bank
->eint_offset
+ 4);
645 save
->eint_mask
= readl(regs
+ bank
->irq_chip
->eint_mask
646 + bank
->eint_offset
);
648 pr_debug("%s: save con %#010x\n", bank
->name
, save
->eint_con
);
649 pr_debug("%s: save fltcon0 %#010x\n", bank
->name
, save
->eint_fltcon0
);
650 pr_debug("%s: save fltcon1 %#010x\n", bank
->name
, save
->eint_fltcon1
);
651 pr_debug("%s: save mask %#010x\n", bank
->name
, save
->eint_mask
);
654 void exynos_pinctrl_suspend(struct samsung_pinctrl_drv_data
*drvdata
)
656 struct samsung_pin_bank
*bank
= drvdata
->pin_banks
;
657 struct exynos_irq_chip
*irq_chip
= NULL
;
660 for (i
= 0; i
< drvdata
->nr_banks
; ++i
, ++bank
) {
661 if (bank
->eint_type
== EINT_TYPE_GPIO
)
662 exynos_pinctrl_suspend_bank(drvdata
, bank
);
663 else if (bank
->eint_type
== EINT_TYPE_WKUP
) {
665 irq_chip
= bank
->irq_chip
;
666 irq_chip
->set_eint_wakeup_mask(drvdata
,
668 } else if (bank
->irq_chip
!= irq_chip
) {
669 dev_warn(drvdata
->dev
,
670 "More than one external wakeup interrupt chip configured (bank: %s). This is not supported by hardware nor by driver.\n",
677 static void exynos_pinctrl_resume_bank(
678 struct samsung_pinctrl_drv_data
*drvdata
,
679 struct samsung_pin_bank
*bank
)
681 struct exynos_eint_gpio_save
*save
= bank
->soc_priv
;
682 void __iomem
*regs
= bank
->eint_base
;
684 pr_debug("%s: con %#010x => %#010x\n", bank
->name
,
685 readl(regs
+ EXYNOS_GPIO_ECON_OFFSET
686 + bank
->eint_offset
), save
->eint_con
);
687 pr_debug("%s: fltcon0 %#010x => %#010x\n", bank
->name
,
688 readl(regs
+ EXYNOS_GPIO_EFLTCON_OFFSET
689 + 2 * bank
->eint_offset
), save
->eint_fltcon0
);
690 pr_debug("%s: fltcon1 %#010x => %#010x\n", bank
->name
,
691 readl(regs
+ EXYNOS_GPIO_EFLTCON_OFFSET
692 + 2 * bank
->eint_offset
+ 4), save
->eint_fltcon1
);
693 pr_debug("%s: mask %#010x => %#010x\n", bank
->name
,
694 readl(regs
+ bank
->irq_chip
->eint_mask
695 + bank
->eint_offset
), save
->eint_mask
);
697 writel(save
->eint_con
, regs
+ EXYNOS_GPIO_ECON_OFFSET
698 + bank
->eint_offset
);
699 writel(save
->eint_fltcon0
, regs
+ EXYNOS_GPIO_EFLTCON_OFFSET
700 + 2 * bank
->eint_offset
);
701 writel(save
->eint_fltcon1
, regs
+ EXYNOS_GPIO_EFLTCON_OFFSET
702 + 2 * bank
->eint_offset
+ 4);
703 writel(save
->eint_mask
, regs
+ bank
->irq_chip
->eint_mask
704 + bank
->eint_offset
);
707 void exynos_pinctrl_resume(struct samsung_pinctrl_drv_data
*drvdata
)
709 struct samsung_pin_bank
*bank
= drvdata
->pin_banks
;
712 for (i
= 0; i
< drvdata
->nr_banks
; ++i
, ++bank
)
713 if (bank
->eint_type
== EINT_TYPE_GPIO
)
714 exynos_pinctrl_resume_bank(drvdata
, bank
);
717 static void exynos_retention_enable(struct samsung_pinctrl_drv_data
*drvdata
)
719 if (drvdata
->retention_ctrl
->refcnt
)
720 atomic_inc(drvdata
->retention_ctrl
->refcnt
);
723 static void exynos_retention_disable(struct samsung_pinctrl_drv_data
*drvdata
)
725 struct samsung_retention_ctrl
*ctrl
= drvdata
->retention_ctrl
;
726 struct regmap
*pmu_regs
= ctrl
->priv
;
729 if (ctrl
->refcnt
&& !atomic_dec_and_test(ctrl
->refcnt
))
732 for (i
= 0; i
< ctrl
->nr_regs
; i
++)
733 regmap_write(pmu_regs
, ctrl
->regs
[i
], ctrl
->value
);
736 struct samsung_retention_ctrl
*
737 exynos_retention_init(struct samsung_pinctrl_drv_data
*drvdata
,
738 const struct samsung_retention_data
*data
)
740 struct samsung_retention_ctrl
*ctrl
;
741 struct regmap
*pmu_regs
;
744 ctrl
= devm_kzalloc(drvdata
->dev
, sizeof(*ctrl
), GFP_KERNEL
);
746 return ERR_PTR(-ENOMEM
);
748 pmu_regs
= exynos_get_pmu_regmap();
749 if (IS_ERR(pmu_regs
))
750 return ERR_CAST(pmu_regs
);
752 ctrl
->priv
= pmu_regs
;
753 ctrl
->regs
= data
->regs
;
754 ctrl
->nr_regs
= data
->nr_regs
;
755 ctrl
->value
= data
->value
;
756 ctrl
->refcnt
= data
->refcnt
;
757 ctrl
->enable
= exynos_retention_enable
;
758 ctrl
->disable
= exynos_retention_disable
;
760 /* Ensure that retention is disabled on driver init */
761 for (i
= 0; i
< ctrl
->nr_regs
; i
++)
762 regmap_write(pmu_regs
, ctrl
->regs
[i
], ctrl
->value
);