net: stmmac: dwmac-stm32: fix resume on STM32 MCU
authorBen Wolsieffer <ben.wolsieffer@hefring.com>
Wed, 27 Sep 2023 17:57:49 +0000 (13:57 -0400)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 10 Oct 2023 20:00:43 +0000 (22:00 +0200)
[ Upstream commit 6f195d6b0da3b689922ba9e302af2f49592fa9fc ]

The STM32MP1 keeps clk_rx enabled during suspend, and therefore the
driver does not enable the clock in stm32_dwmac_init() if the device was
suspended. The problem is that this same code runs on STM32 MCUs, which
do disable clk_rx during suspend, causing the clock to never be
re-enabled on resume.

This patch adds a variant flag to indicate that clk_rx remains enabled
during suspend, and uses this to decide whether to enable the clock in
stm32_dwmac_init() if the device was suspended.

This approach fixes this specific bug with limited opportunity for
unintended side-effects, but I have a follow up patch that will refactor
the clock configuration and hopefully make it less error prone.

Fixes: 6528e02cc9ff ("net: ethernet: stmmac: add adaptation for stm32mp157c.")
Signed-off-by: Ben Wolsieffer <ben.wolsieffer@hefring.com>
Reviewed-by: Jacob Keller <jacob.e.keller@intel.com>
Link: https://lore.kernel.org/r/20230927175749.1419774-1-ben.wolsieffer@hefring.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
drivers/net/ethernet/stmicro/stmmac/dwmac-stm32.c

index 2b38a49..533f524 100644 (file)
@@ -105,6 +105,7 @@ struct stm32_ops {
        int (*parse_data)(struct stm32_dwmac *dwmac,
                          struct device *dev);
        u32 syscfg_eth_mask;
+       bool clk_rx_enable_in_suspend;
 };
 
 static int stm32_dwmac_init(struct plat_stmmacenet_data *plat_dat)
@@ -122,7 +123,8 @@ static int stm32_dwmac_init(struct plat_stmmacenet_data *plat_dat)
        if (ret)
                return ret;
 
-       if (!dwmac->dev->power.is_suspended) {
+       if (!dwmac->ops->clk_rx_enable_in_suspend ||
+           !dwmac->dev->power.is_suspended) {
                ret = clk_prepare_enable(dwmac->clk_rx);
                if (ret) {
                        clk_disable_unprepare(dwmac->clk_tx);
@@ -515,7 +517,8 @@ static struct stm32_ops stm32mp1_dwmac_data = {
        .suspend = stm32mp1_suspend,
        .resume = stm32mp1_resume,
        .parse_data = stm32mp1_parse_data,
-       .syscfg_eth_mask = SYSCFG_MP1_ETH_MASK
+       .syscfg_eth_mask = SYSCFG_MP1_ETH_MASK,
+       .clk_rx_enable_in_suspend = true
 };
 
 static const struct of_device_id stm32_dwmac_match[] = {