Commit f5667274 authored by Gregory CLEMENT's avatar Gregory CLEMENT

clk: mvebu: cp110: do not depend anymore of the *-clock-output-names

Using the *-clock-output-names property was a convenient way to have a
unique name for each clock even when there are multiple cp110 blocks
as we can find on Armada 8K.

However it has some drawbacks: the main one being a stronger link than
necessary between the driver and the device tree. For example the clock
name can't be changed, removed or moved. It is still the early stage of
introduction of the Armada 7K/8K and the hardware is still not totally
documented, especially for the clock part. By removing the use of
*-clock-output-names it will be easier to add new clocks without breaking
the compatibility.

The name of each clock is now created by using its physical address as a
prefix (as it was done for the platform device names). Thanks to this we
have an automatic way to compute a unique name.
Acked-by: default avatarRob Herring <robh@kernel.org>
Signed-off-by: default avatarGregory CLEMENT <gregory.clement@free-electrons.com>
parent 29e6beb5
...@@ -84,6 +84,33 @@ enum { ...@@ -84,6 +84,33 @@ enum {
#define CP110_GATE_EIP150 25 #define CP110_GATE_EIP150 25
#define CP110_GATE_EIP197 26 #define CP110_GATE_EIP197 26
const char *gate_base_names[] = {
[CP110_GATE_AUDIO] = "audio",
[CP110_GATE_COMM_UNIT] = "communit",
[CP110_GATE_NAND] = "nand",
[CP110_GATE_PPV2] = "ppv2",
[CP110_GATE_SDIO] = "sdio",
[CP110_GATE_MG] = "mg-domain",
[CP110_GATE_MG_CORE] = "mg-core",
[CP110_GATE_XOR1] = "xor1",
[CP110_GATE_XOR0] = "xor0",
[CP110_GATE_GOP_DP] = "gop-dp",
[CP110_GATE_PCIE_X1_0] = "pcie_x10",
[CP110_GATE_PCIE_X1_1] = "pcie_x11",
[CP110_GATE_PCIE_X4] = "pcie_x4",
[CP110_GATE_PCIE_XOR] = "pcie-xor",
[CP110_GATE_SATA] = "sata",
[CP110_GATE_SATA_USB] = "sata-usb",
[CP110_GATE_MAIN] = "main",
[CP110_GATE_SDMMC_GOP] = "sd-mmc-gop",
[CP110_GATE_SLOW_IO] = "slow-io",
[CP110_GATE_USB3H0] = "usb3h0",
[CP110_GATE_USB3H1] = "usb3h1",
[CP110_GATE_USB3DEV] = "usb3dev",
[CP110_GATE_EIP150] = "eip150",
[CP110_GATE_EIP197] = "eip197"
};
struct cp110_gate_clk { struct cp110_gate_clk {
struct clk_hw hw; struct clk_hw hw;
struct regmap *regmap; struct regmap *regmap;
...@@ -186,15 +213,33 @@ static struct clk_hw *cp110_of_clk_get(struct of_phandle_args *clkspec, ...@@ -186,15 +213,33 @@ static struct clk_hw *cp110_of_clk_get(struct of_phandle_args *clkspec,
return ERR_PTR(-EINVAL); return ERR_PTR(-EINVAL);
} }
static char *cp110_unique_name(struct device *dev, const char *name)
{
struct device_node *np = dev->of_node;
const __be32 *reg;
u64 addr;
/* Do not create a name if there is no clock */
if (!name)
return NULL;
reg = of_get_property(np, "reg", NULL);
addr = of_translate_address(np, reg);
return devm_kasprintf(dev, GFP_KERNEL, "%llx-%s",
(unsigned long long)addr, name);
}
static int cp110_syscon_clk_probe(struct platform_device *pdev) static int cp110_syscon_clk_probe(struct platform_device *pdev)
{ {
struct regmap *regmap; struct regmap *regmap;
struct device_node *np = pdev->dev.of_node; struct device *dev = &pdev->dev;
struct device_node *np = dev->of_node;
const char *ppv2_name, *apll_name, *core_name, *eip_name, *nand_name; const char *ppv2_name, *apll_name, *core_name, *eip_name, *nand_name;
struct clk_hw_onecell_data *cp110_clk_data; struct clk_hw_onecell_data *cp110_clk_data;
struct clk_hw *hw, **cp110_clks; struct clk_hw *hw, **cp110_clks;
u32 nand_clk_ctrl; u32 nand_clk_ctrl;
int i, ret; int i, ret;
char *gate_name[ARRAY_SIZE(gate_base_names)];
regmap = syscon_node_to_regmap(np); regmap = syscon_node_to_regmap(np);
if (IS_ERR(regmap)) if (IS_ERR(regmap))
...@@ -205,7 +250,7 @@ static int cp110_syscon_clk_probe(struct platform_device *pdev) ...@@ -205,7 +250,7 @@ static int cp110_syscon_clk_probe(struct platform_device *pdev)
if (ret) if (ret)
return ret; return ret;
cp110_clk_data = devm_kzalloc(&pdev->dev, sizeof(*cp110_clk_data) + cp110_clk_data = devm_kzalloc(dev, sizeof(*cp110_clk_data) +
sizeof(struct clk_hw *) * CP110_CLK_NUM, sizeof(struct clk_hw *) * CP110_CLK_NUM,
GFP_KERNEL); GFP_KERNEL);
if (!cp110_clk_data) if (!cp110_clk_data)
...@@ -215,8 +260,7 @@ static int cp110_syscon_clk_probe(struct platform_device *pdev) ...@@ -215,8 +260,7 @@ static int cp110_syscon_clk_probe(struct platform_device *pdev)
cp110_clk_data->num = CP110_CLK_NUM; cp110_clk_data->num = CP110_CLK_NUM;
/* Register the APLL which is the root of the hw tree */ /* Register the APLL which is the root of the hw tree */
of_property_read_string_index(np, "core-clock-output-names", apll_name = cp110_unique_name(dev, "apll");
CP110_CORE_APLL, &apll_name);
hw = clk_hw_register_fixed_rate(NULL, apll_name, NULL, 0, hw = clk_hw_register_fixed_rate(NULL, apll_name, NULL, 0,
1000 * 1000 * 1000); 1000 * 1000 * 1000);
if (IS_ERR(hw)) { if (IS_ERR(hw)) {
...@@ -227,8 +271,7 @@ static int cp110_syscon_clk_probe(struct platform_device *pdev) ...@@ -227,8 +271,7 @@ static int cp110_syscon_clk_probe(struct platform_device *pdev)
cp110_clks[CP110_CORE_APLL] = hw; cp110_clks[CP110_CORE_APLL] = hw;
/* PPv2 is APLL/3 */ /* PPv2 is APLL/3 */
of_property_read_string_index(np, "core-clock-output-names", ppv2_name = cp110_unique_name(dev, "ppv2-core");
CP110_CORE_PPV2, &ppv2_name);
hw = clk_hw_register_fixed_factor(NULL, ppv2_name, apll_name, 0, 1, 3); hw = clk_hw_register_fixed_factor(NULL, ppv2_name, apll_name, 0, 1, 3);
if (IS_ERR(hw)) { if (IS_ERR(hw)) {
ret = PTR_ERR(hw); ret = PTR_ERR(hw);
...@@ -238,8 +281,7 @@ static int cp110_syscon_clk_probe(struct platform_device *pdev) ...@@ -238,8 +281,7 @@ static int cp110_syscon_clk_probe(struct platform_device *pdev)
cp110_clks[CP110_CORE_PPV2] = hw; cp110_clks[CP110_CORE_PPV2] = hw;
/* EIP clock is APLL/2 */ /* EIP clock is APLL/2 */
of_property_read_string_index(np, "core-clock-output-names", eip_name = cp110_unique_name(dev, "eip");
CP110_CORE_EIP, &eip_name);
hw = clk_hw_register_fixed_factor(NULL, eip_name, apll_name, 0, 1, 2); hw = clk_hw_register_fixed_factor(NULL, eip_name, apll_name, 0, 1, 2);
if (IS_ERR(hw)) { if (IS_ERR(hw)) {
ret = PTR_ERR(hw); ret = PTR_ERR(hw);
...@@ -249,8 +291,7 @@ static int cp110_syscon_clk_probe(struct platform_device *pdev) ...@@ -249,8 +291,7 @@ static int cp110_syscon_clk_probe(struct platform_device *pdev)
cp110_clks[CP110_CORE_EIP] = hw; cp110_clks[CP110_CORE_EIP] = hw;
/* Core clock is EIP/2 */ /* Core clock is EIP/2 */
of_property_read_string_index(np, "core-clock-output-names", core_name = cp110_unique_name(dev, "core");
CP110_CORE_CORE, &core_name);
hw = clk_hw_register_fixed_factor(NULL, core_name, eip_name, 0, 1, 2); hw = clk_hw_register_fixed_factor(NULL, core_name, eip_name, 0, 1, 2);
if (IS_ERR(hw)) { if (IS_ERR(hw)) {
ret = PTR_ERR(hw); ret = PTR_ERR(hw);
...@@ -258,10 +299,8 @@ static int cp110_syscon_clk_probe(struct platform_device *pdev) ...@@ -258,10 +299,8 @@ static int cp110_syscon_clk_probe(struct platform_device *pdev)
} }
cp110_clks[CP110_CORE_CORE] = hw; cp110_clks[CP110_CORE_CORE] = hw;
/* NAND can be either APLL/2.5 or core clock */ /* NAND can be either APLL/2.5 or core clock */
of_property_read_string_index(np, "core-clock-output-names", nand_name = cp110_unique_name(dev, "nand-core");
CP110_CORE_NAND, &nand_name);
if (nand_clk_ctrl & NF_CLOCK_SEL_400_MASK) if (nand_clk_ctrl & NF_CLOCK_SEL_400_MASK)
hw = clk_hw_register_fixed_factor(NULL, nand_name, hw = clk_hw_register_fixed_factor(NULL, nand_name,
apll_name, 0, 2, 5); apll_name, 0, 2, 5);
...@@ -275,18 +314,14 @@ static int cp110_syscon_clk_probe(struct platform_device *pdev) ...@@ -275,18 +314,14 @@ static int cp110_syscon_clk_probe(struct platform_device *pdev)
cp110_clks[CP110_CORE_NAND] = hw; cp110_clks[CP110_CORE_NAND] = hw;
for (i = 0; i < CP110_MAX_GATABLE_CLOCKS; i++) { /* create the unique name for all the gate clocks */
const char *parent, *name; for (i = 0; i < ARRAY_SIZE(gate_base_names); i++)
int ret; gate_name[i] = cp110_unique_name(dev, gate_base_names[i]);
ret = of_property_read_string_index(np, for (i = 0; i < ARRAY_SIZE(gate_base_names); i++) {
"gate-clock-output-names", const char *parent;
i, &name);
/* Reached the end of the list? */
if (ret < 0)
break;
if (!strcmp(name, "none")) if (gate_name[i] == NULL)
continue; continue;
switch (i) { switch (i) {
...@@ -295,14 +330,10 @@ static int cp110_syscon_clk_probe(struct platform_device *pdev) ...@@ -295,14 +330,10 @@ static int cp110_syscon_clk_probe(struct platform_device *pdev)
case CP110_GATE_EIP150: case CP110_GATE_EIP150:
case CP110_GATE_EIP197: case CP110_GATE_EIP197:
case CP110_GATE_SLOW_IO: case CP110_GATE_SLOW_IO:
of_property_read_string_index(np, parent = gate_name[CP110_GATE_MAIN];
"gate-clock-output-names",
CP110_GATE_MAIN, &parent);
break; break;
case CP110_GATE_MG: case CP110_GATE_MG:
of_property_read_string_index(np, parent = gate_name[CP110_GATE_MG_CORE];
"gate-clock-output-names",
CP110_GATE_MG_CORE, &parent);
break; break;
case CP110_GATE_NAND: case CP110_GATE_NAND:
parent = nand_name; parent = nand_name;
...@@ -312,33 +343,27 @@ static int cp110_syscon_clk_probe(struct platform_device *pdev) ...@@ -312,33 +343,27 @@ static int cp110_syscon_clk_probe(struct platform_device *pdev)
break; break;
case CP110_GATE_SDIO: case CP110_GATE_SDIO:
case CP110_GATE_GOP_DP: case CP110_GATE_GOP_DP:
of_property_read_string_index(np, parent = gate_name[CP110_GATE_SDMMC_GOP];
"gate-clock-output-names",
CP110_GATE_SDMMC_GOP, &parent);
break; break;
case CP110_GATE_XOR1: case CP110_GATE_XOR1:
case CP110_GATE_XOR0: case CP110_GATE_XOR0:
case CP110_GATE_PCIE_X1_0: case CP110_GATE_PCIE_X1_0:
case CP110_GATE_PCIE_X1_1: case CP110_GATE_PCIE_X1_1:
case CP110_GATE_PCIE_X4: case CP110_GATE_PCIE_X4:
of_property_read_string_index(np, parent = gate_name[CP110_GATE_PCIE_XOR];
"gate-clock-output-names",
CP110_GATE_PCIE_XOR, &parent);
break; break;
case CP110_GATE_SATA: case CP110_GATE_SATA:
case CP110_GATE_USB3H0: case CP110_GATE_USB3H0:
case CP110_GATE_USB3H1: case CP110_GATE_USB3H1:
case CP110_GATE_USB3DEV: case CP110_GATE_USB3DEV:
of_property_read_string_index(np, parent = gate_name[CP110_GATE_SATA_USB];
"gate-clock-output-names",
CP110_GATE_SATA_USB, &parent);
break; break;
default: default:
parent = core_name; parent = core_name;
break; break;
} }
hw = cp110_register_gate(gate_name[i], parent, regmap, i);
hw = cp110_register_gate(name, parent, regmap, i);
if (IS_ERR(hw)) { if (IS_ERR(hw)) {
ret = PTR_ERR(hw); ret = PTR_ERR(hw);
goto fail_gate; goto fail_gate;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment