From: sashiko-bot@kernel.org
To: "Alex Elder" <elder@riscstar.com>
Cc: devicetree@vger.kernel.org, linux-clk@vger.kernel.org,
robh@kernel.org, conor+dt@kernel.org
Subject: Re: [PATCH 3/4] clk: toshiba: introduce a TC9564 SoC clock driver
Date: Wed, 04 Nov 2026 00:54:33 +0000 [thread overview]
Message-ID: <sashiko-outbox-196325@kernel.org> (raw)
In-Reply-To: <20261104004332.2141282-4-elder@riscstar.com>
Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:
- [High] clk: tc9564: duplicate clock names across chips due to using dev->id
- [High] clk: tc9564: uninitialized clk_data->num in tc9564_clk_probe()
--
commit d0d52063b982041aca91451199195cd79995784b
Author: Alex Elder <elder@riscstar.com>
clk: toshiba: introduce a TC9564 SoC clock driver
This commit adds a platform clock driver for the Toshiba TC9564 SoC,
registering its PLL, fixed-factor, and gate clocks via a syscon regmap.
> diff --git a/drivers/clk/clk-tc9564.c b/drivers/clk/clk-tc9564.c
> new file mode 100644
> index 0000000000000..8eeba85919703
> --- /dev/null
> +++ b/drivers/clk/clk-tc9564.c
> @@ -0,0 +1,288 @@
[ ... ]
> +/*
> + * The full name of every clock has a prefix "tc9564" followed by a single
> + * character ('a', 'b', etc.) that differs for each chip/device number.
> + * Each clock's "name" defines the unique portion of the clock's full name.
> + */
> +#define FULL_NAME_SIZE 24 /* Enough for formatted full name */
> +#define NAME_SIZE 12 /* Unique portion of the clock name */
> +#define FORMAT_FULL_NAME(_full_name, _id, _name) \
> + snprintf(_full_name, FULL_NAME_SIZE, "tc9564%c_%.*s", \
> + 'a' + (_id), NAME_SIZE, _name)
[ ... ]
> +/* Parent is the input oscillator running at 25 MHz; PLL runs at 1250 MHz */
> +static struct clk_hw *pll_register(struct device *dev,
> + const struct clock_init *init)
> +{
> + char full_name[FULL_NAME_SIZE];
> +
> + FORMAT_FULL_NAME(full_name, dev->id, init->name);
> +
> + return devm_clk_hw_register_fixed_factor_index(dev, full_name, 0, 0,
> + init->mult, 1);
> +}
> +
> +/* The PLL is the parent of all fixed clocks */
> +static struct clk_hw *fixed_register(struct device *dev,
> + const struct clock_init *init)
> +{
> + struct tc9564_clock *tc9564_clock = dev_get_drvdata(dev);
> + char full_name[FULL_NAME_SIZE];
> + struct clk_hw *pll_hw;
> +
> + FORMAT_FULL_NAME(full_name, dev->id, init->name);
[ ... ]
> +static struct clk_hw *gate_register(struct device *dev,
> + const struct clock_init *init)
> +{
> + struct tc9564_clock *tc9564_clock = dev_get_drvdata(dev);
> + struct clk_init_data clk_init = { };
> + const struct clk_hw *parent_hw;
> + char full_name[FULL_NAME_SIZE];
> + struct gate_clock *clock;
> + int ret;
> +
> + clock = devm_kzalloc_obj(dev, *clock);
> + if (!clock)
> + return ERR_PTR(-ENOMEM);
> +
> + FORMAT_FULL_NAME(full_name, dev->id, init->name);
[Severity: High]
Will passing dev->id to FORMAT_FULL_NAME() in pll_register(),
fixed_register(), and gate_register() cause clock registration to fail with
-EEXIST when more than one TC9564 device is present?
The clock MFD cell is registered as a platform device in
tc9564_config_syscon_probe():
drivers/soc/toshiba/tc9564-syscon.c:tc9564_config_syscon_probe() {
...
return devm_mfd_add_devices(&pdev->dev, PLATFORM_DEVID_AUTO,
tc9564_config_syscon_cells,
ARRAY_SIZE(tc9564_config_syscon_cells),
NULL, 0, NULL);
}
For platform devices, the platform bus stores the instance ID in pdev->id
(struct platform_device::id), while dev->id (struct device::id) is never set
and remains 0 for every instance. As a result, every TC9564 device formats
its clocks with the "tc9564a_" prefix (such as "tc9564a_PLL"), so probing a
second TC9564 device collides in __clk_core_init() when registering its
clocks in the global clock namespace.
Note that pdev->id cannot be passed directly to 'a' + (_id) either, because
PLATFORM_DEVID_AUTO allocates IDs from the system-wide platform_devid_ida
shared across all auto-numbered platform devices rather than a 0-based
per-chip index.
> +
> + parent_hw = tc9564_clock->clk_data->hws[init->parent];
> +
> + clk_init.name = full_name;
> + clk_init.ops = &gate_clk_ops;
> + clk_init.parent_hws = &parent_hw;
> + clk_init.num_parents = 1;
> +
> + clock->hw.init = &clk_init;
> + clock->init = init;
> +
> + ret = devm_clk_hw_register(dev, &clock->hw);
> + if (ret)
> + return ERR_PTR(ret);
> +
> + return &clock->hw;
> +}
> +
> +static int tc9564_clk_probe(struct platform_device *pdev)
> +{
> + struct clk_hw_onecell_data *clk_data;
> + struct tc9564_clock *tc9564_clock;
> + struct device *dev = &pdev->dev;
> + struct device_node *parent_np;
> + int ret;
> +
> + parent_np = dev_of_node(dev->parent);
> + if (!parent_np)
> + return dev_err_probe(dev, -EINVAL, "no devicetree node\n");
> +
> + tc9564_clock = devm_kzalloc_obj(dev, *tc9564_clock);
> + if (!tc9564_clock)
> + return -ENOMEM;
> +
> + /* Note: MMIO regmap (no error checking needed when used) */
> + tc9564_clock->regmap = device_node_to_regmap(parent_np);
> + if (IS_ERR(tc9564_clock->regmap))
> + return dev_err_probe(dev, PTR_ERR(tc9564_clock->regmap),
> + "failed to get config regmap\n");
> +
> + clk_data = devm_kzalloc_flex(dev, *tc9564_clock->clk_data, hws,
> + CLOCK_COUNT);
> + if (!clk_data)
> + return -ENOMEM;
> + tc9564_clock->clk_data = clk_data;
> +
> + dev_set_drvdata(dev, tc9564_clock);
> +
> + /* Initialize all the clocks */
> + for (u32 i = 0; i < clk_data->num; i++) {
[Severity: High]
Does clk_data->num remain 0 in tc9564_clk_probe() when building with
compilers that do not support __builtin_counted_by_ref?
devm_kzalloc_flex() populates the __counted_by counter via
__set_flex_counter():
include/linux/compiler_types.h:
#if __has_builtin(__builtin_counted_by_ref) && \
!defined(CONFIG_CC_HAS_BROKEN_COUNTED_BY_REF)
#define __flex_counter(FAM) __builtin_counted_by_ref(FAM)
#else
#define __flex_counter(FAM) ((void *)NULL)
#endif
include/linux/overflow.h:
#define __set_flex_counter(FAM, COUNT) \
({ \
*_Generic(__flex_counter(FAM), \
void *: &(size_t){ 0 }, \
default: __flex_counter(FAM)) = (COUNT); \
})
On compilers without a working __builtin_counted_by_ref (such as GCC < 15.1
or Clang < 22.1), __set_flex_counter() writes COUNT into a temporary compound
literal and leaves clk_data->num as 0. Without an explicit
clk_data->num = CLOCK_COUNT assignment, the loop in tc9564_clk_probe()
registers zero clocks and of_clk_hw_onecell_get() rejects all clock lookups
with -EINVAL.
--
Sashiko AI review · https://sashiko.dev/#/patchset/20261104004332.2141282-1-elder@riscstar.com?part=3
next prev parent reply other threads:[~2026-11-04 0:54 UTC|newest]
Thread overview: 11+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-11-04 0:43 [PATCH 0/4] soc: toshiba: tc9564: config system controller Alex Elder
2026-11-04 0:43 ` [PATCH 1/4] dt-bindings: soc: introduce toshiba,tc9564-config-syscon.yaml Alex Elder
2026-11-04 0:43 ` [PATCH 2/4] soc: toshiba: tc9564: add a new syscon driver Alex Elder
2026-11-04 0:50 ` sashiko-bot
2026-11-04 21:22 ` Alex Elder
2026-11-04 0:43 ` [PATCH 3/4] clk: toshiba: introduce a TC9564 SoC clock driver Alex Elder
2026-11-04 0:54 ` sashiko-bot [this message]
2026-11-04 21:22 ` Alex Elder
2026-11-04 0:43 ` [PATCH 4/4] reset: toshiba: introduce a TC9564 SoC reset driver Alex Elder
2026-11-04 9:49 ` Philipp Zabel
2026-11-04 21:22 ` Alex Elder
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=sashiko-outbox-196325@kernel.org \
--to=sashiko-bot@kernel.org \
--cc=conor+dt@kernel.org \
--cc=devicetree@vger.kernel.org \
--cc=elder@riscstar.com \
--cc=linux-clk@vger.kernel.org \
--cc=robh@kernel.org \
--cc=sashiko-reviews@lists.linux.dev \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox