clk: fixed_rate: add API for directly registering fixed rate clocks

Current driver only supports registering fixed rate clocks from DT. Add
new API which makes it possible to register fixed rate clocks directly
from e.g. platform specific clock drivers.

Reviewed-by: Peng Fan <peng.fan@nxp.com>
Signed-off-by: Tero Kristo <t-kristo@ti.com>
Signed-off-by: Tero Kristo <kristo@kernel.org>
diff --git a/drivers/clk/clk_fixed_rate.c b/drivers/clk/clk_fixed_rate.c
index 09f9ef2..325a9b2 100644
--- a/drivers/clk/clk_fixed_rate.c
+++ b/drivers/clk/clk_fixed_rate.c
@@ -9,6 +9,9 @@
 #include <dm/device-internal.h>
 #include <linux/clk-provider.h>
 
+#define UBOOT_DM_CLK_FIXED_RATE "fixed_rate_clock"
+#define UBOOT_DM_CLK_FIXED_RATE_RAW "fixed_rate_raw_clock"
+
 static ulong clk_fixed_rate_get_rate(struct clk *clk)
 {
 	return to_clk_fixed_rate(clk->dev)->fixed_rate;
@@ -40,12 +43,47 @@
 	clk->enable_count = 0;
 }
 
+static ulong clk_fixed_rate_raw_get_rate(struct clk *clk)
+{
+	return container_of(clk, struct clk_fixed_rate, clk)->fixed_rate;
+}
+
+const struct clk_ops clk_fixed_rate_raw_ops = {
+	.get_rate = clk_fixed_rate_raw_get_rate,
+};
+
 static int clk_fixed_rate_of_to_plat(struct udevice *dev)
 {
 	clk_fixed_rate_ofdata_to_plat_(dev, to_clk_fixed_rate(dev));
 
 	return 0;
 }
+
+#if CONFIG_IS_ENABLED(CLK_CCF)
+struct clk *clk_register_fixed_rate(struct device *dev, const char *name,
+				    ulong rate)
+{
+	struct clk *clk;
+	struct clk_fixed_rate *fixed;
+	int ret;
+
+	fixed = kzalloc(sizeof(*fixed), GFP_KERNEL);
+	if (!fixed)
+		return ERR_PTR(-ENOMEM);
+
+	fixed->fixed_rate = rate;
+
+	clk = &fixed->clk;
+
+	ret = clk_register(clk, UBOOT_DM_CLK_FIXED_RATE_RAW, name, NULL);
+	if (ret) {
+		kfree(fixed);
+		return ERR_PTR(ret);
+	}
+
+	return clk;
+}
+#endif
 
 static const struct udevice_id clk_fixed_rate_match[] = {
 	{
@@ -63,3 +101,10 @@
 	.ops = &clk_fixed_rate_ops,
 	.flags = DM_FLAG_PRE_RELOC,
 };
+
+U_BOOT_DRIVER(clk_fixed_rate_raw) = {
+	.name = UBOOT_DM_CLK_FIXED_RATE_RAW,
+	.id = UCLASS_CLK,
+	.ops = &clk_fixed_rate_raw_ops,
+	.flags = DM_FLAG_PRE_RELOC,
+};