Messages in this thread | | | Date | Thu, 31 Mar 2011 14:48:33 -0600 | From | Grant Likely <> | Subject | Re: gpio: pca953x: prevent freeing IRQ 0 on probe error |
| |
On Fri, Mar 25, 2011 at 03:02:54PM -0700, H Hartley Sweeten wrote: > If CONFIG_GPIO_PCA953X_IRQ is enabled and an error occurs in the probe > before pca953x_irq_setup() is called chip->client->irq will be 0 due to > the kmalloc. pca953x_irq_teardown() will then try to free_irq(0, chip) > which will produce a: > > WARN(1, "Trying to free already-free IRQ %d\n", irq); > > Add an error path to prevent this. > > Signed-off-by: H Hartley Sweeten <hsweeten@visionengravers.com> > Cc: Grant Likely <grant.likely@secretlab.ca>
Thanks for catching this Hartley.
Ben also submitted a patch for this and I ended up looking at his patch first, so that is what's applied. :-)
g.
> > --- > > diff --git a/drivers/gpio/pca953x.c b/drivers/gpio/pca953x.c > index 2fc25de..e1ff4d5 100644 > --- a/drivers/gpio/pca953x.c > +++ b/drivers/gpio/pca953x.c > @@ -523,7 +523,7 @@ static int __devinit pca953x_probe(struct i2c_client *client, > if (pdata == NULL) { > dev_dbg(&client->dev, "no platform data\n"); > ret = -EINVAL; > - goto out_failed; > + goto out_free; > } > > chip->client = client; > @@ -541,20 +541,20 @@ static int __devinit pca953x_probe(struct i2c_client *client, > > ret = pca953x_read_reg(chip, PCA953X_OUTPUT, &chip->reg_output); > if (ret) > - goto out_failed; > + goto out_free; > > ret = pca953x_read_reg(chip, PCA953X_DIRECTION, &chip->reg_direction); > if (ret) > - goto out_failed; > + goto out_free; > > /* set platform specific polarity inversion */ > ret = pca953x_write_reg(chip, PCA953X_INVERT, pdata->invert); > if (ret) > - goto out_failed; > + goto out_free; > > ret = pca953x_irq_setup(chip, id); > if (ret) > - goto out_failed; > + goto out_free; > > ret = gpiochip_add(&chip->gpio_chip); > if (ret) > @@ -572,6 +572,7 @@ static int __devinit pca953x_probe(struct i2c_client *client, > > out_failed: > pca953x_irq_teardown(chip); > +out_free: > kfree(chip->dyn_pdata); > kfree(chip); > return ret;
| |