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