From patchwork Mon Dec 14 09:16:08 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Serge Semin X-Patchwork-Id: 11971625 X-Patchwork-Delegate: kuba@kernel.org Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-13.7 required=3.0 tests=BAYES_00, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 32425C1B0D8 for ; Mon, 14 Dec 2020 09:19:47 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id D9CE1207A2 for ; Mon, 14 Dec 2020 09:19:46 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2439868AbgLNJSz (ORCPT ); Mon, 14 Dec 2020 04:18:55 -0500 Received: from ns2.baikalchip.ru ([94.125.187.42]:46534 "EHLO mail.baikalelectronics.ru" rhost-flags-OK-FAIL-OK-FAIL) by vger.kernel.org with ESMTP id S2439819AbgLNJSn (ORCPT ); Mon, 14 Dec 2020 04:18:43 -0500 From: Serge Semin To: Rob Herring , Giuseppe Cavallaro , Alexandre Torgue , Jose Abreu , "David S. Miller" , Jakub Kicinski , Johan Hovold , Maxime Ripard , Joao Pinto , Lars Persson , Maxime Coquelin CC: Serge Semin , Serge Semin , Alexey Malahov , Pavel Parkhomenko , Vyacheslav Mitrofanov , , , , , Subject: [PATCH 18/25] net: stmmac: dwc-qos: Cleanup STMMAC platform data clock pointers Date: Mon, 14 Dec 2020 12:16:08 +0300 Message-ID: <20201214091616.13545-19-Sergey.Semin@baikalelectronics.ru> In-Reply-To: <20201214091616.13545-1-Sergey.Semin@baikalelectronics.ru> References: <20201214091616.13545-1-Sergey.Semin@baikalelectronics.ru> MIME-Version: 1.0 X-ClientProxiedBy: MAIL.baikal.int (192.168.51.25) To mail (192.168.51.25) Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org X-Patchwork-Delegate: kuba@kernel.org The pointers need to be nullified otherwise the stmmac_remove_config_dt() method called after them being initialized will disable the clocks. That then will cause a WARN() backtrace being printed since the clocks would be also disabled in the locally defined remove method. Signed-off-by: Serge Semin --- .../stmicro/stmmac/dwmac-dwc-qos-eth.c | 42 ++++++++++++++----- 1 file changed, 32 insertions(+), 10 deletions(-) diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-dwc-qos-eth.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-dwc-qos-eth.c index 2342d497348e..31ca299a1cfd 100644 --- a/drivers/net/ethernet/stmicro/stmmac/dwmac-dwc-qos-eth.c +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-dwc-qos-eth.c @@ -123,39 +123,46 @@ static void *dwc_qos_probe(struct platform_device *pdev, struct plat_stmmacenet_data *plat_dat, struct stmmac_resources *stmmac_res) { + struct clk *clk; int err; - plat_dat->stmmac_clk = devm_clk_get(&pdev->dev, "apb_pclk"); - if (IS_ERR(plat_dat->stmmac_clk)) { + clk = devm_clk_get(&pdev->dev, "apb_pclk"); + if (IS_ERR(clk)) { dev_err(&pdev->dev, "apb_pclk clock not found.\n"); - return ERR_CAST(plat_dat->stmmac_clk); + return ERR_CAST(clk); } - err = clk_prepare_enable(plat_dat->stmmac_clk); + err = clk_prepare_enable(clk); if (err < 0) { dev_err(&pdev->dev, "failed to enable apb_pclk clock: %d\n", err); return ERR_PTR(err); } - plat_dat->pclk = devm_clk_get(&pdev->dev, "phy_ref_clk"); - if (IS_ERR(plat_dat->pclk)) { + plat_dat->stmmac_clk = clk; + + clk = devm_clk_get(&pdev->dev, "phy_ref_clk"); + if (IS_ERR(clk)) { dev_err(&pdev->dev, "phy_ref_clk clock not found.\n"); - err = PTR_ERR(plat_dat->pclk); + err = PTR_ERR(clk); goto disable; } - err = clk_prepare_enable(plat_dat->pclk); + err = clk_prepare_enable(clk); if (err < 0) { dev_err(&pdev->dev, "failed to enable phy_ref clock: %d\n", err); goto disable; } + plat_dat->pclk = clk; + return NULL; disable: clk_disable_unprepare(plat_dat->stmmac_clk); + plat_dat->stmmac_clk = NULL; + return ERR_PTR(err); } @@ -164,8 +171,15 @@ static int dwc_qos_remove(struct platform_device *pdev) struct net_device *ndev = platform_get_drvdata(pdev); struct stmmac_priv *priv = netdev_priv(ndev); + /* Cleanup the pointers to the clock handlers hidden in the platform + * data so the stmmac_remove_config_dt() method wouldn't have disabled + * the clocks too. + */ clk_disable_unprepare(priv->plat->pclk); + priv->plat->pclk = NULL; + clk_disable_unprepare(priv->plat->stmmac_clk); + priv->plat->stmmac_clk = NULL; return 0; } @@ -303,12 +317,12 @@ static void *tegra_eqos_probe(struct platform_device *pdev, goto disable_master; } - data->stmmac_clk = eqos->clk_slave; - err = clk_prepare_enable(eqos->clk_slave); if (err < 0) goto disable_master; + data->stmmac_clk = eqos->clk_slave; + eqos->clk_rx = devm_clk_get(&pdev->dev, "rx"); if (IS_ERR(eqos->clk_rx)) { err = PTR_ERR(eqos->clk_rx); @@ -381,6 +395,7 @@ static void *tegra_eqos_probe(struct platform_device *pdev, clk_disable_unprepare(eqos->clk_rx); disable_slave: clk_disable_unprepare(eqos->clk_slave); + data->stmmac_clk = NULL; disable_master: clk_disable_unprepare(eqos->clk_master); error: @@ -390,6 +405,7 @@ static void *tegra_eqos_probe(struct platform_device *pdev, static int tegra_eqos_remove(struct platform_device *pdev) { + struct stmmac_priv *priv = netdev_priv(platform_get_drvdata(pdev)); struct tegra_eqos *eqos = get_stmmac_bsp_priv(&pdev->dev); reset_control_assert(eqos->rst); @@ -399,6 +415,12 @@ static int tegra_eqos_remove(struct platform_device *pdev) clk_disable_unprepare(eqos->clk_slave); clk_disable_unprepare(eqos->clk_master); + /* Cleanup the pointers to the clock handlers hidden in the platform + * data so the stmmac_remove_config_dt() method wouldn't have disabled + * the clocks too. + */ + priv->plat->stmmac_clk = NULL; + return 0; }