forked from Mirrors/opensbi

Have the SBI irqchip core keep track of registered irqchip devices. This is useful for any callbacks the irqchip driver may have, such as for warm initialization, the external interrupt handler function, and any future support for handling external interrupts (beyond IPIs) in M-mode. This improves on the tracking done in fdt_irqchip.c, as it tracks device instances, not just drivers, so callbacks can target a specific device. Signed-off-by: Samuel Holland <samuel.holland@sifive.com> Reviewed-by: Anup Patel <anup@brainfault.org>
63 lines
1.1 KiB
C
63 lines
1.1 KiB
C
/*
|
|
* SPDX-License-Identifier: BSD-2-Clause
|
|
*
|
|
* Copyright (c) 2022 Ventana Micro Systems Inc.
|
|
*
|
|
* Authors:
|
|
* Anup Patel <apatel@ventanamicro.com>
|
|
*/
|
|
|
|
#include <sbi/sbi_irqchip.h>
|
|
#include <sbi/sbi_list.h>
|
|
#include <sbi/sbi_platform.h>
|
|
|
|
static SBI_LIST_HEAD(irqchip_list);
|
|
|
|
static int default_irqfn(void)
|
|
{
|
|
return SBI_ENODEV;
|
|
}
|
|
|
|
static int (*ext_irqfn)(void) = default_irqfn;
|
|
|
|
void sbi_irqchip_set_irqfn(int (*fn)(void))
|
|
{
|
|
if (fn)
|
|
ext_irqfn = fn;
|
|
}
|
|
|
|
int sbi_irqchip_process(void)
|
|
{
|
|
return ext_irqfn();
|
|
}
|
|
|
|
void sbi_irqchip_add_device(struct sbi_irqchip_device *dev)
|
|
{
|
|
sbi_list_add_tail(&dev->node, &irqchip_list);
|
|
}
|
|
|
|
int sbi_irqchip_init(struct sbi_scratch *scratch, bool cold_boot)
|
|
{
|
|
int rc;
|
|
const struct sbi_platform *plat = sbi_platform_ptr(scratch);
|
|
|
|
rc = sbi_platform_irqchip_init(plat, cold_boot);
|
|
if (rc)
|
|
return rc;
|
|
|
|
if (ext_irqfn != default_irqfn)
|
|
csr_set(CSR_MIE, MIP_MEIP);
|
|
|
|
return 0;
|
|
}
|
|
|
|
void sbi_irqchip_exit(struct sbi_scratch *scratch)
|
|
{
|
|
const struct sbi_platform *plat = sbi_platform_ptr(scratch);
|
|
|
|
if (ext_irqfn != default_irqfn)
|
|
csr_clear(CSR_MIE, MIP_MEIP);
|
|
|
|
sbi_platform_irqchip_exit(plat);
|
|
}
|