Re: pinctrl: mcp23s08: detected irqchip that is shared with multiple gpiochips - real of false?

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



G'day Marco,

On 11/06/2019 23:09, Marco Felsch wrote:
Hi Linus,

On 19-06-09 12:58, Linus Walleij wrote:
Added Marco and a few other MCP23s08 people who may be more familiar
with this code. (The driver is a bit complex.)

On Thu, Jun 6, 2019 at 10:59 AM Phil Reid <preid@xxxxxxxxxxxxxxxxx> wrote:

Using kernel 5.1 I'm getting the following message:
"detected irqchip that is shared with multiple gpiochips: please fix the driver"

Which I believe should be fixed by:
19ab5ca "pinctrl: mcp23s08: Allocate irq_chip dynamic"

However mcp23s08_probe_one() ends up calling gpiochip_set_irq_hooks() twice.

It looks strange when I look at the mcp23s08_probe_one() function
because it goes like:

if (mcp->irq && mcp->irq_controller) {
     ret = mcp23s08_irqchip_setup(mcp);
     if (ret)
         goto fail;
}
(...)
if (mcp->irq)
     ret = mcp23s08_irq_setup(mcp);

That seems wrong... but overall the code in this probe_one is pretty hard to
follow and probably needs some refactoring.

I don't think that this is wrong since I splitted only the irqchip setup
and the hw irq line setup.

This comes from f259f896f234 ("pinctrl: mcp23s08: fix irq and irqchip
setup order")
by Marco, Marco can you look into this and help us figure out why this happens?

I greped the code and found the possible failure:


static int mcp23s08_probe_one()
{
	...

	if (mcp->irq && mcp->irq_controller) {
		ret = mcp23s08_irqchip_setup(mcp);
		if (ret)
			goto fail;
	}

	ret = devm_gpiochip_add_data(dev, &mcp->chip, mcp);
	if (ret < 0)
		goto fail;

	...
}

The mcp23s08_irqchip_setup() call hierarchy:
mcp23s08_irqchip_setup()
   gpiochip_irqchip_add_nested()
     gpiochip_irqchip_add_key()
       gpiochip_set_irq_hooks()

The devm_gpiochip_add_data() call hierarchy:

devm_gpiochip_add_data()
   gpiochip_add_data_with_key()
     gpiochip_add_irqchip()
       gpiochip_set_irq_hooks()

The gpiochip_add_irqchip() returns immediately if there isn't a irqchip
but we added a irqchip due to the previous mcp23s08_irqchip_setup()
call. So it calls gpiochip_set_irq_hooks() a second time. If I got this
right the proper fix is:

static int mcp23s08_probe_one()
{
	...

	ret = devm_gpiochip_add_data(dev, &mcp->chip, mcp);
	if (ret < 0)
		goto fail;

	if (mcp->irq && mcp->irq_controller) {
		ret = mcp23s08_irqchip_setup(mcp);
		if (ret)
			goto fail;
	}

	...
}

I checked other users of gpiochip_irqchip_add_nested() and they call
(devm_)gpiochip_add_data always infront of the
gpiochip_irqchip_add_nested() call.

I hope this helps you.


Thanks, that fixed the error message and everything else seems to be working.
I've posted a patch with what I used.
Hopefully I've attributed everything appropriately.



--
Regards
Phil Reid



[Index of Archives]     [Linux SPI]     [Linux Kernel]     [Linux ARM (vger)]     [Linux ARM MSM]     [Linux Omap]     [Linux Arm]     [Linux Tegra]     [Fedora ARM]     [Linux for Samsung SOC]     [eCos]     [Linux Fastboot]     [Gcc Help]     [Git]     [DCCP]     [IETF Announce]     [Security]     [Linux MIPS]     [Yosemite Campsites]

  Powered by Linux