static int __devinit vmac_mii_probe(struct net_device *dev)\r
{\r
struct vmac_priv *ap = netdev_priv(dev);\r
- struct phy_device *phydev = NULL;\r
- struct clk *sys_clk;\r
- unsigned long clock_rate;\r
+ struct phy_device *phydev = NULL; \r
+ //struct clk *sys_clk;\r
+ //unsigned long clock_rate;\r
int phy_addr, err;\r
\r
/* find the first phy */\r
ap->phy_dev = phydev;\r
\r
return 0;\r
-\r
-err_disconnect:\r
- phy_disconnect(phydev);\r
+//err_disconnect:\r
+// phy_disconnect(phydev);\r
err_out:\r
return err;\r
}\r
kfree(ap->mii_bus->irq);\r
err_out:\r
mdiobus_free(ap->mii_bus);\r
+ ap->mii_bus = NULL;\r
return err;\r
}\r
\r
\r
if (ap->phy_dev)\r
phy_disconnect(ap->phy_dev);\r
-\r
- mdiobus_unregister(ap->mii_bus);\r
- kfree(ap->mii_bus->irq);\r
- mdiobus_free(ap->mii_bus);\r
+ if (ap->mii_bus) {\r
+ mdiobus_unregister(ap->mii_bus);\r
+ kfree(ap->mii_bus->irq);\r
+ mdiobus_free(ap->mii_bus);\r
+ ap->mii_bus = NULL;\r
+ }\r
}\r
\r
static int vmacether_get_settings(struct net_device *dev,\r
if (ap == NULL)\r
return -ENODEV;\r
\r
+ wake_lock_timeout(&ap->resume_lock, 5*HZ);\r
+\r
ap->shutdown = 0;\r
\r
//set rmii ref clock 50MHz\r
dev_info(&ap->pdev->dev, "PHY driver [%s] (mii_bus:phy_addr=%s, irq=%d)\n",\r
phydev->drv->name, dev_name(&phydev->dev), phydev->irq);\r
\r
+ ap->suspending = 0;\r
+ ap->open_flag = 1;\r
+\r
return 0;\r
\r
err_free_irq:\r
struct rk29_vmac_platform_data *pdata = ap->pdev->dev.platform_data;\r
\r
printk("enter func %s...\n", __func__);\r
+ \r
+ if (ap->suspending == 1) \r
+ return 0;\r
+\r
+ ap->open_flag = 0;\r
\r
netif_stop_queue(dev);\r
napi_disable(&ap->napi);\r
return 0;\r
}\r
\r
-static void rk29_init_vmac(struct net_device *dev)\r
+int vmac_shutdown(struct net_device *dev)\r
{\r
struct vmac_priv *ap = netdev_priv(dev);\r
unsigned int temp;\r
- struct clk *mac_clk = NULL;\r
- struct rk29_vmac_platform_data *pdata = ap->pdev->dev.platform_data;\r
-\r
+ \r
printk("enter func %s...\n", __func__);\r
- \r
- //set rmii ref clock 50MHz\r
- mac_clk = clk_get(NULL, "mac_ref_div"); \r
- clk_set_rate(mac_clk, 50000000);\r
- clk_enable(mac_clk);\r
- clk_enable(clk_get(NULL,"mii_rx"));\r
- clk_enable(clk_get(NULL,"mii_tx"));\r
- clk_enable(clk_get(NULL,"hclk_mac"));\r
- clk_enable(clk_get(NULL,"mac_ref"));\r
-\r
- //phy power on\r
- if (pdata && pdata->rmii_power_control)\r
- pdata->rmii_power_control(1);\r
\r
- //msleep(1000);\r
-\r
- /* IRQ mask */\r
- temp = RXINT_MASK | ERR_MASK | TXCH_MASK | MDIO_MASK;\r
- vmac_writel(ap, temp, ENABLE);\r
+ netif_stop_queue(dev);\r
+ napi_disable(&ap->napi);\r
\r
- /* Set control */\r
- temp = (RX_BDT_LEN << 24) | (TX_BDT_LEN << 16) | TXRN_MASK | RXRN_MASK;\r
+ /* stop running transfers */\r
+ temp = vmac_readl(ap, CONTROL);\r
+ temp &= ~(TXRN_MASK | RXRN_MASK);\r
vmac_writel(ap, temp, CONTROL);\r
\r
- /* enable, after all other bits are set */\r
- vmac_writel(ap, temp | EN_MASK, CONTROL);\r
+ del_timer_sync(&ap->rx_timeout);\r
\r
-}\r
+ /* disable phy */\r
+ phy_stop(ap->phy_dev);\r
+ vmac_mii_exit(dev);\r
+ netif_carrier_off(dev);\r
\r
-static void rk29_vmac_shutdown(struct net_device *dev)\r
-{\r
- struct vmac_priv *ap = netdev_priv(dev);\r
- struct rk29_vmac_platform_data *pdata = ap->pdev->dev.platform_data;\r
- \r
- printk("enter func %s...\n", __func__);\r
- \r
/* disable interrupts */\r
vmac_writel(ap, 0, ENABLE);\r
- \r
+ free_irq(dev->irq, dev);\r
+\r
/* turn off vmac */\r
vmac_writel(ap, 0, CONTROL);\r
- \r
- //phy power off\r
- if (pdata && pdata->rmii_power_control)\r
- pdata->rmii_power_control(0);\r
- \r
- //clock close\r
- clk_disable(clk_get(NULL, "mac_ref_div")); \r
- clk_disable(clk_get(NULL,"mii_rx"));\r
- clk_disable(clk_get(NULL,"mii_tx"));\r
- clk_disable(clk_get(NULL,"hclk_mac"));\r
- clk_disable(clk_get(NULL,"mac_ref"));\r
-}\r
+ /* vmac_reset_hw(vmac) */\r
+\r
+ ap->shutdown = 1;\r
+ wmb();\r
+\r
+ free_buffers(dev);\r
\r
+ return 0;\r
+}\r
\r
void vmac_update_stats(struct vmac_priv *ap)\r
{\r
struct resource *res;\r
unsigned int mem_base, mem_size, irq;\r
int err;\r
- struct clk *sys_clk;\r
struct rk29_vmac_platform_data *pdata = pdev->dev.platform_data;\r
\r
dev = alloc_etherdev(sizeof(*ap));\r
dev->irq, dev->dev_addr);\r
platform_set_drvdata(pdev, dev);\r
\r
+ ap->suspending = 0;\r
+ ap->open_flag = 0;\r
wake_lock_init(&idlelock, WAKE_LOCK_IDLE, "vmac");\r
+ wake_lock_init(&ap->resume_lock, WAKE_LOCK_SUSPEND, "vmac_resume");\r
\r
//config rk29 vmac as rmii, 100MHz \r
if (pdata && pdata->vmac_register_set)\r
return 0;\r
}\r
\r
+static void rk29_vmac_power_off(struct net_device *dev)\r
+{\r
+ struct vmac_priv *ap = netdev_priv(dev);\r
+ struct rk29_vmac_platform_data *pdata = ap->pdev->dev.platform_data;\r
+\r
+ printk("enter func %s...\n", __func__);\r
+\r
+ //phy power off\r
+ if (pdata && pdata->rmii_power_control)\r
+ pdata->rmii_power_control(0);\r
+\r
+ //clock close\r
+ clk_disable(clk_get(NULL, "mac_ref_div"));\r
+ clk_disable(clk_get(NULL,"mii_rx"));\r
+ clk_disable(clk_get(NULL,"mii_tx"));\r
+ clk_disable(clk_get(NULL,"hclk_mac"));\r
+ clk_disable(clk_get(NULL,"mac_ref"));\r
+\r
+}\r
+\r
static int\r
rk29_vmac_suspend(struct device *dev)\r
{\r
struct platform_device *pdev = to_platform_device(dev);\r
struct net_device *ndev = platform_get_drvdata(pdev);\r
-\r
+ struct vmac_priv *ap = netdev_priv(ndev);\r
+ \r
if (ndev) {\r
- if (netif_running(ndev)) {\r
- if (ndev->irq)\r
- disable_irq(ndev->irq);\r
+ if (ap->open_flag == 1) {\r
netif_stop_queue(ndev);\r
netif_device_detach(ndev);\r
- rk29_vmac_shutdown(ndev);\r
+ if (ap->suspending == 0) {\r
+ vmac_shutdown(ndev);\r
+ rk29_vmac_power_off(ndev);\r
+ ap->suspending = 1;\r
+ }\r
}\r
}\r
return 0;\r
{\r
struct platform_device *pdev = to_platform_device(dev);\r
struct net_device *ndev = platform_get_drvdata(pdev);\r
-\r
+ struct vmac_priv *ap = netdev_priv(ndev);\r
+ \r
if (ndev) {\r
- if (netif_running(ndev)) {\r
- rk29_init_vmac(ndev);\r
+ if (ap->open_flag == 1) {\r
netif_device_attach(ndev);\r
netif_start_queue(ndev);\r
- if (ndev->irq)\r
- enable_irq(ndev->irq);\r
}\r
}\r
return 0;\r