Skip to content

[26.04_linux-nvidia] i2c: mediatek: add ACPI/MT8901 support and gpiolib zero-debounce fix - #507

Closed
kmaddaraki wants to merge 2 commits into
NVIDIA:26.04_linux-nvidiafrom
kmaddaraki:i2c-device-clean-stack
Closed

[26.04_linux-nvidia] i2c: mediatek: add ACPI/MT8901 support and gpiolib zero-debounce fix#507
kmaddaraki wants to merge 2 commits into
NVIDIA:26.04_linux-nvidiafrom
kmaddaraki:i2c-device-clean-stack

Conversation

@kmaddaraki

@kmaddaraki kmaddaraki commented Jul 27, 2026

Copy link
Copy Markdown

Two small SAUCE patches to bring up the MediaTek MT8901 I²C host controller under ACPI on 26.04 linux-nvidia.

gpiolib: acpi: route acpi_dev_gpio_irq_wake_get_by() debounce through the warn-only wrapper

Mainline commit e4a77f9 ("gpiolib: acpi: Make set debounce errors non fatal") added the warn-only acpi_gpio_set_debounce_timeout() wrapper and converted two of the three ACPI call sites that program a debounce timeout. The third, in acpi_dev_gpio_irq_wake_get_by(), still returns the raw error: on firmware whose _CRS declares a GpioInt with a DebounceTimeout on an edge-triggered pin, the MediaTek EINT driver rejects set_config(PIN_CONFIG_INPUT_DEBOUNCE) with -EINVAL, the error propagates through acpi_dev_gpio_irq_get(), and i2c_hid_acpi fails probe with HID over i2c has not been provided an Int IRQ — the internal keyboard never enumerates. Convert the remaining call site to the same wrapper so all three ACPI debounce paths behave consistently: the rejection is logged and the IRQ is still delivered. Core gpiolib.c semantics are untouched.

i2c: mediatek: add ACPI/MT8901 support and firmware-managed clocks
Adds ACPI binding to the DT-only i2c-mt65xx driver so the MT8901 I²C controllers enumerate under NVDA0200:

  • New mt8901_compat (v3 register layout, default_parent_rate=124.8 MHz) and an acpi_match_table entry NVDA0200 → mt8901_compat.
  • Switch probe to device_get_match_data() and fwnode-aware device_property_read_*() so DT and ACPI share the same code path.
  • device_set_node(&adap->dev, dev_fwnode(&pdev->dev)) so i2c_acpi_register_devices() walks the child HID nodes and instantiates them.
  • Gate devm_clk_get() for main/dma on has_acpi_companion() — use devm_clk_get_optional() for the ACPI path (firmware keeps those clocks running and does not expose them via the Linux clk framework), and fall back to dev_comp->default_parent_rate in mtk_i2c_set_speed() when no clock handle is available.

DT behaviour is unchanged: both device_get_match_data() and device_property_read_*() fall through to the existing OF helpers for DT-described nodes, and the DT clock path is preserved.

LP: https://bugs.launchpad.net/ubuntu/+source/linux-nvidia-7.0/+bug/2163407

@nirmoy nirmoy added the help wanted Extra attention is needed label Jul 27, 2026
@nirmoy

nirmoy commented Jul 27, 2026

Copy link
Copy Markdown
Collaborator

BaseOS Kernel Review

Summary

No issues found across the reviewed commits.

Findings: no problems found

Latest watcher review: open review

Generated test plan: open test plan

Kernel deb build: successful (download debs, 4 files)

Head: f2581685e05e

This comment is maintained by nv-pr-bot. It is updated when the GitHub watcher publishes a newer review.

@jamieNguyenNVIDIA

Copy link
Copy Markdown
Collaborator

Are these patches that you intend to send to the mailing list? If so, I'd suggest doing that first and then referencing the mailing list URL in this PR:

(backported from <lore URL>)

Secondly, I suggest targeting this PR at the following branches instead of 24.04_linux-nvidia-7.0-next:

  • 26.04_linux-nvidia-bos
  • 26.04_linux-nvidia

Canonical helps ensure that the 24.04 kernel source is kept in sync with the 26.04 versions, so no need to target PRs at the 24.04+7.0 branches.

@nvidia-bfigg
nvidia-bfigg force-pushed the 24.04_linux-nvidia-7.0-next branch from dfa0ae4 to a625012 Compare July 27, 2026 15:25
@kmaddaraki
kmaddaraki changed the base branch from 24.04_linux-nvidia-7.0-next to 26.04_linux-nvidia July 28, 2026 04:11
@github-actions

