dbus-cynara: Upgrade to 1.10.20
[AGL/meta-agl.git] / meta-agl-bsp / meta-renesas / recipes-kernel / linux / linux / hibernation / 0010-Add-rcar-eth-hibernation-code.patch
1 From 1d20d3bd16eac561e14513c9e6cac543fab5a3f0 Mon Sep 17 00:00:00 2001
2 From: Yuichi Kusakabe <yuichi.kusakabe@jp.fujitsu.com>
3 Date: Thu, 18 May 2017 17:42:33 +0900
4 Subject: [PATCH 10/15] Add rcar-eth hibernation code
5
6 Signed-off-by: Yuichi Kusakabe <yuichi.kusakabe@jp.fujitsu.com>
7 ---
8  drivers/net/ethernet/renesas/sh_eth.c | 57 +++++++++++++++++++++++++++++++++--
9  drivers/net/phy/phy_device.c          | 41 +++++++++++++++++++++++++
10  2 files changed, 95 insertions(+), 3 deletions(-)
11
12 diff --git a/drivers/net/ethernet/renesas/sh_eth.c b/drivers/net/ethernet/renesas/sh_eth.c
13 index 991fa1e..7e91b26 100644
14 --- a/drivers/net/ethernet/renesas/sh_eth.c
15 +++ b/drivers/net/ethernet/renesas/sh_eth.c
16 @@ -33,6 +33,7 @@
17  #include <linux/of.h>
18  #include <linux/of_device.h>
19  #include <linux/of_irq.h>
20 +#include <linux/of_gpio.h>
21  #include <linux/of_net.h>
22  #include <linux/phy.h>
23  #include <linux/cache.h>
24 @@ -999,6 +1000,7 @@ static unsigned long sh_eth_get_edtrr_trns(struct sh_eth_private *mdp)
25  struct bb_info {
26         void (*set_gate)(void *addr);
27         struct mdiobb_ctrl ctrl;
28 +       struct sh_eth_private *mdp;
29         void *addr;
30         u32 mmd_msk;/* MMD */
31         u32 mdo_msk;
32 @@ -1029,6 +1031,8 @@ static void sh_mmd_ctrl(struct mdiobb_ctrl *ctrl, int bit)
33  {
34         struct bb_info *bitbang = container_of(ctrl, struct bb_info, ctrl);
35  
36 +       pm_runtime_get_sync(&bitbang->mdp->pdev->dev);
37 +
38         if (bitbang->set_gate)
39                 bitbang->set_gate(bitbang->addr);
40  
41 @@ -1036,6 +1040,8 @@ static void sh_mmd_ctrl(struct mdiobb_ctrl *ctrl, int bit)
42                 bb_set(bitbang->addr, bitbang->mmd_msk);
43         else
44                 bb_clr(bitbang->addr, bitbang->mmd_msk);
45 +
46 +       pm_runtime_put_sync(&bitbang->mdp->pdev->dev);
47  }
48  
49  /* Set bit data*/
50 @@ -1043,6 +1049,8 @@ static void sh_set_mdio(struct mdiobb_ctrl *ctrl, int bit)
51  {
52         struct bb_info *bitbang = container_of(ctrl, struct bb_info, ctrl);
53  
54 +       pm_runtime_get_sync(&bitbang->mdp->pdev->dev);
55 +
56         if (bitbang->set_gate)
57                 bitbang->set_gate(bitbang->addr);
58  
59 @@ -1050,17 +1058,26 @@ static void sh_set_mdio(struct mdiobb_ctrl *ctrl, int bit)
60                 bb_set(bitbang->addr, bitbang->mdo_msk);
61         else
62                 bb_clr(bitbang->addr, bitbang->mdo_msk);
63 +
64 +       pm_runtime_put_sync(&bitbang->mdp->pdev->dev);
65  }
66  
67  /* Get bit data*/
68  static int sh_get_mdio(struct mdiobb_ctrl *ctrl)
69  {
70         struct bb_info *bitbang = container_of(ctrl, struct bb_info, ctrl);
71 +       unsigned int ret;
72 +
73 +       pm_runtime_get_sync(&bitbang->mdp->pdev->dev);
74  
75         if (bitbang->set_gate)
76                 bitbang->set_gate(bitbang->addr);
77  
78 -       return bb_read(bitbang->addr, bitbang->mdi_msk);
79 +       ret = bb_read(bitbang->addr, bitbang->mdi_msk);
80 +
81 +       pm_runtime_put_sync(&bitbang->mdp->pdev->dev);
82 +
83 +       return ret;
84  }
85  
86  /* MDC pin control */
87 @@ -1068,6 +1085,8 @@ static void sh_mdc_ctrl(struct mdiobb_ctrl *ctrl, int bit)
88  {
89         struct bb_info *bitbang = container_of(ctrl, struct bb_info, ctrl);
90  
91 +       pm_runtime_get_sync(&bitbang->mdp->pdev->dev);
92 +
93         if (bitbang->set_gate)
94                 bitbang->set_gate(bitbang->addr);
95  
96 @@ -1075,6 +1094,8 @@ static void sh_mdc_ctrl(struct mdiobb_ctrl *ctrl, int bit)
97                 bb_set(bitbang->addr, bitbang->mdc_msk);
98         else
99                 bb_clr(bitbang->addr, bitbang->mdc_msk);
100 +
101 +       pm_runtime_put_sync(&bitbang->mdp->pdev->dev);
102  }
103  
104  /* mdio bus control struct */
105 @@ -2664,6 +2685,7 @@ static int sh_mdio_init(struct sh_eth_private *mdp,
106         bitbang->mdo_msk = PIR_MDO;
107         bitbang->mmd_msk = PIR_MMD;
108         bitbang->mdc_msk = PIR_MDC;
109 +       bitbang->mdp = mdp;
110         bitbang->ctrl.ops = &bb_ops;
111  
112         /* MII controller setting */
113 @@ -3002,9 +3024,38 @@ static int sh_eth_runtime_nop(struct device *dev)
114         return 0;
115  }
116  
117 +static int sh_eth_suspend(struct device *dev)
118 +{
119 +       int ret = 0;
120 +       struct net_device *ndev = dev_get_drvdata(dev);
121 +
122 +       if (netif_running(ndev)) {
123 +               netif_device_detach(ndev);
124 +               ret = sh_eth_close(ndev);
125 +       }
126 +
127 +       return ret;
128 +}
129 +
130 +static int sh_eth_resume(struct device *dev)
131 +{
132 +       int ret = 0;
133 +       struct net_device *ndev = dev_get_drvdata(dev);
134 +
135 +       if (netif_running(ndev)) {
136 +               ret = sh_eth_open(ndev);
137 +               if (ret < 0)
138 +                       goto err;
139 +               netif_device_attach(ndev);
140 +       }
141 +
142 +err:
143 +       return ret;
144 +}
145 +
146  static const struct dev_pm_ops sh_eth_dev_pm_ops = {
147 -       .runtime_suspend = sh_eth_runtime_nop,
148 -       .runtime_resume = sh_eth_runtime_nop,
149 +       SET_RUNTIME_PM_OPS(sh_eth_runtime_nop, sh_eth_runtime_nop, NULL)
150 +       SET_SYSTEM_SLEEP_PM_OPS(sh_eth_suspend, sh_eth_resume)
151  };
152  #define SH_ETH_PM_OPS (&sh_eth_dev_pm_ops)
153  #else
154 diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c
155 index 3657b4a..3ceb4f9 100644
156 --- a/drivers/net/phy/phy_device.c
157 +++ b/drivers/net/phy/phy_device.c
158 @@ -510,6 +510,32 @@ int phy_init_hw(struct phy_device *phydev)
159         return phydev->drv->config_init(phydev);
160  }
161  
162 +int phy_suspend(struct phy_device *phydev)
163 +{
164 +       struct phy_driver *phydrv = to_phy_driver(phydev->dev.driver);
165 +       struct ethtool_wolinfo wol = { .cmd = ETHTOOL_GWOL };
166 +
167 +       /* If the device has WOL enabled, we cannot suspend the PHY */
168 +       phy_ethtool_get_wol(phydev, &wol);
169 +       if (wol.wolopts)
170 +               return -EBUSY;
171 +
172 +       if (phydrv->suspend)
173 +               return phydrv->suspend(phydev);
174 +       return 0;
175 +}
176 +EXPORT_SYMBOL(phy_suspend);
177 +
178 +int phy_resume(struct phy_device *phydev)
179 +{
180 +       struct phy_driver *phydrv = to_phy_driver(phydev->dev.driver);
181 +
182 +       if (phydrv->resume)
183 +               return phydrv->resume(phydev);
184 +       return 0;
185 +}
186 +EXPORT_SYMBOL(phy_resume);
187 +
188  /**
189   * phy_attach_direct - attach a network device to a given PHY device pointer
190   * @dev: network device to attach
191 @@ -528,6 +554,7 @@ static int phy_attach_direct(struct net_device *dev, struct phy_device *phydev,
192                              u32 flags, phy_interface_t interface)
193  {
194         struct device *d = &phydev->dev;
195 +       struct module *bus_module;
196         int err;
197  
198         /* Assume that if there is no driver, that it doesn't
199 @@ -553,6 +580,14 @@ static int phy_attach_direct(struct net_device *dev, struct phy_device *phydev,
200                 return -EBUSY;
201         }
202  
203 +       /* Increment the bus module reference count */
204 +       bus_module = phydev->bus->dev.driver ?
205 +                    phydev->bus->dev.driver->owner : NULL;
206 +       if (!try_module_get(bus_module)) {
207 +               dev_err(&dev->dev, "failed to get the bus module\n");
208 +               return -EIO;
209 +       }
210 +
211         phydev->attached_dev = dev;
212         dev->phydev = phydev;
213  
214 @@ -568,6 +603,8 @@ static int phy_attach_direct(struct net_device *dev, struct phy_device *phydev,
215         err = phy_init_hw(phydev);
216         if (err)
217                 phy_detach(phydev);
218 +       else
219 +               phy_resume(phydev);
220  
221         return err;
222  }
223 @@ -612,8 +649,12 @@ EXPORT_SYMBOL(phy_attach);
224   */
225  void phy_detach(struct phy_device *phydev)
226  {
227 +       if (phydev->bus->dev.driver)
228 +               module_put(phydev->bus->dev.driver->owner);
229 +
230         phydev->attached_dev->phydev = NULL;
231         phydev->attached_dev = NULL;
232 +       phy_suspend(phydev);
233  
234         /* If the device had no specific driver before (i.e. - it
235          * was using the generic driver), we unbind the device
236 -- 
237 1.8.3.1
238