summaryrefslogtreecommitdiffstats
path: root/drivers/clk/clkdev.c
diff options
context:
space:
mode:
authorTomeu Vizoso <tomeu.vizoso@collabora.com>2015-01-23 12:03:30 +0100
committerMichael Turquette <mturquette@linaro.org>2015-02-02 14:22:19 -0800
commit035a61c314eb3dab5bcc5683afaf4d412689858a (patch)
tree3c325fc76191cf1319c4a3399dfdd9f777033d6d /drivers/clk/clkdev.c
parentaf0f349b2996f9f3d83e5aac1edf58fff727a0e0 (diff)
downloadlinux-035a61c314eb3dab5bcc5683afaf4d412689858a.tar.bz2
clk: Make clk API return per-user struct clk instances
Moves clock state to struct clk_core, but takes care to change as little API as possible. struct clk_hw still has a pointer to a struct clk, which is the implementation's per-user clk instance, for backwards compatibility. The struct clk that clk_get_parent() returns isn't owned by the caller, but by the clock implementation, so the former shouldn't call clk_put() on it. Because some boards in mach-omap2 still register clocks statically, their clock registration had to be updated to take into account that the clock information is stored in struct clk_core now. Signed-off-by: Tomeu Vizoso <tomeu.vizoso@collabora.com> Reviewed-by: Stephen Boyd <sboyd@codeaurora.org> Tested-by: Tony Lindgren <tony@atomide.com> Signed-off-by: Michael Turquette <mturquette@linaro.org> [mturquette@linaro.org: adapted clk_has_parent to struct clk_core applied OMAP3+ DPLL fix from Tero & Tony]
Diffstat (limited to 'drivers/clk/clkdev.c')
-rw-r--r--drivers/clk/clkdev.c84
1 files changed, 65 insertions, 19 deletions
diff --git a/drivers/clk/clkdev.c b/drivers/clk/clkdev.c
index da4bda8b7fc7..901d242f38ea 100644
--- a/drivers/clk/clkdev.c
+++ b/drivers/clk/clkdev.c
@@ -19,6 +19,7 @@
#include <linux/mutex.h>
#include <linux/clk.h>
#include <linux/clkdev.h>
+#include <linux/clk-provider.h>
#include <linux/of.h>
#include "clk.h"
@@ -53,7 +54,7 @@ struct clk *of_clk_get_by_clkspec(struct of_phandle_args *clkspec)
return clk;
}
-struct clk *of_clk_get(struct device_node *np, int index)
+static struct clk *__of_clk_get(struct device_node *np, int index)
{
struct of_phandle_args clkspec;
struct clk *clk;
@@ -69,20 +70,24 @@ struct clk *of_clk_get(struct device_node *np, int index)
clk = of_clk_get_by_clkspec(&clkspec);
of_node_put(clkspec.np);
+
+ return clk;
+}
+
+struct clk *of_clk_get(struct device_node *np, int index)
+{
+ struct clk *clk = __of_clk_get(np, index);
+
+ if (!IS_ERR(clk))
+ clk = __clk_create_clk(__clk_get_hw(clk), np->full_name, NULL);
+
return clk;
}
EXPORT_SYMBOL(of_clk_get);
-/**
- * of_clk_get_by_name() - Parse and lookup a clock referenced by a device node
- * @np: pointer to clock consumer node
- * @name: name of consumer's clock input, or NULL for the first clock reference
- *
- * This function parses the clocks and clock-names properties,
- * and uses them to look up the struct clk from the registered list of clock
- * providers.
- */
-struct clk *of_clk_get_by_name(struct device_node *np, const char *name)
+static struct clk *__of_clk_get_by_name(struct device_node *np,
+ const char *dev_id,
+ const char *name)
{
struct clk *clk = ERR_PTR(-ENOENT);
@@ -97,9 +102,11 @@ struct clk *of_clk_get_by_name(struct device_node *np, const char *name)
*/
if (name)
index = of_property_match_string(np, "clock-names", name);
- clk = of_clk_get(np, index);
- if (!IS_ERR(clk))
+ clk = __of_clk_get(np, index);
+ if (!IS_ERR(clk)) {
+ clk = __clk_create_clk(__clk_get_hw(clk), dev_id, name);
break;
+ }
else if (name && index >= 0) {
if (PTR_ERR(clk) != -EPROBE_DEFER)
pr_err("ERROR: could not get clock %s:%s(%i)\n",
@@ -119,7 +126,33 @@ struct clk *of_clk_get_by_name(struct device_node *np, const char *name)
return clk;
}
+
+/**
+ * of_clk_get_by_name() - Parse and lookup a clock referenced by a device node
+ * @np: pointer to clock consumer node
+ * @name: name of consumer's clock input, or NULL for the first clock reference
+ *
+ * This function parses the clocks and clock-names properties,
+ * and uses them to look up the struct clk from the registered list of clock
+ * providers.
+ */
+struct clk *of_clk_get_by_name(struct device_node *np, const char *name)
+{
+ if (!np)
+ return ERR_PTR(-ENOENT);
+
+ return __of_clk_get_by_name(np, np->full_name, name);
+}
EXPORT_SYMBOL(of_clk_get_by_name);
+
+#else /* defined(CONFIG_OF) && defined(CONFIG_COMMON_CLK) */
+
+static struct clk *__of_clk_get_by_name(struct device_node *np,
+ const char *dev_id,
+ const char *name)
+{
+ return ERR_PTR(-ENOENT);
+}
#endif
/*
@@ -168,14 +201,29 @@ static struct clk_lookup *clk_find(const char *dev_id, const char *con_id)
struct clk *clk_get_sys(const char *dev_id, const char *con_id)
{
struct clk_lookup *cl;
+ struct clk *clk = NULL;
mutex_lock(&clocks_mutex);
+
cl = clk_find(dev_id, con_id);
- if (cl && !__clk_get(cl->clk))
+ if (!cl)
+ goto out;
+
+ if (!__clk_get(cl->clk)) {
cl = NULL;
+ goto out;
+ }
+
+#if defined(CONFIG_COMMON_CLK)
+ clk = __clk_create_clk(__clk_get_hw(cl->clk), dev_id, con_id);
+#else
+ clk = cl->clk;
+#endif
+
+out:
mutex_unlock(&clocks_mutex);
- return cl ? cl->clk : ERR_PTR(-ENOENT);
+ return cl ? clk : ERR_PTR(-ENOENT);
}
EXPORT_SYMBOL(clk_get_sys);
@@ -185,10 +233,8 @@ struct clk *clk_get(struct device *dev, const char *con_id)
struct clk *clk;
if (dev) {
- clk = of_clk_get_by_name(dev->of_node, con_id);
- if (!IS_ERR(clk))
- return clk;
- if (PTR_ERR(clk) == -EPROBE_DEFER)
+ clk = __of_clk_get_by_name(dev->of_node, dev_id, con_id);
+ if (!IS_ERR(clk) || PTR_ERR(clk) == -EPROBE_DEFER)
return clk;
}