github-actions Bot commented Jul 28, 2026

Copy link
Copy Markdown
Contributor

PR Validation Report

Patchscan ✅ No Missing Fixes

All cherry-picked commits checked — no missing upstream fixes found.

PR Lint ✅ All checks passed

Details
Checking 2 commits...

Cherry-pick digest:
┌──────────────┬──────────────────────────────────────────────────────────────────┬────────────┬─────────┬───────────────────────────┐
│ Local        │ Referenced upstream / Patch subject                              │ Patch-ID   │ Subject │ SoB chain                 │
├──────────────┼──────────────────────────────────────────────────────────────────┼────────────┼─────────┼───────────────────────────┤
│ f2581685e05e │ [SAUCE] gpiolib: acpi: route acpi_dev_gpio_irq_wake_get_by() deb │ N/A        │ N/A     │ kmaddara                  │
├──────────────┼──────────────────────────────────────────────────────────────────┼────────────┼─────────┼───────────────────────────┤
│ 90c40ebc4ae0 │ [SAUCE] i2c: mediatek: add acpi/mt8901 support and firmware-mana │ N/A        │ N/A     │ zhang, kmaddara           │
└──────────────┴──────────────────────────────────────────────────────────────────┴────────────┴─────────┴───────────────────────────┘

Lint: all checks passed.

@kmaddaraki
kmaddaraki force-pushed the i2c-device-clean-stack branch from 6cb82e7 to 22d6646 Compare August 3, 2026 05:26

@nirmoy nirmoy left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Codex found these two issues.

Comment thread drivers/gpio/gpiolib.c Outdated
* touching the hardware.
*/
if (!debounce)
return 0;

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Medium: This changes the core API from “zero disables debounce” to “zero is ignored.” If firmware or an earlier request enabled debounce, returning here leaves hardware filtering and desc->debounce_period_us stale, and skips the line-state notification. Please scope the ACPI workaround to the affected call path or make the MediaTek EINT implementation handle zero by disabling debounce.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in v2 by taking your first option — the workaround is now scoped to the affected ACPI call path. The gpiolib.c change is dropped entirely; instead the remaining hard-failing call site in acpi_dev_gpio_irq_wake_get_by() is converted to the warn-only acpi_gpio_set_debounce_timeout() wrapper that e4a77f9 already applied to the other two ACPI call sites. Core semantics ("zero disables debounce") are untouched for all non-ACPI callers.

Comment thread drivers/i2c/busses/i2c-mt65xx.c Outdated
&i2c->clk_src_div);
if (ret < 0)
return ret;
i2c->clk_src_div = 1; /* ACPI doesn't supply this */

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Low: This fallback also applies to DT and to malformed properties. clock-div is required by i2c-mt65xx.yaml, and the previous DT path returned the read error; silently using 1 changes DT behavior and may calculate the wrong SCL timing. Please default only for an absent ACPI property and preserve the DT/malformed-property error.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in v2 — the fallback is now gated on has_acpi_companion():

if (ret < 0) {
if (has_acpi_companion(i2c->dev))
i2c->clk_src_div = 1;
else
return ret;
}

DT retains the previous behavior of returning the property-read error, so a malformed or missing clock-div still fails the probe as i2c-mt65xx.yaml requires.

@clsotog

clsotog commented Aug 3, 2026

Copy link
Copy Markdown
Collaborator

Got the same findings as Nirmoy.

@jamieNguyenNVIDIA

Copy link
Copy Markdown
Collaborator

@kmaddaraki: Are these going to get sent upstream?

@kmaddaraki

Copy link
Copy Markdown
Author

@kmaddaraki: Are these going to get sent upstream?

Mediatek has plan to upstream these changes and it will happen around Oct 2026

@jamieNguyenNVIDIA

Copy link
Copy Markdown
Collaborator

Review: PR 507 — additional notes

The two findings already posted stand (core debounce semantics on
gpiolib.c, the clock-div fallback on i2c-mt65xx.c). The following is
not covered by them.

A four-line fix already exists for the gpiolib problem

e4a77f9c85a5 ("gpiolib: acpi: Make set debounce errors non fatal") is
already in this branch. It added a warn-only wrapper and converted two of
the three gpio_set_debounce_timeout() call sites:

/* drivers/gpio/gpiolib-acpi-core.c */
static void acpi_gpio_set_debounce_timeout(struct gpio_desc *desc,
                                           unsigned int acpi_debounce)
{
        ...
        ret = gpio_set_debounce_timeout(desc, acpi_debounce);
        if (ret)
                gpiod_warn(desc, "Failed to set debounce-timeout %u: %d\n",
                           acpi_debounce, ret);
}

