From: zychen <zychennvt@gmail.com>
To: Krzysztof Kozlowski <krzk@kernel.org>
Cc: andi.shyti@kernel.org, ychuang3@nuvoton.com, robh@kernel.org,
krzk+dt@kernel.org, conor+dt@kernel.org,
linux-i2c@vger.kernel.org, devicetree@vger.kernel.org,
linux-arm-kernel@lists.infradead.org
Subject: Re: [PATCH 2/3] i2c: ma35d1: Add Nuvoton MA35D1 I2C driver support
Date: Mon, 2 Mar 2026 17:39:54 +0800 [thread overview]
Message-ID: <eb013eda-7e3c-492a-9d69-915f1564f522@gmail.com> (raw)
In-Reply-To: <20260302-spiffy-capuchin-of-completion-e8c5b2@quoll>
Hi Krzysztof,
Thank you for the review.
Krzysztof Kozlowski 於 2026/3/2 下午 03:24 寫道:
> On Mon, Mar 02, 2026 at 02:08:21AM +0000, Zi-Yu Chen wrote:
>> Add I2C support for Nuvoton MA35D1 SoC.
>> The controller supports standard, fast and fast-plus modes,
>> and provides master/slave functionality.
>>
>> Signed-off-by: Zi-Yu Chen <zychennvt@gmail.com>
>> ---
>> drivers/i2c/busses/Kconfig | 13 +
>> drivers/i2c/busses/Makefile | 1 +
>> drivers/i2c/busses/i2c-ma35d1.c | 819 ++++++++++++++++++++++++++++++++
>> 3 files changed, 833 insertions(+)
>> create mode 100644 drivers/i2c/busses/i2c-ma35d1.c
>>
>> diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig
>> index e11d50750e63..6bf8be1d2575 100644
>> --- a/drivers/i2c/busses/Kconfig
>> +++ b/drivers/i2c/busses/Kconfig
>> @@ -1589,4 +1589,17 @@ config I2C_VIRTIO
>> This driver can also be built as a module. If so, the module
>> will be called i2c-virtio.
>>
>> +config I2C_MA35D1
>> + tristate "Nuvoton MA35D1 I2C driver"
>> + depends on ARCH_MA35
>
>
> Missing COMPILE_TEST
Will add || COMPILE_TEST to the dependency in v2.
>
> ...
>
>> + /* Setup info block for the I2C core */
>> + strscpy(i2c->adap.name, "ma35d1-i2c", sizeof(i2c->adap.name));
>> + i2c->adap.owner = THIS_MODULE;
>> + i2c->adap.algo = &ma35d1_i2c_algorithm;
>> + i2c->adap.retries = 2;
>> + i2c->adap.algo_data = i2c;
>> + i2c->adap.dev.parent = &pdev->dev;
>> + i2c->adap.dev.of_node = pdev->dev.of_node;
>> + i2c_set_adapdata(&i2c->adap, i2c);
>> +
>> + ret = of_property_read_u32(pdev->dev.of_node, "clock-frequency",
>> + &busfreq);
>> + if (ret) {
>> + dev_err(i2c->dev, "clock-frequency not specified in DT\n");
>> + return ret;
>> + }
>> +
>> + /* Calculate divider based on the current peripheral clock rate */
>> + clkdiv = DIV_ROUND_CLOSEST(clk_get_rate(i2c->clk), busfreq * 4) - 1;
>> + if (clkdiv < 0 || clkdiv > 0xffff) {
>> + dev_err(dev, "invalid clkdiv value: %d\n", clkdiv);
>> + return -EINVAL;
>> + }
>> +
>> + i2c->irq = platform_get_irq(pdev, 0);
>> + if (i2c->irq < 0)
>> + return i2c->irq;
>> +
>> + platform_set_drvdata(pdev, i2c);
>> +
>> + pm_runtime_set_autosuspend_delay(dev, I2C_PM_TIMEOUT);
>> + pm_runtime_use_autosuspend(dev);
>> + pm_runtime_set_active(dev);
>> + pm_runtime_enable(dev);
>> +
>> + ret = pm_runtime_get_sync(dev);
>> + if (ret < 0)
>> + goto rpm_disable;
>> +
>> + writel(clkdiv & 0xffff, i2c->regs + MA35_CLKDIV);
>> +
>> + ret = devm_request_irq(dev, i2c->irq, ma35d1_i2c_irq, IRQF_SHARED,
>> + dev_name(dev), i2c);
>> +
>
> No blank line ever between call and if()
Acknowledged. Will fix in v2.
>
>> + if (ret != 0) {
>
> Write simple and obvious code.
>
> if (ret)
>
Acknowledged. I will simplify the error check to if (ret) in v2.
>> + dev_err(dev, "cannot claim IRQ %d\n", i2c->irq);
>> + goto rpm_disable;
>> + }
>> +
>> + /* Give it another chance if pinctrl used is not ready yet */
>> + if (ret == -EPROBE_DEFER)
>
> Pointless and dead code.
Acknowledged. I will remove the redundant -EPROBE_DEFER check and its associated comment in v2
>
>> + goto rpm_disable;
>> +
>> + ret = i2c_add_adapter(&i2c->adap);
>> + if (ret) {
>> + dev_err(dev, "failed to add bus to i2c core: %d\n", ret);
>> + goto rpm_disable;
>> + }
>> +
>> + pm_runtime_put_autosuspend(dev);
>> +
>> + return 0;
>> +
>> +rpm_disable:
>> + pm_runtime_put_noidle(dev);
>> + pm_runtime_disable(dev);
>> + pm_runtime_set_suspended(dev);
>> + pm_runtime_dont_use_autosuspend(dev);
>> + return ret;
>> +}
>> +
>> +static void ma35d1_i2c_remove(struct platform_device *pdev)
>> +{
>> + struct ma35d1_i2c *i2c = platform_get_drvdata(pdev);
>> +
>> + i2c_del_adapter(&i2c->adap);
>> + pm_runtime_disable(&pdev->dev);
>> +}
>> +
>> +static int ma35d1_i2c_suspend(struct device *dev)
>> +{
>> + struct ma35d1_i2c *i2c = dev_get_drvdata(dev);
>> + unsigned int val;
>> +
>> + spin_lock_irq(&i2c->lock);
>> +
>> + /* Prepare for wake-up from I2C events if slave mode is active */
>> + if (i2c->slave) {
>> + val = readl(i2c->regs + MA35_CTL0);
>> + val |= (MA35_CTL_SI | MA35_CTL_AA);
>> + writel(val, i2c->regs + MA35_CTL0);
>> + ma35d1_i2c_enable_irq(i2c);
>> + }
>> +
>> + spin_unlock_irq(&i2c->lock);
>> +
>> + /* Setup wake-up control */
>> + writel(0x1, i2c->regs + MA35_WKCTL);
>> +
>> + /* Clear pending wake-up flags */
>> + val = readl(i2c->regs + MA35_WKSTS);
>> + writel(val, i2c->regs + MA35_WKSTS);
>> +
>> + enable_irq_wake(i2c->irq);
>> +
>> + return 0;
>> +}
>> +
>> +static int ma35d1_i2c_resume(struct device *dev)
>> +{
>> + struct ma35d1_i2c *i2c = dev_get_drvdata(dev);
>> + unsigned int val;
>> +
>> + /* Disable wake-up */
>> + writel(0x0, i2c->regs + MA35_WKCTL);
>> +
>> + /* Clear pending wake-up flags */
>> + val = readl(i2c->regs + MA35_WKSTS);
>> + writel(val, i2c->regs + MA35_WKSTS);
>> +
>> + disable_irq_wake(i2c->irq);
>> + return 0;
>> +}
>> +
>> +static int ma35d1_i2c_runtime_suspend(struct device *dev)
>> +{
>> + struct ma35d1_i2c *i2c = dev_get_drvdata(dev);
>> + unsigned int val;
>> +
>> + /* Disable I2C controller */
>> + val = readl(i2c->regs + MA35_CTL0);
>> + val &= ~MA35_CTL_I2CEN;
>> + writel(val, i2c->regs + MA35_CTL0);
>> +
>> + clk_disable_unprepare(i2c->clk);
>> +
>> + return 0;
>> +}
>> +
>> +static int ma35d1_i2c_runtime_resume(struct device *dev)
>> +{
>> + struct ma35d1_i2c *i2c = dev_get_drvdata(dev);
>> + unsigned int val;
>> + int ret;
>> +
>> + ret = clk_prepare_enable(i2c->clk);
>> + if (ret) {
>> + dev_err(dev, "failed to enable clock in resume\n");
>> + return ret;
>> + }
>> +
>> + /* Enable I2C controller */
>> + val = readl(i2c->regs + MA35_CTL0);
>> + val |= MA35_CTL_I2CEN;
>> + writel(val, i2c->regs + MA35_CTL0);
>> +
>> + return 0;
>> +}
>> +
>> +static const struct dev_pm_ops ma35d1_i2c_pmops = {
>> + SYSTEM_SLEEP_PM_OPS(ma35d1_i2c_suspend, ma35d1_i2c_resume)
>> + RUNTIME_PM_OPS(ma35d1_i2c_runtime_suspend,
>> + ma35d1_i2c_runtime_resume, NULL)
>> +};
>> +
>> +static const struct of_device_id ma35d1_i2c_of_match[] = {
>> + { .compatible = "nuvoton,ma35d1-i2c" },
>> + {},
>> +};
>> +MODULE_DEVICE_TABLE(of, ma35d1_i2c_of_match);
>> +
>> +static struct platform_driver ma35d1_i2c_driver = {
>> + .probe = ma35d1_i2c_probe,
>> + .remove = ma35d1_i2c_remove,
>> + .driver = {
>> + .name = "ma35d1-i2c",
>> + .owner = THIS_MODULE,
>
> Do not upstream 12-year-old code. We fixed all these issues long time.
> Please write your driver from scratch, so you will not
> repeat/reintroduce all the issues which we already fixed.
>
I will address these issues in V2 by:
Removing the redundant .owner = THIS_MODULE.
Reviewing the entire driver to ensure all APIs and patterns align with current upstream standards.
I am performing a "from-scratch" review to eliminate legacy patterns.
>> + .of_match_table = ma35d1_i2c_of_match,
>> + .pm = pm_ptr(&ma35d1_i2c_pmops),
>> + },
>
> Best regards,
> Krzysztof
>
next prev parent reply other threads:[~2026-03-02 9:40 UTC|newest]
Thread overview: 10+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-03-02 2:08 [PATCH 0/3] Add support for MA35D1 I2C controller Zi-Yu Chen
2026-03-02 2:08 ` [PATCH 1/3] dt-bindings: i2c: nuvoton,ma35d1-i2c: Add " Zi-Yu Chen
2026-03-02 7:20 ` Krzysztof Kozlowski
2026-03-03 0:57 ` zychen
2026-03-02 2:08 ` [PATCH 2/3] i2c: ma35d1: Add Nuvoton MA35D1 I2C driver support Zi-Yu Chen
2026-03-02 7:24 ` Krzysztof Kozlowski
2026-03-02 9:39 ` zychen [this message]
2026-03-02 2:08 ` [PATCH 3/3] arm64: dts: nuvoton: Add I2C nodes for MA35D1 SoC Zi-Yu Chen
2026-03-02 7:25 ` Krzysztof Kozlowski
2026-03-02 8:06 ` zychen
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=eb013eda-7e3c-492a-9d69-915f1564f522@gmail.com \
--to=zychennvt@gmail.com \
--cc=andi.shyti@kernel.org \
--cc=conor+dt@kernel.org \
--cc=devicetree@vger.kernel.org \
--cc=krzk+dt@kernel.org \
--cc=krzk@kernel.org \
--cc=linux-arm-kernel@lists.infradead.org \
--cc=linux-i2c@vger.kernel.org \
--cc=robh@kernel.org \
--cc=ychuang3@nuvoton.com \
/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