Merge tag 'clk-2024.04-rc2' of https://source.denx.de/u-boot/custodians/u-boot-clk

Clock changes for v2024.04

This pull has the usual fixes and new (clock-adjacent) drivers. It also has some
cleanups for the clock API; in particular removing the unused rfree callback.

CI: https://source.denx.de/u-boot/custodians/u-boot-clk/-/pipelines/19486
diff --git a/arch/arm/mach-rockchip/rk3288/rk3288.c b/arch/arm/mach-rockchip/rk3288/rk3288.c
index 26c7e41..d9f782e 100644
--- a/arch/arm/mach-rockchip/rk3288/rk3288.c
+++ b/arch/arm/mach-rockchip/rk3288/rk3288.c
@@ -184,8 +184,6 @@
 
 		rate = clk_get_rate(&clk);
 		printf("%s: %lu\n", clks[i].name, rate);
-
-		clk_free(&clk);
 	}
 
 	return 0;
diff --git a/arch/arm/mach-socfpga/clock_manager_agilex.c b/arch/arm/mach-socfpga/clock_manager_agilex.c
index e035c09..28f593b 100644
--- a/arch/arm/mach-socfpga/clock_manager_agilex.c
+++ b/arch/arm/mach-socfpga/clock_manager_agilex.c
@@ -37,8 +37,6 @@
 
 	rate = clk_get_rate(&clk);
 
-	clk_free(&clk);
-
 	if ((rate == (unsigned long)-ENOSYS) ||
 	    (rate == (unsigned long)-ENXIO) ||
 	    (rate == (unsigned long)-EIO)) {
diff --git a/arch/arm/mach-socfpga/clock_manager_arria10.c b/arch/arm/mach-socfpga/clock_manager_arria10.c
index b48a2b4..8ab18f6 100644
--- a/arch/arm/mach-socfpga/clock_manager_arria10.c
+++ b/arch/arm/mach-socfpga/clock_manager_arria10.c
@@ -962,7 +962,6 @@
 	struct uclass *uc;
 	struct udevice *dev = NULL;
 	struct clk clk = { 0 };
-	ulong rate;
 	int ret;
 
 	/* Device addresses start at 1 */
@@ -982,11 +981,7 @@
 	if (ret)
 		return 0;
 
-	rate = clk_get_rate(&clk);
-
-	clk_free(&clk);
-
-	return rate;
+	return clk_get_rate(&clk);
 }
 
 static u32 cm_get_rate_dm_khz(char *name)
diff --git a/arch/arm/mach-socfpga/clock_manager_n5x.c b/arch/arm/mach-socfpga/clock_manager_n5x.c
index 4f09853..0ed480d 100644
--- a/arch/arm/mach-socfpga/clock_manager_n5x.c
+++ b/arch/arm/mach-socfpga/clock_manager_n5x.c
@@ -36,8 +36,6 @@
 
 	rate = clk_get_rate(&clk);
 
-	clk_free(&clk);
-
 	if ((rate == (unsigned long)-ENXIO) ||
 	    (rate == (unsigned long)-EIO)) {
 		debug("%s id %u: clk_get_rate err: %ld\n",
diff --git a/arch/arm/mach-zynq/clk.c b/arch/arm/mach-zynq/clk.c
index e6a6732..5e1ba8d 100644
--- a/arch/arm/mach-zynq/clk.c
+++ b/arch/arm/mach-zynq/clk.c
@@ -44,8 +44,6 @@
 			gd->bd->bi_arm_freq = rate;
 			gd->cpu_clk = clk_get_rate(&clk);
 		}
-
-		clk_free(&clk);
 	}
 	gd->bd->bi_dsp_freq = 0;
 
diff --git a/arch/mips/mach-pic32/cpu.c b/arch/mips/mach-pic32/cpu.c
index 3181a94..668adbb 100644
--- a/arch/mips/mach-pic32/cpu.c
+++ b/arch/mips/mach-pic32/cpu.c
@@ -30,7 +30,6 @@
 	int ret;
 	struct udevice *dev;
 	struct clk clk;
-	ulong rate;
 
 	ret = uclass_get_device(UCLASS_CLK, 0, &dev);
 	if (ret) {
@@ -43,11 +42,7 @@
 	if (ret < 0)
 		return ret;
 
-	rate = clk_get_rate(&clk);
-
-	clk_free(&clk);
-
-	return rate;
+	return clk_get_rate(&clk);
 }
 
 static ulong clk_get_cpu_rate(void)
diff --git a/arch/sandbox/include/asm/clk.h b/arch/sandbox/include/asm/clk.h
index d4e04ad..37fe49c 100644
--- a/arch/sandbox/include/asm/clk.h
+++ b/arch/sandbox/include/asm/clk.h
@@ -182,14 +182,6 @@
  */
 int sandbox_clk_test_disable_bulk(struct udevice *dev);
 /**
- * sandbox_clk_test_free - Ask the sandbox clock test device to free its
- * clocks.
- *
- * @dev:	The sandbox clock test (client) device.
- * @return:	0 if OK, or a negative error code.
- */
-int sandbox_clk_test_free(struct udevice *dev);
-/**
  * sandbox_clk_test_release_bulk - Ask the sandbox clock test device to release
  * all clocks in it's clock bulk struct.
  *
diff --git a/board/microchip/pic32mzda/pic32mzda.c b/board/microchip/pic32mzda/pic32mzda.c
index e7337de..3c2203d 100644
--- a/board/microchip/pic32mzda/pic32mzda.c
+++ b/board/microchip/pic32mzda/pic32mzda.c
@@ -36,8 +36,6 @@
 	rate = clk_get_rate(&clk);
 	printf("CPU Speed: %lu MHz\n", rate / 1000000);
 
-	clk_free(&clk);
-
 	return 0;
 }
 #endif
diff --git a/board/sipeed/maix/maix.c b/board/sipeed/maix/maix.c
index 79e492f..06653b5 100644
--- a/board/sipeed/maix/maix.c
+++ b/board/sipeed/maix/maix.c
@@ -32,7 +32,6 @@
 			continue;
 
 		ret = clk_enable(&clk);
-		clk_free(&clk);
 		if (ret)
 			return ret;
 	}
diff --git a/board/synopsys/hsdk/clk-lib.c b/board/synopsys/hsdk/clk-lib.c
index be76d6c..a9614e9 100644
--- a/board/synopsys/hsdk/clk-lib.c
+++ b/board/synopsys/hsdk/clk-lib.c
@@ -56,8 +56,6 @@
 
 	priv_rate = clk_get_rate(&clk);
 
-	clk_free(&clk);
-
 	mhz_rate = ceil(priv_rate, HZ_IN_MHZ);
 
 	if (ctl & CLK_MHZ)
diff --git a/drivers/clk/aspeed/clk_ast2600.c b/drivers/clk/aspeed/clk_ast2600.c
index eecfacd..a159093 100644
--- a/drivers/clk/aspeed/clk_ast2600.c
+++ b/drivers/clk/aspeed/clk_ast2600.c
@@ -1143,8 +1143,6 @@
 		ret = clk_get_rate(&clk);
 		rate = ret;
 
-		clk_free(&clk);
-
 		if (ret == -EINVAL) {
 			printf("clk ID %lu not supported yet\n",
 			       aspeed_clk_names[i].id);
diff --git a/drivers/clk/at91/compat.c b/drivers/clk/at91/compat.c
index 2fdc2fb..ee67093 100644
--- a/drivers/clk/at91/compat.c
+++ b/drivers/clk/at91/compat.c
@@ -516,7 +516,6 @@
 {
 	struct udevice *dev;
 	struct clk clk_dev;
-	ulong clk_rate;
 	int ret;
 
 	dev = dev_get_parent(clk->dev);
@@ -525,11 +524,7 @@
 	if (ret)
 		return ret;
 
-	clk_rate = clk_get_rate(&clk_dev);
-
-	clk_free(&clk_dev);
-
-	return clk_rate;
+	return clk_get_rate(&clk_dev);
 }
 
 static struct clk_ops periph_clk_ops = {
@@ -762,7 +757,6 @@
 	struct pmc_plat *plat = dev_get_plat(clk->dev);
 	struct at91_pmc *pmc = plat->reg_base;
 	struct clk parent;
-	ulong clk_rate;
 	u32 tmp, gckdiv;
 	u8 clock_source, parent_index;
 	int ret;
@@ -778,11 +772,7 @@
 	if (ret)
 		return 0;
 
-	clk_rate = clk_get_rate(&parent) / (gckdiv + 1);
-
-	clk_free(&parent);
-
-	return clk_rate;
+	return clk_get_rate(&parent) / (gckdiv + 1);
 }
 
 static ulong generic_clk_set_rate(struct clk *clk, ulong rate)
diff --git a/drivers/clk/clk-gpio.c b/drivers/clk/clk-gpio.c
index 26d795b..4ed1430 100644
--- a/drivers/clk/clk-gpio.c
+++ b/drivers/clk/clk-gpio.c
@@ -3,19 +3,23 @@
  * Copyright (C) 2023 Marek Vasut <marek.vasut+renesas@mailbox.org>
  */
 
-#include <asm/gpio.h>
-#include <common.h>
+#include <clk.h>
 #include <clk-uclass.h>
 #include <dm.h>
+#include <linux/clk-provider.h>
+
+#include <asm/gpio.h>
 
 struct clk_gpio_priv {
-	struct gpio_desc	enable;
+	struct gpio_desc	enable;	/* GPIO, controlling the gate */
+	struct clk		*clk;	/* Gated clock */
 };
 
 static int clk_gpio_enable(struct clk *clk)
 {
 	struct clk_gpio_priv *priv = dev_get_priv(clk->dev);
 
+	clk_enable(priv->clk);
 	dm_gpio_set_value(&priv->enable, 1);
 
 	return 0;
@@ -26,21 +30,45 @@
 	struct clk_gpio_priv *priv = dev_get_priv(clk->dev);
 
 	dm_gpio_set_value(&priv->enable, 0);
+	clk_disable(priv->clk);
 
 	return 0;
 }
 
