aboutsummaryrefslogtreecommitdiffstats
path: root/arch/avr32/mach-at32ap/extint.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/avr32/mach-at32ap/extint.c')
-rw-r--r--arch/avr32/mach-at32ap/extint.c22
1 files changed, 20 insertions, 2 deletions
diff --git a/arch/avr32/mach-at32ap/extint.c b/arch/avr32/mach-at32ap/extint.c
index 4dff1f988900..b59272e81b9a 100644
--- a/arch/avr32/mach-at32ap/extint.c
+++ b/arch/avr32/mach-at32ap/extint.c
@@ -49,12 +49,25 @@ static void eim_unmask_irq(unsigned int irq)
static int eim_set_irq_type(unsigned int irq, unsigned int flow_type)
{
struct at32_sm *sm = get_irq_chip_data(irq);
+ struct irq_desc *desc;
unsigned int i = irq - sm->eim_first_irq;
u32 mode, edge, level;
unsigned long flags;
int ret = 0;
- flow_type &= IRQ_TYPE_SENSE_MASK;
+ if (flow_type == IRQ_TYPE_NONE)
+ flow_type = IRQ_TYPE_LEVEL_LOW;
+
+ desc = &irq_desc[irq];
+ desc->status &= ~(IRQ_TYPE_SENSE_MASK | IRQ_LEVEL);
+ desc->status |= flow_type & IRQ_TYPE_SENSE_MASK;
+
+ if (flow_type & (IRQ_TYPE_LEVEL_LOW | IRQ_TYPE_LEVEL_HIGH)) {
+ desc->status |= IRQ_LEVEL;
+ set_irq_handler(irq, handle_level_irq);
+ } else {
+ set_irq_handler(irq, handle_edge_irq);
+ }
spin_lock_irqsave(&sm->lock, flags);
@@ -148,10 +161,15 @@ static int __init eim_init(void)
pattern = sm_readl(sm, EIM_MODE);
nr_irqs = fls(pattern);
+ /* Trigger on falling edge unless overridden by driver */
+ sm_writel(sm, EIM_MODE, 0UL);
+ sm_writel(sm, EIM_EDGE, 0UL);
+
sm->eim_chip = &eim_chip;
for (i = 0; i < nr_irqs; i++) {
- set_irq_chip(sm->eim_first_irq + i, &eim_chip);
+ set_irq_chip_and_handler(sm->eim_first_irq + i, &eim_chip,
+ handle_edge_irq);
set_irq_chip_data(sm->eim_first_irq + i, sm);
}