示例#1
0
文件: mii-bitbang.c 项目: 274914765/C
static int __devinit fs_enet_mdio_probe(struct device *dev)
{
    struct platform_device *pdev = to_platform_device(dev);
    struct fs_mii_bb_platform_info *pdata;
    struct mii_bus *new_bus;
    struct bb_info *bitbang;
    int err = 0;

    if (NULL == dev)
        return -EINVAL;

    bitbang = kzalloc(sizeof(struct bb_info), GFP_KERNEL);

    if (NULL == bitbang)
        return -ENOMEM;

    bitbang->ctrl.ops = &bb_ops;

    new_bus = alloc_mdio_bitbang(&bitbang->ctrl);

    if (NULL == new_bus)
        return -ENOMEM;

    new_bus->name = "BB MII Bus",
    snprintf(new_bus->id, MII_BUS_ID_SIZE, "%x", pdev->id);

    new_bus->phy_mask = ~0x9;
    pdata = (struct fs_mii_bb_platform_info *)pdev->dev.platform_data;

    if (NULL == pdata) {
        printk(KERN_ERR "gfar mdio %d: Missing platform data!\n", pdev->id);
        return -ENODEV;
    }

    /*set up workspace*/
    fs_mii_bitbang_init(bitbang, pdata);

    new_bus->priv = bitbang;

    new_bus->irq = pdata->irq;

    new_bus->dev = dev;
    dev_set_drvdata(dev, new_bus);

    err = mdiobus_register(new_bus);

    if (0 != err) {
        printk (KERN_ERR "%s: Cannot register as MDIO bus\n",
                new_bus->name);
        goto bus_register_fail;
    }

    return 0;

bus_register_fail:
    free_mdio_bitbang(new_bus);
    kfree(bitbang);

    return err;
}
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 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;
}