[PATCH] Balance alloc/free and ioremap/iounmap in gpio_mdio_probe (powerpc/platforms/pasemi/gpio_mdio.c)
Nathan Lynch
ntl at pobox.com
Mon Nov 5 04:18:14 EST 2007
Hi,
Roel Kluin wrote:
> I think this is how it should be done, but
> please review: it was not tested.
> --
> Balance alloc/free and ioremap/iounmap
It would be more helpful if your changelog identified the objects
which could be leaked. More comments below.
> -static int __devinit gpio_mdio_probe(struct of_device *ofdev,
> - const struct of_device_id *match)
> +static int __devinit __gpio_mdio_register_bus(struct of_device *ofdev,
> + const struct of_device_id *match)
> {
> struct device *dev = &ofdev->dev;
> struct device_node *np = ofdev->node;
> - struct device_node *gpio_np;
> struct mii_bus *new_bus;
> struct resource res;
> struct gpio_priv *priv;
> const unsigned int *prop;
> - int err = 0;
> int i;
>
> - gpio_np = of_find_compatible_node(NULL, "gpio", "1682m-gpio");
> -
> - if (!gpio_np)
> - return -ENODEV;
> -
> - err = of_address_to_resource(gpio_np, 0, &res);
> - of_node_put(gpio_np);
> -
> - if (err)
> - return -EINVAL;
> -
> - if (!gpio_regs)
> - gpio_regs = ioremap(res.start, 0x100);
> -
> - if (!gpio_regs)
> - return -EPERM;
> -
> priv = kzalloc(sizeof(struct gpio_priv), GFP_KERNEL);
> - if (priv == NULL)
> + if (unlikely(priv == NULL))
> return -ENOMEM;
Please don't add likely/unlikely to non-hot paths such as this.
> new_bus = kzalloc(sizeof(struct mii_bus), GFP_KERNEL);
>
> - if (new_bus == NULL)
> - return -ENOMEM;
> + if (unlikely(new_bus == NULL))
> + goto free_priv;
again
>
> new_bus->name = "pasemi gpio mdio bus",
> new_bus->read = &gpio_mdio_read,
> new_bus->write = &gpio_mdio_write,
> new_bus->reset = &gpio_mdio_reset,
>
> prop = of_get_property(np, "reg", NULL);
> new_bus->id = *prop;
> new_bus->priv = priv;
>
> new_bus->phy_mask = 0;
>
> new_bus->irq = kmalloc(sizeof(int)*PHY_MAX_ADDR, GFP_KERNEL);
> + if (unlikely(new_bus->irq == NULL))
> + goto free_new_bus;
> +
again
> for(i = 0; i < PHY_MAX_ADDR; ++i)
> new_bus->irq[i] = irq_create_mapping(NULL, 10);
>
>
> prop = of_get_property(np, "mdc-pin", NULL);
> priv->mdc_pin = *prop;
>
> prop = of_get_property(np, "mdio-pin", NULL);
> priv->mdio_pin = *prop;
>
> new_bus->dev = dev;
> dev_set_drvdata(dev, new_bus);
>
> err = mdiobus_register(new_bus);
>
> - if (0 != err) {
> + if (unlikely(0 != err)) {
again
> printk(KERN_ERR "%s: Cannot register as MDIO bus, err %d\n",
> new_bus->name, err);
> goto bus_register_fail;
> }
>
> return 0;
>
> bus_register_fail:
> + kfree(new_bus->irq);
> +free_new_bus:
> kfree(new_bus);
> +free_priv:
> + kfree(priv);
> +
> + return -ENOMEM;
> +}
> +
> +
> +static int __devinit gpio_mdio_probe(struct of_device *ofdev,
> + const struct of_device_id *match)
> +{
> + struct device_node *gpio_np;
> + int err;
> +
> + gpio_np = of_find_compatible_node(NULL, "gpio", "1682m-gpio");
> +
> + if (!gpio_np)
> + return -ENODEV;
> +
> + err = of_address_to_resource(gpio_np, 0, &res);
Hmm, where is "res" defined?
> + of_node_put(gpio_np);
> +
> + if (err)
> + return -EINVAL;
> +
> + if (!gpio_regs) {
> +
Unneeded newline
> + gpio_regs = ioremap(res.start, 0x100);
> + if (unlikely(!gpio_regs))
> + return -EPERM;
> +
> + err = __gpio_mdio_register_bus(ofdev, match);
> + if (err < 0)
> + iounmap(gpio_regs);
> + } else
> + err = __gpio_mdio_register_bus(ofdev, match);
>
> return err;
> +
again
> }
>
>
> static int gpio_mdio_remove(struct of_device *dev)
> {
> struct mii_bus *bus = dev_get_drvdata(&dev->dev);
>
> mdiobus_unregister(bus);
>
More information about the Linuxppc-dev
mailing list