Two consequences.

The commit message is out of date. It says the error "propagated
through gpiod_get_index() and acpi_dev_gpio_irq_get()". The
gpiod_get_index() path — gpiod_find_and_request()
gpiod_fwnode_lookup()gpiod_find_by_fwnode()acpi_find_gpio()
only warns now.

One call site still fails, acpi_dev_gpio_irq_wake_get_by():

ret = gpio_set_debounce_timeout(desc, info.debounce * 10);
if (ret)
        return ret;

Converting that single call to acpi_gpio_set_debounce_timeout() is the
"scope it to the affected call path" fix suggested above, needs no core
change, and finishes what e4a77f9c85a5 started. That commit also records
the upstream position on this failure mode:

But gpio_set_debounce_timeout() failing is a somewhat normal
occurrence, since not all debounce values are supported on all
GPIO/pinctrl chips.

The zero-only guard is incomplete

mtk_eint_set_debounce() rejects the request without inspecting the
requested value at all:

static unsigned int mtk_eint_can_en_debounce(struct mtk_eint *eint,
                                             unsigned int eint_num)
{
        ...
        if (eint->pins[eint_num].debounce && sens != MTK_EINT_EDGE_SENSITIVE)
                return 1;
        else
                return 0;
}

An MT8901 _CRS declaring any non-zero DebounceTimeout on an
edge-triggered EINT would still return -EINVAL and still fail
acpi_dev_gpio_irq_get(). Fixing the call site covers that case; the zero
guard does not.

Nits

  • default_parent_rate = 124800000 has no stated source. With
    clk_src_div falling back to 1, it is the sole input to the ACPI timing
    calculation — a comment naming the source would make it reviewable.
  • i2c->adap.dev.of_node = pdev->dev.of_node; in mtk_i2c_probe() is
    dead; device_set_node() sets of_node from the fwnode a few lines
    later.
  • checkpatch: CHECK: Alignment should match open parenthesis on the
    mtk_i2c_set_speed() call. A local holding the parent rate would read
    better than the nested conditional.

Two corrections to the earlier review

  • desc->debounce_period_us is not left stale by this patch.
    gpio_set_debounce_timeout() never wrote that field on any path; it is
    written only by gpiolib-cdev.c.
  • The skipped gpiod_line_state_notify() is arguably correct now, since no
    configuration changed. Previously it fired even when the call was a
    no-op.

Both changed objects build clean on arm64 defconfig with CONFIG_ACPI=y
and =n.

@kmaddaraki
kmaddaraki force-pushed the i2c-device-clean-stack branch from 22d6646 to c439da8 Compare August 11, 2026 17:23
@kmaddaraki

Copy link
Copy Markdown
Author

@jamieNguyenNVIDIA sorry for the delay. Testing took more time than anticipated.

v2 implements exactly this — thanks for the pointer to e4a77f9. The gpiolib commit is now a conversion of the third call site to the existing wrapper (net 4 lines in gpiolib-acpi-core.c, gpiolib.c untouched), and it also covers the nonzero-debounce failure case the previous zero-only guard missed.
The i2c-mt65xx nits are all folded in: dead adap.dev.of_node assignment removed, comment added for default_parent_rate = 124800000, and the mtk_i2c_set_speed() alignment fixed via a parent_rate local.

@jamieNguyenNVIDIA

Copy link
Copy Markdown
Collaborator

@jamieNguyenNVIDIA sorry for the delay. Testing took more time than anticipated.

v2 implements exactly this — thanks for the pointer to e4a77f9. The gpiolib commit is now a conversion of the third call site to the existing wrapper (net 4 lines in gpiolib-acpi-core.c, gpiolib.c untouched), and it also covers the nonzero-debounce failure case the previous zero-only guard missed. The i2c-mt65xx nits are all folded in: dead adap.dev.of_node assignment removed, comment added for default_parent_rate = 124800000, and the mtk_i2c_set_speed() alignment fixed via a parent_rate local.

@kmaddaraki: No worries! Does c439da8 need to carry the following fixes tag?

Fixes: 8dcb7a15a585 ("gpiolib: acpi: Take into account debounce settings")

Other than that:

Acked-by: Jamie Nguyen <jamien@nvidia.com>

@nvmochs

nvmochs commented Aug 11, 2026

Copy link
Copy Markdown
Collaborator

+1 on the fixes tag.

I confirmed the issues reported here and in PR 518 have been resolved.