+static ulong clk_gpio_get_rate(struct clk *clk)
+{
+	struct clk_gpio_priv *priv = dev_get_priv(clk->dev);
+
+	return clk_get_rate(priv->clk);
+}
+
 const struct clk_ops clk_gpio_ops = {
 	.enable		= clk_gpio_enable,
 	.disable	= clk_gpio_disable,
+	.get_rate	= clk_gpio_get_rate,
 };
 
 static int clk_gpio_probe(struct udevice *dev)
 {
 	struct clk_gpio_priv *priv = dev_get_priv(dev);
+	int ret;
 
-	return gpio_request_by_name(dev, "enable-gpios", 0,
-				    &priv->enable, GPIOD_IS_OUT);
+	priv->clk = devm_clk_get(dev, NULL);
+	if (IS_ERR(priv->clk)) {
+		log_debug("%s: Could not get gated clock: %ld\n",
+			  __func__, PTR_ERR(priv->clk));
+		return PTR_ERR(priv->clk);
+	}
+
+	ret = gpio_request_by_name(dev, "enable-gpios", 0,
+				   &priv->enable, GPIOD_IS_OUT);
+	if (ret) {
+		log_debug("%s: Could not decode enable-gpios (%d)\n",
+			  __func__, ret);
+		return ret;
+	}
+
+	return 0;
 }
 
 /*
diff --git a/drivers/clk/clk-uclass.c b/drivers/clk/clk-uclass.c
index 3e9d68f..ed6e60b 100644
--- a/drivers/clk/clk-uclass.c
+++ b/drivers/clk/clk-uclass.c
@@ -437,8 +437,6 @@
 		ret = clk_disable(&clk[i]);
 		if (ret && ret != -ENOSYS)
 			return ret;
-
-		clk_free(&clk[i]);
 	}
 
 	return 0;
@@ -461,24 +459,9 @@
 	return ops->request(clk);
 }
 
-void clk_free(struct clk *clk)
-{
-	const struct clk_ops *ops;
-
-	debug("%s(clk=%p)\n", __func__, clk);
-	if (!clk_valid(clk))
-		return;
-	ops = clk_dev_ops(clk->dev);
-
-	if (ops->rfree)
-		ops->rfree(clk);
-	return;
-}
-
 ulong clk_get_rate(struct clk *clk)
 {
 	const struct clk_ops *ops;
-	ulong ret;
 
 	debug("%s(clk=%p)\n", __func__, clk);
 	if (!clk_valid(clk))
@@ -488,11 +471,7 @@
 	if (!ops->get_rate)
 		return -ENOSYS;
 
-	ret = ops->get_rate(clk);
-	if (ret)
-		return log_ret(ret);
-
-	return 0;
+	return ops->get_rate(clk);
 }
 
 struct clk *clk_get_parent(struct clk *clk)
@@ -791,22 +770,12 @@
 	return false;
 }
 
-static void devm_clk_release(struct udevice *dev, void *res)
-{
-	clk_free(res);
-}
-
-static int devm_clk_match(struct udevice *dev, void *res, void *data)
-{
-	return res == data;
-}
-
 struct clk *devm_clk_get(struct udevice *dev, const char *id)
 {
 	int rc;
 	struct clk *clk;
 
-	clk = devres_alloc(devm_clk_release, sizeof(struct clk), __GFP_ZERO);
+	clk = devm_kzalloc(dev, sizeof(*clk), GFP_KERNEL);
 	if (unlikely(!clk))
 		return ERR_PTR(-ENOMEM);
 
@@ -814,21 +783,9 @@
 	if (rc)
 		return ERR_PTR(rc);
 
-	devres_add(dev, clk);
 	return clk;
 }
 
-void devm_clk_put(struct udevice *dev, struct clk *clk)
-{
-	int rc;
-
-	if (!clk)
-		return;
-
-	rc = devres_release(dev, devm_clk_release, devm_clk_match, clk);
-	WARN_ON(rc);
-}
-
 int clk_uclass_post_probe(struct udevice *dev)
 {
 	/*
diff --git a/drivers/clk/clk-xlnx-clock-wizard.c b/drivers/clk/clk-xlnx-clock-wizard.c
index 70ee3af..a10a843 100644
--- a/drivers/clk/clk-xlnx-clock-wizard.c
+++ b/drivers/clk/clk-xlnx-clock-wizard.c
@@ -137,7 +137,6 @@
 	ret = clk_enable(&clk_in1);
 	if (ret) {
 		dev_err(dev, "failed to enable clock\n");
-		clk_free(&clk_in1);
 		return ret;
 	}
 
diff --git a/drivers/clk/clk_sandbox.c b/drivers/clk/clk_sandbox.c
index 636914d..73d943f 100644
--- a/drivers/clk/clk_sandbox.c
+++ b/drivers/clk/clk_sandbox.c
@@ -101,17 +101,6 @@
 	return 0;
 }
 
-static void sandbox_clk_free(struct clk *clk)
-{
-	struct sandbox_clk_priv *priv = dev_get_priv(clk->dev);
-
-	if (clk->id >= SANDBOX_CLK_ID_COUNT)
-		return;
-
-	priv->requested[clk->id] = false;
-	return;
-}
-
 static struct clk_ops sandbox_clk_ops = {
 	.round_rate	= sandbox_clk_round_rate,
 	.get_rate	= sandbox_clk_get_rate,
@@ -119,7 +108,6 @@
 	.enable		= sandbox_clk_enable,
 	.disable	= sandbox_clk_disable,
 	.request	= sandbox_clk_request,
-	.rfree		= sandbox_clk_free,
 };
 
 static int sandbox_clk_probe(struct udevice *dev)
diff --git a/drivers/clk/clk_sandbox_test.c b/drivers/clk/clk_sandbox_test.c
index c695b69..c224dc1 100644
--- a/drivers/clk/clk_sandbox_test.c
+++ b/drivers/clk/clk_sandbox_test.c
@@ -135,18 +135,6 @@
 	return clk_disable_bulk(&sbct->bulk);
 }
 
-int sandbox_clk_test_free(struct udevice *dev)
-{
-	struct sandbox_clk_test *sbct = dev_get_priv(dev);
-	int i;
-
-	devm_clk_put(dev, sbct->clkps[SANDBOX_CLK_TEST_ID_DEVM1]);
-	for (i = 0; i < SANDBOX_CLK_TEST_NON_DEVM_COUNT; i++)
-		clk_free(&sbct->clks[i]);
-
-	return 0;
-}
-
 int sandbox_clk_test_release_bulk(struct udevice *dev)
 {
 	struct sandbox_clk_test *sbct = dev_get_priv(dev);
diff --git a/drivers/clk/clk_versaclock.c b/drivers/clk/clk_versaclock.c
index 699df3c..bbe7225 100644
--- a/drivers/clk/clk_versaclock.c
+++ b/drivers/clk/clk_versaclock.c
@@ -1000,26 +1000,18 @@
 	return 0;
 
 free_out:
-	for (n = 1; n < vc5->chip_info->clk_out_cnt; n++) {
-		clk_free(&vc5->clk_out[n].hw);
+	for (n = 1; n < vc5->chip_info->clk_out_cnt; n++)
 		free(out_name[n]);
-	}
 free_selb:
-	clk_free(&vc5->clk_out[0].hw);
 	free(outsel_name);
 free_fod:
-	for (n = 0; n < vc5->chip_info->clk_fod_cnt; n++) {
-		clk_free(&vc5->clk_fod[n].hw);
+	for (n = 0; n < vc5->chip_info->clk_fod_cnt; n++)
 		free(fod_name[n]);
-	}
 free_pll:
-	clk_free(&vc5->clk_pll.hw);
 	free(pll_name);
 free_pfd:
-	clk_free(&vc5->clk_pfd);
 	free(pfd_name);
 free_mux:
-	clk_free(&vc5->clk_mux);
 	free(mux_name);
 
 	return ret;
diff --git a/drivers/clk/clk_zynq.c b/drivers/clk/clk_zynq.c
index 34f964d..e3cefe2 100644
--- a/drivers/clk/clk_zynq.c
+++ b/drivers/clk/clk_zynq.c
@@ -491,8 +491,6 @@
 
 			rate = clk_get_rate(&clk);
 
-			clk_free(&clk);
-
 			if ((rate == (unsigned long)-ENOSYS) ||
 			    (rate == (unsigned long)-ENXIO))
 				printf("%10s%20s\n", name, "unknown");
diff --git a/drivers/clk/clk_zynqmp.c b/drivers/clk/clk_zynqmp.c
index 0ffac19..e23f7da 100644
--- a/drivers/clk/clk_zynqmp.c
+++ b/drivers/clk/clk_zynqmp.c
@@ -757,8 +757,6 @@
 
 			rate = clk_get_rate(&clk);
 
-			clk_free(&clk);
-
 			if ((rate == (unsigned long)-ENOSYS) ||
 			    (rate == (unsigned long)-ENXIO) ||
 			    (rate == (unsigned long)-EIO))
diff --git a/drivers/clk/imx/clk-imx8.c b/drivers/clk/imx/clk-imx8.c
index 9600672..d39b87b 100644
--- a/drivers/clk/imx/clk-imx8.c
+++ b/drivers/clk/imx/clk-imx8.c
@@ -62,8 +62,6 @@
 		ret = clk_get_rate(&clk);
 		rate = ret;
 
-		clk_free(&clk);
-
 		if (ret == -EINVAL) {
 			printf("clk ID %lu not supported yet\n",
 			       imx8_clk_names[i].id);
diff --git a/drivers/clk/meson/Kconfig b/drivers/clk/meson/Kconfig
index cdc9d6f..ee33c61 100644
--- a/drivers/clk/meson/Kconfig
+++ b/drivers/clk/meson/Kconfig
@@ -29,3 +29,13 @@
 	help
 	  Enable clock support for the Amlogic A1 SoC family, such as
 	  the A113L
+
+config CLK_MESON_MSR
+	bool "Enable clock measure driver for Amlogic SoCs"
+	depends on CLK && ARCH_MESON
+	depends on CMD_CLK
+	default ARCH_MESON
+	help
+	  Enable measuring a set of internal Amlogic SoC clock frequencies
+	  using the Hardware Clock Measure registers and print them using
+	  the clk dump command.
diff --git a/drivers/clk/meson/Makefile b/drivers/clk/meson/Makefile
index d975f07..c7a446e 100644
--- a/drivers/clk/meson/Makefile
+++ b/drivers/clk/meson/Makefile
@@ -9,3 +9,4 @@
 obj-$(CONFIG_CLK_MESON_G12A) += g12a.o
 obj-$(CONFIG_CLK_MESON_G12A) += g12a-ao.o
 obj-$(CONFIG_CLK_MESON_A1) += a1.o
+obj-$(CONFIG_CLK_MESON_MSR) += clk-measure.o
diff --git a/drivers/clk/meson/clk-measure.c b/drivers/clk/meson/clk-measure.c
new file mode 100644
index 0000000..f653fc6
--- /dev/null
+++ b/drivers/clk/meson/clk-measure.c
@@ -0,0 +1,634 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Based on Linux driver from:
+ * (C) Copyright 2018 - BayLibre, SAS
+ * Author: Neil Armstrong <narmstrong@baylibre.com>
+ * (C) Copyright 2023 - Neil Armstrong <neil.armstrong@linaro.org>
+ */
+
+#include <log.h>
+#include <clk-uclass.h>
+#include <div64.h>
+#include <dm.h>
+#include <time.h>
+#include <regmap.h>
+#include <syscon.h>
+#include <linux/bitops.h>
+#include <linux/bitfield.h>
+#include <linux/delay.h>
+#include <linux/err.h>
+#include <linux/kernel.h>
+
+#define MSR_CLK_DUTY		0x0
+#define MSR_CLK_REG0		0x4
+#define MSR_CLK_REG1		0x8
+#define MSR_CLK_REG2		0xc
+
+#define MSR_DURATION		GENMASK(15, 0)
+#define MSR_ENABLE		BIT(16)
+#define MSR_CONT		BIT(17) /* continuous measurement */
+#define MSR_INTR		BIT(18) /* interrupts */
+#define MSR_RUN			BIT(19)
+#define MSR_CLK_SRC		GENMASK(26, 20)
+#define MSR_BUSY		BIT(31)
+
+#define MSR_VAL_MASK		GENMASK(15, 0)
+
+#define DIV_MIN			32
+#define DIV_STEP		32
+#define DIV_MAX			640
+
+#define CLK_MSR_MAX		128
+
+struct meson_msr_id {
+	unsigned int id;
+	const char *name;
+};
+
+struct meson_msr {
+	struct regmap *regmap;
+	struct meson_msr_id *msr_table;
+};
+
+#define CLK_MSR_ID(__id, __name) \
+	[__id] = {.id = __id, .name = __name,}
+
+static struct meson_msr_id clk_msr_m8[CLK_MSR_MAX] = {
+	CLK_MSR_ID(0, "ring_osc_out_ee0"),
+	CLK_MSR_ID(1, "ring_osc_out_ee1"),
+	CLK_MSR_ID(2, "ring_osc_out_ee2"),
+	CLK_MSR_ID(3, "a9_ring_osck"),
+	CLK_MSR_ID(6, "vid_pll"),
+	CLK_MSR_ID(7, "clk81"),
+	CLK_MSR_ID(8, "encp"),
+	CLK_MSR_ID(9, "encl"),
+	CLK_MSR_ID(11, "eth_rmii"),
+	CLK_MSR_ID(13, "amclk"),
+	CLK_MSR_ID(14, "fec_clk_0"),
+	CLK_MSR_ID(15, "fec_clk_1"),
+	CLK_MSR_ID(16, "fec_clk_2"),
+	CLK_MSR_ID(18, "a9_clk_div16"),
+	CLK_MSR_ID(19, "hdmi_sys"),
+	CLK_MSR_ID(20, "rtc_osc_clk_out"),
+	CLK_MSR_ID(21, "i2s_clk_in_src0"),
+	CLK_MSR_ID(22, "clk_rmii_from_pad"),
+	CLK_MSR_ID(23, "hdmi_ch0_tmds"),
+	CLK_MSR_ID(24, "lvds_fifo"),
+	CLK_MSR_ID(26, "sc_clk_int"),
+	CLK_MSR_ID(28, "sar_adc"),
+	CLK_MSR_ID(30, "mpll_clk_test_out"),
+	CLK_MSR_ID(31, "audac_clkpi"),
+	CLK_MSR_ID(32, "vdac"),
+	CLK_MSR_ID(33, "sdhc_rx"),
+	CLK_MSR_ID(34, "sdhc_sd"),
+	CLK_MSR_ID(35, "mali"),
+	CLK_MSR_ID(36, "hdmi_tx_pixel"),
+	CLK_MSR_ID(38, "vdin_meas"),
+	CLK_MSR_ID(39, "pcm_sclk"),
+	CLK_MSR_ID(40, "pcm_mclk"),
+	CLK_MSR_ID(41, "eth_rx_tx"),
+	CLK_MSR_ID(42, "pwm_d"),
+	CLK_MSR_ID(43, "pwm_c"),
+	CLK_MSR_ID(44, "pwm_b"),
+	CLK_MSR_ID(45, "pwm_a"),
+	CLK_MSR_ID(46, "pcm2_sclk"),
+	CLK_MSR_ID(47, "ddr_dpll_pt"),
+	CLK_MSR_ID(48, "pwm_f"),
+	CLK_MSR_ID(49, "pwm_e"),
+	CLK_MSR_ID(59, "hcodec"),
+	CLK_MSR_ID(60, "usb_32k_alt"),
+	CLK_MSR_ID(61, "gpio"),
+	CLK_MSR_ID(62, "vid2_pll"),
+	CLK_MSR_ID(63, "mipi_csi_cfg"),
+};
+
+static struct meson_msr_id clk_msr_gx[CLK_MSR_MAX] = {
+	CLK_MSR_ID(0, "ring_osc_out_ee_0"),
+	CLK_MSR_ID(1, "ring_osc_out_ee_1"),
+	CLK_MSR_ID(2, "ring_osc_out_ee_2"),
+	CLK_MSR_ID(3, "a53_ring_osc"),
+	CLK_MSR_ID(4, "gp0_pll"),
+	CLK_MSR_ID(6, "enci"),
+	CLK_MSR_ID(7, "clk81"),
+	CLK_MSR_ID(8, "encp"),
+	CLK_MSR_ID(9, "encl"),
+	CLK_MSR_ID(10, "vdac"),
+	CLK_MSR_ID(11, "rgmii_tx"),
+	CLK_MSR_ID(12, "pdm"),
+	CLK_MSR_ID(13, "amclk"),
+	CLK_MSR_ID(14, "fec_0"),
+	CLK_MSR_ID(15, "fec_1"),
+	CLK_MSR_ID(16, "fec_2"),
+	CLK_MSR_ID(17, "sys_pll_div16"),
+	CLK_MSR_ID(18, "sys_cpu_div16"),
+	CLK_MSR_ID(19, "hdmitx_sys"),
+	CLK_MSR_ID(20, "rtc_osc_out"),
+	CLK_MSR_ID(21, "i2s_in_src0"),
+	CLK_MSR_ID(22, "eth_phy_ref"),
+	CLK_MSR_ID(23, "hdmi_todig"),
+	CLK_MSR_ID(26, "sc_int"),
+	CLK_MSR_ID(28, "sar_adc"),
+	CLK_MSR_ID(31, "mpll_test_out"),
+	CLK_MSR_ID(32, "vdec"),
+	CLK_MSR_ID(35, "mali"),
+	CLK_MSR_ID(36, "hdmi_tx_pixel"),
+	CLK_MSR_ID(37, "i958"),
+	CLK_MSR_ID(38, "vdin_meas"),
+	CLK_MSR_ID(39, "pcm_sclk"),
+	CLK_MSR_ID(40, "pcm_mclk"),
+	CLK_MSR_ID(41, "eth_rx_or_rmii"),
+	CLK_MSR_ID(42, "mp0_out"),
+	CLK_MSR_ID(43, "fclk_div5"),
+	CLK_MSR_ID(44, "pwm_b"),
+	CLK_MSR_ID(45, "pwm_a"),
+	CLK_MSR_ID(46, "vpu"),
+	CLK_MSR_ID(47, "ddr_dpll_pt"),
+	CLK_MSR_ID(48, "mp1_out"),
+	CLK_MSR_ID(49, "mp2_out"),
+	CLK_MSR_ID(50, "mp3_out"),
+	CLK_MSR_ID(51, "nand_core"),
+	CLK_MSR_ID(52, "sd_emmc_b"),
+	CLK_MSR_ID(53, "sd_emmc_a"),
+	CLK_MSR_ID(55, "vid_pll_div_out"),
+	CLK_MSR_ID(56, "cci"),
+	CLK_MSR_ID(57, "wave420l_c"),
+	CLK_MSR_ID(58, "wave420l_b"),
+	CLK_MSR_ID(59, "hcodec"),
+	CLK_MSR_ID(60, "alt_32k"),
+	CLK_MSR_ID(61, "gpio_msr"),
+	CLK_MSR_ID(62, "hevc"),
+	CLK_MSR_ID(66, "vid_lock"),
+	CLK_MSR_ID(70, "pwm_f"),
+	CLK_MSR_ID(71, "pwm_e"),
+	CLK_MSR_ID(72, "pwm_d"),
+	CLK_MSR_ID(73, "pwm_c"),
+	CLK_MSR_ID(75, "aoclkx2_int"),
+	CLK_MSR_ID(76, "aoclk_int"),
+	CLK_MSR_ID(77, "rng_ring_osc_0"),
+	CLK_MSR_ID(78, "rng_ring_osc_1"),
+	CLK_MSR_ID(79, "rng_ring_osc_2"),
+	CLK_MSR_ID(80, "rng_ring_osc_3"),
+	CLK_MSR_ID(81, "vapb"),
+	CLK_MSR_ID(82, "ge2d"),
+};
+
+static struct meson_msr_id clk_msr_axg[CLK_MSR_MAX] = {
+	CLK_MSR_ID(0, "ring_osc_out_ee_0"),
+	CLK_MSR_ID(1, "ring_osc_out_ee_1"),
+	CLK_MSR_ID(2, "ring_osc_out_ee_2"),
+	CLK_MSR_ID(3, "a53_ring_osc"),
+	CLK_MSR_ID(4, "gp0_pll"),
+	CLK_MSR_ID(5, "gp1_pll"),
+	CLK_MSR_ID(7, "clk81"),
+	CLK_MSR_ID(9, "encl"),
+	CLK_MSR_ID(17, "sys_pll_div16"),
+	CLK_MSR_ID(18, "sys_cpu_div16"),
+	CLK_MSR_ID(20, "rtc_osc_out"),
+	CLK_MSR_ID(23, "mmc_clk"),
+	CLK_MSR_ID(28, "sar_adc"),
+	CLK_MSR_ID(31, "mpll_test_out"),
+	CLK_MSR_ID(40, "mod_eth_tx_clk"),
+	CLK_MSR_ID(41, "mod_eth_rx_clk_rmii"),
+	CLK_MSR_ID(42, "mp0_out"),
+	CLK_MSR_ID(43, "fclk_div5"),
+	CLK_MSR_ID(44, "pwm_b"),
+	CLK_MSR_ID(45, "pwm_a"),
+	CLK_MSR_ID(46, "vpu"),
+	CLK_MSR_ID(47, "ddr_dpll_pt"),
+	CLK_MSR_ID(48, "mp1_out"),
+	CLK_MSR_ID(49, "mp2_out"),
+	CLK_MSR_ID(50, "mp3_out"),
+	CLK_MSR_ID(51, "sd_emmm_c"),
+	CLK_MSR_ID(52, "sd_emmc_b"),
+	CLK_MSR_ID(61, "gpio_msr"),
+	CLK_MSR_ID(66, "audio_slv_lrclk_c"),
+	CLK_MSR_ID(67, "audio_slv_lrclk_b"),
+	CLK_MSR_ID(68, "audio_slv_lrclk_a"),
+	CLK_MSR_ID(69, "audio_slv_sclk_c"),
+	CLK_MSR_ID(70, "audio_slv_sclk_b"),
+	CLK_MSR_ID(71, "audio_slv_sclk_a"),
+	CLK_MSR_ID(72, "pwm_d"),
+	CLK_MSR_ID(73, "pwm_c"),
+	CLK_MSR_ID(74, "wifi_beacon"),
+	CLK_MSR_ID(75, "tdmin_lb_lrcl"),
+	CLK_MSR_ID(76, "tdmin_lb_sclk"),
+	CLK_MSR_ID(77, "rng_ring_osc_0"),
+	CLK_MSR_ID(78, "rng_ring_osc_1"),
+	CLK_MSR_ID(79, "rng_ring_osc_2"),
+	CLK_MSR_ID(80, "rng_ring_osc_3"),
+	CLK_MSR_ID(81, "vapb"),
+	CLK_MSR_ID(82, "ge2d"),
+	CLK_MSR_ID(84, "audio_resample"),
+	CLK_MSR_ID(85, "audio_pdm_sys"),
+	CLK_MSR_ID(86, "audio_spdifout"),
+	CLK_MSR_ID(87, "audio_spdifin"),
+	CLK_MSR_ID(88, "audio_lrclk_f"),
+	CLK_MSR_ID(89, "audio_lrclk_e"),
+	CLK_MSR_ID(90, "audio_lrclk_d"),
+	CLK_MSR_ID(91, "audio_lrclk_c"),
+	CLK_MSR_ID(92, "audio_lrclk_b"),
+	CLK_MSR_ID(93, "audio_lrclk_a"),
+	CLK_MSR_ID(94, "audio_sclk_f"),
+	CLK_MSR_ID(95, "audio_sclk_e"),
+	CLK_MSR_ID(96, "audio_sclk_d"),
+	CLK_MSR_ID(97, "audio_sclk_c"),
+	CLK_MSR_ID(98, "audio_sclk_b"),
+	CLK_MSR_ID(99, "audio_sclk_a"),
+	CLK_MSR_ID(100, "audio_mclk_f"),
+	CLK_MSR_ID(101, "audio_mclk_e"),
+	CLK_MSR_ID(102, "audio_mclk_d"),
+	CLK_MSR_ID(103, "audio_mclk_c"),
+	CLK_MSR_ID(104, "audio_mclk_b"),
+	CLK_MSR_ID(105, "audio_mclk_a"),
+	CLK_MSR_ID(106, "pcie_refclk_n"),
+	CLK_MSR_ID(107, "pcie_refclk_p"),
+	CLK_MSR_ID(108, "audio_locker_out"),
+	CLK_MSR_ID(109, "audio_locker_in"),
+};
+
+static struct meson_msr_id clk_msr_g12a[CLK_MSR_MAX] = {
+	CLK_MSR_ID(0, "ring_osc_out_ee_0"),
+	CLK_MSR_ID(1, "ring_osc_out_ee_1"),
+	CLK_MSR_ID(2, "ring_osc_out_ee_2"),
+	CLK_MSR_ID(3, "sys_cpu_ring_osc"),
+	CLK_MSR_ID(4, "gp0_pll"),
+	CLK_MSR_ID(6, "enci"),
+	CLK_MSR_ID(7, "clk81"),
+	CLK_MSR_ID(8, "encp"),
+	CLK_MSR_ID(9, "encl"),
+	CLK_MSR_ID(10, "vdac"),
+	CLK_MSR_ID(11, "eth_tx"),
+	CLK_MSR_ID(12, "hifi_pll"),
+	CLK_MSR_ID(13, "mod_tcon"),
+	CLK_MSR_ID(14, "fec_0"),
+	CLK_MSR_ID(15, "fec_1"),
+	CLK_MSR_ID(16, "fec_2"),
+	CLK_MSR_ID(17, "sys_pll_div16"),
+	CLK_MSR_ID(18, "sys_cpu_div16"),
+	CLK_MSR_ID(19, "lcd_an_ph2"),
+	CLK_MSR_ID(20, "rtc_osc_out"),
+	CLK_MSR_ID(21, "lcd_an_ph3"),
+	CLK_MSR_ID(22, "eth_phy_ref"),
+	CLK_MSR_ID(23, "mpll_50m"),
+	CLK_MSR_ID(24, "eth_125m"),
+	CLK_MSR_ID(25, "eth_rmii"),
+	CLK_MSR_ID(26, "sc_int"),
+	CLK_MSR_ID(27, "in_mac"),
+	CLK_MSR_ID(28, "sar_adc"),
+	CLK_MSR_ID(29, "pcie_inp"),
+	CLK_MSR_ID(30, "pcie_inn"),
+	CLK_MSR_ID(31, "mpll_test_out"),
+	CLK_MSR_ID(32, "vdec"),
+	CLK_MSR_ID(33, "sys_cpu_ring_osc_1"),
+	CLK_MSR_ID(34, "eth_mpll_50m"),
+	CLK_MSR_ID(35, "mali"),
+	CLK_MSR_ID(36, "hdmi_tx_pixel"),
+	CLK_MSR_ID(37, "cdac"),
+	CLK_MSR_ID(38, "vdin_meas"),
+	CLK_MSR_ID(39, "bt656"),
+	CLK_MSR_ID(41, "eth_rx_or_rmii"),
+	CLK_MSR_ID(42, "mp0_out"),
+	CLK_MSR_ID(43, "fclk_div5"),
+	CLK_MSR_ID(44, "pwm_b"),
+	CLK_MSR_ID(45, "pwm_a"),
+	CLK_MSR_ID(46, "vpu"),
+	CLK_MSR_ID(47, "ddr_dpll_pt"),
+	CLK_MSR_ID(48, "mp1_out"),
+	CLK_MSR_ID(49, "mp2_out"),
+	CLK_MSR_ID(50, "mp3_out"),
+	CLK_MSR_ID(51, "sd_emmc_c"),
+	CLK_MSR_ID(52, "sd_emmc_b"),
+	CLK_MSR_ID(53, "sd_emmc_a"),
+	CLK_MSR_ID(54, "vpu_clkc"),
+	CLK_MSR_ID(55, "vid_pll_div_out"),
+	CLK_MSR_ID(56, "wave420l_a"),
+	CLK_MSR_ID(57, "wave420l_c"),
+	CLK_MSR_ID(58, "wave420l_b"),
+	CLK_MSR_ID(59, "hcodec"),
+	CLK_MSR_ID(61, "gpio_msr"),
+	CLK_MSR_ID(62, "hevcb"),
+	CLK_MSR_ID(63, "dsi_meas"),
+	CLK_MSR_ID(64, "spicc_1"),
+	CLK_MSR_ID(65, "spicc_0"),
+	CLK_MSR_ID(66, "vid_lock"),
+	CLK_MSR_ID(67, "dsi_phy"),
+	CLK_MSR_ID(68, "hdcp22_esm"),
+	CLK_MSR_ID(69, "hdcp22_skp"),
+	CLK_MSR_ID(70, "pwm_f"),
+	CLK_MSR_ID(71, "pwm_e"),
+	CLK_MSR_ID(72, "pwm_d"),
+	CLK_MSR_ID(73, "pwm_c"),
+	CLK_MSR_ID(75, "hevcf"),
+	CLK_MSR_ID(77, "rng_ring_osc_0"),
+	CLK_MSR_ID(78, "rng_ring_osc_1"),
+	CLK_MSR_ID(79, "rng_ring_osc_2"),
+	CLK_MSR_ID(80, "rng_ring_osc_3"),
+	CLK_MSR_ID(81, "vapb"),
+	CLK_MSR_ID(82, "ge2d"),
+	CLK_MSR_ID(83, "co_rx"),
+	CLK_MSR_ID(84, "co_tx"),
+	CLK_MSR_ID(89, "hdmi_todig"),
+	CLK_MSR_ID(90, "hdmitx_sys"),
+	CLK_MSR_ID(91, "sys_cpub_div16"),
+	CLK_MSR_ID(92, "sys_pll_cpub_div16"),
+	CLK_MSR_ID(94, "eth_phy_rx"),
+	CLK_MSR_ID(95, "eth_phy_pll"),
+	CLK_MSR_ID(96, "vpu_b"),
+	CLK_MSR_ID(97, "cpu_b_tmp"),
+	CLK_MSR_ID(98, "ts"),
+	CLK_MSR_ID(99, "ring_osc_out_ee_3"),
+	CLK_MSR_ID(100, "ring_osc_out_ee_4"),
+	CLK_MSR_ID(101, "ring_osc_out_ee_5"),
+	CLK_MSR_ID(102, "ring_osc_out_ee_6"),
+	CLK_MSR_ID(103, "ring_osc_out_ee_7"),
+	CLK_MSR_ID(104, "ring_osc_out_ee_8"),
+	CLK_MSR_ID(105, "ring_osc_out_ee_9"),
+	CLK_MSR_ID(106, "ephy_test"),
+	CLK_MSR_ID(107, "au_dac_g128x"),
+	CLK_MSR_ID(108, "audio_locker_out"),
+	CLK_MSR_ID(109, "audio_locker_in"),
+	CLK_MSR_ID(110, "audio_tdmout_c_sclk"),
+	CLK_MSR_ID(111, "audio_tdmout_b_sclk"),
+	CLK_MSR_ID(112, "audio_tdmout_a_sclk"),
+	CLK_MSR_ID(113, "audio_tdmin_lb_sclk"),
+	CLK_MSR_ID(114, "audio_tdmin_c_sclk"),
+	CLK_MSR_ID(115, "audio_tdmin_b_sclk"),
+	CLK_MSR_ID(116, "audio_tdmin_a_sclk"),
+	CLK_MSR_ID(117, "audio_resample"),
+	CLK_MSR_ID(118, "audio_pdm_sys"),
+	CLK_MSR_ID(119, "audio_spdifout_b"),
+	CLK_MSR_ID(120, "audio_spdifout"),
+	CLK_MSR_ID(121, "audio_spdifin"),
+	CLK_MSR_ID(122, "audio_pdm_dclk"),
+};
+
+static struct meson_msr_id clk_msr_sm1[CLK_MSR_MAX] = {
+	CLK_MSR_ID(0, "ring_osc_out_ee_0"),
+	CLK_MSR_ID(1, "ring_osc_out_ee_1"),
+	CLK_MSR_ID(2, "ring_osc_out_ee_2"),
+	CLK_MSR_ID(3, "ring_osc_out_ee_3"),
+	CLK_MSR_ID(4, "gp0_pll"),
+	CLK_MSR_ID(5, "gp1_pll"),
+	CLK_MSR_ID(6, "enci"),
+	CLK_MSR_ID(7, "clk81"),
+	CLK_MSR_ID(8, "encp"),
+	CLK_MSR_ID(9, "encl"),
+	CLK_MSR_ID(10, "vdac"),
+	CLK_MSR_ID(11, "eth_tx"),
+	CLK_MSR_ID(12, "hifi_pll"),
+	CLK_MSR_ID(13, "mod_tcon"),
+	CLK_MSR_ID(14, "fec_0"),
+	CLK_MSR_ID(15, "fec_1"),
+	CLK_MSR_ID(16, "fec_2"),
+	CLK_MSR_ID(17, "sys_pll_div16"),
+	CLK_MSR_ID(18, "sys_cpu_div16"),
+	CLK_MSR_ID(19, "lcd_an_ph2"),
+	CLK_MSR_ID(20, "rtc_osc_out"),
+	CLK_MSR_ID(21, "lcd_an_ph3"),
+	CLK_MSR_ID(22, "eth_phy_ref"),
+	CLK_MSR_ID(23, "mpll_50m"),
+	CLK_MSR_ID(24, "eth_125m"),
+	CLK_MSR_ID(25, "eth_rmii"),
+	CLK_MSR_ID(26, "sc_int"),
+	CLK_MSR_ID(27, "in_mac"),
+	CLK_MSR_ID(28, "sar_adc"),
+	CLK_MSR_ID(29, "pcie_inp"),
+	CLK_MSR_ID(30, "pcie_inn"),
+	CLK_MSR_ID(31, "mpll_test_out"),
+	CLK_MSR_ID(32, "vdec"),
+	CLK_MSR_ID(34, "eth_mpll_50m"),
+	CLK_MSR_ID(35, "mali"),
+	CLK_MSR_ID(36, "hdmi_tx_pixel"),
+	CLK_MSR_ID(37, "cdac"),
+	CLK_MSR_ID(38, "vdin_meas"),
+	CLK_MSR_ID(39, "bt656"),
+	CLK_MSR_ID(40, "arm_ring_osc_out_4"),
+	CLK_MSR_ID(41, "eth_rx_or_rmii"),
+	CLK_MSR_ID(42, "mp0_out"),
+	CLK_MSR_ID(43, "fclk_div5"),
+	CLK_MSR_ID(44, "pwm_b"),
+	CLK_MSR_ID(45, "pwm_a"),
+	CLK_MSR_ID(46, "vpu"),
+	CLK_MSR_ID(47, "ddr_dpll_pt"),
+	CLK_MSR_ID(48, "mp1_out"),
+	CLK_MSR_ID(49, "mp2_out"),
+	CLK_MSR_ID(50, "mp3_out"),
+	CLK_MSR_ID(51, "sd_emmc_c"),
+	CLK_MSR_ID(52, "sd_emmc_b"),
+	CLK_MSR_ID(53, "sd_emmc_a"),
+	CLK_MSR_ID(54, "vpu_clkc"),
+	CLK_MSR_ID(55, "vid_pll_div_out"),
+	CLK_MSR_ID(56, "wave420l_a"),
+	CLK_MSR_ID(57, "wave420l_c"),
+	CLK_MSR_ID(58, "wave420l_b"),
+	CLK_MSR_ID(59, "hcodec"),
+	CLK_MSR_ID(60, "arm_ring_osc_out_5"),
+	CLK_MSR_ID(61, "gpio_msr"),
+	CLK_MSR_ID(62, "hevcb"),
+	CLK_MSR_ID(63, "dsi_meas"),
+	CLK_MSR_ID(64, "spicc_1"),
+	CLK_MSR_ID(65, "spicc_0"),
+	CLK_MSR_ID(66, "vid_lock"),
+	CLK_MSR_ID(67, "dsi_phy"),
+	CLK_MSR_ID(68, "hdcp22_esm"),
+	CLK_MSR_ID(69, "hdcp22_skp"),
+	CLK_MSR_ID(70, "pwm_f"),
+	CLK_MSR_ID(71, "pwm_e"),
+	CLK_MSR_ID(72, "pwm_d"),
+	CLK_MSR_ID(73, "pwm_c"),
+	CLK_MSR_ID(74, "arm_ring_osc_out_6"),
+	CLK_MSR_ID(75, "hevcf"),
+	CLK_MSR_ID(76, "arm_ring_osc_out_7"),
+	CLK_MSR_ID(77, "rng_ring_osc_0"),
+	CLK_MSR_ID(78, "rng_ring_osc_1"),
+	CLK_MSR_ID(79, "rng_ring_osc_2"),
+	CLK_MSR_ID(80, "rng_ring_osc_3"),
+	CLK_MSR_ID(81, "vapb"),
+	CLK_MSR_ID(82, "ge2d"),
+	CLK_MSR_ID(83, "co_rx"),
+	CLK_MSR_ID(84, "co_tx"),
+	CLK_MSR_ID(85, "arm_ring_osc_out_8"),
+	CLK_MSR_ID(86, "arm_ring_osc_out_9"),
+	CLK_MSR_ID(87, "mipi_dsi_phy"),
+	CLK_MSR_ID(88, "cis2_adapt"),
+	CLK_MSR_ID(89, "hdmi_todig"),
+	CLK_MSR_ID(90, "hdmitx_sys"),
+	CLK_MSR_ID(91, "nna_core"),
+	CLK_MSR_ID(92, "nna_axi"),
+	CLK_MSR_ID(93, "vad"),
+	CLK_MSR_ID(94, "eth_phy_rx"),
+	CLK_MSR_ID(95, "eth_phy_pll"),
+	CLK_MSR_ID(96, "vpu_b"),
+	CLK_MSR_ID(97, "cpu_b_tmp"),
+	CLK_MSR_ID(98, "ts"),
+	CLK_MSR_ID(99, "arm_ring_osc_out_10"),
+	CLK_MSR_ID(100, "arm_ring_osc_out_11"),
+	CLK_MSR_ID(101, "arm_ring_osc_out_12"),
+	CLK_MSR_ID(102, "arm_ring_osc_out_13"),
+	CLK_MSR_ID(103, "arm_ring_osc_out_14"),
+	CLK_MSR_ID(104, "arm_ring_osc_out_15"),
+	CLK_MSR_ID(105, "arm_ring_osc_out_16"),
+	CLK_MSR_ID(106, "ephy_test"),
+	CLK_MSR_ID(107, "au_dac_g128x"),
+	CLK_MSR_ID(108, "audio_locker_out"),
+	CLK_MSR_ID(109, "audio_locker_in"),
+	CLK_MSR_ID(110, "audio_tdmout_c_sclk"),
+	CLK_MSR_ID(111, "audio_tdmout_b_sclk"),
+	CLK_MSR_ID(112, "audio_tdmout_a_sclk"),
+	CLK_MSR_ID(113, "audio_tdmin_lb_sclk"),
+	CLK_MSR_ID(114, "audio_tdmin_c_sclk"),
+	CLK_MSR_ID(115, "audio_tdmin_b_sclk"),
+	CLK_MSR_ID(116, "audio_tdmin_a_sclk"),
+	CLK_MSR_ID(117, "audio_resample"),
+	CLK_MSR_ID(118, "audio_pdm_sys"),
+	CLK_MSR_ID(119, "audio_spdifout_b"),
+	CLK_MSR_ID(120, "audio_spdifout"),
+	CLK_MSR_ID(121, "audio_spdifin"),
+	CLK_MSR_ID(122, "audio_pdm_dclk"),
+	CLK_MSR_ID(123, "audio_resampled"),
+	CLK_MSR_ID(124, "earcrx_pll"),
+	CLK_MSR_ID(125, "earcrx_pll_test"),
+	CLK_MSR_ID(126, "csi_phy0"),
+	CLK_MSR_ID(127, "csi2_data"),
+};
+
+static int meson_clk_msr_measure_id(struct meson_msr *priv, unsigned int id,
+				    unsigned int duration)
+{
+	unsigned int val;
+	int ret;
+
+	regmap_write(priv->regmap, MSR_CLK_REG0, 0);
+
+	/* Set measurement duration */
+	regmap_update_bits(priv->regmap, MSR_CLK_REG0, MSR_DURATION,
+			   FIELD_PREP(MSR_DURATION, duration - 1));
+
+	/* Set ID */
+	regmap_update_bits(priv->regmap, MSR_CLK_REG0, MSR_CLK_SRC,
+			   FIELD_PREP(MSR_CLK_SRC, id));
+
+	/* Enable & Start */
+	regmap_update_bits(priv->regmap, MSR_CLK_REG0,
+			   MSR_RUN | MSR_ENABLE,
+			   MSR_RUN | MSR_ENABLE);
+
+	ret = regmap_read_poll_timeout(priv->regmap, MSR_CLK_REG0,
+				       val, !(val & MSR_BUSY), 10, 10000);
+	if (ret)
+		return ret;
+
+	/* Disable */
+	regmap_update_bits(priv->regmap, MSR_CLK_REG0, MSR_ENABLE, 0);
+
+	/* Get the value in multiple of gate time counts */
+	regmap_read(priv->regmap, MSR_CLK_REG2, &val);
+
+	if (val >= MSR_VAL_MASK)
+		return -EINVAL;
+
+	return DIV_ROUND_CLOSEST_ULL((val & MSR_VAL_MASK) * 1000000ULL,
+				     duration);
+}
+
+static int meson_clk_msr_best_id(struct meson_msr *priv, unsigned int id,
+				 unsigned int *precision)
+{
+	unsigned int duration = DIV_MAX;
+	int ret;
+
+	/* Start from max duration and down to min duration */
+	do {
+		ret = meson_clk_msr_measure_id(priv, id, duration);
+		if (ret >= 0)
+			*precision = (2 * 1000000) / duration;
+		else
+			duration -= DIV_STEP;
+	} while (duration >= DIV_MIN && ret == -EINVAL);
+
+	return ret;
+}
+
+static void meson_clk_msr_dump(struct udevice *dev)
+{
+	struct meson_msr *priv = dev_get_priv(dev);
+	unsigned int precision = 0;
+	int val, i;
+
+	printf("  clock                     rate    precision\n");
+	printf("---------------------------------------------\n");
+
+	for (i = 0 ; i < CLK_MSR_MAX ; ++i) {
+		if (!priv->msr_table[i].name)
+			continue;
+
+		val = meson_clk_msr_best_id(priv, i, &precision);
+		if (val < 0)
+			return;
+
+		printf(" %-20s %10d    +/-%dHz\n",
+		       priv->msr_table[i].name, val, precision);
+	}
+}
+
+static int meson_clk_msr_xlate(struct clk *clk, struct ofnode_phandle_args *args)
+{
+	/* This driver doesn't expose any clocks */
+	return -EINVAL;
+}
+
+static int meson_clk_msr_probe(struct udevice *dev)
+{
+	struct meson_msr *priv = dev_get_priv(dev);
+	int ret;
+
+	priv->msr_table = (struct meson_msr_id *)dev_get_driver_data(dev);
+
+	ret = regmap_init_mem(dev_ofnode(dev), &priv->regmap);
+	if (ret)
+		return ret;
+
+	return 0;
+}
+
+static struct clk_ops meson_clk_msr_ops = {
+	.of_xlate = meson_clk_msr_xlate,
+	.dump = meson_clk_msr_dump,
+};
+
+static const struct udevice_id meson_clk_msr_ids[] = {
+	{
+		.compatible = "amlogic,meson-gx-clk-measure",
+		.data = (ulong)clk_msr_gx,
+	},
+	{
+		.compatible = "amlogic,meson8-clk-measure",
+		.data = (ulong)clk_msr_m8,
+	},
+	{
+		.compatible = "amlogic,meson8b-clk-measure",
+		.data = (ulong)clk_msr_m8,
+	},
+	{
+		.compatible = "amlogic,meson-axg-clk-measure",
+		.data = (ulong)clk_msr_axg,
+	},
+	{
+		.compatible = "amlogic,meson-g12a-clk-measure",
+		.data = (ulong)clk_msr_g12a,
+	},
+	{
+		.compatible = "amlogic,meson-sm1-clk-measure",
+		.data = (ulong)clk_msr_sm1,
+	},
+	{ /* sentinel */ }
+};
+
+U_BOOT_DRIVER(meson_clk_msr) = {
+	.name		= "meson_clk_msr",
+	.id		= UCLASS_CLK,
+	.of_match	= meson_clk_msr_ids,
+	.priv_auto	= sizeof(struct meson_msr),
+	.ops		= &meson_clk_msr_ops,
+	.probe		= meson_clk_msr_probe,
+};
diff --git a/drivers/clk/mvebu/armada-37xx-periph.c b/drivers/clk/mvebu/armada-37xx-periph.c
index 1a70970..f5c9bd7 100644
--- a/drivers/clk/mvebu/armada-37xx-periph.c
+++ b/drivers/clk/mvebu/armada-37xx-periph.c
@@ -454,7 +454,6 @@
 	if (parent->dev != check_parent.dev)
 		ret = -EINVAL;
 
