diff options
author | Abhilash Kesavan <a.kesavan@samsung.com> | 2014-10-09 09:54:29 -0400 |
---|---|---|
committer | Tomasz Figa <tomasz.figa@gmail.com> | 2014-11-09 08:26:49 -0500 |
commit | 0d3d30db93635936652417efd0f4a3e9049d0938 (patch) | |
tree | 09992cde74688df03c630c7ac0a9b707a48a15b9 | |
parent | 8100cf47698fedbde6dc3fa540b1fefcee69fd40 (diff) |
pinctrl: exynos: Generalize the eint16_31 demux code
The function exynos_irq_demux_eint16_31 uses pre-defined offsets for external
interrupt pending status and mask registers. So this function is not extensible
for Exynos7 SoC which has these registers at different offsets. Generalize
the exynos_irq_demux_eint16_31 function by using the pending/mask register
offset values from the exynos_irq_chip structure. This is done by adding a
irq_chip field to the samsung_pin_bank struct.
Signed-off-by: Abhilash Kesavan <a.kesavan@samsung.com>
Reviewed-by: Thomas Abraham <thomas.ab@samsung.com>
Tested-by: Thomas Abraham <thomas.ab@samsung.com>
Acked-by: Tomasz Figa <tomasz.figa@gmail.com>
Cc: Linus Walleij <linus.walleij@linaro.org>
Signed-off-by: Tomasz Figa <tomasz.figa@gmail.com>
-rw-r--r-- | drivers/pinctrl/samsung/pinctrl-exynos.c | 14 | ||||
-rw-r--r-- | drivers/pinctrl/samsung/pinctrl-samsung.h | 2 |
2 files changed, 12 insertions, 4 deletions
diff --git a/drivers/pinctrl/samsung/pinctrl-exynos.c b/drivers/pinctrl/samsung/pinctrl-exynos.c index b4490cb2a439..954e555766df 100644 --- a/drivers/pinctrl/samsung/pinctrl-exynos.c +++ b/drivers/pinctrl/samsung/pinctrl-exynos.c | |||
@@ -260,7 +260,7 @@ static int exynos_gpio_irq_map(struct irq_domain *h, unsigned int virq, | |||
260 | struct samsung_pin_bank *b = h->host_data; | 260 | struct samsung_pin_bank *b = h->host_data; |
261 | 261 | ||
262 | irq_set_chip_data(virq, b); | 262 | irq_set_chip_data(virq, b); |
263 | irq_set_chip_and_handler(virq, &exynos_gpio_irq_chip.chip, | 263 | irq_set_chip_and_handler(virq, &b->irq_chip->chip, |
264 | handle_level_irq); | 264 | handle_level_irq); |
265 | set_irq_flags(virq, IRQF_VALID); | 265 | set_irq_flags(virq, IRQF_VALID); |
266 | return 0; | 266 | return 0; |
@@ -343,6 +343,8 @@ static int exynos_eint_gpio_init(struct samsung_pinctrl_drv_data *d) | |||
343 | ret = -ENOMEM; | 343 | ret = -ENOMEM; |
344 | goto err_domains; | 344 | goto err_domains; |
345 | } | 345 | } |
346 | |||
347 | bank->irq_chip = &exynos_gpio_irq_chip; | ||
346 | } | 348 | } |
347 | 349 | ||
348 | return 0; | 350 | return 0; |
@@ -444,9 +446,9 @@ static void exynos_irq_demux_eint16_31(unsigned int irq, struct irq_desc *desc) | |||
444 | 446 | ||
445 | for (i = 0; i < eintd->nr_banks; ++i) { | 447 | for (i = 0; i < eintd->nr_banks; ++i) { |
446 | struct samsung_pin_bank *b = eintd->banks[i]; | 448 | struct samsung_pin_bank *b = eintd->banks[i]; |
447 | pend = readl(d->virt_base + EXYNOS_WKUP_EPEND_OFFSET | 449 | pend = readl(d->virt_base + b->irq_chip->eint_pend |
448 | + b->eint_offset); | 450 | + b->eint_offset); |
449 | mask = readl(d->virt_base + EXYNOS_WKUP_EMASK_OFFSET | 451 | mask = readl(d->virt_base + b->irq_chip->eint_mask |
450 | + b->eint_offset); | 452 | + b->eint_offset); |
451 | exynos_irq_demux_eint(pend & ~mask, b->irq_domain); | 453 | exynos_irq_demux_eint(pend & ~mask, b->irq_domain); |
452 | } | 454 | } |
@@ -457,7 +459,9 @@ static void exynos_irq_demux_eint16_31(unsigned int irq, struct irq_desc *desc) | |||
457 | static int exynos_wkup_irq_map(struct irq_domain *h, unsigned int virq, | 459 | static int exynos_wkup_irq_map(struct irq_domain *h, unsigned int virq, |
458 | irq_hw_number_t hw) | 460 | irq_hw_number_t hw) |
459 | { | 461 | { |
460 | irq_set_chip_and_handler(virq, &exynos_wkup_irq_chip.chip, | 462 | struct samsung_pin_bank *b = h->host_data; |
463 | |||
464 | irq_set_chip_and_handler(virq, &b->irq_chip->chip, | ||
461 | handle_level_irq); | 465 | handle_level_irq); |
462 | irq_set_chip_data(virq, h->host_data); | 466 | irq_set_chip_data(virq, h->host_data); |
463 | set_irq_flags(virq, IRQF_VALID); | 467 | set_irq_flags(virq, IRQF_VALID); |
@@ -509,6 +513,8 @@ static int exynos_eint_wkup_init(struct samsung_pinctrl_drv_data *d) | |||
509 | return -ENXIO; | 513 | return -ENXIO; |
510 | } | 514 | } |
511 | 515 | ||
516 | bank->irq_chip = &exynos_wkup_irq_chip; | ||
517 | |||
512 | if (!of_find_property(bank->of_node, "interrupts", NULL)) { | 518 | if (!of_find_property(bank->of_node, "interrupts", NULL)) { |
513 | bank->eint_type = EINT_TYPE_WKUP_MUX; | 519 | bank->eint_type = EINT_TYPE_WKUP_MUX; |
514 | ++muxed_banks; | 520 | ++muxed_banks; |
diff --git a/drivers/pinctrl/samsung/pinctrl-samsung.h b/drivers/pinctrl/samsung/pinctrl-samsung.h index ec43b7d49fb9..3076b8b591c7 100644 --- a/drivers/pinctrl/samsung/pinctrl-samsung.h +++ b/drivers/pinctrl/samsung/pinctrl-samsung.h | |||
@@ -151,6 +151,7 @@ struct samsung_pin_bank_data { | |||
151 | * @irq_domain: IRQ domain of the bank. | 151 | * @irq_domain: IRQ domain of the bank. |
152 | * @gpio_chip: GPIO chip of the bank. | 152 | * @gpio_chip: GPIO chip of the bank. |
153 | * @grange: linux gpio pin range supported by this bank. | 153 | * @grange: linux gpio pin range supported by this bank. |
154 | * @irq_chip: link to irq chip for external gpio and wakeup interrupts. | ||
154 | * @slock: spinlock protecting bank registers | 155 | * @slock: spinlock protecting bank registers |
155 | * @pm_save: saved register values during suspend | 156 | * @pm_save: saved register values during suspend |
156 | */ | 157 | */ |
@@ -171,6 +172,7 @@ struct samsung_pin_bank { | |||
171 | struct irq_domain *irq_domain; | 172 | struct irq_domain *irq_domain; |
172 | struct gpio_chip gpio_chip; | 173 | struct gpio_chip gpio_chip; |
173 | struct pinctrl_gpio_range grange; | 174 | struct pinctrl_gpio_range grange; |
175 | struct exynos_irq_chip *irq_chip; | ||
174 | spinlock_t slock; | 176 | spinlock_t slock; |
175 | 177 | ||
176 | u32 pm_save[PINCFG_TYPE_NUM + 1]; /* +1 to handle double CON registers*/ | 178 | u32 pm_save[PINCFG_TYPE_NUM + 1]; /* +1 to handle double CON registers*/ |