This series intended to improve runtime PM and allow CPSW to be
RPM suspended when all ethX netdevices are down.
To achieve above goal it is required to relax runtime PM constraints for
Davinci MDIO which blocks CPSW runtime PM now, because Davinci MDIO is always
powered on during probe and powered off only when it's going to be removed.
- Patches 6-11 implement PM runtime autosuspend for Davinci MDIO, but keep it
disabled by default, because Davinci MDIO is integrated in big set of TI devices
and not all of them verified to work correctly with RPM autosuspend enabled:
expected to work on SoCs where MDIO is defined as part of CPSW in DT
(cpsw.c DRA7/am57x, am437x, am335x)
The CPSW need to be fixed before RPM suspended can be allowed:
- Patches 1-5 ensure that CPSW will not cause L3 errors while it is in RPM
suspended state.
Davinci MDIO RPM autosuspend can be enabled through sysfs:
echo 100 > /sys/devices/../48484000.ethernet/48485000.mdio/power/autosuspend_delay_ms
Patches 12 - 15: introduce new compatible string "ti,cpsw-mdio" which is used
then to enable RPM for am335x/am437x/dra7 SoCs.
Tested on am335x, am437x, am572x and k2g (on k2g with RPM disabled for Davinci MDIO)
These changes should not affect on errata i877 implementation on DRA7.
Power measurement on am335x GP EVM:
Without this series: 547.60 mW total SoC power
With this series + "ifconfig eth0 down": 477.32 mW Total Soc Power
Changes in v2:
- CPSW ethtool interface updated to use .begin()/.complete() callbacks
- kbuild failure fixed
- davinci_mdio DT updated with proper description of allowed compatible strings
combinations
Link on v1:
https://lkml.org/lkml/2016/6/15/362
Grygorii Strashko (15):
drivers: net: cpsw: fix suspend when all ethX devices are down
drivers: net: cpsw: check return code from pm runtime calls
drivers: net: cpsw: remove pm runtime calls from suspend callbacks
drivers: net: cpsw: ethtool: fix accessing to suspended device
drivers: net: cpsw: ndev: fix accessing to suspended device
drivers: net: davinci_mdio: do pm runtime initialization later in probe
drivers: net: davinci_mdio: remove pm runtime calls from suspend callbacks
drivers: net: davinci_mdio: drop suspended and lock fields from mdio_data
drivers: net: davinci_mdio: split reset function on init_clk and enable
drivers: net: davinci_mdio: add pm runtime callbacks
drivers: net: davinci_mdio: implement pm runtime auto mode
net: davinci_mdio: document missed "ti,am4372-mdio" compat string
net: davinci_mdio: introduce "ti,cpsw-mdio" compat string
drivers: net: davinci_mdio: enable pm runtime auto for ti cpsw-mdio
ARM: dts: am335x/am437x/dra7: use new "ti,cpsw-mdio" compat string
.../devicetree/bindings/net/davinci-mdio.txt | 5 +-
arch/arm/boot/dts/am33xx.dtsi | 2 +-
arch/arm/boot/dts/am4372.dtsi | 2 +-
arch/arm/boot/dts/dra7.dtsi | 2 +-
drivers/net/ethernet/ti/cpsw.c | 79 ++++++++--
drivers/net/ethernet/ti/davinci_mdio.c | 169 +++++++++++++--------
6 files changed, 182 insertions(+), 77 deletions(-)
--
2.9.0
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
The cpsw_suspend() could trigger L3 error and CPSW will stop
functioning if System enters suspend when all ethX net-devices are
down - in this case CPSW could be already suspended by PM runtime, but
cpsw_suspend() will try to call soft_reset_slave() unconditionally
and access CPSW registers.
Hence, fix it by moving soft_reset_slave() from cpsw_suspend() to
cpsw_slave_stop(). This way slave ports will be reset when CPSW is
active and will be in proper state during Suspend.
Signed-off-by: Grygorii Strashko <grygorii.strashko@ti.com>
---
drivers/net/ethernet/ti/cpsw.c | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
The CPSW might be suspended by RPM if all ethX interfaces are down,
but it still could be accesible through net_device_ops interfce. In
this case net_device_ops operations requiring registers access will
cause L3 errors and CPSW crash.
Hence, fix it by adding RPM get/put calls in net_device_ops callbacks
which need to access CPSW registers: .ndo_set_mac_address(),
.ndo_vlan_rx_add_vid(), .ndo_vlan_rx_kill_vid().
Signed-off-by: Grygorii Strashko <grygorii.strashko@ti.com>
---
drivers/net/ethernet/ti/cpsw.c | 33 ++++++++++++++++++++++++++++++---
1 file changed, 30 insertions(+), 3 deletions(-)
@@ -1698,10 +1707,17 @@ static int cpsw_ndo_vlan_rx_add_vid(struct net_device *ndev,__be16proto,u16vid){structcpsw_priv*priv=netdev_priv(ndev);+intret;if(vid==priv->data.default_vlan)return0;+ret=pm_runtime_get_sync(&priv->pdev->dev);+if(ret<0){+pm_runtime_put_noidle(&priv->pdev->dev);+returnret;+}+if(priv->data.dual_emac){/* In dual EMAC, reserved VLAN id should not be used for*creatingVLANinterfacesasthiscanbreakthedual
@@ -1716,7 +1732,10 @@ static int cpsw_ndo_vlan_rx_add_vid(struct net_device *ndev,}dev_info(priv->dev,"Adding vlanid %d to vlan filter\n",vid);-returncpsw_add_vlan_ale_entry(priv,vid);+ret=cpsw_add_vlan_ale_entry(priv,vid);++pm_runtime_put(&priv->pdev->dev);+returnret;}staticintcpsw_ndo_vlan_rx_kill_vid(structnet_device*ndev,
@@ -1728,6 +1747,12 @@ static int cpsw_ndo_vlan_rx_kill_vid(struct net_device *ndev,if(vid==priv->data.default_vlan)return0;+ret=pm_runtime_get_sync(&priv->pdev->dev);+if(ret<0){+pm_runtime_put_noidle(&priv->pdev->dev);+returnret;+}+if(priv->data.dual_emac){inti;
@@ -1747,8 +1772,10 @@ static int cpsw_ndo_vlan_rx_kill_vid(struct net_device *ndev,if(ret!=0)returnret;-returncpsw_ale_del_mcast(priv->ale,priv->ndev->broadcast,-0,ALE_VLAN,vid);+ret=cpsw_ale_del_mcast(priv->ale,priv->ndev->broadcast,+0,ALE_VLAN,vid);+pm_runtime_put(&priv->pdev->dev);+returnret;}staticconststructnet_device_opscpsw_netdev_ops={
The Davinci MDIO MDIO_CONTROL.CLKDIV can be calculated only once
during probe, hence split __davinci_mdio_reset() on
davinci_mdio_init_clk() and davinci_mdio_enable(). Initialize and
save CLKDIV in .probe(). Then just use saved value.
Signed-off-by: Grygorii Strashko <grygorii.strashko@ti.com>
---
drivers/net/ethernet/ti/davinci_mdio.c | 21 ++++++++++++++-------
1 file changed, 14 insertions(+), 7 deletions(-)
@@ -350,6 +355,8 @@ static int davinci_mdio_probe(struct platform_device *pdev)if(IS_ERR(data->regs))returnPTR_ERR(data->regs);+davinci_mdio_init_clk(data);+pm_runtime_enable(&pdev->dev);pm_runtime_get_sync(&pdev->dev);
@@ -425,7 +432,7 @@ static int davinci_mdio_resume(struct device *dev)pinctrl_pm_select_default_state(dev);/* restart the scan state machine */-__davinci_mdio_reset(data);+davinci_mdio_enable(data);return0;}
It's not expected Davinci MDIO to be accessible after its suspend
callbacks have been called:
- all consumers of Davinci MDIO will stop/disconnect phys at Device
suspend stage;
- all phys are expected to be suspned already by PHY/MDIO core;
- MDIO locking is done by MDIO Bus code.
Hence, it's safe to drop "suspended" and "lock" fields from mdio_data.
Signed-off-by: Grygorii Strashko <grygorii.strashko@ti.com>
---
drivers/net/ethernet/ti/davinci_mdio.c | 30 ------------------------------
1 file changed, 30 deletions(-)
@@ -225,13 +223,6 @@ static int davinci_mdio_read(struct mii_bus *bus, int phy_id, int phy_reg)if(phy_reg&~PHY_REG_MASK||phy_id&~PHY_ID_MASK)return-EINVAL;-spin_lock(&data->lock);--if(data->suspended){-spin_unlock(&data->lock);-return-ENODEV;-}-reg=(USERACCESS_GO|USERACCESS_READ|(phy_reg<<21)|(phy_id<<16));
@@ -255,8 +246,6 @@ static int davinci_mdio_read(struct mii_bus *bus, int phy_id, int phy_reg)break;}-spin_unlock(&data->lock);-returnret;}
@@ -270,13 +259,6 @@ static int davinci_mdio_write(struct mii_bus *bus, int phy_id,if(phy_reg&~PHY_REG_MASK||phy_id&~PHY_ID_MASK)return-EINVAL;-spin_lock(&data->lock);--if(data->suspended){-spin_unlock(&data->lock);-return-ENODEV;-}-reg=(USERACCESS_GO|USERACCESS_WRITE|(phy_reg<<21)|(phy_id<<16)|(phy_data&USERACCESS_DATA));
@@ -295,8 +277,6 @@ static int davinci_mdio_write(struct mii_bus *bus, int phy_id,break;}-spin_unlock(&data->lock);-return0;}
@@ -364,7 +344,6 @@ static int davinci_mdio_probe(struct platform_device *pdev)dev_set_drvdata(dev,data);data->dev=dev;-spin_lock_init(&data->lock);res=platform_get_resource(pdev,IORESOURCE_MEM,0);data->regs=devm_ioremap_resource(dev,res);
@@ -426,17 +405,12 @@ static int davinci_mdio_suspend(struct device *dev)structdavinci_mdio_data*data=dev_get_drvdata(dev);u32ctrl;-spin_lock(&data->lock);-/* shutdown the scan state machine */ctrl=__raw_readl(&data->regs->control);ctrl&=~CONTROL_ENABLE;__raw_writel(ctrl,&data->regs->control);wait_for_idle(data);-data->suspended=true;-spin_unlock(&data->lock);-/* Select sleep pin state */pinctrl_pm_select_sleep_state(dev);
@@ -450,13 +424,9 @@ static int davinci_mdio_resume(struct device *dev)/* Select default pin state */pinctrl_pm_select_default_state(dev);-spin_lock(&data->lock);/* restart the scan state machine */__davinci_mdio_reset(data);-data->suspended=false;-spin_unlock(&data->lock);-return0;}#endif
Introduce "ti,cpsw-mdio" compatible string for Davinci MDIO, because
it's required to distinguish the case when MDIO is part of TI CPSW to
enable features supported by TI CPSW (for example, enable PM
management).
Signed-off-by: Grygorii Strashko <grygorii.strashko@ti.com>
---
Documentation/devicetree/bindings/net/davinci-mdio.txt | 1 +
1 file changed, 1 insertion(+)
@@ -4,6 +4,7 @@ TI SoC Davinci/Keystone2 MDIO Controller Device Tree Bindings Required properties: - compatible : Should be "ti,davinci_mdio" and "ti,keystone_mdio" for Keystone 2 SoCs+ and "ti,cpsw-mdio" for am335x, am472x, am57xx/dra7, dm814x SoCs and "ti,am4372-mdio" for am472x SoC - reg : physical base address and size of the davinci mdio registers map
Add "ti,cpsw-mdio" for am335x/am437x/dra7 SoCs where MDIO is
implemented as part of TI CPSW and, this way, enable PM runtime auto
suspend for Davinci MDIO driver on these paltforms.
Signed-off-by: Grygorii Strashko <grygorii.strashko@ti.com>
---
arch/arm/boot/dts/am33xx.dtsi | 2 +-
arch/arm/boot/dts/am4372.dtsi | 2 +-
arch/arm/boot/dts/dra7.dtsi | 2 +-
3 files changed, 3 insertions(+), 3 deletions(-)
Use "ti,cpsw-mdio" to enable PM runtime auto-suspend on supported
platforms, where MDIO is implemented as part of TI CPSW.
Signed-off-by: Grygorii Strashko <grygorii.strashko@ti.com>
---
drivers/net/ethernet/ti/davinci_mdio.c | 45 +++++++++++++++++++++++++---------
1 file changed, 34 insertions(+), 11 deletions(-)
@@ -2,7 +2,9 @@ TI SoC Davinci/Keystone2 MDIO Controller Device Tree Bindings --------------------------------------------------- Required properties:-- compatible : Should be "ti,davinci_mdio" or "ti,keystone_mdio"+- compatible : Should be "ti,davinci_mdio"+ and "ti,keystone_mdio" for Keystone 2 SoCs+ and "ti,am4372-mdio" for am472x SoC - reg : physical base address and size of the davinci mdio registers map - bus_freq : Mdio Bus frequency
Davinci MDIO is always used as slave device which services
read/write requests from MDIO/PHY core. It doesn't use IRQ also.
As result, It's possible to relax PM runtime constraints for Davinci
MDIO and enable it on demand, instead of powering it during probe
and powering off during removal.
Hence, implement PM runtime autosuspend for Davinci MDIO, but keep it
disabled by default, because Davinci MDIO is integrated in big set of
TI devices and not all of them expected to work corectly with RPM
autosuspend enabled:
- expected to work on SoCs where MDIO is part of TI CPSW
(cpsw.c DRA7/am57x, am437x, am335x, dm814x)
- not verified on Keystone 2 and other SoCs where MDIO is used with TI EMAC IP
(davinci_emac.c: dm6467-emac, am3517-emac, dm816-emac).
Davinci MDIO RPM autosuspend can be enabled through sysfs:
echo 100 > /sys/devices/../48484000.ethernet/48485000.mdio/power/autosuspend_delay_ms
Signed-off-by: Grygorii Strashko <grygorii.strashko@ti.com>
---
drivers/net/ethernet/ti/davinci_mdio.c | 48 +++++++++++++++++++++++++++-------
1 file changed, 39 insertions(+), 9 deletions(-)
@@ -93,6 +93,7 @@ struct davinci_mdio_data {structclk*clk;structdevice*dev;structmii_bus*bus;+boolactive_in_suspend;unsignedlongaccess_time;/* jiffies *//* Indicates that driver shouldn't modify phy_mask in case*ifMDIObusisregisteredfromDT.
@@ -141,8 +142,13 @@ static int davinci_mdio_reset(struct mii_bus *bus){structdavinci_mdio_data*data=bus->priv;u32phy_mask,ver;+intret;-davinci_mdio_enable(data);+ret=pm_runtime_get_sync(data->dev);+if(ret<0){+pm_runtime_put_noidle(data->dev);+returnret;+}/* wait for scan logic to settle */msleep(PHY_MAX_ADDR*data->access_time);
@@ -153,7 +159,7 @@ static int davinci_mdio_reset(struct mii_bus *bus)(ver>>8)&0xff,ver&0xff);if(data->skip_scan)-return0;+gotodone;/* get phy mask from the alive register */phy_mask=__raw_readl(&data->regs->alive);
@@ -168,6 +174,10 @@ static int davinci_mdio_reset(struct mii_bus *bus)}data->bus->phy_mask=phy_mask;+done:+pm_runtime_mark_last_busy(data->dev);+pm_runtime_put_autosuspend(data->dev);+return0;}
@@ -228,6 +238,12 @@ static int davinci_mdio_read(struct mii_bus *bus, int phy_id, int phy_reg)if(phy_reg&~PHY_REG_MASK||phy_id&~PHY_ID_MASK)return-EINVAL;+ret=pm_runtime_get_sync(data->dev);+if(ret<0){+pm_runtime_put_noidle(data->dev);+returnret;+}+reg=(USERACCESS_GO|USERACCESS_READ|(phy_reg<<21)|(phy_id<<16));
@@ -251,6 +267,8 @@ static int davinci_mdio_read(struct mii_bus *bus, int phy_id, int phy_reg)break;}+pm_runtime_mark_last_busy(data->dev);+pm_runtime_put_autosuspend(data->dev);returnret;}
@@ -264,6 +282,12 @@ static int davinci_mdio_write(struct mii_bus *bus, int phy_id,if(phy_reg&~PHY_REG_MASK||phy_id&~PHY_ID_MASK)return-EINVAL;+ret=pm_runtime_get_sync(data->dev);+if(ret<0){+pm_runtime_put_noidle(data->dev);+returnret;+}+reg=(USERACCESS_GO|USERACCESS_WRITE|(phy_reg<<21)|(phy_id<<16)|(phy_data&USERACCESS_DATA));
@@ -282,7 +306,10 @@ static int davinci_mdio_write(struct mii_bus *bus, int phy_id,break;}-return0;+pm_runtime_mark_last_busy(data->dev);+pm_runtime_put_autosuspend(data->dev);++returnret;}#if IS_ENABLED(CONFIG_OF)
@@ -357,8 +384,9 @@ static int davinci_mdio_probe(struct platform_device *pdev)davinci_mdio_init_clk(data);+pm_runtime_set_autosuspend_delay(&pdev->dev,-1);+pm_runtime_use_autosuspend(&pdev->dev);pm_runtime_enable(&pdev->dev);-pm_runtime_get_sync(&pdev->dev);/* register the mii bus*CreatePHYsfromDTonlyincaseifPHYchildnodesareexplicitly
@@ -387,9 +415,8 @@ static int davinci_mdio_probe(struct platform_device *pdev)return0;bail_out:-pm_runtime_put_sync(&pdev->dev);+pm_runtime_dont_use_autosuspend(&pdev->dev);pm_runtime_disable(&pdev->dev);-returnret;}
@@ -400,7 +427,7 @@ static int davinci_mdio_remove(struct platform_device *pdev)if(data->bus)mdiobus_unregister(data->bus);-pm_runtime_put_sync(&pdev->dev);+pm_runtime_dont_use_autosuspend(&pdev->dev);pm_runtime_disable(&pdev->dev);return0;
@@ -436,7 +463,9 @@ static int davinci_mdio_suspend(struct device *dev)structdavinci_mdio_data*data=dev_get_drvdata(dev);intret=0;-ret=pm_runtime_force_suspend(dev);+data->active_in_suspend=!pm_runtime_status_suspended(dev);+if(data->active_in_suspend)+ret=pm_runtime_force_suspend(dev);if(ret<0)returnret;
@@ -453,7 +482,8 @@ static int davinci_mdio_resume(struct device *dev)/* Select default pin state */pinctrl_pm_select_default_state(dev);-pm_runtime_force_resume(dev);+if(data->active_in_suspend)+pm_runtime_force_resume(dev);return0;}
Add PM runtime .runtime_suspend()/.runtime_resume() callbacks and
perform Davinci MDIO enabling/disabling from these callbacks. This
allows to reuse pm_runtime_force_suspend/resume() APIs during System
suspend and required for further implementation of PM runtime
autosuspend.
Signed-off-by: Grygorii Strashko <grygorii.strashko@ti.com>
---
drivers/net/ethernet/ti/davinci_mdio.c | 31 +++++++++++++++++++++++++++----
1 file changed, 27 insertions(+), 4 deletions(-)
@@ -418,6 +418,28 @@ static int davinci_mdio_suspend(struct device *dev)__raw_writel(ctrl,&data->regs->control);wait_for_idle(data);+return0;+}++staticintdavinci_mdio_runtime_resume(structdevice*dev)+{+structdavinci_mdio_data*data=dev_get_drvdata(dev);++davinci_mdio_enable(data);+return0;+}+#endif++#ifdef CONFIG_PM_SLEEP+staticintdavinci_mdio_suspend(structdevice*dev)+{+structdavinci_mdio_data*data=dev_get_drvdata(dev);+intret=0;++ret=pm_runtime_force_suspend(dev);+if(ret<0)+returnret;+/* Select sleep pin state */pinctrl_pm_select_sleep_state(dev);
@@ -431,14 +453,15 @@ static int davinci_mdio_resume(struct device *dev)/* Select default pin state */pinctrl_pm_select_default_state(dev);-/* restart the scan state machine */-davinci_mdio_enable(data);+pm_runtime_force_resume(dev);return0;}#endifstaticconststructdev_pm_opsdavinci_mdio_pm_ops={+SET_RUNTIME_PM_OPS(davinci_mdio_runtime_suspend,+davinci_mdio_runtime_resume,NULL)SET_LATE_SYSTEM_SLEEP_PM_OPS(davinci_mdio_suspend,davinci_mdio_resume)};
PM runtime is disabled when Davinci MDIO .suspend_late() and
.resume_early() callbacks are called. As result, any PM runtime calls here will
be just a nop and can be removed.
Signed-off-by: Grygorii Strashko <grygorii.strashko@ti.com>
---
drivers/net/ethernet/ti/davinci_mdio.c | 3 ---
1 file changed, 3 deletions(-)
@@ -436,7 +436,6 @@ static int davinci_mdio_suspend(struct device *dev)data->suspended=true;spin_unlock(&data->lock);-pm_runtime_put_sync(data->dev);/* Select sleep pin state */pinctrl_pm_select_sleep_state(dev);
@@ -451,8 +450,6 @@ static int davinci_mdio_resume(struct device *dev)/* Select default pin state */pinctrl_pm_select_default_state(dev);-pm_runtime_get_sync(data->dev);-spin_lock(&data->lock);/* restart the scan state machine */__davinci_mdio_reset(data);
The CPSW might be suspended by RPM if all ethX interfaces are down,
but it still could be accesible through ethtool interfce. In this case
ethtool operations, requiring registers access, will cause L3 errors and
CPSW crash.
ethtool callbcaks which need to access CPSW registers now:
.set_coalesce(), .get_ethtool_stats(), .set_pauseparam(), .get_regs()
Hence, fix it by adding .begin()/.complete() ethtool callbacks, which
will be called before/after each ethtool operation runs, and do CPSW
RPM handling in these callbacks. That way CPSW will be active while
handling ethtool requests.
Signed-off-by: Grygorii Strashko <grygorii.strashko@ti.com>
---
drivers/net/ethernet/ti/cpsw.c | 27 ++++++++++++++++++++++++++-
1 file changed, 26 insertions(+), 1 deletion(-)
@@ -356,14 +356,10 @@ static int davinci_mdio_probe(struct platform_device *pdev)data->bus->parent=dev;data->bus->priv=data;-pm_runtime_enable(&pdev->dev);-pm_runtime_get_sync(&pdev->dev);data->clk=devm_clk_get(dev,"fck");if(IS_ERR(data->clk)){dev_err(dev,"failed to get device clock\n");-ret=PTR_ERR(data->clk);-data->clk=NULL;-gotobail_out;+returnPTR_ERR(data->clk);}dev_set_drvdata(dev,data);
@@ -372,10 +368,11 @@ static int davinci_mdio_probe(struct platform_device *pdev)res=platform_get_resource(pdev,IORESOURCE_MEM,0);data->regs=devm_ioremap_resource(dev,res);-if(IS_ERR(data->regs)){-ret=PTR_ERR(data->regs);-gotobail_out;-}+if(IS_ERR(data->regs))+returnPTR_ERR(data->regs);++pm_runtime_enable(&pdev->dev);+pm_runtime_get_sync(&pdev->dev);/* register the mii bus*CreatePHYsfromDTonlyincaseifPHYchildnodesareexplicitly
PM runtime is properly handled in cpsw_ndo_open/stop(), as result it
isn't required to duplicate these calls in .suspend()/.resume()
callbacks. Moreover, it might cause unnecessary RPM resume of CPSW
during System suspend in the case it's already suspended because
all ethX interfaces are down already, before System suspend started.
Signed-off-by: Grygorii Strashko <grygorii.strashko@ti.com>
---
drivers/net/ethernet/ti/cpsw.c | 4 ----
1 file changed, 4 deletions(-)
@@ -1253,7 +1253,11 @@ static int cpsw_ndo_open(struct net_device *ndev)inti,ret;u32reg;-pm_runtime_get_sync(&priv->pdev->dev);+ret=pm_runtime_get_sync(&priv->pdev->dev);+if(ret<0){+pm_runtime_put_noidle(&priv->pdev->dev);+returnret;+}if(!cpsw_common_res_usage_state(priv))cpsw_intr_disable(priv);
@@ -2322,7 +2326,11 @@ static int cpsw_probe(struct platform_device *pdev)/* Need to enable clocks with runtime PM api to access module*registers*/-pm_runtime_get_sync(&pdev->dev);+ret=pm_runtime_get_sync(&pdev->dev);+if(ret<0){+pm_runtime_put_noidle(&pdev->dev);+gotoclean_runtime_disable_ret;+}priv->version=readl(&priv->regs->id_ver);pm_runtime_put_sync(&pdev->dev);
From: Mugunthan V N <hidden> Date: 2016-06-27 09:18:21
On Friday 24 June 2016 11:53 PM, Grygorii Strashko wrote:
This series intended to improve runtime PM and allow CPSW to be
RPM suspended when all ethX netdevices are down.
To achieve above goal it is required to relax runtime PM constraints for
Davinci MDIO which blocks CPSW runtime PM now, because Davinci MDIO is always
powered on during probe and powered off only when it's going to be removed.
- Patches 6-11 implement PM runtime autosuspend for Davinci MDIO, but keep it
disabled by default, because Davinci MDIO is integrated in big set of TI devices
and not all of them verified to work correctly with RPM autosuspend enabled:
expected to work on SoCs where MDIO is defined as part of CPSW in DT
(cpsw.c DRA7/am57x, am437x, am335x)
The CPSW need to be fixed before RPM suspended can be allowed:
- Patches 1-5 ensure that CPSW will not cause L3 errors while it is in RPM
suspended state.
Davinci MDIO RPM autosuspend can be enabled through sysfs:
echo 100 > /sys/devices/../48484000.ethernet/48485000.mdio/power/autosuspend_delay_ms
Patches 12 - 15: introduce new compatible string "ti,cpsw-mdio" which is used
then to enable RPM for am335x/am437x/dra7 SoCs.
Tested on am335x, am437x, am572x and k2g (on k2g with RPM disabled for Davinci MDIO)
These changes should not affect on errata i877 implementation on DRA7.
Power measurement on am335x GP EVM:
Without this series: 547.60 mW total SoC power
With this series + "ifconfig eth0 down": 477.32 mW Total Soc Power
Changes in v2:
- CPSW ethtool interface updated to use .begin()/.complete() callbacks
- kbuild failure fixed
- davinci_mdio DT updated with proper description of allowed compatible strings
combinations
Link on v1:
https://lkml.org/lkml/2016/6/15/362
For the series.
Reviewed-by: Mugunthan V N <redacted>
Regards
Mugunthan V N
Grygorii Strashko (15):
drivers: net: cpsw: fix suspend when all ethX devices are down
drivers: net: cpsw: check return code from pm runtime calls
drivers: net: cpsw: remove pm runtime calls from suspend callbacks
drivers: net: cpsw: ethtool: fix accessing to suspended device
drivers: net: cpsw: ndev: fix accessing to suspended device
drivers: net: davinci_mdio: do pm runtime initialization later in probe
drivers: net: davinci_mdio: remove pm runtime calls from suspend callbacks
drivers: net: davinci_mdio: drop suspended and lock fields from mdio_data
drivers: net: davinci_mdio: split reset function on init_clk and enable
drivers: net: davinci_mdio: add pm runtime callbacks
drivers: net: davinci_mdio: implement pm runtime auto mode
net: davinci_mdio: document missed "ti,am4372-mdio" compat string
net: davinci_mdio: introduce "ti,cpsw-mdio" compat string
drivers: net: davinci_mdio: enable pm runtime auto for ti cpsw-mdio
ARM: dts: am335x/am437x/dra7: use new "ti,cpsw-mdio" compat string
.../devicetree/bindings/net/davinci-mdio.txt | 5 +-
arch/arm/boot/dts/am33xx.dtsi | 2 +-
arch/arm/boot/dts/am4372.dtsi | 2 +-
arch/arm/boot/dts/dra7.dtsi | 2 +-
drivers/net/ethernet/ti/cpsw.c | 79 ++++++++--
drivers/net/ethernet/ti/davinci_mdio.c | 169 +++++++++++++--------
6 files changed, 182 insertions(+), 77 deletions(-)
This series intended to improve runtime PM and allow CPSW to be
RPM suspended when all ethX netdevices are down.
Series applied, thanks.
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html