Introduces hierarchical interrupt controllers in the system, allowing to easily utilize multiplexers such as GPIOs to serve as interrupt sources. nexus driver is a top-level interrupt controller, exposing single interruprt (IRQ) on ARM. The GIC or any other used interrupt controller setups handler on that interrupt, exposing new IRQs available for other peripherals. In an example SoC, interrupt hierarchy may look like that: nexus0 (1 interrupts) | \-- gic0 (160 interrupts, uses irq nexus0:0) | \-- gpio0 (8 interrupts, uses irq gic0:42) | | | \-- mmcsd0 (uses irqs gpio0:1, gpio0:2) | \-- spi0 (uses irq gpio0:3) | ... \-- gpio1 (8 interrupts, uses irq gic0:43) \-- ehci0 (uses irq gic0:109) ... That change should not break any existing ports in any way, except for need to add 'arm/arm/intr.c' to 'files.*' of existing ports, as it's no longer compiled-in by default.
Unit Tests Skipped
A few points I found from a quick look through.
This comment has sneaked in.
This comment doesn't make sense, I see no 0xdeadbeef here.
Do we need this as it's in the global files.arm?
This looks odd, does the GIC use irq 0? My copy of the Linux dts doesn't have this so we shouldn't require it.
Shouldn't we still allow the old interrupt code here until we enable intrng on all SoCs?
That's clearly wrong. I've missed these two lines when doing merge.
Yes, that comment seems invalid. It is also present in head.
Nope, this will be removed.
It's a temporary solution. We were talking with Ian how to handle that and the best solution will be to allow ICs to setup interrupt 0 without having such resource assigned (ignore error from bus_alloc_resource*() and proceed to bus_setup_intr()).
the changes in this routine break the spurious interrupt detection, which counts on last_irq being passed in from what used to be a loop in the caller, and it also requires the old standard of returning -1 to mean "no more active irqs".
we'll need to think about how to report spurious interrupts with intrng. an occasional spurious interrupt is no big deal, but lots of them mean trouble in a driver (or, recently, trouble in our whole armv6 architecture really, which I hacked around with the arm_irq_memory_barrier() stuff).
this isn't right, the EOI can't be done until after the filter handler is done. recent changes on -current moved this to a post_filter function.
this static buffer is not SMP-safe (although I think it would take something like two hot-plug devices being handled concurrently on two different cores both of which trigger the loading of drivers and resource allocation, and both arriving here at the same time to get a glich).
arm_intrnames_init() can go, it's no longer referenced from anywhere except intr.c
another place where static buffers may not be SMP-safe
In my fdt_clock work I store a similar table of dev<->node references, and Nathan said, well, I'm not sure I have a complete handle on what he was saying, but I'll paste it here so we can remember to follow up...
<DamnHippi> nathanw: so you're saying fdt_clock_register_provider() should call ofw_bus_get_node() then pass that value through OF_xref_phandle() before storing it?
Also, if we're going to have multiple places storing dev<->phandle lookup lists/tables, maybe we should put some common code for it into dev/fdt or dev/ofw. gpio and pinmux stuff also tends to have lots of &node refs in properties that we may some day handle by making the node reference correspond to a device_t.
if all masking/unmasking/eoi now comes through these routines, then maybe this would be the new place where arm_irq_memory_barrier() calls should go, instead of individual IC drivers.
I think this might be the place to check for res == NULL and use that to set up the root IC. We can validate that flags includes INTR_CONTROLLER, and perhaps also that no root controller is regigistered already.
I'm curious why this cpu_to_fdt32() is needed, when the resource loops in simplebus and ofwbus that call this code have already done OF_getencprop() which includes endian-swapping already.
some ICs put the irq number in intr. this is that whole ugly "only the IC driver knows how to decode the interrupts=<...> cell contents" thing.
the parens on these macros aren't quite right, should be
#define FDT_MAP_IRQ(node, pin) arm_fdt_map_irq((node), (pin))
likewise the one in the #else below
I have no idea why arm has a psl.h, but I'm pretty sure it isn't needed in here.
If this is for trapframe, we can get away with a simple fwd decl of it.
arm_intrnames_init() can go away. it used to be referenced from several files, but now it's only called by a SYSINIT local to the same file.
With Warner's recent config(8) changes we can do that with a line like:
arm/arm/intr.c optional !arm_intrng
btw, is this an aid to converting platforms one at a time and eventually it will go away, or will we always have both old and new intr code around?