static void ssb_gpio_irq_chipco_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_chipco_gpio_in(&bus->chipco, BIT(gpio)); ssb_chipco_gpio_polarity(&bus->chipco, BIT(gpio), val); ssb_chipco_gpio_intmask(&bus->chipco, 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_chipco_handler(int irq, void *dev_id) { struct ssb_bus *bus = dev_id; struct ssb_chipcommon *chipco = &bus->chipco; u32 val = chipco_read32(chipco, SSB_CHIPCO_GPIOIN); u32 mask = chipco_read32(chipco, SSB_CHIPCO_GPIOIRQ); u32 pol = chipco_read32(chipco, SSB_CHIPCO_GPIOPOL); 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_chipco_gpio_polarity(chipco, irqs, val & irqs); return IRQ_HANDLED; }