diff options
| -rw-r--r-- | drivers/net/ethernet/socionext/sni_ave.c | 60 |
1 files changed, 59 insertions, 1 deletions
diff --git a/drivers/net/ethernet/socionext/sni_ave.c b/drivers/net/ethernet/socionext/sni_ave.c index 9e7391faa1dc..1f9ef68d91ee 100644 --- a/drivers/net/ethernet/socionext/sni_ave.c +++ b/drivers/net/ethernet/socionext/sni_ave.c | |||
| @@ -261,6 +261,7 @@ struct ave_private { | |||
| 261 | struct regmap *regmap; | 261 | struct regmap *regmap; |
| 262 | unsigned int pinmode_mask; | 262 | unsigned int pinmode_mask; |
| 263 | unsigned int pinmode_val; | 263 | unsigned int pinmode_val; |
| 264 | u32 wolopts; | ||
| 264 | 265 | ||
| 265 | /* stats */ | 266 | /* stats */ |
| 266 | struct ave_stats stats_rx; | 267 | struct ave_stats stats_rx; |
| @@ -1208,9 +1209,13 @@ static int ave_init(struct net_device *ndev) | |||
| 1208 | 1209 | ||
| 1209 | priv->phydev = phydev; | 1210 | priv->phydev = phydev; |
| 1210 | 1211 | ||
| 1211 | phy_ethtool_get_wol(phydev, &wol); | 1212 | ave_ethtool_get_wol(ndev, &wol); |
| 1212 | device_set_wakeup_capable(&ndev->dev, !!wol.supported); | 1213 | device_set_wakeup_capable(&ndev->dev, !!wol.supported); |
| 1213 | 1214 | ||
| 1215 | /* set wol initial state disabled */ | ||
| 1216 | wol.wolopts = 0; | ||
| 1217 | ave_ethtool_set_wol(ndev, &wol); | ||
| 1218 | |||
| 1214 | if (!phy_interface_is_rgmii(phydev)) | 1219 | if (!phy_interface_is_rgmii(phydev)) |
| 1215 | phy_set_max_speed(phydev, SPEED_100); | 1220 | phy_set_max_speed(phydev, SPEED_100); |
| 1216 | 1221 | ||
| @@ -1734,6 +1739,58 @@ static int ave_remove(struct platform_device *pdev) | |||
| 1734 | return 0; | 1739 | return 0; |
| 1735 | } | 1740 | } |
| 1736 | 1741 | ||
| 1742 | #ifdef CONFIG_PM_SLEEP | ||
| 1743 | static int ave_suspend(struct device *dev) | ||
| 1744 | { | ||
| 1745 | struct ethtool_wolinfo wol = { .cmd = ETHTOOL_GWOL }; | ||
| 1746 | struct net_device *ndev = dev_get_drvdata(dev); | ||
| 1747 | struct ave_private *priv = netdev_priv(ndev); | ||
| 1748 | int ret = 0; | ||
| 1749 | |||
| 1750 | if (netif_running(ndev)) { | ||
| 1751 | ret = ave_stop(ndev); | ||
| 1752 | netif_device_detach(ndev); | ||
| 1753 | } | ||
| 1754 | |||
| 1755 | ave_ethtool_get_wol(ndev, &wol); | ||
| 1756 | priv->wolopts = wol.wolopts; | ||
| 1757 | |||
| 1758 | return ret; | ||
| 1759 | } | ||
| 1760 | |||
| 1761 | static int ave_resume(struct device *dev) | ||
| 1762 | { | ||
| 1763 | struct ethtool_wolinfo wol = { .cmd = ETHTOOL_GWOL }; | ||
| 1764 | struct net_device *ndev = dev_get_drvdata(dev); | ||
| 1765 | struct ave_private *priv = netdev_priv(ndev); | ||
| 1766 | int ret = 0; | ||
| 1767 | |||
| 1768 | ave_global_reset(ndev); | ||
| 1769 | |||
| 1770 | ave_ethtool_get_wol(ndev, &wol); | ||
| 1771 | wol.wolopts = priv->wolopts; | ||
| 1772 | ave_ethtool_set_wol(ndev, &wol); | ||
| 1773 | |||
| 1774 | if (ndev->phydev) { | ||
| 1775 | ret = phy_resume(ndev->phydev); | ||
| 1776 | if (ret) | ||
| 1777 | return ret; | ||
| 1778 | } | ||
| 1779 | |||
| 1780 | if (netif_running(ndev)) { | ||
| 1781 | ret = ave_open(ndev); | ||
| 1782 | netif_device_attach(ndev); | ||
| 1783 | } | ||
| 1784 | |||
| 1785 | return ret; | ||
| 1786 | } | ||
| 1787 | |||
| 1788 | static SIMPLE_DEV_PM_OPS(ave_pm_ops, ave_suspend, ave_resume); | ||
| 1789 | #define AVE_PM_OPS (&ave_pm_ops) | ||
| 1790 | #else | ||
| 1791 | #define AVE_PM_OPS NULL | ||
| 1792 | #endif | ||
| 1793 | |||
| 1737 | static int ave_pro4_get_pinmode(struct ave_private *priv, | 1794 | static int ave_pro4_get_pinmode(struct ave_private *priv, |
| 1738 | phy_interface_t phy_mode, u32 arg) | 1795 | phy_interface_t phy_mode, u32 arg) |
| 1739 | { | 1796 | { |
| @@ -1908,6 +1965,7 @@ static struct platform_driver ave_driver = { | |||
| 1908 | .remove = ave_remove, | 1965 | .remove = ave_remove, |
| 1909 | .driver = { | 1966 | .driver = { |
| 1910 | .name = "ave", | 1967 | .name = "ave", |
| 1968 | .pm = AVE_PM_OPS, | ||
| 1911 | .of_match_table = of_ave_match, | 1969 | .of_match_table = of_ave_match, |
| 1912 | }, | 1970 | }, |
| 1913 | }; | 1971 | }; |
