static int mdio_gpio_probe(struct platform_device *pdev) { struct mdio_gpio_platform_data *pdata; struct mii_bus *new_bus; int ret, bus_id; if (pdev->dev.of_node) { pdata = mdio_gpio_of_get_data(pdev); bus_id = of_alias_get_id(pdev->dev.of_node, "mdio-gpio"); } else { pdata = dev_get_platdata(&pdev->dev); bus_id = pdev->id; } if (!pdata) return -ENODEV; new_bus = mdio_gpio_bus_init(&pdev->dev, pdata, bus_id); if (!new_bus) return -ENODEV; if (pdev->dev.of_node) ret = of_mdiobus_register(new_bus, pdev->dev.of_node); else ret = mdiobus_register(new_bus); if (ret) mdio_gpio_bus_deinit(&pdev->dev); return ret; }
static int mdio_gpio_probe(struct platform_device *pdev) { struct mdio_gpio_info *bitbang; struct mii_bus *new_bus; int ret, bus_id; bitbang = devm_kzalloc(&pdev->dev, sizeof(*bitbang), GFP_KERNEL); if (!bitbang) return -ENOMEM; ret = mdio_gpio_get_data(&pdev->dev, bitbang); if (ret) return ret; if (pdev->dev.of_node) { bus_id = of_alias_get_id(pdev->dev.of_node, "mdio-gpio"); if (bus_id < 0) { dev_warn(&pdev->dev, "failed to get alias id\n"); bus_id = 0; } } else { bus_id = pdev->id; } new_bus = mdio_gpio_bus_init(&pdev->dev, bitbang, bus_id); if (!new_bus) return -ENODEV; ret = of_mdiobus_register(new_bus, pdev->dev.of_node); if (ret) mdio_gpio_bus_deinit(&pdev->dev); return ret; }
static int __devinit mdio_gpio_probe(struct platform_device *pdev) { struct mdio_gpio_platform_data *pdata; struct mii_bus *new_bus; int ret; if (pdev->dev.of_node) pdata = mdio_gpio_of_get_data(pdev); else pdata = pdev->dev.platform_data; if (!pdata) return -ENODEV; new_bus = mdio_gpio_bus_init(&pdev->dev, pdata, pdev->id); if (!new_bus) return -ENODEV; if (pdev->dev.of_node) ret = of_mdiobus_register(new_bus, pdev->dev.of_node); else ret = mdiobus_register(new_bus); if (ret) mdio_gpio_bus_deinit(&pdev->dev); return ret; }
static int bcmgenet_mii_of_init(struct bcmgenet_priv *priv) { struct device_node *dn = priv->pdev->dev.of_node; struct device *kdev = &priv->pdev->dev; struct device_node *mdio_dn; char *compat; int ret; compat = kasprintf(GFP_KERNEL, "brcm,genet-mdio-v%d", priv->version); if (!compat) return -ENOMEM; mdio_dn = of_find_compatible_node(dn, NULL, compat); kfree(compat); if (!mdio_dn) { dev_err(kdev, "unable to find MDIO bus node\n"); return -ENODEV; } ret = of_mdiobus_register(priv->mii_bus, mdio_dn); if (ret) { dev_err(kdev, "failed to register MDIO bus\n"); return ret; } /* Fetch the PHY phandle */ priv->phy_dn = of_parse_phandle(dn, "phy-handle", 0); /* Get the link mode */ priv->phy_interface = of_get_phy_mode(dn); return 0; }
static int __devinit ep8248e_mdio_probe(struct of_device *ofdev, const struct of_device_id *match) { struct mii_bus *bus; struct resource res; struct device_node *node; int ret; node = of_get_parent(ofdev->node); of_node_put(node); if (node != ep8248e_bcsr_node) return -ENODEV; ret = of_address_to_resource(ofdev->node, 0, &res); if (ret) return ret; bus = alloc_mdio_bitbang(&ep8248e_mdio_ctrl); if (!bus) return -ENOMEM; bus->irq = kmalloc(sizeof(int) * PHY_MAX_ADDR, GFP_KERNEL); bus->name = "ep8248e-mdio-bitbang"; bus->parent = &ofdev->dev; snprintf(bus->id, MII_BUS_ID_SIZE, "%x", res.start); return of_mdiobus_register(bus, ofdev->node); }
static int mpc52xx_fec_mdio_probe(struct platform_device *of) { struct device *dev = &of->dev; struct device_node *np = of->dev.of_node; struct mii_bus *bus; struct mpc52xx_fec_mdio_priv *priv; struct resource res; int err; bus = mdiobus_alloc(); if (bus == NULL) return -ENOMEM; priv = kzalloc(sizeof(*priv), GFP_KERNEL); if (priv == NULL) { err = -ENOMEM; goto out_free; } bus->name = "mpc52xx MII bus"; bus->read = mpc52xx_fec_mdio_read; bus->write = mpc52xx_fec_mdio_write; /* setup irqs */ bus->irq = priv->mdio_irqs; /* setup registers */ err = of_address_to_resource(np, 0, &res); if (err) goto out_free; priv->regs = ioremap(res.start, resource_size(&res)); if (priv->regs == NULL) { err = -ENOMEM; goto out_free; } snprintf(bus->id, MII_BUS_ID_SIZE, "%x", res.start); bus->priv = priv; bus->parent = dev; dev_set_drvdata(dev, bus); /* set MII speed */ out_be32(&priv->regs->mii_speed, ((mpc5xxx_get_bus_frequency(of->dev.of_node) >> 20) / 5) << 1); err = of_mdiobus_register(bus, np); if (err) goto out_unmap; return 0; out_unmap: iounmap(priv->regs); out_free: kfree(priv); mdiobus_free(bus); return err; }
static int bcm_sf2_mdio_register(struct dsa_switch *ds) { struct bcm_sf2_priv *priv = ds_to_priv(ds); struct device_node *dn; static int index; int err; /* Find our integrated MDIO bus node */ dn = of_find_compatible_node(NULL, NULL, "brcm,unimac-mdio"); priv->master_mii_bus = of_mdio_find_bus(dn); if (!priv->master_mii_bus) return -EPROBE_DEFER; get_device(&priv->master_mii_bus->dev); priv->master_mii_dn = dn; priv->slave_mii_bus = devm_mdiobus_alloc(ds->dev); if (!priv->slave_mii_bus) return -ENOMEM; priv->slave_mii_bus->priv = priv; priv->slave_mii_bus->name = "sf2 slave mii"; priv->slave_mii_bus->read = bcm_sf2_sw_mdio_read; priv->slave_mii_bus->write = bcm_sf2_sw_mdio_write; snprintf(priv->slave_mii_bus->id, MII_BUS_ID_SIZE, "sf2-%d", index++); priv->slave_mii_bus->dev.of_node = dn; /* Include the pseudo-PHY address to divert reads towards our * workaround. This is only required for 7445D0, since 7445E0 * disconnects the internal switch pseudo-PHY such that we can use the * regular SWITCH_MDIO master controller instead. * * Here we flag the pseudo PHY as needing special treatment and would * otherwise make all other PHY read/writes go to the master MDIO bus * controller that comes with this switch backed by the "mdio-unimac" * driver. */ if (of_machine_is_compatible("brcm,bcm7445d0")) priv->indir_phy_mask |= (1 << BRCM_PSEUDO_PHY_ADDR); else priv->indir_phy_mask = 0; ds->phys_mii_mask = priv->indir_phy_mask; ds->slave_mii_bus = priv->slave_mii_bus; priv->slave_mii_bus->parent = ds->dev->parent; priv->slave_mii_bus->phy_mask = ~priv->indir_phy_mask; if (dn) err = of_mdiobus_register(priv->slave_mii_bus, dn); else err = mdiobus_register(priv->slave_mii_bus); if (err) of_node_put(dn); return err; }
static int __devinit gpio_mdio_probe(struct platform_device *ofdev, const struct of_device_id *match) { struct device *dev = &ofdev->dev; struct device_node *np = ofdev->dev.of_node; struct mii_bus *new_bus; struct gpio_priv *priv; const unsigned int *prop; int err; err = -ENOMEM; priv = kzalloc(sizeof(struct gpio_priv), GFP_KERNEL); if (!priv) goto out; new_bus = mdiobus_alloc(); if (!new_bus) goto out_free_priv; 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); snprintf(new_bus->id, MII_BUS_ID_SIZE, "%x", *prop); new_bus->priv = priv; new_bus->irq = priv->mdio_irqs; 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->parent = dev; dev_set_drvdata(dev, new_bus); err = of_mdiobus_register(new_bus, np); if (err != 0) { printk(KERN_ERR "%s: Cannot register as MDIO bus, err %d\n", new_bus->name, err); goto out_free_irq; } return 0; out_free_irq: kfree(new_bus); out_free_priv: kfree(priv); out: return err; }
static int vsc848x_nexus_probe(struct platform_device *pdev) { struct vsc848x_nexus_mdiobus *bus; const char *bus_id; int len; int err = 0; bus = devm_kzalloc(&pdev->dev, sizeof(*bus), GFP_KERNEL); if (!bus) return -ENOMEM; bus->parent_mii_bus = container_of(pdev->dev.parent, struct mii_bus, dev); /* The PHY nexux must have a reg property in the range [0-31] */ err = of_property_read_u32(pdev->dev.of_node, "reg", &bus->reg_offset); if (err) { dev_err(&pdev->dev, "%s has invalid PHY address\n", pdev->dev.of_node->full_name); return err; } bus->mii_bus = mdiobus_alloc(); if (!bus->mii_bus) return -ENOMEM; bus->mii_bus->priv = bus; bus->mii_bus->irq = bus->phy_irq; bus->mii_bus->name = "vsc848x_nexus"; bus_id = bus->parent_mii_bus->id; len = strlen(bus_id); if (len > MII_BUS_ID_SIZE - 4) bus_id += len - (MII_BUS_ID_SIZE - 4); snprintf(bus->mii_bus->id, MII_BUS_ID_SIZE, "%s:%02x", bus_id, bus->reg_offset); bus->mii_bus->parent = &pdev->dev; bus->mii_bus->read = vsc848x_nexus_read; bus->mii_bus->write = vsc848x_nexus_write; mutex_init(&bus->lock); dev_set_drvdata(&pdev->dev, bus); err = of_mdiobus_register(bus->mii_bus, pdev->dev.of_node); if (err) { dev_err(&pdev->dev, "Error registering with device tree\n"); goto fail_register; } return 0; fail_register: dev_err(&pdev->dev, "Failed to register\n"); mdiobus_free(bus->mii_bus); return err; }
int temac_mdio_setup(struct temac_local *lp, struct device_node *np) { struct mii_bus *bus; u32 bus_hz; int clk_div; int rc; struct resource res; struct device_node *np1 = of_get_parent(lp->phy_node); /* Calculate a reasonable divisor for the clock rate */ clk_div = 0x3f; /* worst-case default setting */ if (of_property_read_u32(np, "clock-frequency", &bus_hz) == 0) { clk_div = bus_hz / (2500 * 1000 * 2) - 1; if (clk_div < 1) clk_div = 1; if (clk_div > 0x3f) clk_div = 0x3f; } /* Enable the MDIO bus by asserting the enable bit and writing * in the clock config */ mutex_lock(&lp->indirect_mutex); temac_indirect_out32(lp, XTE_MC_OFFSET, 1 << 6 | clk_div); mutex_unlock(&lp->indirect_mutex); bus = mdiobus_alloc(); if (!bus) return -ENOMEM; of_address_to_resource(np1, 0, &res); snprintf(bus->id, MII_BUS_ID_SIZE, "%.8llx", (unsigned long long)res.start); bus->priv = lp; bus->name = "Xilinx TEMAC MDIO"; bus->read = temac_mdio_read; bus->write = temac_mdio_write; bus->parent = lp->dev; lp->mii_bus = bus; rc = of_mdiobus_register(bus, np1); if (rc) goto err_register; mutex_lock(&lp->indirect_mutex); dev_dbg(lp->dev, "MDIO bus registered; MC:%x\n", temac_indirect_in32(lp, XTE_MC_OFFSET)); mutex_unlock(&lp->indirect_mutex); return 0; err_register: mdiobus_free(bus); return rc; }
static int sun4i_mdio_probe(struct platform_device *pdev) { struct device_node *np = pdev->dev.of_node; struct mii_bus *bus; struct sun4i_mdio_data *data; struct resource *res; int ret; bus = mdiobus_alloc_size(sizeof(*data)); if (!bus) return -ENOMEM; bus->name = "sun4i_mii_bus"; bus->read = &sun4i_mdio_read; bus->write = &sun4i_mdio_write; snprintf(bus->id, MII_BUS_ID_SIZE, "%s-mii", dev_name(&pdev->dev)); bus->parent = &pdev->dev; data = bus->priv; res = platform_get_resource(pdev, IORESOURCE_MEM, 0); data->membase = devm_ioremap_resource(&pdev->dev, res); if (IS_ERR(data->membase)) { ret = PTR_ERR(data->membase); goto err_out_free_mdiobus; } data->regulator = devm_regulator_get(&pdev->dev, "phy"); if (IS_ERR(data->regulator)) { if (PTR_ERR(data->regulator) == -EPROBE_DEFER) return -EPROBE_DEFER; dev_info(&pdev->dev, "no regulator found\n"); data->regulator = NULL; } else { ret = regulator_enable(data->regulator); if (ret) goto err_out_free_mdiobus; } ret = of_mdiobus_register(bus, np); if (ret < 0) goto err_out_disable_regulator; platform_set_drvdata(pdev, bus); return 0; err_out_disable_regulator: if (data->regulator) regulator_disable(data->regulator); err_out_free_mdiobus: mdiobus_free(bus); return ret; }
int temac_mdio_setup(struct temac_local *lp, struct device_node *np) { struct mii_bus *bus; const u32 *bus_hz; int clk_div; int rc, size; struct resource res; clk_div = 0x3f; bus_hz = of_get_property(np, "clock-frequency", &size); if (bus_hz && size >= sizeof(*bus_hz)) { clk_div = (*bus_hz) / (2500 * 1000 * 2) - 1; if (clk_div < 1) clk_div = 1; if (clk_div > 0x3f) clk_div = 0x3f; } mutex_lock(&lp->indirect_mutex); temac_indirect_out32(lp, XTE_MC_OFFSET, 1 << 6 | clk_div); mutex_unlock(&lp->indirect_mutex); bus = mdiobus_alloc(); if (!bus) return -ENOMEM; of_address_to_resource(np, 0, &res); snprintf(bus->id, MII_BUS_ID_SIZE, "%.8llx", (unsigned long long)res.start); bus->priv = lp; bus->name = "Xilinx TEMAC MDIO"; bus->read = temac_mdio_read; bus->write = temac_mdio_write; bus->parent = lp->dev; bus->irq = lp->mdio_irqs; lp->mii_bus = bus; rc = of_mdiobus_register(bus, np); if (rc) goto err_register; mutex_lock(&lp->indirect_mutex); dev_dbg(lp->dev, "MDIO bus registered; MC:%x\n", temac_indirect_in32(lp, XTE_MC_OFFSET)); mutex_unlock(&lp->indirect_mutex); return 0; err_register: mdiobus_free(bus); return rc; }
static int xgmac_mdio_probe(struct platform_device *pdev) { struct device_node *np = pdev->dev.of_node; struct mii_bus *bus; struct resource res; int ret; ret = of_address_to_resource(np, 0, &res); if (ret) { dev_err(&pdev->dev, "could not obtain address\n"); return ret; } bus = mdiobus_alloc_size(PHY_MAX_ADDR * sizeof(int)); if (!bus) return -ENOMEM; bus->name = "Freescale XGMAC MDIO Bus"; bus->read = xgmac_mdio_read; bus->write = xgmac_mdio_write; bus->reset = xgmac_mdio_reset; bus->irq = bus->priv; bus->parent = &pdev->dev; snprintf(bus->id, MII_BUS_ID_SIZE, "%llx", (unsigned long long)res.start); /* Set the PHY base address */ bus->priv = of_iomap(np, 0); if (!bus->priv) { ret = -ENOMEM; goto err_ioremap; } ret = of_mdiobus_register(bus, np); if (ret) { dev_err(&pdev->dev, "cannot register MDIO bus\n"); goto err_registration; } platform_set_drvdata(pdev, bus); return 0; err_registration: iounmap(bus->priv); err_ioremap: mdiobus_free(bus); return ret; }
static int __devinit fs_enet_mdio_probe(struct platform_device *ofdev) { struct mii_bus *new_bus; struct bb_info *bitbang; int ret = -ENOMEM; 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->dev.of_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) { ret = -ENOMEM; goto out_unmap_regs; } new_bus->parent = &ofdev->dev; dev_set_drvdata(&ofdev->dev, new_bus); ret = of_mdiobus_register(new_bus, ofdev->dev.of_node); 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; }
int mtk_mdio_init(struct mtk_eth *eth) { struct device_node *mii_np; int err; if (!eth->soc->mdio_read || !eth->soc->mdio_write) return 0; spin_lock_init(&phy_ralink.lock); eth->phy = &phy_ralink; mii_np = of_get_child_by_name(eth->dev->of_node, "mdio-bus"); if (!mii_np) { dev_err(eth->dev, "no %s child node found", "mdio-bus"); return -ENODEV; } if (!of_device_is_available(mii_np)) { err = 0; goto err_put_node; } eth->mii_bus = mdiobus_alloc(); if (!eth->mii_bus) { err = -ENOMEM; goto err_put_node; } eth->mii_bus->name = "mdio"; eth->mii_bus->read = eth->soc->mdio_read; eth->mii_bus->write = eth->soc->mdio_write; eth->mii_bus->reset = mtk_mdio_reset; eth->mii_bus->priv = eth; eth->mii_bus->parent = eth->dev; snprintf(eth->mii_bus->id, MII_BUS_ID_SIZE, "%s", mii_np->name); err = of_mdiobus_register(eth->mii_bus, mii_np); if (err) goto err_free_bus; return 0; err_free_bus: kfree(eth->mii_bus); err_put_node: of_node_put(mii_np); eth->mii_bus = NULL; return err; }
static int moxart_mdio_probe(struct platform_device *pdev) { struct device_node *np = pdev->dev.of_node; struct mii_bus *bus; struct moxart_mdio_data *data; struct resource *res; int ret, i; bus = mdiobus_alloc_size(sizeof(*data)); if (!bus) return -ENOMEM; bus->name = "MOXA ART Ethernet MII"; bus->read = &moxart_mdio_read; bus->write = &moxart_mdio_write; bus->reset = &moxart_mdio_reset; snprintf(bus->id, MII_BUS_ID_SIZE, "%s-%d-mii", pdev->name, pdev->id); bus->parent = &pdev->dev; /* Setting PHY_IGNORE_INTERRUPT here even if it has no effect, * of_mdiobus_register() sets these PHY_POLL. * Ideally, the interrupt from MAC controller could be used to * detect link state changes, not polling, i.e. if there was * a way phy_driver could set PHY_HAS_INTERRUPT but have that * interrupt handled in ethernet drivercode. */ for (i = 0; i < PHY_MAX_ADDR; i++) bus->irq[i] = PHY_IGNORE_INTERRUPT; data = bus->priv; res = platform_get_resource(pdev, IORESOURCE_MEM, 0); data->base = devm_ioremap_resource(&pdev->dev, res); if (IS_ERR(data->base)) { ret = PTR_ERR(data->base); goto err_out_free_mdiobus; } ret = of_mdiobus_register(bus, np); if (ret < 0) goto err_out_free_mdiobus; platform_set_drvdata(pdev, bus); return 0; err_out_free_mdiobus: mdiobus_free(bus); return ret; }
static int iproc_mdio_probe(struct platform_device *pdev) { struct iproc_mdio_priv *priv; struct mii_bus *bus; struct resource *res; int rc; priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL); if (!priv) return -ENOMEM; res = platform_get_resource(pdev, IORESOURCE_MEM, 0); priv->base = devm_ioremap_resource(&pdev->dev, res); if (IS_ERR(priv->base)) { dev_err(&pdev->dev, "failed to ioremap register\n"); return PTR_ERR(priv->base); } priv->mii_bus = mdiobus_alloc(); if (!priv->mii_bus) { dev_err(&pdev->dev, "MDIO bus alloc failed\n"); return -ENOMEM; } bus = priv->mii_bus; bus->priv = priv; bus->name = "iProc MDIO bus"; snprintf(bus->id, MII_BUS_ID_SIZE, "%s-%d", pdev->name, pdev->id); bus->parent = &pdev->dev; bus->read = iproc_mdio_read; bus->write = iproc_mdio_write; rc = of_mdiobus_register(bus, pdev->dev.of_node); if (rc) { dev_err(&pdev->dev, "MDIO bus registration failed\n"); goto err_iproc_mdio; } platform_set_drvdata(pdev, priv); dev_info(&pdev->dev, "Broadcom iProc MDIO bus at 0x%p\n", priv->base); return 0; err_iproc_mdio: mdiobus_free(bus); return rc; }
/** * arc_mdio_probe - MDIO probe function. * @priv: Pointer to ARC EMAC private data structure. * * returns: 0 on success, -ENOMEM when mdiobus_alloc * (to allocate memory for MII bus structure) fails. * * Sets up and registers the MDIO interface. */ int arc_mdio_probe(struct arc_emac_priv *priv) { struct arc_emac_mdio_bus_data *data = &priv->bus_data; struct device_node *np = priv->dev->of_node; struct mii_bus *bus; int error; bus = mdiobus_alloc(); if (!bus) return -ENOMEM; priv->bus = bus; bus->priv = priv; bus->parent = priv->dev; bus->name = "Synopsys MII Bus"; bus->read = &arc_mdio_read; bus->write = &arc_mdio_write; bus->reset = &arc_mdio_reset; /* optional reset-related properties */ data->reset_gpio = devm_gpiod_get_optional(priv->dev, "phy-reset", GPIOD_OUT_LOW); if (IS_ERR(data->reset_gpio)) { error = PTR_ERR(data->reset_gpio); dev_err(priv->dev, "Failed to request gpio: %d\n", error); return error; } of_property_read_u32(np, "phy-reset-duration", &data->msec); /* A sane reset duration should not be longer than 1s */ if (data->msec > 1000) data->msec = 1; snprintf(bus->id, MII_BUS_ID_SIZE, "%s", bus->name); error = of_mdiobus_register(bus, priv->dev->of_node); if (error) { dev_err(priv->dev, "cannot register MDIO bus %s\n", bus->name); mdiobus_free(bus); return error; } return 0; }
static int gswip_mdio(struct gswip_priv *priv, struct device_node *mdio_np) { struct dsa_switch *ds = priv->ds; ds->slave_mii_bus = devm_mdiobus_alloc(priv->dev); if (!ds->slave_mii_bus) return -ENOMEM; ds->slave_mii_bus->priv = priv; ds->slave_mii_bus->read = gswip_mdio_rd; ds->slave_mii_bus->write = gswip_mdio_wr; ds->slave_mii_bus->name = "lantiq,xrx200-mdio"; snprintf(ds->slave_mii_bus->id, MII_BUS_ID_SIZE, "%s-mii", dev_name(priv->dev)); ds->slave_mii_bus->parent = priv->dev; ds->slave_mii_bus->phy_mask = ~ds->phys_mii_mask; return of_mdiobus_register(ds->slave_mii_bus, mdio_np); }
static int hip04_mdio_probe(struct platform_device *pdev) { struct resource *r; struct mii_bus *bus; struct hip04_mdio_priv *priv; int ret; bus = mdiobus_alloc_size(sizeof(struct hip04_mdio_priv)); if (!bus) { dev_err(&pdev->dev, "Cannot allocate MDIO bus\n"); return -ENOMEM; } bus->name = "hip04_mdio_bus"; bus->read = hip04_mdio_read; bus->write = hip04_mdio_write; bus->reset = hip04_mdio_reset; snprintf(bus->id, MII_BUS_ID_SIZE, "%s-mii", dev_name(&pdev->dev)); bus->parent = &pdev->dev; priv = bus->priv; r = platform_get_resource(pdev, IORESOURCE_MEM, 0); priv->base = devm_ioremap_resource(&pdev->dev, r); if (IS_ERR(priv->base)) { ret = PTR_ERR(priv->base); goto out_mdio; } ret = of_mdiobus_register(bus, pdev->dev.of_node); if (ret < 0) { dev_err(&pdev->dev, "Cannot register MDIO bus (%d)\n", ret); goto out_mdio; } platform_set_drvdata(pdev, bus); return 0; out_mdio: mdiobus_free(bus); return ret; }
static int __devinit ep8248e_mdio_probe(struct platform_device *ofdev) { struct mii_bus *bus; struct resource res; struct device_node *node; int ret; node = of_get_parent(ofdev->dev.of_node); of_node_put(node); if (node != ep8248e_bcsr_node) return -ENODEV; ret = of_address_to_resource(ofdev->dev.of_node, 0, &res); if (ret) return ret; bus = alloc_mdio_bitbang(&ep8248e_mdio_ctrl); if (!bus) return -ENOMEM; bus->irq = kmalloc(sizeof(int) * PHY_MAX_ADDR, GFP_KERNEL); if (bus->irq == NULL) { ret = -ENOMEM; goto err_free_bus; } bus->name = "ep8248e-mdio-bitbang"; bus->parent = &ofdev->dev; snprintf(bus->id, MII_BUS_ID_SIZE, "%x", res.start); ret = of_mdiobus_register(bus, ofdev->dev.of_node); if (ret) goto err_free_irq; return 0; err_free_irq: kfree(bus->irq); err_free_bus: free_mdio_bitbang(bus); return ret; }
/** * axienet_mdio_setup - MDIO setup function * @lp: Pointer to axienet local data structure. * @np: Pointer to device node * * returns: 0 on success, -ETIMEDOUT on a timeout, -ENOMEM when * mdiobus_alloc (to allocate memory for mii bus structure) fails. * * Sets up the MDIO interface by initializing the MDIO clock and enabling the * MDIO interface in hardware. Register the MDIO interface. **/ int axienet_mdio_setup(struct axienet_local *lp, struct device_node *np) { int ret; u32 clk_div, host_clock; u32 *property_p; struct mii_bus *bus; struct resource res; struct device_node *np1; /* clk_div can be calculated by deriving it from the equation: * fMDIO = fHOST / ((1 + clk_div) * 2) * * Where fMDIO <= 2500000, so we get: * fHOST / ((1 + clk_div) * 2) <= 2500000 * * Then we get: * 1 / ((1 + clk_div) * 2) <= (2500000 / fHOST) * * Then we get: * 1 / (1 + clk_div) <= ((2500000 * 2) / fHOST) * * Then we get: * 1 / (1 + clk_div) <= (5000000 / fHOST) * * So: * (1 + clk_div) >= (fHOST / 5000000) * * And finally: * clk_div >= (fHOST / 5000000) - 1 * * fHOST can be read from the flattened device tree as property * "clock-frequency" from the CPU */ np1 = of_find_node_by_name(NULL, "cpu"); if (!np1) { printk(KERN_WARNING "%s(): Could not find CPU device node.", __func__); printk(KERN_WARNING "Setting MDIO clock divisor to " "default %d\n", DEFAULT_CLOCK_DIVISOR); clk_div = DEFAULT_CLOCK_DIVISOR; goto issue; } property_p = (u32 *) of_get_property(np1, "clock-frequency", NULL); if (!property_p) { printk(KERN_WARNING "%s(): Could not find CPU property: " "clock-frequency.", __func__); printk(KERN_WARNING "Setting MDIO clock divisor to " "default %d\n", DEFAULT_CLOCK_DIVISOR); clk_div = DEFAULT_CLOCK_DIVISOR; of_node_put(np1); goto issue; } host_clock = be32_to_cpup(property_p); clk_div = (host_clock / (MAX_MDIO_FREQ * 2)) - 1; /* If there is any remainder from the division of * fHOST / (MAX_MDIO_FREQ * 2), then we need to add * 1 to the clock divisor or we will surely be above 2.5 MHz */ if (host_clock % (MAX_MDIO_FREQ * 2)) clk_div++; printk(KERN_DEBUG "%s(): Setting MDIO clock divisor to %u based " "on %u Hz host clock.\n", __func__, clk_div, host_clock); of_node_put(np1); issue: axienet_iow(lp, XAE_MDIO_MC_OFFSET, (((u32) clk_div) | XAE_MDIO_MC_MDIOEN_MASK)); ret = axienet_mdio_wait_until_ready(lp); if (ret < 0) return ret; bus = mdiobus_alloc(); if (!bus) return -ENOMEM; np1 = of_get_parent(lp->phy_node); of_address_to_resource(np1, 0, &res); snprintf(bus->id, MII_BUS_ID_SIZE, "%.8llx", (unsigned long long) res.start); bus->priv = lp; bus->name = "Xilinx Axi Ethernet MDIO"; bus->read = axienet_mdio_read; bus->write = axienet_mdio_write; bus->parent = lp->dev; bus->irq = lp->mdio_irqs; /* preallocated IRQ table */ lp->mii_bus = bus; ret = of_mdiobus_register(bus, np1); if (ret) { mdiobus_free(bus); return ret; } return 0; }
static int sun4i_mdio_probe(struct vmm_device *pdev, const struct vmm_devtree_nodeid *devid) { struct device_node *np = pdev->node; struct mii_bus *bus; struct sun4i_mdio_data *data; int ret, i; virtual_addr_t reg_addr; bus = mdiobus_alloc_size(sizeof(*data)); if (!bus) return -ENOMEM; bus->name = "sun4i_mii_bus"; bus->read = &sun4i_mdio_read; bus->write = &sun4i_mdio_write; bus->reset = &sun4i_mdio_reset; snprintf(bus->id, MII_BUS_ID_SIZE, "%s-mii", dev_name(pdev)); bus->parent = pdev; #if 0 bus->irq = devm_kzalloc(&pdev->dev, sizeof(int) * PHY_MAX_ADDR, GFP_KERNEL); #endif bus->irq = kzalloc(sizeof(int) * PHY_MAX_ADDR, GFP_KERNEL); if (!bus->irq) { ret = -ENOMEM; goto err_out_free_mdiobus; } for (i = 0; i < PHY_MAX_ADDR; i++) bus->irq[i] = PHY_POLL; data = bus->priv; #if 0 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); data->membase = devm_ioremap_resource(&pdev->dev, res); if (IS_ERR(data->membase)) { ret = PTR_ERR(data->membase); goto err_out_free_mdiobus; } #endif if ((ret = vmm_devtree_request_regmap(np, ®_addr, 0, "Sun4i MDIO"))) { vmm_printf("%s: Failed to ioremap\n", __func__); return -ENOMEM; } data->membase = (void *) reg_addr; #if 0 data->regulator = devm_regulator_get(&pdev->dev, "phy"); #endif data->regulator = devm_regulator_get(pdev, "phy"); if (IS_ERR(data->regulator)) { if (PTR_ERR(data->regulator) == -EPROBE_DEFER) return -EPROBE_DEFER; dev_info(pdev, "no regulator found\n"); } else { ret = regulator_enable(data->regulator); if (ret) goto err_out_free_mdiobus; } ret = of_mdiobus_register(bus, np); if (ret < 0) goto err_out_disable_regulator; platform_set_drvdata(pdev, bus); return 0; err_out_disable_regulator: regulator_disable(data->regulator); err_out_free_mdiobus: mdiobus_free(bus); return ret; }
static int fs_enet_mdio_probe(struct platform_device *ofdev) { const struct of_device_id *match; struct resource res; struct mii_bus *new_bus; struct fec_info *fec; int (*get_bus_freq)(struct device_node *); int ret = -ENOMEM, clock, speed; match = of_match_device(fs_enet_mdio_fec_match, &ofdev->dev); if (!match) return -EINVAL; get_bus_freq = match->data; new_bus = mdiobus_alloc(); 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; ret = of_address_to_resource(ofdev->dev.of_node, 0, &res); if (ret) goto out_res; snprintf(new_bus->id, MII_BUS_ID_SIZE, "%x", res.start); fec->fecp = ioremap(res.start, resource_size(&res)); if (!fec->fecp) { ret = -ENOMEM; goto out_fec; } if (get_bus_freq) { clock = get_bus_freq(ofdev->dev.of_node); if (!clock) { /* Use maximum divider if clock is unknown */ dev_warn(&ofdev->dev, "could not determine IPS clock\n"); clock = 0x3F * 5000000; } } else clock = ppc_proc_freq; /* * Scale for a MII clock <= 2.5 MHz * Note that only 6 bits (25:30) are available for MII speed. */ speed = (clock + 4999999) / 5000000; if (speed > 0x3F) { speed = 0x3F; dev_err(&ofdev->dev, "MII clock (%d Hz) exceeds max (2.5 MHz)\n", clock / speed); } fec->mii_speed = speed << 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); clrsetbits_be32(&fec->fecp->fec_mii_speed, 0x7E, fec->mii_speed); new_bus->phy_mask = ~0; new_bus->parent = &ofdev->dev; platform_set_drvdata(ofdev, new_bus); ret = of_mdiobus_register(new_bus, ofdev->dev.of_node); if (ret) goto out_unmap_regs; return 0; out_unmap_regs: iounmap(fec->fecp); out_res: out_fec: kfree(fec); out_mii: mdiobus_free(new_bus); out: return ret; }
/* Configure the MDIO bus and connect the external PHY */ int emac_phy_config(struct platform_device *pdev, struct emac_adapter *adpt) { struct device_node *np = pdev->dev.of_node; struct mii_bus *mii_bus; int ret; /* Create the mii_bus object for talking to the MDIO bus */ adpt->mii_bus = mii_bus = devm_mdiobus_alloc(&pdev->dev); if (!mii_bus) return -ENOMEM; mii_bus->name = "emac-mdio"; snprintf(mii_bus->id, MII_BUS_ID_SIZE, "%s", pdev->name); mii_bus->read = emac_mdio_read; mii_bus->write = emac_mdio_write; mii_bus->parent = &pdev->dev; mii_bus->priv = adpt; if (has_acpi_companion(&pdev->dev)) { u32 phy_addr; ret = mdiobus_register(mii_bus); if (ret) { dev_err(&pdev->dev, "could not register mdio bus\n"); return ret; } ret = device_property_read_u32(&pdev->dev, "phy-channel", &phy_addr); if (ret) /* If we can't read a valid phy address, then assume * that there is only one phy on this mdio bus. */ adpt->phydev = phy_find_first(mii_bus); else adpt->phydev = mdiobus_get_phy(mii_bus, phy_addr); /* of_phy_find_device() claims a reference to the phydev, * so we do that here manually as well. When the driver * later unloads, it can unilaterally drop the reference * without worrying about ACPI vs DT. */ if (adpt->phydev) get_device(&adpt->phydev->mdio.dev); } else { struct device_node *phy_np; ret = of_mdiobus_register(mii_bus, np); if (ret) { dev_err(&pdev->dev, "could not register mdio bus\n"); return ret; } phy_np = of_parse_phandle(np, "phy-handle", 0); adpt->phydev = of_phy_find_device(phy_np); of_node_put(phy_np); } if (!adpt->phydev) { dev_err(&pdev->dev, "could not find external phy\n"); mdiobus_unregister(mii_bus); return -ENODEV; } return 0; }
int mdio_mux_init(struct device *dev, struct device_node *mux_node, int (*switch_fn)(int cur, int desired, void *data), void **mux_handle, void *data, struct mii_bus *mux_bus) { struct device_node *parent_bus_node; struct device_node *child_bus_node; int r, ret_val; struct mii_bus *parent_bus; struct mdio_mux_parent_bus *pb; struct mdio_mux_child_bus *cb; if (!mux_node) return -ENODEV; if (!mux_bus) { parent_bus_node = of_parse_phandle(mux_node, "mdio-parent-bus", 0); if (!parent_bus_node) return -ENODEV; parent_bus = of_mdio_find_bus(parent_bus_node); if (!parent_bus) { ret_val = -EPROBE_DEFER; goto err_parent_bus; } } else { parent_bus_node = NULL; parent_bus = mux_bus; get_device(&parent_bus->dev); } pb = devm_kzalloc(dev, sizeof(*pb), GFP_KERNEL); if (!pb) { ret_val = -ENOMEM; goto err_pb_kz; } pb->switch_data = data; pb->switch_fn = switch_fn; pb->current_child = -1; pb->parent_id = parent_count++; pb->mii_bus = parent_bus; ret_val = -ENODEV; for_each_available_child_of_node(mux_node, child_bus_node) { int v; r = of_property_read_u32(child_bus_node, "reg", &v); if (r) { dev_err(dev, "Error: Failed to find reg for child %pOF\n", child_bus_node); continue; } cb = devm_kzalloc(dev, sizeof(*cb), GFP_KERNEL); if (!cb) { ret_val = -ENOMEM; continue; } cb->bus_number = v; cb->parent = pb; cb->mii_bus = mdiobus_alloc(); if (!cb->mii_bus) { ret_val = -ENOMEM; devm_kfree(dev, cb); continue; } cb->mii_bus->priv = cb; cb->mii_bus->name = "mdio_mux"; snprintf(cb->mii_bus->id, MII_BUS_ID_SIZE, "%x.%x", pb->parent_id, v); cb->mii_bus->parent = dev; cb->mii_bus->read = mdio_mux_read; cb->mii_bus->write = mdio_mux_write; r = of_mdiobus_register(cb->mii_bus, child_bus_node); if (r) { dev_err(dev, "Error: Failed to register MDIO bus for child %pOF\n", child_bus_node); mdiobus_free(cb->mii_bus); devm_kfree(dev, cb); } else { cb->next = pb->children; pb->children = cb; } }
static int orion_mdio_probe(struct platform_device *pdev) { struct resource *r; struct mii_bus *bus; struct orion_mdio_dev *dev; int ret; r = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!r) { dev_err(&pdev->dev, "No SMI register address given\n"); return -ENODEV; } bus = devm_mdiobus_alloc_size(&pdev->dev, sizeof(struct orion_mdio_dev)); if (!bus) return -ENOMEM; bus->name = "orion_mdio_bus"; bus->read = orion_mdio_read; bus->write = orion_mdio_write; snprintf(bus->id, MII_BUS_ID_SIZE, "%s-mii", dev_name(&pdev->dev)); bus->parent = &pdev->dev; dev = bus->priv; dev->regs = devm_ioremap(&pdev->dev, r->start, resource_size(r)); if (!dev->regs) { dev_err(&pdev->dev, "Unable to remap SMI register\n"); ret = -ENODEV; goto out_mdio; } init_waitqueue_head(&dev->smi_busy_wait); dev->clk = devm_clk_get(&pdev->dev, NULL); if (!IS_ERR(dev->clk)) clk_prepare_enable(dev->clk); dev->err_interrupt = platform_get_irq(pdev, 0); if (dev->err_interrupt > 0) { ret = devm_request_irq(&pdev->dev, dev->err_interrupt, orion_mdio_err_irq, IRQF_SHARED, pdev->name, dev); if (ret) goto out_mdio; writel(MVMDIO_ERR_INT_SMI_DONE, dev->regs + MVMDIO_ERR_INT_MASK); } else if (dev->err_interrupt == -EPROBE_DEFER) { return -EPROBE_DEFER; } mutex_init(&dev->lock); if (pdev->dev.of_node) ret = of_mdiobus_register(bus, pdev->dev.of_node); else ret = mdiobus_register(bus); if (ret < 0) { dev_err(&pdev->dev, "Cannot register MDIO bus (%d)\n", ret); goto out_mdio; } platform_set_drvdata(pdev, bus); return 0; out_mdio: if (!IS_ERR(dev->clk)) clk_disable_unprepare(dev->clk); return ret; }
static int xgene_mdio_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; struct mii_bus *mdio_bus; const struct of_device_id *of_id; struct resource *res; struct xgene_mdio_pdata *pdata; void __iomem *csr_base; int mdio_id = 0, ret = 0; of_id = of_match_device(xgene_mdio_of_match, &pdev->dev); if (of_id) { mdio_id = (enum xgene_mdio_id)of_id->data; } else { #ifdef CONFIG_ACPI const struct acpi_device_id *acpi_id; acpi_id = acpi_match_device(xgene_mdio_acpi_match, &pdev->dev); if (acpi_id) mdio_id = (enum xgene_mdio_id)acpi_id->driver_data; #endif } if (!mdio_id) return -ENODEV; pdata = devm_kzalloc(dev, sizeof(struct xgene_mdio_pdata), GFP_KERNEL); if (!pdata) return -ENOMEM; pdata->mdio_id = mdio_id; pdata->dev = dev; res = platform_get_resource(pdev, IORESOURCE_MEM, 0); csr_base = devm_ioremap_resource(dev, res); if (IS_ERR(csr_base)) return PTR_ERR(csr_base); pdata->mac_csr_addr = csr_base; pdata->mdio_csr_addr = csr_base + BLOCK_XG_MDIO_CSR_OFFSET; pdata->diag_csr_addr = csr_base + BLOCK_DIAG_CSR_OFFSET; if (mdio_id == XGENE_MDIO_RGMII) spin_lock_init(&pdata->mac_lock); if (dev->of_node) { pdata->clk = devm_clk_get(dev, NULL); if (IS_ERR(pdata->clk)) { dev_err(dev, "Unable to retrieve clk\n"); return PTR_ERR(pdata->clk); } } ret = xgene_mdio_reset(pdata); if (ret) return ret; mdio_bus = mdiobus_alloc(); if (!mdio_bus) { ret = -ENOMEM; goto out_clk; } mdio_bus->name = "APM X-Gene MDIO bus"; if (mdio_id == XGENE_MDIO_RGMII) { mdio_bus->read = xgene_mdio_rgmii_read; mdio_bus->write = xgene_mdio_rgmii_write; mdio_bus->priv = (void __force *)pdata; snprintf(mdio_bus->id, MII_BUS_ID_SIZE, "%s", "xgene-mii-rgmii"); } else { mdio_bus->read = xgene_xfi_mdio_read; mdio_bus->write = xgene_xfi_mdio_write; mdio_bus->priv = (void __force *)pdata->mdio_csr_addr; snprintf(mdio_bus->id, MII_BUS_ID_SIZE, "%s", "xgene-mii-xfi"); } mdio_bus->parent = dev; platform_set_drvdata(pdev, pdata); if (dev->of_node) { ret = of_mdiobus_register(mdio_bus, dev->of_node); } else { #ifdef CONFIG_ACPI /* Mask out all PHYs from auto probing. */ mdio_bus->phy_mask = ~0; ret = mdiobus_register(mdio_bus); if (ret) goto out_mdiobus; acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_HANDLE(dev), 1, acpi_register_phy, NULL, mdio_bus, NULL); #endif } if (ret) goto out_mdiobus; pdata->mdio_bus = mdio_bus; xgene_mdio_status = true; return 0; out_mdiobus: mdiobus_free(mdio_bus); out_clk: if (dev->of_node) clk_disable_unprepare(pdata->clk); return ret; }
/** * axienet_mdio_setup - MDIO setup function * @lp: Pointer to axienet local data structure. * @np: Pointer to device node * * returns: 0 on success, -ETIMEDOUT on a timeout, -ENOMEM when * mdiobus_alloc (to allocate memory for mii bus structure) fails. * * Sets up the MDIO interface by initializing the MDIO clock and enabling the * MDIO interface in hardware. Register the MDIO interface. **/ int axienet_mdio_setup(struct axienet_local *lp, struct device_node *np) { int ret; u32 clk_div; struct mii_bus *bus; struct resource res; struct device_node *np1; struct device_node *npp = 0; /* the ethernet controller device node */ /* clk_div can be calculated by deriving it from the equation: * fMDIO = fHOST / ((1 + clk_div) * 2) * * Where fMDIO <= 2500000, so we get: * fHOST / ((1 + clk_div) * 2) <= 2500000 * * Then we get: * 1 / ((1 + clk_div) * 2) <= (2500000 / fHOST) * * Then we get: * 1 / (1 + clk_div) <= ((2500000 * 2) / fHOST) * * Then we get: * 1 / (1 + clk_div) <= (5000000 / fHOST) * * So: * (1 + clk_div) >= (fHOST / 5000000) * * And finally: * clk_div >= (fHOST / 5000000) - 1 * * fHOST can be read from the flattened device tree as property * "clock-frequency" from the CPU */ np1 = of_get_parent(lp->phy_node); if (np1) npp = of_get_parent(np1); if (!npp) { dev_warn(lp->dev, "Could not find ethernet controller device node."); dev_warn(lp->dev, "Setting MDIO clock divisor to default %d\n", DEFAULT_CLOCK_DIVISOR); clk_div = DEFAULT_CLOCK_DIVISOR; } else { u32 *property_p; property_p = (uint32_t *)of_get_property(npp, "clock-frequency", NULL); if (!property_p) { dev_warn(lp->dev, "Could not find clock ethernet " \ "controller property."); dev_warn(lp->dev, "Setting MDIO clock divisor to default %d\n", DEFAULT_CLOCK_DIVISOR); clk_div = DEFAULT_CLOCK_DIVISOR; } else { u32 host_clock = be32_to_cpup(property_p); clk_div = (host_clock / (MAX_MDIO_FREQ * 2)) - 1; /* If there is any remainder from the division of * fHOST / (MAX_MDIO_FREQ * 2), then we need to add 1 * to the clock divisor or we will surely be * above 2.5 MHz */ if (host_clock % (MAX_MDIO_FREQ * 2)) clk_div++; dev_dbg(lp->dev, "Setting MDIO clock divisor to %u " \ "based on %u Hz host clock.\n", clk_div, host_clock); } } axienet_iow(lp, XAE_MDIO_MC_OFFSET, (((u32)clk_div) | XAE_MDIO_MC_MDIOEN_MASK)); ret = axienet_mdio_wait_until_ready(lp); if (ret < 0) return ret; bus = mdiobus_alloc(); if (!bus) return -ENOMEM; of_address_to_resource(npp, 0, &res); snprintf(bus->id, MII_BUS_ID_SIZE, "%.8llx", (unsigned long long) res.start); bus->priv = lp; bus->name = "Xilinx Axi Ethernet MDIO"; bus->read = axienet_mdio_read; bus->write = axienet_mdio_write; bus->parent = lp->dev; bus->irq = lp->mdio_irqs; /* preallocated IRQ table */ lp->mii_bus = bus; ret = of_mdiobus_register(bus, np1); if (ret) { mdiobus_free(bus); return ret; } return 0; }
/** * stmmac_mdio_register * @ndev: net device structure * Description: it registers the MII bus */ int stmmac_mdio_register(struct net_device *ndev) { int err = 0; struct mii_bus *new_bus; struct stmmac_priv *priv = netdev_priv(ndev); struct stmmac_mdio_bus_data *mdio_bus_data = priv->plat->mdio_bus_data; struct device_node *mdio_node = priv->plat->mdio_node; int addr, found; if (!mdio_bus_data) return 0; new_bus = mdiobus_alloc(); if (new_bus == NULL) return -ENOMEM; if (mdio_bus_data->irqs) memcpy(new_bus->irq, mdio_bus_data, sizeof(new_bus->irq)); #ifdef CONFIG_OF if (priv->device->of_node) mdio_bus_data->reset_gpio = -1; #endif new_bus->name = "stmmac"; new_bus->read = &stmmac_mdio_read; new_bus->write = &stmmac_mdio_write; new_bus->reset = &stmmac_mdio_reset; snprintf(new_bus->id, MII_BUS_ID_SIZE, "%s-%x", new_bus->name, priv->plat->bus_id); new_bus->priv = ndev; new_bus->phy_mask = mdio_bus_data->phy_mask; new_bus->parent = priv->device; if (mdio_node) err = of_mdiobus_register(new_bus, mdio_node); else err = mdiobus_register(new_bus); if (err != 0) { pr_err("%s: Cannot register as MDIO bus\n", new_bus->name); goto bus_register_fail; } if (priv->plat->phy_node || mdio_node) goto bus_register_done; found = 0; for (addr = 0; addr < PHY_MAX_ADDR; addr++) { struct phy_device *phydev = mdiobus_get_phy(new_bus, addr); if (phydev) { int act = 0; char irq_num[4]; char *irq_str; /* * If an IRQ was provided to be assigned after * the bus probe, do it here. */ if ((mdio_bus_data->irqs == NULL) && (mdio_bus_data->probed_phy_irq > 0)) { new_bus->irq[addr] = mdio_bus_data->probed_phy_irq; phydev->irq = mdio_bus_data->probed_phy_irq; } /* * If we're going to bind the MAC to this PHY bus, * and no PHY number was provided to the MAC, * use the one probed here. */ if (priv->plat->phy_addr == -1) priv->plat->phy_addr = addr; act = (priv->plat->phy_addr == addr); switch (phydev->irq) { case PHY_POLL: irq_str = "POLL"; break; case PHY_IGNORE_INTERRUPT: irq_str = "IGNORE"; break; default: sprintf(irq_num, "%d", phydev->irq); irq_str = irq_num; break; } pr_info("%s: PHY ID %08x at %d IRQ %s (%s)%s\n", ndev->name, phydev->phy_id, addr, irq_str, phydev_name(phydev), act ? " active" : ""); found = 1; } } if (!found && !mdio_node) { pr_warn("%s: No PHY found\n", ndev->name); mdiobus_unregister(new_bus); mdiobus_free(new_bus); return -ENODEV; } bus_register_done: priv->mii = new_bus; return 0; bus_register_fail: mdiobus_free(new_bus); return err; }