-	clk_free(&check_parent);
 	if (ret < 0)
 		return ret;
 
@@ -596,7 +595,6 @@
 		}
 
 		priv->parents[i] = clk_get_rate(&clk);
-		clk_free(&clk);
 	}
 
 	return 0;
diff --git a/drivers/cpu/riscv_cpu.c b/drivers/cpu/riscv_cpu.c
index 034b9b4..a9b2537 100644
--- a/drivers/cpu/riscv_cpu.c
+++ b/drivers/cpu/riscv_cpu.c
@@ -45,7 +45,6 @@
 		ret = clk_get_rate(&clk);
 		if (!IS_ERR_VALUE(ret))
 			info->cpu_freq = ret;
-		clk_free(&clk);
 	}
 
 	if (!info->cpu_freq)
@@ -145,7 +144,6 @@
 		return 0;
 
 	ret = clk_enable(&clk);
-	clk_free(&clk);
 	if (ret == -ENOSYS || ret == -ENOTSUPP)
 		return 0;
 	else
diff --git a/drivers/dma/bcm6348-iudma.c b/drivers/dma/bcm6348-iudma.c
index d4cfe0c..33c7b98 100644
--- a/drivers/dma/bcm6348-iudma.c
+++ b/drivers/dma/bcm6348-iudma.c
@@ -596,8 +596,6 @@
 			pr_err("error enabling clock %d\n", i);
 			return ret;
 		}
