Commit 5a2490e0 authored by Ludovic Barre's avatar Ludovic Barre Committed by Marc Zyngier

irqchip/stm32: Prepare common functions

This patch prepares functions which could be reused by
next variant of stm32 exti controller.
Signed-off-by: default avatarLudovic Barre <ludovic.barre@st.com>
Signed-off-by: default avatarMarc Zyngier <marc.zyngier@arm.com>
parent f9fc1745
...@@ -145,37 +145,50 @@ static void stm32_irq_handler(struct irq_desc *desc) ...@@ -145,37 +145,50 @@ static void stm32_irq_handler(struct irq_desc *desc)
chained_irq_exit(chip, desc); chained_irq_exit(chip, desc);
} }
static int stm32_irq_set_type(struct irq_data *data, unsigned int type) static int stm32_exti_set_type(struct irq_data *d,
unsigned int type, u32 *rtsr, u32 *ftsr)
{ {
struct irq_chip_generic *gc = irq_data_get_irq_chip_data(data); u32 mask = BIT(d->hwirq % IRQS_PER_BANK);
struct stm32_exti_chip_data *chip_data = gc->private;
const struct stm32_exti_bank *stm32_bank = chip_data->reg_bank;
int pin = data->hwirq % IRQS_PER_BANK;
u32 rtsr, ftsr;
irq_gc_lock(gc);
rtsr = irq_reg_readl(gc, stm32_bank->rtsr_ofst);
ftsr = irq_reg_readl(gc, stm32_bank->ftsr_ofst);
switch (type) { switch (type) {
case IRQ_TYPE_EDGE_RISING: case IRQ_TYPE_EDGE_RISING:
rtsr |= BIT(pin); *rtsr |= mask;
ftsr &= ~BIT(pin); *ftsr &= ~mask;
break; break;
case IRQ_TYPE_EDGE_FALLING: case IRQ_TYPE_EDGE_FALLING:
rtsr &= ~BIT(pin); *rtsr &= ~mask;
ftsr |= BIT(pin); *ftsr |= mask;
break; break;
case IRQ_TYPE_EDGE_BOTH: case IRQ_TYPE_EDGE_BOTH:
rtsr |= BIT(pin); *rtsr |= mask;
ftsr |= BIT(pin); *ftsr |= mask;
break; break;
default: default:
irq_gc_unlock(gc);
return -EINVAL; return -EINVAL;
} }
return 0;
}
static int stm32_irq_set_type(struct irq_data *d, unsigned int type)
{
struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d);
struct stm32_exti_chip_data *chip_data = gc->private;
const struct stm32_exti_bank *stm32_bank = chip_data->reg_bank;
u32 rtsr, ftsr;
int err;
irq_gc_lock(gc);
rtsr = irq_reg_readl(gc, stm32_bank->rtsr_ofst);
ftsr = irq_reg_readl(gc, stm32_bank->ftsr_ofst);
err = stm32_exti_set_type(d, type, &rtsr, &ftsr);
if (err) {
irq_gc_unlock(gc);
return err;
}
irq_reg_writel(gc, rtsr, stm32_bank->rtsr_ofst); irq_reg_writel(gc, rtsr, stm32_bank->rtsr_ofst);
irq_reg_writel(gc, ftsr, stm32_bank->ftsr_ofst); irq_reg_writel(gc, ftsr, stm32_bank->ftsr_ofst);
...@@ -184,35 +197,47 @@ static int stm32_irq_set_type(struct irq_data *data, unsigned int type) ...@@ -184,35 +197,47 @@ static int stm32_irq_set_type(struct irq_data *data, unsigned int type)
return 0; return 0;
} }
static void stm32_irq_suspend(struct irq_chip_generic *gc) static void stm32_chip_suspend(struct stm32_exti_chip_data *chip_data,
u32 wake_active)
{ {
struct stm32_exti_chip_data *chip_data = gc->private;
const struct stm32_exti_bank *stm32_bank = chip_data->reg_bank; const struct stm32_exti_bank *stm32_bank = chip_data->reg_bank;
void __iomem *base = chip_data->host_data->base;
irq_gc_lock(gc);
/* save rtsr, ftsr registers */ /* save rtsr, ftsr registers */
chip_data->rtsr_cache = irq_reg_readl(gc, stm32_bank->rtsr_ofst); chip_data->rtsr_cache = readl_relaxed(base + stm32_bank->rtsr_ofst);
chip_data->ftsr_cache = irq_reg_readl(gc, stm32_bank->ftsr_ofst); chip_data->ftsr_cache = readl_relaxed(base + stm32_bank->ftsr_ofst);
irq_reg_writel(gc, gc->wake_active, stm32_bank->imr_ofst); writel_relaxed(wake_active, base + stm32_bank->imr_ofst);
}
irq_gc_unlock(gc); static void stm32_chip_resume(struct stm32_exti_chip_data *chip_data,
u32 mask_cache)
{
const struct stm32_exti_bank *stm32_bank = chip_data->reg_bank;
void __iomem *base = chip_data->host_data->base;
/* restore rtsr, ftsr, registers */
writel_relaxed(chip_data->rtsr_cache, base + stm32_bank->rtsr_ofst);
writel_relaxed(chip_data->ftsr_cache, base + stm32_bank->ftsr_ofst);
writel_relaxed(mask_cache, base + stm32_bank->imr_ofst);
} }
static void stm32_irq_resume(struct irq_chip_generic *gc) static void stm32_irq_suspend(struct irq_chip_generic *gc)
{ {
struct stm32_exti_chip_data *chip_data = gc->private; struct stm32_exti_chip_data *chip_data = gc->private;
const struct stm32_exti_bank *stm32_bank = chip_data->reg_bank;
irq_gc_lock(gc); irq_gc_lock(gc);
stm32_chip_suspend(chip_data, gc->wake_active);
irq_gc_unlock(gc);
}
/* restore rtsr, ftsr registers */ static void stm32_irq_resume(struct irq_chip_generic *gc)
irq_reg_writel(gc, chip_data->rtsr_cache, stm32_bank->rtsr_ofst); {
irq_reg_writel(gc, chip_data->ftsr_cache, stm32_bank->ftsr_ofst); struct stm32_exti_chip_data *chip_data = gc->private;
irq_reg_writel(gc, gc->mask_cache, stm32_bank->imr_ofst);
irq_gc_lock(gc);
stm32_chip_resume(chip_data, gc->mask_cache);
irq_gc_unlock(gc); irq_gc_unlock(gc);
} }
......
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