OpenWrt Forum Archive

Topic: How can I change the kernel IRQ routing?

The content of this topic has been archived on 3 May 2018. There are no obvious gaps in this topic, but there may still be some posts missing at the end.

Hello again,

after making some progress with kamikaze on the WL-HDD, I've hit a roadblock again. I have most of the hardware up and running, except the USB controller.

The problem is quite simple: the ohci_hcd driver and the serial driver both claim IRQ 2.
When both are compiled into the kernel, this causes a kernel panic, when ohci_hcd is a module, it just refuses to load.

I first thought simply disabling the serial driver would take care of that, however, the code in arch/mips/bcm947xx/ fails to compile if the serial driver is disabled or a module. Besides, when using development kernels, the serial console is highly useful (and that doesn't work without the serial driver compiled right into the kernel).

So now, to make the USB controller work, it's necessary to either give the USB controller another IRQ via the PCI interrupt mapping, or to change the serial driver's IRQ (which may be more complicated, as it's already initialized in arch/mips/bcm947xx/setup.c). What's the easier way?



I think the easiest way is to "fix" the bcm47xx_fixup_device which get called when some device is initialized by the coresponding driver. This device_fix takes care of assigning proper resoruces or any other "tweak" neccessary.
This function is located in arch/mips/bcm947xx/pci.c

Or, if you just go through setup.c and pci.c you'll see where the PCI IRQ's gets assigned to external device etc... besides, you can always "fix" the irq assignment of the serial driver as SHARED. That couls also do the trick.


Thanks for your tips - they worked up to a certain point. I changed bcm47xx_fixup_device to change the IRQ from 2 to 5 (the only other device using IRQ 5 is the internal HomePNA adapter and as it's disabled, that seemed like a good choice). The ohci_hcd module now loads, unfortunately, it still doesn't work. Here's the relevant dmesg output:

<7>ohci_hcd: 2005 April 22 USB 1.1 'Open' Host Controller (OHCI) Driver (PCI)
<4>PCI: Enabling device 0000:00:04.0 (0000 -> 0002)
<4>PCI: ugly USB controller hack, changing irq 2 to 5..
<7>PCI: Setting latency timer of device 0000:00:04.0 to 64
<6>ohci_hcd 0000:00:04.0: OHCI Host Controller
<6>ohci_hcd 0000:00:04.0: new USB bus registered, assigned bus number 1
<6>ohci_hcd 0000:00:04.0: irq 5, io mem 0x18004000
<6>usb usb1: configuration #1 chosen from 1 choice
<6>hub 1-0:1.0: USB hub found
<6>hub 1-0:1.0: 2 ports detected

<- At that point, I plugged in a USB Bluetooth stick:

<6>usb 1-1: new full speed USB device using ohci_hcd and address 2
<3>irq 2: nobody cared (try booting with the "irqpoll" option)
<4>Call Trace: [<8004ddbc>]  [<8004e004>]  [<8004d56c>]  [<8004d56c>]  [<8004d6a8>]  [<8000a98c>]  [<80001e8c>]  [<8002693c>]  [<80001ea4>]  [<8000917c>]  [<802001d4>]  [<8000917c>]  [<8011d550>]  [<800334d0>]  [<800333cc>]  [<800334d0>]  [<8000a994>]  [<8000b168>]  [<80001ea4>]  [<8002d35c>]  [<8000917c>]  [<8000ac0c>]  [<8000abf4>]  [<8026493c>]  [<80264924>]  [<8026412c>]
<0>Disabling IRQ #2
<4>ohci_hcd 0000:00:04.0: Unlink after no-IRQ?  Controller is probably using the wrong IRQ.

After that, the serial console (which did use IRQ 2) was dead.
So some part of the kernel is still convinced that IRQ 2 is responsible for the ohci_hcd.. anybody has an idea where?


P.S. I added the following code to the beginning of bcm47xx_fixup_device:

  if ((d->bus->number == 0) && (d->device == 0x4715)) {
    printk("PCI: ugly USB controller hack, changing irq %d to 5..\n",d->irq);
    d->irq = 5;
    pci_write_config_byte(d, PCI_INTERRUPT_LINE, d->irq);

P.P.S. The lone handler from dmesg at 0x8011d550 is serial8250_interrupt, so obviously the ohci_hcd didn't register IRQ 2 any more, but it's still triggered by the hardware.. even though lspci and /proc/interrupts are convinced it's at IRQ 5.

(Last edited by floe on 8 Oct 2006, 21:11)

Thanks - but the patch from that thread is already part of my patchset. Otherwise, no PCI devices would work anyway..

AFAIK you can't "change" the IRQ for USB.

You'd better post the original kernel panic and see if someone can help.

Unfortunately, I don't have that log anymore. However, I found a workaround: I compile the serial driver into the kernel, but remove the external UART (which isn't part of the original hardware anyway wink ). As no UART is present, the serial driver doesn't register any IRQ, the ohci_hcd module can be loaded and USB works - I mounted an USB stick yesterday just to check.

Of course, that's not really a fix, but if the USB interrupt can't be changed, then the only other solution would be changing the serial interrupt, and from what I've seen in arch/mips/bcm947xx/broadcom/sbmips.c,  this is set in sb_mips_init by sb_setirq. I doubt that simply changing it to 1 or 5 would work, though?

(Last edited by floe on 10 Oct 2006, 21:09)

The right solution would be to get proper sharing of the IRQ like in 2.4.

I fixed it in r5160 by chaging the code that assigns the IRQs to sb cores on BCM4710. I simply removed the IRQ assignment for the unused ILINE20 core and gave that IRQ to the USB stuff... Seems to work now

The discussion might have continued from here.