mirror of
https://github.com/openwrt/openwrt.git
synced 2024-12-30 18:47:06 +00:00
242 lines
6.7 KiB
Diff
242 lines
6.7 KiB
Diff
|
From 73c350e3fb32e9598b66f61081c7e06a7fba49f8 Mon Sep 17 00:00:00 2001
|
||
|
From: Ben Wolsieffer <ben.wolsieffer@hefring.com>
|
||
|
Date: Mon, 9 Oct 2023 10:59:04 -0400
|
||
|
Subject: [PATCH 2/8] net: stmmac: dwmac-stm32: refactor clock config
|
||
|
|
||
|
Currently, clock configuration is spread throughout the driver and
|
||
|
partially duplicated for the STM32MP1 and STM32 MCU variants. This makes
|
||
|
it difficult to keep track of which clocks need to be enabled or disabled
|
||
|
in various scenarios.
|
||
|
|
||
|
This patch adds symmetric stm32_dwmac_clk_enable/disable() functions
|
||
|
that handle all clock configuration, including quirks required while
|
||
|
suspending or resuming. syscfg_clk and clk_eth_ck are not present on
|
||
|
STM32 MCUs, but it is fine to try to configure them anyway since NULL
|
||
|
clocks are ignored.
|
||
|
|
||
|
Signed-off-by: Ben Wolsieffer <ben.wolsieffer@hefring.com>
|
||
|
Signed-off-by: David S. Miller <davem@davemloft.net>
|
||
|
---
|
||
|
.../net/ethernet/stmicro/stmmac/dwmac-stm32.c | 113 +++++++-----------
|
||
|
1 file changed, 45 insertions(+), 68 deletions(-)
|
||
|
|
||
|
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-stm32.c
|
||
|
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-stm32.c
|
||
|
@@ -98,7 +98,6 @@ struct stm32_dwmac {
|
||
|
|
||
|
struct stm32_ops {
|
||
|
int (*set_mode)(struct plat_stmmacenet_data *plat_dat);
|
||
|
- int (*clk_prepare)(struct stm32_dwmac *dwmac, bool prepare);
|
||
|
int (*suspend)(struct stm32_dwmac *dwmac);
|
||
|
void (*resume)(struct stm32_dwmac *dwmac);
|
||
|
int (*parse_data)(struct stm32_dwmac *dwmac,
|
||
|
@@ -107,62 +106,55 @@ struct stm32_ops {
|
||
|
bool clk_rx_enable_in_suspend;
|
||
|
};
|
||
|
|
||
|
-static int stm32_dwmac_init(struct plat_stmmacenet_data *plat_dat)
|
||
|
+static int stm32_dwmac_clk_enable(struct stm32_dwmac *dwmac, bool resume)
|
||
|
{
|
||
|
- struct stm32_dwmac *dwmac = plat_dat->bsp_priv;
|
||
|
int ret;
|
||
|
|
||
|
- if (dwmac->ops->set_mode) {
|
||
|
- ret = dwmac->ops->set_mode(plat_dat);
|
||
|
- if (ret)
|
||
|
- return ret;
|
||
|
- }
|
||
|
-
|
||
|
ret = clk_prepare_enable(dwmac->clk_tx);
|
||
|
if (ret)
|
||
|
- return ret;
|
||
|
+ goto err_clk_tx;
|
||
|
|
||
|
- if (!dwmac->ops->clk_rx_enable_in_suspend ||
|
||
|
- !dwmac->dev->power.is_suspended) {
|
||
|
+ if (!dwmac->ops->clk_rx_enable_in_suspend || !resume) {
|
||
|
ret = clk_prepare_enable(dwmac->clk_rx);
|
||
|
- if (ret) {
|
||
|
- clk_disable_unprepare(dwmac->clk_tx);
|
||
|
- return ret;
|
||
|
- }
|
||
|
+ if (ret)
|
||
|
+ goto err_clk_rx;
|
||
|
}
|
||
|
|
||
|
- if (dwmac->ops->clk_prepare) {
|
||
|
- ret = dwmac->ops->clk_prepare(dwmac, true);
|
||
|
- if (ret) {
|
||
|
- clk_disable_unprepare(dwmac->clk_rx);
|
||
|
- clk_disable_unprepare(dwmac->clk_tx);
|
||
|
- }
|
||
|
+ ret = clk_prepare_enable(dwmac->syscfg_clk);
|
||
|
+ if (ret)
|
||
|
+ goto err_syscfg_clk;
|
||
|
+
|
||
|
+ if (dwmac->enable_eth_ck) {
|
||
|
+ ret = clk_prepare_enable(dwmac->clk_eth_ck);
|
||
|
+ if (ret)
|
||
|
+ goto err_clk_eth_ck;
|
||
|
}
|
||
|
|
||
|
return ret;
|
||
|
+
|
||
|
+err_clk_eth_ck:
|
||
|
+ clk_disable_unprepare(dwmac->syscfg_clk);
|
||
|
+err_syscfg_clk:
|
||
|
+ if (!dwmac->ops->clk_rx_enable_in_suspend || !resume)
|
||
|
+ clk_disable_unprepare(dwmac->clk_rx);
|
||
|
+err_clk_rx:
|
||
|
+ clk_disable_unprepare(dwmac->clk_tx);
|
||
|
+err_clk_tx:
|
||
|
+ return ret;
|
||
|
}
|
||
|
|
||
|
-static int stm32mp1_clk_prepare(struct stm32_dwmac *dwmac, bool prepare)
|
||
|
+static int stm32_dwmac_init(struct plat_stmmacenet_data *plat_dat, bool resume)
|
||
|
{
|
||
|
- int ret = 0;
|
||
|
+ struct stm32_dwmac *dwmac = plat_dat->bsp_priv;
|
||
|
+ int ret;
|
||
|
|
||
|
- if (prepare) {
|
||
|
- ret = clk_prepare_enable(dwmac->syscfg_clk);
|
||
|
+ if (dwmac->ops->set_mode) {
|
||
|
+ ret = dwmac->ops->set_mode(plat_dat);
|
||
|
if (ret)
|
||
|
return ret;
|
||
|
- if (dwmac->enable_eth_ck) {
|
||
|
- ret = clk_prepare_enable(dwmac->clk_eth_ck);
|
||
|
- if (ret) {
|
||
|
- clk_disable_unprepare(dwmac->syscfg_clk);
|
||
|
- return ret;
|
||
|
- }
|
||
|
- }
|
||
|
- } else {
|
||
|
- clk_disable_unprepare(dwmac->syscfg_clk);
|
||
|
- if (dwmac->enable_eth_ck)
|
||
|
- clk_disable_unprepare(dwmac->clk_eth_ck);
|
||
|
}
|
||
|
- return ret;
|
||
|
+
|
||
|
+ return stm32_dwmac_clk_enable(dwmac, resume);
|
||
|
}
|
||
|
|
||
|
static int stm32mp1_set_mode(struct plat_stmmacenet_data *plat_dat)
|
||
|
@@ -252,13 +244,15 @@ static int stm32mcu_set_mode(struct plat
|
||
|
dwmac->ops->syscfg_eth_mask, val << 23);
|
||
|
}
|
||
|
|
||
|
-static void stm32_dwmac_clk_disable(struct stm32_dwmac *dwmac)
|
||
|
+static void stm32_dwmac_clk_disable(struct stm32_dwmac *dwmac, bool suspend)
|
||
|
{
|
||
|
clk_disable_unprepare(dwmac->clk_tx);
|
||
|
- clk_disable_unprepare(dwmac->clk_rx);
|
||
|
+ if (!dwmac->ops->clk_rx_enable_in_suspend || !suspend)
|
||
|
+ clk_disable_unprepare(dwmac->clk_rx);
|
||
|
|
||
|
- if (dwmac->ops->clk_prepare)
|
||
|
- dwmac->ops->clk_prepare(dwmac, false);
|
||
|
+ clk_disable_unprepare(dwmac->syscfg_clk);
|
||
|
+ if (dwmac->enable_eth_ck)
|
||
|
+ clk_disable_unprepare(dwmac->clk_eth_ck);
|
||
|
}
|
||
|
|
||
|
static int stm32_dwmac_parse_data(struct stm32_dwmac *dwmac,
|
||
|
@@ -397,7 +391,7 @@ static int stm32_dwmac_probe(struct plat
|
||
|
|
||
|
plat_dat->bsp_priv = dwmac;
|
||
|
|
||
|
- ret = stm32_dwmac_init(plat_dat);
|
||
|
+ ret = stm32_dwmac_init(plat_dat, false);
|
||
|
if (ret)
|
||
|
return ret;
|
||
|
|
||
|
@@ -408,7 +402,7 @@ static int stm32_dwmac_probe(struct plat
|
||
|
return 0;
|
||
|
|
||
|
err_clk_disable:
|
||
|
- stm32_dwmac_clk_disable(dwmac);
|
||
|
+ stm32_dwmac_clk_disable(dwmac, false);
|
||
|
|
||
|
return ret;
|
||
|
}
|
||
|
@@ -421,7 +415,7 @@ static void stm32_dwmac_remove(struct pl
|
||
|
|
||
|
stmmac_dvr_remove(&pdev->dev);
|
||
|
|
||
|
- stm32_dwmac_clk_disable(priv->plat->bsp_priv);
|
||
|
+ stm32_dwmac_clk_disable(dwmac, false);
|
||
|
|
||
|
if (dwmac->irq_pwr_wakeup >= 0) {
|
||
|
dev_pm_clear_wake_irq(&pdev->dev);
|
||
|
@@ -431,18 +425,7 @@ static void stm32_dwmac_remove(struct pl
|
||
|
|
||
|
static int stm32mp1_suspend(struct stm32_dwmac *dwmac)
|
||
|
{
|
||
|
- int ret = 0;
|
||
|
-
|
||
|
- ret = clk_prepare_enable(dwmac->clk_ethstp);
|
||
|
- if (ret)
|
||
|
- return ret;
|
||
|
-
|
||
|
- clk_disable_unprepare(dwmac->clk_tx);
|
||
|
- clk_disable_unprepare(dwmac->syscfg_clk);
|
||
|
- if (dwmac->enable_eth_ck)
|
||
|
- clk_disable_unprepare(dwmac->clk_eth_ck);
|
||
|
-
|
||
|
- return ret;
|
||
|
+ return clk_prepare_enable(dwmac->clk_ethstp);
|
||
|
}
|
||
|
|
||
|
static void stm32mp1_resume(struct stm32_dwmac *dwmac)
|
||
|
@@ -450,14 +433,6 @@ static void stm32mp1_resume(struct stm32
|
||
|
clk_disable_unprepare(dwmac->clk_ethstp);
|
||
|
}
|
||
|
|
||
|
-static int stm32mcu_suspend(struct stm32_dwmac *dwmac)
|
||
|
-{
|
||
|
- clk_disable_unprepare(dwmac->clk_tx);
|
||
|
- clk_disable_unprepare(dwmac->clk_rx);
|
||
|
-
|
||
|
- return 0;
|
||
|
-}
|
||
|
-
|
||
|
#ifdef CONFIG_PM_SLEEP
|
||
|
static int stm32_dwmac_suspend(struct device *dev)
|
||
|
{
|
||
|
@@ -468,6 +443,10 @@ static int stm32_dwmac_suspend(struct de
|
||
|
int ret;
|
||
|
|
||
|
ret = stmmac_suspend(dev);
|
||
|
+ if (ret)
|
||
|
+ return ret;
|
||
|
+
|
||
|
+ stm32_dwmac_clk_disable(dwmac, true);
|
||
|
|
||
|
if (dwmac->ops->suspend)
|
||
|
ret = dwmac->ops->suspend(dwmac);
|
||
|
@@ -485,7 +464,7 @@ static int stm32_dwmac_resume(struct dev
|
||
|
if (dwmac->ops->resume)
|
||
|
dwmac->ops->resume(dwmac);
|
||
|
|
||
|
- ret = stm32_dwmac_init(priv->plat);
|
||
|
+ ret = stm32_dwmac_init(priv->plat, true);
|
||
|
if (ret)
|
||
|
return ret;
|
||
|
|
||
|
@@ -500,13 +479,11 @@ static SIMPLE_DEV_PM_OPS(stm32_dwmac_pm_
|
||
|
|
||
|
static struct stm32_ops stm32mcu_dwmac_data = {
|
||
|
.set_mode = stm32mcu_set_mode,
|
||
|
- .suspend = stm32mcu_suspend,
|
||
|
.syscfg_eth_mask = SYSCFG_MCU_ETH_MASK
|
||
|
};
|
||
|
|
||
|
static struct stm32_ops stm32mp1_dwmac_data = {
|
||
|
.set_mode = stm32mp1_set_mode,
|
||
|
- .clk_prepare = stm32mp1_clk_prepare,
|
||
|
.suspend = stm32mp1_suspend,
|
||
|
.resume = stm32mp1_resume,
|
||
|
.parse_data = stm32mp1_parse_data,
|