linux-stable/include/linux/firmware/xlnx-event-manager.h
Abhyuday Godhasara c7fdb2404f drivers: soc: xilinx: add xilinx event management driver
Xilinx event management driver provides an interface to subscribe or
unsubscribe for the event/callback supported by firmware. An agent can use
this driver to register for Error Event, Device Event and Suspend callback.
This driver only allows one agent per event to do registration. Driver will
return an error in case of multiple registration for the same event.

This driver gets notification from firmware through TF-A as SGI. During
initialization, event manager driver register handler for SGI used for
notification. It also provides SGI number info to TF-A by using
IOCTL_REGISTER_SGI call to TF-A.

After receiving notification from firmware, the driver makes an SMC call to
TF-A to get IPI data. From the IPI data provided by TF-A, event manager
identified the cause of event and forward that event/callback notification
to the respective subscribed driver. After this, in case of Error Event,
driver performs unregistration as firmware expecting from agent to do
re-registration if the agent wants to get notified on the second occurrence
of an error event.

Add new IOCTL id IOCTL_REGISTER_SGI = 25 which is used to register SGI on
TF-A.

Older firmware doesn't have all required support for event handling which
is required by the event manager driver. So add check for the register
notifier version in the event manager driver.

Xilinx event management driver provides support to subscribe for multiple
error events with the use of Event Mask in a single call of
xlnx_register_event(). Agent driver can provide 'Event' parameter value as
ORed of multiple event masks to register single callback for multiple
events. For example, to register callback for event=0x1 and event=0x2 for
the given node, agent can provide event=0x3 (0x1 | 0x2). It is not possible
to register multiple events for different nodes in a single registration
call.

Also provide support to receive multiple error events as in single
notification from firmware and then forward it to subscribed drivers via
registered callback one by one.

Acked-by: Michal Simek <michal.simek@xilinx.com>
Signed-off-by: Tejas Patel <tejas.patel@xilinx.com>
Signed-off-by: Rajan Vaja <rajan.vaja@xilinx.com>
Signed-off-by: Abhyuday Godhasara <abhyuday.godhasara@xilinx.com>
Link: https://lore.kernel.org/r/20211129070216.30253-2-abhyuday.godhasara@xilinx.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2021-12-03 16:08:46 +01:00

36 lines
1.1 KiB
C

/* SPDX-License-Identifier: GPL-2.0 */
#ifndef _FIRMWARE_XLNX_EVENT_MANAGER_H_
#define _FIRMWARE_XLNX_EVENT_MANAGER_H_
#include <linux/firmware/xlnx-zynqmp.h>
#define CB_MAX_PAYLOAD_SIZE (4U) /*In payload maximum 32bytes */
/************************** Exported Function *****************************/
typedef void (*event_cb_func_t)(const u32 *payload, void *data);
#if IS_REACHABLE(CONFIG_XLNX_EVENT_MANAGER)
int xlnx_register_event(const enum pm_api_cb_id cb_type, const u32 node_id,
const u32 event, const bool wake,
event_cb_func_t cb_fun, void *data);
int xlnx_unregister_event(const enum pm_api_cb_id cb_type, const u32 node_id,
const u32 event, event_cb_func_t cb_fun);
#else
static inline int xlnx_register_event(const enum pm_api_cb_id cb_type, const u32 node_id,
const u32 event, const bool wake,
event_cb_func_t cb_fun, void *data)
{
return -ENODEV;
}
static inline int xlnx_unregister_event(const enum pm_api_cb_id cb_type, const u32 node_id,
const u32 event, event_cb_func_t cb_fun)
{
return -ENODEV;
}
#endif
#endif /* _FIRMWARE_XLNX_EVENT_MANAGER_H_ */