-
-		clk_free(&clk);
 	}
 
 	/* try to perform resets */
diff --git a/drivers/gpio/at91_gpio.c b/drivers/gpio/at91_gpio.c
index 1409db5..f80f4af 100644
--- a/drivers/gpio/at91_gpio.c
+++ b/drivers/gpio/at91_gpio.c
@@ -603,8 +603,6 @@
 	if (ret)
 		return ret;
 
-	clk_free(&clk);
-
 #if CONFIG_IS_ENABLED(OF_CONTROL)
 	plat->base_addr = dev_read_addr(dev);
 #endif
diff --git a/drivers/gpio/atmel_pio4.c b/drivers/gpio/atmel_pio4.c
index 47ed297..be1dd75 100644
--- a/drivers/gpio/atmel_pio4.c
+++ b/drivers/gpio/atmel_pio4.c
@@ -310,8 +310,6 @@
 	if (ret)
 		return ret;
 
-	clk_free(&clk);
-
 	addr_base = dev_read_addr(dev);
 	if (addr_base == FDT_ADDR_T_NONE)
 		return -EINVAL;
diff --git a/drivers/gpio/gpio-rcar.c b/drivers/gpio/gpio-rcar.c
index d6cfbd2..7077850 100644
--- a/drivers/gpio/gpio-rcar.c
+++ b/drivers/gpio/gpio-rcar.c
@@ -165,7 +165,6 @@
 	}
 
 	ret = clk_enable(&clk);
-	clk_free(&clk);
 	if (ret) {
 		dev_err(dev, "Failed to enable GPIO bank clock\n");
 		return ret;
diff --git a/drivers/hwspinlock/stm32_hwspinlock.c b/drivers/hwspinlock/stm32_hwspinlock.c
index 46ed646..346b138 100644
--- a/drivers/hwspinlock/stm32_hwspinlock.c
+++ b/drivers/hwspinlock/stm32_hwspinlock.c
@@ -69,11 +69,7 @@
 	if (ret)
 		return ret;
 
-	ret = clk_enable(&clk);
-	if (ret)
-		clk_free(&clk);
-
-	return ret;
+	return clk_enable(&clk);
 }
 
 static const struct hwspinlock_ops stm32mp1_hwspinlock_ops = {
diff --git a/drivers/i2c/at91_i2c.c b/drivers/i2c/at91_i2c.c
index e743d2a..b7a2588 100644
--- a/drivers/i2c/at91_i2c.c
+++ b/drivers/i2c/at91_i2c.c
@@ -201,8 +201,6 @@
 
 	bus->bus_clk_rate = clk_rate;
 
-	clk_free(&clk);
-
 	return 0;
 }
 
diff --git a/drivers/i2c/designware_i2c.c b/drivers/i2c/designware_i2c.c
index 215ce01..29cf633 100644
--- a/drivers/i2c/designware_i2c.c
+++ b/drivers/i2c/designware_i2c.c
@@ -770,7 +770,6 @@
 
 	ret = clk_enable(&priv->clk);
 	if (ret && ret != -ENOSYS && ret != -ENOTSUPP) {
-		clk_free(&priv->clk);
 		dev_err(bus, "failed to enable clock\n");
 		return ret;
 	}
@@ -803,7 +802,6 @@
 
 #if CONFIG_IS_ENABLED(CLK)
 	clk_disable(&priv->clk);
-	clk_free(&priv->clk);
 #endif
 
 	return reset_release_bulk(&priv->resets);
diff --git a/drivers/i2c/i2c-microchip.c b/drivers/i2c/i2c-microchip.c
index d82b80f..d453e24 100644
--- a/drivers/i2c/i2c-microchip.c
+++ b/drivers/i2c/i2c-microchip.c
@@ -183,8 +183,6 @@
 	if (!clk_rate)
 		return -EINVAL;
 
-	clk_free(&bus->i2c_clk);
-
 	divisor = clk_rate / bus->clk_rate;
 
 	ctrl = readl(bus->base + MPFS_I2C_CTRL);
diff --git a/drivers/i2c/npcm_i2c.c b/drivers/i2c/npcm_i2c.c
index b867b6c..c64752e 100644
--- a/drivers/i2c/npcm_i2c.c
+++ b/drivers/i2c/npcm_i2c.c
@@ -570,7 +570,6 @@
 		printf("%s: fail to get rate\n", __func__);
 		return -EINVAL;
 	}
-	clk_free(&clk);
 
 	bus->num = dev->seq_;
 	bus->reg = dev_read_addr_ptr(dev);
diff --git a/drivers/i2c/ocores_i2c.c b/drivers/i2c/ocores_i2c.c
index 3b19ba7..fff8511 100644
--- a/drivers/i2c/ocores_i2c.c
+++ b/drivers/i2c/ocores_i2c.c
@@ -396,8 +396,6 @@
 
 	bus->ip_clk_khz = clk_rate / 1000;
 
-	clk_free(&bus->clk);
-
 	return 0;
 }
 
diff --git a/drivers/i2c/stm32f7_i2c.c b/drivers/i2c/stm32f7_i2c.c
index eaa1d69..f42e08a 100644
--- a/drivers/i2c/stm32f7_i2c.c
+++ b/drivers/i2c/stm32f7_i2c.c
@@ -890,7 +890,7 @@
 
 	ret = clk_enable(&i2c_priv->clk);
 	if (ret)
-		goto clk_free;
+		return ret;
 
 	ret = reset_get_by_index(dev, 0, &reset_ctl);
 	if (ret)
@@ -904,8 +904,6 @@
 
 clk_disable:
 	clk_disable(&i2c_priv->clk);
-clk_free:
-	clk_free(&i2c_priv->clk);
 
 	return ret;
 }
diff --git a/drivers/mailbox/stm32-ipcc.c b/drivers/mailbox/stm32-ipcc.c
index 69c86e0..046e1a8 100644
--- a/drivers/mailbox/stm32-ipcc.c
+++ b/drivers/mailbox/stm32-ipcc.c
@@ -134,18 +134,13 @@
 
 	ret = clk_enable(&clk);
 	if (ret)
