[PATCH 1/3] clk: introduce omap_clk_associate

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



From: Felipe Balbi <felipe.balbi@xxxxxxxxx>

Introduce a new mechanism to omap's clk implementation to
associate the device with its clock during platform_device
registration. Also gives the clock a function name (like
mmc_fck, uart_fck, ehci_fck, etc) so drivers won't have to
care about clk names any longer.

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).

Clk's function names will be defined as they come necessary
but let's try to keep it as simple as possible.

Signed-off-by: Felipe Balbi <felipe.balbi@xxxxxxxxx>
---
 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 majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Linux Arm (vger)]     [ARM Kernel]     [ARM MSM]     [Linux Tegra]     [Linux WPAN Networking]     [Linux Wireless Networking]     [Maemo Users]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite Trails]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux