From: Felipe Balbi <[EMAIL PROTECTED]>
Introduce a new mechanism to omap's clk implementation to
associate consumer device(s) with its clock during
platform_device registration.
With this mechanism we can also be sure drivers won't be able
to clk_get the wrong clk (only true when we move all drivers
to this new mechanism and drop the old ones).
Signed-off-by: Felipe Balbi <[EMAIL PROTECTED]>
---
arch/arm/plat-omap/clock.c | 47 ++++++++++++++++++++++++++++--
arch/arm/plat-omap/include/mach/clock.h | 4 ++
2 files changed, 47 insertions(+), 4 deletions(-)
diff --git a/arch/arm/plat-omap/clock.c b/arch/arm/plat-omap/clock.c
index 5178701..083a3ff 100644
--- a/arch/arm/plat-omap/clock.c
+++ b/arch/arm/plat-omap/clock.c
@@ -44,6 +44,7 @@ static struct clk_functions *arch_clock;
struct clk * clk_get(struct device *dev, const char *id)
{
struct clk *p, *clk = ERR_PTR(-ENOENT);
+ struct device *d;
int idno;
if (dev == NULL || dev->bus != &platform_bus_type)
@@ -54,27 +55,65 @@ struct clk * clk_get(struct device *dev, const char *id)
mutex_lock(&clocks_mutex);
list_for_each_entry(p, &clocks, node) {
+ list_for_each_entry(d, &p->consumers, node) {
+ if (dev == d) {
+ clk = p;
+ break;
+ }
+ }
+
if (p->id == idno &&
strcmp(id, p->name) == 0 && try_module_get(p->owner)) {
clk = p;
- goto found;
+ break;
}
- }
- list_for_each_entry(p, &clocks, node) {
if (strcmp(id, p->name) == 0 && try_module_get(p->owner)) {
clk = p;
break;
}
}
-found:
mutex_unlock(&clocks_mutex);
return clk;
}
EXPORT_SYMBOL(clk_get);
+/**
+ * omap_clk_associate - associates a clock to its consumer device(s)
+ * @id: clock id as defined in arch/arm/mach-omapX/clkxxxx.h
+ * @dev: device pointer for the clock consumer
+ *
+ * This function attempts to simplify clock handling for device drivers
+ * by letting struct clk know which device is the correct consumer for
+ * that clock. By making this trick, we let drivers get the correct
+ * clock without knowing about different clock names between omap
+ * versions.
+ */
+void __init omap_clk_associate(const char *id, struct device *dev)
+{
+ struct clk *clk = clk_get(NULL, id);
+
+ if (!clk || IS_ERR(clk)) {
+ pr_debug("%s: unable to get clock\n", __func__);
+ return;
+ }
+
+ if (!dev) {
+ pr_debug("%s: missing device to associate with\n", __func__);
+ clk_put(clk);
+ return;
+ }
+
+ if (list_empty(&clk->consumers))
+ INIT_LIST_HEAD(&clk->consumers);
+
+ /* add device to consumer list */
+ list_add(&dev->node, &clk->consumers);
+ clk_put(clk);
+};
+
int clk_enable(struct clk *clk)
{
unsigned long flags;
diff --git a/arch/arm/plat-omap/include/mach/clock.h
b/arch/arm/plat-omap/include/mach/clock.h
index 9088925..1600a14 100644
--- a/arch/arm/plat-omap/include/mach/clock.h
+++ b/arch/arm/plat-omap/include/mach/clock.h
@@ -13,6 +13,8 @@
#ifndef __ARCH_ARM_OMAP_CLOCK_H
#define __ARCH_ARM_OMAP_CLOCK_H
+#include <linux/device.h>
+
struct module;
struct clk;
struct clockdomain;
@@ -61,6 +63,7 @@ struct dpll_data {
struct clk {
struct list_head node;
+ struct list_head consumers;
struct module *owner;
const char *name;
int id;
@@ -116,6 +119,7 @@ struct clk_functions {
extern unsigned int mpurate;
+extern void omap_clk_associate(const char *id, struct device *dev);
extern int clk_init(struct clk_functions *custom_clocks);
extern int clk_register(struct clk *clk);
extern void clk_unregister(struct clk *clk);
--
1.6.0.2.307.gc427
--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at http://vger.kernel.org/majordomo-info.html