18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0
28c2ecf20Sopenharmony_ci// Copyright (C) 2017 Arm Ltd.
38c2ecf20Sopenharmony_ci#ifndef __LINUX_ARM_SDEI_H
48c2ecf20Sopenharmony_ci#define __LINUX_ARM_SDEI_H
58c2ecf20Sopenharmony_ci
68c2ecf20Sopenharmony_ci#include <uapi/linux/arm_sdei.h>
78c2ecf20Sopenharmony_ci
88c2ecf20Sopenharmony_ci#include <acpi/ghes.h>
98c2ecf20Sopenharmony_ci
108c2ecf20Sopenharmony_ci#ifdef CONFIG_ARM_SDE_INTERFACE
118c2ecf20Sopenharmony_ci#include <asm/sdei.h>
128c2ecf20Sopenharmony_ci#endif
138c2ecf20Sopenharmony_ci
148c2ecf20Sopenharmony_ci/* Arch code should override this to set the entry point from firmware... */
158c2ecf20Sopenharmony_ci#ifndef sdei_arch_get_entry_point
168c2ecf20Sopenharmony_ci#define sdei_arch_get_entry_point(conduit)	(0)
178c2ecf20Sopenharmony_ci#endif
188c2ecf20Sopenharmony_ci
198c2ecf20Sopenharmony_ci/*
208c2ecf20Sopenharmony_ci * When an event occurs sdei_event_handler() will call a user-provided callback
218c2ecf20Sopenharmony_ci * like this in NMI context on the CPU that received the event.
228c2ecf20Sopenharmony_ci */
238c2ecf20Sopenharmony_citypedef int (sdei_event_callback)(u32 event, struct pt_regs *regs, void *arg);
248c2ecf20Sopenharmony_ci
258c2ecf20Sopenharmony_ci/*
268c2ecf20Sopenharmony_ci * Register your callback to claim an event. The event must be described
278c2ecf20Sopenharmony_ci * by firmware.
288c2ecf20Sopenharmony_ci */
298c2ecf20Sopenharmony_ciint sdei_event_register(u32 event_num, sdei_event_callback *cb, void *arg);
308c2ecf20Sopenharmony_ci
318c2ecf20Sopenharmony_ci/*
328c2ecf20Sopenharmony_ci * Calls to sdei_event_unregister() may return EINPROGRESS. Keep calling
338c2ecf20Sopenharmony_ci * it until it succeeds.
348c2ecf20Sopenharmony_ci */
358c2ecf20Sopenharmony_ciint sdei_event_unregister(u32 event_num);
368c2ecf20Sopenharmony_ci
378c2ecf20Sopenharmony_ciint sdei_event_enable(u32 event_num);
388c2ecf20Sopenharmony_ciint sdei_event_disable(u32 event_num);
398c2ecf20Sopenharmony_ci
408c2ecf20Sopenharmony_ci/* GHES register/unregister helpers */
418c2ecf20Sopenharmony_ciint sdei_register_ghes(struct ghes *ghes, sdei_event_callback *normal_cb,
428c2ecf20Sopenharmony_ci		       sdei_event_callback *critical_cb);
438c2ecf20Sopenharmony_ciint sdei_unregister_ghes(struct ghes *ghes);
448c2ecf20Sopenharmony_ci
458c2ecf20Sopenharmony_ci#ifdef CONFIG_ARM_SDE_INTERFACE
468c2ecf20Sopenharmony_ci/* For use by arch code when CPU hotplug notifiers are not appropriate. */
478c2ecf20Sopenharmony_ciint sdei_mask_local_cpu(void);
488c2ecf20Sopenharmony_ciint sdei_unmask_local_cpu(void);
498c2ecf20Sopenharmony_civoid __init sdei_init(void);
508c2ecf20Sopenharmony_civoid sdei_handler_abort(void);
518c2ecf20Sopenharmony_ci#else
528c2ecf20Sopenharmony_cistatic inline int sdei_mask_local_cpu(void) { return 0; }
538c2ecf20Sopenharmony_cistatic inline int sdei_unmask_local_cpu(void) { return 0; }
548c2ecf20Sopenharmony_cistatic inline void sdei_init(void) { }
558c2ecf20Sopenharmony_cistatic inline void sdei_handler_abort(void) { }
568c2ecf20Sopenharmony_ci#endif /* CONFIG_ARM_SDE_INTERFACE */
578c2ecf20Sopenharmony_ci
588c2ecf20Sopenharmony_ci
598c2ecf20Sopenharmony_ci/*
608c2ecf20Sopenharmony_ci * This struct represents an event that has been registered. The driver
618c2ecf20Sopenharmony_ci * maintains a list of all events, and which ones are registered. (Private
628c2ecf20Sopenharmony_ci * events have one entry in the list, but are registered on each CPU).
638c2ecf20Sopenharmony_ci * A pointer to this struct is passed to firmware, and back to the event
648c2ecf20Sopenharmony_ci * handler. The event handler can then use this to invoke the registered
658c2ecf20Sopenharmony_ci * callback, without having to walk the list.
668c2ecf20Sopenharmony_ci *
678c2ecf20Sopenharmony_ci * For CPU private events, this structure is per-cpu.
688c2ecf20Sopenharmony_ci */
698c2ecf20Sopenharmony_cistruct sdei_registered_event {
708c2ecf20Sopenharmony_ci	/* For use by arch code: */
718c2ecf20Sopenharmony_ci	struct pt_regs          interrupted_regs;
728c2ecf20Sopenharmony_ci
738c2ecf20Sopenharmony_ci	sdei_event_callback	*callback;
748c2ecf20Sopenharmony_ci	void			*callback_arg;
758c2ecf20Sopenharmony_ci	u32			 event_num;
768c2ecf20Sopenharmony_ci	u8			 priority;
778c2ecf20Sopenharmony_ci};
788c2ecf20Sopenharmony_ci
798c2ecf20Sopenharmony_ci/* The arch code entry point should then call this when an event arrives. */
808c2ecf20Sopenharmony_ciint notrace sdei_event_handler(struct pt_regs *regs,
818c2ecf20Sopenharmony_ci			       struct sdei_registered_event *arg);
828c2ecf20Sopenharmony_ci
838c2ecf20Sopenharmony_ci/* arch code may use this to retrieve the extra registers. */
848c2ecf20Sopenharmony_ciint sdei_api_event_context(u32 query, u64 *result);
858c2ecf20Sopenharmony_ci
868c2ecf20Sopenharmony_ci#endif /* __LINUX_ARM_SDEI_H */
87