xref: /openbmc/linux/include/linux/arm_sdei.h (revision 5cd474e5)
1ad6eb31eSJames Morse // SPDX-License-Identifier: GPL-2.0
2ad6eb31eSJames Morse // Copyright (C) 2017 Arm Ltd.
3ad6eb31eSJames Morse #ifndef __LINUX_ARM_SDEI_H
4ad6eb31eSJames Morse #define __LINUX_ARM_SDEI_H
5ad6eb31eSJames Morse 
6ad6eb31eSJames Morse #include <uapi/linux/arm_sdei.h>
7ad6eb31eSJames Morse 
8f96935d3SJames Morse #include <acpi/ghes.h>
9f9f05395SJames Morse 
10f9f05395SJames Morse #ifdef CONFIG_ARM_SDE_INTERFACE
11ad6eb31eSJames Morse #include <asm/sdei.h>
12f9f05395SJames Morse #endif
13ad6eb31eSJames Morse 
14ad6eb31eSJames Morse /* Arch code should override this to set the entry point from firmware... */
15ad6eb31eSJames Morse #ifndef sdei_arch_get_entry_point
16ad6eb31eSJames Morse #define sdei_arch_get_entry_point(conduit)	(0)
17ad6eb31eSJames Morse #endif
18ad6eb31eSJames Morse 
19ad6eb31eSJames Morse /*
20ad6eb31eSJames Morse  * When an event occurs sdei_event_handler() will call a user-provided callback
21ad6eb31eSJames Morse  * like this in NMI context on the CPU that received the event.
22ad6eb31eSJames Morse  */
23ad6eb31eSJames Morse typedef int (sdei_event_callback)(u32 event, struct pt_regs *regs, void *arg);
24ad6eb31eSJames Morse 
25ad6eb31eSJames Morse /*
26ad6eb31eSJames Morse  * Register your callback to claim an event. The event must be described
27ad6eb31eSJames Morse  * by firmware.
28ad6eb31eSJames Morse  */
29ad6eb31eSJames Morse int sdei_event_register(u32 event_num, sdei_event_callback *cb, void *arg);
30ad6eb31eSJames Morse 
31ad6eb31eSJames Morse /*
32ad6eb31eSJames Morse  * Calls to sdei_event_unregister() may return EINPROGRESS. Keep calling
33ad6eb31eSJames Morse  * it until it succeeds.
34ad6eb31eSJames Morse  */
35ad6eb31eSJames Morse int sdei_event_unregister(u32 event_num);
36ad6eb31eSJames Morse 
37ad6eb31eSJames Morse int sdei_event_enable(u32 event_num);
38ad6eb31eSJames Morse int sdei_event_disable(u32 event_num);
39ad6eb31eSJames Morse 
40f96935d3SJames Morse /* GHES register/unregister helpers */
41f96935d3SJames Morse int sdei_register_ghes(struct ghes *ghes, sdei_event_callback *normal_cb,
42f96935d3SJames Morse 		       sdei_event_callback *critical_cb);
43f96935d3SJames Morse int sdei_unregister_ghes(struct ghes *ghes);
44f96935d3SJames Morse 
45ad6eb31eSJames Morse #ifdef CONFIG_ARM_SDE_INTERFACE
46ad6eb31eSJames Morse /* For use by arch code when CPU hotplug notifiers are not appropriate. */
47ad6eb31eSJames Morse int sdei_mask_local_cpu(void);
48ad6eb31eSJames Morse int sdei_unmask_local_cpu(void);
49dc4e8c07SShuai Xue void __init sdei_init(void);
50*5cd474e5SD Scott Phillips void sdei_handler_abort(void);
51ad6eb31eSJames Morse #else
sdei_mask_local_cpu(void)52ad6eb31eSJames Morse static inline int sdei_mask_local_cpu(void) { return 0; }
sdei_unmask_local_cpu(void)53ad6eb31eSJames Morse static inline int sdei_unmask_local_cpu(void) { return 0; }
sdei_init(void)54dc4e8c07SShuai Xue static inline void sdei_init(void) { }
sdei_handler_abort(void)55*5cd474e5SD Scott Phillips static inline void sdei_handler_abort(void) { }
56ad6eb31eSJames Morse #endif /* CONFIG_ARM_SDE_INTERFACE */
57ad6eb31eSJames Morse 
58ad6eb31eSJames Morse 
59ad6eb31eSJames Morse /*
60ad6eb31eSJames Morse  * This struct represents an event that has been registered. The driver
61ad6eb31eSJames Morse  * maintains a list of all events, and which ones are registered. (Private
62ad6eb31eSJames Morse  * events have one entry in the list, but are registered on each CPU).
63ad6eb31eSJames Morse  * A pointer to this struct is passed to firmware, and back to the event
64ad6eb31eSJames Morse  * handler. The event handler can then use this to invoke the registered
65ad6eb31eSJames Morse  * callback, without having to walk the list.
66ad6eb31eSJames Morse  *
67ad6eb31eSJames Morse  * For CPU private events, this structure is per-cpu.
68ad6eb31eSJames Morse  */
69ad6eb31eSJames Morse struct sdei_registered_event {
70ad6eb31eSJames Morse 	/* For use by arch code: */
71ad6eb31eSJames Morse 	struct pt_regs          interrupted_regs;
72ad6eb31eSJames Morse 
73ad6eb31eSJames Morse 	sdei_event_callback	*callback;
74ad6eb31eSJames Morse 	void			*callback_arg;
75ad6eb31eSJames Morse 	u32			 event_num;
76ad6eb31eSJames Morse 	u8			 priority;
77ad6eb31eSJames Morse };
78ad6eb31eSJames Morse 
79ad6eb31eSJames Morse /* The arch code entry point should then call this when an event arrives. */
80ad6eb31eSJames Morse int notrace sdei_event_handler(struct pt_regs *regs,
81ad6eb31eSJames Morse 			       struct sdei_registered_event *arg);
82ad6eb31eSJames Morse 
83ad6eb31eSJames Morse /* arch code may use this to retrieve the extra registers. */
84ad6eb31eSJames Morse int sdei_api_event_context(u32 query, u64 *result);
85ad6eb31eSJames Morse 
86ad6eb31eSJames Morse #endif /* __LINUX_ARM_SDEI_H */
87