for_each_available_child_of_node(np, np2) { iprop = of_get_property(np2, "reg", &len); if (!iprop || len != sizeof(uint32_t)) { dev_err(&pdev->dev, "mdio-mux child node %s is " "missing a 'reg' property\n", np2->full_name); return -ENODEV; } if (be32_to_cpup(iprop) & ~s->mask) { dev_err(&pdev->dev, "mdio-mux child node %s has " "a 'reg' value with unmasked bits\n", np2->full_name); return -ENODEV; } } ret = mdio_mux_init(&pdev->dev, mdio_mux_mmioreg_switch_fn, &s->mux_handle, s); if (ret) { dev_err(&pdev->dev, "failed to register mdio-mux bus %s\n", np->full_name); return ret; } pdev->dev.platform_data = s; return 0; } static int mdio_mux_mmioreg_remove(struct platform_device *pdev) { struct mdio_mux_mmioreg_state *s = dev_get_platdata(&pdev->dev);
static int mdio_mux_iproc_probe(struct platform_device *pdev) { struct iproc_mdiomux_desc *md; struct mii_bus *bus; struct resource *res; int rc; md = devm_kzalloc(&pdev->dev, sizeof(*md), GFP_KERNEL); if (!md) return -ENOMEM; md->dev = &pdev->dev; res = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (res->start & 0xfff) { /* For backward compatibility in case the * base address is specified with an offset. */ dev_info(&pdev->dev, "fix base address in dt-blob\n"); res->start &= ~0xfff; res->end = res->start + MDIO_REG_ADDR_SPACE_SIZE - 1; } md->base = devm_ioremap_resource(&pdev->dev, res); if (IS_ERR(md->base)) { dev_err(&pdev->dev, "failed to ioremap register\n"); return PTR_ERR(md->base); } md->mii_bus = devm_mdiobus_alloc(&pdev->dev); if (!md->mii_bus) { dev_err(&pdev->dev, "mdiomux bus alloc failed\n"); return -ENOMEM; } md->core_clk = devm_clk_get(&pdev->dev, NULL); if (md->core_clk == ERR_PTR(-ENOENT) || md->core_clk == ERR_PTR(-EINVAL)) md->core_clk = NULL; else if (IS_ERR(md->core_clk)) return PTR_ERR(md->core_clk); rc = clk_prepare_enable(md->core_clk); if (rc) { dev_err(&pdev->dev, "failed to enable core clk\n"); return rc; } bus = md->mii_bus; bus->priv = md; bus->name = "iProc MDIO mux bus"; snprintf(bus->id, MII_BUS_ID_SIZE, "%s-%d", pdev->name, pdev->id); bus->parent = &pdev->dev; bus->read = iproc_mdiomux_read; bus->write = iproc_mdiomux_write; bus->phy_mask = ~0; bus->dev.of_node = pdev->dev.of_node; rc = mdiobus_register(bus); if (rc) { dev_err(&pdev->dev, "mdiomux registration failed\n"); goto out_clk; } platform_set_drvdata(pdev, md); rc = mdio_mux_init(md->dev, md->dev->of_node, mdio_mux_iproc_switch_fn, &md->mux_handle, md, md->mii_bus); if (rc) { dev_info(md->dev, "mdiomux initialization failed\n"); goto out_register; } mdio_mux_iproc_config(md); dev_info(md->dev, "iProc mdiomux registered\n"); return 0; out_register: mdiobus_unregister(bus); out_clk: clk_disable_unprepare(md->core_clk); return rc; }