diff options
author | Paul Mundt <lethal@linux-sh.org> | 2009-05-11 17:18:09 -0400 |
---|---|---|
committer | Paul Mundt <lethal@linux-sh.org> | 2009-05-11 17:18:09 -0400 |
commit | 0dae89572cbcd5f676ea52a9448d9639d97a53d6 (patch) | |
tree | 5da5cbf7b044052ccc621d6b17276e4713bf04d1 | |
parent | 007e8363b656768fe3f59c180824ff704680bb25 (diff) |
sh: clkfwk: Wire up clk_get_sys() support.
This stubs in clk_get_sys() from the ARM clkdev implementation.
Tentatively conver the clk_get() lookup code to use this, and once the
rest of the in-tree users are happy with this, it can replace the
fallback lookups.
Signed-off-by: Paul Mundt <lethal@linux-sh.org>
-rw-r--r-- | arch/sh/include/asm/clock.h | 7 | ||||
-rw-r--r-- | arch/sh/kernel/cpu/clock.c | 59 |
2 files changed, 66 insertions, 0 deletions
diff --git a/arch/sh/include/asm/clock.h b/arch/sh/include/asm/clock.h index 6a2f46333376..e2f5bf1b4a9c 100644 --- a/arch/sh/include/asm/clock.h +++ b/arch/sh/include/asm/clock.h | |||
@@ -37,6 +37,13 @@ struct clk { | |||
37 | unsigned long arch_flags; | 37 | unsigned long arch_flags; |
38 | }; | 38 | }; |
39 | 39 | ||
40 | struct clk_lookup { | ||
41 | struct list_head node; | ||
42 | const char *dev_id; | ||
43 | const char *con_id; | ||
44 | struct clk *clk; | ||
45 | }; | ||
46 | |||
40 | #define CLK_ENABLE_ON_INIT (1 << 0) | 47 | #define CLK_ENABLE_ON_INIT (1 << 0) |
41 | 48 | ||
42 | /* Should be defined by processor-specific code */ | 49 | /* Should be defined by processor-specific code */ |
diff --git a/arch/sh/kernel/cpu/clock.c b/arch/sh/kernel/cpu/clock.c index 7a356de99d7d..34707b867760 100644 --- a/arch/sh/kernel/cpu/clock.c +++ b/arch/sh/kernel/cpu/clock.c | |||
@@ -10,6 +10,10 @@ | |||
10 | * | 10 | * |
11 | * Modified for omap shared clock framework by Tony Lindgren <tony@atomide.com> | 11 | * Modified for omap shared clock framework by Tony Lindgren <tony@atomide.com> |
12 | * | 12 | * |
13 | * With clkdev bits: | ||
14 | * | ||
15 | * Copyright (C) 2008 Russell King. | ||
16 | * | ||
13 | * This file is subject to the terms and conditions of the GNU General Public | 17 | * This file is subject to the terms and conditions of the GNU General Public |
14 | * License. See the file "COPYING" in the main directory of this archive | 18 | * License. See the file "COPYING" in the main directory of this archive |
15 | * for more details. | 19 | * for more details. |
@@ -335,14 +339,69 @@ long clk_round_rate(struct clk *clk, unsigned long rate) | |||
335 | EXPORT_SYMBOL_GPL(clk_round_rate); | 339 | EXPORT_SYMBOL_GPL(clk_round_rate); |
336 | 340 | ||
337 | /* | 341 | /* |
342 | * Find the correct struct clk for the device and connection ID. | ||
343 | * We do slightly fuzzy matching here: | ||
344 | * An entry with a NULL ID is assumed to be a wildcard. | ||
345 | * If an entry has a device ID, it must match | ||
346 | * If an entry has a connection ID, it must match | ||
347 | * Then we take the most specific entry - with the following | ||
348 | * order of precidence: dev+con > dev only > con only. | ||
349 | */ | ||
350 | static struct clk *clk_find(const char *dev_id, const char *con_id) | ||
351 | { | ||
352 | struct clk_lookup *p; | ||
353 | struct clk *clk = NULL; | ||
354 | int match, best = 0; | ||
355 | |||
356 | list_for_each_entry(p, &clock_list, node) { | ||
357 | match = 0; | ||
358 | if (p->dev_id) { | ||
359 | if (!dev_id || strcmp(p->dev_id, dev_id)) | ||
360 | continue; | ||
361 | match += 2; | ||
362 | } | ||
363 | if (p->con_id) { | ||
364 | if (!con_id || strcmp(p->con_id, con_id)) | ||
365 | continue; | ||
366 | match += 1; | ||
367 | } | ||
368 | if (match == 0) | ||
369 | continue; | ||
370 | |||
371 | if (match > best) { | ||
372 | clk = p->clk; | ||
373 | best = match; | ||
374 | } | ||
375 | } | ||
376 | return clk; | ||
377 | } | ||
378 | |||
379 | struct clk *clk_get_sys(const char *dev_id, const char *con_id) | ||
380 | { | ||
381 | struct clk *clk; | ||
382 | |||
383 | mutex_lock(&clock_list_sem); | ||
384 | clk = clk_find(dev_id, con_id); | ||
385 | mutex_unlock(&clock_list_sem); | ||
386 | |||
387 | return clk ? clk : ERR_PTR(-ENOENT); | ||
388 | } | ||
389 | EXPORT_SYMBOL_GPL(clk_get_sys); | ||
390 | |||
391 | /* | ||
338 | * Returns a clock. Note that we first try to use device id on the bus | 392 | * Returns a clock. Note that we first try to use device id on the bus |
339 | * and clock name. If this fails, we try to use clock name only. | 393 | * and clock name. If this fails, we try to use clock name only. |
340 | */ | 394 | */ |
341 | struct clk *clk_get(struct device *dev, const char *id) | 395 | struct clk *clk_get(struct device *dev, const char *id) |
342 | { | 396 | { |
397 | const char *dev_id = dev ? dev_name(dev) : NULL; | ||
343 | struct clk *p, *clk = ERR_PTR(-ENOENT); | 398 | struct clk *p, *clk = ERR_PTR(-ENOENT); |
344 | int idno; | 399 | int idno; |
345 | 400 | ||
401 | clk = clk_get_sys(dev_id, id); | ||
402 | if (clk) | ||
403 | return clk; | ||
404 | |||
346 | if (dev == NULL || dev->bus != &platform_bus_type) | 405 | if (dev == NULL || dev->bus != &platform_bus_type) |
347 | idno = -1; | 406 | idno = -1; |
348 | else | 407 | else |