static void ssb_gpio_irq_extif_unmask(struct irq_data *d) { struct ssb_bus *bus = irq_data_get_irq_chip_data(d); int gpio = irqd_to_hwirq(d); u32 val = ssb_extif_gpio_in(&bus->extif, BIT(gpio)); ssb_extif_gpio_polarity(&bus->extif, BIT(gpio), val); ssb_extif_gpio_intmask(&bus->extif, BIT(gpio), BIT(gpio)); }
u32 ssb_gpio_polarity(struct ssb_bus *bus, u32 mask, u32 value) { unsigned long flags; u32 res = 0; spin_lock_irqsave(&bus->gpio_lock, flags); if (ssb_chipco_available(&bus->chipco)) res = ssb_chipco_gpio_polarity(&bus->chipco, mask, value); else if (ssb_extif_available(&bus->extif)) res = ssb_extif_gpio_polarity(&bus->extif, mask, value); else SSB_WARN_ON(1); spin_unlock_irqrestore(&bus->gpio_lock, flags); return res; }
static irqreturn_t ssb_gpio_irq_extif_handler(int irq, void *dev_id) { struct ssb_bus *bus = dev_id; struct ssb_extif *extif = &bus->extif; u32 val = ssb_read32(extif->dev, SSB_EXTIF_GPIO_IN); u32 mask = ssb_read32(extif->dev, SSB_EXTIF_GPIO_INTMASK); u32 pol = ssb_read32(extif->dev, SSB_EXTIF_GPIO_INTPOL); unsigned long irqs = (val ^ pol) & mask; int gpio; if (!irqs) return IRQ_NONE; for_each_set_bit(gpio, &irqs, bus->gpio.ngpio) generic_handle_irq(ssb_gpio_to_irq(&bus->gpio, gpio)); ssb_extif_gpio_polarity(extif, irqs, val & irqs); return IRQ_HANDLED; }