aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAbhilash Kesavan <a.kesavan@samsung.com>2014-10-09 09:54:29 -0400
committerTomasz Figa <tomasz.figa@gmail.com>2014-11-09 08:26:49 -0500
commit0d3d30db93635936652417efd0f4a3e9049d0938 (patch)
tree09992cde74688df03c630c7ac0a9b707a48a15b9
parent8100cf47698fedbde6dc3fa540b1fefcee69fd40 (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.c14
-rw-r--r--drivers/pinctrl/samsung/pinctrl-samsung.h2
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)
457static int exynos_wkup_irq_map(struct irq_domain *h, unsigned int virq, 459static 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*/