[PATCH 01/10] lib: irqchip: add S-mode notification helpers
Raymond Mao <[email protected]>
| Newsgroups | org.infradead.lists.opensbi |
|---|---|
| Message-ID | <[email protected]> |
From: Raymond Mao <[email protected]> Add irqchip helpers to set/clear S-mode notification (SEIP-based), In addition to set/clear, expose a get API to read the current notification state so upper layers can do edge-triggered notification. Signed-off-by: Raymond Mao <[email protected]> --- include/sbi/sbi_irqchip.h | 24 ++++++++++++++++++++++++ lib/sbi/sbi_irqchip.c | 18 +++++++++++++++++- 2 files changed, 41 insertions(+), 1 deletion(-) diff --git a/include/sbi/sbi_irqchip.h b/include/sbi/sbi_irqchip.h index 77b54110..7f23615a 100644 --- a/include/sbi/sbi_irqchip.h +++ b/include/sbi/sbi_irqchip.h @@ -110,4 +110,28 @@ int sbi_irqchip_init(struct sbi_scratch *scratch, bool cold_boot); /** Exit interrupt controllers */ void sbi_irqchip_exit(struct sbi_scratch *scratch); +/** + * Notify S-mode for a pending virtual interrupt on this hart. + * + * The irqchip layer abstracts the notification mechanism; on platforms that + * use SEIP, this sets mip.SEIP. + */ +int sbi_irqchip_notify_smode_set(void); + +/** + * Clear S-mode notification for virtual interrupts on this hart. + * + * The irqchip layer abstracts the notification mechanism; on platforms that + * use SEIP, this clears mip.SEIP. + */ +void sbi_irqchip_notify_smode_clear(void); + +/** + * Read S-mode notification state for virtual interrupts on this hart. + * + * The irqchip layer abstracts the notification mechanism; on platforms that + * use SEIP, this reads mip.SEIP. + */ +bool sbi_irqchip_notify_smode_get(void); + #endif diff --git a/lib/sbi/sbi_irqchip.c b/lib/sbi/sbi_irqchip.c index f8599fa6..e022d534 100644 --- a/lib/sbi/sbi_irqchip.c +++ b/lib/sbi/sbi_irqchip.c @@ -122,7 +122,7 @@ int sbi_irqchip_raw_handler_default(struct sbi_irqchip_device *chip, u32 hwirq) sbi_printf("[IRQCHIP] Calling hwirq %u raw handler callback\n", hwirq); rc = h->callback(hwirq, h->priv); - if (chip->hwirq_eoi) { + if (chip->hwirq_eoi && rc != SBI_EALREADY) { sbi_printf("[IRQCHIP] Calling EOI of hwirq %u\n", hwirq); chip->hwirq_eoi(chip, hwirq); } @@ -320,3 +320,19 @@ void sbi_irqchip_exit(struct sbi_scratch *scratch) if (hd && hd->chip && hd->chip->process_hwirqs) csr_clear(CSR_MIE, MIP_MEIP); } + +int sbi_irqchip_notify_smode_set(void) +{ + csr_set(CSR_MIP, MIP_SEIP); + return 0; +} + +void sbi_irqchip_notify_smode_clear(void) +{ + csr_clear(CSR_MIP, MIP_SEIP); +} + +bool sbi_irqchip_notify_smode_get(void) +{ + return !!(csr_read(CSR_MIP) & MIP_SEIP); +} -- 2.25.1 -- opensbi mailing list [email protected] http://lists.infradead.org/mailman/listinfo/opensbi