diff --git a/drivers/clk/hisilicon/clk-hi3519.c b/drivers/clk/hisilicon/clk-hi3519.c
index ad0c7f350..556c89037 100644
--- a/drivers/clk/hisilicon/clk-hi3519.c
+++ b/drivers/clk/hisilicon/clk-hi3519.c
@@ -75,10 +75,12 @@ static const struct hisi_gate_clock hi3519_gate_clks[] = {
 
 static struct hisi_clock_data *hi3519_clk_register(struct platform_device *pdev)
 {
+	struct device *dev = &pdev->dev;
+	struct device_node *np = dev->of_node;
 	struct hisi_clock_data *clk_data;
 	int ret;
 
-	clk_data = hisi_clk_alloc(pdev, HI3519_NR_CLKS);
+	clk_data = hisi_clk_init(np, HI3519_NR_CLKS);
 	if (!clk_data)
 		return ERR_PTR(-ENOMEM);
 
@@ -100,11 +102,6 @@ static struct hisi_clock_data *hi3519_clk_register(struct platform_device *pdev)
 	if (ret)
 		goto unregister_mux;
 
-	ret = of_clk_add_provider(pdev->dev.of_node,
-			of_clk_src_onecell_get, &clk_data->clk_data);
-	if (ret)
-		goto unregister_gate;
-
 	return clk_data;
 
 unregister_fixed_rate:
@@ -127,8 +124,6 @@ static void hi3519_clk_unregister(struct platform_device *pdev)
 {
 	struct hi3519_crg_data *crg = platform_get_drvdata(pdev);
 
-	of_clk_del_provider(pdev->dev.of_node);
-
 	hisi_clk_unregister_gate(hi3519_gate_clks,
 				ARRAY_SIZE(hi3519_mux_clks),
 				crg->clk_data);
@@ -164,10 +159,13 @@ static int hi3519_clk_probe(struct platform_device *pdev)
 
 static int hi3519_clk_remove(struct platform_device *pdev)
 {
+	struct device *dev = &pdev->dev;
+	struct device_node *np = dev->of_node;
 	struct hi3519_crg_data *crg = platform_get_drvdata(pdev);
 
 	hisi_reset_exit(crg->rstc);
 	hi3519_clk_unregister(pdev);
+	hisi_clk_free(np, crg->clk_data);
 	return 0;
 }
 
diff --git a/drivers/clk/hisilicon/clk-hi3559a.c b/drivers/clk/hisilicon/clk-hi3559a.c
index 8036bd8cb..c3dd018f8 100644
--- a/drivers/clk/hisilicon/clk-hi3559a.c
+++ b/drivers/clk/hisilicon/clk-hi3559a.c
@@ -505,10 +505,12 @@ static void hisi_clk_register_pll(struct hi3559av100_pll_clock *clks,
 static struct hisi_clock_data *hi3559av100_clk_register(
 	struct platform_device *pdev)
 {
+	struct device *dev = &pdev->dev;
+	struct device_node *np = dev->of_node;
 	struct hisi_clock_data *clk_data;
 	int ret;
 
-	clk_data = hisi_clk_alloc(pdev, HI3559AV100_CRG_NR_CLKS);
+	clk_data = hisi_clk_init(np, HI3559AV100_CRG_NR_CLKS);
 	if (!clk_data)
 		return ERR_PTR(-ENOMEM);
 
@@ -530,11 +532,6 @@ static struct hisi_clock_data *hi3559av100_clk_register(
 	if (ret)
 		goto unregister_mux;
 
-	ret = of_clk_add_provider(pdev->dev.of_node,
-				  of_clk_src_onecell_get, &clk_data->clk_data);
-	if (ret)
-		goto unregister_gate;
-
 	return clk_data;
 
 unregister_gate:
@@ -553,8 +550,6 @@ static void hi3559av100_clk_unregister(struct platform_device *pdev)
 {
 	struct hisi_crg_dev *crg = platform_get_drvdata(pdev);
 
-	of_clk_del_provider(pdev->dev.of_node);
-
 	hisi_clk_unregister_gate(hi3559av100_gate_clks,
 				 ARRAY_SIZE(hi3559av100_gate_clks), crg->clk_data);
 	hisi_clk_unregister_mux(hi3559av100_mux_clks_crg,
@@ -699,12 +694,14 @@ static int hi3559av100_shub_default_clk_set(void)
 static struct hisi_clock_data *hi3559av100_shub_clk_register(
 	struct platform_device *pdev)
 {
+	struct device *dev = &pdev->dev;
+	struct device_node *np = dev->of_node;
 	struct hisi_clock_data *clk_data = NULL;
 	int ret;
 
 	hi3559av100_shub_default_clk_set();
 
-	clk_data = hisi_clk_alloc(pdev, HI3559AV100_SHUB_NR_CLKS);
+	clk_data = hisi_clk_init(np, HI3559AV100_SHUB_NR_CLKS);
 	if (!clk_data)
 		return ERR_PTR(-ENOMEM);
 
@@ -728,11 +725,6 @@ static struct hisi_clock_data *hi3559av100_shub_clk_register(
 	if (ret)
 		goto unregister_factor;
 
-	ret = of_clk_add_provider(pdev->dev.of_node,
-				  of_clk_src_onecell_get, &clk_data->clk_data);
-	if (ret)
-		goto unregister_gate;
-
 	return clk_data;
 
 unregister_gate:
@@ -754,8 +746,6 @@ static void hi3559av100_shub_clk_unregister(struct platform_device *pdev)
 {
 	struct hisi_crg_dev *crg = platform_get_drvdata(pdev);
 
-	of_clk_del_provider(pdev->dev.of_node);
-
 	hisi_clk_unregister_gate(hi3559av100_shub_gate_clks,
 				 ARRAY_SIZE(hi3559av100_shub_gate_clks), crg->clk_data);
 	hisi_clk_unregister_divider(hi3559av100_shub_div_clks,
@@ -812,10 +802,13 @@ static int hi3559av100_crg_probe(struct platform_device *pdev)
 
 static int hi3559av100_crg_remove(struct platform_device *pdev)
 {
+	struct device *dev = &pdev->dev;
+	struct device_node *np = dev->of_node;
 	struct hisi_crg_dev *crg = platform_get_drvdata(pdev);
 
 	hisi_reset_exit(crg->rstc);
 	crg->funcs->unregister_clks(pdev);
+	hisi_clk_free(np, crg->clk_data);
 	return 0;
 }
 
diff --git a/drivers/clk/hisilicon/clk.c b/drivers/clk/hisilicon/clk.c
index 54d9fdc93..a949be5fa 100644
--- a/drivers/clk/hisilicon/clk.c
+++ b/drivers/clk/hisilicon/clk.c
@@ -23,38 +23,6 @@
 
 static DEFINE_SPINLOCK(hisi_clk_lock);
 
-struct hisi_clock_data *hisi_clk_alloc(struct platform_device *pdev,
-						int nr_clks)
-{
-	struct hisi_clock_data *clk_data;
-	struct resource *res;
-	struct clk **clk_table;
-
-	clk_data = devm_kmalloc(&pdev->dev, sizeof(*clk_data), GFP_KERNEL);
-	if (!clk_data)
-		return NULL;
-
-	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	if (!res)
-		return NULL;
-	clk_data->base = devm_ioremap(&pdev->dev,
-				res->start, resource_size(res));
-	if (!clk_data->base)
-		return NULL;
-
-	clk_table = devm_kmalloc_array(&pdev->dev, nr_clks,
-				       sizeof(*clk_table),
-				       GFP_KERNEL);
-	if (!clk_table)
-		return NULL;
-
-	clk_data->clk_data.clks = clk_table;
-	clk_data->clk_data.clk_num = nr_clks;
-
-	return clk_data;
-}
-EXPORT_SYMBOL_GPL(hisi_clk_alloc);
-
 struct hisi_clock_data *hisi_clk_init(struct device_node *np,
 					     int nr_clks)
 {
@@ -88,6 +56,14 @@ struct hisi_clock_data *hisi_clk_init(struct device_node *np,
 }
 EXPORT_SYMBOL_GPL(hisi_clk_init);
 
+void hisi_clk_free(struct device_node *np, struct hisi_clock_data *data)
+{
+	of_clk_del_provider(np);
+	kfree(data->clk_data.clks);
+	kfree(data);
+}
+EXPORT_SYMBOL_GPL(hisi_clk_free);
+
 int hisi_clk_register_fixed_rate(const struct hisi_fixed_rate_clock *clks,
 					 int nums, struct hisi_clock_data *data)
 {
diff --git a/drivers/clk/hisilicon/clk.h b/drivers/clk/hisilicon/clk.h
index 7a9b42e1b..30b6d4405 100644
--- a/drivers/clk/hisilicon/clk.h
+++ b/drivers/clk/hisilicon/clk.h
@@ -111,8 +111,9 @@ struct clk *hi6220_register_clkdiv(struct device *dev, const char *name,
 	const char *parent_name, unsigned long flags, void __iomem *reg,
 	u8 shift, u8 width, u32 mask_bit, spinlock_t *lock);
 
-struct hisi_clock_data *hisi_clk_alloc(struct platform_device *, int);
 struct hisi_clock_data *hisi_clk_init(struct device_node *, int);
+void hisi_clk_free(struct device_node *np, struct hisi_clock_data *data);
+
 int hisi_clk_register_fixed_rate(const struct hisi_fixed_rate_clock *,
 				int, struct hisi_clock_data *);
 int hisi_clk_register_fixed_factor(const struct hisi_fixed_factor_clock *,
diff --git a/drivers/clk/hisilicon/crg-hi3516cv300.c b/drivers/clk/hisilicon/crg-hi3516cv300.c
index 5d4e61c7a..6c756680d 100644
--- a/drivers/clk/hisilicon/crg-hi3516cv300.c
+++ b/drivers/clk/hisilicon/crg-hi3516cv300.c
@@ -129,10 +129,12 @@ static const struct hisi_gate_clock hi3516cv300_gate_clks[] = {
 static struct hisi_clock_data *hi3516cv300_clk_register(
 		struct platform_device *pdev)
 {
+	struct device *dev = &pdev->dev;
+	struct device_node *np = dev->of_node;
 	struct hisi_clock_data *clk_data;
 	int ret;
 
-	clk_data = hisi_clk_alloc(pdev, HI3516CV300_CRG_NR_CLKS);
+	clk_data = hisi_clk_init(np, HI3516CV300_CRG_NR_CLKS);
 	if (!clk_data)
 		return ERR_PTR(-ENOMEM);
 
@@ -151,11 +153,6 @@ static struct hisi_clock_data *hi3516cv300_clk_register(
 	if (ret)
 		goto unregister_mux;
 
-	ret = of_clk_add_provider(pdev->dev.of_node,
-			of_clk_src_onecell_get, &clk_data->clk_data);
-	if (ret)
-		goto unregister_gate;
-
 	return clk_data;
 
 unregister_gate:
@@ -174,8 +171,6 @@ static void hi3516cv300_clk_unregister(struct platform_device *pdev)
 {
 	struct hisi_crg_dev *crg = platform_get_drvdata(pdev);
 
-	of_clk_del_provider(pdev->dev.of_node);
-
 	hisi_clk_unregister_gate(hi3516cv300_gate_clks,
 			ARRAY_SIZE(hi3516cv300_gate_clks), crg->clk_data);
 	hisi_clk_unregister_mux(hi3516cv300_mux_clks,
@@ -203,10 +198,12 @@ static const struct hisi_mux_clock hi3516cv300_sysctrl_mux_clks[] = {
 static struct hisi_clock_data *hi3516cv300_sysctrl_clk_register(
 		struct platform_device *pdev)
 {
+	struct device *dev = &pdev->dev;
+	struct device_node *np = dev->of_node;
 	struct hisi_clock_data *clk_data;
 	int ret;
 
-	clk_data = hisi_clk_alloc(pdev, HI3516CV300_SYSCTRL_NR_CLKS);
+	clk_data = hisi_clk_init(np, HI3516CV300_SYSCTRL_NR_CLKS);
 	if (!clk_data)
 		return ERR_PTR(-ENOMEM);
 
@@ -215,12 +212,6 @@ static struct hisi_clock_data *hi3516cv300_sysctrl_clk_register(
 	if (ret)
 		return ERR_PTR(ret);
 
-
-	ret = of_clk_add_provider(pdev->dev.of_node,
-			of_clk_src_onecell_get, &clk_data->clk_data);
-	if (ret)
-		goto unregister_mux;
-
 	return clk_data;
 
 unregister_mux:
@@ -233,8 +224,6 @@ static void hi3516cv300_sysctrl_clk_unregister(struct platform_device *pdev)
 {
 	struct hisi_crg_dev *crg = platform_get_drvdata(pdev);
 
-	of_clk_del_provider(pdev->dev.of_node);
-
 	hisi_clk_unregister_mux(hi3516cv300_sysctrl_mux_clks,
 			ARRAY_SIZE(hi3516cv300_sysctrl_mux_clks),
 			crg->clk_data);
@@ -286,10 +275,13 @@ static int hi3516cv300_crg_probe(struct platform_device *pdev)
 
 static int hi3516cv300_crg_remove(struct platform_device *pdev)
 {
+	struct device *dev = &pdev->dev;
+	struct device_node *np = dev->of_node;
 	struct hisi_crg_dev *crg = platform_get_drvdata(pdev);
 
 	hisi_reset_exit(crg->rstc);
 	crg->funcs->unregister_clks(pdev);
+	hisi_clk_free(np, crg->clk_data);
 	return 0;
 }
 
diff --git a/drivers/clk/hisilicon/crg-hi3798.c b/drivers/clk/hisilicon/crg-hi3798.c
index 778637131..fad1a2fba 100644
--- a/drivers/clk/hisilicon/crg-hi3798.c
+++ b/drivers/clk/hisilicon/crg-hi3798.c
@@ -72,10 +72,12 @@ static struct hisi_clock_data *
 hi3798_clk_register(struct platform_device *pdev,
 		    const struct hi3798_clks *clks)
 {
+	struct device *dev = &pdev->dev;
+	struct device_node *np = dev->of_node;
 	struct hisi_clock_data *clk_data;
 	int ret;
 
-	clk_data = hisi_clk_alloc(pdev, HI3798_CRG_NR_CLKS);
+	clk_data = hisi_clk_init(np, HI3798_CRG_NR_CLKS);
 	if (!clk_data)
 		return ERR_PTR(-ENOMEM);
 
@@ -99,11 +101,6 @@ hi3798_clk_register(struct platform_device *pdev,
 	if (ret)
 		goto unregister_mux;
 
-	ret = of_clk_add_provider(pdev->dev.of_node,
-			of_clk_src_onecell_get, &clk_data->clk_data);
-	if (ret)
-		goto unregister_gate;
-
 	return clk_data;
 
 unregister_gate:
@@ -122,8 +119,6 @@ static void hi3798_clk_unregister(struct platform_device *pdev,
 {
 	struct hisi_crg_dev *crg = platform_get_drvdata(pdev);
 
-	of_clk_del_provider(pdev->dev.of_node);
-
 	hisi_clk_unregister_gate(clks->gate_clks, clks->gate_clks_nums, crg->clk_data);
 	hisi_clk_unregister_mux(clks->mux_clks, clks->mux_clks_nums, crg->clk_data);
 	hisi_clk_unregister_fixed_rate(hi3798_fixed_rate_clks,
@@ -139,10 +134,12 @@ static struct hisi_clock_data *
 hi3798_sysctrl_clk_register(struct platform_device *pdev,
 			    const struct hi3798_clks *clks)
 {
+	struct device *dev = &pdev->dev;
+	struct device_node *np = dev->of_node;
 	struct hisi_clock_data *clk_data;
 	int ret;
 
-	clk_data = hisi_clk_alloc(pdev, HI3798_SYSCTRL_NR_CLKS);
+	clk_data = hisi_clk_init(np, HI3798_SYSCTRL_NR_CLKS);
 	if (!clk_data)
 		return ERR_PTR(-ENOMEM);
 
@@ -150,11 +147,6 @@ hi3798_sysctrl_clk_register(struct platform_device *pdev,
 	if (ret)
 		return ERR_PTR(ret);
 
-	ret = of_clk_add_provider(pdev->dev.of_node,
-			of_clk_src_onecell_get, &clk_data->clk_data);
-	if (ret)
-		goto unregister_gate;
-
 	return clk_data;
 
 unregister_gate:
@@ -167,8 +159,6 @@ static void hi3798_sysctrl_clk_unregister(struct platform_device *pdev,
 {
 	struct hisi_crg_dev *crg = platform_get_drvdata(pdev);
 
-	of_clk_del_provider(pdev->dev.of_node);
-
 	hisi_clk_unregister_gate(clks->gate_clks, clks->gate_clks_nums, crg->clk_data);
 }
 
@@ -401,10 +391,13 @@ static int hi3798_crg_probe(struct platform_device *pdev)
 
 static int hi3798_crg_remove(struct platform_device *pdev)
 {
+	struct device *dev = &pdev->dev;
+	struct device_node *np = dev->of_node;
 	struct hisi_crg_dev *crg = platform_get_drvdata(pdev);
 
 	hisi_reset_exit(crg->rstc);
 	crg->funcs->unregister_clks(pdev);
+	hisi_clk_free(np, crg->clk_data);
 	return 0;
 }
 
