2 * Exynos specific support for Samsung pinctrl/gpiolib driver with eint support.
4 * Copyright (c) 2012 Samsung Electronics Co., Ltd.
5 * http://www.samsung.com
6 * Copyright (c) 2012 Linaro Ltd
7 * http://www.linaro.org
9 * Author: Thomas Abraham <thomas.ab@samsung.com>
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
16 * This file contains the Samsung Exynos specific information required by the
17 * the Samsung pinctrl/gpiolib driver. It also includes the implementation of
18 * external gpio and wakeup interrupt support.
21 #include <linux/device.h>
22 #include <linux/interrupt.h>
23 #include <linux/irqdomain.h>
24 #include <linux/irq.h>
25 #include <linux/irqchip/chained_irq.h>
27 #include <linux/of_irq.h>
28 #include <linux/slab.h>
29 #include <linux/spinlock.h>
30 #include <linux/regmap.h>
31 #include <linux/err.h>
32 #include <linux/soc/samsung/exynos-pmu.h>
34 #include <dt-bindings/pinctrl/samsung.h>
36 #include "pinctrl-samsung.h"
37 #include "pinctrl-exynos.h"
39 struct exynos_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
,
225 static int exynos_eint_irq_map(struct irq_domain
*h
, unsigned int virq
,
228 struct samsung_pin_bank
*b
= h
->host_data
;
230 irq_set_chip_data(virq
, b
);
231 irq_set_chip_and_handler(virq
, &b
->irq_chip
->chip
,
237 * irq domain callbacks for external gpio and wakeup interrupt controllers.
239 static const struct irq_domain_ops exynos_eint_irqd_ops
= {
240 .map
= exynos_eint_irq_map
,
241 .xlate
= irq_domain_xlate_twocell
,
244 static irqreturn_t
exynos_eint_gpio_irq(int irq
, void *data
)
246 struct samsung_pinctrl_drv_data
*d
= data
;
247 struct samsung_pin_bank
*bank
= d
->pin_banks
;
248 unsigned int svc
, group
, pin
, virq
;
250 svc
= readl(bank
->eint_base
+ EXYNOS_SVC_OFFSET
);
251 group
= EXYNOS_SVC_GROUP(svc
);
252 pin
= svc
& EXYNOS_SVC_NUM_MASK
;
258 virq
= irq_linear_revmap(bank
->irq_domain
, pin
);
261 generic_handle_irq(virq
);
265 struct exynos_eint_gpio_save
{
272 * exynos_eint_gpio_init() - setup handling of external gpio interrupts.
273 * @d: driver data of samsung pinctrl driver.
275 int exynos_eint_gpio_init(struct samsung_pinctrl_drv_data
*d
)
277 struct samsung_pin_bank
*bank
;
278 struct device
*dev
= d
->dev
;
283 dev_err(dev
, "irq number not available\n");
287 ret
= devm_request_irq(dev
, d
->irq
, exynos_eint_gpio_irq
,
288 0, dev_name(dev
), d
);
290 dev_err(dev
, "irq request failed\n");
295 for (i
= 0; i
< d
->nr_banks
; ++i
, ++bank
) {
296 if (bank
->eint_type
!= EINT_TYPE_GPIO
)
298 bank
->irq_domain
= irq_domain_add_linear(bank
->of_node
,
299 bank
->nr_pins
, &exynos_eint_irqd_ops
, bank
);
300 if (!bank
->irq_domain
) {
301 dev_err(dev
, "gpio irq domain add failed\n");
306 bank
->soc_priv
= devm_kzalloc(d
->dev
,
307 sizeof(struct exynos_eint_gpio_save
), GFP_KERNEL
);
308 if (!bank
->soc_priv
) {
309 irq_domain_remove(bank
->irq_domain
);
314 bank
->irq_chip
= &exynos_gpio_irq_chip
;
320 for (--i
, --bank
; i
>= 0; --i
, --bank
) {
321 if (bank
->eint_type
!= EINT_TYPE_GPIO
)
323 irq_domain_remove(bank
->irq_domain
);
329 static u32 exynos_eint_wake_mask
= 0xffffffff;
331 u32
exynos_get_eint_wake_mask(void)
333 return exynos_eint_wake_mask
;
336 static int exynos_wkup_irq_set_wake(struct irq_data
*irqd
, unsigned int on
)
338 struct samsung_pin_bank
*bank
= irq_data_get_irq_chip_data(irqd
);
339 unsigned long bit
= 1UL << (2 * bank
->eint_offset
+ irqd
->hwirq
);
341 pr_info("wake %s for irq %d\n", on
? "enabled" : "disabled", irqd
->irq
);
344 exynos_eint_wake_mask
|= bit
;
346 exynos_eint_wake_mask
&= ~bit
;
352 * irq_chip for wakeup interrupts
354 static const struct exynos_irq_chip exynos4210_wkup_irq_chip __initconst
= {
356 .name
= "exynos4210_wkup_irq_chip",
357 .irq_unmask
= exynos_irq_unmask
,
358 .irq_mask
= exynos_irq_mask
,
359 .irq_ack
= exynos_irq_ack
,
360 .irq_set_type
= exynos_irq_set_type
,
361 .irq_set_wake
= exynos_wkup_irq_set_wake
,
362 .irq_request_resources
= exynos_irq_request_resources
,
363 .irq_release_resources
= exynos_irq_release_resources
,
365 .eint_con
= EXYNOS_WKUP_ECON_OFFSET
,
366 .eint_mask
= EXYNOS_WKUP_EMASK_OFFSET
,
367 .eint_pend
= EXYNOS_WKUP_EPEND_OFFSET
,
370 static const struct exynos_irq_chip exynos7_wkup_irq_chip __initconst
= {
372 .name
= "exynos7_wkup_irq_chip",
373 .irq_unmask
= exynos_irq_unmask
,
374 .irq_mask
= exynos_irq_mask
,
375 .irq_ack
= exynos_irq_ack
,
376 .irq_set_type
= exynos_irq_set_type
,
377 .irq_set_wake
= exynos_wkup_irq_set_wake
,
378 .irq_request_resources
= exynos_irq_request_resources
,
379 .irq_release_resources
= exynos_irq_release_resources
,
381 .eint_con
= EXYNOS7_WKUP_ECON_OFFSET
,
382 .eint_mask
= EXYNOS7_WKUP_EMASK_OFFSET
,
383 .eint_pend
= EXYNOS7_WKUP_EPEND_OFFSET
,
386 /* list of external wakeup controllers supported */
387 static const struct of_device_id exynos_wkup_irq_ids
[] = {
388 { .compatible
= "samsung,exynos4210-wakeup-eint",
389 .data
= &exynos4210_wkup_irq_chip
},
390 { .compatible
= "samsung,exynos7-wakeup-eint",
391 .data
= &exynos7_wkup_irq_chip
},
395 /* interrupt handler for wakeup interrupts 0..15 */
396 static void exynos_irq_eint0_15(struct irq_desc
*desc
)
398 struct exynos_weint_data
*eintd
= irq_desc_get_handler_data(desc
);
399 struct samsung_pin_bank
*bank
= eintd
->bank
;
400 struct irq_chip
*chip
= irq_desc_get_chip(desc
);
403 chained_irq_enter(chip
, desc
);
405 eint_irq
= irq_linear_revmap(bank
->irq_domain
, eintd
->irq
);
406 generic_handle_irq(eint_irq
);
408 chained_irq_exit(chip
, desc
);
411 static inline void exynos_irq_demux_eint(unsigned long pend
,
412 struct irq_domain
*domain
)
418 generic_handle_irq(irq_find_mapping(domain
, irq
));
423 /* interrupt handler for wakeup interrupt 16 */
424 static void exynos_irq_demux_eint16_31(struct irq_desc
*desc
)
426 struct irq_chip
*chip
= irq_desc_get_chip(desc
);
427 struct exynos_muxed_weint_data
*eintd
= irq_desc_get_handler_data(desc
);
432 chained_irq_enter(chip
, desc
);
434 for (i
= 0; i
< eintd
->nr_banks
; ++i
) {
435 struct samsung_pin_bank
*b
= eintd
->banks
[i
];
436 pend
= readl(b
->eint_base
+ b
->irq_chip
->eint_pend
438 mask
= readl(b
->eint_base
+ b
->irq_chip
->eint_mask
440 exynos_irq_demux_eint(pend
& ~mask
, b
->irq_domain
);
443 chained_irq_exit(chip
, desc
);
447 * exynos_eint_wkup_init() - setup handling of external wakeup interrupts.
448 * @d: driver data of samsung pinctrl driver.
450 int exynos_eint_wkup_init(struct samsung_pinctrl_drv_data
*d
)
452 struct device
*dev
= d
->dev
;
453 struct device_node
*wkup_np
= NULL
;
454 struct device_node
*np
;
455 struct samsung_pin_bank
*bank
;
456 struct exynos_weint_data
*weint_data
;
457 struct exynos_muxed_weint_data
*muxed_data
;
458 struct exynos_irq_chip
*irq_chip
;
459 unsigned int muxed_banks
= 0;
463 for_each_child_of_node(dev
->of_node
, np
) {
464 const struct of_device_id
*match
;
466 match
= of_match_node(exynos_wkup_irq_ids
, np
);
468 irq_chip
= kmemdup(match
->data
,
469 sizeof(*irq_chip
), GFP_KERNEL
);
480 for (i
= 0; i
< d
->nr_banks
; ++i
, ++bank
) {
481 if (bank
->eint_type
!= EINT_TYPE_WKUP
)
484 bank
->irq_domain
= irq_domain_add_linear(bank
->of_node
,
485 bank
->nr_pins
, &exynos_eint_irqd_ops
, bank
);
486 if (!bank
->irq_domain
) {
487 dev_err(dev
, "wkup irq domain add failed\n");
491 bank
->irq_chip
= irq_chip
;
493 if (!of_find_property(bank
->of_node
, "interrupts", NULL
)) {
494 bank
->eint_type
= EINT_TYPE_WKUP_MUX
;
499 weint_data
= devm_kzalloc(dev
, bank
->nr_pins
500 * sizeof(*weint_data
), GFP_KERNEL
);
504 for (idx
= 0; idx
< bank
->nr_pins
; ++idx
) {
505 irq
= irq_of_parse_and_map(bank
->of_node
, idx
);
507 dev_err(dev
, "irq number for eint-%s-%d not found\n",
511 weint_data
[idx
].irq
= idx
;
512 weint_data
[idx
].bank
= bank
;
513 irq_set_chained_handler_and_data(irq
,
522 irq
= irq_of_parse_and_map(wkup_np
, 0);
524 dev_err(dev
, "irq number for muxed EINTs not found\n");
528 muxed_data
= devm_kzalloc(dev
, sizeof(*muxed_data
)
529 + muxed_banks
*sizeof(struct samsung_pin_bank
*), GFP_KERNEL
);
533 irq_set_chained_handler_and_data(irq
, exynos_irq_demux_eint16_31
,
538 for (i
= 0; i
< d
->nr_banks
; ++i
, ++bank
) {
539 if (bank
->eint_type
!= EINT_TYPE_WKUP_MUX
)
542 muxed_data
->banks
[idx
++] = bank
;
544 muxed_data
->nr_banks
= muxed_banks
;
549 static void exynos_pinctrl_suspend_bank(
550 struct samsung_pinctrl_drv_data
*drvdata
,
551 struct samsung_pin_bank
*bank
)
553 struct exynos_eint_gpio_save
*save
= bank
->soc_priv
;
554 void __iomem
*regs
= bank
->eint_base
;
556 save
->eint_con
= readl(regs
+ EXYNOS_GPIO_ECON_OFFSET
557 + bank
->eint_offset
);
558 save
->eint_fltcon0
= readl(regs
+ EXYNOS_GPIO_EFLTCON_OFFSET
559 + 2 * bank
->eint_offset
);
560 save
->eint_fltcon1
= readl(regs
+ EXYNOS_GPIO_EFLTCON_OFFSET
561 + 2 * bank
->eint_offset
+ 4);
563 pr_debug("%s: save con %#010x\n", bank
->name
, save
->eint_con
);
564 pr_debug("%s: save fltcon0 %#010x\n", bank
->name
, save
->eint_fltcon0
);
565 pr_debug("%s: save fltcon1 %#010x\n", bank
->name
, save
->eint_fltcon1
);
568 void exynos_pinctrl_suspend(struct samsung_pinctrl_drv_data
*drvdata
)
570 struct samsung_pin_bank
*bank
= drvdata
->pin_banks
;
573 for (i
= 0; i
< drvdata
->nr_banks
; ++i
, ++bank
)
574 if (bank
->eint_type
== EINT_TYPE_GPIO
)
575 exynos_pinctrl_suspend_bank(drvdata
, bank
);
578 static void exynos_pinctrl_resume_bank(
579 struct samsung_pinctrl_drv_data
*drvdata
,
580 struct samsung_pin_bank
*bank
)
582 struct exynos_eint_gpio_save
*save
= bank
->soc_priv
;
583 void __iomem
*regs
= bank
->eint_base
;
585 pr_debug("%s: con %#010x => %#010x\n", bank
->name
,
586 readl(regs
+ EXYNOS_GPIO_ECON_OFFSET
587 + bank
->eint_offset
), save
->eint_con
);
588 pr_debug("%s: fltcon0 %#010x => %#010x\n", bank
->name
,
589 readl(regs
+ EXYNOS_GPIO_EFLTCON_OFFSET
590 + 2 * bank
->eint_offset
), save
->eint_fltcon0
);
591 pr_debug("%s: fltcon1 %#010x => %#010x\n", bank
->name
,
592 readl(regs
+ EXYNOS_GPIO_EFLTCON_OFFSET
593 + 2 * bank
->eint_offset
+ 4), save
->eint_fltcon1
);
595 writel(save
->eint_con
, regs
+ EXYNOS_GPIO_ECON_OFFSET
596 + bank
->eint_offset
);
597 writel(save
->eint_fltcon0
, regs
+ EXYNOS_GPIO_EFLTCON_OFFSET
598 + 2 * bank
->eint_offset
);
599 writel(save
->eint_fltcon1
, regs
+ EXYNOS_GPIO_EFLTCON_OFFSET
600 + 2 * bank
->eint_offset
+ 4);
603 void exynos_pinctrl_resume(struct samsung_pinctrl_drv_data
*drvdata
)
605 struct samsung_pin_bank
*bank
= drvdata
->pin_banks
;
608 for (i
= 0; i
< drvdata
->nr_banks
; ++i
, ++bank
)
609 if (bank
->eint_type
== EINT_TYPE_GPIO
)
610 exynos_pinctrl_resume_bank(drvdata
, bank
);
613 static void exynos_retention_enable(struct samsung_pinctrl_drv_data
*drvdata
)
615 if (drvdata
->retention_ctrl
->refcnt
)
616 atomic_inc(drvdata
->retention_ctrl
->refcnt
);
619 static void exynos_retention_disable(struct samsung_pinctrl_drv_data
*drvdata
)
621 struct samsung_retention_ctrl
*ctrl
= drvdata
->retention_ctrl
;
622 struct regmap
*pmu_regs
= ctrl
->priv
;
625 if (ctrl
->refcnt
&& !atomic_dec_and_test(ctrl
->refcnt
))
628 for (i
= 0; i
< ctrl
->nr_regs
; i
++)
629 regmap_write(pmu_regs
, ctrl
->regs
[i
], ctrl
->value
);
632 struct samsung_retention_ctrl
*
633 exynos_retention_init(struct samsung_pinctrl_drv_data
*drvdata
,
634 const struct samsung_retention_data
*data
)
636 struct samsung_retention_ctrl
*ctrl
;
637 struct regmap
*pmu_regs
;
640 ctrl
= devm_kzalloc(drvdata
->dev
, sizeof(*ctrl
), GFP_KERNEL
);
642 return ERR_PTR(-ENOMEM
);
644 pmu_regs
= exynos_get_pmu_regmap();
645 if (IS_ERR(pmu_regs
))
646 return ERR_CAST(pmu_regs
);
648 ctrl
->priv
= pmu_regs
;
649 ctrl
->regs
= data
->regs
;
650 ctrl
->nr_regs
= data
->nr_regs
;
651 ctrl
->value
= data
->value
;
652 ctrl
->refcnt
= data
->refcnt
;
653 ctrl
->enable
= exynos_retention_enable
;
654 ctrl
->disable
= exynos_retention_disable
;
656 /* Ensure that retention is disabled on driver init */
657 for (i
= 0; i
< ctrl
->nr_regs
; i
++)
658 regmap_write(pmu_regs
, ctrl
->regs
[i
], ctrl
->value
);