summaryrefslogtreecommitdiff
path: root/kernel
diff options
context:
space:
mode:
authorEliav Farber <farbere@amazon.com>2026-10-11 05:04:48 +0000
committerThomas Gleixner <tglx@kernel.org>2026-10-15 14:25:07 +0200
commit9376df3496753563e3d7f7cb5d91525f9a6e9497 (patch)
tree7cf0a777de134f94a92a4e2576812c9a637100e3 /kernel
parent0b9bc458d9607388576c759483d0ff2d4957cd93 (diff)
irqchip/al-fic: Support per-child affinity via interrupt redirection
The FIC multiplexes up to 32 sources into one parent GIC SPI, and a child's handler runs in the parent's context, so a child has no affinity control of its own. irq_set_affinity() therefore fails with -EINVAL, and drivers that treat that as fatal cannot probe when their interrupt arrives through a FIC group. The parent routing cannot be changed on behalf of one child either, because several FIC groups may share one SPI and all of them would move with it. Use the interrupt redirection infrastructure. Dispatch children with generic_handle_demux_domain_irq() and set irq_set_affinity to irq_chip_redirect_set_affinity(), so a child whose affinity excludes the CPU taking the parent interrupt runs on its target CPU in IRQ work context. The interrupt is still taken on the parent's CPU; only the child's handler body moves. Redirection defers the whole flow handler, so the cause bit is cleared in al_fic_irq_pre_redirect(), which runs in parent context on both the inline and the redirected path. A level configured group is masked there too, because its cause bit re-latches while the input stays asserted; the deferred handle_level_irq() masks again and unmasks when the handler is done. An edge configured group is only acked, since handle_edge_irq() has no unconditional unmask. irq_ack is a noop because irq_pre_redirect runs on every dispatch and the ack must not happen twice. Signed-off-by: Eliav Farber <farbere@amazon.com> Signed-off-by: Thomas Gleixner <tglx@kernel.org> Reviewed-by: Radu Rendec <radu@rendec.net> Link: https://patch.msgid.link/20261011050449.41903-10-farbere@amazon.com
Diffstat (limited to 'kernel')
0 files changed, 0 insertions, 0 deletions