|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen master] xen: arm: log warning for interrupt configuration mismatch
commit 7eb6564d2339c7c1c94b74a8228f34a8b4d6444f
Author: Ian Campbell <ian.campbell@xxxxxxxxxx>
AuthorDate: Thu Feb 19 15:24:02 2015 +0000
Commit: Ian Campbell <ian.campbell@xxxxxxxxxx>
CommitDate: Wed Feb 25 13:45:00 2015 +0000
xen: arm: log warning for interrupt configuration mismatch
The ICFGR register is not necessarily writeable, in particular it is
IMPLEMENTATION DEFINED for a PPI if the configuration register is
writeable. Log a warning if the hardware has ignored our write and
update the actual type in the irq descriptor so subsequent code can do
the right thing.
This most likely implies a buggy firmware description (e.g.
device-tree).
The issue is observed for example on the APM Mustang board where the
device tree (as shipped by Linux) describes all 3 timer interrupts as
rising edge but the PPI is hard-coded to level triggered (as makes
sense for an arch timer interrupt).
Signed-off-by: Ian Campbell <ian.campbell@xxxxxxxxxx>
Reviewed-by: Julien Grall <julien.grall@xxxxxxxxxx>
Cc: Pranavkumar Sawargaonkar <psawargaonkar@xxxxxxx>
---
xen/arch/arm/gic-v2.c | 16 +++++++++++++++-
xen/arch/arm/gic-v3.c | 16 +++++++++++++++-
2 files changed, 30 insertions(+), 2 deletions(-)
diff --git a/xen/arch/arm/gic-v2.c b/xen/arch/arm/gic-v2.c
index ee400b6..c05b64a 100644
--- a/xen/arch/arm/gic-v2.c
+++ b/xen/arch/arm/gic-v2.c
@@ -211,7 +211,7 @@ static void gicv2_set_irq_properties(struct irq_desc *desc,
const cpumask_t *cpu_mask,
unsigned int priority)
{
- uint32_t cfg, edgebit;
+ uint32_t cfg, actual, edgebit;
unsigned int mask = gicv2_cpu_mask(cpu_mask);
unsigned int irq = desc->irq;
unsigned int type = desc->arch.type;
@@ -229,6 +229,20 @@ static void gicv2_set_irq_properties(struct irq_desc *desc,
cfg |= edgebit;
writel_gicd(cfg, GICD_ICFGR + (irq / 16) * 4);
+ actual = readl_gicd(GICD_ICFGR + (irq / 16) * 4);
+ if ( ( cfg & edgebit ) ^ ( actual & edgebit ) )
+ {
+ printk(XENLOG_WARNING "GICv2: WARNING: "
+ "CPU%d: Failed to configure IRQ%u as %s-triggered. "
+ "H/w forces to %s-triggered.\n",
+ smp_processor_id(), desc->irq,
+ cfg & edgebit ? "Edge" : "Level",
+ actual & edgebit ? "Edge" : "Level");
+ desc->arch.type = actual & edgebit ?
+ DT_IRQ_TYPE_EDGE_RISING :
+ DT_IRQ_TYPE_LEVEL_LOW;
+ }
+
/* Set target CPU mask (RAZ/WI on uniprocessor) */
writeb_gicd(mask, GICD_ITARGETSR + irq);
/* Set priority */
diff --git a/xen/arch/arm/gic-v3.c b/xen/arch/arm/gic-v3.c
index 41042ab..1558e17 100644
--- a/xen/arch/arm/gic-v3.c
+++ b/xen/arch/arm/gic-v3.c
@@ -466,7 +466,7 @@ static void gicv3_set_irq_properties(struct irq_desc *desc,
const cpumask_t *cpu_mask,
unsigned int priority)
{
- uint32_t cfg, edgebit;
+ uint32_t cfg, actual, edgebit;
uint64_t affinity;
void __iomem *base;
unsigned int cpu = gicv3_get_cpu_from_mask(cpu_mask);
@@ -493,6 +493,20 @@ static void gicv3_set_irq_properties(struct irq_desc *desc,
writel_relaxed(cfg, base);
+ actual = readl_relaxed(base);
+ if ( ( cfg & edgebit ) ^ ( actual & edgebit ) )
+ {
+ printk(XENLOG_WARNING "GICv3: WARNING: "
+ "CPU%d: Failed to configure IRQ%u as %s-triggered. "
+ "H/w forces to %s-triggered.\n",
+ smp_processor_id(), desc->irq,
+ cfg & edgebit ? "Edge" : "Level",
+ actual & edgebit ? "Edge" : "Level");
+ desc->arch.type = actual & edgebit ?
+ DT_IRQ_TYPE_EDGE_RISING :
+ DT_IRQ_TYPE_LEVEL_LOW;
+ }
+
affinity = gicv3_mpidr_to_affinity(cpu);
/* Make sure we don't broadcast the interrupt */
affinity &= ~GICD_IROUTER_SPI_MODE_ANY;
--
generated by git-patchbot for /home/xen/git/xen.git#master
_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |