diff --git a/drivers/firmware/arm_sdei.c b/drivers/firmware/arm_sdei.c index 08e828660e81..63b17b617ae3 100644 --- a/drivers/firmware/arm_sdei.c +++ b/drivers/firmware/arm_sdei.c @@ -924,6 +924,47 @@ int sdei_event_routing_set(u32 event_num, unsigned long flags, return err; } + +static int sdei_api_interrupt_bind(u32 intr_num, u64 *result) +{ + return invoke_sdei_fn(SDEI_1_0_FN_SDEI_INTERRUPT_BIND, intr_num, 0, 0, 0, + 0, result); +} + +int sdei_interrupt_bind(u32 intr_num, u32 *event_num) +{ + int err; + u64 result; + + err = sdei_api_interrupt_bind(intr_num, &result); + if (!err) + *event_num = (u32)result; + + return err; +} + +static int sdei_api_interrupt_release(u32 event_num) +{ + return invoke_sdei_fn(SDEI_1_0_FN_SDEI_INTERRUPT_RELEASE, event_num, 0, 0, 0, + 0, NULL); +} + +int sdei_interrupt_release(u32 event_num) +{ + struct sdei_event *event; + + mutex_lock(&sdei_events_lock); + event = sdei_event_find(event_num); + mutex_unlock(&sdei_events_lock); + + if (event) { + pr_err("%s: need unregister event:%d before release\n", + __func__, event_num); + return SDEI_DENIED; + } + + return sdei_api_interrupt_release(event_num); +} #endif static int sdei_get_conduit(struct platform_device *pdev) diff --git a/include/linux/arm_sdei.h b/include/linux/arm_sdei.h index d3f1d27aba64..d8bd2a1feb77 100644 --- a/include/linux/arm_sdei.h +++ b/include/linux/arm_sdei.h @@ -40,13 +40,51 @@ int sdei_event_enable(u32 event_num); int sdei_event_disable(u32 event_num); #ifdef CONFIG_FIQ_DEBUGGER_TRUST_ZONE +#ifdef CONFIG_ARM_SDE_INTERFACE int sdei_event_enable_nolock(u32 event_num); int sdei_event_disable_nolock(u32 event_num); int sdei_event_routing_set_nolock(u32 event_num, unsigned long flags, unsigned long affinity); int sdei_event_routing_set(u32 event_num, unsigned long flags, unsigned long affinity); -#endif +int sdei_interrupt_bind(u32 intr_num, u32 *event_num); +int sdei_interrupt_release(u32 event_num); +#else +static inline int sdei_event_enable_nolock(u32 event_num) +{ + return SDEI_NOT_SUPPORTED; +} + +static inline int sdei_event_disable_nolock(u32 event_num) +{ + return SDEI_NOT_SUPPORTED; +} + +static inline int sdei_event_routing_set_nolock(u32 event_num, + unsigned long flags, + unsigned long affinity) +{ + return SDEI_NOT_SUPPORTED; +} + +static inline int sdei_event_routing_set(u32 event_num, + unsigned long flags, + unsigned long affinity) +{ + return SDEI_NOT_SUPPORTED; +} + +static inline int sdei_interrupt_bind(u32 intr_num, u32 *event_num) +{ + return SDEI_NOT_SUPPORTED; +} + +static inline int sdei_interrupt_release(u32 event_num) +{ + return SDEI_NOT_SUPPORTED; +} +#endif /* CONFIG_ARM_SDE_INTERFACE */ +#endif /* CONFIG_FIQ_DEBUGGER_TRUST_ZONE */ #ifdef CONFIG_ARM_SDE_INTERFACE /* For use by arch code when CPU hotplug notifiers are not appropriate. */