static int ssb_gpio_irq_chipco_domain_init()

in driver_gpio.c [141:184]


static int ssb_gpio_irq_chipco_domain_init(struct ssb_bus *bus)
{
	struct ssb_chipcommon *chipco = &bus->chipco;
	struct gpio_chip *chip = &bus->gpio;
	int gpio, hwirq, err;

	if (bus->bustype != SSB_BUSTYPE_SSB)
		return 0;

	bus->irq_domain = irq_domain_add_linear(NULL, chip->ngpio,
						&irq_domain_simple_ops, chipco);
	if (!bus->irq_domain) {
		err = -ENODEV;
		goto err_irq_domain;
	}
	for (gpio = 0; gpio < chip->ngpio; gpio++) {
		int irq = irq_create_mapping(bus->irq_domain, gpio);

		irq_set_chip_data(irq, bus);
		irq_set_chip_and_handler(irq, &ssb_gpio_irq_chipco_chip,
					 handle_simple_irq);
	}

	hwirq = ssb_mips_irq(bus->chipco.dev) + 2;
	err = request_irq(hwirq, ssb_gpio_irq_chipco_handler, IRQF_SHARED,
			  "gpio", bus);
	if (err)
		goto err_req_irq;

	ssb_chipco_gpio_intmask(&bus->chipco, ~0, 0);
	chipco_set32(chipco, SSB_CHIPCO_IRQMASK, SSB_CHIPCO_IRQ_GPIO);

	return 0;

err_req_irq:
	for (gpio = 0; gpio < chip->ngpio; gpio++) {
		int irq = irq_find_mapping(bus->irq_domain, gpio);

		irq_dispose_mapping(irq);
	}
	irq_domain_remove(bus->irq_domain);
err_irq_domain:
	return err;
}