aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/sh_eth.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/sh_eth.c')
-rw-r--r--drivers/net/sh_eth.c56
1 files changed, 46 insertions, 10 deletions
diff --git a/drivers/net/sh_eth.c b/drivers/net/sh_eth.c
index 528b912a4b0d..c88bc1013047 100644
--- a/drivers/net/sh_eth.c
+++ b/drivers/net/sh_eth.c
@@ -30,6 +30,7 @@
30#include <linux/phy.h> 30#include <linux/phy.h>
31#include <linux/cache.h> 31#include <linux/cache.h>
32#include <linux/io.h> 32#include <linux/io.h>
33#include <linux/pm_runtime.h>
33#include <asm/cacheflush.h> 34#include <asm/cacheflush.h>
34 35
35#include "sh_eth.h" 36#include "sh_eth.h"
@@ -299,16 +300,20 @@ static void update_mac_address(struct net_device *ndev)
299 * When you want use this device, you must set MAC address in bootloader. 300 * When you want use this device, you must set MAC address in bootloader.
300 * 301 *
301 */ 302 */
302static void read_mac_address(struct net_device *ndev) 303static void read_mac_address(struct net_device *ndev, unsigned char *mac)
303{ 304{
304 u32 ioaddr = ndev->base_addr; 305 u32 ioaddr = ndev->base_addr;
305 306
306 ndev->dev_addr[0] = (ctrl_inl(ioaddr + MAHR) >> 24); 307 if (mac[0] || mac[1] || mac[2] || mac[3] || mac[4] || mac[5]) {
307 ndev->dev_addr[1] = (ctrl_inl(ioaddr + MAHR) >> 16) & 0xFF; 308 memcpy(ndev->dev_addr, mac, 6);
308 ndev->dev_addr[2] = (ctrl_inl(ioaddr + MAHR) >> 8) & 0xFF; 309 } else {
309 ndev->dev_addr[3] = (ctrl_inl(ioaddr + MAHR) & 0xFF); 310 ndev->dev_addr[0] = (ctrl_inl(ioaddr + MAHR) >> 24);
310 ndev->dev_addr[4] = (ctrl_inl(ioaddr + MALR) >> 8) & 0xFF; 311 ndev->dev_addr[1] = (ctrl_inl(ioaddr + MAHR) >> 16) & 0xFF;
311 ndev->dev_addr[5] = (ctrl_inl(ioaddr + MALR) & 0xFF); 312 ndev->dev_addr[2] = (ctrl_inl(ioaddr + MAHR) >> 8) & 0xFF;
313 ndev->dev_addr[3] = (ctrl_inl(ioaddr + MAHR) & 0xFF);
314 ndev->dev_addr[4] = (ctrl_inl(ioaddr + MALR) >> 8) & 0xFF;
315 ndev->dev_addr[5] = (ctrl_inl(ioaddr + MALR) & 0xFF);
316 }
312} 317}
313 318
314struct bb_info { 319struct bb_info {
@@ -1009,7 +1014,9 @@ static int sh_eth_open(struct net_device *ndev)
1009 int ret = 0; 1014 int ret = 0;
1010 struct sh_eth_private *mdp = netdev_priv(ndev); 1015 struct sh_eth_private *mdp = netdev_priv(ndev);
1011 1016
1012 ret = request_irq(ndev->irq, &sh_eth_interrupt, 1017 pm_runtime_get_sync(&mdp->pdev->dev);
1018
1019 ret = request_irq(ndev->irq, sh_eth_interrupt,
1013#if defined(CONFIG_CPU_SUBTYPE_SH7763) || defined(CONFIG_CPU_SUBTYPE_SH7764) 1020#if defined(CONFIG_CPU_SUBTYPE_SH7763) || defined(CONFIG_CPU_SUBTYPE_SH7764)
1014 IRQF_SHARED, 1021 IRQF_SHARED,
1015#else 1022#else
@@ -1045,6 +1052,7 @@ static int sh_eth_open(struct net_device *ndev)
1045 1052
1046out_free_irq: 1053out_free_irq:
1047 free_irq(ndev->irq, ndev); 1054 free_irq(ndev->irq, ndev);
1055 pm_runtime_put_sync(&mdp->pdev->dev);
1048 return ret; 1056 return ret;
1049} 1057}
1050 1058
@@ -1176,6 +1184,8 @@ static int sh_eth_close(struct net_device *ndev)
1176 ringsize = sizeof(struct sh_eth_txdesc) * TX_RING_SIZE; 1184 ringsize = sizeof(struct sh_eth_txdesc) * TX_RING_SIZE;
1177 dma_free_coherent(NULL, ringsize, mdp->tx_ring, mdp->tx_desc_dma); 1185 dma_free_coherent(NULL, ringsize, mdp->tx_ring, mdp->tx_desc_dma);
1178 1186
1187 pm_runtime_put_sync(&mdp->pdev->dev);
1188
1179 return 0; 1189 return 0;
1180} 1190}
1181 1191
@@ -1184,6 +1194,8 @@ static struct net_device_stats *sh_eth_get_stats(struct net_device *ndev)
1184 struct sh_eth_private *mdp = netdev_priv(ndev); 1194 struct sh_eth_private *mdp = netdev_priv(ndev);
1185 u32 ioaddr = ndev->base_addr; 1195 u32 ioaddr = ndev->base_addr;
1186 1196
1197 pm_runtime_get_sync(&mdp->pdev->dev);
1198
1187 mdp->stats.tx_dropped += ctrl_inl(ioaddr + TROCR); 1199 mdp->stats.tx_dropped += ctrl_inl(ioaddr + TROCR);
1188 ctrl_outl(0, ioaddr + TROCR); /* (write clear) */ 1200 ctrl_outl(0, ioaddr + TROCR); /* (write clear) */
1189 mdp->stats.collisions += ctrl_inl(ioaddr + CDCR); 1201 mdp->stats.collisions += ctrl_inl(ioaddr + CDCR);
@@ -1199,6 +1211,8 @@ static struct net_device_stats *sh_eth_get_stats(struct net_device *ndev)
1199 mdp->stats.tx_carrier_errors += ctrl_inl(ioaddr + CNDCR); 1211 mdp->stats.tx_carrier_errors += ctrl_inl(ioaddr + CNDCR);
1200 ctrl_outl(0, ioaddr + CNDCR); /* (write clear) */ 1212 ctrl_outl(0, ioaddr + CNDCR); /* (write clear) */
1201#endif 1213#endif
1214 pm_runtime_put_sync(&mdp->pdev->dev);
1215
1202 return &mdp->stats; 1216 return &mdp->stats;
1203} 1217}
1204 1218
@@ -1407,6 +1421,9 @@ static int sh_eth_drv_probe(struct platform_device *pdev)
1407 1421
1408 mdp = netdev_priv(ndev); 1422 mdp = netdev_priv(ndev);
1409 spin_lock_init(&mdp->lock); 1423 spin_lock_init(&mdp->lock);
1424 mdp->pdev = pdev;
1425 pm_runtime_enable(&pdev->dev);
1426 pm_runtime_resume(&pdev->dev);
1410 1427
1411 pd = (struct sh_eth_plat_data *)(pdev->dev.platform_data); 1428 pd = (struct sh_eth_plat_data *)(pdev->dev.platform_data);
1412 /* get PHY ID */ 1429 /* get PHY ID */
@@ -1428,7 +1445,7 @@ static int sh_eth_drv_probe(struct platform_device *pdev)
1428 mdp->post_fw = POST_FW >> (devno << 1); 1445 mdp->post_fw = POST_FW >> (devno << 1);
1429 1446
1430 /* read and set MAC address */ 1447 /* read and set MAC address */
1431 read_mac_address(ndev); 1448 read_mac_address(ndev, pd->mac_addr);
1432 1449
1433 /* First device only init */ 1450 /* First device only init */
1434 if (!devno) { 1451 if (!devno) {
@@ -1482,18 +1499,37 @@ static int sh_eth_drv_remove(struct platform_device *pdev)
1482 sh_mdio_release(ndev); 1499 sh_mdio_release(ndev);
1483 unregister_netdev(ndev); 1500 unregister_netdev(ndev);
1484 flush_scheduled_work(); 1501 flush_scheduled_work();
1485 1502 pm_runtime_disable(&pdev->dev);
1486 free_netdev(ndev); 1503 free_netdev(ndev);
1487 platform_set_drvdata(pdev, NULL); 1504 platform_set_drvdata(pdev, NULL);
1488 1505
1489 return 0; 1506 return 0;
1490} 1507}
1491 1508
1509static int sh_eth_runtime_nop(struct device *dev)
1510{
1511 /*
1512 * Runtime PM callback shared between ->runtime_suspend()
1513 * and ->runtime_resume(). Simply returns success.
1514 *
1515 * This driver re-initializes all registers after
1516 * pm_runtime_get_sync() anyway so there is no need
1517 * to save and restore registers here.
1518 */
1519 return 0;
1520}
1521
1522static struct dev_pm_ops sh_eth_dev_pm_ops = {
1523 .runtime_suspend = sh_eth_runtime_nop,
1524 .runtime_resume = sh_eth_runtime_nop,
1525};
1526
1492static struct platform_driver sh_eth_driver = { 1527static struct platform_driver sh_eth_driver = {
1493 .probe = sh_eth_drv_probe, 1528 .probe = sh_eth_drv_probe,
1494 .remove = sh_eth_drv_remove, 1529 .remove = sh_eth_drv_remove,
1495 .driver = { 1530 .driver = {
1496 .name = CARDNAME, 1531 .name = CARDNAME,
1532 .pm = &sh_eth_dev_pm_ops,
1497 }, 1533 },
1498}; 1534};
1499 1535