static int __devinit fs_enet_mdio_probe(struct of_device *ofdev, const struct of_device_id *match) { struct device_node *np = NULL; struct mii_bus *new_bus; struct bb_info *bitbang; int ret = -ENOMEM; int i; bitbang = kzalloc(sizeof(struct bb_info), GFP_KERNEL); if (!bitbang) goto out; bitbang->ctrl.ops = &bb_ops; new_bus = alloc_mdio_bitbang(&bitbang->ctrl); if (!new_bus) goto out_free_priv; new_bus->name = "CPM2 Bitbanged MII", ret = fs_mii_bitbang_init(new_bus, ofdev->node); if (ret) goto out_free_bus; new_bus->phy_mask = ~0; new_bus->irq = kmalloc(sizeof(int) * PHY_MAX_ADDR, GFP_KERNEL); if (!new_bus->irq) goto out_unmap_regs; for (i = 0; i < PHY_MAX_ADDR; i++) new_bus->irq[i] = -1; while ((np = of_get_next_child(ofdev->node, np))) if (!strcmp(np->type, "ethernet-phy")) add_phy(new_bus, np); new_bus->parent = &ofdev->dev; dev_set_drvdata(&ofdev->dev, new_bus); ret = mdiobus_register(new_bus); if (ret) goto out_free_irqs; return 0; out_free_irqs: dev_set_drvdata(&ofdev->dev, NULL); kfree(new_bus->irq); out_unmap_regs: iounmap(bitbang->dir); out_free_bus: free_mdio_bitbang(new_bus); out_free_priv: kfree(bitbang); out: return ret; }
static int __devinit fs_enet_mdio_probe(struct of_device *ofdev, const struct of_device_id *match) { struct device_node *np = NULL; struct resource res; struct mii_bus *new_bus; struct fec_info *fec; int ret = -ENOMEM, i; new_bus = kzalloc(sizeof(struct mii_bus), GFP_KERNEL); if (!new_bus) goto out; fec = kzalloc(sizeof(struct fec_info), GFP_KERNEL); if (!fec) goto out_mii; new_bus->priv = fec; new_bus->name = "FEC MII Bus"; new_bus->read = &fs_enet_fec_mii_read; new_bus->write = &fs_enet_fec_mii_write; new_bus->reset = &fs_enet_fec_mii_reset; ret = of_address_to_resource(ofdev->node, 0, &res); if (ret) goto out_res; snprintf(new_bus->id, MII_BUS_ID_SIZE, "%x", res.start); fec->fecp = ioremap(res.start, res.end - res.start + 1); if (!fec->fecp) goto out_fec; fec->mii_speed = ((ppc_proc_freq + 4999999) / 5000000) << 1; setbits32(&fec->fecp->fec_r_cntrl, FEC_RCNTRL_MII_MODE); setbits32(&fec->fecp->fec_ecntrl, FEC_ECNTRL_PINMUX | FEC_ECNTRL_ETHER_EN); out_be32(&fec->fecp->fec_ievent, FEC_ENET_MII); out_be32(&fec->fecp->fec_mii_speed, fec->mii_speed); new_bus->phy_mask = ~0; new_bus->irq = kmalloc(sizeof(int) * PHY_MAX_ADDR, GFP_KERNEL); if (!new_bus->irq) goto out_unmap_regs; for (i = 0; i < PHY_MAX_ADDR; i++) new_bus->irq[i] = -1; while ((np = of_get_next_child(ofdev->node, np))) if (!strcmp(np->type, "ethernet-phy")) add_phy(new_bus, np); new_bus->dev = &ofdev->dev; dev_set_drvdata(&ofdev->dev, new_bus); ret = mdiobus_register(new_bus); if (ret) goto out_free_irqs; return 0; out_free_irqs: dev_set_drvdata(&ofdev->dev, NULL); kfree(new_bus->irq); out_unmap_regs: iounmap(fec->fecp); out_res: out_fec: kfree(fec); out_mii: kfree(new_bus); out: return ret; }