linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [RESEND PATCH v2 0/5] clk: hisilicon: Fix some problems of clk-hi3519
@ 2016-06-15  6:26 Jiancheng Xue
  2016-06-15  6:26 ` [PATCH v2 1/5] reset: hisilicon: change the definition of hisi_reset_init Jiancheng Xue
                   ` (5 more replies)
  0 siblings, 6 replies; 12+ messages in thread
From: Jiancheng Xue @ 2016-06-15  6:26 UTC (permalink / raw)
  To: mturquette, sboyd, p.zabel
  Cc: linux-clk, linux-kernel, yanhaifeng, yanghongwei, Jiancheng Xue

This patch is base on branch clk-hi3519 in clk tree. It mainly fixes the
following issues:
1. Add driver remove path.
2. Fix the ordering issue about clock provider being published.
3. Add error checking upon registering clocks. 

change log
v2:
-Redivided patches to make sure every patch can be compiled successfully.

Jiancheng Xue (5):
  reset: hisilicon: change the definition of hisi_reset_init
  clk: hisilicon: add hisi_clk_alloc function.
  clk: hisilicon: add error processing for hisi_clk_register_* functions
  clk: hisilicon: add hisi_clk_unregister_* functions
  clk: hisilicon: hi3519: add driver remove path and fix some issues

 drivers/clk/hisilicon/clk-hi3519.c | 116 ++++++++++++++++++++++++++++++++-----
 drivers/clk/hisilicon/clk.c        |  89 ++++++++++++++++++++++++----
 drivers/clk/hisilicon/clk.h        |  34 +++++++++--
 drivers/clk/hisilicon/reset.c      |  19 +++---
 drivers/clk/hisilicon/reset.h      |   5 +-
 5 files changed, 220 insertions(+), 43 deletions(-)

-- 
1.9.1

^ permalink raw reply	[flat|nested] 12+ messages in thread

* [PATCH v2 1/5] reset: hisilicon: change the definition of hisi_reset_init
  2016-06-15  6:26 [RESEND PATCH v2 0/5] clk: hisilicon: Fix some problems of clk-hi3519 Jiancheng Xue
@ 2016-06-15  6:26 ` Jiancheng Xue
  2016-06-15  6:26 ` [PATCH v2 2/5] clk: hisilicon: add hisi_clk_alloc function Jiancheng Xue
                   ` (4 subsequent siblings)
  5 siblings, 0 replies; 12+ messages in thread
From: Jiancheng Xue @ 2016-06-15  6:26 UTC (permalink / raw)
  To: mturquette, sboyd, p.zabel
  Cc: linux-clk, linux-kernel, yanhaifeng, yanghongwei, Jiancheng Xue

Change the input arguments type to struct platform_device pointer.

Signed-off-by: Jiancheng Xue <xuejiancheng@hisilicon.com>
---
 drivers/clk/hisilicon/clk-hi3519.c |  2 +-
 drivers/clk/hisilicon/reset.c      | 19 +++++++++----------
 drivers/clk/hisilicon/reset.h      |  5 +++--
 3 files changed, 13 insertions(+), 13 deletions(-)

diff --git a/drivers/clk/hisilicon/clk-hi3519.c b/drivers/clk/hisilicon/clk-hi3519.c
index 715c730..8d12700 100644
--- a/drivers/clk/hisilicon/clk-hi3519.c
+++ b/drivers/clk/hisilicon/clk-hi3519.c
@@ -86,7 +86,7 @@ static int hi3519_clk_probe(struct platform_device *pdev)
 	struct hisi_clock_data *clk_data;
 	struct hisi_reset_controller *rstc;
 
-	rstc = hisi_reset_init(np);
+	rstc = hisi_reset_init(pdev);
 	if (!rstc)
 		return -ENOMEM;
 
diff --git a/drivers/clk/hisilicon/reset.c b/drivers/clk/hisilicon/reset.c
index 6aa49c2..2a5015c 100644
--- a/drivers/clk/hisilicon/reset.c
+++ b/drivers/clk/hisilicon/reset.c
@@ -19,6 +19,7 @@
 
 #include <linux/io.h>
 #include <linux/of_address.h>
+#include <linux/platform_device.h>
 #include <linux/reset-controller.h>
 #include <linux/slab.h>
 #include <linux/spinlock.h>
@@ -98,25 +99,25 @@ static const struct reset_control_ops hisi_reset_ops = {
 	.deassert	= hisi_reset_deassert,
 };
 
-struct hisi_reset_controller *hisi_reset_init(struct device_node *np)
+struct hisi_reset_controller *hisi_reset_init(struct platform_device *pdev)
 {
 	struct hisi_reset_controller *rstc;
+	struct resource *res;
 
-	rstc = kzalloc(sizeof(*rstc), GFP_KERNEL);
+	rstc = devm_kmalloc(&pdev->dev, sizeof(*rstc), GFP_KERNEL);
 	if (!rstc)
 		return NULL;
 
-	rstc->membase = of_iomap(np, 0);
-	if (!rstc->membase) {
-		kfree(rstc);
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	rstc->membase = devm_ioremap(&pdev->dev,
+				res->start, resource_size(res));
+	if (!rstc->membase)
 		return NULL;
-	}
 
 	spin_lock_init(&rstc->lock);
-
 	rstc->rcdev.owner = THIS_MODULE;
 	rstc->rcdev.ops = &hisi_reset_ops;
-	rstc->rcdev.of_node = np;
+	rstc->rcdev.of_node = pdev->dev.of_node;
 	rstc->rcdev.of_reset_n_cells = 2;
 	rstc->rcdev.of_xlate = hisi_reset_of_xlate;
 	reset_controller_register(&rstc->rcdev);
@@ -128,7 +129,5 @@ EXPORT_SYMBOL_GPL(hisi_reset_init);
 void hisi_reset_exit(struct hisi_reset_controller *rstc)
 {
 	reset_controller_unregister(&rstc->rcdev);
-	iounmap(rstc->membase);
-	kfree(rstc);
 }
 EXPORT_SYMBOL_GPL(hisi_reset_exit);
diff --git a/drivers/clk/hisilicon/reset.h b/drivers/clk/hisilicon/reset.h
index 677d773..9a69374 100644
--- a/drivers/clk/hisilicon/reset.h
+++ b/drivers/clk/hisilicon/reset.h
@@ -22,10 +22,11 @@ struct device_node;
 struct hisi_reset_controller;
 
 #ifdef CONFIG_RESET_CONTROLLER
-struct hisi_reset_controller *hisi_reset_init(struct device_node *np);
+struct hisi_reset_controller *hisi_reset_init(struct platform_device *pdev);
 void hisi_reset_exit(struct hisi_reset_controller *rstc);
 #else
-static inline hisi_reset_controller *hisi_reset_init(struct device_node *np)
+static inline
+struct hisi_reset_controller *hisi_reset_init(struct platform_device *pdev)
 {
 	return 0;
 }
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH v2 2/5] clk: hisilicon: add hisi_clk_alloc function.
  2016-06-15  6:26 [RESEND PATCH v2 0/5] clk: hisilicon: Fix some problems of clk-hi3519 Jiancheng Xue
  2016-06-15  6:26 ` [PATCH v2 1/5] reset: hisilicon: change the definition of hisi_reset_init Jiancheng Xue
