clk-uclass.c contains all of the UCLASS_CLK specific code but it also
contains common clk functionality which is generic between UCLASS_CLK
and CCF.

Split this functionality out so that we can reuse it with CCF and avoid
building clk-uclass.c entirely.

Signed-off-by: Casey Connolly <[email protected]>
---
 drivers/clk/Makefile         |   8 +-
 drivers/clk/clk-common.c     | 220 +++++++++++++++++++++++++++++++++++++++++++
 drivers/clk/clk-common.h     |  45 +++++++++
 drivers/clk/clk-uclass.c     | 175 ++--------------------------------
 include/linux/clk-provider.h |   3 +
 5 files changed, 278 insertions(+), 173 deletions(-)

diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile
index dd71d005aada..ee06bffaef72 100644
--- a/drivers/clk/Makefile
+++ b/drivers/clk/Makefile
@@ -4,19 +4,19 @@
 # Wolfgang Denk, DENX Software Engineering, [email protected].
 #
 
 obj-$(CONFIG_$(PHASE_)CLK) += clk-uclass.o
+obj-$(CONFIG_$(PHASE_)CLK) += clk-common.o
 obj-$(CONFIG_$(PHASE_)CLK_GPIO) += clk-gpio.o
 obj-$(CONFIG_$(PHASE_)CLK_STUB) += clk-stub.o
 
 # Full Linux CCF support
-obj-$(CONFIG_$(PHASE_)CLK_CCF_FULL) += ccf/
-
+ifdef CONFIG_CLK_CCF_FULL
+obj-y += ccf/
+else
 # U-Boot basic fixed clocks, full CCF has a
 # different and incompatible implementation
-ifndef CONFIG_CLK_CCF_FULL
 obj-y += basic/
-
 # U-Boot/IMX "micro" CCF port
 obj-$(CONFIG_$(PHASE_)CLK_CCF) += uccf/
 endif
 
