]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
net: bcmasp: fix double disable of clk
authorJustin Chen <justin.chen@broadcom.com>
Thu, 19 Mar 2026 23:48:13 +0000 (16:48 -0700)
committerJakub Kicinski <kuba@kernel.org>
Sat, 21 Mar 2026 02:07:28 +0000 (19:07 -0700)
Switch to devm_clk_get_optional() so we can manage the clock ourselves.
We dynamically control the clocks depending on the state of the interface
for power savings. The default state is clock disabled, so unbinding the
driver causes a double disable.

Fixes: 490cb412007d ("net: bcmasp: Add support for ASP2.0 Ethernet controller")
Signed-off-by: Justin Chen <justin.chen@broadcom.com>
Reviewed-by: Florian Fainelli <florian.fainelli@broadcom.com>
Link: https://patch.msgid.link/20260319234813.1937315-3-justin.chen@broadcom.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
drivers/net/ethernet/broadcom/asp2/bcmasp.c

index 2034a1593db71401f85e1b167821720debce8203..972474893a6bcbcd1cc94438c9c5a433da03fc86 100644 (file)
@@ -1249,7 +1249,7 @@ static int bcmasp_probe(struct platform_device *pdev)
        if (priv->irq <= 0)
                return -EINVAL;
 
-       priv->clk = devm_clk_get_optional_enabled(dev, "sw_asp");
+       priv->clk = devm_clk_get_optional(dev, "sw_asp");
        if (IS_ERR(priv->clk))
                return dev_err_probe(dev, PTR_ERR(priv->clk),
                                     "failed to request clock\n");
@@ -1277,6 +1277,10 @@ static int bcmasp_probe(struct platform_device *pdev)
 
        bcmasp_set_pdata(priv, pdata);
 
+       ret = clk_prepare_enable(priv->clk);
+       if (ret)
+               return dev_err_probe(dev, ret, "failed to start clock\n");
+
        /* Enable all clocks to ensure successful probing */
        bcmasp_core_clock_set(priv, ASP_CTRL_CLOCK_CTRL_ASP_ALL_DISABLE, 0);
 
@@ -1288,8 +1292,10 @@ static int bcmasp_probe(struct platform_device *pdev)
 
        ret = devm_request_irq(&pdev->dev, priv->irq, bcmasp_isr, 0,
                               pdev->name, priv);
-       if (ret)
-               return dev_err_probe(dev, ret, "failed to request ASP interrupt: %d", ret);
+       if (ret) {
+               dev_err(dev, "Failed to request ASP interrupt: %d", ret);
+               goto err_clock_disable;
+       }
 
        /* Register mdio child nodes */
        of_platform_populate(dev->of_node, bcmasp_mdio_of_match, NULL, dev);
@@ -1301,13 +1307,17 @@ static int bcmasp_probe(struct platform_device *pdev)
 
        priv->mda_filters = devm_kcalloc(dev, priv->num_mda_filters,
                                         sizeof(*priv->mda_filters), GFP_KERNEL);
-       if (!priv->mda_filters)
-               return -ENOMEM;
+       if (!priv->mda_filters) {
+               ret = -ENOMEM;
+               goto err_clock_disable;
+       }
 
        priv->net_filters = devm_kcalloc(dev, priv->num_net_filters,
                                         sizeof(*priv->net_filters), GFP_KERNEL);
-       if (!priv->net_filters)
-               return -ENOMEM;
+       if (!priv->net_filters) {
+               ret = -ENOMEM;
+               goto err_clock_disable;
+       }
 
        bcmasp_core_init_filters(priv);
 
@@ -1316,7 +1326,8 @@ static int bcmasp_probe(struct platform_device *pdev)
        ports_node = of_find_node_by_name(dev->of_node, "ethernet-ports");
        if (!ports_node) {
                dev_warn(dev, "No ports found\n");
-               return -EINVAL;
+               ret = -EINVAL;
+               goto err_clock_disable;
        }
 
        i = 0;
@@ -1338,8 +1349,6 @@ static int bcmasp_probe(struct platform_device *pdev)
         */
        bcmasp_core_clock_set(priv, 0, ASP_CTRL_CLOCK_CTRL_ASP_ALL_DISABLE);
 
-       clk_disable_unprepare(priv->clk);
-
        /* Now do the registration of the network ports which will take care
         * of managing the clock properly.
         */
@@ -1352,12 +1361,16 @@ static int bcmasp_probe(struct platform_device *pdev)
                count++;
        }
 
+       clk_disable_unprepare(priv->clk);
+
        dev_info(dev, "Initialized %d port(s)\n", count);
 
        return ret;
 
 err_cleanup:
        bcmasp_remove_intfs(priv);
+err_clock_disable:
+       clk_disable_unprepare(priv->clk);
 
        return ret;
 }