* well, the first items in the list being the first things populated in the
* LRs.
*
- * A hard rule is that active interrupts can never be pushed out of the LRs
- * (and therefore take priority) since we cannot reliably trap on deactivation
- * of IRQs and therefore they have to be present in the LRs.
- *
+ * Pending, non-active interrupts must be placed at the head of the list.
* Otherwise things should be sorted by the priority field and the GIC
* hardware support will take care of preemption of priority groups etc.
*
raw_spin_lock(&irqa->irq_lock);
raw_spin_lock_nested(&irqb->irq_lock, SINGLE_DEPTH_NESTING);
- if (irqa->active || irqb->active) {
- ret = (int)irqb->active - (int)irqa->active;
- goto out;
- }
+ penda = irqa->enabled && irq_is_pending(irqa) && !irqa->active;
+ pendb = irqb->enabled && irq_is_pending(irqb) && !irqb->active;
- penda = irqa->enabled && irq_is_pending(irqa);
- pendb = irqb->enabled && irq_is_pending(irqb);
+ ret = (int)pendb - (int)penda;
+ if (ret)
+ goto out;
- if (!penda || !pendb) {
- ret = (int)pendb - (int)penda;
+ /* Both pending and enabled, sort by priority (lower number first) */
+ ret = (int)irqa->priority - (int)irqb->priority;
+ if (ret)
goto out;
- }
- /* Both pending and enabled, sort by priority */
- ret = irqa->priority - irqb->priority;
+ /* Finally, HW bit active interrupts have priority over non-HW ones */
+ ret = (int)irqb->hw - (int)irqa->hw;
+
out:
raw_spin_unlock(&irqb->irq_lock);
raw_spin_unlock(&irqa->irq_lock);