diff options
author | Mike Turquette <mturquette@linaro.org> | 2012-03-26 20:51:03 -0400 |
---|---|---|
committer | Mike Turquette <mturquette@linaro.org> | 2012-04-24 19:37:39 -0400 |
commit | 27d545915fd49cbe18a3877d82359896e9851efb (patch) | |
tree | ca3234eef7925fc068f6f55cd965abe21dfa399c | |
parent | d1302a36a7f1c33d1a8babc6a510e1401a5e5aed (diff) |
clk: basic: improve parent_names & return errors
This patch is the basic clk version of 'clk: core: copy parent_names &
return error codes'.
The registration functions are changed to allow the core code to copy
the array of strings and allow platforms to declare those arrays as
__initdata.
This patch also converts all of the basic clk registration functions to
return error codes which better aligns them with the existing clk.h api.
Signed-off-by: Mike Turquette <mturquette@linaro.org>
-rw-r--r-- | drivers/clk/clk-divider.c | 34 | ||||
-rw-r--r-- | drivers/clk/clk-fixed-rate.c | 40 | ||||
-rw-r--r-- | drivers/clk/clk-gate.c | 34 | ||||
-rw-r--r-- | drivers/clk/clk-mux.c | 10 | ||||
-rw-r--r-- | include/linux/clk-provider.h | 2 |
5 files changed, 64 insertions, 56 deletions
diff --git a/drivers/clk/clk-divider.c b/drivers/clk/clk-divider.c index b1c4b02aaaf1..5fc541d017f1 100644 --- a/drivers/clk/clk-divider.c +++ b/drivers/clk/clk-divider.c | |||
@@ -153,6 +153,18 @@ const struct clk_ops clk_divider_ops = { | |||
153 | }; | 153 | }; |
154 | EXPORT_SYMBOL_GPL(clk_divider_ops); | 154 | EXPORT_SYMBOL_GPL(clk_divider_ops); |
155 | 155 | ||
156 | /** | ||
157 | * clk_register_divider - register a divider clock with the clock framework | ||
158 | * @dev: device registering this clock | ||
159 | * @name: name of this clock | ||
160 | * @parent_name: name of clock's parent | ||
161 | * @flags: framework-specific flags | ||
162 | * @reg: register address to adjust divider | ||
163 | * @shift: number of bits to shift the bitfield | ||
164 | * @width: width of the bitfield | ||
165 | * @clk_divider_flags: divider-specific flags for this clock | ||
166 | * @lock: shared register lock for this clock | ||
167 | */ | ||
156 | struct clk *clk_register_divider(struct device *dev, const char *name, | 168 | struct clk *clk_register_divider(struct device *dev, const char *name, |
157 | const char *parent_name, unsigned long flags, | 169 | const char *parent_name, unsigned long flags, |
158 | void __iomem *reg, u8 shift, u8 width, | 170 | void __iomem *reg, u8 shift, u8 width, |
@@ -161,11 +173,11 @@ struct clk *clk_register_divider(struct device *dev, const char *name, | |||
161 | struct clk_divider *div; | 173 | struct clk_divider *div; |
162 | struct clk *clk; | 174 | struct clk *clk; |
163 | 175 | ||
176 | /* allocate the divider */ | ||
164 | div = kzalloc(sizeof(struct clk_divider), GFP_KERNEL); | 177 | div = kzalloc(sizeof(struct clk_divider), GFP_KERNEL); |
165 | |||
166 | if (!div) { | 178 | if (!div) { |
167 | pr_err("%s: could not allocate divider clk\n", __func__); | 179 | pr_err("%s: could not allocate divider clk\n", __func__); |
168 | return NULL; | 180 | return ERR_PTR(-ENOMEM); |
169 | } | 181 | } |
170 | 182 | ||
171 | /* struct clk_divider assignments */ | 183 | /* struct clk_divider assignments */ |
@@ -175,23 +187,15 @@ struct clk *clk_register_divider(struct device *dev, const char *name, | |||
175 | div->flags = clk_divider_flags; | 187 | div->flags = clk_divider_flags; |
176 | div->lock = lock; | 188 | div->lock = lock; |
177 | 189 | ||
178 | if (parent_name) { | 190 | /* register the clock */ |
179 | div->parent[0] = kstrdup(parent_name, GFP_KERNEL); | ||
180 | if (!div->parent[0]) | ||
181 | goto out; | ||
182 | } | ||
183 | |||
184 | clk = clk_register(dev, name, | 191 | clk = clk_register(dev, name, |
185 | &clk_divider_ops, &div->hw, | 192 | &clk_divider_ops, &div->hw, |
186 | div->parent, | 193 | (parent_name ? &parent_name: NULL), |
187 | (parent_name ? 1 : 0), | 194 | (parent_name ? 1 : 0), |
188 | flags); | 195 | flags); |
189 | if (clk) | ||
190 | return clk; | ||
191 | 196 | ||
192 | out: | 197 | if (IS_ERR(clk)) |
193 | kfree(div->parent[0]); | 198 | kfree(div); |
194 | kfree(div); | ||
195 | 199 | ||
196 | return NULL; | 200 | return clk; |
197 | } | 201 | } |
diff --git a/drivers/clk/clk-fixed-rate.c b/drivers/clk/clk-fixed-rate.c index 027e47704de9..b555a04c8df8 100644 --- a/drivers/clk/clk-fixed-rate.c +++ b/drivers/clk/clk-fixed-rate.c | |||
@@ -38,16 +38,23 @@ const struct clk_ops clk_fixed_rate_ops = { | |||
38 | }; | 38 | }; |
39 | EXPORT_SYMBOL_GPL(clk_fixed_rate_ops); | 39 | EXPORT_SYMBOL_GPL(clk_fixed_rate_ops); |
40 | 40 | ||
41 | /** | ||
42 | * clk_register_fixed_rate - register fixed-rate clock with the clock framework | ||
43 | * @dev: device that is registering this clock | ||
44 | * @name: name of this clock | ||
45 | * @parent_name: name of clock's parent | ||
46 | * @flags: framework-specific flags | ||
47 | * @fixed_rate: non-adjustable clock rate | ||
48 | */ | ||
41 | struct clk *clk_register_fixed_rate(struct device *dev, const char *name, | 49 | struct clk *clk_register_fixed_rate(struct device *dev, const char *name, |
42 | const char *parent_name, unsigned long flags, | 50 | const char *parent_name, unsigned long flags, |
43 | unsigned long fixed_rate) | 51 | unsigned long fixed_rate) |
44 | { | 52 | { |
45 | struct clk_fixed_rate *fixed; | 53 | struct clk_fixed_rate *fixed; |
46 | char **parent_names = NULL; | 54 | struct clk *clk; |
47 | u8 len; | ||
48 | 55 | ||
56 | /* allocate fixed-rate clock */ | ||
49 | fixed = kzalloc(sizeof(struct clk_fixed_rate), GFP_KERNEL); | 57 | fixed = kzalloc(sizeof(struct clk_fixed_rate), GFP_KERNEL); |
50 | |||
51 | if (!fixed) { | 58 | if (!fixed) { |
52 | pr_err("%s: could not allocate fixed clk\n", __func__); | 59 | pr_err("%s: could not allocate fixed clk\n", __func__); |
53 | return ERR_PTR(-ENOMEM); | 60 | return ERR_PTR(-ENOMEM); |
@@ -56,26 +63,15 @@ struct clk *clk_register_fixed_rate(struct device *dev, const char *name, | |||
56 | /* struct clk_fixed_rate assignments */ | 63 | /* struct clk_fixed_rate assignments */ |
57 | fixed->fixed_rate = fixed_rate; | 64 | fixed->fixed_rate = fixed_rate; |
58 | 65 | ||
59 | if (parent_name) { | 66 | /* register the clock */ |
60 | parent_names = kmalloc(sizeof(char *), GFP_KERNEL); | 67 | clk = clk_register(dev, name, |
61 | |||
62 | if (! parent_names) | ||
63 | goto out; | ||
64 | |||
65 | len = sizeof(char) * strlen(parent_name); | ||
66 | |||
67 | parent_names[0] = kmalloc(len, GFP_KERNEL); | ||
68 | |||
69 | if (!parent_names[0]) | ||
70 | goto out; | ||
71 | |||
72 | strncpy(parent_names[0], parent_name, len); | ||
73 | } | ||
74 | |||
75 | out: | ||
76 | return clk_register(dev, name, | ||
77 | &clk_fixed_rate_ops, &fixed->hw, | 68 | &clk_fixed_rate_ops, &fixed->hw, |
78 | parent_names, | 69 | (parent_name ? &parent_name : NULL), |
79 | (parent_name ? 1 : 0), | 70 | (parent_name ? 1 : 0), |
80 | flags); | 71 | flags); |
72 | |||
73 | if (IS_ERR(clk)) | ||
74 | kfree(fixed); | ||
75 | |||
76 | return clk; | ||
81 | } | 77 | } |
diff --git a/drivers/clk/clk-gate.c b/drivers/clk/clk-gate.c index fe2ff9e774c2..42a4b941b6e7 100644 --- a/drivers/clk/clk-gate.c +++ b/drivers/clk/clk-gate.c | |||
@@ -105,6 +105,17 @@ const struct clk_ops clk_gate_ops = { | |||
105 | }; | 105 | }; |
106 | EXPORT_SYMBOL_GPL(clk_gate_ops); | 106 | EXPORT_SYMBOL_GPL(clk_gate_ops); |
107 | 107 | ||
108 | /** | ||
109 | * clk_register_gate - register a gate clock with the clock framework | ||
110 | * @dev: device that is registering this clock | ||
111 | * @name: name of this clock | ||
112 | * @parent_name: name of this clock's parent | ||
113 | * @flags: framework-specific flags for this clock | ||
114 | * @reg: register address to control gating of this clock | ||
115 | * @bit_idx: which bit in the register controls gating of this clock | ||
116 | * @clk_gate_flags: gate-specific flags for this clock | ||
117 | * @lock: shared register lock for this clock | ||
118 | */ | ||
108 | struct clk *clk_register_gate(struct device *dev, const char *name, | 119 | struct clk *clk_register_gate(struct device *dev, const char *name, |
109 | const char *parent_name, unsigned long flags, | 120 | const char *parent_name, unsigned long flags, |
110 | void __iomem *reg, u8 bit_idx, | 121 | void __iomem *reg, u8 bit_idx, |
@@ -113,11 +124,11 @@ struct clk *clk_register_gate(struct device *dev, const char *name, | |||
113 | struct clk_gate *gate; | 124 | struct clk_gate *gate; |
114 | struct clk *clk; | 125 | struct clk *clk; |
115 | 126 | ||
127 | /* allocate the gate */ | ||
116 | gate = kzalloc(sizeof(struct clk_gate), GFP_KERNEL); | 128 | gate = kzalloc(sizeof(struct clk_gate), GFP_KERNEL); |
117 | |||
118 | if (!gate) { | 129 | if (!gate) { |
119 | pr_err("%s: could not allocate gated clk\n", __func__); | 130 | pr_err("%s: could not allocate gated clk\n", __func__); |
120 | return NULL; | 131 | return ERR_PTR(-ENOMEM); |
121 | } | 132 | } |
122 | 133 | ||
123 | /* struct clk_gate assignments */ | 134 | /* struct clk_gate assignments */ |
@@ -126,22 +137,15 @@ struct clk *clk_register_gate(struct device *dev, const char *name, | |||
126 | gate->flags = clk_gate_flags; | 137 | gate->flags = clk_gate_flags; |
127 | gate->lock = lock; | 138 | gate->lock = lock; |
128 | 139 | ||
129 | if (parent_name) { | 140 | /* register the clock */ |
130 | gate->parent[0] = kstrdup(parent_name, GFP_KERNEL); | ||
131 | if (!gate->parent[0]) | ||
132 | goto out; | ||
133 | } | ||
134 | |||
135 | clk = clk_register(dev, name, | 141 | clk = clk_register(dev, name, |
136 | &clk_gate_ops, &gate->hw, | 142 | &clk_gate_ops, &gate->hw, |
137 | gate->parent, | 143 | (parent_name ? &parent_name : NULL), |
138 | (parent_name ? 1 : 0), | 144 | (parent_name ? 1 : 0), |
139 | flags); | 145 | flags); |
140 | if (clk) | ||
141 | return clk; | ||
142 | out: | ||
143 | kfree(gate->parent[0]); | ||
144 | kfree(gate); | ||
145 | 146 | ||
146 | return NULL; | 147 | if (IS_ERR(clk)) |
148 | kfree(gate); | ||
149 | |||
150 | return clk; | ||
147 | } | 151 | } |
diff --git a/drivers/clk/clk-mux.c b/drivers/clk/clk-mux.c index bd5e598b9f1e..6e58f11ab81f 100644 --- a/drivers/clk/clk-mux.c +++ b/drivers/clk/clk-mux.c | |||
@@ -94,9 +94,10 @@ struct clk *clk_register_mux(struct device *dev, const char *name, | |||
94 | u8 clk_mux_flags, spinlock_t *lock) | 94 | u8 clk_mux_flags, spinlock_t *lock) |
95 | { | 95 | { |
96 | struct clk_mux *mux; | 96 | struct clk_mux *mux; |
97 | struct clk *clk; | ||
97 | 98 | ||
99 | /* allocate the mux */ | ||
98 | mux = kzalloc(sizeof(struct clk_mux), GFP_KERNEL); | 100 | mux = kzalloc(sizeof(struct clk_mux), GFP_KERNEL); |
99 | |||
100 | if (!mux) { | 101 | if (!mux) { |
101 | pr_err("%s: could not allocate mux clk\n", __func__); | 102 | pr_err("%s: could not allocate mux clk\n", __func__); |
102 | return ERR_PTR(-ENOMEM); | 103 | return ERR_PTR(-ENOMEM); |
@@ -109,6 +110,11 @@ struct clk *clk_register_mux(struct device *dev, const char *name, | |||
109 | mux->flags = clk_mux_flags; | 110 | mux->flags = clk_mux_flags; |
110 | mux->lock = lock; | 111 | mux->lock = lock; |
111 | 112 | ||
112 | return clk_register(dev, name, &clk_mux_ops, &mux->hw, | 113 | clk = clk_register(dev, name, &clk_mux_ops, &mux->hw, |
113 | parent_names, num_parents, flags); | 114 | parent_names, num_parents, flags); |
115 | |||
116 | if (IS_ERR(clk)) | ||
117 | kfree(mux); | ||
118 | |||
119 | return clk; | ||
114 | } | 120 | } |
diff --git a/include/linux/clk-provider.h b/include/linux/clk-provider.h index 97f9fabf3be2..3323d24a7be4 100644 --- a/include/linux/clk-provider.h +++ b/include/linux/clk-provider.h | |||
@@ -176,7 +176,6 @@ struct clk_gate { | |||
176 | u8 bit_idx; | 176 | u8 bit_idx; |
177 | u8 flags; | 177 | u8 flags; |
178 | spinlock_t *lock; | 178 | spinlock_t *lock; |
179 | const char *parent[1]; | ||
180 | }; | 179 | }; |
181 | 180 | ||
182 | #define CLK_GATE_SET_TO_DISABLE BIT(0) | 181 | #define CLK_GATE_SET_TO_DISABLE BIT(0) |
@@ -214,7 +213,6 @@ struct clk_divider { | |||
214 | u8 width; | 213 | u8 width; |
215 | u8 flags; | 214 | u8 flags; |
216 | spinlock_t *lock; | 215 | spinlock_t *lock; |
217 | const char *parent[1]; | ||
218 | }; | 216 | }; |
219 | 217 | ||
220 | #define CLK_DIVIDER_ONE_BASED BIT(0) | 218 | #define CLK_DIVIDER_ONE_BASED BIT(0) |