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);
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);
}