コード例 #1
0
ファイル: sh_eth.c プロジェクト: artm1248/linux
static int sh_eth_drv_probe(struct platform_device *pdev)
{
    int ret, i, devno = 0;
    struct resource *res;
    struct net_device *ndev = NULL;
    struct sh_eth_private *mdp;
    struct sh_eth_plat_data *pd;

    /* get base addr */
    res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
    if (unlikely(res == NULL)) {
        dev_err(&pdev->dev, "invalid resource\n");
        ret = -EINVAL;
        goto out;
    }

    ndev = alloc_etherdev(sizeof(struct sh_eth_private));
    if (!ndev) {
        printk(KERN_ERR "%s: could not allocate device.\n", CARDNAME);
        ret = -ENOMEM;
        goto out;
    }

    /* The sh Ether-specific entries in the device structure. */
    ndev->base_addr = res->start;
    devno = pdev->id;
    if (devno < 0)
        devno = 0;

    ndev->dma = -1;
    ret = platform_get_irq(pdev, 0);
    if (ret < 0) {
        ret = -ENODEV;
        goto out_release;
    }
    ndev->irq = ret;

    SET_NETDEV_DEV(ndev, &pdev->dev);

    /* Fill in the fields of the device structure with ethernet values. */
    ether_setup(ndev);

    mdp = netdev_priv(ndev);
    spin_lock_init(&mdp->lock);

    pd = (struct sh_eth_plat_data *)(pdev->dev.platform_data);
    /* get PHY ID */
    mdp->phy_id = pd->phy;
    /* EDMAC endian */
    mdp->edmac_endian = pd->edmac_endian;

    /* set function */
    ndev->netdev_ops = &sh_eth_netdev_ops;
    ndev->watchdog_timeo = TX_TIMEOUT;

    mdp->post_rx = POST_RX >> (devno << 1);
    mdp->post_fw = POST_FW >> (devno << 1);

    /* read and set MAC address */
    read_mac_address(ndev);

    /* First device only init */
    if (!devno) {
#if defined(ARSTR)
        /* reset device */
        ctrl_outl(ARSTR_ARSTR, ARSTR);
        mdelay(1);
#endif

#if defined(SH_TSU_ADDR)
        /* TSU init (Init only)*/
        sh_eth_tsu_init(SH_TSU_ADDR);
#endif
    }

    /* network device register */
    ret = register_netdev(ndev);
    if (ret)
        goto out_release;

    /* mdio bus init */
    ret = sh_mdio_init(ndev, pdev->id);
    if (ret)
        goto out_unregister;

    /* pritnt device infomation */
    printk(KERN_INFO "%s: %s at 0x%x, ",
           ndev->name, CARDNAME, (u32) ndev->base_addr);

    for (i = 0; i < 5; i++)
        printk("%02X:", ndev->dev_addr[i]);
    printk("%02X, IRQ %d.\n", ndev->dev_addr[i], ndev->irq);

    platform_set_drvdata(pdev, ndev);

    return ret;

out_unregister:
    unregister_netdev(ndev);

out_release:
    /* net_dev free */
    if (ndev)
        free_netdev(ndev);

out:
    return ret;
}
コード例 #2
0
ファイル: sh_eth.c プロジェクト: andi34/Dhollmen_Kernel
static int sh_eth_drv_probe(struct platform_device *pdev)
{
	int ret, devno = 0;
	struct resource *res;
	struct net_device *ndev = NULL;
	struct sh_eth_private *mdp;
	struct sh_eth_plat_data *pd;

	/* get base addr */
	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	if (unlikely(res == NULL)) {
		dev_err(&pdev->dev, "invalid resource\n");
		ret = -EINVAL;
		goto out;
	}

	ndev = alloc_etherdev(sizeof(struct sh_eth_private));
	if (!ndev) {
		dev_err(&pdev->dev, "Could not allocate device.\n");
		ret = -ENOMEM;
		goto out;
	}

	/* The sh Ether-specific entries in the device structure. */
	ndev->base_addr = res->start;
	devno = pdev->id;
	if (devno < 0)
		devno = 0;

	ndev->dma = -1;
	ret = platform_get_irq(pdev, 0);
	if (ret < 0) {
		ret = -ENODEV;
		goto out_release;
	}
	ndev->irq = ret;

	SET_NETDEV_DEV(ndev, &pdev->dev);

	/* Fill in the fields of the device structure with ethernet values. */
	ether_setup(ndev);

	mdp = netdev_priv(ndev);
	spin_lock_init(&mdp->lock);
	mdp->pdev = pdev;
	pm_runtime_enable(&pdev->dev);
	pm_runtime_resume(&pdev->dev);

	pd = (struct sh_eth_plat_data *)(pdev->dev.platform_data);
	/* get PHY ID */
	mdp->phy_id = pd->phy;
	mdp->phy_interface = pd->phy_interface;
	/* EDMAC endian */
	mdp->edmac_endian = pd->edmac_endian;
	mdp->no_ether_link = pd->no_ether_link;
	mdp->ether_link_active_low = pd->ether_link_active_low;
	mdp->reg_offset = sh_eth_get_register_offset(pd->register_type);

	/* set cpu data */
#if defined(SH_ETH_HAS_BOTH_MODULES)
	mdp->cd = sh_eth_get_cpu_data(mdp);
#else
	mdp->cd = &sh_eth_my_cpu_data;
#endif
	sh_eth_set_default_cpu_data(mdp->cd);

	/* set function */
	ndev->netdev_ops = &sh_eth_netdev_ops;
	SET_ETHTOOL_OPS(ndev, &sh_eth_ethtool_ops);
	ndev->watchdog_timeo = TX_TIMEOUT;

	/* debug message level */
	mdp->msg_enable = SH_ETH_DEF_MSG_ENABLE;
	mdp->post_rx = POST_RX >> (devno << 1);
	mdp->post_fw = POST_FW >> (devno << 1);

	/* read and set MAC address */
	read_mac_address(ndev, pd->mac_addr);

	/* First device only init */
	if (!devno) {
		if (mdp->cd->tsu) {
			struct resource *rtsu;
			rtsu = platform_get_resource(pdev, IORESOURCE_MEM, 1);
			if (!rtsu) {
				dev_err(&pdev->dev, "Not found TSU resource\n");
				goto out_release;
			}
			mdp->tsu_addr = ioremap(rtsu->start,
						resource_size(rtsu));
		}
		if (mdp->cd->chip_reset)
			mdp->cd->chip_reset(ndev);

		if (mdp->cd->tsu) {
			/* TSU init (Init only)*/
			sh_eth_tsu_init(mdp);
		}
	}

	/* network device register */
	ret = register_netdev(ndev);
	if (ret)
		goto out_release;

	/* mdio bus init */
	ret = sh_mdio_init(ndev, pdev->id, pd);
	if (ret)
		goto out_unregister;

	/* print device information */
	pr_info("Base address at 0x%x, %pM, IRQ %d.\n",
	       (u32)ndev->base_addr, ndev->dev_addr, ndev->irq);

	platform_set_drvdata(pdev, ndev);

	return ret;

out_unregister:
	unregister_netdev(ndev);

out_release:
	/* net_dev free */
	if (mdp->tsu_addr)
		iounmap(mdp->tsu_addr);
	if (ndev)
		free_netdev(ndev);

out:
	return ret;
}