diff options
Diffstat (limited to 'drivers/firmware/xilinx/zynqmp.c')
| -rw-r--r-- | drivers/firmware/xilinx/zynqmp.c | 66 | 
1 files changed, 65 insertions, 1 deletions
diff --git a/drivers/firmware/xilinx/zynqmp.c b/drivers/firmware/xilinx/zynqmp.c index 0dd117860b63..5e5b0bb2e4e0 100644 --- a/drivers/firmware/xilinx/zynqmp.c +++ b/drivers/firmware/xilinx/zynqmp.c @@ -23,6 +23,7 @@  #include <linux/hashtable.h>  #include <linux/firmware/xlnx-zynqmp.h> +#include <linux/firmware/xlnx-event-manager.h>  #include "zynqmp-debug.h"  /* Max HashMap Order for PM API feature check (1<<7 = 128) */ @@ -38,6 +39,8 @@  static bool feature_check_enabled;  static DEFINE_HASHTABLE(pm_api_features_map, PM_API_FEATURE_CHECK_MAX_ORDER); +static struct platform_device *em_dev; +  /**   * struct pm_api_feature_data - PM API Feature data   * @pm_api_id:		PM API Id, used as key to index into hashmap @@ -160,7 +163,7 @@ static noinline int do_fw_call_hvc(u64 arg0, u64 arg1, u64 arg2,   *   * Return: Returns status, either success or error+reason   */ -static int zynqmp_pm_feature(u32 api_id) +int zynqmp_pm_feature(const u32 api_id)  {  	int ret;  	u32 ret_payload[PAYLOAD_ARG_CNT]; @@ -197,6 +200,7 @@ static int zynqmp_pm_feature(u32 api_id)  	return ret;  } +EXPORT_SYMBOL_GPL(zynqmp_pm_feature);  /**   * zynqmp_pm_invoke_fn() - Invoke the system-level platform management layer @@ -1117,6 +1121,55 @@ int zynqmp_pm_aes_engine(const u64 address, u32 *out)  EXPORT_SYMBOL_GPL(zynqmp_pm_aes_engine);  /** + * zynqmp_pm_sha_hash - Access the SHA engine to calculate the hash + * @address:	Address of the data/ Address of output buffer where + *		hash should be stored. + * @size:	Size of the data. + * @flags: + *	BIT(0) - for initializing csudma driver and SHA3(Here address + *		 and size inputs can be NULL). + *	BIT(1) - to call Sha3_Update API which can be called multiple + *		 times when data is not contiguous. + *	BIT(2) - to get final hash of the whole updated data. + *		 Hash will be overwritten at provided address with + *		 48 bytes. + * + * Return:	Returns status, either success or error code. + */ +int zynqmp_pm_sha_hash(const u64 address, const u32 size, const u32 flags) +{ +	u32 lower_addr = lower_32_bits(address); +	u32 upper_addr = upper_32_bits(address); + +	return zynqmp_pm_invoke_fn(PM_SECURE_SHA, upper_addr, lower_addr, +				   size, flags, NULL); +} +EXPORT_SYMBOL_GPL(zynqmp_pm_sha_hash); + +/** + * zynqmp_pm_register_notifier() - PM API for register a subsystem + *                                to be notified about specific + *                                event/error. + * @node:	Node ID to which the event is related. + * @event:	Event Mask of Error events for which wants to get notified. + * @wake:	Wake subsystem upon capturing the event if value 1 + * @enable:	Enable the registration for value 1, disable for value 0 + * + * This function is used to register/un-register for particular node-event + * combination in firmware. + * + * Return: Returns status, either success or error+reason + */ + +int zynqmp_pm_register_notifier(const u32 node, const u32 event, +				const u32 wake, const u32 enable) +{ +	return zynqmp_pm_invoke_fn(PM_REGISTER_NOTIFIER, node, event, +				   wake, enable, NULL); +} +EXPORT_SYMBOL_GPL(zynqmp_pm_register_notifier); + +/**   * zynqmp_pm_system_shutdown - PM call to request a system shutdown or restart   * @type:	Shutdown or restart? 0 for shutdown, 1 for restart   * @subtype:	Specifies which system should be restarted or shut down @@ -1471,6 +1524,15 @@ static int zynqmp_firmware_probe(struct platform_device *pdev)  	zynqmp_pm_api_debugfs_init(); +	np = of_find_compatible_node(NULL, NULL, "xlnx,versal"); +	if (np) { +		em_dev = platform_device_register_data(&pdev->dev, "xlnx_event_manager", +						       -1, NULL, 0); +		if (IS_ERR(em_dev)) +			dev_err_probe(&pdev->dev, PTR_ERR(em_dev), "EM register fail with error\n"); +	} +	of_node_put(np); +  	return of_platform_populate(dev->of_node, NULL, NULL, dev);  } @@ -1488,6 +1550,8 @@ static int zynqmp_firmware_remove(struct platform_device *pdev)  		kfree(feature_data);  	} +	platform_device_unregister(em_dev); +  	return 0;  }  |