@@ -68,6 +68,7 @@ struct plic_priv {
unsigned long plic_quirks;
unsigned int nr_irqs;
unsigned long *prio_save;
+ u32 gsi_base;
};
struct plic_handler {
@@ -314,6 +315,10 @@ static int plic_irq_domain_translate(struct irq_domain *d,
{
struct plic_priv *priv = d->host_data;
+ /* For DT, gsi_base is always zero. */
+ if (fwspec->param[0] >= priv->gsi_base)
+ fwspec->param[0] = fwspec->param[0] - priv->gsi_base;
+
if (test_bit(PLIC_QUIRK_EDGE_INTERRUPT, &priv->plic_quirks))
return irq_domain_translate_twocell(d, fwspec, hwirq, type);
@@ -453,6 +458,17 @@ static int plic_probe(struct platform_device *pdev)
return -EIO;
}
+ /*
+ * Find out GSI base number
+ *
+ * Note: DT does not define "riscv,gsi-base" property so GSI
+ * base is always zero for DT.
+ */
+ rc = fwnode_property_read_u32_array(dev->fwnode, "riscv,gsi-base",
+ &priv->gsi_base, 1);
+ if (rc)
+ priv->gsi_base = 0;
+
rc = fwnode_property_read_u32_array(dev->fwnode, "riscv,ndev",
&nr_irqs, 1);
if (rc) {
ACPI uses flat Global System Interrupt Vector space and hence the GSI number needs to be converted to corresponding local IRQ number of the interrupt controller. Add a new gsi_base field in the priv structure to handle this which will be 0 on DT based systems. Signed-off-by: Sunil V L <sunilvl@ventanamicro.com> --- drivers/irqchip/irq-sifive-plic.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+)