Acked-by: Matthew R. Ochs <mochs@nvidia.com>

@nirmoy nirmoy added has_2_acks and removed help wanted Extra attention is needed labels Aug 11, 2026
@clsotog

clsotog commented Aug 11, 2026

Copy link
Copy Markdown
Collaborator

no further issues from me.
Acked-by: Carol L Soto <csoto@nvidia.com>

@kmaddaraki
kmaddaraki force-pushed the i2c-device-clean-stack branch from c439da8 to 731b531 Compare August 12, 2026 05:36
@kmaddaraki

Copy link
Copy Markdown
Author

@jamieNguyenNVIDIA Yes, agreed — added Fixes: 8dcb7a1 ("gpiolib: acpi: Take into account debounce settings")

@jamieNguyenNVIDIA

Copy link
Copy Markdown
Collaborator

Hi @kmaddaraki, looks like this one needs a rebase.

housongzhang-maker and others added 2 commits August 13, 2026 15:47
…naged clocks

On MT8901-based platforms the I2C controllers are described through
ACPI (HID NVDA0200) rather than device tree. The upstream i2c-mt65xx
driver is DT-only: no acpi_match_table, no propagation of the ACPI
fwnode to the i2c_adapter device, and clock/timing properties read
through of_property_read_*() helpers that don't operate on ACPI nodes.
Compounding that, on these platforms firmware keeps the controller's
"main" and "dma" clocks running and does not expose them via the
Linux clk framework, so devm_clk_get() returns -ENOENT for both.

Consequently the driver does not bind on ACPI systems: no i2c_adapter
is created, HID-over-I2C never enumerates child devices, and the
internal I2C keyboard stays silent.

Wire up ACPI and accept firmware-managed clocks:

* Add mt8901_compat (v3 register layout, default_parent_rate=124.8 MHz
  as a stand-in for clk_get_rate() when no clock provider is exposed)
  and an acpi_match_table entry NVDA0200 -> mt8901_compat.

* Replace of_device_get_match_data() with device_get_match_data() in
  probe (with a NULL-match check), and switch mtk_i2c_parse_dt() to
  the fwnode-aware device_property_read_*() helpers so DT and ACPI
  share the same probe path.

* Call device_set_node(&adap->dev, dev_fwnode(&pdev->dev)) so the
  ACPI fwnode reaches the i2c_adapter device; without it,
  has_acpi_companion() on the adapter returns 0 and
  i2c_acpi_register_devices() exits early, leaving HID children
  unenumerated.

* Gate devm_clk_get() for "main"/"dma" on has_acpi_companion() - use
  devm_clk_get_optional() in the ACPI branch so absent clocks are
  accepted, and substitute i2c->dev_comp->default_parent_rate when
  mtk_i2c_set_speed() has no clock handle to query.

Signed-off-by: Housong Zhang <housong.zhang@mediatek.com>
Signed-off-by: Kiran Maddaraki <kmaddaraki@nvidia.com>
…ebounce through the warn-only wrapper

Mainline commit e4a77f9 ("gpiolib: acpi: Make set debounce errors
non fatal") introduced acpi_gpio_set_debounce_timeout() and converted
two of the three ACPI call sites that program a debounce timeout to
use it. The wrapper downgrades a set_config(PIN_CONFIG_INPUT_DEBOUNCE)
failure to a dev_warn() so that GPIO controllers which reject that
config (e.g. the MediaTek EINT block used behind pinctrl-paris, which
returns -EINVAL for any debounce request on an edge-triggered pin)
do not fail the whole GpioInt lookup.

The third call site in acpi_dev_gpio_irq_wake_get_by() was not
converted by that commit and still returns the raw -EINVAL from
gpio_set_debounce_timeout(). On ACPI systems whose _CRS declares a
GpioInt with any DebounceTimeout on an edge-triggered pinctrl backend,
that error propagates through acpi_dev_gpio_irq_get() and its
callers, and the affected consumer (e.g. i2c_hid_acpi) fails to
bind - no HID children enumerate.

Route this call site through the same warn-only wrapper so all three
ACPI debounce paths behave consistently.

Fixes: 8dcb7a1 ("gpiolib: acpi: Take into account debounce settings")
Signed-off-by: Kiran Maddaraki <kmaddaraki@nvidia.com>
@kmaddaraki
kmaddaraki force-pushed the i2c-device-clean-stack branch from 731b531 to f258168 Compare August 13, 2026 10:20
@jamieNguyenNVIDIA

Copy link
Copy Markdown
Collaborator

Acked-by: Jamie Nguyen <jamien@nvidia.com>

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants