aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2018-11-29 13:34:46 -0500
committerDavid S. Miller <davem@davemloft.net>2018-11-29 13:34:46 -0500
commita32701068632f74c2ab8cb5fac5ca640e39dc43c (patch)
tree82205652e64d1251bd4e365fb8795867da7561e0
parentbd82233f16c4665f186c84fca68419f8cbe97f07 (diff)
parent8d1283b1d6afe9c67ad8d8053f6202ef6fcb038a (diff)
Merge branch 'ave-suspend-resume'
Kunihiko Hayashi says: ==================== Add suspend/resume support for AVE ethernet driver This series adds support for suspend/resume to AVE ethernet driver. And to avoid the error that wol state of phy hardware is enabled by default, this sets initial wol state to disabled and add preservation the state in suspend/resume sequence. ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--drivers/net/ethernet/socionext/sni_ave.c60
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
1743static 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
1761static 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
1788static 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
1737static int ave_pro4_get_pinmode(struct ave_private *priv, 1794static 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};