OSDN Git Service

leds: lgm-sso: Fix clock handling
authorAndy Shevchenko <andy.shevchenko@gmail.com>
Mon, 10 May 2021 09:50:24 +0000 (12:50 +0300)
committerPavel Machek <pavel@ucw.cz>
Fri, 28 May 2021 10:00:00 +0000 (12:00 +0200)
The clock handling has a few issues:
 - when getting second clock fails, the first one left prepared and enabled
 - on ->remove() clocks are unprepared and disabled twice

Fix all these by converting to use bulk clock operations since both clocks
are mandatory.

Fixes: c3987cd2bca3 ("leds: lgm: Add LED controller driver for LGM SoC")
Cc: Amireddy Mallikarjuna reddy <mallikarjunax.reddy@linux.intel.com>
Signed-off-by: Andy Shevchenko <andy.shevchenko@gmail.com>
Signed-off-by: Pavel Machek <pavel@ucw.cz>
drivers/leds/blink/leds-lgm-sso.c

index 6a63846..7d5f0bf 100644 (file)
@@ -132,8 +132,7 @@ struct sso_led_priv {
        struct regmap *mmap;
        struct device *dev;
        struct platform_device *pdev;
-       struct clk *gclk;
-       struct clk *fpid_clk;
+       struct clk_bulk_data clocks[2];
        u32 fpid_clkrate;
        u32 gptc_clkrate;
        u32 freq[MAX_FREQ_RANK];
@@ -763,12 +762,11 @@ static int sso_probe_gpios(struct sso_led_priv *priv)
        return sso_gpio_gc_init(dev, priv);
 }
 
-static void sso_clk_disable(void *data)
+static void sso_clock_disable_unprepare(void *data)
 {
        struct sso_led_priv *priv = data;
 
-       clk_disable_unprepare(priv->fpid_clk);
-       clk_disable_unprepare(priv->gclk);
+       clk_bulk_disable_unprepare(ARRAY_SIZE(priv->clocks), priv->clocks);
 }
 
 static int intel_sso_led_probe(struct platform_device *pdev)
@@ -785,36 +783,30 @@ static int intel_sso_led_probe(struct platform_device *pdev)
        priv->dev = dev;
 
        /* gate clock */
-       priv->gclk = devm_clk_get(dev, "sso");
-       if (IS_ERR(priv->gclk)) {
-               dev_err(dev, "get sso gate clock failed!\n");
-               return PTR_ERR(priv->gclk);
-       }
+       priv->clocks[0].id = "sso";
+
+       /* fpid clock */
+       priv->clocks[1].id = "fpid";
 
-       ret = clk_prepare_enable(priv->gclk);
+       ret = devm_clk_bulk_get(dev, ARRAY_SIZE(priv->clocks), priv->clocks);
        if (ret) {
-               dev_err(dev, "Failed to prepare/enable sso gate clock!\n");
+               dev_err(dev, "Getting clocks failed!\n");
                return ret;
        }
 
-       priv->fpid_clk = devm_clk_get(dev, "fpid");
-       if (IS_ERR(priv->fpid_clk)) {
-               dev_err(dev, "Failed to get fpid clock!\n");
-               return PTR_ERR(priv->fpid_clk);
-       }
-
-       ret = clk_prepare_enable(priv->fpid_clk);
+       ret = clk_bulk_prepare_enable(ARRAY_SIZE(priv->clocks), priv->clocks);
        if (ret) {
-               dev_err(dev, "Failed to prepare/enable fpid clock!\n");
+               dev_err(dev, "Failed to prepare and enable clocks!\n");
                return ret;
        }
-       priv->fpid_clkrate = clk_get_rate(priv->fpid_clk);
 
-       ret = devm_add_action_or_reset(dev, sso_clk_disable, priv);
-       if (ret) {
-               dev_err(dev, "Failed to devm_add_action_or_reset, %d\n", ret);
+       ret = devm_add_action_or_reset(dev, sso_clock_disable_unprepare, priv);
+       if (ret)
                return ret;
-       }
+
+       priv->fpid_clkrate = clk_get_rate(priv->clocks[1].clk);
+
+       priv->mmap = syscon_node_to_regmap(dev->of_node);
 
        priv->mmap = syscon_node_to_regmap(dev->of_node);
        if (IS_ERR(priv->mmap)) {
@@ -859,8 +851,6 @@ static int intel_sso_led_remove(struct platform_device *pdev)
                sso_led_shutdown(led);
        }
 
-       clk_disable_unprepare(priv->fpid_clk);
-       clk_disable_unprepare(priv->gclk);
        regmap_exit(priv->mmap);
 
        return 0;