diff options
Diffstat (limited to 'arch/arm/plat-mxc/clock.c')
| -rw-r--r-- | arch/arm/plat-mxc/clock.c | 37 |
1 files changed, 25 insertions, 12 deletions
diff --git a/arch/arm/plat-mxc/clock.c b/arch/arm/plat-mxc/clock.c index 323ff8ccc877..2ed3ab173add 100644 --- a/arch/arm/plat-mxc/clock.c +++ b/arch/arm/plat-mxc/clock.c | |||
| @@ -52,13 +52,14 @@ static void __clk_disable(struct clk *clk) | |||
| 52 | { | 52 | { |
| 53 | if (clk == NULL || IS_ERR(clk)) | 53 | if (clk == NULL || IS_ERR(clk)) |
| 54 | return; | 54 | return; |
| 55 | |||
| 56 | __clk_disable(clk->parent); | ||
| 57 | __clk_disable(clk->secondary); | ||
| 58 | |||
| 59 | WARN_ON(!clk->usecount); | 55 | WARN_ON(!clk->usecount); |
| 60 | if (!(--clk->usecount) && clk->disable) | 56 | |
| 61 | clk->disable(clk); | 57 | if (!(--clk->usecount)) { |
| 58 | if (clk->disable) | ||
| 59 | clk->disable(clk); | ||
| 60 | __clk_disable(clk->parent); | ||
| 61 | __clk_disable(clk->secondary); | ||
| 62 | } | ||
| 62 | } | 63 | } |
| 63 | 64 | ||
| 64 | static int __clk_enable(struct clk *clk) | 65 | static int __clk_enable(struct clk *clk) |
| @@ -66,12 +67,13 @@ static int __clk_enable(struct clk *clk) | |||
| 66 | if (clk == NULL || IS_ERR(clk)) | 67 | if (clk == NULL || IS_ERR(clk)) |
| 67 | return -EINVAL; | 68 | return -EINVAL; |
| 68 | 69 | ||
| 69 | __clk_enable(clk->parent); | 70 | if (clk->usecount++ == 0) { |
| 70 | __clk_enable(clk->secondary); | 71 | __clk_enable(clk->parent); |
| 71 | 72 | __clk_enable(clk->secondary); | |
| 72 | if (clk->usecount++ == 0 && clk->enable) | ||
| 73 | clk->enable(clk); | ||
| 74 | 73 | ||
| 74 | if (clk->enable) | ||
| 75 | clk->enable(clk); | ||
| 76 | } | ||
| 75 | return 0; | 77 | return 0; |
| 76 | } | 78 | } |
| 77 | 79 | ||
| @@ -160,17 +162,28 @@ EXPORT_SYMBOL(clk_set_rate); | |||
| 160 | int clk_set_parent(struct clk *clk, struct clk *parent) | 162 | int clk_set_parent(struct clk *clk, struct clk *parent) |
| 161 | { | 163 | { |
| 162 | int ret = -EINVAL; | 164 | int ret = -EINVAL; |
| 165 | struct clk *old; | ||
| 163 | 166 | ||
| 164 | if (clk == NULL || IS_ERR(clk) || parent == NULL || | 167 | if (clk == NULL || IS_ERR(clk) || parent == NULL || |
| 165 | IS_ERR(parent) || clk->set_parent == NULL) | 168 | IS_ERR(parent) || clk->set_parent == NULL) |
| 166 | return ret; | 169 | return ret; |
| 167 | 170 | ||
| 171 | if (clk->usecount) | ||
| 172 | clk_enable(parent); | ||
| 173 | |||
| 168 | mutex_lock(&clocks_mutex); | 174 | mutex_lock(&clocks_mutex); |
| 169 | ret = clk->set_parent(clk, parent); | 175 | ret = clk->set_parent(clk, parent); |
| 170 | if (ret == 0) | 176 | if (ret == 0) { |
| 177 | old = clk->parent; | ||
| 171 | clk->parent = parent; | 178 | clk->parent = parent; |
| 179 | } else { | ||
| 180 | old = parent; | ||
| 181 | } | ||
| 172 | mutex_unlock(&clocks_mutex); | 182 | mutex_unlock(&clocks_mutex); |
| 173 | 183 | ||
| 184 | if (clk->usecount) | ||
| 185 | clk_disable(old); | ||
| 186 | |||
| 174 | return ret; | 187 | return ret; |
| 175 | } | 188 | } |
| 176 | EXPORT_SYMBOL(clk_set_parent); | 189 | EXPORT_SYMBOL(clk_set_parent); |
