Re: [PATCH v2 2/2] clk: keystone: Add new driver to handle syscon based clocks

From: Vignesh Raghavendra
Date: Sat Feb 15 2020 - 07:43:14 EST




On 2/11/2020 12:29 AM, Stephen Boyd wrote:
> Quoting Vignesh Raghavendra (2020-02-06 20:44:25)
>> diff --git a/drivers/clk/keystone/Kconfig b/drivers/clk/keystone/Kconfig
>> index 38aeefb1e808..69ca3db1a99e 100644
>> --- a/drivers/clk/keystone/Kconfig
>> +++ b/drivers/clk/keystone/Kconfig
>> @@ -26,3 +26,11 @@ config TI_SCI_CLK_PROBE_FROM_FW
>> This is mostly only useful for debugging purposes, and will
>> increase the boot time of the device. If you want the clocks probed
>> from firmware, say Y. Otherwise, say N.
>> +
>> +config TI_SYSCON_CLK
>> + tristate "Syscon based clock driver for K2/K3 SoCs"
>> + depends on (ARCH_KEYSTONE || ARCH_K3 || COMPILE_TEST) && OF
>> + default (ARCH_KEYSTONE || ARCH_K3)
>
> Drop parenthesis. It's not useful. Also, not sure why OF is a build
> dependency. Please drop it.
>

Yes, will drop..

> depends on ARCH_KEYSTONE || ARCH_K3 || COMPILE_TEST
> default ARCH_KEYSTONE || ARCH_K3
>
>> + help
>> + This adds clock driver support for syscon based gate
>> + clocks on TI's K2 and K3 SoCs.
>> diff --git a/drivers/clk/keystone/Makefile b/drivers/clk/keystone/Makefile
>> index d044de6f965c..0e426e648f7c 100644
>> --- a/drivers/clk/keystone/Makefile
>> +++ b/drivers/clk/keystone/Makefile
>> @@ -1,3 +1,4 @@
>> # SPDX-License-Identifier: GPL-2.0-only
>> obj-$(CONFIG_COMMON_CLK_KEYSTONE) += pll.o gate.o
>> obj-$(CONFIG_TI_SCI_CLK) += sci-clk.o
>> +obj-$(CONFIG_TI_SYSCON_CLK) += syscon-clk.o
>> diff --git a/drivers/clk/keystone/syscon-clk.c b/drivers/clk/keystone/syscon-clk.c
>> new file mode 100644
>> index 000000000000..42e7416371ff
>> --- /dev/null
>> +++ b/drivers/clk/keystone/syscon-clk.c
>> @@ -0,0 +1,177 @@
>> +// SPDX-License-Identifier: GPL-2.0
>> +//
>> +// Copyright (C) 2020 Texas Instruments Incorporated - http://www.ti.com/
>> +//
>
> These last three comment lines should be normal kernel style. /* */
>
>> +
>> +#include <linux/clk-provider.h>
>> +#include <linux/clk.h>
>
> Is this used?
>

Will drop

>> +#include <linux/mfd/syscon.h>
>> +#include <linux/module.h>
>> +#include <linux/of.h>
>> +#include <linux/of_device.h>
>
> Hopefully these two includes aren't needed.
>

Not anymore

>> +#include <linux/platform_device.h>
>> +#include <linux/regmap.h>
>> +
> [...]
>> +
>> +static int ti_syscon_gate_clk_probe(struct platform_device *pdev)
>> +{
>> + const struct ti_syscon_gate_clk_data *data, *p;
>> + struct clk_hw_onecell_data *hw_data;
>> + struct device *dev = &pdev->dev;
>> + struct regmap *regmap;
>> + int num_clks = 0;
>
> Please don't initialize here.

Ok

>
>> + int i;
>> +
>> + data = of_device_get_match_data(dev);
>
> Use device_get_match_data() instead?

Sure

>
>> + if (!data)
>> + return -EINVAL;
>> +
>> + regmap = syscon_regmap_lookup_by_phandle(dev->of_node,
>> + "ti,tbclk-syscon");
>> + if (IS_ERR(regmap)) {
>> + if (PTR_ERR(regmap) == -EPROBE_DEFER)
>> + return -EPROBE_DEFER;
>> + dev_err(dev, "failed to find parent regmap\n");
>> + return PTR_ERR(regmap);
>> + }
>> +
>> + for (p = data; p->name; p++)
>
> Initialize num_clks here so we know it's a loop that's counting.

OK

>
>> + num_clks++;
>> +
>> + hw_data = devm_kzalloc(dev, struct_size(hw_data, hws, num_clks),
>> + GFP_KERNEL);
>> + if (!hw_data)
>> + return -ENOMEM;
>> +
>> + hw_data->num = num_clks;
>> +
>> + for (i = 0; i < num_clks; i++) {
>> + hw_data->hws[i] = ti_syscon_gate_clk_register(dev, regmap,
>> + &data[i]);
>> + if (IS_ERR(hw_data->hws[i]))
>> + dev_err(dev, "failed to register %s",
>
> Add a newline?

Yes, will add

>
>> + data[i].name);
>
> And we don't fail? So it really isn't a problem? Maybe dev_warn()
> instead?
>

OK

>> + }
>> +
>> + return devm_of_clk_add_hw_provider(dev, of_clk_hw_onecell_get,
>> + hw_data);
>> +}
>> +
>> +#define TI_SYSCON_CLK_GATE(_name, _offset, _bit_idx) \
>> + { \
>> + .name = _name, \
>> + .offset = (_offset), \
>> + .bit_idx = (_bit_idx), \
>> + }
>> +
>> +static const struct ti_syscon_gate_clk_data am654_clk_data[] = {
>> + TI_SYSCON_CLK_GATE("ehrpwm_tbclk0", 0x0, 0),
>> + TI_SYSCON_CLK_GATE("ehrpwm_tbclk1", 0x4, 0),
>> + TI_SYSCON_CLK_GATE("ehrpwm_tbclk2", 0x8, 0),
>> + TI_SYSCON_CLK_GATE("ehrpwm_tbclk3", 0xc, 0),
>> + TI_SYSCON_CLK_GATE("ehrpwm_tbclk4", 0x10, 0),
>> + TI_SYSCON_CLK_GATE("ehrpwm_tbclk5", 0x14, 0),
>> + { /* Sentinel */ },
>> +};
>> +
>> +static const struct of_device_id ti_syscon_gate_clk_ids[] = {
>> + {
>> + .compatible = "ti,am654-ehrpwm-tbclk",
>> + .data = &am654_clk_data,
>> + },
>> + { }
>> +};
>> +MODULE_DEVICE_TABLE(of, ti_syscon_gate_clk_ids);
>> +
>> +static struct platform_driver ti_syscon_gate_clk_driver = {
>> + .probe = ti_syscon_gate_clk_probe,
>> + .driver = {
>> + .name = "ti-syscon-gate-clk",
>> + .of_match_table = ti_syscon_gate_clk_ids,
>> + },
>> +};
>> +
>
> Nitpick: Drop the newline.
>

Ok

>> +module_platform_driver(ti_syscon_gate_clk_driver);
>> +

Thanks for the review!

Regards
Vignesh