@ 2016-06-15  6:26 ` Jiancheng Xue
  2016-06-30 19:36   ` Stephen Boyd
  2016-06-15  6:26 ` [PATCH v2 3/5] clk: hisilicon: add error processing for hisi_clk_register_* functions Jiancheng Xue
                   ` (3 subsequent siblings)
  5 siblings, 1 reply; 12+ messages in thread
From: Jiancheng Xue @ 2016-06-15  6:26 UTC (permalink / raw)
  To: mturquette, sboyd, p.zabel
  Cc: linux-clk, linux-kernel, yanhaifeng, yanghongwei, Jiancheng Xue

Before, there was an ordering issue that the clock provider
had been published in hisi_clk_init before it could provide
valid clocks to consumers. hisi_clk_alloc is just used to
allocate memory space for struct hisi_clock_data. It makes
it possible to publish the provider after the clocks are ready.

Signed-off-by: Jiancheng Xue <xuejiancheng@hisilicon.com>
---
 drivers/clk/hisilicon/clk.c | 29 +++++++++++++++++++++++++++++
 drivers/clk/hisilicon/clk.h |  3 +++
 2 files changed, 32 insertions(+)

diff --git a/drivers/clk/hisilicon/clk.c b/drivers/clk/hisilicon/clk.c
index 9b15adb..78675d1 100644
--- a/drivers/clk/hisilicon/clk.c
+++ b/drivers/clk/hisilicon/clk.c
@@ -37,6 +37,35 @@
 
 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);
+	clk_data->base = devm_ioremap(&pdev->dev,
+				res->start, resource_size(res));
+	if (!clk_data->base)
+		return NULL;
+
+	clk_table = devm_kmalloc(&pdev->dev, sizeof(struct clk *) * nr_clks,
+				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)
 {
diff --git a/drivers/clk/hisilicon/clk.h b/drivers/clk/hisilicon/clk.h
index 20d64af..5fc644f 100644
--- a/drivers/clk/hisilicon/clk.h
+++ b/drivers/clk/hisilicon/clk.h
@@ -30,6 +30,8 @@
 #include <linux/io.h>
 #include <linux/spinlock.h>
 
+struct platform_device;
+
 struct hisi_clock_data {
 	struct clk_onecell_data	clk_data;
 	void __iomem		*base;
@@ -110,6 +112,7 @@ 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_register_fixed_rate(const struct hisi_fixed_rate_clock *,
 				int, struct hisi_clock_data *);
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH v2 3/5] clk: hisilicon: add error processing for hisi_clk_register_* functions
  2016-06-15  6:26 [RESEND PATCH v2 0/5] clk: hisilicon: Fix some problems of clk-hi3519 Jiancheng Xue
  2016-06-15  6:26 ` [PATCH v2 1/5] reset: hisilicon: change the definition of hisi_reset_init Jiancheng Xue
  2016-06-15  6:26 ` [PATCH v2 2/5] clk: hisilicon: add hisi_clk_alloc function Jiancheng Xue
@ 2016-06-15  6:26 ` Jiancheng Xue
  2016-06-30 19:36   ` Stephen Boyd
  2016-06-15  6:26 ` [PATCH v2 4/5] clk: hisilicon: add hisi_clk_unregister_* functions Jiancheng Xue
                   ` (2 subsequent siblings)
  5 siblings, 1 reply; 12+ messages in thread
From: Jiancheng Xue @ 2016-06-15  6:26 UTC (permalink / raw)
  To: mturquette, sboyd, p.zabel
  Cc: linux-clk, linux-kernel, yanhaifeng, yanghongwei, Jiancheng Xue

Add error processing for hisi_clk_register_* functions.

Signed-off-by: Jiancheng Xue <xuejiancheng@hisilicon.com>
---
 drivers/clk/hisilicon/clk.c | 60 +++++++++++++++++++++++++++++++++++++--------
 drivers/clk/hisilicon/clk.h | 10 ++++----
 2 files changed, 55 insertions(+), 15 deletions(-)

diff --git a/drivers/clk/hisilicon/clk.c b/drivers/clk/hisilicon/clk.c
index 78675d1..9ba2d91 100644
--- a/drivers/clk/hisilicon/clk.c
+++ b/drivers/clk/hisilicon/clk.c
@@ -102,7 +102,7 @@ err:
 }
 EXPORT_SYMBOL_GPL(hisi_clk_init);
 
