aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKrzysztof Kozlowski <k.kozlowski@samsung.com>2015-01-05 04:52:40 -0500
committerMichael Turquette <mturquette@linaro.org>2015-01-17 16:52:41 -0500
commit4e3c021fb995bcbb5d1f814d00584cb80eb904a8 (patch)
treec9e503e37f84172b5184ebe0dd62d2ad8ab62462
parent0c7665c356021c10c3f45a620f3f12ad599850d5 (diff)
clk: Add clk_unregister_{divider, gate, mux} to close memory leak
The common clk_register_{divider,gate,mux} functions allocated memory for internal data which wasn't freed anywhere. Drivers using these helpers could only unregister clocks but the memory would still leak. Add corresponding unregister functions which will release all resources. Signed-off-by: Krzysztof Kozlowski <k.kozlowski@samsung.com> Reviewed-by: Stephen Boyd <sboyd@codeaurora.org> Signed-off-by: Michael Turquette <mturquette@linaro.org>
-rw-r--r--drivers/clk/clk-divider.c16
-rw-r--r--drivers/clk/clk-gate.c16
-rw-r--r--drivers/clk/clk-mux.c16
-rw-r--r--include/linux/clk-provider.h4
4 files changed, 52 insertions, 0 deletions
diff --git a/drivers/clk/clk-divider.c b/drivers/clk/clk-divider.c
index c0a842b335c5..c2bb9f679ec6 100644
--- a/drivers/clk/clk-divider.c
+++ b/drivers/clk/clk-divider.c
@@ -463,3 +463,19 @@ struct clk *clk_register_divider_table(struct device *dev, const char *name,
463 width, clk_divider_flags, table, lock); 463 width, clk_divider_flags, table, lock);
464} 464}
465EXPORT_SYMBOL_GPL(clk_register_divider_table); 465EXPORT_SYMBOL_GPL(clk_register_divider_table);
466
467void clk_unregister_divider(struct clk *clk)
468{
469 struct clk_divider *div;
470 struct clk_hw *hw;
471
472 hw = __clk_get_hw(clk);
473 if (!hw)
474 return;
475
476 div = to_clk_divider(hw);
477
478 clk_unregister(clk);
479 kfree(div);
480}
481EXPORT_SYMBOL_GPL(clk_unregister_divider);
diff --git a/drivers/clk/clk-gate.c b/drivers/clk/clk-gate.c
index 51fd87fb7ba6..186b96efeebf 100644
--- a/drivers/clk/clk-gate.c
+++ b/drivers/clk/clk-gate.c
@@ -162,3 +162,19 @@ struct clk *clk_register_gate(struct device *dev, const char *name,
162 return clk; 162 return clk;
163} 163}
164EXPORT_SYMBOL_GPL(clk_register_gate); 164EXPORT_SYMBOL_GPL(clk_register_gate);
165
166void clk_unregister_gate(struct clk *clk)
167{
168 struct clk_gate *gate;
169 struct clk_hw *hw;
170
171 hw = __clk_get_hw(clk);
172 if (!hw)
173 return;
174
175 gate = to_clk_gate(hw);
176
177 clk_unregister(clk);
178 kfree(gate);
179}
180EXPORT_SYMBOL_GPL(clk_unregister_gate);
diff --git a/drivers/clk/clk-mux.c b/drivers/clk/clk-mux.c
index 6e1ecf94bf58..69a094c3783d 100644
--- a/drivers/clk/clk-mux.c
+++ b/drivers/clk/clk-mux.c
@@ -177,3 +177,19 @@ struct clk *clk_register_mux(struct device *dev, const char *name,
177 NULL, lock); 177 NULL, lock);
178} 178}
179EXPORT_SYMBOL_GPL(clk_register_mux); 179EXPORT_SYMBOL_GPL(clk_register_mux);
180
181void clk_unregister_mux(struct clk *clk)
182{
183 struct clk_mux *mux;
184 struct clk_hw *hw;
185
186 hw = __clk_get_hw(clk);
187 if (!hw)
188 return;
189
190 mux = to_clk_mux(hw);
191
192 clk_unregister(clk);
193 kfree(mux);
194}
195EXPORT_SYMBOL_GPL(clk_unregister_mux);
diff --git a/include/linux/clk-provider.h b/include/linux/clk-provider.h
index d936409520f8..ebb7055a6d84 100644
--- a/include/linux/clk-provider.h
+++ b/include/linux/clk-provider.h
@@ -294,6 +294,7 @@ struct clk *clk_register_gate(struct device *dev, const char *name,
294 const char *parent_name, unsigned long flags, 294 const char *parent_name, unsigned long flags,
295 void __iomem *reg, u8 bit_idx, 295 void __iomem *reg, u8 bit_idx,
296 u8 clk_gate_flags, spinlock_t *lock); 296 u8 clk_gate_flags, spinlock_t *lock);
297void clk_unregister_gate(struct clk *clk);
297 298
298struct clk_div_table { 299struct clk_div_table {
299 unsigned int val; 300 unsigned int val;
@@ -361,6 +362,7 @@ struct clk *clk_register_divider_table(struct device *dev, const char *name,
361 void __iomem *reg, u8 shift, u8 width, 362 void __iomem *reg, u8 shift, u8 width,
362 u8 clk_divider_flags, const struct clk_div_table *table, 363 u8 clk_divider_flags, const struct clk_div_table *table,
363 spinlock_t *lock); 364 spinlock_t *lock);
365void clk_unregister_divider(struct clk *clk);
364 366
365/** 367/**
366 * struct clk_mux - multiplexer clock 368 * struct clk_mux - multiplexer clock
@@ -411,6 +413,8 @@ struct clk *clk_register_mux_table(struct device *dev, const char *name,
411 void __iomem *reg, u8 shift, u32 mask, 413 void __iomem *reg, u8 shift, u32 mask,
412 u8 clk_mux_flags, u32 *table, spinlock_t *lock); 414 u8 clk_mux_flags, u32 *table, spinlock_t *lock);
413 415
416void clk_unregister_mux(struct clk *clk);
417
414void of_fixed_factor_clk_setup(struct device_node *node); 418void of_fixed_factor_clk_setup(struct device_node *node);
415 419
416/** 420/**