From 19ab5ca9b77d8b30a00cd3b7474d9c1f87df5c0a Mon Sep 17 00:00:00 2001 From: Lars Poeschel Date: Fri, 11 Jan 2019 17:25:16 +0100 Subject: [PATCH] pinctrl: mcp23s08: Allocate irq_chip dynamic Keeping the irq_chip definition static shares it with multiple instances of the mcp23s08 gpiochip in the system. This is bad and now we get this warning from gpiolib core: "detected irqchip that is shared with multiple gpiochips: please fix the driver." Hence, move the irq_chip definition from being driver static into the struct mcp23s08. So a unique irq_chip is used for each gpiochip instance. Signed-off-by: Lars Poeschel Signed-off-by: Linus Walleij --- drivers/pinctrl/pinctrl-mcp23s08.c | 28 +++++++++++++++++----------- 1 file changed, 17 insertions(+), 11 deletions(-) diff --git a/drivers/pinctrl/pinctrl-mcp23s08.c b/drivers/pinctrl/pinctrl-mcp23s08.c index 6b4def13df8f..2047e03178a3 100644 --- a/drivers/pinctrl/pinctrl-mcp23s08.c +++ b/drivers/pinctrl/pinctrl-mcp23s08.c @@ -68,6 +68,7 @@ struct mcp23s08 { struct mutex lock; struct gpio_chip chip; + struct irq_chip irq_chip; struct regmap *regmap; struct device *dev; @@ -607,15 +608,6 @@ static void mcp23s08_irq_bus_unlock(struct irq_data *data) mutex_unlock(&mcp->lock); } -static struct irq_chip mcp23s08_irq_chip = { - .name = "gpio-mcp23xxx", - .irq_mask = mcp23s08_irq_mask, - .irq_unmask = mcp23s08_irq_unmask, - .irq_set_type = mcp23s08_irq_set_type, - .irq_bus_lock = mcp23s08_irq_bus_lock, - .irq_bus_sync_unlock = mcp23s08_irq_bus_unlock, -}; - static int mcp23s08_irq_setup(struct mcp23s08 *mcp) { struct gpio_chip *chip = &mcp->chip; @@ -645,7 +637,7 @@ static int mcp23s08_irqchip_setup(struct mcp23s08 *mcp) int err; err = gpiochip_irqchip_add_nested(chip, - &mcp23s08_irq_chip, + &mcp->irq_chip, 0, handle_simple_irq, IRQ_TYPE_NONE); @@ -656,7 +648,7 @@ static int mcp23s08_irqchip_setup(struct mcp23s08 *mcp) } gpiochip_set_nested_irqchip(chip, - &mcp23s08_irq_chip, + &mcp->irq_chip, mcp->irq); return 0; @@ -1042,6 +1034,13 @@ static int mcp230xx_probe(struct i2c_client *client, return -ENOMEM; mcp->irq = client->irq; + mcp->irq_chip.name = dev_name(&client->dev); + mcp->irq_chip.irq_mask = mcp23s08_irq_mask; + mcp->irq_chip.irq_unmask = mcp23s08_irq_unmask; + mcp->irq_chip.irq_set_type = mcp23s08_irq_set_type; + mcp->irq_chip.irq_bus_lock = mcp23s08_irq_bus_lock; + mcp->irq_chip.irq_bus_sync_unlock = mcp23s08_irq_bus_unlock; + status = mcp23s08_probe_one(mcp, &client->dev, client, client->addr, id->driver_data, pdata->base, 0); if (status) @@ -1151,6 +1150,13 @@ static int mcp23s08_probe(struct spi_device *spi) chips--; data->mcp[addr] = &data->chip[chips]; data->mcp[addr]->irq = spi->irq; + data->mcp[addr]->irq_chip.name = dev_name(&spi->dev); + data->mcp[addr]->irq_chip.irq_mask = mcp23s08_irq_mask; + data->mcp[addr]->irq_chip.irq_unmask = mcp23s08_irq_unmask; + data->mcp[addr]->irq_chip.irq_set_type = mcp23s08_irq_set_type; + data->mcp[addr]->irq_chip.irq_bus_lock = mcp23s08_irq_bus_lock; + data->mcp[addr]->irq_chip.irq_bus_sync_unlock = + mcp23s08_irq_bus_unlock; status = mcp23s08_probe_one(data->mcp[addr], &spi->dev, spi, 0x40 | (addr << 1), type, pdata->base, addr);