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;
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 */
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);
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;