aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/clk/mvebu
diff options
context:
space:
mode:
authorGregory CLEMENT <gregory.clement@free-electrons.com>2017-05-31 10:07:26 -0400
committerMichael Turquette <mturquette@baylibre.com>2017-05-31 23:03:21 -0400
commitb90da67543e5aae5cb8162402ac5b483fb660dbd (patch)
tree8e19ead84e3eb9ff229f930de1c586e54856776c /drivers/clk/mvebu
parent55de4d06b4589e5fba9f27b6876884e5af68890e (diff)
clk: mvebu: ap806: introduce a new binding
As for cp110, the initial intent when the binding of the ap806 system controller was to have one flat node. The idea being that what is currently a clock-only driver in drivers would become a MFD driver, exposing the clock, GPIO and pinctrl functionality. However, after taking a step back, this would lead to a messy binding. Indeed, a single node would be a GPIO controller, clock controller, pinmux controller, and more. This patch adopts a more classical solution of a top-level syscon node with sub-nodes for the individual devices. The main benefit will be to have each functional block associated to its own sub-node where we can put its own properties. The introduction of the Armada 7K/8K is still in the early stage so the plan is to remove the old binding. However, we don't want to break the device tree compatibility for the few devices already in the field. For this we still keep the support of the legacy compatible string with a big warning in the kernel about updating the device tree. Acked-by: Rob Herring <robh@kernel.org> Signed-off-by: Gregory CLEMENT <gregory.clement@free-electrons.com> Signed-off-by: Michael Turquette <mturquette@baylibre.com> Link: lkml.kernel.org/r/cc8c8c40fa4c4e71133033358992ec38e5aa2be5.1496239589.git-series.gregory.clement@free-electrons.com
Diffstat (limited to 'drivers/clk/mvebu')
-rw-r--r--drivers/clk/mvebu/ap806-system-controller.c56
1 files changed, 44 insertions, 12 deletions
diff --git a/drivers/clk/mvebu/ap806-system-controller.c b/drivers/clk/mvebu/ap806-system-controller.c
index 95ae16e203ea..fa2fbd2cef4a 100644
--- a/drivers/clk/mvebu/ap806-system-controller.c
+++ b/drivers/clk/mvebu/ap806-system-controller.c
@@ -44,7 +44,8 @@ static char *ap806_unique_name(struct device *dev, struct device_node *np,
44 (unsigned long long)addr, name); 44 (unsigned long long)addr, name);
45} 45}
46 46
47static int ap806_syscon_clk_probe(struct platform_device *pdev) 47static int ap806_syscon_common_probe(struct platform_device *pdev,
48 struct device_node *syscon_node)
48{ 49{
49 unsigned int freq_mode, cpuclk_freq; 50 unsigned int freq_mode, cpuclk_freq;
50 const char *name, *fixedclk_name; 51 const char *name, *fixedclk_name;
@@ -54,7 +55,7 @@ static int ap806_syscon_clk_probe(struct platform_device *pdev)
54 u32 reg; 55 u32 reg;
55 int ret; 56 int ret;
56 57
57 regmap = syscon_node_to_regmap(np); 58 regmap = syscon_node_to_regmap(syscon_node);
58 if (IS_ERR(regmap)) { 59 if (IS_ERR(regmap)) {
59 dev_err(dev, "cannot get regmap\n"); 60 dev_err(dev, "cannot get regmap\n");
60 return PTR_ERR(regmap); 61 return PTR_ERR(regmap);
@@ -110,7 +111,7 @@ static int ap806_syscon_clk_probe(struct platform_device *pdev)
110 cpuclk_freq *= 1000 * 1000; 111 cpuclk_freq *= 1000 * 1000;
111 112
112 /* CPU clocks depend on the Sample At Reset configuration */ 113 /* CPU clocks depend on the Sample At Reset configuration */
113 name = ap806_unique_name(dev, np, "cpu-cluster-0"); 114 name = ap806_unique_name(dev, syscon_node, "cpu-cluster-0");
114 ap806_clks[0] = clk_register_fixed_rate(dev, name, NULL, 115 ap806_clks[0] = clk_register_fixed_rate(dev, name, NULL,
115 0, cpuclk_freq); 116 0, cpuclk_freq);
116 if (IS_ERR(ap806_clks[0])) { 117 if (IS_ERR(ap806_clks[0])) {
@@ -118,7 +119,7 @@ static int ap806_syscon_clk_probe(struct platform_device *pdev)
118 goto fail0; 119 goto fail0;
119 } 120 }
120 121
121 name = ap806_unique_name(dev, np, "cpu-cluster-1"); 122 name = ap806_unique_name(dev, syscon_node, "cpu-cluster-1");
122 ap806_clks[1] = clk_register_fixed_rate(dev, name, NULL, 0, 123 ap806_clks[1] = clk_register_fixed_rate(dev, name, NULL, 0,
123 cpuclk_freq); 124 cpuclk_freq);
124 if (IS_ERR(ap806_clks[1])) { 125 if (IS_ERR(ap806_clks[1])) {
@@ -127,7 +128,7 @@ static int ap806_syscon_clk_probe(struct platform_device *pdev)
127 } 128 }
128 129
129 /* Fixed clock is always 1200 Mhz */ 130 /* Fixed clock is always 1200 Mhz */
130 fixedclk_name = ap806_unique_name(dev, np, "fixed"); 131 fixedclk_name = ap806_unique_name(dev, syscon_node, "fixed");
131 ap806_clks[2] = clk_register_fixed_rate(dev, fixedclk_name, NULL, 132 ap806_clks[2] = clk_register_fixed_rate(dev, fixedclk_name, NULL,
132 0, 1200 * 1000 * 1000); 133 0, 1200 * 1000 * 1000);
133 if (IS_ERR(ap806_clks[2])) { 134 if (IS_ERR(ap806_clks[2])) {
@@ -136,7 +137,7 @@ static int ap806_syscon_clk_probe(struct platform_device *pdev)
136 } 137 }
137 138
138 /* MSS Clock is fixed clock divided by 6 */ 139 /* MSS Clock is fixed clock divided by 6 */
139 name = ap806_unique_name(dev, np, "mss"); 140 name = ap806_unique_name(dev, syscon_node, "mss");
140 ap806_clks[3] = clk_register_fixed_factor(NULL, name, fixedclk_name, 141 ap806_clks[3] = clk_register_fixed_factor(NULL, name, fixedclk_name,
141 0, 1, 6); 142 0, 1, 6);
142 if (IS_ERR(ap806_clks[3])) { 143 if (IS_ERR(ap806_clks[3])) {
@@ -145,7 +146,7 @@ static int ap806_syscon_clk_probe(struct platform_device *pdev)
145 } 146 }
146 147
147 /* SDIO(/eMMC) Clock is fixed clock divided by 3 */ 148 /* SDIO(/eMMC) Clock is fixed clock divided by 3 */
148 name = ap806_unique_name(dev, np, "sdio"); 149 name = ap806_unique_name(dev, syscon_node, "sdio");
149 ap806_clks[4] = clk_register_fixed_factor(NULL, name, 150 ap806_clks[4] = clk_register_fixed_factor(NULL, name,
150 fixedclk_name, 151 fixedclk_name,
151 0, 1, 3); 152 0, 1, 3);
@@ -175,17 +176,48 @@ fail0:
175 return ret; 176 return ret;
176} 177}
177 178
178static const struct of_device_id ap806_syscon_of_match[] = { 179static int ap806_syscon_legacy_probe(struct platform_device *pdev)
180{
181 dev_warn(&pdev->dev, FW_WARN "Using legacy device tree binding\n");
182 dev_warn(&pdev->dev, FW_WARN "Update your device tree:\n");
183 dev_warn(&pdev->dev, FW_WARN
184 "This binding won't be supported in future kernel\n");
185
186 return ap806_syscon_common_probe(pdev, pdev->dev.of_node);
187
188}
189
190static int ap806_clock_probe(struct platform_device *pdev)
191{
192 return ap806_syscon_common_probe(pdev, pdev->dev.of_node->parent);
193}
194
195static const struct of_device_id ap806_syscon_legacy_of_match[] = {
179 { .compatible = "marvell,ap806-system-controller", }, 196 { .compatible = "marvell,ap806-system-controller", },
180 { } 197 { }
181}; 198};
182 199
183static struct platform_driver ap806_syscon_driver = { 200static struct platform_driver ap806_syscon_legacy_driver = {
184 .probe = ap806_syscon_clk_probe, 201 .probe = ap806_syscon_legacy_probe,
185 .driver = { 202 .driver = {
186 .name = "marvell-ap806-system-controller", 203 .name = "marvell-ap806-system-controller",
187 .of_match_table = ap806_syscon_of_match, 204 .of_match_table = ap806_syscon_legacy_of_match,
205 .suppress_bind_attrs = true,
206 },
207};
208builtin_platform_driver(ap806_syscon_legacy_driver);
209
210static const struct of_device_id ap806_clock_of_match[] = {
211 { .compatible = "marvell,ap806-clock", },
212 { }
213};
214
215static struct platform_driver ap806_clock_driver = {
216 .probe = ap806_clock_probe,
217 .driver = {
218 .name = "marvell-ap806-clock",
219 .of_match_table = ap806_clock_of_match,
188 .suppress_bind_attrs = true, 220 .suppress_bind_attrs = true,
189 }, 221 },
190}; 222};
191builtin_platform_driver(ap806_syscon_driver); 223builtin_platform_driver(ap806_clock_driver);