-		goto clk_free;
+		return ret;
 
 	/* get channel number */
 	ipcc->n_chans = readl(ipcc->reg_base + IPCC_HWCFGR);
 	ipcc->n_chans &= IPCFGR_CHAN_MASK;
 
 	return 0;
-
-clk_free:
-	clk_free(&clk);
-
-	return ret;
 }
 
 static const struct udevice_id stm32_ipcc_ids[] = {
diff --git a/drivers/misc/ls2_sfp.c b/drivers/misc/ls2_sfp.c
index 2a81bc7..5351c7e 100644
--- a/drivers/misc/ls2_sfp.c
+++ b/drivers/misc/ls2_sfp.c
@@ -249,7 +249,6 @@
 		}
 
 		rate = clk_get_rate(&clk);
-		clk_free(&clk);
 		if (!rate || IS_ERR_VALUE(rate)) {
 			ret = rate ? rate : -ENOENT;
 			dev_dbg(dev, "could not get clock rate (err %d)\n",
diff --git a/drivers/mmc/arm_pl180_mmci.c b/drivers/mmc/arm_pl180_mmci.c
index 9c5d48e..5cf5502 100644
--- a/drivers/mmc/arm_pl180_mmci.c
+++ b/drivers/mmc/arm_pl180_mmci.c
@@ -447,7 +447,6 @@
 
 	ret = clk_enable(&clk);
 	if (ret) {
-		clk_free(&clk);
 		dev_err(dev, "failed to enable clock\n");
 		return ret;
 	}
diff --git a/drivers/mmc/aspeed_sdhci.c b/drivers/mmc/aspeed_sdhci.c
index 9d79bf5..c9626c6 100644
--- a/drivers/mmc/aspeed_sdhci.c
+++ b/drivers/mmc/aspeed_sdhci.c
@@ -35,7 +35,7 @@
 	ret = clk_enable(&clk);
 	if (ret) {
 		debug("%s: clock enable failed %d\n", __func__, ret);
-		goto free;
+		return ret;
 	}
 
 	host->name = dev->name;
@@ -66,8 +66,6 @@
 
 err:
 	clk_disable(&clk);
-free:
-	clk_free(&clk);
 	return ret;
 }
 
diff --git a/drivers/mmc/atmel_sdhci.c b/drivers/mmc/atmel_sdhci.c
index 5347ba9..d92bad9 100644
--- a/drivers/mmc/atmel_sdhci.c
+++ b/drivers/mmc/atmel_sdhci.c
@@ -147,8 +147,6 @@
 	host->ops = &atmel_sdhci_ops;
 	upriv->mmc = host->mmc;
 
-	clk_free(&clk);
-
 	ret = sdhci_probe(dev);
 	if (ret)
 		return ret;
diff --git a/drivers/mmc/gen_atmel_mci.c b/drivers/mmc/gen_atmel_mci.c
index d91819a..3ee9955 100644
--- a/drivers/mmc/gen_atmel_mci.c
+++ b/drivers/mmc/gen_atmel_mci.c
@@ -559,27 +559,20 @@
 	int ret = 0;
 
 	ret = clk_get_by_index(dev, 0, &clk);
-	if (ret) {
-		ret = -EINVAL;
-		goto failed;
-	}
+	if (ret)
+		return -EINVAL;
 
 	ret = clk_enable(&clk);
 	if (ret)
-		goto failed;
+		return ret;
 
 	clk_rate = clk_get_rate(&clk);
-	if (!clk_rate) {
-		ret = -EINVAL;
-		goto failed;
-	}
+	if (!clk_rate)
+		return -EINVAL;
 
 	priv->bus_clk_rate = clk_rate;
 
-failed:
-	clk_free(&clk);
-
-	return ret;
+	return 0;
 }
 
 static int atmel_mci_probe(struct udevice *dev)
diff --git a/drivers/mmc/msm_sdhci.c b/drivers/mmc/msm_sdhci.c
index 604f9c3..fe1e754 100644
--- a/drivers/mmc/msm_sdhci.c
+++ b/drivers/mmc/msm_sdhci.c
@@ -81,7 +81,6 @@
 		return ret;
 
 	ret = clk_set_rate(&clk, clk_rate);
-	clk_free(&clk);
 	if (ret < 0)
 		return ret;
 
diff --git a/drivers/mmc/pic32_sdhci.c b/drivers/mmc/pic32_sdhci.c
index fe55510..7a8e33d 100644
--- a/drivers/mmc/pic32_sdhci.c
+++ b/drivers/mmc/pic32_sdhci.c
@@ -32,7 +32,6 @@
 		return ret;
 
 	clk_rate = clk_get_rate(&clk);
-	clk_free(&clk);
 
 	if (IS_ERR_VALUE(clk_rate))
 		return clk_rate;
diff --git a/drivers/mmc/renesas-sdhi.c b/drivers/mmc/renesas-sdhi.c
index 97aaf1e..a74559c 100644
--- a/drivers/mmc/renesas-sdhi.c
+++ b/drivers/mmc/renesas-sdhi.c
@@ -979,19 +979,19 @@
 	ret = clk_get_by_name(dev, "cd", &imclk2);
 	if (ret < 0) {
 		dev_err(dev, "failed to get imclk2 (chip detect clk)\n");
-		goto err_get_imclk2;
+		return ret;
 	}
 
 	ret = clk_get_by_name(dev, "aclk", &aclk);
 	if (ret < 0) {
 		dev_err(dev, "failed to get aclk\n");
-		goto err_get_aclk;
+		return ret;
 	}
 
 	ret = clk_enable(&imclk2);
 	if (ret < 0) {
 		dev_err(dev, "failed to enable imclk2 (chip detect clk)\n");
-		goto err_imclk2;
+		return ret;
 	}
 
 	ret = clk_enable(&aclk);
@@ -1026,11 +1026,6 @@
 	clk_disable(&aclk);
 err_aclk:
 	clk_disable(&imclk2);
-err_imclk2:
-	clk_free(&aclk);
-err_get_aclk:
-	clk_free(&imclk2);
-err_get_imclk2:
 	return ret;
 }
 
@@ -1071,7 +1066,7 @@
 		ret = clk_set_rate(&priv->clkh, 800000000);
 		if (ret < 0) {
 			dev_err(dev, "failed to set rate for SDnH clock (%d)\n", ret);
-			goto err_clk;
+			return ret;
 		}
 	}
 
@@ -1079,13 +1074,13 @@
 	ret = clk_set_rate(&priv->clk, 200000000);
 	if (ret < 0) {
 		dev_err(dev, "failed to set rate for SDn clock (%d)\n", ret);
-		goto err_clkh;
+		return ret;
 	}
 
 	ret = clk_enable(&priv->clk);
 	if (ret) {
 		dev_err(dev, "failed to enable SDn clock (%d)\n", ret);
-		goto err_clkh;
+		return ret;
 	}
 
 	if (device_is_compatible(dev, "renesas,sdhi-r9a07g044"))
@@ -1107,10 +1102,6 @@
 
 err_tmio_probe:
 	clk_disable(&priv->clk);
-err_clkh:
-	clk_free(&priv->clkh);
-err_clk:
-	clk_free(&priv->clk);
 	return ret;
 }
 
diff --git a/drivers/mmc/snps_dw_mmc.c b/drivers/mmc/snps_dw_mmc.c
index 50a8805..0134399 100644
--- a/drivers/mmc/snps_dw_mmc.c
+++ b/drivers/mmc/snps_dw_mmc.c
@@ -46,7 +46,7 @@
 
 	ret = clk_enable(&clk_ciu);
 	if (ret && ret != -ENOSYS && ret != -ENOTSUPP)
-		goto clk_err_ciu;
+		goto clk_err;
 
 	host->bus_hz = clk_get_rate(&clk_ciu);
 	if (host->bus_hz < CLOCK_MIN) {
@@ -60,16 +60,12 @@
 
 	ret = clk_enable(&clk_biu);
 	if (ret && ret != -ENOSYS && ret != -ENOTSUPP)
-		goto clk_err_biu;
+		goto clk_err_ciu_dis;
 
 	return 0;
 
-clk_err_biu:
-	clk_free(&clk_biu);
 clk_err_ciu_dis:
 	clk_disable(&clk_ciu);
-clk_err_ciu:
-	clk_free(&clk_ciu);
 clk_err:
 	dev_err(dev, "failed to setup clocks, ret %d\n", ret);
 
diff --git a/drivers/mmc/socfpga_dw_mmc.c b/drivers/mmc/socfpga_dw_mmc.c
index be3d8bf..387cb8b 100644
--- a/drivers/mmc/socfpga_dw_mmc.c
+++ b/drivers/mmc/socfpga_dw_mmc.c
@@ -99,7 +99,6 @@
 
 	host->bus_hz = clk_get_rate(&clk);
 
-	clk_free(&clk);
 #else
 	/* Fixed clock divide by 4 which due to the SDMMC wrapper */
 	host->bus_hz = cm_get_mmc_controller_clk_hz();
diff --git a/drivers/mmc/stm32_sdmmc2.c b/drivers/mmc/stm32_sdmmc2.c
index 5ff5e1a..a2b111a 100644
--- a/drivers/mmc/stm32_sdmmc2.c
+++ b/drivers/mmc/stm32_sdmmc2.c
@@ -766,10 +766,8 @@
 	int ret;
 
 	ret = clk_enable(&plat->clk);
-	if (ret) {
-		clk_free(&plat->clk);
+	if (ret)
 		return ret;
-	}
 
 	upriv->mmc = &plat->mmc;
 
diff --git a/drivers/mmc/uniphier-sd.c b/drivers/mmc/uniphier-sd.c
index 75003a0..8cde430 100644
--- a/drivers/mmc/uniphier-sd.c
+++ b/drivers/mmc/uniphier-sd.c
@@ -64,7 +64,6 @@
 	ret = clk_set_rate(&priv->clk, ULONG_MAX);
 	if (ret < 0) {
 		dev_err(dev, "failed to set rate for host clock\n");
-		clk_free(&priv->clk);
 		return ret;
 	}
 
diff --git a/drivers/mtd/nand/raw/atmel/nand-controller.c b/drivers/mtd/nand/raw/atmel/nand-controller.c
index a2151f9..0e04414 100644
--- a/drivers/mtd/nand/raw/atmel/nand-controller.c
+++ b/drivers/mtd/nand/raw/atmel/nand-controller.c
@@ -1999,10 +1999,8 @@
 
 	hsmc_nc = container_of(nc, struct atmel_hsmc_nand_controller, base);
 
-	if (hsmc_nc->clk) {
+	if (hsmc_nc->clk)
 		clk_disable_unprepare(hsmc_nc->clk);
-		devm_clk_put(nc->dev, hsmc_nc->clk);
-	}
 
 	return 0;
 }
diff --git a/drivers/mtd/renesas_rpc_hf.c b/drivers/mtd/renesas_rpc_hf.c
index aca7a6c..979b64d 100644
--- a/drivers/mtd/renesas_rpc_hf.c
+++ b/drivers/mtd/renesas_rpc_hf.c
@@ -370,7 +370,6 @@
 	}
 
 	ret = clk_enable(&clk);
-	clk_free(&clk);
 	if (ret) {
 		dev_err(dev, "Failed to enable RPC clock\n");
 		return ret;
diff --git a/drivers/net/bcm6348-eth.c b/drivers/net/bcm6348-eth.c
index 72dcd07..15a94f6 100644
--- a/drivers/net/bcm6348-eth.c
+++ b/drivers/net/bcm6348-eth.c
@@ -457,8 +457,6 @@
 			pr_err("%s: error enabling clock %d\n", __func__, i);
 			return ret;
 		}
-
-		clk_free(&clk);
 	}
 
 	/* try to perform resets */
diff --git a/drivers/net/bcm6368-eth.c b/drivers/net/bcm6368-eth.c
index fdd938c..9679a45 100644
--- a/drivers/net/bcm6368-eth.c
+++ b/drivers/net/bcm6368-eth.c
@@ -546,8 +546,6 @@
 			pr_err("%s: error enabling clock %d\n", __func__, i);
 			return ret;
 		}
-
-		clk_free(&clk);
 	}
 
 	/* try to perform resets */
diff --git a/drivers/net/designware.c b/drivers/net/designware.c
index a174344..c869635 100644
--- a/drivers/net/designware.c
+++ b/drivers/net/designware.c
@@ -702,7 +702,6 @@
 			err = clk_enable(&priv->clocks[i]);
 			if (err && err != -ENOSYS && err != -ENOTSUPP) {
 				pr_err("failed to enable clock %d\n", i);
-				clk_free(&priv->clocks[i]);
 				goto clk_err;
 			}
 			priv->clock_count++;
diff --git a/drivers/net/dwc_eth_qos.c b/drivers/net/dwc_eth_qos.c
index e40e399..9b3bce1 100644
--- a/drivers/net/dwc_eth_qos.c
+++ b/drivers/net/dwc_eth_qos.c
@@ -1382,38 +1382,30 @@
 	ret = clk_get_by_name(dev, "master_bus", &eqos->clk_master_bus);
 	if (ret) {
 		pr_err("clk_get_by_name(master_bus) failed: %d", ret);
-		goto err_free_clk_slave_bus;
+		goto err_free_gpio_phy_reset;
 	}
 
 	ret = clk_get_by_name(dev, "rx", &eqos->clk_rx);
 	if (ret) {
 		pr_err("clk_get_by_name(rx) failed: %d", ret);
-		goto err_free_clk_master_bus;
+		goto err_free_gpio_phy_reset;
 	}
 
 	ret = clk_get_by_name(dev, "ptp_ref", &eqos->clk_ptp_ref);
 	if (ret) {
 		pr_err("clk_get_by_name(ptp_ref) failed: %d", ret);
-		goto err_free_clk_rx;
+		goto err_free_gpio_phy_reset;
 	}
 
 	ret = clk_get_by_name(dev, "tx", &eqos->clk_tx);
 	if (ret) {
 		pr_err("clk_get_by_name(tx) failed: %d", ret);
-		goto err_free_clk_ptp_ref;
+		goto err_free_gpio_phy_reset;
 	}
 
 	debug("%s: OK\n", __func__);
 	return 0;
 
-err_free_clk_ptp_ref:
-	clk_free(&eqos->clk_ptp_ref);
-err_free_clk_rx:
-	clk_free(&eqos->clk_rx);
-err_free_clk_master_bus:
-	clk_free(&eqos->clk_master_bus);
-err_free_clk_slave_bus:
-	clk_free(&eqos->clk_slave_bus);
 err_free_gpio_phy_reset:
 	dm_gpio_free(dev, &eqos->phy_reset_gpio);
 err_free_reset_eqos:
@@ -1451,13 +1443,13 @@
 	ret = clk_get_by_name(dev, "mac-clk-rx", &eqos->clk_rx);
 	if (ret) {
 		pr_err("clk_get_by_name(rx) failed: %d", ret);
-		goto err_free_clk_master_bus;
+		goto err_probe;
 	}
 
 	ret = clk_get_by_name(dev, "mac-clk-tx", &eqos->clk_tx);
 	if (ret) {
 		pr_err("clk_get_by_name(tx) failed: %d", ret);
-		goto err_free_clk_rx;
+		goto err_probe;
 	}
 
 	/*  Get ETH_CLK clocks (optional) */
@@ -1468,10 +1460,6 @@
 	debug("%s: OK\n", __func__);
 	return 0;
 
-err_free_clk_rx:
-	clk_free(&eqos->clk_rx);
-err_free_clk_master_bus:
-	clk_free(&eqos->clk_master_bus);
 err_probe:
 
 	debug("%s: returns %d\n", __func__, ret);