diff --git a/drivers/clk/clk-common.c b/drivers/clk/clk-common.c
new file mode 100644
index 000000000000..7f30ad496da2
--- /dev/null
+++ b/drivers/clk/clk-common.c
@@ -0,0 +1,220 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2015 Google, Inc
+ * Written by Simon Glass <[email protected]>
+ * Copyright (c) 2016, NVIDIA CORPORATION.
+ * Copyright (c) 2018, Theobroma Systems Design und Consulting GmbH
+ *
+ * Common clock support code shared between CCF_FULL and UCLASS_CLK
+ */
+
+#include <clk.h>
+#include <clk-uclass.h>
+#include <dm.h>
+#include <dt-structs.h>
+#include <log.h>
+#include <malloc.h>
+#include <asm/global_data.h>
+#include <dm/device_compat.h>
+#include <dm/device-internal.h>
+#include <dm/devres.h>
+#include <dm/read.h>
+#include <linux/bug.h>
+#include <linux/clk-provider.h>
+#include <linux/err.h>
+
+#include "clk-common.h"
+
+#if CONFIG_IS_ENABLED(OF_REAL)
+int clk_get_by_index(struct udevice *dev, int index, struct clk *clk)
+{
+       return clk_get_by_index_nodev(dev_ofnode(dev), index, clk);
+}
+
+int clk_get_by_index_nodev(ofnode node, int index, struct clk *clk)
+{
+       struct ofnode_phandle_args args;
+       int ret;
+
+       ret = ofnode_parse_phandle_with_args(node, "clocks", "#clock-cells", 0,
+                                            index, &args);
+
+       return clk_get_by_index_tail(ret, node, &args, "clocks",
+                                    index, clk);
+}
+
+int clk_get_bulk(struct udevice *dev, struct clk_bulk *bulk)
+{
+       int i, ret, err, count;
+
+       bulk->count = 0;
+
+       count = dev_count_phandle_with_args(dev, "clocks", "#clock-cells", 0);
+       if (count < 1)
+               return count;
+
+       bulk->clks = devm_kcalloc(dev, count, sizeof(struct clk), GFP_KERNEL);
+       if (!bulk->clks)
+               return -ENOMEM;
+
+       for (i = 0; i < count; i++) {
+               ret = clk_get_by_index(dev, i, &bulk->clks[i]);
+               if (ret < 0)
+                       goto bulk_get_err;
+
+               ++bulk->count;
+       }
+
+       return 0;
+
+bulk_get_err:
+       err = clk_release_all(bulk->clks, bulk->count);
+       if (err)
+               debug("%s: could not release all clocks for %s\n",
+                     __func__, dev_read_name(dev));
+
+       return ret;
+}
+
+int clk_get_by_name(struct udevice *dev, const char *name, struct clk *clk)
+{
+       return clk_get_by_name_nodev(dev_ofnode(dev), name, clk);
+}
+#endif /* OF_REAL */
+
+int clk_get_by_name_nodev(ofnode node, const char *name, struct clk *clk)
+{
+       int index = 0;
+
+       debug("%s(node=%s, name=%s, clk=%p)\n", __func__,
+               ofnode_get_name(node), name, clk);
+       clk->dev = NULL;
+
+       if (name) {
+               index = ofnode_stringlist_search(node, "clock-names", name);
+               if (index < 0) {
+                       debug("fdt_stringlist_search() failed: %d\n", index);
+                       return index;
+               }
+       }
+
+       return clk_get_by_index_nodev(node, index, clk);
+}
+
+int clk_release_all(struct clk *clk, unsigned int count)
+{
+       unsigned int i;
+       int ret;
+
+       for (i = 0; i < count; i++) {
+               debug("%s(clk[%u]=%p)\n", __func__, i, &clk[i]);
+
+               /* check if clock has been previously requested */
+               if (!clk[i].dev)
+                       continue;
+
+               ret = clk_disable(&clk[i]);
+               if (ret && ret != -ENOSYS)
+                       return ret;
+       }
+
+       return 0;
+}
+
+
+int clk_set_defaults(struct udevice *dev, enum clk_defaults_stage stage)
+{
+       int ret;
+
+       if (!dev_has_ofnode(dev))
+               return 0;
+
+       /*
+        * To avoid setting defaults twice, don't set them before relocation.
+        * However, still set them for SPL. And still set them if explicitly
+        * asked.
+        */
+       if (!(IS_ENABLED(CONFIG_XPL_BUILD) || (gd->flags & GD_FLG_RELOC)))
+               if (stage != CLK_DEFAULTS_POST_FORCE)
+                       return 0;
+
+       debug("%s(%s)\n", __func__, dev_read_name(dev));
+
+       ret = clk_set_default_parents(dev, stage);
+       if (ret)
+               return ret;
+
+       ret = clk_set_default_rates(dev, stage);
+       if (ret < 0)
+               return ret;
+
+       return 0;
+}
+
+struct clk *devm_clk_get(struct udevice *dev, const char *id)
+{
+       int rc;
+       struct clk *clk;
+
+       clk = devm_kzalloc(dev, sizeof(*clk), GFP_KERNEL);
+       if (unlikely(!clk))
+               return ERR_PTR(-ENOMEM);
+
+       rc = clk_get_by_name(dev, id, clk);
+       if (rc)
+               return ERR_PTR(rc);
+
+       return clk;
+}
+
+int clk_prepare_bulk(struct clk_bulk *bulk)
+{
+       int i, ret;
+
+       for (i = 0; i < bulk->count; i++) {
+               ret = clk_prepare(&bulk->clks[i]);
+               if (ret < 0 && ret != -ENOSYS)
+                       return ret;
+       }
+
+       return 0;
+}
+
+int clk_unprepare_bulk(struct clk_bulk *bulk)
+{
+       int i, ret;
+
+       for (i = 0; i < bulk->count; i++) {
+               ret = clk_prepare(&bulk->clks[i]);
+               if (ret < 0 && ret != -ENOSYS)
+                       return ret;
+       }
+
+       return 0;
+}
+
+int clk_enable_bulk(struct clk_bulk *bulk)
+{
+       int i, ret;
+
+       for (i = 0; i < bulk->count; i++) {
+               ret = clk_enable(&bulk->clks[i]);
+               if (ret < 0 && ret != -ENOSYS)
+                       return ret;
+       }
+
+       return 0;
+}
+
+int clk_disable_bulk(struct clk_bulk *bulk)
+{
+       int i, ret;
+
+       for (i = 0; i < bulk->count; i++) {
+               ret = clk_disable(&bulk->clks[i]);
+               if (ret < 0 && ret != -ENOSYS)
+                       return ret;
+       }
+
+       return 0;
+}
diff --git a/drivers/clk/clk-common.h b/drivers/clk/clk-common.h
new file mode 100644
index 000000000000..fbb1bd5b3ba0
--- /dev/null
+++ b/drivers/clk/clk-common.h
@@ -0,0 +1,45 @@
+
+#include <dm/ofnode.h>
+#include <clk.h>
+
+#ifndef __CLK_COMMON_H__
+#define __CLK_COMMON_H__
+
+/* These functions are unused with CCF_FULL */
+
+#if !CONFIG_IS_ENABLED(CLK_CCF_FULL)
+int clk_get_by_index_tail(int ret, ofnode node,
+                                struct ofnode_phandle_args *args,
+                                const char *list_name, int index,
+                                struct clk *clk);
+
+int clk_set_default_parents(struct udevice *dev,
+                                  enum clk_defaults_stage stage);
+
+
+int clk_set_default_rates(struct udevice *dev,
+                                enum clk_defaults_stage stage);
+#else
+int clk_get_by_index_tail(int ret, ofnode node,
+                                struct ofnode_phandle_args *args,
+                                const char *list_name, int index,
+                                struct clk *clk)
+{
+       return -ENOSYS;
+}
+
+int clk_set_default_parents(struct udevice *dev,
+                                  enum clk_defaults_stage stage)
+{
+       return -ENOSYS;
+}
+
+int clk_set_default_rates(struct udevice *dev,
+                                enum clk_defaults_stage stage)
+{
+       return -ENOSYS;
+}
+
+#endif /* CONFIG_CLK_CCF_FULL */
+
+#endif /* __CLK_COMMON_H__ */
diff --git a/drivers/clk/clk-uclass.c b/drivers/clk/clk-uclass.c
index e960d2ad2383..e6036d880cb7 100644
--- a/drivers/clk/clk-uclass.c
+++ b/drivers/clk/clk-uclass.c
@@ -23,8 +23,10 @@
 #include <linux/bug.h>
 #include <linux/clk-provider.h>
 #include <linux/err.h>
 
