[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [Xen-devel] [PATCH RFC 3/6] xen/arm: Allow platforms to hook IRQ routing.
On Mon, 5 Sep 2016, Kyle Temkin wrote: > From: "Kyle J. Temkin" <temkink@xxxxxxxxxxxx> > > Some common platforms (e.g. Tegra) have non-traditional IRQ controllers > that must be programmed in addition to their primary GICs-- and which > can come in unusual topologies. Device trees for targets that feature > these controllers often deviate from the conventions that Xen expects. > > This commit provides a foundation for support of these platforms, by: > - Allowing the platform to decide which IRQs can be routed by Xen, > rather than assuming that only GIC-connected IRQs can be routed. > - Allowing the platform to extend/replace existing IRQ routing logic, > rather than asssuming that the GIC will always be programmed to route > IRQs. > - Allows the platform to override IRQ translation, rather than assuming > GIC translation will always be followed. This is useful in cases where > device tree IRQ numbers don't correspond to GIC IRQ numbers. > > Signed-off-by: Kyle Temkin <temkink@xxxxxxxxxxxx> > --- > xen/arch/arm/domain_build.c | 14 +++++++++----- > xen/arch/arm/irq.c | 5 +++-- > xen/arch/arm/platform.c | 39 > ++++++++++++++++++++++++++++++++++++++ > xen/arch/arm/time.c | 2 +- > xen/drivers/char/cadence-uart.c | 3 ++- > xen/drivers/char/exynos4210-uart.c | 3 ++- > xen/drivers/char/ns16550.c | 3 ++- > xen/drivers/char/omap-uart.c | 3 ++- > xen/drivers/char/pl011.c | 3 ++- > xen/drivers/char/scif-uart.c | 3 ++- > xen/drivers/passthrough/arm/smmu.c | 4 ++-- > xen/include/asm-arm/platform.h | 14 ++++++++++++++ > 12 files changed, 80 insertions(+), 16 deletions(-) > > diff --git a/xen/arch/arm/domain_build.c b/xen/arch/arm/domain_build.c > index 52c9a01..402c766 100644 > --- a/xen/arch/arm/domain_build.c > +++ b/xen/arch/arm/domain_build.c > @@ -1094,16 +1094,20 @@ static int handle_device(struct domain *d, struct > dt_device_node *dev) > > /* > * Don't map IRQ that have no physical meaning > - * ie: IRQ whose controller is not the GIC > + * ie: IRQ that does not wind up being controlled by the GIC > + * (Note that we can't just check to see if an IRQ is owned by the > GIC, > + * as some platforms have a controller between the device irq and > the GIC, > + * such as the Tegra legacy interrupt controller.) > */ > - if ( rirq.controller != dt_interrupt_controller ) > + if ( !platform_irq_is_routable(&rirq) ) > { > - dt_dprintk("irq %u not connected to primary controller. > Connected to %s\n", > - i, dt_node_full_name(rirq.controller)); > + dt_dprintk("irq %u not (directly or indirectly) connected to > primary" > + "controller. Connected to %s\n", i, > + dt_node_full_name(rirq.controller)); > continue; > } > > - res = platform_get_irq(dev, i); > + res = platform_irq_for_device(dev, i); > if ( res < 0 ) > { > printk(XENLOG_ERR "Unable to get irq %u for %s\n", > diff --git a/xen/arch/arm/irq.c b/xen/arch/arm/irq.c > index 06d4843..dc42817 100644 > --- a/xen/arch/arm/irq.c > +++ b/xen/arch/arm/irq.c > @@ -27,6 +27,7 @@ > > #include <asm/gic.h> > #include <asm/vgic.h> > +#include <asm/platform.h> > > static unsigned int local_irqs_type[NR_LOCAL_IRQS]; > static DEFINE_SPINLOCK(local_irqs_type_lock); > @@ -370,7 +371,7 @@ int setup_irq(unsigned int irq, unsigned int irqflags, > struct irqaction *new) > /* First time the IRQ is setup */ > if ( disabled ) > { > - gic_route_irq_to_xen(desc, GIC_PRI_IRQ); > + platform_route_irq_to_xen(desc, GIC_PRI_IRQ); > /* It's fine to use smp_processor_id() because: > * For PPI: irq_desc is banked > * For SPI: we don't care for now which CPU will receive the > @@ -504,7 +505,7 @@ int route_irq_to_guest(struct domain *d, unsigned int > virq, > if ( retval ) > goto out; > > - retval = gic_route_irq_to_guest(d, virq, desc, GIC_PRI_IRQ); > + retval = platform_route_irq_to_guest(d, virq, desc, GIC_PRI_IRQ); > > spin_unlock_irqrestore(&desc->lock, flags); > > diff --git a/xen/arch/arm/platform.c b/xen/arch/arm/platform.c > index b0bfaa9..74abdc6 100644 > --- a/xen/arch/arm/platform.c > +++ b/xen/arch/arm/platform.c > @@ -137,6 +137,45 @@ bool_t platform_device_is_blacklisted(const struct > dt_device_node *node) > return (dt_match_node(blacklist, node) != NULL); > } > > +int platform_route_irq_to_guest(struct domain *d, unsigned int virq, > + struct irq_desc *desc, unsigned int priority) > +{ > + if ( platform && platform->route_irq_to_guest ) > + return platform->route_irq_to_guest(d, virq, desc, priority); > + else > + return gic_route_irq_to_guest(d, virq, desc, priority); > +} > + > +void platform_route_irq_to_xen(struct irq_desc *desc, unsigned int priority) > +{ > + if ( platform && platform->route_irq_to_xen ) > + platform->route_irq_to_xen(desc, priority); > + else > + gic_route_irq_to_xen(desc, priority); > +} > + > +bool_t platform_irq_is_routable(struct dt_raw_irq * rirq) > +{ > + /* > + * If we have a platform-specific method to determine if an IRQ is > routable, > + * check that; otherwise fall back to checking to see if an IRQ belongs > to > + * the GIC. > + */ > + if ( platform && platform->irq_is_routable ) > + return platform->irq_is_routable(rirq); > + else > + return (rirq->controller == dt_interrupt_controller); > +} > + > +int platform_irq_for_device(const struct dt_device_node *dev, int index) > +{ > + if ( platform && platform->irq_for_device ) > + return platform->irq_for_device(dev, index); > + else > + return platform_get_irq(dev, index); > +} If it's not too much trouble I would move these functions to platform.h as static inlines. In any case the patch is OK: Reviewed-by: Stefano Stabellini <sstabellini@xxxxxxxxxx> _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxx https://lists.xen.org/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |