Commit fba8a6f2 authored by Andy Shevchenko's avatar Andy Shevchenko Committed by Pavel Machek

leds: lgm-sso: Fix clock handling

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: c3987cd2 ("leds: lgm: Add LED controller driver for LGM SoC")
Cc: Amireddy Mallikarjuna reddy <mallikarjunax.reddy@linux.intel.com>
Signed-off-by: default avatarAndy Shevchenko <andy.shevchenko@gmail.com>
Signed-off-by: default avatarPavel Machek <pavel@ucw.cz>
parent a43a4e58
...@@ -132,8 +132,7 @@ struct sso_led_priv { ...@@ -132,8 +132,7 @@ struct sso_led_priv {
struct regmap *mmap; struct regmap *mmap;
struct device *dev; struct device *dev;
struct platform_device *pdev; struct platform_device *pdev;
struct clk *gclk; struct clk_bulk_data clocks[2];
struct clk *fpid_clk;
u32 fpid_clkrate; u32 fpid_clkrate;
u32 gptc_clkrate; u32 gptc_clkrate;
u32 freq[MAX_FREQ_RANK]; u32 freq[MAX_FREQ_RANK];
...@@ -763,12 +762,11 @@ static int sso_probe_gpios(struct sso_led_priv *priv) ...@@ -763,12 +762,11 @@ static int sso_probe_gpios(struct sso_led_priv *priv)
return sso_gpio_gc_init(dev, 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; struct sso_led_priv *priv = data;
clk_disable_unprepare(priv->fpid_clk); clk_bulk_disable_unprepare(ARRAY_SIZE(priv->clocks), priv->clocks);
clk_disable_unprepare(priv->gclk);
} }
static int intel_sso_led_probe(struct platform_device *pdev) static int intel_sso_led_probe(struct platform_device *pdev)
...@@ -785,36 +783,30 @@ 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; priv->dev = dev;
/* gate clock */ /* gate clock */
priv->gclk = devm_clk_get(dev, "sso"); priv->clocks[0].id = "sso";
if (IS_ERR(priv->gclk)) {
dev_err(dev, "get sso gate clock failed!\n"); /* fpid clock */
return PTR_ERR(priv->gclk); 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) { if (ret) {
dev_err(dev, "Failed to prepare/enable sso gate clock!\n"); dev_err(dev, "Getting clocks failed!\n");
return ret; return ret;
} }
priv->fpid_clk = devm_clk_get(dev, "fpid"); ret = clk_bulk_prepare_enable(ARRAY_SIZE(priv->clocks), priv->clocks);
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);
if (ret) { if (ret) {
dev_err(dev, "Failed to prepare/enable fpid clock!\n"); dev_err(dev, "Failed to prepare and enable clocks!\n");
return ret; return ret;
} }
priv->fpid_clkrate = clk_get_rate(priv->fpid_clk);
ret = devm_add_action_or_reset(dev, sso_clk_disable, priv); ret = devm_add_action_or_reset(dev, sso_clock_disable_unprepare, priv);
if (ret) { if (ret)
dev_err(dev, "Failed to devm_add_action_or_reset, %d\n", ret);
return 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); priv->mmap = syscon_node_to_regmap(dev->of_node);
if (IS_ERR(priv->mmap)) { if (IS_ERR(priv->mmap)) {
...@@ -859,8 +851,6 @@ static int intel_sso_led_remove(struct platform_device *pdev) ...@@ -859,8 +851,6 @@ static int intel_sso_led_remove(struct platform_device *pdev)
sso_led_shutdown(led); sso_led_shutdown(led);
} }
clk_disable_unprepare(priv->fpid_clk);
clk_disable_unprepare(priv->gclk);
regmap_exit(priv->mmap); regmap_exit(priv->mmap);
return 0; return 0;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment