// SPDX-License-Identifier: GPL-2.0 /* * Copyright (C) 2021 Western Digital Corporation or its affiliates. * Copyright (C) 2022 Ventana Micro Systems Inc.
*/
int aplic_irq_set_type(struct irq_data *d, unsignedint type)
{ struct aplic_priv *priv = irq_data_get_irq_chip_data(d); void __iomem *sourcecfg;
u32 val = 0;
switch (type) { case IRQ_TYPE_NONE:
val = APLIC_SOURCECFG_SM_INACTIVE; break; case IRQ_TYPE_LEVEL_LOW:
val = APLIC_SOURCECFG_SM_LEVEL_LOW; break; case IRQ_TYPE_LEVEL_HIGH:
val = APLIC_SOURCECFG_SM_LEVEL_HIGH; break; case IRQ_TYPE_EDGE_FALLING:
val = APLIC_SOURCECFG_SM_EDGE_FALL; break; case IRQ_TYPE_EDGE_RISING:
val = APLIC_SOURCECFG_SM_EDGE_RISE; break; default: return -EINVAL;
}
/* Setup APLIC domaincfg register */
val = readl(priv->regs + APLIC_DOMAINCFG);
val |= APLIC_DOMAINCFG_IE; if (msi_mode)
val |= APLIC_DOMAINCFG_DM;
writel(val, priv->regs + APLIC_DOMAINCFG); if (readl(priv->regs + APLIC_DOMAINCFG) != val)
dev_warn(priv->dev, "unable to write 0x%x in domaincfg\n", val);
}
staticvoid aplic_init_hw_irqs(struct aplic_priv *priv)
{ int i;
/* Disable all interrupts */ for (i = 0; i <= priv->nr_irqs; i += 32)
writel(-1U, priv->regs + APLIC_CLRIE_BASE + (i / 32) * sizeof(u32));
/* Set interrupt type and default priority for all interrupts */ for (i = 1; i <= priv->nr_irqs; i++) {
writel(0, priv->regs + APLIC_SOURCECFG_BASE + (i - 1) * sizeof(u32));
writel(APLIC_DEFAULT_PRIORITY,
priv->regs + APLIC_TARGET_BASE + (i - 1) * sizeof(u32));
}
/* Save device pointer and register base */
priv->dev = dev;
priv->regs = regs;
if (np) { /* Find out number of interrupt sources */
rc = of_property_read_u32(np, "riscv,num-sources", &priv->nr_irqs); if (rc) {
dev_err(dev, "failed to get number of interrupt sources\n"); return rc;
}
/* * Find out number of IDCs based on parent interrupts * * If "msi-parent" property is present then we ignore the * APLIC IDCs which forces the APLIC driver to use MSI mode.
*/ if (!of_property_present(np, "msi-parent")) { while (!of_irq_parse_one(np, priv->nr_idcs, &parent))
priv->nr_idcs++;
}
} else {
rc = riscv_acpi_get_gsi_info(dev->fwnode, &priv->gsi_base, &priv->acpi_aplic_id,
&priv->nr_irqs, &priv->nr_idcs); if (rc) {
dev_err(dev, "failed to find GSI mapping\n"); return rc;
}
}
/* Setup initial state APLIC interrupts */
aplic_init_hw_irqs(priv);
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.