Commit 0d3d30db authored by Abhilash Kesavan's avatar Abhilash Kesavan Committed by Tomasz Figa

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: default avatarAbhilash Kesavan <a.kesavan@samsung.com>
Reviewed-by: default avatarThomas Abraham <thomas.ab@samsung.com>
Tested-by: default avatarThomas Abraham <thomas.ab@samsung.com>
Acked-by: default avatarTomasz Figa <tomasz.figa@gmail.com>
Cc: Linus Walleij <linus.walleij@linaro.org>
Signed-off-by: default avatarTomasz Figa <tomasz.figa@gmail.com>
parent 8100cf47
......@@ -260,7 +260,7 @@ static int exynos_gpio_irq_map(struct irq_domain *h, unsigned int virq,
struct samsung_pin_bank *b = h->host_data;
irq_set_chip_data(virq, b);
irq_set_chip_and_handler(virq, &exynos_gpio_irq_chip.chip,
irq_set_chip_and_handler(virq, &b->irq_chip->chip,
handle_level_irq);
set_irq_flags(virq, IRQF_VALID);
return 0;
......@@ -343,6 +343,8 @@ static int exynos_eint_gpio_init(struct samsung_pinctrl_drv_data *d)
ret = -ENOMEM;
goto err_domains;
}
bank->irq_chip = &exynos_gpio_irq_chip;
}
return 0;
......@@ -444,9 +446,9 @@ static void exynos_irq_demux_eint16_31(unsigned int irq, struct irq_desc *desc)
for (i = 0; i < eintd->nr_banks; ++i) {
struct samsung_pin_bank *b = eintd->banks[i];
pend = readl(d->virt_base + EXYNOS_WKUP_EPEND_OFFSET
pend = readl(d->virt_base + b->irq_chip->eint_pend
+ b->eint_offset);
mask = readl(d->virt_base + EXYNOS_WKUP_EMASK_OFFSET
mask = readl(d->virt_base + b->irq_chip->eint_mask
+ b->eint_offset);
exynos_irq_demux_eint(pend & ~mask, b->irq_domain);
}
......@@ -457,7 +459,9 @@ static void exynos_irq_demux_eint16_31(unsigned int irq, struct irq_desc *desc)
static int exynos_wkup_irq_map(struct irq_domain *h, unsigned int virq,
irq_hw_number_t hw)
{
irq_set_chip_and_handler(virq, &exynos_wkup_irq_chip.chip,
struct samsung_pin_bank *b = h->host_data;
irq_set_chip_and_handler(virq, &b->irq_chip->chip,
handle_level_irq);
irq_set_chip_data(virq, h->host_data);
set_irq_flags(virq, IRQF_VALID);
......@@ -509,6 +513,8 @@ static int exynos_eint_wkup_init(struct samsung_pinctrl_drv_data *d)
return -ENXIO;
}
bank->irq_chip = &exynos_wkup_irq_chip;
if (!of_find_property(bank->of_node, "interrupts", NULL)) {
bank->eint_type = EINT_TYPE_WKUP_MUX;
++muxed_banks;
......
......@@ -151,6 +151,7 @@ struct samsung_pin_bank_data {
* @irq_domain: IRQ domain of the bank.
* @gpio_chip: GPIO chip of the bank.
* @grange: linux gpio pin range supported by this bank.
* @irq_chip: link to irq chip for external gpio and wakeup interrupts.
* @slock: spinlock protecting bank registers
* @pm_save: saved register values during suspend
*/
......@@ -171,6 +172,7 @@ struct samsung_pin_bank {
struct irq_domain *irq_domain;
struct gpio_chip gpio_chip;
struct pinctrl_gpio_range grange;
struct exynos_irq_chip *irq_chip;
spinlock_t slock;
u32 pm_save[PINCFG_TYPE_NUM + 1]; /* +1 to handle double CON registers*/
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment