From: Jerome Brunet <jbrunet@baylibre.com>
To: Alex Elder <elder@riscstar.com>, Brian Masney <bmasney@redhat.com>
Cc: sboyd@kernel.org, bmasney+clk@redhat.com,
jbrunet+clk@baylibre.com, robh@kernel.org, krzk+dt@kernel.org,
conor+dt@kernel.org, lee@kernel.org, andersson@kernel.org,
konradybcio@kernel.org, abelvesa@kernel.org, kees@kernel.org,
gustavoars@kernel.org, p.zabel@pengutronix.de,
daniel@riscstar.com, mohd.anwar@oss.qualcomm.com,
lorenzo.bianconi@oss.qualcomm.com, linux-clk@vger.kernel.org,
devicetree@vger.kernel.org, mfd@lists.linux.dev,
linux-arm-msm@vger.kernel.org, linux-hardening@vger.kernel.org,
linux-kernel@vger.kernel.org
Subject: Re: [PATCH 3/4] clk: toshiba: introduce a TC9564 SoC clock and reset driver
Date: Wed, 23 Sep 2026 22:58:21 +0200 [thread overview]
Message-ID: <1jcxu3adn6.fsf@starbuckisacylon.baylibre.com> (raw)
In-Reply-To: <0785235b-de06-44d4-9068-ec706eeba848@riscstar.com>
On mar. 22 sept. 2026 at 08:33, Alex Elder <elder@riscstar.com> wrote:
> On 9/21/26 5:59 PM, Brian Masney wrote:
>> Hi Alex,
>>
>> On Fri, Sep 18, 2026 at 11:52:32AM -0500, Alex Elder wrote:
>>> Define a new platform driver that manages clock and reset signals
>>> within the TC9564 SoC. There are 21 clocks, which can only be
>>> enabled and disabled, as well as 13 reset signals.
>>>
>>> Two registers manage the state of the clocks and two others manage
>>> the state of the resets. The registers are accessed via a regmap
>>> supplied by a system controller, which coordinates access to a
>>> region of memory that will be shared with another driver.
>>>
>>> Access to the memory region is provided via a BAR on a PCIe endpoint
>>> function embedded in the TC9564 SoC. For that reason, neither the
>>> PCIe clock nor PCIe reset can be manipulated by this driver (they
>>> are assumed always on and deasserted, respectively).
>>>
>>> Similarly, control is not available for the I2C clock and reset,
>>> because the PCIe subsystem on the TC9564 relies on I2C
>>>
>>> Co-developed-by: Daniel Thompson <daniel@riscstar.com>
>>> Signed-off-by: Daniel Thompson <daniel@riscstar.com>
>>> Signed-off-by: Alex Elder <elder@riscstar.com>
>>> ---
>>> MAINTAINERS | 1 +
>>> drivers/clk/Kconfig | 11 ++
>>> drivers/clk/Makefile | 1 +
>>> drivers/clk/clk-tc9564.c | 366 +++++++++++++++++++++++++++++++++++++++
>>> 4 files changed, 379 insertions(+)
>>> create mode 100644 drivers/clk/clk-tc9564.c
>>>
>>> diff --git a/MAINTAINERS b/MAINTAINERS
>>> index 66d0e7e65adcb..39346a5cd9a7f 100644
>>> --- a/MAINTAINERS
>>> +++ b/MAINTAINERS
>>> @@ -27675,6 +27675,7 @@ M: Alex Elder <elder@kernel.org>
>>> M: Daniel Thompson <danielt@kernel.org>
>>> S: Maintained
>>> F: Documentation/devicetree/bindings/clock/toshiba,tc9564-clock.yaml
>>> +F: drivers/clk/clk-tc9564.c
>>> F: include/dt-bindings/clock/toshiba,tc9564.h
>>>
>>> TOSHIBA TC9564 PCI DRIVER
>>> diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig
>>> index f9592fd9ec2bb..50efa10d48450 100644
>>> --- a/drivers/clk/Kconfig
>>> +++ b/drivers/clk/Kconfig
>>> @@ -292,6 +292,17 @@ config COMMON_CLK_S2MPS11
>>> clock. These multi-function devices have two (S2MPS14) or three
>>> (S2MPS11, S5M8767) fixed-rate oscillators, clocked at 32KHz each.
>>>
>>> +config COMMON_CLK_TC9564
>>> + tristate "Toshiba TC9564 clock support"
>>> + depends on TC9564_PCI
>>
>> select RESET_CONTROLLER
>
> Thank you. The reset and clock drivers were previously separate
> and the reset only became available if RESET_CONTROLLER was enabled.
> Combining them means I need this. I will add it.
Why did you combine them ?
it would be a lot better if the reset were handled in
drivers/reset rather than in clock. There has already been some work to
move reset from clock back to reset. This often involve auxiliary drivers.
>
> I also need to select MFD_SYSCON to get syscon_node_to_regmap()
> (or perhaps something similar, depending on the answers to my
> questions about the proper way to define the syscon).
>>
>>> + default m
>>
>> default n
>
> This depends on TC9564_PCI, and if TC9564_PCI is enabled I would
> like this to (automatically) be available (at least as a module).
>
> Why do you recommend "n"?
>
>>> + help
>>> + This enables support for the clock and reset controller embedded
>>> + in the Toshiba TC9564 (and Qualcomm QPS615) SoC. The state of
>>> + clock and reset lines is controlled by MMIO to a region managed
>>> + by a system controller; this ensures access to the region is
>>> + coordinated between this and other drivers.
>>
>> Rather than 'other drivers', outline specifically which other drivers.
>
> I was intentionally vague at this point because the one other driver
> has not yet gone out for upstream review for this iteration of the
> code. But I do agree with you, so I'll change this to say:
>
> ... between this and the XGMAC (stmmac) driver.
>
> Then it will be correct without modification once that driver goes
> out for review. Is that better, or do you suggest something else?
>
>>> +
>>> config CLK_TWL
>>> tristate "Clock driver for the TWL PMIC family"
>>> depends on TWL4030_CORE
>>> diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile
>>> index b18af485d7f03..a98ea8ff92066 100644
>>> --- a/drivers/clk/Makefile
>>> +++ b/drivers/clk/Makefile
>>> @@ -110,6 +110,7 @@ obj-$(CONFIG_COMMON_CLK_SI570) += clk-si570.o
>>> obj-$(CONFIG_COMMON_CLK_SP7021) += clk-sp7021.o
>>> obj-$(CONFIG_COMMON_CLK_STM32F) += clk-stm32f4.o
>>> obj-$(CONFIG_COMMON_CLK_STM32H7) += clk-stm32h7.o
>>> +obj-$(CONFIG_COMMON_CLK_TC9564) += clk-tc9564.o
>>> obj-$(CONFIG_COMMON_CLK_TPS68470) += clk-tps68470.o
>>> obj-$(CONFIG_CLK_TWL6040) += clk-twl6040.o
>>> obj-$(CONFIG_CLK_TWL) += clk-twl.o
>>> diff --git a/drivers/clk/clk-tc9564.c b/drivers/clk/clk-tc9564.c
>>> new file mode 100644
>>> index 0000000000000..4f900bc8994a7
>>> --- /dev/null
>>> +++ b/drivers/clk/clk-tc9564.c
>>> @@ -0,0 +1,366 @@
>>> +// SPDX-License-Identifier: GPL-2.0-only
>>> +
>>> +/*
>>> + * Copyright (C) 2026 by RISCstar Solutions Corporation. All rights reserved.
>>> + */
>>> +
>>> +#include <linux/bits.h>
>>> +#include <linux/clk-provider.h>
>>> +#include <linux/mfd/syscon.h>
>>> +#include <linux/mod_devicetable.h>
>>
>> Uwe already pointed out removing this.
>
> Yes, done.
>
>>
>>> +#include <linux/module.h>
>>> +#include <linux/platform_device.h>
>>> +#include <linux/regmap.h>
>>> +#include <linux/reset-controller.h>
>>> +
>>> +#include <dt-bindings/clock/toshiba,tc9564.h>
>>> +
>>> +#define CLK_CTRL0_OFFSET 0x1004
>>> +#define RST_CTRL0_OFFSET 0x1008
>>> +#define CLK_CTRL1_OFFSET 0x100c
>>> +#define RST_CTRL1_OFFSET 0x1010
>>> +
>>> +struct tc9564_clock_init {
>>> + const char *name; /* NULL means unused entry */
>>> + u32 offset;
>>> + u32 mask;
>>> +};
>>> +
>>> +struct tc9564_clock {
>>> + struct clk_hw hw;
>>> + u32 which;
>>> + u32 offset; /* CLK_CTRL0_OFFSET or CLK_CTRL1_OFFSET */
>>> + u32 mask; /* Zero means undefined clock */
>>> +};
>>> +
>>> +struct tc9564_reset {
>>> + u32 offset; /* RST_CTRL0_OFFSET or RST_CTRL1_OFFSET */
>>> + u32 mask; /* Zero means undefined reset */
>>> +};
>>> +
>>> +struct tc9564_clocks {
>>> + struct device *dev;
>>> + struct regmap *regmap;
>>> + struct reset_controller_dev rcdev;
>>> + size_t clock_count;
>>> + struct tc9564_clock clocks[] __counted_by(clock_count);
>>> +};
>>> +
>>> +#define TC9564_CLOCK_INIT0(_name, _bit) __TC9564_CLOCK_INIT(_name, 0, _bit)
>>> +#define TC9564_CLOCK_INIT1(_name, _bit) __TC9564_CLOCK_INIT(_name, 1, _bit)
>>> +
>>> +#define __TC9564_CLOCK_INIT(_name, _reg, _bit) \
>>> + [CLOCK_##_name] = { \
>>> + .name = #_name, \
>>> + .offset = CLK_CTRL ## _reg ## _OFFSET, \
>>> + .mask = BIT(_bit), \
>>> + }
>>> +
>>> +#define TC9564_RESET_INIT0(_name, _bit) __TC9564_RESET_INIT(_name, 0, _bit)
>>> +#define TC9564_RESET_INIT1(_name, _bit) __TC9564_RESET_INIT(_name, 1, _bit)
>>> +
>>> +#define __TC9564_RESET_INIT(_name, _reg, _bit) \
>>> + [RESET_##_name] = { \
>>> + .offset = RST_CTRL ## _reg ## _OFFSET, \
>>> + .mask = BIT(_bit), \
>>> + }
>>> +
>>> +static const struct tc9564_clock_init tc9564_clock_init[] = {
>>> + TC9564_CLOCK_INIT0(MCU, 0),
>>> + TC9564_CLOCK_INIT0(INTC, 4),
>>> + /* TC9564_CLOCK_INIT0(PCIE, 9), */
>>> + /* TC9564_CLOCK_INIT0(I2C, 12), */
>>
>> A comment would be useful here to outline why these are commented out.
>> Is the PCIE one comment out because of what's outlined in the commit
>> message?
>
> Yes, that is why. We are downstream of PCIe, and PCIe in this
> case depends on I2C. So we don't want to mess with these two
> clocks or their reset counterparts.
>
> I only provide this for the benefit of documentation. If someone
> happens to see bit 9 set in this register, it means the PCIe clock
> is enabled.
>
> Anyway, others have suggested simply removing these comments.
> So I'll do what you suggest, but I'm interested to know whether
> you would favor just deleting them instead.
>>
>>> + TC9564_CLOCK_INIT0(SRAM, 13),
>>> + TC9564_CLOCK_INIT0(UART, 16),
>>> + TC9564_CLOCK_INIT0(MSIGEN, 18),
>>> + TC9564_CLOCK_INIT0(PLL, 24),
>>> + TC9564_CLOCK_INIT0(SGMII, 25),
>>> + TC9564_CLOCK_INIT0(REFCLKO, 26),
>
> . . .
>
>>> +static const struct reset_control_ops tc9564_reset_control_ops = {
>>> + .assert = tc9564_reset_assert,
>>> + .deassert = tc9564_reset_deassert,
>>
>> I'd rather not have the extra spaces because sometimes these get out of
>> line with new members that need more space. Also tc9564_clk_ops above
>> doesn't have the extra spaces.
>
> That's OK with me. I normally align assignments like this for
> readability, but it's obviously an arbitrary stylistic choice.
> I'll just use one space, no alignment (just as the clk_ops do
> above). I'll do the same in the platform driver structure
> assignments.
>>
>>> +};
>>> +
>>> +static void tc9564_reset_assert_all(struct tc9564_clocks *clocks)
>>> +{
>>> + for (u32 id = 0; id < TC9564_RESET_COUNT; id++)
>>> + if (tc9564_reset[id].mask)
>>> + tc9564_reset_manage(&clocks->rcdev, id, true);
>>> +}
>>> +
>>> +static int tc9564_reset_init(struct tc9564_clocks *clocks)
>>> +{
>>> + struct reset_controller_dev *rcdev = &clocks->rcdev;
>>> +
>>> + rcdev->ops = &tc9564_reset_control_ops;
>>> + rcdev->owner = THIS_MODULE;
>>> + rcdev->dev = clocks->dev;
>>> + rcdev->of_node = dev_of_node(clocks->dev);
>>> + rcdev->nr_resets = TC9564_RESET_COUNT;
>>> +
>>> + return devm_reset_controller_register(clocks->dev, rcdev);
>>> +}
>>> +
>>> +static int tc9564_clk_probe(struct platform_device *pdev)
>>> +{
>>> + struct device *dev = &pdev->dev;
>>> + struct tc9564_clocks *clocks;
>>> + int ret;
>>> +
>>> + if (!dev_of_node(dev))
>>> + return dev_err_probe(dev, -EINVAL, "no devicetree node\n");
>>> +
>>> + clocks = tc9564_clk_init(dev);
>>> + if (IS_ERR(clocks))
>>> + return dev_err_probe(dev, PTR_ERR(clocks),
>>> + "failed to initialize clocks\n");
>>> +
>>> + ret = tc9564_reset_init(clocks);
>>> + if (ret)
>>> + return dev_err_probe(dev, ret, "failed to initialize resets\n");
>>> +
>>> + /* Force all resets to be initially asserted */
>>> + tc9564_reset_assert_all(clocks);
>>> +
>>> + /* Force all clocks to be initially disabled */
>>> + tc9564_clock_disable_all(clocks);
>>> +
>>> + platform_set_drvdata(pdev, clocks);
>>> +
>>> + return 0;
>>> +}
>>> +
>>> +static void tc9564_clk_remove(struct platform_device *pdev)
>>> +{
>>> + struct tc9564_clocks *clocks = platform_get_drvdata(pdev);
>>> +
>>> + /* Leave all resets to be deasserted when done */
>>> + tc9564_reset_assert_all(clocks);
>>
>> The comment says deasserted but the code calls assert_all.
>
> Oops. Will fix. Thank you very much for your review Brian.
>
> -Alex
>
>>
>> Brian
>>
>>
>>> +
>>> + /* Leave all clocks disabled when done */
>>> + tc9564_clock_disable_all(clocks);
>>> +}
>>> +
>>> +static const struct of_device_id tc9564_clk_ids[] = {
>>> + { .compatible = "toshiba,tc9564-clock" },
>>> + { },
>>> +};
>>> +MODULE_DEVICE_TABLE(of, tc9564_clk_ids);
>>> +
>>> +static struct platform_driver tc9564_clk_driver = {
>>> + .probe = tc9564_clk_probe,
>>> + .remove = tc9564_clk_remove,
>>> + .driver = {
>>> + .name = KBUILD_MODNAME,
>>> + .of_match_table = tc9564_clk_ids,
>>> + .probe_type = PROBE_PREFER_ASYNCHRONOUS,
>>> + },
>>> +};
>>> +module_platform_driver(tc9564_clk_driver);
>>> +
>>> +MODULE_DESCRIPTION("Toshiba TC9564 Clock and Reset Driver");
>>> +MODULE_LICENSE("GPL");
>>> --
>>> 2.53.0
>>>
>>
>
--
Jerome
next prev parent reply other threads:[~2026-09-23 20:58 UTC|newest]
Thread overview: 20+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-09-18 16:52 [PATCH 0/4] clk: introduce TC9564 clock and reset Alex Elder
2026-09-18 16:52 ` [PATCH 1/4] dt-bindings: mfd: introduce the TC9564 config syscon Alex Elder
2026-09-20 18:18 ` Krzysztof Kozlowski
2026-09-21 21:46 ` Alex Elder
2026-09-22 21:02 ` Alex Elder
2026-09-23 7:25 ` Krzysztof Kozlowski
2026-09-18 16:52 ` [PATCH 2/4] dt-bindings: clock: introduce toshiba,tc9564-clock.yaml Alex Elder
2026-09-20 18:21 ` Krzysztof Kozlowski
2026-09-21 21:46 ` Alex Elder
2026-09-22 13:13 ` Alex Elder
2026-09-23 7:18 ` Krzysztof Kozlowski
2026-09-18 16:52 ` [PATCH 3/4] clk: toshiba: introduce a TC9564 SoC clock and reset driver Alex Elder
2026-09-20 19:39 ` Uwe Kleine-König
2026-09-22 12:37 ` Alex Elder
2026-09-22 12:53 ` Uwe Kleine-König
2026-09-21 22:59 ` Brian Masney
2026-09-22 13:33 ` Alex Elder
2026-09-23 20:58 ` Jerome Brunet [this message]
2026-09-23 21:33 ` Alex Elder
2026-09-18 16:52 ` [PATCH 4/4] arm64: dts: qcom: qcs6490-rb3gen2: add the clock controller 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=1jcxu3adn6.fsf@starbuckisacylon.baylibre.com \
--to=jbrunet@baylibre.com \
--cc=abelvesa@kernel.org \
--cc=andersson@kernel.org \
--cc=bmasney+clk@redhat.com \
--cc=bmasney@redhat.com \
--cc=conor+dt@kernel.org \
--cc=daniel@riscstar.com \
--cc=devicetree@vger.kernel.org \
--cc=elder@riscstar.com \
--cc=gustavoars@kernel.org \
--cc=jbrunet+clk@baylibre.com \
--cc=kees@kernel.org \
--cc=konradybcio@kernel.org \
--cc=krzk+dt@kernel.org \
--cc=lee@kernel.org \
--cc=linux-arm-msm@vger.kernel.org \
--cc=linux-clk@vger.kernel.org \
--cc=linux-hardening@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=lorenzo.bianconi@oss.qualcomm.com \
--cc=mfd@lists.linux.dev \
--cc=mohd.anwar@oss.qualcomm.com \
--cc=p.zabel@pengutronix.de \
--cc=robh@kernel.org \
--cc=sboyd@kernel.org \
/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
all inboxes | Powered by JetHome®