Re: [BUG] CI20: interrupt-controller@10001000 didn't like hwirq-0x0 to VIRQ8 mapping (rc=-19)

From: Paul Cercueil
Date: Fri Dec 20 2019 - 12:01:26 EST


Hi Nikolaus,

Try with this: https://lkml.org/lkml/2019/11/22/1831

And don't hesitate to add your Tested-by :)

Cheers,
-Paul


Le ven., déc. 20, 2019 at 17:49, H. Nikolaus Schaller <hns@xxxxxxxxxxxxx> a écrit :
Hi Paul,
since v5.5-rc1 the boot log is flooded by a sequence of messages like:

[ 0.000000] NR_IRQS: 222
[ 0.000000] irq: :interrupt-controller@10001000 didn't like hwirq-0x0 to VIRQ8 mapping (rc=-19)
[ 0.000000] irq: :interrupt-controller@10001000 didn't like hwirq-0x1 to VIRQ9 mapping (rc=-19)
[ 0.000000] irq: :interrupt-controller@10001000 didn't like hwirq-0x2 to VIRQ10 mapping (rc=-19)
[ 0.000000] irq: :interrupt-controller@10001000 didn't like hwirq-0x3 to VIRQ11 mapping (rc=-19)
[ 0.000000] irq: :interrupt-controller@10001000 didn't like hwirq-0x4 to VIRQ12 mapping (rc=-19)
...
[ 0.000000] irq: :interrupt-controller@10001000 didn't like hwirq-0x3e to VIRQ70 mapping (rc=-19)
[ 0.000000] irq: :interrupt-controller@10001000 didn't like hwirq-0x3f to VIRQ71 mapping (rc=-19)

A handful of /proc/interrupts are nevertheless working.

I have now analyzed the situation a little:

* the message is printed by irq_domain_associate()
* call sequence is ingenic_intc_of_init() -> irq_domain_add_legacy() -> irq_domain_associate_many() -> irq_domain_associate()
* the reason for the message is that
domain->ops->map()
called in irq_domain_associate() returns an error
* domain->ops is initialized to &irq_generic_chip_ops
* domain->ops->map is initialized to irq_map_generic_chip()
* irq_map_generic_chip() calls __irq_get_domain_generic_chip()
* which returns -ENODEV (-19) if d->gc == NULL

So the location, where the -19 comes from, is found.

Now why is d->gc == NULL in __irq_get_domain_generic_chip() ?

This IMHO seems to be a bad initialization sequence:

* ingenic_intc_of_init() calls firstly irq_domain_add_legacy()
* which does *not* initialize domain->gc but expects it to be !NULL through irq_map_generic_chip()
* and would only irq_alloc_domain_generic_chips() which initializes domain->gc if irq_domain_add_legacy() is successful
* irq_alloc_domain_generic_chips() would initialize domain->gc by calling __irq_alloc_domain_generic_chips()

There are indeed significant changes in drivers/irqchip/irq-ingenic.c
from v5.4to v5.5-rc1 which have introduced the use of irq_domain_add_legacy()
and irq_alloc_domain_generic_chips() by

52ecc87642f2 irqchip: ingenic: Error out if IRQ domain creation failed
208caadce5d4 irqchip: ingenic: Get virq number from IRQ domain
8bc7464b5140 irqchip: ingenic: Alloc generic chips from IRQ domain
b8b0145f7d0e irqchip: Ingenic: Add process for more than one irq at the same time.

Most likely 52ecc87642f2 has changed the call sequence and therefore always fails.

Is there some essential patch missing to be upstreamed?
I have looked but not found anything related in linux-next.

I have also tried reverting 52ecc87642f2 alone but it has conflicts.

But I can revert all 4 commits with an otherwise unchanged setup and
the messages are gone for me.

How would a fix look like?

BR and thanks,
Nikolaus