add chaos_calmer branch
[15.05/openwrt.git] / target / linux / ipq806x / patches-3.18 / 132-clk-Add-clk_unregister_-divider-gate-mux-to-close-me.patch
1 From 4e3c021fb995bcbb5d1f814d00584cb80eb904a8 Mon Sep 17 00:00:00 2001
2 From: Krzysztof Kozlowski <k.kozlowski@samsung.com>
3 Date: Mon, 5 Jan 2015 10:52:40 +0100
4 Subject: [PATCH] clk: Add clk_unregister_{divider, gate, mux} to close memory
5  leak
6
7 The common clk_register_{divider,gate,mux} functions allocated memory
8 for internal data which wasn't freed anywhere. Drivers using these
9 helpers could only unregister clocks but the memory would still leak.
10
11 Add corresponding unregister functions which will release all resources.
12
13 Signed-off-by: Krzysztof Kozlowski <k.kozlowski@samsung.com>
14 Reviewed-by: Stephen Boyd <sboyd@codeaurora.org>
15 Signed-off-by: Michael Turquette <mturquette@linaro.org>
16 ---
17  drivers/clk/clk-divider.c    | 16 ++++++++++++++++
18  drivers/clk/clk-gate.c       | 16 ++++++++++++++++
19  drivers/clk/clk-mux.c        | 16 ++++++++++++++++
20  include/linux/clk-provider.h |  4 ++++
21  4 files changed, 52 insertions(+)
22
23 --- a/drivers/clk/clk-divider.c
24 +++ b/drivers/clk/clk-divider.c
25 @@ -461,3 +461,19 @@ struct clk *clk_register_divider_table(s
26                         width, clk_divider_flags, table, lock);
27  }
28  EXPORT_SYMBOL_GPL(clk_register_divider_table);
29 +
30 +void clk_unregister_divider(struct clk *clk)
31 +{
32 +       struct clk_divider *div;
33 +       struct clk_hw *hw;
34 +
35 +       hw = __clk_get_hw(clk);
36 +       if (!hw)
37 +               return;
38 +
39 +       div = to_clk_divider(hw);
40 +
41 +       clk_unregister(clk);
42 +       kfree(div);
43 +}
44 +EXPORT_SYMBOL_GPL(clk_unregister_divider);
45 --- a/drivers/clk/clk-gate.c
46 +++ b/drivers/clk/clk-gate.c
47 @@ -162,3 +162,19 @@ struct clk *clk_register_gate(struct dev
48         return clk;
49  }
50  EXPORT_SYMBOL_GPL(clk_register_gate);
51 +
52 +void clk_unregister_gate(struct clk *clk)
53 +{
54 +       struct clk_gate *gate;
55 +       struct clk_hw *hw;
56 +
57 +       hw = __clk_get_hw(clk);
58 +       if (!hw)
59 +               return;
60 +
61 +       gate = to_clk_gate(hw);
62 +
63 +       clk_unregister(clk);
64 +       kfree(gate);
65 +}
66 +EXPORT_SYMBOL_GPL(clk_unregister_gate);
67 --- a/drivers/clk/clk-mux.c
68 +++ b/drivers/clk/clk-mux.c
69 @@ -177,3 +177,19 @@ struct clk *clk_register_mux(struct devi
70                                       NULL, lock);
71  }
72  EXPORT_SYMBOL_GPL(clk_register_mux);
73 +
74 +void clk_unregister_mux(struct clk *clk)
75 +{
76 +       struct clk_mux *mux;
77 +       struct clk_hw *hw;
78 +
79 +       hw = __clk_get_hw(clk);
80 +       if (!hw)
81 +               return;
82 +
83 +       mux = to_clk_mux(hw);
84 +
85 +       clk_unregister(clk);
86 +       kfree(mux);
87 +}
88 +EXPORT_SYMBOL_GPL(clk_unregister_mux);
89 --- a/include/linux/clk-provider.h
90 +++ b/include/linux/clk-provider.h
91 @@ -294,6 +294,7 @@ struct clk *clk_register_gate(struct dev
92                 const char *parent_name, unsigned long flags,
93                 void __iomem *reg, u8 bit_idx,
94                 u8 clk_gate_flags, spinlock_t *lock);
95 +void clk_unregister_gate(struct clk *clk);
96  
97  struct clk_div_table {
98         unsigned int    val;
99 @@ -361,6 +362,7 @@ struct clk *clk_register_divider_table(s
100                 void __iomem *reg, u8 shift, u8 width,
101                 u8 clk_divider_flags, const struct clk_div_table *table,
102                 spinlock_t *lock);
103 +void clk_unregister_divider(struct clk *clk);
104  
105  /**
106   * struct clk_mux - multiplexer clock
107 @@ -414,6 +416,8 @@ struct clk *clk_register_mux_table(struc
108                 void __iomem *reg, u8 shift, u32 mask,
109                 u8 clk_mux_flags, u32 *table, spinlock_t *lock);
110  
111 +void clk_unregister_mux(struct clk *clk);
112 +
113  void of_fixed_factor_clk_setup(struct device_node *node);
114  
115  /**