Skip to content

Commit 7ec03b5

Browse files
smaeulmripard
authored andcommitted
clk: sunxi-ng: Convert early providers to platform drivers
The PRCM CCU drivers depend on clocks provided by other CCU drivers. For example, the sun8i-r-ccu driver uses the "pll-periph" clock provided by the SoC's main CCU. However, sun8i-r-ccu is an early OF clock provider, and many of the main CCUs (e.g. sun50i-a64-ccu) use platform drivers. This means that the consumer clocks will be orphaned until the supplier driver is bound. This can be avoided by converting the remaining CCUs to use platform drivers. Then fw_devlink will ensure the drivers are bound in the optimal order. The sun5i CCU is the only one which actually needs to be an early clock provider, because it provides the clock for the system timer. That one is left alone. Signed-off-by: Samuel Holland <[email protected]> Signed-off-by: Maxime Ripard <[email protected]> Link: https://lore.kernel.org/r/[email protected]
1 parent c8c525b commit 7ec03b5

File tree

11 files changed

+333
-173
lines changed

11 files changed

+333
-173
lines changed

drivers/clk/sunxi-ng/Kconfig

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ config SUNXI_CCU
88
if SUNXI_CCU
99

1010
config SUNIV_F1C100S_CCU
11-
bool "Support for the Allwinner newer F1C100s CCU"
11+
tristate "Support for the Allwinner newer F1C100s CCU"
1212
default MACH_SUNIV
1313
depends on MACH_SUNIV || COMPILE_TEST
1414

@@ -33,17 +33,17 @@ config SUN50I_H6_CCU
3333
depends on (ARM64 && ARCH_SUNXI) || COMPILE_TEST
3434

3535
config SUN50I_H616_CCU
36-
bool "Support for the Allwinner H616 CCU"
36+
tristate "Support for the Allwinner H616 CCU"
3737
default ARM64 && ARCH_SUNXI
3838
depends on (ARM64 && ARCH_SUNXI) || COMPILE_TEST
3939

4040
config SUN50I_H6_R_CCU
41-
bool "Support for the Allwinner H6 and H616 PRCM CCU"
41+
tristate "Support for the Allwinner H6 and H616 PRCM CCU"
4242
default ARM64 && ARCH_SUNXI
4343
depends on (ARM64 && ARCH_SUNXI) || COMPILE_TEST
4444

4545
config SUN4I_A10_CCU
46-
bool "Support for the Allwinner A10/A20 CCU"
46+
tristate "Support for the Allwinner A10/A20 CCU"
4747
default MACH_SUN4I
4848
default MACH_SUN7I
4949
depends on MACH_SUN4I || MACH_SUN7I || COMPILE_TEST
@@ -54,17 +54,17 @@ config SUN5I_CCU
5454
depends on MACH_SUN5I || COMPILE_TEST
5555

5656
config SUN6I_A31_CCU
57-
bool "Support for the Allwinner A31/A31s CCU"
57+
tristate "Support for the Allwinner A31/A31s CCU"
5858
default MACH_SUN6I
5959
depends on MACH_SUN6I || COMPILE_TEST
6060

6161
config SUN8I_A23_CCU
62-
bool "Support for the Allwinner A23 CCU"
62+
tristate "Support for the Allwinner A23 CCU"
6363
default MACH_SUN8I
6464
depends on MACH_SUN8I || COMPILE_TEST
6565

6666
config SUN8I_A33_CCU
67-
bool "Support for the Allwinner A33 CCU"
67+
tristate "Support for the Allwinner A33 CCU"
6868
default MACH_SUN8I
6969
depends on MACH_SUN8I || COMPILE_TEST
7070

@@ -74,12 +74,12 @@ config SUN8I_A83T_CCU
7474
depends on MACH_SUN8I || COMPILE_TEST
7575

7676
config SUN8I_H3_CCU
77-
bool "Support for the Allwinner H3 CCU"
77+
tristate "Support for the Allwinner H3 CCU"
7878
default MACH_SUN8I || (ARM64 && ARCH_SUNXI)
7979
depends on MACH_SUN8I || (ARM64 && ARCH_SUNXI) || COMPILE_TEST
8080

8181
config SUN8I_V3S_CCU
82-
bool "Support for the Allwinner V3s CCU"
82+
tristate "Support for the Allwinner V3s CCU"
8383
default MACH_SUN8I
8484
depends on MACH_SUN8I || COMPILE_TEST
8585

@@ -98,7 +98,7 @@ config SUN9I_A80_CCU
9898
depends on MACH_SUN9I || COMPILE_TEST
9999

