Skip to content

ARM: dts: hi3516cv500/hi3516dv300: give the hibvt i2c controllers their interrupts - #94

Merged
widgetii merged 1 commit into
hisilicon-hi3516cv500from
i2c/hibvt-irq-hisilicon-hi3516cv500
Oct 17, 2026
Merged

widgetii merged 1 commit into
hisilicon-hi3516cv500from
i2c/hibvt-irq-hisilicon-hi3516cv500

Conversation

@widgetii

@widgetii widgetii commented Oct 17, 2026 •

Copy link
Copy Markdown
Member

None of the hibvt I2C nodes in hi3516cv500.dtsi or hi3516dv300.dtsi has an interrupts property (HiSilicon's SDK dtsi doesn't either), so i2c-hibvt always runs in polling mode.

The problem

In polling mode, a transfer that never completes spins udelay(50) up to 0x10000 times, 3.28 s with the CPU held, before wait idle timeout. That cost lands on anything that probes an empty address or an absent bus.

The fix

Wire every controller to its GIC line. The numbers come from the "Mapping between the interrupt bits and interrupt sources" table in the Hi3516AV300 data sheet (en) and the Hi3516DV300 user guide (zh), which agree:

Controller Interrupt bit SPI
I2C0–I2C4 43–47 11–15
I2C5–I2C7 109–111 77–79

hi3516av300_lite builds ARCH_HI3516DV300 and appends hi3516dv300-demb.dtb, so both dtsi files need the change.

Tested on a Hi3516AV300 with an IMX415 on i2c0

I booted the camera's own flash kernel from RAM, with only its appended DTB replaced. The new DTB differs from the stock one by exactly these eight interrupts lines.

  • Interrupts registered: all eight controllers appear in /proc/interrupts, at GIC 43–47 and 109–111.

  • Sensor traffic: the IMX415 initialised over i2c0 in interrupt mode (IMX415 4K2K_10BIT_30FPS init succuss!), and the ISP's register traffic kept raising i2c0's interrupt count (226, then 292).

  • Reads: a combined I2C_RDWR read of the sensor (i2ctransfer -y 0 w2@0x1a 0x30 0x00 r1) returns in 10 ms.

  • Empty bus: a transfer on i2c1 fails in 10 ms with irq handle abort, RIS: 0x800, instead of after the polling timeout.

  • End to end, video0 on: a snapshot came back on the first try (HTTP 200, 444 KB), and RTSP gave 200 frames of 3840x2160 HEVC in 10 s, the configured 20 fps.

  • The only I2C errors were 16 irq handle abort, RIS: 0x1 on i2c0, all right after majestic's own shutdown during the restart. That's the sensor being parked, and polling mode reports the same NACKs as wait idle abort!.

…ir interrupts

None of the i2c nodes has an interrupts property, so i2c-hibvt falls back
to polling, and a transfer to an address that never completes spins in
udelay(50) up to 0x10000 times -- 3.3 s per transfer with the CPU held --
before "wait idle timeout". Wire each controller to its GIC line from the
interrupt table of the Hi3516AV300 and Hi3516DV300 data sheets: I2C0-4 are
interrupt bits 43-47 (SPI 11-15) and I2C5-7 are 109-111 (SPI 77-79).

On a Hi3516AV300 with an IMX415 on i2c0, all eight controllers register
their interrupts; the sensor initialises over i2c0 and the ISP's register
traffic keeps raising its interrupt count; a combined write/read transfer
returns in 10 ms; and a transfer to an empty bus fails in 10 ms with
"irq handle abort" instead of after the polling timeout.
@qodo-free-for-open-source-projects

Copy link
Copy Markdown

PR Summary by Qodo

ARM: Wire Hi3516CV500 and Hi3516DV300 I2C controller interrupts

🐞 Bug fix 🕐 Less than 10 minutes

Grey Divider

AI Description

• Add GIC interrupt mappings to every defined hibvt I2C controller on both SoCs.
• Enable the driver's existing interrupt mode, avoiding lengthy polling timeouts on failed
 transfers.
Diagram

graph TD
  CV["Hi3516CV500 DT"] -->|"SPI mappings"| GIC["GIC lines"] -->|"IRQ delivery"| Driver["hibvt I2C driver"] -->|"interrupt mode"| Transfers["I2C transfers"]
  DV["Hi3516DV300 DT"] -->|"SPI mappings"| GIC
Loading
High-Level Assessment

Adding the missing device-tree interrupt properties is the direct fix: the driver already supports IRQ-driven transfers. Changing its polling behavior would not provide the correct hardware mappings or enable that existing path.

Files changed (2) +15 / -0

Bug fix (2) +15 / -0
hi3516cv500.dtsiMap seven hibvt I2C controllers to GIC interrupts +7/-0

Map seven hibvt I2C controllers to GIC interrupts

• Adds SPI 11–14 for I2C0–I2C3 and SPI 77–79 for I2C5–I2C7. These properties allow the existing driver to register an interrupt for each defined controller.

arch/arm/boot/dts/hi3516cv500.dtsi

hi3516dv300.dtsiMap eight hibvt I2C controllers to GIC interrupts +8/-0

Map eight hibvt I2C controllers to GIC interrupts

• Adds SPI 11–15 for I2C0–I2C4 and SPI 77–79 for I2C5–I2C7. This enables interrupt-driven operation for the controllers defined in this device tree.

arch/arm/boot/dts/hi3516dv300.dtsi

@qodo-free-for-open-source-projects

Copy link
Copy Markdown

Code Review by Qodo

🐞 Bugs (0) 📘 Rule violations (0) 📎 Requirement gaps (0)

Grey Divider

Great, no issues found!

Qodo reviewed your code and found no material issues that require review

Grey Divider

Tip of the day
💡 Did you know, you can see how risky a PR is at a glance with blast radius labels

More tips ↗ | Customize Qodo ↗ | Qodo docs ↗

Grey Divider

Qodo Logo

@widgetii
widgetii merged commit 78133ed into hisilicon-hi3516cv500 Oct 17, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant