static int bcma_gpio_irq_init(struct bcma_drv_cc *cc) { struct gpio_chip *chip = &cc->gpio; int hwirq, err; if (cc->core->bus->hosttype != BCMA_HOSTTYPE_SOC) return 0; hwirq = bcma_core_irq(cc->core, 0); err = request_irq(hwirq, bcma_gpio_irq_handler, IRQF_SHARED, "gpio", cc); if (err) return err; bcma_chipco_gpio_intmask(cc, ~0, 0); bcma_cc_set32(cc, BCMA_CC_IRQMASK, BCMA_CC_IRQ_GPIO); err = gpiochip_irqchip_add(chip, &bcma_gpio_irq_chip, 0, handle_simple_irq, IRQ_TYPE_NONE); if (err) { free_irq(hwirq, cc); return err; } return 0; }
static void bcma_gpio_irq_mask(struct irq_data *d) { struct bcma_drv_cc *cc = irq_data_get_irq_chip_data(d); int gpio = irqd_to_hwirq(d); bcma_chipco_gpio_intmask(cc, BIT(gpio), 0); }
static void bcma_gpio_irq_unmask(struct irq_data *d) { struct bcma_drv_cc *cc = irq_data_get_irq_chip_data(d); int gpio = irqd_to_hwirq(d); u32 val = bcma_chipco_gpio_in(cc, BIT(gpio)); bcma_chipco_gpio_polarity(cc, BIT(gpio), val); bcma_chipco_gpio_intmask(cc, BIT(gpio), BIT(gpio)); }
static int bcma_gpio_irq_domain_init(struct bcma_drv_cc *cc) { struct gpio_chip *chip = &cc->gpio; int gpio, hwirq, err; if (cc->core->bus->hosttype != BCMA_HOSTTYPE_SOC) return 0; cc->irq_domain = irq_domain_add_linear(NULL, chip->ngpio, &irq_domain_simple_ops, cc); if (!cc->irq_domain) { err = -ENODEV; goto err_irq_domain; } for (gpio = 0; gpio < chip->ngpio; gpio++) { int irq = irq_create_mapping(cc->irq_domain, gpio); irq_set_chip_data(irq, cc); irq_set_chip_and_handler(irq, &bcma_gpio_irq_chip, handle_simple_irq); } hwirq = bcma_core_irq(cc->core, 0); err = request_irq(hwirq, bcma_gpio_irq_handler, IRQF_SHARED, "gpio", cc); if (err) goto err_req_irq; bcma_chipco_gpio_intmask(cc, ~0, 0); bcma_cc_set32(cc, BCMA_CC_IRQMASK, BCMA_CC_IRQ_GPIO); return 0; err_req_irq: for (gpio = 0; gpio < chip->ngpio; gpio++) { int irq = irq_find_mapping(cc->irq_domain, gpio); irq_dispose_mapping(irq); } irq_domain_remove(cc->irq_domain); err_irq_domain: return err; }