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

Reply via email to