100100
config SUN8I_R_CCU
101-
bool "Support for Allwinner SoCs' PRCM CCUs"
101+
tristate "Support for Allwinner SoCs' PRCM CCUs"
102102
default MACH_SUN8I || (ARCH_SUNXI && ARM64)
103103

104104
endif

drivers/clk/sunxi-ng/ccu-sun4i-a10.c

Lines changed: 36 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,9 @@
77

88
#include <linux/clk-provider.h>
99
#include <linux/io.h>
10-
#include <linux/of_address.h>
10+
#include <linux/module.h>
11+
#include <linux/of_device.h>
12+
#include <linux/platform_device.h>
1113

1214
#include "ccu_common.h"
1315
#include "ccu_reset.h"
@@ -1425,18 +1427,19 @@ static const struct sunxi_ccu_desc sun7i_a20_ccu_desc = {
14251427
.num_resets = ARRAY_SIZE(sunxi_a10_a20_ccu_resets),
14261428
};
14271429

1428-
static void __init sun4i_ccu_init(struct device_node *node,
1429-
const struct sunxi_ccu_desc *desc)
1430+
static int sun4i_a10_ccu_probe(struct platform_device *pdev)
14301431
{
1432+
const struct sunxi_ccu_desc *desc;
14311433
void __iomem *reg;
14321434
u32 val;
14331435

1434-
reg = of_io_request_and_map(node, 0, of_node_full_name(node));
1435-
if (IS_ERR(reg)) {
1436-
pr_err("%s: Could not map the clock registers\n",
1437-
of_node_full_name(node));
1438-
return;
1439-
}
1436+
desc = of_device_get_match_data(&pdev->dev);
1437+
if (!desc)
1438+
return -EINVAL;
1439+
1440+
reg = devm_platform_ioremap_resource(pdev, 0);
1441+
if (IS_ERR(reg))
1442+
return PTR_ERR(reg);
14401443

14411444
val = readl(reg + SUN4I_PLL_AUDIO_REG);
14421445

@@ -1464,19 +1467,30 @@ static void __init sun4i_ccu_init(struct device_node *node,
14641467
val &= ~GENMASK(7, 6);
14651468
writel(val | (2 << 6), reg + SUN4I_AHB_REG);
14661469

1467-
of_sunxi_ccu_probe(node, reg, desc);
1470+
return devm_sunxi_ccu_probe(&pdev->dev, reg, desc);
14681471
}
14691472

1470-
static void __init sun4i_a10_ccu_setup(struct device_node *node)
1471-
{
1472-
sun4i_ccu_init(node, &sun4i_a10_ccu_desc);
1473-
}
1474-
CLK_OF_DECLARE(sun4i_a10_ccu, "allwinner,sun4i-a10-ccu",
1475-
sun4i_a10_ccu_setup);
1473+
static const struct of_device_id sun4i_a10_ccu_ids[] = {
1474+
{
1475+
.compatible = "allwinner,sun4i-a10-ccu",
1476+
.data = &sun4i_a10_ccu_desc,
1477+
},
1478+
{
1479+
.compatible = "allwinner,sun7i-a20-ccu",
1480+
.data = &sun7i_a20_ccu_desc,
1481+
},
1482+
{ }
1483+
};
14761484

1477-
static void __init sun7i_a20_ccu_setup(struct device_node *node)
1478-
{
1479-
sun4i_ccu_init(node, &sun7i_a20_ccu_desc);
1480-
}
1481-
CLK_OF_DECLARE(sun7i_a20_ccu, "allwinner,sun7i-a20-ccu",
1482-
sun7i_a20_ccu_setup);
1485+
static struct platform_driver sun4i_a10_ccu_driver = {
1486+
.probe = sun4i_a10_ccu_probe,
1487+
.driver = {
1488+
.name = "sun4i-a10-ccu",
1489+
.suppress_bind_attrs = true,
1490+
.of_match_table = sun4i_a10_ccu_ids,
1491+
},
1492+
};
1493+
module_platform_driver(sun4i_a10_ccu_driver);
1494+
1495+
MODULE_IMPORT_NS(SUNXI_CCU);
1496+
MODULE_LICENSE("GPL");

drivers/clk/sunxi-ng/ccu-sun50i-h6-r.c

Lines changed: 35 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,8 @@
44
*/
55

66
#include <linux/clk-provider.h>
7-
#include <linux/of_address.h>
7+
#include <linux/module.h>
8+
#include <linux/of_device.h>
89
#include <linux/platform_device.h>
910

1011
#include "ccu_common.h"
@@ -221,30 +222,43 @@ static const struct sunxi_ccu_desc sun50i_h616_r_ccu_desc = {
221222
.num_resets = ARRAY_SIZE(sun50i_h616_r_ccu_resets),
222223
};
223224

224-
static void __init sunxi_r_ccu_init(struct device_node *node,
225-
const struct sunxi_ccu_desc *desc)
225+
static int sun50i_h6_r_ccu_probe(struct platform_device *pdev)
226226
{
227+
const struct sunxi_ccu_desc *desc;
227228
void __iomem *reg;
228229

229-
reg = of_io_request_and_map(node, 0, of_node_full_name(node));
230-
if (IS_ERR(reg)) {
231-
pr_err("%pOF: Could not map the clock registers\n", node);
232-
return;
233-
}
230+
desc = of_device_get_match_data(&pdev->dev);
231+
if (!desc)
232+
return -EINVAL;
234233

235-
of_sunxi_ccu_probe(node, reg, desc);
236-
}
234+
reg = devm_platform_ioremap_resource(pdev, 0);
235+
if (IS_ERR(reg))
236+
return PTR_ERR(reg);
237237

238-
static void __init sun50i_h6_r_ccu_setup(struct device_node *node)
239-
{
240-
sunxi_r_ccu_init(node, &sun50i_h6_r_ccu_desc);
238+
return devm_sunxi_ccu_probe(&pdev->dev, reg, desc);
241239
}
242-
CLK_OF_DECLARE(sun50i_h6_r_ccu, "allwinner,sun50i-h6-r-ccu",
243-
sun50i_h6_r_ccu_setup);
244240

245-
static void __init sun50i_h616_r_ccu_setup(struct device_node *node)
246-
{
247-
sunxi_r_ccu_init(node, &sun50i_h616_r_ccu_desc);
248-
}
249-
CLK_OF_DECLARE(sun50i_h616_r_ccu, "allwinner,sun50i-h616-r-ccu",
250-
sun50i_h616_r_ccu_setup);
241+
static const struct of_device_id sun50i_h6_r_ccu_ids[] = {
242+
{
243+
.compatible = "allwinner,sun50i-h6-r-ccu",
244+
.data = &sun50i_h6_r_ccu_desc,
245+
},
246+
{
247+
.compatible = "allwinner,sun50i-h616-r-ccu",
248+
.data = &sun50i_h616_r_ccu_desc,
249+
},
250+
{ }
251+
};
252+
253+
static struct platform_driver sun50i_h6_r_ccu_driver = {
254+
.probe = sun50i_h6_r_ccu_probe,
255+
.driver = {
256+
.name = "sun50i-h6-r-ccu",
257+
.suppress_bind_attrs = true,
258+
.of_match_table = sun50i_h6_r_ccu_ids,
259+
},
260+
};
261+
module_platform_driver(sun50i_h6_r_ccu_driver);
262+
263+
MODULE_IMPORT_NS(SUNXI_CCU);
264+
MODULE_LICENSE("GPL");

drivers/clk/sunxi-ng/ccu-sun50i-h616.c

Lines changed: 23 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77

88
#include <linux/clk-provider.h>
99
#include <linux/io.h>
10-
#include <linux/of_address.h>
10+
#include <linux/module.h>
1111
#include <linux/platform_device.h>
1212

1313
#include "ccu_common.h"
@@ -1082,17 +1082,15 @@ static const u32 usb2_clk_regs[] = {
10821082
SUN50I_H616_USB3_CLK_REG,
10831083
};
10841084

1085-
static void __init sun50i_h616_ccu_setup(struct device_node *node)
1085+
static int sun50i_h616_ccu_probe(struct platform_device *pdev)
10861086
{
10871087
void __iomem *reg;
10881088
u32 val;
10891089
int i;
10901090

1091-
reg = of_io_request_and_map(node, 0, of_node_full_name(node));
1092-
if (IS_ERR(reg)) {
1093-
pr_err("%pOF: Could not map clock registers\n", node);
1094-
return;
1095-
}
1091+
reg = devm_platform_ioremap_resource(pdev, 0);
1092+
if (IS_ERR(reg))
1093+
return PTR_ERR(reg);
10961094

10971095
/* Enable the lock bits and the output enable bits on all PLLs */
10981096
for (i = 0; i < ARRAY_SIZE(pll_regs); i++) {
@@ -1141,8 +1139,23 @@ static void __init sun50i_h616_ccu_setup(struct device_node *node)
11411139
val |= BIT(24);
11421140
writel(val, reg + SUN50I_H616_HDMI_CEC_CLK_REG);
11431141

1144-
of_sunxi_ccu_probe(node, reg, &sun50i_h616_ccu_desc);
1142+
return devm_sunxi_ccu_probe(&pdev->dev, reg, &sun50i_h616_ccu_desc);
11451143
}
11461144

1147-
CLK_OF_DECLARE(sun50i_h616_ccu, "allwinner,sun50i-h616-ccu",
1148-
sun50i_h616_ccu_setup);
1145+
static const struct of_device_id sun50i_h616_ccu_ids[] = {
1146+
{ .compatible = "allwinner,sun50i-h616-ccu" },
1147+
{ }
1148+
};
1149+
1150+
static struct platform_driver sun50i_h616_ccu_driver = {
1151+
.probe = sun50i_h616_ccu_probe,
1152+
.driver = {
1153+
.name = "sun50i-h616-ccu",
1154+
.suppress_bind_attrs = true,
1155+
.of_match_table = sun50i_h616_ccu_ids,
1156+
},
1157+
};
1158+
module_platform_driver(sun50i_h616_ccu_driver);
1159+
1160+
MODULE_IMPORT_NS(SUNXI_CCU);
1161+
MODULE_LICENSE("GPL");

drivers/clk/sunxi-ng/ccu-sun6i-a31.c

Lines changed: 30 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,8 @@
99

1010
#include <linux/clk-provider.h>
1111
#include <linux/io.h>
12-
#include <linux/of_address.h>
12+
#include <linux/module.h>
13+
#include <linux/platform_device.h>
1314

1415
#include "ccu_common.h"
1516
#include "ccu_reset.h"
@@ -1226,16 +1227,15 @@ static struct ccu_mux_nb sun6i_a31_cpu_nb = {
12261227
.bypass_index = 1, /* index of 24 MHz oscillator */
12271228
};
12281229

1229-
static void __init sun6i_a31_ccu_setup(struct device_node *node)
1230+
static int sun6i_a31_ccu_probe(struct platform_device *pdev)
12301231
{
12311232
void __iomem *reg;
1233+
int ret;
12321234
u32 val;
12331235

1234-
reg = of_io_request_and_map(node, 0, of_node_full_name(node));
1235-
if (IS_ERR(reg)) {
1236-
pr_err("%pOF: Could not map the clock registers\n", node);
1237-
return;
1238-
}
1236+
reg = devm_platform_ioremap_resource(pdev, 0);
1237+
if (IS_ERR(reg))
1238+
return PTR_ERR(reg);
12391239

12401240
/* Force the PLL-Audio-1x divider to 1 */
12411241
val = readl(reg + SUN6I_A31_PLL_AUDIO_REG);
@@ -1257,10 +1257,30 @@ static void __init sun6i_a31_ccu_setup(struct device_node *node)
12571257
val |= 0x3 << 12;
12581258
writel(val, reg + SUN6I_A31_AHB1_REG);
12591259

1260-
of_sunxi_ccu_probe(node, reg, &sun6i_a31_ccu_desc);
1260+
ret = devm_sunxi_ccu_probe(&pdev->dev, reg, &sun6i_a31_ccu_desc);
1261+
if (ret)
1262+
return ret;
12611263

12621264
ccu_mux_notifier_register(pll_cpu_clk.common.hw.clk,
12631265
&sun6i_a31_cpu_nb);
1266+
1267+
return 0;
12641268
}
1265-
CLK_OF_DECLARE(sun6i_a31_ccu, "allwinner,sun6i-a31-ccu",
1266-
sun6i_a31_ccu_setup);
1269+
1270+
static const struct of_device_id sun6i_a31_ccu_ids[] = {
1271+
{ .compatible = "allwinner,sun6i-a31-ccu" },
1272+
{ }
1273+
};
1274+
1275+
static struct platform_driver sun6i_a31_ccu_driver = {
1276+
.probe = sun6i_a31_ccu_probe,
1277+
.driver = {
1278+
.name = "sun6i-a31-ccu",
1279+
.suppress_bind_attrs = true,
1280+
.of_match_table = sun6i_a31_ccu_ids,
1281+
},
1282+
};
1283+
module_platform_driver(sun6i_a31_ccu_driver);
1284+
1285+
MODULE_IMPORT_NS(SUNXI_CCU);
1286+
MODULE_LICENSE("GPL");

0 commit comments

Comments
 (0)