aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJiancheng Xue <xuejiancheng@hisilicon.com>2016-06-15 02:26:38 -0400
committerStephen Boyd <sboyd@codeaurora.org>2016-06-30 15:35:20 -0400
commit224b3b262c52ef3b13ec62cd879b48d2611c2c10 (patch)
tree08ed88e6c84465ae452bb42370410ade5a92c095
parentfbf0410ed5f96ae63fcb221ab785e746871a4e62 (diff)
clk: hisilicon: hi3519: add driver remove path and fix some issues
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> Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
-rw-r--r--drivers/clk/hisilicon/clk-hi3519.c116
1 files changed, 100 insertions, 16 deletions
diff --git a/drivers/clk/hisilicon/clk-hi3519.c b/drivers/clk/hisilicon/clk-hi3519.c
index 8d12700d0cff..51b173ef1dda 100644
--- a/drivers/clk/hisilicon/clk-hi3519.c
+++ b/drivers/clk/hisilicon/clk-hi3519.c
@@ -38,6 +38,11 @@
38 38
39#define HI3519_NR_CLKS 128 39#define HI3519_NR_CLKS 128
40 40
41struct hi3519_crg_data {
42 struct hisi_clock_data *clk_data;
43 struct hisi_reset_controller *rstc;
44};
45
41static const struct hisi_fixed_rate_clock hi3519_fixed_rate_clks[] = { 46static const struct hisi_fixed_rate_clock hi3519_fixed_rate_clks[] = {
42 { HI3519_FIXED_24M, "24m", NULL, 0, 24000000, }, 47 { HI3519_FIXED_24M, "24m", NULL, 0, 24000000, },
43 { HI3519_FIXED_50M, "50m", NULL, 0, 50000000, }, 48 { HI3519_FIXED_50M, "50m", NULL, 0, 50000000, },
@@ -80,33 +85,105 @@ static const struct hisi_gate_clock hi3519_gate_clks[] = {
80 CLK_SET_RATE_PARENT, 0xe4, 18, 0, }, 85 CLK_SET_RATE_PARENT, 0xe4, 18, 0, },
81}; 86};
82 87
83static int hi3519_clk_probe(struct platform_device *pdev) 88static struct hisi_clock_data *hi3519_clk_register(struct platform_device *pdev)
84{ 89{
85 struct device_node *np = pdev->dev.of_node;
86 struct hisi_clock_data *clk_data; 90 struct hisi_clock_data *clk_data;
87 struct hisi_reset_controller *rstc; 91 int ret;
88 92
89 rstc = hisi_reset_init(pdev); 93 clk_data = hisi_clk_alloc(pdev, HI3519_NR_CLKS);
90 if (!rstc) 94 if (!clk_data)
95 return ERR_PTR(-ENOMEM);
96
97 ret = hisi_clk_register_fixed_rate(hi3519_fixed_rate_clks,
98 ARRAY_SIZE(hi3519_fixed_rate_clks),
99 clk_data);
100 if (ret)
101 return ERR_PTR(ret);
102
103 ret = hisi_clk_register_mux(hi3519_mux_clks,
104 ARRAY_SIZE(hi3519_mux_clks),
105 clk_data);
106 if (ret)
107 goto unregister_fixed_rate;
108
109 ret = hisi_clk_register_gate(hi3519_gate_clks,
110 ARRAY_SIZE(hi3519_gate_clks),
111 clk_data);
112 if (ret)
113 goto unregister_mux;
114
115 ret = of_clk_add_provider(pdev->dev.of_node,
116 of_clk_src_onecell_get, &clk_data->clk_data);
117 if (ret)
118 goto unregister_gate;
119
120 return clk_data;
121
122unregister_fixed_rate:
123 hisi_clk_unregister_fixed_rate(hi3519_fixed_rate_clks,
124 ARRAY_SIZE(hi3519_fixed_rate_clks),
125 clk_data);
126
127unregister_mux:
128 hisi_clk_unregister_mux(hi3519_mux_clks,
129 ARRAY_SIZE(hi3519_mux_clks),
130 clk_data);
131unregister_gate:
132 hisi_clk_unregister_gate(hi3519_gate_clks,
133 ARRAY_SIZE(hi3519_gate_clks),
134 clk_data);
135 return ERR_PTR(ret);
136}
137
138static void hi3519_clk_unregister(struct platform_device *pdev)
139{
140 struct hi3519_crg_data *crg = platform_get_drvdata(pdev);
141
142 of_clk_del_provider(pdev->dev.of_node);
143
144 hisi_clk_unregister_gate(hi3519_gate_clks,
145 ARRAY_SIZE(hi3519_mux_clks),
146 crg->clk_data);
147 hisi_clk_unregister_mux(hi3519_mux_clks,
148 ARRAY_SIZE(hi3519_mux_clks),
149 crg->clk_data);
150 hisi_clk_unregister_fixed_rate(hi3519_fixed_rate_clks,
151 ARRAY_SIZE(hi3519_fixed_rate_clks),
152 crg->clk_data);
153}
154
155static int hi3519_clk_probe(struct platform_device *pdev)
156{
157 struct hi3519_crg_data *crg;
158
159 crg = devm_kmalloc(&pdev->dev, sizeof(*crg), GFP_KERNEL);
160 if (!crg)
161 return -ENOMEM;
162
163 crg->rstc = hisi_reset_init(pdev);
164 if (!crg->rstc)
91 return -ENOMEM; 165 return -ENOMEM;
92 166
93 clk_data = hisi_clk_init(np, HI3519_NR_CLKS); 167 crg->clk_data = hi3519_clk_register(pdev);
94 if (!clk_data) { 168 if (IS_ERR(crg->clk_data)) {
95 hisi_reset_exit(rstc); 169 hisi_reset_exit(crg->rstc);
96 return -ENODEV; 170 return PTR_ERR(crg->clk_data);
97 } 171 }
98 172
99 hisi_clk_register_fixed_rate(hi3519_fixed_rate_clks, 173 platform_set_drvdata(pdev, crg);
100 ARRAY_SIZE(hi3519_fixed_rate_clks), 174 return 0;
101 clk_data); 175}
102 hisi_clk_register_mux(hi3519_mux_clks, ARRAY_SIZE(hi3519_mux_clks), 176
103 clk_data); 177static int hi3519_clk_remove(struct platform_device *pdev)
104 hisi_clk_register_gate(hi3519_gate_clks, 178{
105 ARRAY_SIZE(hi3519_gate_clks), clk_data); 179 struct hi3519_crg_data *crg = platform_get_drvdata(pdev);
106 180
181 hisi_reset_exit(crg->rstc);
182 hi3519_clk_unregister(pdev);
107 return 0; 183 return 0;
108} 184}
109 185
186
110static const struct of_device_id hi3519_clk_match_table[] = { 187static const struct of_device_id hi3519_clk_match_table[] = {
111 { .compatible = "hisilicon,hi3519-crg" }, 188 { .compatible = "hisilicon,hi3519-crg" },
112 { } 189 { }
@@ -115,6 +192,7 @@ MODULE_DEVICE_TABLE(of, hi3519_clk_match_table);
115 192
116static struct platform_driver hi3519_clk_driver = { 193static struct platform_driver hi3519_clk_driver = {
117 .probe = hi3519_clk_probe, 194 .probe = hi3519_clk_probe,
195 .remove = hi3519_clk_remove,
118 .driver = { 196 .driver = {
119 .name = "hi3519-clk", 197 .name = "hi3519-clk",
120 .of_match_table = hi3519_clk_match_table, 198 .of_match_table = hi3519_clk_match_table,
@@ -127,5 +205,11 @@ static int __init hi3519_clk_init(void)
127} 205}
128core_initcall(hi3519_clk_init); 206core_initcall(hi3519_clk_init);
129 207
208static void __exit hi3519_clk_exit(void)
209{
210 platform_driver_unregister(&hi3519_clk_driver);
211}
212module_exit(hi3519_clk_exit);
213
130MODULE_LICENSE("GPL v2"); 214MODULE_LICENSE("GPL v2");
131MODULE_DESCRIPTION("HiSilicon Hi3519 Clock Driver"); 215MODULE_DESCRIPTION("HiSilicon Hi3519 Clock Driver");