rust-embedded/rust-raspberrypi-OS-tutorials · critical

Error during driver interrupt handler registration

Error message

Error during driver interrupt handler registration: {}: {}

What it means

In the IRQ phase of init_drivers_and_irqs, every descriptor carrying an irq_number gets register_and_enable_irq_handler called on its driver; if that returns Err the manager panics with the driver's compatible name and the error string. This is the final step of wiring a driver's interrupt into the system, so failure is fatal.

Solutions

  1. Check the panic message for the compatible name and error to find the failing driver and reason.
  2. Verify the irq_number on the descriptor matches the hardware's interrupt line for that device.
  3. Ensure the real IRQ manager is registered before init_drivers_and_irqs runs (otherwise the null manager or error paths trigger).
  4. Confirm the driver's register_and_enable_irq_handler implementation returns Ok on success and only errors on genuine failures.

Example fix

// before
let desc = DeviceDriverDescriptor::new(driver, Some(post_init))
    .with_irq_number(IRQNumber::new(99)); // wrong line for this device

// after
let desc = DeviceDriverDescriptor::new(driver, Some(post_init))
    .with_irq_number(IRQNumber::new(1)); // correct IRQ line
Defensive patterns

Strategy: validation

Validate before calling

// cross-check IRQ numbers against a board table before bring-up:
let expected = board_irq_for(driver.compatible());
assert_eq!(descriptor.irq_number.map(|n| n.get()), expected, "IRQ number mismatch for {}", driver.compatible());

Try / catch

// make registration failures non-fatal when appropriate:
if let Err(x) = descriptor.device_driver.register_and_enable_irq_handler(irq_number) {
    log_warn("IRQ registration failed for {}: {}", descriptor.device_driver.compatible(), x);
}

Prevention

When it happens

Trigger: A descriptor has Some(irq_number) and its device_driver's register_and_enable_irq_handler returns Err — e.g. the underlying IRQ manager registration or the handler registration fails, or the default panicking trait stub returns via a driver that reports errors.

Common situations: The IRQ number in the descriptor does not match what the driver/IRQ manager expects; the driver's handler registration returns Err because the IRQ manager is not registered or the line is already claimed; copy-pasted descriptor gives one driver another driver's IRQ number.

Understand the failure class

Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.

Related errors


AI-assisted analysis of rust-embedded/rust-raspberrypi-OS-tutorials@644474cc09 (2026-09-06). Data as JSON: /api/errors/0f2bf0f244265cae. Report an issue: GitHub.

Appendix: source

Thrown at 20_timer_callbacks/kernel/src/driver.rs:159

                    if let Err(x) = callback() {
                        panic!(
                            "Error during driver post-init callback: {}: {}",
                            descriptor.device_driver.compatible(),
                            x
                        );
                    }
                }
            }

            // 3. After all post-init callbacks were done, the interrupt controller should be
            //    registered and functional. So let drivers register with it now.
            for descriptor in descriptors {
                if let Some(irq_number) = &descriptor.irq_number {
                    if let Err(x) = descriptor
                        .device_driver
                        .register_and_enable_irq_handler(irq_number)
                    {
                        panic!(
                            "Error during driver interrupt handler registration: {}: {}",
                            descriptor.device_driver.compatible(),
                            x
                        );
                    }
                }
            }
        })
    }

    /// Enumerate all registered device drivers.
    pub fn enumerate(&self) {
        self.descriptors.read(|descriptors| {
            for (i, desc) in descriptors.iter().enumerate() {
                info!("      {}. {}", i + 1, desc.device_driver.compatible());
            }
        });
    }

View on GitHub (pinned to 644474cc09)