mmio_write32(gicc_base + GICC_DIR, i);
}
- /* Disable PPIs if necessary */
- if (!root_shutdown)
- mmio_write32(gicd_base + GICD_ICENABLER, 0xffff0000);
- /* Ensure IPIs are enabled */
- mmio_write32(gicd_base + GICD_ISENABLER, 0x0000ffff);
+ /* Ensure all IPIs and the maintenance PPI are enabled */
+ mmio_write32(gicd_base + GICD_ISENABLER,
+ 0x0000ffff | (1 << MAINTENANCE_IRQ));
+
+ /*
+ * Disable PPIs, except for the maintenance interrupt.
+ * On shutdown, the root cell expects to find all its PPIs still
+ * enabled - except for the maintenance interrupt we used.
+ */
+ mmio_write32(gicd_base + GICD_ICENABLER,
+ root_shutdown ? 1 << MAINTENANCE_IRQ :
+ 0xffff0000 & ~(1 << MAINTENANCE_IRQ));
if (is_shutdown)
mmio_write32(gich_base + GICH_HCR, 0);
u32 vtr, vmcr;
u32 cell_gicc_ctlr, cell_gicc_pmr;
- /* Ensure all IPIs are enabled */
- mmio_write32(gicd_base + GICD_ISENABLER, 0x0000ffff);
+ /* Ensure all IPIs and the maintenance PPI are enabled. */
+ mmio_write32(gicd_base + GICD_ISENABLER,
+ 0x0000ffff | (1 << MAINTENANCE_IRQ));
cell_gicc_ctlr = mmio_read32(gicc_base + GICC_CTLR);
cell_gicc_pmr = mmio_read32(gicc_base + GICC_PMR);
{
paging_destroy(&cell->arch.mm, (unsigned long)gicc_base, gicc_size,
PAGING_NON_COHERENT);
- /* Reset interrupt routing of the cell's spis */
- gic_target_spis(cell, &root_cell);
}
static int gic_send_sgi(struct sgi *sgi)
return 0;
}
-static int gic_inject_irq(struct per_cpu *cpu_data, struct pending_irq *irq)
+static int gic_inject_irq(struct per_cpu *cpu_data, u16 irq_id)
{
int i;
int first_free = -1;
/* Check that there is no overlapping */
lr = gic_read_lr(i);
- if ((lr & GICH_LR_VIRT_ID_MASK) == irq->virt_id)
- return -EINVAL;
+ if ((lr & GICH_LR_VIRT_ID_MASK) == irq_id)
+ return -EEXIST;
}
if (first_free == -1)
return -EBUSY;
/* Inject group 0 interrupt (seen as IRQ by the guest) */
- lr = irq->virt_id;
+ lr = irq_id;
lr |= GICH_LR_PENDING_BIT;
- if (!is_sgi(irq->virt_id)) {
+ if (!is_sgi(irq_id)) {
lr |= GICH_LR_HW_BIT;
- lr |= irq->virt_id << GICH_LR_PHYS_ID_SHIFT;
+ lr |= (u32)irq_id << GICH_LR_PHYS_ID_SHIFT;
}
gic_write_lr(first_free, lr);
mmio_write32(gich_base + GICH_HCR, hcr);
}
+enum mmio_result gic_handle_irq_route(struct mmio_access *mmio,
+ unsigned int irq)
+{
+ /* doesn't exist in v2 - ignore access */
+ return MMIO_HANDLED;
+}
+
unsigned int irqchip_mmio_count_regions(struct cell *cell)
{
return 1;
}
-struct irqchip_ops gic_irqchip = {
+struct irqchip_ops irqchip = {
.init = gic_init,
.cpu_init = gic_cpu_init,
.cpu_reset = gic_cpu_reset,