@@ -7,6 +7,13 @@ Controller 0 and System Controller 1. This Device Tree binding allows
to describe the first system controller, which provides registers to
configure various aspects of the SoC.
+For the top level node:
+ - compatible: must be: "syscon", "simple-mfd";
+ - reg: register area of the CP110 system controller 0
+
+Clocks:
+-------
+
The Device Tree node representing this System Controller 0 provides a
number of clocks:
@@ -56,14 +63,17 @@ The following clocks are available:
Required properties:
- compatible: must be:
- "marvell,cp110-system-controller0", "syscon";
- - reg: register area of the CP110 system controller 0
+ "marvell,cp110-clock"
- #clock-cells: must be set to 2
Example:
cpm_syscon0: system-controller@440000 {
- compatible = "marvell,cp110-system-controller0", "syscon";
+ compatible = "syscon", "simple-mfd";
reg = <0x440000 0x1000>;
- #clock-cells = <2>;
+
+ cpm_clk: clock {
+ compatible = "marvell,cp110-clock";
+ #clock-cells = <2>;
+ };
};
@@ -213,9 +213,9 @@ static struct clk_hw *cp110_of_clk_get(struct of_phandle_args *clkspec,
return ERR_PTR(-EINVAL);
}
-static char *cp110_unique_name(struct device *dev, const char *name)
+static char *cp110_unique_name(struct device *dev, struct device_node *np,
+ const char *name)
{
- struct device_node *np = dev->of_node;
const __be32 *reg;
u64 addr;
@@ -229,7 +229,8 @@ static char *cp110_unique_name(struct device *dev, const char *name)
(unsigned long long)addr, name);
}
-static int cp110_syscon_clk_probe(struct platform_device *pdev)
+static int cp110_syscon_common_probe(struct platform_device *pdev,
+ struct device_node *syscon_node)
{
struct regmap *regmap;
struct device *dev = &pdev->dev;
@@ -241,7 +242,7 @@ static int cp110_syscon_clk_probe(struct platform_device *pdev)
int i, ret;
char *gate_name[ARRAY_SIZE(gate_base_names)];
- regmap = syscon_node_to_regmap(np);
+ regmap = syscon_node_to_regmap(syscon_node);
if (IS_ERR(regmap))
return PTR_ERR(regmap);
@@ -260,7 +261,7 @@ static int cp110_syscon_clk_probe(struct platform_device *pdev)
cp110_clk_data->num = CP110_CLK_NUM;
/* Register the APLL which is the root of the hw tree */
- apll_name = cp110_unique_name(dev, "apll");
+ apll_name = cp110_unique_name(dev, syscon_node, "apll");
hw = clk_hw_register_fixed_rate(NULL, apll_name, NULL, 0,
1000 * 1000 * 1000);
if (IS_ERR(hw)) {
@@ -271,7 +272,7 @@ static int cp110_syscon_clk_probe(struct platform_device *pdev)
cp110_clks[CP110_CORE_APLL] = hw;
/* PPv2 is APLL/3 */
- ppv2_name = cp110_unique_name(dev, "ppv2-core");
+ ppv2_name = cp110_unique_name(dev, syscon_node, "ppv2-core");
hw = clk_hw_register_fixed_factor(NULL, ppv2_name, apll_name, 0, 1, 3);
if (IS_ERR(hw)) {
ret = PTR_ERR(hw);
@@ -281,7 +282,7 @@ static int cp110_syscon_clk_probe(struct platform_device *pdev)
cp110_clks[CP110_CORE_PPV2] = hw;
/* EIP clock is APLL/2 */
- eip_name = cp110_unique_name(dev, "eip");
+ eip_name = cp110_unique_name(dev, syscon_node, "eip");
hw = clk_hw_register_fixed_factor(NULL, eip_name, apll_name, 0, 1, 2);
if (IS_ERR(hw)) {
ret = PTR_ERR(hw);
@@ -291,7 +292,7 @@ static int cp110_syscon_clk_probe(struct platform_device *pdev)
cp110_clks[CP110_CORE_EIP] = hw;
/* Core clock is EIP/2 */
- core_name = cp110_unique_name(dev, "core");
+ core_name = cp110_unique_name(dev, syscon_node, "core");
hw = clk_hw_register_fixed_factor(NULL, core_name, eip_name, 0, 1, 2);
if (IS_ERR(hw)) {
ret = PTR_ERR(hw);
@@ -300,7 +301,7 @@ static int cp110_syscon_clk_probe(struct platform_device *pdev)
cp110_clks[CP110_CORE_CORE] = hw;
/* NAND can be either APLL/2.5 or core clock */
- nand_name = cp110_unique_name(dev, "nand-core");
+ nand_name = cp110_unique_name(dev, syscon_node, "nand-core");
if (nand_clk_ctrl & NF_CLOCK_SEL_400_MASK)
hw = clk_hw_register_fixed_factor(NULL, nand_name,
apll_name, 0, 2, 5);
@@ -316,7 +317,8 @@ static int cp110_syscon_clk_probe(struct platform_device *pdev)
/* create the unique name for all the gate clocks */
for (i = 0; i < ARRAY_SIZE(gate_base_names); i++)
- gate_name[i] = cp110_unique_name(dev, gate_base_names[i]);
+ gate_name[i] = cp110_unique_name(dev, syscon_node,
+ gate_base_names[i]);
for (i = 0; i < ARRAY_SIZE(gate_base_names); i++) {
const char *parent;
@@ -402,17 +404,48 @@ static int cp110_syscon_clk_probe(struct platform_device *pdev)
return ret;
}
-static const struct of_device_id cp110_syscon_of_match[] = {
+static int cp110_syscon_legacy_clk_probe(struct platform_device *pdev)
+{
+ dev_warn(&pdev->dev, FW_WARN "Using legacy device tree binding\n");
+ dev_warn(&pdev->dev, FW_WARN "Update your device tree:\n");
+ dev_warn(&pdev->dev, FW_WARN
+ "This binding won't be supported in future kernels\n");
+
+ return cp110_syscon_common_probe(pdev, pdev->dev.of_node);
+}
+
+static int cp110_clk_probe(struct platform_device *pdev)
+{
+ return cp110_syscon_common_probe(pdev, pdev->dev.of_node->parent);
+}
+
+
+static const struct of_device_id cp110_syscon_legacy_of_match[] = {
{ .compatible = "marvell,cp110-system-controller0", },
{ }
};
-static struct platform_driver cp110_syscon_driver = {
- .probe = cp110_syscon_clk_probe,
+static struct platform_driver cp110_syscon_legacy_driver = {
+ .probe = *cp110_syscon_legacy_clk_probe,
.driver = {
.name = "marvell-cp110-system-controller0",
- .of_match_table = cp110_syscon_of_match,
+ .of_match_table = cp110_syscon_legacy_of_match,
+ .suppress_bind_attrs = true,
+ },
+};
+builtin_platform_driver(cp110_syscon_legacy_driver);
+
+static const struct of_device_id cp110_clock_of_match[] = {
+ { .compatible = "marvell,cp110-clock", },
+ { }
+};
+
+static struct platform_driver cp110_clock_driver = {
+ .probe = cp110_clk_probe,
+ .driver = {
+ .name = "marvell-cp110-clock",
+ .of_match_table = cp110_clock_of_match,
.suppress_bind_attrs = true,
},
};
-builtin_platform_driver(cp110_syscon_driver);
+builtin_platform_driver(cp110_clock_driver);