| From 700f2c231b4f6e1e57574646ebae1bc24df4b319 Mon Sep 17 00:00:00 2001 |
| From: Tony Lindgren <tony@atomide.com> |
| Date: Mon, 16 Dec 2019 14:41:53 -0800 |
| Subject: [PATCH] bus: ti-sysc: Fix iterating over clocks |
| |
| commit 2c81f0f6d3f52ac222a5dc07a6e5c06e1543e88b upstream. |
| |
| Commit d878970f6ce1 ("bus: ti-sysc: Add separate functions for handling |
| clocks") separated handling of optional clocks from the main clocks, but |
| introduced an issue where we do not necessarily allocate a slot for both |
| fck and ick clocks, but still assume fixed slots for enumerating over the |
| clocks. |
| |
| Let's fix the issue by ensuring we always have slots for both fck and ick |
| even if we don't use ick, and don't attempt to enumerate optional clocks |
| if not allocated. |
| |
| In the long run we might want to simplify things a bit by only allocating |
| space only for the optional clocks as we have only few devices with |
| optional clocks. |
| |
| Fixes: d878970f6ce1 ("bus: ti-sysc: Add separate functions for handling clocks") |
| Signed-off-by: Tony Lindgren <tony@atomide.com> |
| Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com> |
| |
| diff --git a/drivers/bus/ti-sysc.c b/drivers/bus/ti-sysc.c |
| index 0d122440d111..b412062c879c 100644 |
| --- a/drivers/bus/ti-sysc.c |
| +++ b/drivers/bus/ti-sysc.c |
| @@ -296,6 +296,12 @@ static int sysc_get_clocks(struct sysc *ddata) |
| return -EINVAL; |
| } |
| |
| + /* Always add a slot for main clocks fck and ick even if unused */ |
| + if (!nr_fck) |
| + ddata->nr_clocks++; |
| + if (!nr_ick) |
| + ddata->nr_clocks++; |
| + |
| ddata->clocks = devm_kcalloc(ddata->dev, |
| ddata->nr_clocks, sizeof(*ddata->clocks), |
| GFP_KERNEL); |
| @@ -374,7 +380,7 @@ static int sysc_enable_opt_clocks(struct sysc *ddata) |
| struct clk *clock; |
| int i, error; |
| |
| - if (!ddata->clocks) |
| + if (!ddata->clocks || ddata->nr_clocks < SYSC_OPTFCK0 + 1) |
| return 0; |
| |
| for (i = SYSC_OPTFCK0; i < SYSC_MAX_CLOCKS; i++) { |
| @@ -408,7 +414,7 @@ static void sysc_disable_opt_clocks(struct sysc *ddata) |
| struct clk *clock; |
| int i; |
| |
| - if (!ddata->clocks) |
| + if (!ddata->clocks || ddata->nr_clocks < SYSC_OPTFCK0 + 1) |
| return; |
| |
| for (i = SYSC_OPTFCK0; i < SYSC_MAX_CLOCKS; i++) { |
| -- |
| 2.7.4 |
| |