aboutsummaryrefslogtreecommitdiffstats
path: root/arch/avr32/mach-at32ap/clock.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/avr32/mach-at32ap/clock.c')
-rw-r--r--arch/avr32/mach-at32ap/clock.c52
1 files changed, 40 insertions, 12 deletions
diff --git a/arch/avr32/mach-at32ap/clock.c b/arch/avr32/mach-at32ap/clock.c
index 6c27ddac5adf..138a00a2a2d0 100644
--- a/arch/avr32/mach-at32ap/clock.c
+++ b/arch/avr32/mach-at32ap/clock.c
@@ -15,24 +15,40 @@
15#include <linux/err.h> 15#include <linux/err.h>
16#include <linux/device.h> 16#include <linux/device.h>
17#include <linux/string.h> 17#include <linux/string.h>
18#include <linux/list.h>
18 19
19#include <mach/chip.h> 20#include <mach/chip.h>
20 21
21#include "clock.h" 22#include "clock.h"
22 23
24/* at32 clock list */
25static LIST_HEAD(at32_clock_list);
26
23static DEFINE_SPINLOCK(clk_lock); 27static DEFINE_SPINLOCK(clk_lock);
28static DEFINE_SPINLOCK(clk_list_lock);
29
30void at32_clk_register(struct clk *clk)
31{
32 spin_lock(&clk_list_lock);
33 /* add the new item to the end of the list */
34 list_add_tail(&clk->list, &at32_clock_list);
35 spin_unlock(&clk_list_lock);
36}
24 37
25struct clk *clk_get(struct device *dev, const char *id) 38struct clk *clk_get(struct device *dev, const char *id)
26{ 39{
27 int i; 40 struct clk *clk;
28 41
29 for (i = 0; i < at32_nr_clocks; i++) { 42 spin_lock(&clk_list_lock);
30 struct clk *clk = at32_clock_list[i];
31 43
32 if (clk->dev == dev && strcmp(id, clk->name) == 0) 44 list_for_each_entry(clk, &at32_clock_list, list) {
45 if (clk->dev == dev && strcmp(id, clk->name) == 0) {
46 spin_unlock(&clk_list_lock);
33 return clk; 47 return clk;
48 }
34 } 49 }
35 50
51 spin_unlock(&clk_list_lock);
36 return ERR_PTR(-ENOENT); 52 return ERR_PTR(-ENOENT);
37} 53}
38EXPORT_SYMBOL(clk_get); 54EXPORT_SYMBOL(clk_get);
@@ -203,8 +219,8 @@ dump_clock(struct clk *parent, struct clkinf *r)
203 219
204 /* cost of this scan is small, but not linear... */ 220 /* cost of this scan is small, but not linear... */
205 r->nest = nest + NEST_DELTA; 221 r->nest = nest + NEST_DELTA;
206 for (i = 3; i < at32_nr_clocks; i++) { 222
207 clk = at32_clock_list[i]; 223 list_for_each_entry(clk, &at32_clock_list, list) {
208 if (clk->parent == parent) 224 if (clk->parent == parent)
209 dump_clock(clk, r); 225 dump_clock(clk, r);
210 } 226 }
@@ -215,6 +231,7 @@ static int clk_show(struct seq_file *s, void *unused)
215{ 231{
216 struct clkinf r; 232 struct clkinf r;
217 int i; 233 int i;
234 struct clk *clk;
218 235
219 /* show all the power manager registers */ 236 /* show all the power manager registers */
220 seq_printf(s, "MCCTRL = %8x\n", pm_readl(MCCTRL)); 237 seq_printf(s, "MCCTRL = %8x\n", pm_readl(MCCTRL));
@@ -234,14 +251,25 @@ static int clk_show(struct seq_file *s, void *unused)
234 251
235 seq_printf(s, "\n"); 252 seq_printf(s, "\n");
236 253
237 /* show clock tree as derived from the three oscillators
238 * we "know" are at the head of the list
239 */
240 r.s = s; 254 r.s = s;
241 r.nest = 0; 255 r.nest = 0;
242 dump_clock(at32_clock_list[0], &r); 256 /* protected from changes on the list while dumping */
243 dump_clock(at32_clock_list[1], &r); 257 spin_lock(&clk_list_lock);
244 dump_clock(at32_clock_list[2], &r); 258
259 /* show clock tree as derived from the three oscillators */
260 clk = clk_get(NULL, "osc32k");
261 dump_clock(clk, &r);
262 clk_put(clk);
263
264 clk = clk_get(NULL, "osc0");
265 dump_clock(clk, &r);
266 clk_put(clk);
267
268 clk = clk_get(NULL, "osc1");
269 dump_clock(clk, &r);
270 clk_put(clk);
271
272 spin_unlock(&clk_list_lock);
245 273
246 return 0; 274 return 0;
247} 275}