Skip to content

Commit

Permalink
clk: mvebu: cp110: introduce a new binding
Browse files Browse the repository at this point in the history
The initial intent when the binding of the cp110 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.

Reviewed-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
Acked-by: Rob Herring <robh@kernel.org>
Signed-off-by: Gregory CLEMENT <gregory.clement@free-electrons.com>
  • Loading branch information
gclement committed Jun 19, 2017
1 parent f566727 commit 5ffeb5f
Showing 1 changed file with 48 additions and 15 deletions.
63 changes: 48 additions & 15 deletions drivers/clk/mvebu/cp110-system-controller.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand All @@ -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;
Expand All @@ -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);

Expand All @@ -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)) {
Expand All @@ -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);
Expand All @@ -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);
Expand All @@ -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);
Expand All @@ -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);
Expand All @@ -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;
Expand Down Expand Up @@ -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);

0 comments on commit 5ffeb5f

Please sign in to comment.