@@ -1489,13 +1477,6 @@
 
 	debug("%s(dev=%p):\n", __func__, dev);
 
-#ifdef CONFIG_CLK
-	clk_free(&eqos->clk_tx);
-	clk_free(&eqos->clk_ptp_ref);
-	clk_free(&eqos->clk_rx);
-	clk_free(&eqos->clk_slave_bus);
-	clk_free(&eqos->clk_master_bus);
-#endif
 	dm_gpio_free(dev, &eqos->phy_reset_gpio);
 	reset_free(&eqos->reset_ctl);
 
@@ -1505,19 +1486,7 @@
 
 static int eqos_remove_resources_stm32(struct udevice *dev)
 {
-	struct eqos_priv * __maybe_unused eqos = dev_get_priv(dev);
-
 	debug("%s(dev=%p):\n", __func__, dev);
-
-#ifdef CONFIG_CLK
-	clk_free(&eqos->clk_tx);
-	clk_free(&eqos->clk_rx);
-	clk_free(&eqos->clk_master_bus);
-	if (clk_valid(&eqos->clk_ck))
-		clk_free(&eqos->clk_ck);
-#endif
-
-	debug("%s: OK\n", __func__);
 	return 0;
 }
 
diff --git a/drivers/net/dwc_eth_qos_imx.c b/drivers/net/dwc_eth_qos_imx.c
index e3f55dd..9c4e390 100644
--- a/drivers/net/dwc_eth_qos_imx.c
+++ b/drivers/net/dwc_eth_qos_imx.c
@@ -70,30 +70,24 @@
 	ret = clk_get_by_name(dev, "ptp_ref", &eqos->clk_ptp_ref);
 	if (ret) {
 		dev_dbg(dev, "clk_get_by_name(ptp_ref) failed: %d", ret);
-		goto err_free_clk_master_bus;
+		goto err_probe;
 	}
 
 	ret = clk_get_by_name(dev, "tx", &eqos->clk_tx);
 	if (ret) {
 		dev_dbg(dev, "clk_get_by_name(tx) failed: %d", ret);
-		goto err_free_clk_ptp_ref;
+		goto err_probe;
 	}
 
 	ret = clk_get_by_name(dev, "pclk", &eqos->clk_ck);
 	if (ret) {
 		dev_dbg(dev, "clk_get_by_name(pclk) failed: %d", ret);
-		goto err_free_clk_tx;
+		goto err_probe;
 	}
 
 	debug("%s: OK\n", __func__);
 	return 0;
 
-err_free_clk_tx:
-	clk_free(&eqos->clk_tx);
-err_free_clk_ptp_ref:
-	clk_free(&eqos->clk_ptp_ref);
-err_free_clk_master_bus:
-	clk_free(&eqos->clk_master_bus);
 err_probe:
 
 	debug("%s: returns %d\n", __func__, ret);
@@ -102,16 +96,7 @@
 
 static int eqos_remove_resources_imx(struct udevice *dev)
 {
-	struct eqos_priv *eqos = dev_get_priv(dev);
-
 	debug("%s(dev=%p):\n", __func__, dev);
-
-	clk_free(&eqos->clk_ck);
-	clk_free(&eqos->clk_tx);
-	clk_free(&eqos->clk_ptp_ref);
-	clk_free(&eqos->clk_master_bus);
-
-	debug("%s: OK\n", __func__);
 	return 0;
 }
 
diff --git a/drivers/net/dwc_eth_qos_qcom.c b/drivers/net/dwc_eth_qos_qcom.c
index df83f1c..8178138 100644
--- a/drivers/net/dwc_eth_qos_qcom.c
+++ b/drivers/net/dwc_eth_qos_qcom.c
@@ -575,7 +575,6 @@
 
 	debug("%s(dev=%p):\n", __func__, dev);
 
-	clk_free(&eqos->clk_tx);
 	dm_gpio_free(dev, &eqos->phy_reset_gpio);
 	reset_free(&eqos->reset_ctl);
 
diff --git a/drivers/net/dwc_eth_qos_rockchip.c b/drivers/net/dwc_eth_qos_rockchip.c
index 834307a..fa9e513 100644
--- a/drivers/net/dwc_eth_qos_rockchip.c
+++ b/drivers/net/dwc_eth_qos_rockchip.c
@@ -372,7 +372,7 @@
 		ret = clk_get_by_name(dev, "clk_mac_speed", &eqos->clk_tx);
 		if (ret) {
 			dev_dbg(dev, "clk_get_by_name(clk_mac_speed) failed: %d", ret);
-			goto err_free_clk_master_bus;
+			goto err_release_resets;
 		}
 	}
 
@@ -393,8 +393,6 @@
 
 	return 0;
 
-err_free_clk_master_bus:
-	clk_free(&eqos->clk_master_bus);
 err_release_resets:
 	reset_release_bulk(&data->resets);
 err_free:
@@ -412,8 +410,6 @@
 	if (dm_gpio_is_valid(&eqos->phy_reset_gpio))
 		dm_gpio_free(dev, &eqos->phy_reset_gpio);
 
-	clk_free(&eqos->clk_tx);
-	clk_free(&eqos->clk_master_bus);
 	reset_release_bulk(&data->resets);
 	free(data);
 
diff --git a/drivers/net/sni_ave.c b/drivers/net/sni_ave.c
index 8eeecbc..a265ce9 100644
--- a/drivers/net/sni_ave.c
+++ b/drivers/net/sni_ave.c
@@ -777,7 +777,7 @@
 		if (ret) {
 			dev_err(dev, "Failed to get clocks property: %d\n",
 				ret);
-			goto out_clk_free;
+			return ret;
 		}
 		priv->nclks++;
 	}
@@ -823,9 +823,6 @@
 out_reset_free:
 	while (--nr >= 0)
 		reset_free(&priv->rst[nr]);
-out_clk_free:
-	while (--nc >= 0)
-		clk_free(&priv->clk[nc]);
 
 	return ret;
 }
diff --git a/drivers/net/ti/am65-cpsw-nuss.c b/drivers/net/ti/am65-cpsw-nuss.c
index 18a33c4..6da018c 100644
--- a/drivers/net/ti/am65-cpsw-nuss.c
+++ b/drivers/net/ti/am65-cpsw-nuss.c
@@ -948,7 +948,6 @@
 		 cpsw_common->bus_freq);
 
 out:
-	clk_free(&cpsw_common->fclk);
 	power_domain_free(&cpsw_common->pwrdmn);
 	return ret;
 }
diff --git a/drivers/phy/bcm6318-usbh-phy.c b/drivers/phy/bcm6318-usbh-phy.c
index 1c10853..a2fa446 100644
--- a/drivers/phy/bcm6318-usbh-phy.c
+++ b/drivers/phy/bcm6318-usbh-phy.c
@@ -98,8 +98,6 @@
 	if (ret < 0)
 		return ret;
 
-	clk_free(&clk);
-
 	/* enable power domain */
 	ret = power_domain_get(dev, &pwr_dom);
 	if (ret < 0)
diff --git a/drivers/phy/bcm6348-usbh-phy.c b/drivers/phy/bcm6348-usbh-phy.c
index ce6be3d..857fb57 100644
--- a/drivers/phy/bcm6348-usbh-phy.c
+++ b/drivers/phy/bcm6348-usbh-phy.c
@@ -62,8 +62,6 @@
 	if (ret < 0)
 		return ret;
 
-	clk_free(&clk);
-
 	/* perform reset */
 	ret = reset_get_by_index(dev, 0, &rst_ctl);
 	if (ret < 0)
diff --git a/drivers/phy/bcm6368-usbh-phy.c b/drivers/phy/bcm6368-usbh-phy.c
index d057f1f..1a2870d 100644
--- a/drivers/phy/bcm6368-usbh-phy.c
+++ b/drivers/phy/bcm6368-usbh-phy.c
@@ -137,8 +137,6 @@
 	if (ret < 0)
 		return ret;
 
-	clk_free(&clk);
-
 #if defined(CONFIG_POWER_DOMAIN)
 	/* enable power domain */
 	ret = power_domain_get(dev, &pwr_dom);
@@ -173,8 +171,6 @@
 		ret = clk_enable(&clk);
 		if (ret < 0)
 			return ret;
-
-		clk_free(&clk);
 	}
 
 	mdelay(100);
diff --git a/drivers/phy/meson-axg-mipi-dphy.c b/drivers/phy/meson-axg-mipi-dphy.c
index a69b6c9..faa1d9d 100644
--- a/drivers/phy/meson-axg-mipi-dphy.c
+++ b/drivers/phy/meson-axg-mipi-dphy.c
@@ -369,7 +369,6 @@
 	ret = clk_enable(&priv->clk);
 	if (ret && ret != -ENOSYS && ret != -ENOTSUPP) {
 		pr_err("failed to enable PHY clock\n");
-		clk_free(&priv->clk);
 		return ret;
 	}
 #endif
diff --git a/drivers/phy/meson-g12a-usb3-pcie.c b/drivers/phy/meson-g12a-usb3-pcie.c
index 40a5da9..1eaff41 100644
--- a/drivers/phy/meson-g12a-usb3-pcie.c
+++ b/drivers/phy/meson-g12a-usb3-pcie.c
@@ -398,7 +398,6 @@
 	ret = clk_enable(&priv->clk);
 	if (ret && ret != -ENOENT && ret != -ENOTSUPP) {
 		pr_err("failed to enable PHY clock\n");
-		clk_free(&priv->clk);
 		return ret;
 	}
 #endif
diff --git a/drivers/phy/meson-gxl-usb2.c b/drivers/phy/meson-gxl-usb2.c
index 8f5e4a4..d633eff 100644
--- a/drivers/phy/meson-gxl-usb2.c
+++ b/drivers/phy/meson-gxl-usb2.c
@@ -203,7 +203,6 @@
 	ret = clk_enable(&priv->clk);
 	if (ret && ret != -ENOSYS && ret != -ENOTSUPP) {
 		pr_err("failed to enable PHY clock\n");
-		clk_free(&priv->clk);
 		return ret;
 	}
 #endif
diff --git a/drivers/phy/phy-rcar-gen2.c b/drivers/phy/phy-rcar-gen2.c
index 1794095..e528c4e 100644
--- a/drivers/phy/phy-rcar-gen2.c
+++ b/drivers/phy/phy-rcar-gen2.c
@@ -172,7 +172,6 @@
 	struct rcar_gen2_phy *priv = dev_get_priv(dev);
 
 	clk_disable(&priv->clk);
-	clk_free(&priv->clk);
 
 	return 0;
 }
diff --git a/drivers/phy/phy-rcar-gen3.c b/drivers/phy/phy-rcar-gen3.c
index 7159e7e..03c747b 100644
--- a/drivers/phy/phy-rcar-gen3.c
+++ b/drivers/phy/phy-rcar-gen3.c
@@ -142,7 +142,6 @@
 	struct rcar_gen3_phy *priv = dev_get_priv(dev);
 
 	clk_disable(&priv->clk);
-	clk_free(&priv->clk);
 
 	return 0;
 }
diff --git a/drivers/pinctrl/pinctrl-k210.c b/drivers/pinctrl/pinctrl-k210.c
index 13f0a34..ee35dfe 100644
--- a/drivers/pinctrl/pinctrl-k210.c
+++ b/drivers/pinctrl/pinctrl-k210.c
@@ -691,23 +691,19 @@
 
 	ret = clk_enable(&priv->clk);
 	if (ret && ret != -ENOSYS && ret != -ENOTSUPP)
-		goto err;
+		return ret;
 
 	ret = dev_read_phandle_with_args(dev, "canaan,k210-sysctl-power",
 					NULL, 1, 0, &args);
         if (ret)
-		goto err;
+		return ret;
 
-	if (args.args_count != 1) {
-		ret = -EINVAL;
-		goto err;
-        }
+	if (args.args_count != 1)
+		return -EINVAL;
 
 	priv->sysctl = syscon_node_to_regmap(args.node);
-	if (IS_ERR(priv->sysctl)) {
-		ret = PTR_ERR(priv->sysctl);
-		goto err;
-	}
+	if (IS_ERR(priv->sysctl))
+		return PTR_ERR(priv->sysctl);
 
 	priv->power_offset = args.args[0];
 
@@ -728,10 +724,6 @@
 	}
 
 	return 0;
-
-err:
-	clk_free(&priv->clk);
-	return ret;
 }
 
 static const struct udevice_id k210_pc_ids[] = {
diff --git a/drivers/power/domain/imx8mp-hsiomix.c b/drivers/power/domain/imx8mp-hsiomix.c
index 6a721a9..e2d772c 100644
--- a/drivers/power/domain/imx8mp-hsiomix.c
+++ b/drivers/power/domain/imx8mp-hsiomix.c
@@ -111,7 +111,7 @@
 
 	ret = power_domain_get_by_name(dev, &priv->pd_bus, "bus");
 	if (ret < 0)
-		goto err_pd_bus;
+		return ret;
 
 	ret = power_domain_get_by_name(dev, &priv->pd_usb, "usb");
 	if (ret < 0)
@@ -133,8 +133,6 @@
 	power_domain_free(&priv->pd_usb);
 err_pd_usb:
 	power_domain_free(&priv->pd_bus);
-err_pd_bus:
-	clk_free(&priv->clk_usb);
 	return ret;
 }
 
diff --git a/drivers/rtc/stm32_rtc.c b/drivers/rtc/stm32_rtc.c
index 1753283..ec7584c 100644
--- a/drivers/rtc/stm32_rtc.c
+++ b/drivers/rtc/stm32_rtc.c
@@ -223,10 +223,8 @@
 		return ret;
 
 	ret = clk_enable(&clk);
-	if (ret) {
-		clk_free(&clk);
+	if (ret)
 		return ret;
-	}
 
 	rate = clk_get_rate(&clk);
 
@@ -275,10 +273,8 @@
 unlock:
 	stm32_rtc_lock(dev);
 
-	if (ret) {
+	if (ret)
 		clk_disable(&clk);
-		clk_free(&clk);
-	}
 
 	return ret;
 }
@@ -298,17 +294,13 @@
 		return ret;
 
 	ret = clk_enable(&clk);
-	if (ret) {
-		clk_free(&clk);
+	if (ret)
 		return ret;
-	}
 
 	ret = stm32_rtc_init(dev);
 
-	if (ret) {
+	if (ret)
 		clk_disable(&clk);
-		clk_free(&clk);
-	}
 
 	return ret;
 }
diff --git a/drivers/serial/atmel_usart.c b/drivers/serial/atmel_usart.c
index 9853f49..9827c00 100644
--- a/drivers/serial/atmel_usart.c
+++ b/drivers/serial/atmel_usart.c
@@ -253,8 +253,6 @@
 
 	priv->usart_clk_rate = clk_rate;
 
-	clk_free(&clk);
-
 	return 0;
 }
 #endif
diff --git a/drivers/serial/serial_bcm6345.c b/drivers/serial/serial_bcm6345.c
index 2359656..13bc517 100644
--- a/drivers/serial/serial_bcm6345.c
+++ b/drivers/serial/serial_bcm6345.c
@@ -239,7 +239,6 @@
 	if (ret < 0)
 		return ret;
 	priv->uartclk = clk_get_rate(&clk);
-	clk_free(&clk);
 
 	/* initialize serial */
 	return bcm6345_serial_init(priv->base, priv->uartclk, CONFIG_BAUDRATE);
diff --git a/drivers/serial/serial_msm.c b/drivers/serial/serial_msm.c
index a22623c..f4d9631 100644
--- a/drivers/serial/serial_msm.c
+++ b/drivers/serial/serial_msm.c
@@ -185,7 +185,6 @@
 		return ret;
 
 	ret = clk_set_rate(&clk, clk_rate);
