#include <linux/device.h>
#include <linux/of.h>
#include <linux/printk.h>
+#include "clk.h"
static int __set_clk_parents(struct device_node *node, bool clk_supplier)
{
}
if (clkspec.np == node && !clk_supplier)
return 0;
- pclk = of_clk_get_from_provider(&clkspec);
+ pclk = of_clk_get_from_provider_with_orphans(&clkspec);
if (IS_ERR(pclk)) {
pr_warn("clk: couldn't get parent clock %d for %s\n",
index, node->full_name);
rc = 0;
goto err;
}
- clk = of_clk_get_from_provider(&clkspec);
+ clk = of_clk_get_from_provider_with_orphans(&clkspec);
if (IS_ERR(clk)) {
pr_warn("clk: couldn't get parent clock %d for %s\n",
index, node->full_name);
return ret;
}
-struct clk *__clk_create_clk(struct clk_hw *hw, const char *dev_id,
- const char *con_id)
+static struct clk *clk_hw_create_clk(struct clk_hw *hw, const char *dev_id,
+ const char *con_id)
{
struct clk *clk;
- /* This is to allow this function to be chained to others */
- if (!hw || IS_ERR(hw))
- return (struct clk *) hw;
-
clk = kzalloc(sizeof(*clk), GFP_KERNEL);
if (!clk)
return ERR_PTR(-ENOMEM);
return clk;
}
+struct clk *__clk_create_clk(struct clk_hw *hw, const char *dev_id,
+ const char *con_id, bool with_orphans)
+{
+ /* This is to allow this function to be chained to others */
+ if (!hw || IS_ERR(hw))
+ return (struct clk *) hw;
+
+ if (hw->core->orphan && !with_orphans)
+ return ERR_PTR(-EPROBE_DEFER);
+
+ return clk_hw_create_clk(hw, dev_id, con_id);
+}
+
void __clk_free_clk(struct clk *clk)
{
clk_prepare_lock();
INIT_HLIST_HEAD(&core->clks);
- hw->clk = __clk_create_clk(hw, NULL, NULL);
+ hw->clk = clk_hw_create_clk(hw, NULL, NULL);
if (IS_ERR(hw->clk)) {
ret = PTR_ERR(hw->clk);
goto fail_parent_names_copy;
EXPORT_SYMBOL_GPL(of_clk_del_provider);
struct clk *__of_clk_get_from_provider(struct of_phandle_args *clkspec,
- const char *dev_id, const char *con_id)
+ const char *dev_id, const char *con_id,
+ bool with_orphans)
{
struct of_clk_provider *provider;
struct clk *clk = ERR_PTR(-EPROBE_DEFER);
clk = provider->get(clkspec, provider->data);
if (!IS_ERR(clk)) {
clk = __clk_create_clk(__clk_get_hw(clk), dev_id,
- con_id);
+ con_id, with_orphans);
if (!IS_ERR(clk) && !__clk_get(clk)) {
__clk_free_clk(clk);
*/
struct clk *of_clk_get_from_provider(struct of_phandle_args *clkspec)
{
- return __of_clk_get_from_provider(clkspec, NULL, __func__);
+ return __of_clk_get_from_provider(clkspec, NULL, __func__, false);
+}
+
+/**
+ * of_clk_get_from_provider_with_orphans() - Lookup clock from a clock provider
+ * @clkspec: pointer to a clock specifier data structure
+ *
+ * This function looks up a struct clk from the registered list of clock
+ * providers, an input is a clock specifier data structure as returned
+ * from the of_parse_phandle_with_args() function call.
+ *
+ * The difference to of_clk_get_from_provider() is that this function will
+ * also successfully lookup orphan-clocks, as it in some cases may be
+ * necessary to access such orphan-clocks as well.
+ */
+struct clk *
+of_clk_get_from_provider_with_orphans(struct of_phandle_args *clkspec)
+{
+ return __of_clk_get_from_provider(clkspec, NULL, __func__, true);
}
int of_clk_get_parent_count(struct device_node *np)
#if defined(CONFIG_OF) && defined(CONFIG_COMMON_CLK)
struct clk *__of_clk_get_from_provider(struct of_phandle_args *clkspec,
- const char *dev_id, const char *con_id);
+ const char *dev_id, const char *con_id,
+ bool with_orphans);
+struct clk *
+of_clk_get_from_provider_with_orphans(struct of_phandle_args *clkspec);
#endif
#ifdef CONFIG_COMMON_CLK
struct clk *__clk_create_clk(struct clk_hw *hw, const char *dev_id,
- const char *con_id);
+ const char *con_id, bool with_orphans);
void __clk_free_clk(struct clk *clk);
#else
/* All these casts to avoid ifdefs in clkdev... */
static inline struct clk *
-__clk_create_clk(struct clk_hw *hw, const char *dev_id, const char *con_id)
+__clk_create_clk(struct clk_hw *hw, const char *dev_id, const char *con_id,
+ bool with_orphans)
{
return (struct clk *)hw;
}