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