[PATCH] RFT: pinctrl: samsung: separate wakeup irqdomain
Linus Walleij
linus.walleij at linaro.org
Thu Apr 9 00:40:41 PDT 2015
The Samsung pin control driver and subdrivers sometimes use both
an irqdomain for some IRQs and another irqdomain for wakeup irqs,
registering the first with a call to the per-SoC callback
.eint_gpio_init() and the second with a call to .eint_wkup_init()
however it seems both runpaths will assign the resulting irqdomain
to the per-bank bank.irq_domain member, making the second
(wakeup) irqdomain overwrite the first one.
I'm surprised this even works, and it seems that the S3C
per-domain "domain data" that seems to be used in part to work
around this bug by creating a local array with copies of the
irqdomain (!).
This patch mainly adds a new record to the GPIO/pin "bank"
for wakeups and use this in the .eint_wkup_init() callbacks
to pave the way for more cleanups.
Signed-off-by: Linus Walleij <linus.walleij at linaro.org>
---
Tomasz etc: I don't know if I'm just misunderstanding this,
can you look at it and tell me how badly I misunderstand
these Samsung wakeups, to me it is a complete mystery.
---
drivers/pinctrl/samsung/pinctrl-exynos.c | 6 +++---
drivers/pinctrl/samsung/pinctrl-s3c24xx.c | 6 +++---
drivers/pinctrl/samsung/pinctrl-s3c64xx.c | 6 +++---
drivers/pinctrl/samsung/pinctrl-samsung.h | 1 +
4 files changed, 10 insertions(+), 9 deletions(-)
diff --git a/drivers/pinctrl/samsung/pinctrl-exynos.c b/drivers/pinctrl/samsung/pinctrl-exynos.c
index c8f83f96546c..6adf34e3cce6 100644
--- a/drivers/pinctrl/samsung/pinctrl-exynos.c
+++ b/drivers/pinctrl/samsung/pinctrl-exynos.c
@@ -469,7 +469,7 @@ static void exynos_irq_demux_eint16_31(unsigned int irq, struct irq_desc *desc)
+ b->eint_offset);
mask = readl(d->virt_base + b->irq_chip->eint_mask
+ b->eint_offset);
- exynos_irq_demux_eint(pend & ~mask, b->irq_domain);
+ exynos_irq_demux_eint(pend & ~mask, b->wkup_domain);
}
chained_irq_exit(chip, desc);
@@ -511,9 +511,9 @@ static int exynos_eint_wkup_init(struct samsung_pinctrl_drv_data *d)
if (bank->eint_type != EINT_TYPE_WKUP)
continue;
- bank->irq_domain = irq_domain_add_linear(bank->of_node,
+ bank->wkup_domain = irq_domain_add_linear(bank->of_node,
bank->nr_pins, &exynos_eint_irqd_ops, bank);
- if (!bank->irq_domain) {
+ if (!bank->wkup_domain) {
dev_err(dev, "wkup irq domain add failed\n");
return -ENXIO;
}
diff --git a/drivers/pinctrl/samsung/pinctrl-s3c24xx.c b/drivers/pinctrl/samsung/pinctrl-s3c24xx.c
index f1993f42114c..1dd1e5a0ed58 100644
--- a/drivers/pinctrl/samsung/pinctrl-s3c24xx.c
+++ b/drivers/pinctrl/samsung/pinctrl-s3c24xx.c
@@ -539,9 +539,9 @@ static int s3c24xx_eint_init(struct samsung_pinctrl_drv_data *d)
ops = (bank->eint_offset == 0) ? &s3c24xx_gpf_irq_ops
: &s3c24xx_gpg_irq_ops;
- bank->irq_domain = irq_domain_add_linear(bank->of_node,
+ bank->wkup_domain = irq_domain_add_linear(bank->of_node,
bank->nr_pins, ops, ddata);
- if (!bank->irq_domain) {
+ if (!bank->wkup_domain) {
dev_err(dev, "wkup irq domain add failed\n");
return -ENXIO;
}
@@ -553,7 +553,7 @@ static int s3c24xx_eint_init(struct samsung_pinctrl_drv_data *d)
break;
if (!(mask & 1))
continue;
- eint_data->domains[irq] = bank->irq_domain;
+ eint_data->domains[irq] = bank->wkup_domain;
++irq;
}
}
diff --git a/drivers/pinctrl/samsung/pinctrl-s3c64xx.c b/drivers/pinctrl/samsung/pinctrl-s3c64xx.c
index 7756c1e9e763..9701424a8bea 100644
--- a/drivers/pinctrl/samsung/pinctrl-s3c64xx.c
+++ b/drivers/pinctrl/samsung/pinctrl-s3c64xx.c
@@ -757,9 +757,9 @@ static int s3c64xx_eint_eint0_init(struct samsung_pinctrl_drv_data *d)
}
ddata->bank = bank;
- bank->irq_domain = irq_domain_add_linear(bank->of_node,
+ bank->wkup_domain = irq_domain_add_linear(bank->of_node,
nr_eints, &s3c64xx_eint0_irqd_ops, ddata);
- if (!bank->irq_domain) {
+ if (!bank->wkup_domain) {
dev_err(dev, "wkup irq domain add failed\n");
return -ENXIO;
}
@@ -769,7 +769,7 @@ static int s3c64xx_eint_eint0_init(struct samsung_pinctrl_drv_data *d)
for (pin = 0; mask; ++pin, mask >>= 1) {
if (!(mask & 1))
continue;
- data->domains[irq] = bank->irq_domain;
+ data->domains[irq] = bank->wkup_domain;
data->pins[irq] = pin;
ddata->eints[pin] = irq;
++irq;
diff --git a/drivers/pinctrl/samsung/pinctrl-samsung.h b/drivers/pinctrl/samsung/pinctrl-samsung.h
index 1b8c0139d604..c97dd1e6ae2e 100644
--- a/drivers/pinctrl/samsung/pinctrl-samsung.h
+++ b/drivers/pinctrl/samsung/pinctrl-samsung.h
@@ -170,6 +170,7 @@ struct samsung_pin_bank {
struct device_node *of_node;
struct samsung_pinctrl_drv_data *drvdata;
struct irq_domain *irq_domain;
+ struct irq_domain *wkup_domain;
struct gpio_chip gpio_chip;
struct pinctrl_gpio_range grange;
struct exynos_irq_chip *irq_chip;
--
1.9.3
More information about the linux-arm-kernel
mailing list