#define PIC_ENABLES 0x20 /* set interrupt pass through bits */
/** * struct fpga_irq_data - irq data container for the FPGA IRQ controller * @base: memory offset in virtual memory * @domain: IRQ domain for this instance * @valid: mask for valid IRQs on this controller * @used_irqs: number of active IRQs on this controller
*/ struct fpga_irq_data { void __iomem *base;
u32 valid; struct irq_domain *domain;
u8 used_irqs;
};
/* we cannot allocate memory when the controllers are initially registered */ staticstruct fpga_irq_data fpga_irq_devices[CONFIG_VERSATILE_FPGA_IRQ_NR]; staticint fpga_irq_id;
status = readl(f->base + IRQ_STATUS); if (status == 0) {
do_bad_IRQ(desc); goto out;
}
do { unsignedint irq = ffs(status) - 1;
status &= ~(1 << irq);
generic_handle_domain_irq(f->domain, irq);
} while (status);
out:
chained_irq_exit(chip, desc);
}
/* * Handle each interrupt in a single FPGA IRQ controller. Returns non-zero * if we've handled at least one interrupt. This does a single read of the * status register and handles all interrupts in order from LSB first.
*/ staticint handle_one_fpga(struct fpga_irq_data *f, struct pt_regs *regs)
{ int handled = 0; int irq;
u32 status;
/* * Keep iterating over all registered FPGA IRQ controllers until there are * no pending interrupts.
*/ staticvoid __exception_irq_entry fpga_handle_irq(struct pt_regs *regs)
{ int i, handled;
do { for (i = 0, handled = 0; i < fpga_irq_id; ++i)
handled |= handle_one_fpga(&fpga_irq_devices[i], regs);
} while (handled);
}
/* This will allocate all valid descriptors in the linear case */ for (i = 0; i < fls(valid); i++) if (valid & BIT(i)) { /* Is this still required? */
irq_create_mapping(f->domain, i);
f->used_irqs++;
}
base = of_iomap(node, 0);
WARN(!base, "unable to map fpga irq registers\n");
if (of_property_read_u32(node, "clear-mask", &clear_mask))
clear_mask = 0;
if (of_property_read_u32(node, "valid-mask", &valid_mask))
valid_mask = 0;
writel(clear_mask, base + IRQ_ENABLE_CLEAR);
writel(clear_mask, base + FIQ_ENABLE_CLEAR);
/* Some chips are cascaded from a parent IRQ */
parent_irq = irq_of_parse_and_map(node, 0); if (!parent_irq) {
set_handle_irq(fpga_handle_irq);
parent_irq = -1;
}
/* * On Versatile AB/PB, some secondary interrupts have a direct * pass-thru to the primary controller for IRQs 20 and 22-31 which need * to be enabled. See section 3.10 of the Versatile AB user guide.
*/ if (of_device_is_compatible(node, "arm,versatile-sic"))
writel(0xffd00000, base + PIC_ENABLES);
¤ Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.0.10Bemerkung:
(vorverarbeitet)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.