+#include "clk-common.h"
+
 static inline const struct clk_ops_uboot *clk_dev_ops(struct udevice *dev)
 {
        return (const struct clk_ops_uboot *)dev->driver->ops;
 }
@@ -74,9 +76,9 @@ static int clk_of_xlate_default(struct clk *clk,
 
        return 0;
 }
 
-static int clk_get_by_index_tail(int ret, ofnode node,
+int clk_get_by_index_tail(int ret, ofnode node,
                                 struct ofnode_phandle_args *args,
                                 const char *list_name, int index,
                                 struct clk *clk)
 {
@@ -114,8 +116,9 @@ err:
              __func__, ofnode_get_name(node), list_name, index, ret);
 
        return log_msg_ret("prop", ret);
 }
+#endif /* OF_REAL */
 
 static int clk_get_by_indexed_prop(struct udevice *dev, const char *prop_name,
                                   int index, struct clk *clk)
 {
@@ -139,58 +142,8 @@ static int clk_get_by_indexed_prop(struct udevice *dev, 
const char *prop_name,
        return clk_get_by_index_tail(ret, dev_ofnode(dev), &args, "clocks",
                                     index, clk);
 }
 
-int clk_get_by_index(struct udevice *dev, int index, struct clk *clk)
-{
-       return clk_get_by_index_nodev(dev_ofnode(dev), index, clk);
-}
-
-int clk_get_by_index_nodev(ofnode node, int index, struct clk *clk)
-{
-       struct ofnode_phandle_args args;
-       int ret;
-
-       ret = ofnode_parse_phandle_with_args(node, "clocks", "#clock-cells", 0,
-                                            index, &args);
-
-       return clk_get_by_index_tail(ret, node, &args, "clocks",
-                                    index, clk);
-}
-
-int clk_get_bulk(struct udevice *dev, struct clk_bulk *bulk)
-{
-       int i, ret, err, count;
-
-       bulk->count = 0;
-
-       count = dev_count_phandle_with_args(dev, "clocks", "#clock-cells", 0);
-       if (count < 1)
-               return count;
-
-       bulk->clks = devm_kcalloc(dev, count, sizeof(struct clk), GFP_KERNEL);
-       if (!bulk->clks)
-               return -ENOMEM;
-
-       for (i = 0; i < count; i++) {
-               ret = clk_get_by_index(dev, i, &bulk->clks[i]);
-               if (ret < 0)
-                       goto bulk_get_err;
-
-               ++bulk->count;
-       }
-
-       return 0;
-
-bulk_get_err:
-       err = clk_release_all(bulk->clks, bulk->count);
-       if (err)
-               debug("%s: could not release all clocks for %s\n",
-                     __func__, dev_read_name(dev));
-
-       return ret;
-}
-
 static struct clk *clk_set_default_get_by_id(struct clk *clk)
 {
        struct clk *c = clk;
 
@@ -206,9 +159,9 @@ static struct clk *clk_set_default_get_by_id(struct clk 
*clk)
 
        return c;
 }
 
-static int clk_set_default_parents(struct udevice *dev,
+int clk_set_default_parents(struct udevice *dev,
                                   enum clk_defaults_stage stage)
 {
        struct clk clk, parent_clk, *c, *p;
        int index;
@@ -289,9 +242,9 @@ static int clk_set_default_parents(struct udevice *dev,
 
        return 0;
 }
 
-static int clk_set_default_rates(struct udevice *dev,
+int clk_set_default_rates(struct udevice *dev,
                                 enum clk_defaults_stage stage)
 {
        struct clk clk, *c;
        int index;
@@ -371,62 +324,8 @@ fail:
        free(rates);
        return ret;
 }
 
-int clk_set_defaults(struct udevice *dev, enum clk_defaults_stage stage)
-{
-       int ret;
-
-       if (!dev_has_ofnode(dev))
-               return 0;
-
-       /*
-        * To avoid setting defaults twice, don't set them before relocation.
-        * However, still set them for SPL. And still set them if explicitly
-        * asked.
-        */
-       if (!(IS_ENABLED(CONFIG_XPL_BUILD) || (gd->flags & GD_FLG_RELOC)))
-               if (stage != CLK_DEFAULTS_POST_FORCE)
-                       return 0;
-
-       debug("%s(%s)\n", __func__, dev_read_name(dev));
-
-       ret = clk_set_default_parents(dev, stage);
-       if (ret)
-               return ret;
-
-       ret = clk_set_default_rates(dev, stage);
-       if (ret < 0)
-               return ret;
-
-       return 0;
-}
-
-int clk_get_by_name(struct udevice *dev, const char *name, struct clk *clk)
-{
-       return clk_get_by_name_nodev(dev_ofnode(dev), name, clk);
-}
-#endif /* OF_REAL */
-
-int clk_get_by_name_nodev(ofnode node, const char *name, struct clk *clk)
-{
-       int index = 0;
-
-       debug("%s(node=%s, name=%s, clk=%p)\n", __func__,
-               ofnode_get_name(node), name, clk);
-       clk->dev = NULL;
-
-       if (name) {
-               index = ofnode_stringlist_search(node, "clock-names", name);
-               if (index < 0) {
-                       debug("fdt_stringlist_search() failed: %d\n", index);
-                       return index;
-               }
-       }
-
-       return clk_get_by_index_nodev(node, index, clk);
-}
-
 const char *
 clk_resolve_parent_clk(struct udevice *dev, const char *name)
 {
        struct udevice *parent;
@@ -443,28 +342,8 @@ clk_resolve_parent_clk(struct udevice *dev, const char 
*name)
 
        return clk.dev->name;
 }
 
-int clk_release_all(struct clk *clk, unsigned int count)
-{
-       unsigned int i;
-       int ret;
-
-       for (i = 0; i < count; i++) {
-               debug("%s(clk[%u]=%p)\n", __func__, i, &clk[i]);
-
-               /* check if clock has been previously requested */
-               if (!clk[i].dev)
-                       continue;
-
-               ret = clk_disable(&clk[i]);
-               if (ret && ret != -ENOSYS)
-                       return ret;
-       }
-
-       return 0;
-}
-
 int clk_request(struct udevice *dev, struct clk *clk)
 {
        const struct clk_ops_uboot *ops;
 
@@ -704,21 +583,8 @@ int clk_enable(struct clk *clk)
 
        return 0;
 }
 
-int clk_enable_bulk(struct clk_bulk *bulk)
-{
-       int i, ret;
-
-       for (i = 0; i < bulk->count; i++) {
-               ret = clk_enable(&bulk->clks[i]);
-               if (ret < 0 && ret != -ENOSYS)
-                       return ret;
-       }
-
-       return 0;
-}
-
 int clk_disable(struct clk *clk)
 {
        const struct clk_ops_uboot *ops;
        struct clk *clkp = NULL;
@@ -769,21 +635,8 @@ int clk_disable(struct clk *clk)
 
        return 0;
 }
 
-int clk_disable_bulk(struct clk_bulk *bulk)
-{
-       int i, ret;
-
-       for (i = 0; i < bulk->count; i++) {
-               ret = clk_disable(&bulk->clks[i]);
-               if (ret < 0 && ret != -ENOSYS)
-                       return ret;
-       }
-
-       return 0;
-}
-
 int clk_get_by_id(ulong id, struct clk **clkp)
 {
        struct udevice *dev;
        struct uclass *uc;
@@ -821,24 +674,8 @@ bool clk_is_match(const struct clk *p, const struct clk *q)
 
        return false;
 }
 
-struct clk *devm_clk_get(struct udevice *dev, const char *id)
-{
-       int rc;
-       struct clk *clk;
-
-       clk = devm_kzalloc(dev, sizeof(*clk), GFP_KERNEL);
-       if (unlikely(!clk))
-               return ERR_PTR(-ENOMEM);
-
-       rc = clk_get_by_name(dev, id, clk);
-       if (rc)
-               return ERR_PTR(rc);
-
-       return clk;
-}
-
 int clk_prepare(struct clk *clk)
 {
        return 0;
 }
diff --git a/include/linux/clk-provider.h b/include/linux/clk-provider.h
index 4fcdb5a86799..17d6190134dd 100644
--- a/include/linux/clk-provider.h
+++ b/include/linux/clk-provider.h
@@ -39,8 +39,11 @@
  */
 #if CONFIG_IS_ENABLED(CLK_CCF_FULL)
 #include "clk-provider-ccf_full.h"
 #else
+/* Forward-declare clk_hw so we can compile code that references it even 
though it's unused*/
+struct clk_hw;
+
 #include "clk-provider-uccf.h"
 #endif
 
 #endif /* __LINUX_CLK_PROVIDER_H */

-- 
2.55.0

Reply via email to