-	clk_free(&clk);
 	if (ret < 0)
 		return ret;
 
diff --git a/drivers/serial/serial_pic32.c b/drivers/serial/serial_pic32.c
index 3c5d37c..0a03a9a 100644
--- a/drivers/serial/serial_pic32.c
+++ b/drivers/serial/serial_pic32.c
@@ -155,7 +155,6 @@
 	if (ret < 0)
 		return ret;
 	priv->uartclk = clk_get_rate(&clk);
-	clk_free(&clk);
 
 	/* initialize serial */
 	return pic32_serial_init(priv->base, priv->uartclk, CONFIG_BAUDRATE);
diff --git a/drivers/spi/atcspi200_spi.c b/drivers/spi/atcspi200_spi.c
index de9c148..70cb242 100644
--- a/drivers/spi/atcspi200_spi.c
+++ b/drivers/spi/atcspi200_spi.c
@@ -362,7 +362,6 @@
 		return -EINVAL;
 
 	ns->clock = clk_rate;
-	clk_free(&clk);
 
 	return 0;
 }
diff --git a/drivers/spi/atmel-quadspi.c b/drivers/spi/atmel-quadspi.c
index cb64119..bd73e4f 100644
--- a/drivers/spi/atmel-quadspi.c
+++ b/drivers/spi/atmel-quadspi.c
@@ -877,7 +877,6 @@
 	ret = clk_enable(&gclk);
 	if (ret)
 		dev_err(bus, "Failed to enable QSPI generic clock\n");
-	clk_free(&gclk);
 
 	return ret;
 }
@@ -1000,7 +999,7 @@
 	ret = clk_enable(&pclk);
 	if (ret) {
 		dev_err(dev, "Failed to enable QSPI peripheral clock\n");
-		goto free_pclk;
+		return ret;
 	}
 
 	if (aq->caps->has_qspick) {
@@ -1008,32 +1007,27 @@
 		ret = clk_get_by_name(dev, "qspick", &qspick);
 		if (ret) {
 			dev_err(dev, "Missing QSPI peripheral clock\n");
-			goto free_pclk;
+			return ret;
 		}
 
 		ret = clk_enable(&qspick);
 		if (ret)
 			dev_err(dev, "Failed to enable QSPI system clock\n");
-		clk_free(&qspick);
 	} else if (aq->caps->has_gclk) {
 		ret = clk_get_by_name(dev, "gclk", &gclk);
 		if (ret) {
 			dev_err(dev, "Missing QSPI generic clock\n");
-			goto free_pclk;
+			return ret;
 		}
 
 		ret = clk_enable(&gclk);
 		if (ret)
 			dev_err(dev, "Failed to enable QSPI system clock\n");
-		clk_free(&gclk);
 	}
 
 	aq->bus_clk_rate = clk_get_rate(&pclk);
 	if (!aq->bus_clk_rate)
-		ret = -EINVAL;
-
-free_pclk:
-	clk_free(&pclk);
+		return -EINVAL;
 
 	return ret;
 }
diff --git a/drivers/spi/atmel_spi.c b/drivers/spi/atmel_spi.c
index aec6f4e..d4f0c4c 100644
--- a/drivers/spi/atmel_spi.c
+++ b/drivers/spi/atmel_spi.c
@@ -338,8 +338,6 @@
 
 	priv->bus_clk_rate = clk_rate;
 
-	clk_free(&clk);
-
 	return 0;
 }
 
diff --git a/drivers/spi/bcm63xx_hsspi.c b/drivers/spi/bcm63xx_hsspi.c
index 19d9a5a..23ac5bb 100644
--- a/drivers/spi/bcm63xx_hsspi.c
+++ b/drivers/spi/bcm63xx_hsspi.c
@@ -581,8 +581,6 @@
 	if (ret < 0 && ret != -ENOSYS)
 		return ret;
 
-	clk_free(&clk);
-
 	/* get clock rate */
 	ret = clk_get_by_name(dev, "pll", &clk);
 	if (ret < 0 && ret != -ENOSYS)
@@ -590,8 +588,6 @@
 
 	priv->clk_rate = clk_get_rate(&clk);
 
-	clk_free(&clk);
-
 	/* perform reset */
 	ret = reset_get_by_index(dev, 0, &rst_ctl);
 	if (ret >= 0) {
diff --git a/drivers/spi/bcm63xx_spi.c b/drivers/spi/bcm63xx_spi.c
index 0600d56..889ac1f 100644
--- a/drivers/spi/bcm63xx_spi.c
+++ b/drivers/spi/bcm63xx_spi.c
@@ -391,8 +391,6 @@
 	if (ret < 0)
 		return ret;
 
-	clk_free(&clk);
-
 	/* perform reset */
 	ret = reset_get_by_index(dev, 0, &rst_ctl);
 	if (ret < 0)
diff --git a/drivers/spi/bcmbca_hsspi.c b/drivers/spi/bcmbca_hsspi.c
index fbe315a..af45882 100644
--- a/drivers/spi/bcmbca_hsspi.c
+++ b/drivers/spi/bcmbca_hsspi.c
@@ -375,8 +375,6 @@
 	if (ret < 0 && ret != -ENOSYS)
 		return ret;
 
-	clk_free(&clk);
-
 	/* get clock rate */
 	ret = clk_get_by_name(dev, "pll", &clk);
 	if (ret < 0 && ret != -ENOSYS)
@@ -384,8 +382,6 @@
 
 	priv->clk_rate = clk_get_rate(&clk);
 
-	clk_free(&clk);
-
 	/* initialize hardware */
 	writel(0, priv->regs + SPI_IR_MASK_REG);
 
diff --git a/drivers/spi/cadence_qspi.c b/drivers/spi/cadence_qspi.c
index dfc74c8..f4593c4 100644
--- a/drivers/spi/cadence_qspi.c
+++ b/drivers/spi/cadence_qspi.c
@@ -236,7 +236,6 @@
 #endif
 		} else {
 			priv->ref_clk_hz = clk_get_rate(&clk);
-			clk_free(&clk);
 			if (IS_ERR_VALUE(priv->ref_clk_hz))
 				return priv->ref_clk_hz;
 		}
diff --git a/drivers/spi/designware_spi.c b/drivers/spi/designware_spi.c
index 98908c5..22a79da 100644
--- a/drivers/spi/designware_spi.c
+++ b/drivers/spi/designware_spi.c
@@ -319,7 +319,6 @@
 
 err_rate:
 	clk_disable(&priv->clk);
-	clk_free(&priv->clk);
 
 	return -EINVAL;
 }
@@ -743,10 +742,6 @@
 	ret = clk_disable(&priv->clk);
 	if (ret)
 		return ret;
-
-	clk_free(&priv->clk);
-	if (ret)
-		return ret;
 #endif
 	return 0;
 }
diff --git a/drivers/spi/meson_spifc_a1.c b/drivers/spi/meson_spifc_a1.c
index cca4deb..943bf69 100644
--- a/drivers/spi/meson_spifc_a1.c
+++ b/drivers/spi/meson_spifc_a1.c
@@ -343,15 +343,6 @@
 	return 0;
 }
 
-static int amlogic_spifc_a1_remove(struct udevice *dev)
-{
-	struct amlogic_spifc_a1 *spifc = dev_get_priv(dev);
-
-	clk_free(&spifc->clk);
-
-	return 0;
-}
-
 static const struct udevice_id meson_spifc_ids[] = {
 	{ .compatible = "amlogic,a1-spifc", },
 	{ }
@@ -379,6 +370,5 @@
 	.of_match	= meson_spifc_ids,
 	.ops		= &amlogic_spifc_a1_ops,
 	.probe		= amlogic_spifc_a1_probe,
-	.remove		= amlogic_spifc_a1_remove,
 	.priv_auto	= sizeof(struct amlogic_spifc_a1),
 };
diff --git a/drivers/spi/mvebu_a3700_spi.c b/drivers/spi/mvebu_a3700_spi.c
index 52882e8..bba2383 100644
--- a/drivers/spi/mvebu_a3700_spi.c
+++ b/drivers/spi/mvebu_a3700_spi.c
@@ -296,15 +296,6 @@
 	return 0;
 }
 
-static int mvebu_spi_remove(struct udevice *bus)
-{
-	struct mvebu_spi_plat *plat = dev_get_plat(bus);
-
-	clk_free(&plat->clk);
-
-	return 0;
-}
-
 static const struct dm_spi_ops mvebu_spi_ops = {
 	.xfer		= mvebu_spi_xfer,
 	.set_speed	= mvebu_spi_set_speed,
@@ -328,5 +319,4 @@
 	.of_to_plat = mvebu_spi_of_to_plat,
 	.plat_auto	= sizeof(struct mvebu_spi_plat),
 	.probe = mvebu_spi_probe,
-	.remove = mvebu_spi_remove,
 };
diff --git a/drivers/spi/spi-aspeed-smc.c b/drivers/spi/spi-aspeed-smc.c
index 3962031..7d5f101 100644
--- a/drivers/spi/spi-aspeed-smc.c
+++ b/drivers/spi/spi-aspeed-smc.c
@@ -1148,7 +1148,6 @@
 	}
 
 	plat->hclk_rate = clk_get_rate(&hclk);
-	clk_free(&hclk);
 
 	dev_dbg(bus, "ctrl_base = 0x%x, ahb_base = 0x%p, size = 0x%llx\n",
 		(u32)priv->regs, plat->ahb_base, (fdt64_t)plat->ahb_sz);
diff --git a/drivers/spi/stm32_spi.c b/drivers/spi/stm32_spi.c
index 82f6ed7..ddb410a 100644
--- a/drivers/spi/stm32_spi.c
+++ b/drivers/spi/stm32_spi.c
@@ -526,22 +526,16 @@
 
 	ret = reset_get_by_index(dev, 0, &plat->rst_ctl);
 	if (ret < 0)
-		goto clk_err;
+		return ret;
 
 	ret = gpio_request_list_by_name(dev, "cs-gpios", plat->cs_gpios,
 					ARRAY_SIZE(plat->cs_gpios), 0);
 	if (ret < 0) {
 		dev_err(dev, "Can't get %s cs gpios: %d", dev->name, ret);
-		ret = -ENOENT;
-		goto clk_err;
+		return -ENOENT;
 	}
 
 	return 0;
-
-clk_err:
-	clk_free(&plat->clk);
-
-	return ret;
 }
 
 static int stm32_spi_probe(struct udevice *dev)
@@ -610,7 +604,6 @@
 
 clk_err:
 	clk_disable(&plat->clk);
-	clk_free(&plat->clk);
 
 	return ret;
 };
@@ -630,13 +623,7 @@
 
 	reset_free(&plat->rst_ctl);
 
-	ret = clk_disable(&plat->clk);
-	if (ret < 0)
-		return ret;
-
-	clk_free(&plat->clk);
-
-	return ret;
+	return clk_disable(&plat->clk);
 };
 
 static const struct dm_spi_ops stm32_spi_ops = {
diff --git a/drivers/timer/dw-apb-timer.c b/drivers/timer/dw-apb-timer.c
index 6cd2525..0607f75 100644
--- a/drivers/timer/dw-apb-timer.c
+++ b/drivers/timer/dw-apb-timer.c
@@ -74,8 +74,6 @@
 			return ret;
 
 		uc_priv->clock_rate = clk_get_rate(&clk);
-
-		clk_free(&clk);
 	}
 
 	/* init timer */
diff --git a/drivers/timer/ostm_timer.c b/drivers/timer/ostm_timer.c
index 3ec729d..3bf0d46 100644
--- a/drivers/timer/ostm_timer.c
+++ b/drivers/timer/ostm_timer.c
@@ -49,8 +49,6 @@
 		return ret;
 
 	uc_priv->clock_rate = clk_get_rate(&clk);
-
-	clk_free(&clk);
 #else
 	uc_priv->clock_rate = get_board_sys_clk() / 2;
 #endif
diff --git a/drivers/usb/dwc3/dwc3-meson-g12a.c b/drivers/usb/dwc3/dwc3-meson-g12a.c
index 1960352..1a3e935 100644
--- a/drivers/usb/dwc3/dwc3-meson-g12a.c
+++ b/drivers/usb/dwc3/dwc3-meson-g12a.c
@@ -361,10 +361,8 @@
 
 #if CONFIG_IS_ENABLED(CLK)
 	ret = clk_enable(&priv->clk);
-	if (ret) {
-		clk_free(&priv->clk);
+	if (ret)
 		return ret;
-	}
 #endif
 
 	return 0;
diff --git a/drivers/usb/dwc3/dwc3-meson-gxl.c b/drivers/usb/dwc3/dwc3-meson-gxl.c
index cbe8aaa..2ce9157 100644
--- a/drivers/usb/dwc3/dwc3-meson-gxl.c
+++ b/drivers/usb/dwc3/dwc3-meson-gxl.c
@@ -284,10 +284,8 @@
 
 #if CONFIG_IS_ENABLED(CLK)
 	ret = clk_enable(&priv->clk);
-	if (ret) {
-		clk_free(&priv->clk);
+	if (ret)
 		return ret;
-	}
 #endif
 
 	return 0;
diff --git a/drivers/usb/host/ehci-atmel.c b/drivers/usb/host/ehci-atmel.c
index fba3595..c6d50fd 100644
--- a/drivers/usb/host/ehci-atmel.c
+++ b/drivers/usb/host/ehci-atmel.c
@@ -70,13 +70,7 @@
 	if (ret)
 		return -EINVAL;
 
-	ret = clk_enable(&clk);
-	if (ret)
-		return ret;
-
-	clk_free(&clk);
-
-	return 0;
+	return clk_enable(&clk);
 }
 
 static int ehci_atmel_probe(struct udevice *dev)
diff --git a/drivers/usb/host/ohci-da8xx.c b/drivers/usb/host/ohci-da8xx.c
index 33c4a91..d3d73d2 100644
--- a/drivers/usb/host/ohci-da8xx.c
+++ b/drivers/usb/host/ohci-da8xx.c
@@ -115,7 +115,6 @@
 			err = clk_enable(&priv->clocks[i]);
 			if (err) {
 				dev_err(dev, "failed to enable clock %d\n", i);
-				clk_free(&priv->clocks[i]);
 				goto clk_err;
 			}
 			priv->clock_count++;
diff --git a/drivers/usb/host/xhci-rcar.c b/drivers/usb/host/xhci-rcar.c
index 5fc7afb..fedcf78 100644
--- a/drivers/usb/host/xhci-rcar.c
+++ b/drivers/usb/host/xhci-rcar.c
@@ -90,7 +90,7 @@
 	ret = clk_enable(&plat->clk);
 	if (ret) {
 		dev_err(dev, "Failed to enable USB3 clock\n");
-		goto err_clk;
+		return ret;
 	}
 
 	ctx->hcd = (struct xhci_hccr *)plat->hcd_base;
@@ -114,8 +114,6 @@
 
 err_fw:
 	clk_disable(&plat->clk);
-err_clk:
-	clk_free(&plat->clk);
 	return ret;
 }
 
@@ -127,7 +125,6 @@
 	ret = xhci_deregister(dev);
 
 	clk_disable(&plat->clk);
-	clk_free(&plat->clk);
 
 	return ret;
 }
diff --git a/drivers/video/atmel_hlcdfb.c b/drivers/video/atmel_hlcdfb.c
index 2bf19a6..652ba14 100644
--- a/drivers/video/atmel_hlcdfb.c
+++ b/drivers/video/atmel_hlcdfb.c
@@ -62,8 +62,6 @@
 
 	priv->clk_rate = clk_rate;
 
-	clk_free(&clk);
-
 	return 0;
 }
 
