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