-void hisi_clk_register_fixed_rate(const struct hisi_fixed_rate_clock *clks,
+int hisi_clk_register_fixed_rate(const struct hisi_fixed_rate_clock *clks,
 					 int nums, struct hisi_clock_data *data)
 {
 	struct clk *clk;
@@ -116,14 +116,22 @@ void hisi_clk_register_fixed_rate(const struct hisi_fixed_rate_clock *clks,
 		if (IS_ERR(clk)) {
 			pr_err("%s: failed to register clock %s\n",
 			       __func__, clks[i].name);
-			continue;
+			goto err;
 		}
 		data->clk_data.clks[clks[i].id] = clk;
 	}
+
+	return 0;
+
+err:
+	while (i--)
+		clk_unregister_fixed_rate(data->clk_data.clks[clks[i].id]);
+
+	return PTR_ERR(clk);
 }
 EXPORT_SYMBOL_GPL(hisi_clk_register_fixed_rate);
 
-void hisi_clk_register_fixed_factor(const struct hisi_fixed_factor_clock *clks,
+int hisi_clk_register_fixed_factor(const struct hisi_fixed_factor_clock *clks,
 					   int nums,
 					   struct hisi_clock_data *data)
 {
@@ -138,14 +146,22 @@ void hisi_clk_register_fixed_factor(const struct hisi_fixed_factor_clock *clks,
 		if (IS_ERR(clk)) {
 			pr_err("%s: failed to register clock %s\n",
 			       __func__, clks[i].name);
-			continue;
+			goto err;
 		}
 		data->clk_data.clks[clks[i].id] = clk;
 	}
+
+	return 0;
+
+err:
+	while (i--)
+		clk_unregister_fixed_factor(data->clk_data.clks[clks[i].id]);
+
+	return PTR_ERR(clk);
 }
 EXPORT_SYMBOL_GPL(hisi_clk_register_fixed_factor);
 
-void hisi_clk_register_mux(const struct hisi_mux_clock *clks,
+int hisi_clk_register_mux(const struct hisi_mux_clock *clks,
 				  int nums, struct hisi_clock_data *data)
 {
 	struct clk *clk;
@@ -164,7 +180,7 @@ void hisi_clk_register_mux(const struct hisi_mux_clock *clks,
 		if (IS_ERR(clk)) {
 			pr_err("%s: failed to register clock %s\n",
 			       __func__, clks[i].name);
-			continue;
+			goto err;
 		}
 
 		if (clks[i].alias)
@@ -172,10 +188,18 @@ void hisi_clk_register_mux(const struct hisi_mux_clock *clks,
 
 		data->clk_data.clks[clks[i].id] = clk;
 	}
+
+	return 0;
+
+err:
+	while (i--)
+		clk_unregister_mux(data->clk_data.clks[clks[i].id]);
+
+	return PTR_ERR(clk);
 }
 EXPORT_SYMBOL_GPL(hisi_clk_register_mux);
 
-void hisi_clk_register_divider(const struct hisi_divider_clock *clks,
+int hisi_clk_register_divider(const struct hisi_divider_clock *clks,
 				      int nums, struct hisi_clock_data *data)
 {
 	struct clk *clk;
@@ -194,7 +218,7 @@ void hisi_clk_register_divider(const struct hisi_divider_clock *clks,
 		if (IS_ERR(clk)) {
 			pr_err("%s: failed to register clock %s\n",
 			       __func__, clks[i].name);
-			continue;
+			goto err;
 		}
 
 		if (clks[i].alias)
@@ -202,10 +226,18 @@ void hisi_clk_register_divider(const struct hisi_divider_clock *clks,
 
 		data->clk_data.clks[clks[i].id] = clk;
 	}
+
+	return 0;
+
+err:
+	while (i--)
+		clk_unregister_divider(data->clk_data.clks[clks[i].id]);
+
+	return PTR_ERR(clk);
 }
 EXPORT_SYMBOL_GPL(hisi_clk_register_divider);
 
-void hisi_clk_register_gate(const struct hisi_gate_clock *clks,
+int hisi_clk_register_gate(const struct hisi_gate_clock *clks,
 				       int nums, struct hisi_clock_data *data)
 {
 	struct clk *clk;
@@ -223,7 +255,7 @@ void hisi_clk_register_gate(const struct hisi_gate_clock *clks,
 		if (IS_ERR(clk)) {
 			pr_err("%s: failed to register clock %s\n",
 			       __func__, clks[i].name);
-			continue;
+			goto err;
 		}
 
 		if (clks[i].alias)
@@ -231,6 +263,14 @@ void hisi_clk_register_gate(const struct hisi_gate_clock *clks,
 
 		data->clk_data.clks[clks[i].id] = clk;
 	}
+
+	return 0;
+
+err:
+	while (i--)
+		clk_unregister_gate(data->clk_data.clks[clks[i].id]);
+
+	return PTR_ERR(clk);
 }
 EXPORT_SYMBOL_GPL(hisi_clk_register_gate);
 
diff --git a/drivers/clk/hisilicon/clk.h b/drivers/clk/hisilicon/clk.h
index 5fc644f..2575329 100644
--- a/drivers/clk/hisilicon/clk.h
+++ b/drivers/clk/hisilicon/clk.h
@@ -114,15 +114,15 @@ struct clk *hi6220_register_clkdiv(struct device *dev, const char *name,
 
 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_register_fixed_rate(const struct hisi_fixed_rate_clock *,
+int hisi_clk_register_fixed_rate(const struct hisi_fixed_rate_clock *,
 				int, struct hisi_clock_data *);
-void hisi_clk_register_fixed_factor(const struct hisi_fixed_factor_clock *,
+int hisi_clk_register_fixed_factor(const struct hisi_fixed_factor_clock *,
 				int, struct hisi_clock_data *);
-void hisi_clk_register_mux(const struct hisi_mux_clock *, int,
+int hisi_clk_register_mux(const struct hisi_mux_clock *, int,
 				struct hisi_clock_data *);
-void hisi_clk_register_divider(const struct hisi_divider_clock *,
+int hisi_clk_register_divider(const struct hisi_divider_clock *,
 				int, struct hisi_clock_data *);
-void hisi_clk_register_gate(const struct hisi_gate_clock *,
+int hisi_clk_register_gate(const struct hisi_gate_clock *,
 				int, struct hisi_clock_data *);
 void hisi_clk_register_gate_sep(const struct hisi_gate_clock *,
 				int, struct hisi_clock_data *);
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH v2 4/5] clk: hisilicon: add hisi_clk_unregister_* functions
  2016-06-15  6:26 [RESEND PATCH v2 0/5] clk: hisilicon: Fix some problems of clk-hi3519 Jiancheng Xue
                   ` (2 preceding siblings ...)
  2016-06-15  6:26 ` [PATCH v2 3/5] clk: hisilicon: add error processing for hisi_clk_register_* functions Jiancheng Xue
@ 2016-06-15  6:26 ` Jiancheng Xue
  2016-06-30 19:36   ` Stephen Boyd
  2016-06-15  6:26 ` [PATCH v2 5/5] clk: hisilicon: hi3519: add driver remove path and fix some issues Jiancheng Xue
  2016-06-28  7:26 ` [RESEND PATCH v2 0/5] clk: hisilicon: Fix some problems of clk-hi3519 Jiancheng Xue
  5 siblings, 1 reply; 12+ messages in thread
From: Jiancheng Xue @ 2016-06-15  6:26 UTC (permalink / raw)
  To: mturquette, sboyd, p.zabel
  Cc: linux-clk, linux-kernel, yanhaifeng, yanghongwei, Jiancheng Xue

Add hisi_clk_unregister_* functions.

Signed-off-by: Jiancheng Xue <xuejiancheng@hisilicon.com>
---
 drivers/clk/hisilicon/clk.h | 21 +++++++++++++++++++++
 1 file changed, 21 insertions(+)

diff --git a/drivers/clk/hisilicon/clk.h b/drivers/clk/hisilicon/clk.h
index 2575329..4e1d1af 100644
--- a/drivers/clk/hisilicon/clk.h
+++ b/drivers/clk/hisilicon/clk.h
@@ -128,4 +128,25 @@ void hisi_clk_register_gate_sep(const struct hisi_gate_clock *,
 				int, struct hisi_clock_data *);
 void hi6220_clk_register_divider(const struct hi6220_divider_clock *,
 				int, struct hisi_clock_data *);
+
+#define hisi_clk_unregister(type) \
+static inline \
+void hisi_clk_unregister_##type(const struct hisi_##type##_clock *clks, \
+				int nums, struct hisi_clock_data *data) \
+{ \
+	struct clk **clocks = data->clk_data.clks; \
+	int i; \
+	for (i = 0; i < nums; i++) { \
+		int id = clks[i].id; \
+		if (clocks[id])  \
+			clk_unregister_##type(clocks[id]); \
+	} \
+}
+
+hisi_clk_unregister(fixed_rate)
+hisi_clk_unregister(fixed_factor)
+hisi_clk_unregister(mux)
+hisi_clk_unregister(divider)
+hisi_clk_unregister(gate)
+
 #endif	/* __HISI_CLK_H */
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH v2 5/5] clk: hisilicon: hi3519: add driver remove path and fix some issues
  2016-06-15  6:26 [RESEND PATCH v2 0/5] clk: hisilicon: Fix some problems of clk-hi3519 Jiancheng Xue
                   ` (3 preceding siblings ...)
  2016-06-15  6:26 ` [PATCH v2 4/5] clk: hisilicon: add hisi_clk_unregister_* functions Jiancheng Xue
@ 2016-06-15  6:26 ` Jiancheng Xue
  2016-06-30 19:36   ` Stephen Boyd
  2016-06-28  7:26 ` [RESEND PATCH v2 0/5] clk: hisilicon: Fix some problems of clk-hi3519 Jiancheng Xue
  5 siblings, 1 reply; 12+ messages in thread
From: Jiancheng Xue @ 2016-06-15  6:26 UTC (permalink / raw)
  To: mturquette, sboyd, p.zabel
  Cc: linux-clk, linux-kernel, yanhaifeng, yanghongwei, Jiancheng Xue

1. Add driver remove path.
2. Fix some issues.
   -Fix the ordering issue about clock provider being published.
   -Add error checking upon registering clocks.

Signed-off-by: Jiancheng Xue <xuejiancheng@hisilicon.com>
---
 drivers/clk/hisilicon/clk-hi3519.c | 116 ++++++++++++++++++++++++++++++++-----
 1 file changed, 100 insertions(+), 16 deletions(-)

diff --git a/drivers/clk/hisilicon/clk-hi3519.c b/drivers/clk/hisilicon/clk-hi3519.c
index 8d12700..51b173e 100644
--- a/drivers/clk/hisilicon/clk-hi3519.c
+++ b/drivers/clk/hisilicon/clk-hi3519.c
@@ -38,6 +38,11 @@
 
 #define HI3519_NR_CLKS		128
 
+struct hi3519_crg_data {
+	struct hisi_clock_data *clk_data;
+	struct hisi_reset_controller *rstc;
+};
+
 static const struct hisi_fixed_rate_clock hi3519_fixed_rate_clks[] = {
 	{ HI3519_FIXED_24M, "24m", NULL, 0, 24000000, },
 	{ HI3519_FIXED_50M, "50m", NULL, 0, 50000000, },
@@ -80,33 +85,105 @@ static const struct hisi_gate_clock hi3519_gate_clks[] = {
 		CLK_SET_RATE_PARENT, 0xe4, 18, 0, },
 };
 
-static int hi3519_clk_probe(struct platform_device *pdev)
+static struct hisi_clock_data *hi3519_clk_register(struct platform_device *pdev)
 {
-	struct device_node *np = pdev->dev.of_node;
 	struct hisi_clock_data *clk_data;
-	struct hisi_reset_controller *rstc;
+	int ret;
 
-	rstc = hisi_reset_init(pdev);
-	if (!rstc)
+	clk_data = hisi_clk_alloc(pdev, HI3519_NR_CLKS);
+	if (!clk_data)
+		return ERR_PTR(-ENOMEM);
+
+	ret = hisi_clk_register_fixed_rate(hi3519_fixed_rate_clks,
+				     ARRAY_SIZE(hi3519_fixed_rate_clks),
+				     clk_data);
+	if (ret)
+		return ERR_PTR(ret);
+
+	ret = hisi_clk_register_mux(hi3519_mux_clks,
+				ARRAY_SIZE(hi3519_mux_clks),
+				clk_data);
+	if (ret)
+		goto unregister_fixed_rate;
+
+	ret = hisi_clk_register_gate(hi3519_gate_clks,
+				ARRAY_SIZE(hi3519_gate_clks),
+				clk_data);
+	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:
+	hisi_clk_unregister_fixed_rate(hi3519_fixed_rate_clks,
+				ARRAY_SIZE(hi3519_fixed_rate_clks),
+				clk_data);
+
+unregister_mux:
+	hisi_clk_unregister_mux(hi3519_mux_clks,
+				ARRAY_SIZE(hi3519_mux_clks),
+				clk_data);
+unregister_gate:
+	hisi_clk_unregister_gate(hi3519_gate_clks,
+				ARRAY_SIZE(hi3519_gate_clks),
+				clk_data);
+	return ERR_PTR(ret);
+}
+
+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);
+	hisi_clk_unregister_mux(hi3519_mux_clks,
+				ARRAY_SIZE(hi3519_mux_clks),
+				crg->clk_data);
+	hisi_clk_unregister_fixed_rate(hi3519_fixed_rate_clks,
+				ARRAY_SIZE(hi3519_fixed_rate_clks),
+				crg->clk_data);
+}
+
+static int hi3519_clk_probe(struct platform_device *pdev)
+{
+	struct hi3519_crg_data *crg;
+
+	crg = devm_kmalloc(&pdev->dev, sizeof(*crg), GFP_KERNEL);
+	if (!crg)
+		return -ENOMEM;
+
+	crg->rstc = hisi_reset_init(pdev);
+	if (!crg->rstc)
 		return -ENOMEM;
 
-	clk_data = hisi_clk_init(np, HI3519_NR_CLKS);
-	if (!clk_data) {
-		hisi_reset_exit(rstc);
-		return -ENODEV;
+	crg->clk_data = hi3519_clk_register(pdev);
+	if (IS_ERR(crg->clk_data)) {
+		hisi_reset_exit(crg->rstc);
+		return PTR_ERR(crg->clk_data);
 	}
 
-	hisi_clk_register_fixed_rate(hi3519_fixed_rate_clks,
-				     ARRAY_SIZE(hi3519_fixed_rate_clks),
-				     clk_data);
-	hisi_clk_register_mux(hi3519_mux_clks, ARRAY_SIZE(hi3519_mux_clks),
-					clk_data);
-	hisi_clk_register_gate(hi3519_gate_clks,
-			ARRAY_SIZE(hi3519_gate_clks), clk_data);
+	platform_set_drvdata(pdev, crg);
+	return 0;
+}
+
+static int hi3519_clk_remove(struct platform_device *pdev)
+{
+	struct hi3519_crg_data *crg = platform_get_drvdata(pdev);
 
+	hisi_reset_exit(crg->rstc);
+	hi3519_clk_unregister(pdev);
 	return 0;
 }
 
+
 static const struct of_device_id hi3519_clk_match_table[] = {
 	{ .compatible = "hisilicon,hi3519-crg" },
 	{ }
@@ -115,6 +192,7 @@ MODULE_DEVICE_TABLE(of, hi3519_clk_match_table);
 
 static struct platform_driver hi3519_clk_driver = {
 	.probe          = hi3519_clk_probe,
+	.remove		= hi3519_clk_remove,
 	.driver         = {
 		.name   = "hi3519-clk",
 		.of_match_table = hi3519_clk_match_table,
@@ -127,5 +205,11 @@ static int __init hi3519_clk_init(void)
 }
 core_initcall(hi3519_clk_init);
 
+static void __exit hi3519_clk_exit(void)
+{
+	platform_driver_unregister(&hi3519_clk_driver);
+}
+module_exit(hi3519_clk_exit);
+
 MODULE_LICENSE("GPL v2");
 MODULE_DESCRIPTION("HiSilicon Hi3519 Clock Driver");
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 12+ messages in thread

* Re: [RESEND PATCH v2 0/5] clk: hisilicon: Fix some problems of clk-hi3519
  2016-06-15  6:26 [RESEND PATCH v2 0/5] clk: hisilicon: Fix some problems of clk-hi3519 Jiancheng Xue
                   ` (4 preceding siblings ...)
  2016-06-15  6:26 ` [PATCH v2 5/5] clk: hisilicon: hi3519: add driver remove path and fix some issues Jiancheng Xue
@ 2016-06-28  7:26 ` Jiancheng Xue
  5 siblings, 0 replies; 12+ messages in thread
From: Jiancheng Xue @ 2016-06-28  7:26 UTC (permalink / raw)
  To: Stephen Boyd; +Cc: linux-clk, linux-kernel, yanhaifeng, yanghongwei

Hi Stephen,
    Can this patch be merged into the clk-next? If there are still some
issues to fix, please let me know. Thank you very much.

Regards,
Jiancheng

On 2016/6/15 14:26, Jiancheng Xue wrote:
> This patch is base on branch clk-hi3519 in clk tree. It mainly fixes the
> following issues:
> 1. Add driver remove path.
> 2. Fix the ordering issue about clock provider being published.
> 3. Add error checking upon registering clocks. 
> 
> change log
> v2:
> -Redivided patches to make sure every patch can be compiled successfully.
> 
> Jiancheng Xue (5):
>   reset: hisilicon: change the definition of hisi_reset_init
>   clk: hisilicon: add hisi_clk_alloc function.
>   clk: hisilicon: add error processing for hisi_clk_register_* functions
>   clk: hisilicon: add hisi_clk_unregister_* functions
>   clk: hisilicon: hi3519: add driver remove path and fix some issues
> 
>  drivers/clk/hisilicon/clk-hi3519.c | 116 ++++++++++++++++++++++++++++++++-----
>  drivers/clk/hisilicon/clk.c        |  89 ++++++++++++++++++++++++----
>  drivers/clk/hisilicon/clk.h        |  34 +++++++++--
>  drivers/clk/hisilicon/reset.c      |  19 +++---
>  drivers/clk/hisilicon/reset.h      |   5 +-
>  5 files changed, 220 insertions(+), 43 deletions(-)
> 

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH v2 5/5] clk: hisilicon: hi3519: add driver remove path and fix some issues
  2016-06-15  6:26 ` [PATCH v2 5/5] clk: hisilicon: hi3519: add driver remove path and fix some issues Jiancheng Xue
@ 2016-06-30 19:36   ` Stephen Boyd
  0 siblings, 0 replies; 12+ messages in thread
From: Stephen Boyd @ 2016-06-30 19:36 UTC (permalink / raw)
  To: Jiancheng Xue
  Cc: mturquette, p.zabel, linux-clk, linux-kernel, yanhaifeng, yanghongwei

On 06/15, Jiancheng Xue wrote:
> 1. Add driver remove path.
> 2. Fix some issues.
>    -Fix the ordering issue about clock provider being published.
>    -Add error checking upon registering clocks.
> 
> Signed-off-by: Jiancheng Xue <xuejiancheng@hisilicon.com>
> ---

Applied to clk-next

-- 
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH v2 4/5] clk: hisilicon: add hisi_clk_unregister_* functions
  2016-06-15  6:26 ` [PATCH v2 4/5] clk: hisilicon: add hisi_clk_unregister_* functions Jiancheng Xue
@ 2016-06-30 19:36   ` Stephen Boyd
  0 siblings, 0 replies; 12+ messages in thread
From: Stephen Boyd @ 2016-06-30 19:36 UTC (permalink / raw)
  To: Jiancheng Xue
  Cc: mturquette, p.zabel, linux-clk, linux-kernel, yanhaifeng, yanghongwei

On 06/15, Jiancheng Xue wrote:
> Add hisi_clk_unregister_* functions.
> 
> Signed-off-by: Jiancheng Xue <xuejiancheng@hisilicon.com>
> ---

Applied to clk-next

-- 
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH v2 3/5] clk: hisilicon: add error processing for hisi_clk_register_* functions
  2016-06-15  6:26 ` [PATCH v2 3/5] clk: hisilicon: add error processing for hisi_clk_register_* functions Jiancheng Xue
@ 2016-06-30 19:36   ` Stephen Boyd
  0 siblings, 0 replies; 12+ messages in thread
From: Stephen Boyd @ 2016-06-30 19:36 UTC (permalink / raw)
  To: Jiancheng Xue
  Cc: mturquette, p.zabel, linux-clk, linux-kernel, yanhaifeng, yanghongwei

On 06/15, Jiancheng Xue wrote:
> Add error processing for hisi_clk_register_* functions.
> 
> Signed-off-by: Jiancheng Xue <xuejiancheng@hisilicon.com>
> ---

Applied to clk-next

-- 
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH v2 2/5] clk: hisilicon: add hisi_clk_alloc function.
  2016-06-15  6:26 ` [PATCH v2 2/5] clk: hisilicon: add hisi_clk_alloc function Jiancheng Xue
@ 2016-06-30 19:36   ` Stephen Boyd
  0 siblings, 0 replies; 12+ messages in thread
From: Stephen Boyd @ 2016-06-30 19:36 UTC (permalink / raw)
  To: Jiancheng Xue
  Cc: mturquette, p.zabel, linux-clk, linux-kernel, yanhaifeng, yanghongwei

On 06/15, Jiancheng Xue wrote:
> Before, there was an ordering issue that the clock provider
> had been published in hisi_clk_init before it could provide
> valid clocks to consumers. hisi_clk_alloc is just used to
> allocate memory space for struct hisi_clock_data. It makes
> it possible to publish the provider after the clocks are ready.
> 
> Signed-off-by: Jiancheng Xue <xuejiancheng@hisilicon.com>
> ---

Applied to clk-next

-- 
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project

^ permalink raw reply	[flat|nested] 12+ messages in thread

* [PATCH v2 3/5] clk: hisilicon: add error processing for hisi_clk_register_* functions
  2016-05-13  2:05 [PATCH " Jiancheng Xue
@ 2016-05-13  2:05 ` Jiancheng Xue
  0 siblings, 0 replies; 12+ messages in thread
From: Jiancheng Xue @ 2016-05-13  2:05 UTC (permalink / raw)
  To: mturquette, sboyd, p.zabel
  Cc: linux-clk, linux-kernel, yanhaifeng, haojian.zhuang,
	zhangfei.gao, xuwei5, yanghongwei, Jiancheng Xue

Add error processing for hisi_clk_register_* functions.

Signed-off-by: Jiancheng Xue <xuejiancheng@hisilicon.com>
---
 drivers/clk/hisilicon/clk.c | 60 +++++++++++++++++++++++++++++++++++++--------
 drivers/clk/hisilicon/clk.h | 10 ++++----
 2 files changed, 55 insertions(+), 15 deletions(-)

diff --git a/drivers/clk/hisilicon/clk.c b/drivers/clk/hisilicon/clk.c
index 78675d1..9ba2d91 100644
--- a/drivers/clk/hisilicon/clk.c
+++ b/drivers/clk/hisilicon/clk.c
@@ -102,7 +102,7 @@ err:
 }
 EXPORT_SYMBOL_GPL(hisi_clk_init);
 
-void hisi_clk_register_fixed_rate(const struct hisi_fixed_rate_clock *clks,
+int hisi_clk_register_fixed_rate(const struct hisi_fixed_rate_clock *clks,
 					 int nums, struct hisi_clock_data *data)
 {
 	struct clk *clk;
@@ -116,14 +116,22 @@ void hisi_clk_register_fixed_rate(const struct hisi_fixed_rate_clock *clks,
 		if (IS_ERR(clk)) {
 			pr_err("%s: failed to register clock %s\n",
 			       __func__, clks[i].name);
-			continue;
+			goto err;
 		}
 		data->clk_data.clks[clks[i].id] = clk;
 	}
+
+	return 0;
+
+err:
+	while (i--)
+		clk_unregister_fixed_rate(data->clk_data.clks[clks[i].id]);
+
+	return PTR_ERR(clk);
 }
 EXPORT_SYMBOL_GPL(hisi_clk_register_fixed_rate);
 
-void hisi_clk_register_fixed_factor(const struct hisi_fixed_factor_clock *clks,
+int hisi_clk_register_fixed_factor(const struct hisi_fixed_factor_clock *clks,
 					   int nums,
 					   struct hisi_clock_data *data)
 {
@@ -138,14 +146,22 @@ void hisi_clk_register_fixed_factor(const struct hisi_fixed_factor_clock *clks,
 		if (IS_ERR(clk)) {
 			pr_err("%s: failed to register clock %s\n",
 			       __func__, clks[i].name);
-			continue;
+			goto err;
 		}
 		data->clk_data.clks[clks[i].id] = clk;
 	}
+
+	return 0;
+
+err:
+	while (i--)
+		clk_unregister_fixed_factor(data->clk_data.clks[clks[i].id]);
+
+	return PTR_ERR(clk);
 }
 EXPORT_SYMBOL_GPL(hisi_clk_register_fixed_factor);
 
-void hisi_clk_register_mux(const struct hisi_mux_clock *clks,
+int hisi_clk_register_mux(const struct hisi_mux_clock *clks,
 				  int nums, struct hisi_clock_data *data)
 {
 	struct clk *clk;
@@ -164,7 +180,7 @@ void hisi_clk_register_mux(const struct hisi_mux_clock *clks,
 		if (IS_ERR(clk)) {
 			pr_err("%s: failed to register clock %s\n",
 			       __func__, clks[i].name);
-			continue;
+			goto err;
 		}
 
 		if (clks[i].alias)
@@ -172,10 +188,18 @@ void hisi_clk_register_mux(const struct hisi_mux_clock *clks,
 
 		data->clk_data.clks[clks[i].id] = clk;
 	}
+
+	return 0;
+
+err:
+	while (i--)
+		clk_unregister_mux(data->clk_data.clks[clks[i].id]);
+
+	return PTR_ERR(clk);
 }
 EXPORT_SYMBOL_GPL(hisi_clk_register_mux);
 
-void hisi_clk_register_divider(const struct hisi_divider_clock *clks,
+int hisi_clk_register_divider(const struct hisi_divider_clock *clks,
 				      int nums, struct hisi_clock_data *data)
 {
 	struct clk *clk;
@@ -194,7 +218,7 @@ void hisi_clk_register_divider(const struct hisi_divider_clock *clks,
 		if (IS_ERR(clk)) {
 			pr_err("%s: failed to register clock %s\n",
 			       __func__, clks[i].name);
-			continue;
+			goto err;
 		}
 
 		if (clks[i].alias)
@@ -202,10 +226,18 @@ void hisi_clk_register_divider(const struct hisi_divider_clock *clks,
 
 		data->clk_data.clks[clks[i].id] = clk;
 	}
+
+	return 0;
+
+err:
+	while (i--)
+		clk_unregister_divider(data->clk_data.clks[clks[i].id]);
+
+	return PTR_ERR(clk);
 }
 EXPORT_SYMBOL_GPL(hisi_clk_register_divider);
 
-void hisi_clk_register_gate(const struct hisi_gate_clock *clks,
+int hisi_clk_register_gate(const struct hisi_gate_clock *clks,
 				       int nums, struct hisi_clock_data *data)
 {
 	struct clk *clk;
@@ -223,7 +255,7 @@ void hisi_clk_register_gate(const struct hisi_gate_clock *clks,
 		if (IS_ERR(clk)) {
 			pr_err("%s: failed to register clock %s\n",
 			       __func__, clks[i].name);
-			continue;
+			goto err;
 		}
 
 		if (clks[i].alias)
@@ -231,6 +263,14 @@ void hisi_clk_register_gate(const struct hisi_gate_clock *clks,
 
 		data->clk_data.clks[clks[i].id] = clk;
 	}
+
+	return 0;
+
+err:
+	while (i--)
+		clk_unregister_gate(data->clk_data.clks[clks[i].id]);
+
+	return PTR_ERR(clk);
 }
 EXPORT_SYMBOL_GPL(hisi_clk_register_gate);
 
diff --git a/drivers/clk/hisilicon/clk.h b/drivers/clk/hisilicon/clk.h
index 5fc644f..2575329 100644
--- a/drivers/clk/hisilicon/clk.h
+++ b/drivers/clk/hisilicon/clk.h
@@ -114,15 +114,15 @@ struct clk *hi6220_register_clkdiv(struct device *dev, const char *name,
 
 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_register_fixed_rate(const struct hisi_fixed_rate_clock *,
+int hisi_clk_register_fixed_rate(const struct hisi_fixed_rate_clock *,
 				int, struct hisi_clock_data *);
-void hisi_clk_register_fixed_factor(const struct hisi_fixed_factor_clock *,
+int hisi_clk_register_fixed_factor(const struct hisi_fixed_factor_clock *,
 				int, struct hisi_clock_data *);
-void hisi_clk_register_mux(const struct hisi_mux_clock *, int,
+int hisi_clk_register_mux(const struct hisi_mux_clock *, int,
 				struct hisi_clock_data *);
-void hisi_clk_register_divider(const struct hisi_divider_clock *,
+int hisi_clk_register_divider(const struct hisi_divider_clock *,
 				int, struct hisi_clock_data *);
-void hisi_clk_register_gate(const struct hisi_gate_clock *,
+int hisi_clk_register_gate(const struct hisi_gate_clock *,
 				int, struct hisi_clock_data *);
 void hisi_clk_register_gate_sep(const struct hisi_gate_clock *,
 				int, struct hisi_clock_data *);
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 12+ messages in thread

end of thread, other threads:[~2016-06-30 19:36 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-06-15  6:26 [RESEND PATCH v2 0/5] clk: hisilicon: Fix some problems of clk-hi3519 Jiancheng Xue
2016-06-15  6:26 ` [PATCH v2 1/5] reset: hisilicon: change the definition of hisi_reset_init Jiancheng Xue
2016-06-15  6:26 ` [PATCH v2 2/5] clk: hisilicon: add hisi_clk_alloc function Jiancheng Xue
2016-06-30 19:36   ` Stephen Boyd
2016-06-15  6:26 ` [PATCH v2 3/5] clk: hisilicon: add error processing for hisi_clk_register_* functions Jiancheng Xue
2016-06-30 19:36   ` Stephen Boyd
2016-06-15  6:26 ` [PATCH v2 4/5] clk: hisilicon: add hisi_clk_unregister_* functions Jiancheng Xue
2016-06-30 19:36   ` Stephen Boyd
2016-06-15  6:26 ` [PATCH v2 5/5] clk: hisilicon: hi3519: add driver remove path and fix some issues Jiancheng Xue
2016-06-30 19:36   ` Stephen Boyd
2016-06-28  7:26 ` [RESEND PATCH v2 0/5] clk: hisilicon: Fix some problems of clk-hi3519 Jiancheng Xue
  -- strict thread matches above, loose matches on Subject: below --
2016-05-13  2:05 [PATCH " Jiancheng Xue
2016-05-13  2:05 ` [PATCH v2 3/5] clk: hisilicon: add error processing for hisi_clk_register_* functions Jiancheng Xue

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).