[net-next,v3,2/2] net: stmmac: add support for phy-supply
Commit Message
Add generic phy-supply handling support to control the phy regulator to
avoid handling it within the glue code. Use the generic stmmac_platform
code to register a possible phy-supply and the stmmac_main code to
handle the power on/off.
Signed-off-by: Marco Felsch <m.felsch@pengutronix.de>
---
Changelog
v3:
- rebased onto net-next/main
- fixed changelog style
v2:
- adapt stmmac_phy_power
- move power-on/off into stmmac_main to handle WOL
- adapt commit message
.../net/ethernet/stmicro/stmmac/stmmac_main.c | 58 ++++++++++++++++++-
.../ethernet/stmicro/stmmac/stmmac_platform.c | 10 ++++
include/linux/stmmac.h | 1 +
3 files changed, 68 insertions(+), 1 deletion(-)
Comments
On Thu, 20 Jul 2023 09:23:04 +0200 Marco Felsch wrote:
> Add generic phy-supply handling support to control the phy regulator to
> avoid handling it within the glue code. Use the generic stmmac_platform
> code to register a possible phy-supply and the stmmac_main code to
> handle the power on/off.
Please rebase on latest net-next/master.
Bartosz converted the use_phy_wol bool to a flag a few weeks back.
On 23-07-20, Jakub Kicinski wrote:
> On Thu, 20 Jul 2023 09:23:04 +0200 Marco Felsch wrote:
> > Add generic phy-supply handling support to control the phy regulator to
> > avoid handling it within the glue code. Use the generic stmmac_platform
> > code to register a possible phy-supply and the stmmac_main code to
> > handle the power on/off.
>
> Please rebase on latest net-next/master.
> Bartosz converted the use_phy_wol bool to a flag a few weeks back.
Arg.. didn't noticed that, I will fix it.
Regards,
Marco
Hi Marco,
kernel test robot noticed the following build errors:
[auto build test ERROR on net-next/main]
url: https://github.com/intel-lab-lkp/linux/commits/Marco-Felsch/net-stmmac-add-support-for-phy-supply/20230720-152642
base: net-next/main
patch link: https://lore.kernel.org/r/20230720072304.3358701-2-m.felsch%40pengutronix.de
patch subject: [PATCH net-next v3 2/2] net: stmmac: add support for phy-supply
config: x86_64-kexec (https://download.01.org/0day-ci/archive/20230722/202307220459.2gaQtSqH-lkp@intel.com/config)
compiler: gcc-12 (Debian 12.2.0-14) 12.2.0
reproduce: (https://download.01.org/0day-ci/archive/20230722/202307220459.2gaQtSqH-lkp@intel.com/reproduce)
If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202307220459.2gaQtSqH-lkp@intel.com/
All errors (new ones prefixed by >>):
drivers/net/ethernet/stmicro/stmmac/stmmac_main.c: In function 'stmmac_suspend':
>> drivers/net/ethernet/stmicro/stmmac/stmmac_main.c:7706:32: error: 'struct plat_stmmacenet_data' has no member named 'use_phy_wol'
7706 | if (!priv->plat->use_phy_wol)
| ^~
drivers/net/ethernet/stmicro/stmmac/stmmac_main.c: In function 'stmmac_resume':
drivers/net/ethernet/stmicro/stmmac/stmmac_main.c:7790:32: error: 'struct plat_stmmacenet_data' has no member named 'use_phy_wol'
7790 | if (!priv->plat->use_phy_wol)
| ^~
vim +7706 drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
7651
7652 /**
7653 * stmmac_suspend - suspend callback
7654 * @dev: device pointer
7655 * Description: this is the function to suspend the device and it is called
7656 * by the platform driver to stop the network queue, release the resources,
7657 * program the PMT register (for WoL), clean and release driver resources.
7658 */
7659 int stmmac_suspend(struct device *dev)
7660 {
7661 struct net_device *ndev = dev_get_drvdata(dev);
7662 struct stmmac_priv *priv = netdev_priv(ndev);
7663 u32 chan;
7664
7665 if (!ndev || !netif_running(ndev))
7666 return 0;
7667
7668 mutex_lock(&priv->lock);
7669
7670 netif_device_detach(ndev);
7671
7672 stmmac_disable_all_queues(priv);
7673
7674 for (chan = 0; chan < priv->plat->tx_queues_to_use; chan++)
7675 hrtimer_cancel(&priv->dma_conf.tx_queue[chan].txtimer);
7676
7677 if (priv->eee_enabled) {
7678 priv->tx_path_in_lpi_mode = false;
7679 del_timer_sync(&priv->eee_ctrl_timer);
7680 }
7681
7682 /* Stop TX/RX DMA */
7683 stmmac_stop_all_dma(priv);
7684
7685 if (priv->plat->serdes_powerdown)
7686 priv->plat->serdes_powerdown(ndev, priv->plat->bsp_priv);
7687
7688 /* Enable Power down mode by programming the PMT regs */
7689 if (device_may_wakeup(priv->device) && priv->plat->pmt) {
7690 stmmac_pmt(priv, priv->hw, priv->wolopts);
7691 priv->irq_wake = 1;
7692 } else {
7693 stmmac_mac_set(priv, priv->ioaddr, false);
7694 pinctrl_pm_select_sleep_state(priv->device);
7695 }
7696
7697 mutex_unlock(&priv->lock);
7698
7699 rtnl_lock();
7700 if (device_may_wakeup(priv->device) && priv->plat->pmt) {
7701 phylink_suspend(priv->phylink, true);
7702 } else {
7703 if (device_may_wakeup(priv->device))
7704 phylink_speed_down(priv->phylink, false);
7705 phylink_suspend(priv->phylink, false);
> 7706 if (!priv->plat->use_phy_wol)
7707 stmmac_phy_power_off(priv);
7708 }
7709 rtnl_unlock();
7710
7711 if (priv->dma_cap.fpesel) {
7712 /* Disable FPE */
7713 stmmac_fpe_configure(priv, priv->ioaddr,
7714 priv->plat->tx_queues_to_use,
7715 priv->plat->rx_queues_to_use, false);
7716
7717 stmmac_fpe_handshake(priv, false);
7718 stmmac_fpe_stop_wq(priv);
7719 }
7720
7721 priv->speed = SPEED_UNKNOWN;
7722 return 0;
7723 }
7724 EXPORT_SYMBOL_GPL(stmmac_suspend);
7725
On 23-07-22, kernel test robot wrote:
> Hi Marco,
>
> kernel test robot noticed the following build errors:
>
> [auto build test ERROR on net-next/main]
>
> url: https://github.com/intel-lab-lkp/linux/commits/Marco-Felsch/net-stmmac-add-support-for-phy-supply/20230720-152642
> base: net-next/main
> patch link: https://lore.kernel.org/r/20230720072304.3358701-2-m.felsch%40pengutronix.de
> patch subject: [PATCH net-next v3 2/2] net: stmmac: add support for phy-supply
> config: x86_64-kexec (https://download.01.org/0day-ci/archive/20230722/202307220459.2gaQtSqH-lkp@intel.com/config)
> compiler: gcc-12 (Debian 12.2.0-14) 12.2.0
> reproduce: (https://download.01.org/0day-ci/archive/20230722/202307220459.2gaQtSqH-lkp@intel.com/reproduce)
>
> If you fix the issue in a separate patch/commit (i.e. not just a new version of
> the same patch/commit), kindly add following tags
> | Reported-by: kernel test robot <lkp@intel.com>
> | Closes: https://lore.kernel.org/oe-kbuild-all/202307220459.2gaQtSqH-lkp@intel.com/
>
> All errors (new ones prefixed by >>):
>
> drivers/net/ethernet/stmicro/stmmac/stmmac_main.c: In function 'stmmac_suspend':
> >> drivers/net/ethernet/stmicro/stmmac/stmmac_main.c:7706:32: error: 'struct plat_stmmacenet_data' has no member named 'use_phy_wol'
> 7706 | if (!priv->plat->use_phy_wol)
> | ^~
> drivers/net/ethernet/stmicro/stmmac/stmmac_main.c: In function 'stmmac_resume':
> drivers/net/ethernet/stmicro/stmmac/stmmac_main.c:7790:32: error: 'struct plat_stmmacenet_data' has no member named 'use_phy_wol'
> 7790 | if (!priv->plat->use_phy_wol)
> | ^~
The fixed v4 can be found here:
https://lore.kernel.org/all/20230721110345.3925719-1-m.felsch@pengutronix.de/
Regards,
Marco
@@ -31,6 +31,7 @@
#include <linux/pm_runtime.h>
#include <linux/prefetch.h>
#include <linux/pinctrl/consumer.h>
+#include <linux/regulator/consumer.h>
#ifdef CONFIG_DEBUG_FS
#include <linux/debugfs.h>
#include <linux/seq_file.h>
@@ -1128,6 +1129,55 @@ static void stmmac_check_pcs_mode(struct stmmac_priv *priv)
}
}
+/**
+ * stmmac_phy_power - PHY regulator on/off
+ * @priv: driver private structure
+ * @enable: turn on the regulator if true else turn it off
+ * Enable or disable the regulator powering the PHY.
+ */
+static int stmmac_phy_power(struct stmmac_priv *priv, bool enable)
+{
+ struct regulator *regulator = priv->plat->phy_regulator;
+ struct device *dev = priv->device;
+
+ if (!regulator)
+ return 0;
+
+ if (enable) {
+ int ret;
+
+ ret = regulator_enable(regulator);
+ if (ret)
+ dev_err(dev, "Fail to enable regulator\n");
+
+ return ret;
+ }
+
+ regulator_disable(regulator);
+
+ return 0;
+}
+
+/**
+ * stmmac_phy_power_on - PHY regulator on
+ * @priv: driver private structure
+ * Enable the PHY regulator
+ */
+static int stmmac_phy_power_on(struct stmmac_priv *priv)
+{
+ return stmmac_phy_power(priv, true);
+}
+
+/**
+ * stmmac_phy_power_off - PHY regulator off
+ * @priv: driver private structure
+ * Disable the PHY regulator
+ */
+static void stmmac_phy_power_off(struct stmmac_priv *priv)
+{
+ stmmac_phy_power(priv, false);
+}
+
/**
* stmmac_init_phy - PHY initialization
* @dev: net device structure
@@ -1253,7 +1303,8 @@ static int stmmac_phy_setup(struct stmmac_priv *priv)
return PTR_ERR(phylink);
priv->phylink = phylink;
- return 0;
+
+ return stmmac_phy_power_on(priv);
}
static void stmmac_display_rx_rings(struct stmmac_priv *priv,
@@ -7588,6 +7639,7 @@ void stmmac_dvr_remove(struct device *dev)
if (priv->hw->pcs != STMMAC_PCS_TBI &&
priv->hw->pcs != STMMAC_PCS_RTBI)
stmmac_mdio_unregister(ndev);
+ stmmac_phy_power_off(priv);
destroy_workqueue(priv->wq);
mutex_destroy(&priv->lock);
bitmap_free(priv->af_xdp_zc_qps);
@@ -7651,6 +7703,8 @@ int stmmac_suspend(struct device *dev)
if (device_may_wakeup(priv->device))
phylink_speed_down(priv->phylink, false);
phylink_suspend(priv->phylink, false);
+ if (!priv->plat->use_phy_wol)
+ stmmac_phy_power_off(priv);
}
rtnl_unlock();
@@ -7733,6 +7787,8 @@ int stmmac_resume(struct device *dev)
priv->irq_wake = 0;
} else {
pinctrl_pm_select_default_state(priv->device);
+ if (!priv->plat->use_phy_wol)
+ stmmac_phy_power_on(priv);
/* reset the phy so that it's ready */
if (priv->mii)
stmmac_mdio_reset(priv->mii);
@@ -11,6 +11,7 @@
#include <linux/device.h>
#include <linux/platform_device.h>
#include <linux/pm_runtime.h>
+#include <linux/regulator/consumer.h>
#include <linux/module.h>
#include <linux/io.h>
#include <linux/of.h>
@@ -424,6 +425,15 @@ stmmac_probe_config_dt(struct platform_device *pdev, u8 *mac)
if (plat->interface < 0)
plat->interface = plat->phy_interface;
+ /* Optional regulator for PHY */
+ plat->phy_regulator = devm_regulator_get_optional(&pdev->dev, "phy");
+ if (IS_ERR(plat->phy_regulator)) {
+ if (PTR_ERR(plat->phy_regulator) == -EPROBE_DEFER)
+ return ERR_CAST(plat->phy_regulator);
+ dev_info(&pdev->dev, "No regulator found\n");
+ plat->phy_regulator = NULL;
+ }
+
/* Some wrapper drivers still rely on phy_node. Let's save it while
* they are not converted to phylink. */
plat->phy_node = of_parse_phandle(np, "phy-handle", 0);
@@ -222,6 +222,7 @@ struct plat_stmmacenet_data {
int phy_addr;
int interface;
phy_interface_t phy_interface;
+ struct regulator *phy_regulator;
struct stmmac_mdio_bus_data *mdio_bus_data;
struct device_node *phy_node;
struct device_node *phylink_node;