Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

net: stmmac: stm32: simplify clock handling

Some stm32 implementations need the receive clock running in suspend,
as indicated by dwmac->ops->clk_rx_enable_in_suspend. The existing
code achieved this in a rather complex way, by passing a flag around.

However, the clk API prepare/enables are counted - which means that a
clock won't be stopped as long as there are more prepare and enables
than disables and unprepares, just like a reference count.

Therefore, we can simplify this logic by calling clk_prepare_enable()
an additional time in the probe function if this flag is set, and then
balancing that at remove time.

With this, we can avoid passing a "are we suspending" and "are we
resuming" flag to various functions in the driver.

Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
Reviewed-by: Simon Horman <horms@kernel.org>
Signed-off-by: David S. Miller <davem@davemloft.net>

authored by

Russell King (Oracle) and committed by
David S. Miller
61499764 0c49baf0

+37 -20
+37 -20
drivers/net/ethernet/stmicro/stmmac/dwmac-stm32.c
··· 119 119 u32 syscfg_clr_off; 120 120 }; 121 121 122 - static int stm32_dwmac_clk_enable(struct stm32_dwmac *dwmac, bool resume) 122 + static int stm32_dwmac_clk_enable(struct stm32_dwmac *dwmac) 123 123 { 124 124 int ret; 125 125 ··· 127 127 if (ret) 128 128 goto err_clk_tx; 129 129 130 - if (!dwmac->ops->clk_rx_enable_in_suspend || !resume) { 131 - ret = clk_prepare_enable(dwmac->clk_rx); 132 - if (ret) 133 - goto err_clk_rx; 134 - } 130 + ret = clk_prepare_enable(dwmac->clk_rx); 131 + if (ret) 132 + goto err_clk_rx; 135 133 136 134 ret = clk_prepare_enable(dwmac->syscfg_clk); 137 135 if (ret) ··· 146 148 err_clk_eth_ck: 147 149 clk_disable_unprepare(dwmac->syscfg_clk); 148 150 err_syscfg_clk: 149 - if (!dwmac->ops->clk_rx_enable_in_suspend || !resume) 150 - clk_disable_unprepare(dwmac->clk_rx); 151 + clk_disable_unprepare(dwmac->clk_rx); 151 152 err_clk_rx: 152 153 clk_disable_unprepare(dwmac->clk_tx); 153 154 err_clk_tx: 154 155 return ret; 155 156 } 156 157 157 - static int stm32_dwmac_init(struct plat_stmmacenet_data *plat_dat, bool resume) 158 + static int stm32_dwmac_init(struct plat_stmmacenet_data *plat_dat) 158 159 { 159 160 struct stm32_dwmac *dwmac = plat_dat->bsp_priv; 160 161 int ret; ··· 164 167 return ret; 165 168 } 166 169 167 - return stm32_dwmac_clk_enable(dwmac, resume); 170 + return stm32_dwmac_clk_enable(dwmac); 168 171 } 169 172 170 173 static int stm32mp1_select_ethck_external(struct plat_stmmacenet_data *plat_dat) ··· 379 382 SYSCFG_MCU_ETH_MASK, val << 23); 380 383 } 381 384 382 - static void stm32_dwmac_clk_disable(struct stm32_dwmac *dwmac, bool suspend) 385 + static void stm32_dwmac_clk_disable(struct stm32_dwmac *dwmac) 383 386 { 384 387 clk_disable_unprepare(dwmac->clk_tx); 385 - if (!dwmac->ops->clk_rx_enable_in_suspend || !suspend) 386 - clk_disable_unprepare(dwmac->clk_rx); 387 - 388 + clk_disable_unprepare(dwmac->clk_rx); 388 389 clk_disable_unprepare(dwmac->syscfg_clk); 389 390 if (dwmac->enable_eth_ck) 390 391 clk_disable_unprepare(dwmac->clk_eth_ck); ··· 536 541 plat_dat->flags |= STMMAC_FLAG_EN_TX_LPI_CLK_PHY_CAP; 537 542 plat_dat->bsp_priv = dwmac; 538 543 539 - ret = stm32_dwmac_init(plat_dat, false); 544 + ret = stm32_dwmac_init(plat_dat); 540 545 if (ret) 541 546 return ret; 542 547 548 + /* If this platform requires the clock to be running in suspend, 549 + * prepare and enable the receive clock an additional time to keep 550 + * it running. 551 + */ 552 + if (dwmac->ops->clk_rx_enable_in_suspend) { 553 + ret = clk_prepare_enable(dwmac->clk_rx); 554 + if (ret) 555 + goto err_clk_disable; 556 + } 557 + 543 558 ret = stmmac_dvr_probe(&pdev->dev, plat_dat, &stmmac_res); 544 559 if (ret) 545 - goto err_clk_disable; 560 + goto err_clk_disable_suspend; 546 561 547 562 return 0; 548 563 564 + err_clk_disable_suspend: 565 + if (dwmac->ops->clk_rx_enable_in_suspend) 566 + clk_disable_unprepare(dwmac->clk_rx); 567 + 549 568 err_clk_disable: 550 - stm32_dwmac_clk_disable(dwmac, false); 569 + stm32_dwmac_clk_disable(dwmac); 551 570 552 571 return ret; 553 572 } ··· 574 565 575 566 stmmac_dvr_remove(&pdev->dev); 576 567 577 - stm32_dwmac_clk_disable(dwmac, false); 568 + /* If this platform requires the clock to be running in suspend, 569 + * we need to disable and unprepare the receive clock an additional 570 + * time to balance the extra clk_prepare_enable() in the probe 571 + * function. 572 + */ 573 + if (dwmac->ops->clk_rx_enable_in_suspend) 574 + clk_disable_unprepare(dwmac->clk_rx); 575 + 576 + stm32_dwmac_clk_disable(dwmac); 578 577 579 578 if (dwmac->irq_pwr_wakeup >= 0) { 580 579 dev_pm_clear_wake_irq(&pdev->dev); ··· 613 596 if (ret) 614 597 return ret; 615 598 616 - stm32_dwmac_clk_disable(dwmac, true); 599 + stm32_dwmac_clk_disable(dwmac); 617 600 618 601 if (dwmac->ops->suspend) 619 602 ret = dwmac->ops->suspend(dwmac); ··· 631 614 if (dwmac->ops->resume) 632 615 dwmac->ops->resume(dwmac); 633 616 634 - ret = stm32_dwmac_init(priv->plat, true); 617 + ret = stm32_dwmac_init(priv->plat); 635 618 if (ret) 636 619 return ret; 637 620