diff --git a/drivers/video/mali_dp.c b/drivers/video/mali_dp.c
index cbcdb99..dbb2f53 100644
--- a/drivers/video/mali_dp.c
+++ b/drivers/video/mali_dp.c
@@ -360,25 +360,18 @@
 
 	err = malidp_setup_mode(priv, &timings);
 	if (err)
-		goto fail_timings;
+		return err;
 
 	malidp_setup_layer(priv, &timings, MALIDP_LAYER_LV1,
 			   (phys_addr_t)uc_plat->base);
 
 	err = malidp_leave_config(priv);
 	if (err)
-		goto fail_timings;
+		return err;
 
 	malidp_set_configvalid(priv);
 
 	return 0;
-
-fail_timings:
-	clk_free(&priv->aclk);
-fail_aclk:
-	clk_free(&priv->pxlclk);
-
-	return err;
 }
 
 static int malidp_bind(struct udevice *dev)
diff --git a/drivers/video/rockchip/rk3288_hdmi.c b/drivers/video/rockchip/rk3288_hdmi.c
index 327ae78..8bedee5 100644
--- a/drivers/video/rockchip/rk3288_hdmi.c
+++ b/drivers/video/rockchip/rk3288_hdmi.c
@@ -67,10 +67,8 @@
 	 * monitor wants
 	 */
 	ret = clk_get_by_index(uc_plat->src_dev, 0, &clk);
-	if (ret >= 0) {
+	if (ret >= 0)
 		ret = clk_set_rate(&clk, 384000000);
-		clk_free(&clk);
-	}
 	if (ret < 0) {
 		debug("%s: Failed to set clock in source device '%s': ret=%d\n",
 		      __func__, uc_plat->src_dev->name, ret);
diff --git a/drivers/video/rockchip/rk_edp.c b/drivers/video/rockchip/rk_edp.c
index 3697d58..dbd70ad 100644
--- a/drivers/video/rockchip/rk_edp.c
+++ b/drivers/video/rockchip/rk_edp.c
@@ -1095,20 +1095,16 @@
 
 	if (edp_data->chip_type == RK3288_DP) {
 		ret = clk_get_by_index(dev, 1, &clk);
-		if (ret >= 0) {
+		if (ret >= 0)
 			ret = clk_set_rate(&clk, 0);
-			clk_free(&clk);
-		}
 		if (ret) {
 			debug("%s: Failed to set EDP clock: ret=%d\n", __func__, ret);
 			return ret;
 		}
 	}
 	ret = clk_get_by_index(uc_plat->src_dev, 0, &clk);
-	if (ret >= 0) {
+	if (ret >= 0)
 		ret = clk_set_rate(&clk, 192000000);
-		clk_free(&clk);
-	}
 	if (ret < 0) {
 		debug("%s: Failed to set clock in source device '%s': ret=%d\n",
 		      __func__, uc_plat->src_dev->name, ret);
diff --git a/drivers/watchdog/designware_wdt.c b/drivers/watchdog/designware_wdt.c
index 447a22d..b22e0ee 100644
--- a/drivers/watchdog/designware_wdt.c
+++ b/drivers/watchdog/designware_wdt.c
@@ -124,13 +124,11 @@
 
 	ret = clk_enable(&clk);
 	if (ret)
-		goto err;
+		return ret;
 
 	priv->clk_khz = clk_get_rate(&clk) / 1000;
-	if (!priv->clk_khz) {
-		ret = -EINVAL;
-		goto err;
-	}
+	if (!priv->clk_khz)
+		return -EINVAL;
 #else
 	priv->clk_khz = CFG_DW_WDT_CLOCK_KHZ;
 #endif
@@ -139,21 +137,15 @@
 	    ofnode_read_prop(dev_ofnode(dev), "resets", &ret)) {
 		ret = reset_get_bulk(dev, &priv->resets);
 		if (ret)
-			goto err;
+			return ret;
 
 		ret = reset_deassert_bulk(&priv->resets);
 		if (ret)
-			goto err;
+			return ret;
 	}
 
 	/* reset to disable the watchdog */
 	return designware_wdt_stop(dev);
-
-err:
-#if CONFIG_IS_ENABLED(CLK)
-	clk_free(&clk);
-#endif
-	return ret;
 }
 
 static const struct wdt_ops designware_wdt_ops = {
diff --git a/drivers/watchdog/meson_gxbb_wdt.c b/drivers/watchdog/meson_gxbb_wdt.c
index 6ab0058..01a35b3 100644
--- a/drivers/watchdog/meson_gxbb_wdt.c
+++ b/drivers/watchdog/meson_gxbb_wdt.c
@@ -98,10 +98,8 @@
 		return ret;
 
 	ret = clk_enable(&clk);
-	if (ret) {
-		clk_free(&clk);
+	if (ret)
 		return ret;
-	}
 
 	/* Setup with 1ms timebase */
 	writel(((clk_get_rate(&clk) / 1000) & GXBB_WDT_CTRL_DIV_MASK) |
diff --git a/include/clk-uclass.h b/include/clk-uclass.h
index cd62848..8c07e72 100644
--- a/include/clk-uclass.h
+++ b/include/clk-uclass.h
@@ -18,7 +18,6 @@
  * struct clk_ops - The functions that a clock driver must implement.
  * @of_xlate: Translate a client's device-tree (OF) clock specifier.
  * @request: Request a translated clock.
- * @rfree: Free a previously requested clock.
  * @round_rate: Adjust a rate to the exact rate a clock can provide.
  * @get_rate: Get current clock rate.
  * @set_rate: Set current clock rate.
@@ -33,7 +32,6 @@
 	int (*of_xlate)(struct clk *clock,
 			struct ofnode_phandle_args *args);
 	int (*request)(struct clk *clock);
-	void (*rfree)(struct clk *clock);
 	ulong (*round_rate)(struct clk *clk, ulong rate);
 	ulong (*get_rate)(struct clk *clk);
 	ulong (*set_rate)(struct clk *clk, ulong rate);
@@ -58,11 +56,20 @@
  * default implementation, which assumes #clock-cells = <1>, and that
  * the DT cell contains a simple integer clock ID.
  *
+ * This function should be a simple translation of @args into @clock->id and
+ * (optionally) @clock->data. All other processing, allocation, or error
+ * checking should take place in request().
+ *
  * At present, the clock API solely supports device-tree. If this
  * changes, other xxx_xlate() functions may be added to support those
  * other mechanisms.
  *
- * Return: 0 if OK, or a negative error code.
+ * Return:
+ * * 0 on success
+ * * -%EINVAL if @args does not have the correct format. For example, it could
+ *   have too many/few arguments.
+ * * -%ENOENT if @args has the correct format but cannot be translated. This can
+ *   happen if translation involves a table lookup and @args is not present.
  */
 int of_xlate(struct clk *clock, struct ofnode_phandle_args *args);
 
@@ -77,24 +84,36 @@
  * xxx_xlate() call, or as the only step in implementing a client's
  * clk_request() call.
  *
- * Return: 0 if OK, or a negative error code.
- */
-int request(struct clk *clock);
-
-/**
- * rfree() - Free a previously requested clock.
- * @clock:	The clock to free.
+ * This is the right place to do bounds checking (rejecting invalid or
+ * unimplemented clocks), allocate resources, or perform other setup not done
+ * during driver probe(). Most clock drivers should allocate resources in their
+ * probe() function, but it is possible to lazily initialize something here.
  *
- * Free any resources allocated in request().
+ * Return:
+ * * 0 on success
+ * * -%ENOENT, if there is no clock corresponding to @clock->id and
+ *   @clock->data.
  */
-void rfree(struct clk *clock);
+int request(struct clk *clock);
 
 /**
  * round_rate() - Adjust a rate to the exact rate a clock can provide.
- * @clk:	The clock to manipulate.
- * @rate:	Desidered clock rate in Hz.
+ * @clk:	The clock to query.
+ * @rate:	Desired clock rate in Hz.
+ *
+ * This function returns a new rate which can be provided to set_rate(). This
+ * new rate should be the closest rate to @rate which can be set without
+ * rounding. The following pseudo-code should hold::
  *
- * Return: rounded rate in Hz, or -ve error code.
+ *   for all rate in range(ULONG_MAX):
+ *     rounded = round_rate(clk, rate)
+ *     new_rate = set_rate(clk, rate)
+ *     assert(IS_ERR_VALUE(new_rate) || new_rate == rounded)
+ *
+ * Return:
+ * * The rounded rate in Hz on success
+ * * A negative error value from another API (such as clk_get_rate()). This
+ *   function must not return an error for any other reason.
  */
 ulong round_rate(struct clk *clk, ulong rate);
 
@@ -102,7 +121,22 @@
  * get_rate() - Get current clock rate.
  * @clk:	The clock to query.
  *
+ * This returns the current rate of a clock. If the clock is disabled, it
+ * returns the rate at which the clock would run if it was enabled. The
+ * following pseudo-code should hold::
+ *
- * Return: clock rate in Hz, or -ve error code
+ *   disable(clk)
+ *   rate = get_rate(clk)
+ *   enable(clk)
+ *   assert(get_rate(clk) == rate)
+ *
+ * Return:
+ * * The rate of @clk
+ * * -%ENOSYS if this function is not implemented for @clk
+ * * -%ENOENT if @clk->id is invalid. Prefer using an assert instead, and doing
+ *   this check in request().
+ * * Another negative error value (such as %EIO or %ECOMM) if the rate could
+ *   not be determined due to a bus error.
  */
 ulong get_rate(struct clk *clk);
 
@@ -111,7 +145,27 @@
  * @clk:	The clock to manipulate.
  * @rate:	New clock rate in Hz.
  *
- * Return: new rate, or -ve error code.
+ * Set the rate of @clk to @rate. The actual rate may be rounded. However,
+ * excessive rounding should be avoided. It is left to the driver author's
+ * discretion when this function should attempt to round and when it should
+ * return an error. For example, a dividing clock might use the following
+ * pseudo-logic when implemening this function::
+ *
+ *   divisor = parent_rate / rate
+ *   if divisor < min || divisor > max:
+ *     return -EINVAL
+ *
+ * If there is any concern about rounding, prefer to let consumers make the
+ * decision by calling round_rate().
+ *
+ * Return:
+ * * The new rate on success
+ * * -%ENOSYS if this function is not implemented for @clk
+ * * -%ENOENT if @clk->id is invalid. Prefer using an assert instead, and doing
+ *   this check in request().
+ * * -%EINVAL if @rate is not valid for @clk.
+ * * Another negative error value (such as %EIO or %ECOMM) if the rate could
+ *   not be set due to a bus error.
  */
 ulong set_rate(struct clk *clk, ulong rate);
 
@@ -120,7 +174,19 @@
  * @clk:        The clock to manipulate.
  * @parent:     New clock parent.
  *
+ * Set the current parent of @clk to @parent. The rate of the clock may be
+ * modified by this call. If @clk was enabled before this function, it should
+ * remain enabled after this function, although it may be temporarily disabled
+ * if necessary.
+ *
- * Return: zero on success, or -ve error code.
+ * Return:
+ * * 0 on success
+ * * -%ENOSYS if this function is not implemented for @clk
+ * * -%ENOENT if @clk->id or @parent->id is invalid. Prefer using an assert
+ *   instead, and doing this check in request().
+ * * -%EINVAL if @parent is not a valid parent for @clk.
+ * * Another negative error value (such as %EIO or %ECOMM) if the parent could
+ *   not be set due to a bus error.
  */
 int set_parent(struct clk *clk, struct clk *parent);
 
@@ -128,7 +194,16 @@
  * enable() - Enable a clock.
  * @clk:	The clock to manipulate.
  *
- * Return: zero on success, or -ve error code.
+ * Enable (un-gate) the clock. This function should not modify the rate of the
+ * clock (see get_rate() for details).
+ *
+ * Return:
+ * * 0 on success
+ * * -%ENOSYS if this function is not implemented for @clk
+ * * -%ENOENT if @clk->id is invalid. Prefer using an assert instead, and doing
+ *   this check in request().
+ * * Another negative error value (such as %EIO or %ECOMM) if the clock could
+ *   not be enabled due to a bus error.
  */
 int enable(struct clk *clk);
 
@@ -136,7 +211,15 @@
  * disable() - Disable a clock.
  * @clk:	The clock to manipulate.
  *
- * Return: zero on success, or -ve error code.
+ * Disable (gate) the clock. This function should not modify the rate of the
+ * clock (see get_rate() for details).
+ *
+ * * 0 on success
+ * * -%ENOSYS if this function is not implemented for @clk
+ * * -%ENOENT if @clk->id is invalid. Prefer using an assert instead, and doing
+ *   this check in request().
+ * * Another negative error value (such as %EIO or %ECOMM) if the clock could
+ *   not be disabled due to a bus error.
  */
 int disable(struct clk *clk);
 
diff --git a/include/clk.h b/include/clk.h
index 3d63944..af23e4f 100644
--- a/include/clk.h
+++ b/include/clk.h
@@ -247,19 +247,6 @@
  */
 int clk_release_all(struct clk *clk, unsigned int count);
 
-/**
- * devm_clk_put	- "free" a managed clock source
- * @dev: device used to acquire the clock
- * @clk: clock source acquired with devm_clk_get()
- *
- * Note: drivers must ensure that all clk_enable calls made on this
- * clock source are balanced by clk_disable calls prior to calling
- * this function.
- *
- * clk_put should not be called from within interrupt context.
- */
-void devm_clk_put(struct udevice *dev, struct clk *clk);
-
 #else
 
 static inline int clk_get_by_phandle(struct udevice *dev, const
@@ -313,10 +300,6 @@
 {
 	return -ENOSYS;
 }
-
-static inline void devm_clk_put(struct udevice *dev, struct clk *clk)
-{
-}
 #endif
 
 /**
@@ -442,15 +425,6 @@
 int clk_request(struct udevice *dev, struct clk *clk);
 
 /**
- * clk_free() - Free a previously requested clock.
- * @clk:	A clock struct that was previously successfully requested by
- *		clk_request/get_by_*().
- *
- * Free resources allocated by clk_request() (or any clk_get_* function).
- */
-void clk_free(struct clk *clk);
-
-/**
  * clk_get_rate() - Get current clock rate.
  * @clk:	A clock struct that was previously successfully requested by
  *		clk_request/get_by_*().
@@ -594,11 +568,6 @@
 	return -ENOSYS;
 }
 
-static inline void clk_free(struct clk *clk)
-{
-	return;
-}
-
 static inline ulong clk_get_rate(struct clk *clk)
 {
 	return -ENOSYS;
diff --git a/test/dm/clk.c b/test/dm/clk.c
index 01417fb..57fabbd 100644
--- a/test/dm/clk.c
+++ b/test/dm/clk.c
@@ -182,19 +182,10 @@
 						   SANDBOX_CLK_ID_I2C));
 	ut_asserteq(1, sandbox_clk_query_requested(dev_clk,
 						   SANDBOX_CLK_ID_UART2));
-	ut_assertok(sandbox_clk_test_free(dev_test));
-	ut_asserteq(0, sandbox_clk_query_requested(dev_clk,
-						   SANDBOX_CLK_ID_SPI));
-	ut_asserteq(0, sandbox_clk_query_requested(dev_clk,
-						   SANDBOX_CLK_ID_I2C));
-	ut_asserteq(0, sandbox_clk_query_requested(dev_clk,
-						   SANDBOX_CLK_ID_UART2));
 
 	ut_asserteq(1, sandbox_clk_query_requested(dev_clk,
 						   SANDBOX_CLK_ID_UART1));
 	ut_assertok(device_remove(dev_test, DM_REMOVE_NORMAL));
-	ut_asserteq(0, sandbox_clk_query_requested(dev_clk,
-						   SANDBOX_CLK_ID_UART1));
 	return 0;
 }
 DM_TEST(dm_test_clk, UT_TESTF_SCAN_FDT);