Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

firmware: xilinx: Add TF_A_PM_REGISTER_SGI SMC call

SGI interrupt register and reset is performed by EEMI ioctl
IOCTL_REGISTER_SGI. However, this is not correct use of EEMI call.
SGI registration functionality does not qualify as energy management
activity and so shouldn't be mapped to EEMI call.

This new call will replace IOCTL_REGISTER_SGI and will be handled by TF-A
specific handler in TF-A. To maintain backward compatibility for a while
firmware driver will still use IOCTL_REGISTER_SGI as fallback strategy if
new call fails or is not supported by TF-A.

This new design also helps to make TF-A as pass through layer for EEMI
calls. So we don't have to maintain PM_IOCTL as EEMI API ID in TF-A.

Signed-off-by: Tanmay Shah <tanmay.shah@xilinx.com>
Acked-by: Michal Simek <michal.simek@amd.com>
Link: https://lore.kernel.org/r/20220607224253.54919-1-tanmay.shah@xilinx.com
Signed-off-by: Michal Simek <michal.simek@amd.com>

authored by

Tanmay Shah and committed by
Michal Simek
acd6510d f2906aa8

+24 -4
+15 -1
drivers/firmware/xilinx/zynqmp.c
··· 2 2 /* 3 3 * Xilinx Zynq MPSoC Firmware layer 4 4 * 5 - * Copyright (C) 2014-2021 Xilinx, Inc. 5 + * Copyright (C) 2014-2022 Xilinx, Inc. 6 6 * 7 7 * Michal Simek <michal.simek@xilinx.com> 8 8 * Davorin Mista <davorin.mista@aggios.com> ··· 339 339 340 340 static u32 pm_api_version; 341 341 static u32 pm_tz_version; 342 + 343 + int zynqmp_pm_register_sgi(u32 sgi_num, u32 reset) 344 + { 345 + int ret; 346 + 347 + ret = zynqmp_pm_invoke_fn(TF_A_PM_REGISTER_SGI, sgi_num, reset, 0, 0, 348 + NULL); 349 + if (!ret) 350 + return ret; 351 + 352 + /* try old implementation as fallback strategy if above fails */ 353 + return zynqmp_pm_invoke_fn(PM_IOCTL, 0, IOCTL_REGISTER_SGI, sgi_num, 354 + reset, NULL); 355 + } 342 356 343 357 /** 344 358 * zynqmp_pm_get_api_version() - Get version number of PMU PM firmware
+2 -3
drivers/soc/xilinx/xlnx_event_manager.c
··· 647 647 cpuhp_setup_state(CPUHP_AP_ONLINE_DYN, "soc/event:starting", 648 648 xlnx_event_cpuhp_start, xlnx_event_cpuhp_down); 649 649 650 - ret = zynqmp_pm_invoke_fn(PM_IOCTL, 0, IOCTL_REGISTER_SGI, sgi_num, 651 - 0, NULL); 650 + ret = zynqmp_pm_register_sgi(sgi_num, 0); 652 651 if (ret) { 653 652 dev_err(&pdev->dev, "SGI %d Registration over TF-A failed with %d\n", sgi_num, ret); 654 653 xlnx_event_cleanup_sgi(pdev); ··· 680 681 kfree(eve_data); 681 682 } 682 683 683 - ret = zynqmp_pm_invoke_fn(PM_IOCTL, 0, IOCTL_REGISTER_SGI, 0, 1, NULL); 684 + ret = zynqmp_pm_register_sgi(0, 1); 684 685 if (ret) 685 686 dev_err(&pdev->dev, "SGI unregistration over TF-A failed with %d\n", ret); 686 687
+7
include/linux/firmware/xlnx-zynqmp.h
··· 34 34 #define PM_API_VERSION_2 2 35 35 36 36 /* ATF only commands */ 37 + #define TF_A_PM_REGISTER_SGI 0xa04 37 38 #define PM_GET_TRUSTZONE_VERSION 0xa03 38 39 #define PM_SET_SUSPEND_MODE 0xa02 39 40 #define GET_CALLBACK_DATA 0xa01 ··· 469 468 int zynqmp_pm_is_function_supported(const u32 api_id, const u32 id); 470 469 int zynqmp_pm_set_feature_config(enum pm_feature_config_id id, u32 value); 471 470 int zynqmp_pm_get_feature_config(enum pm_feature_config_id id, u32 *payload); 471 + int zynqmp_pm_register_sgi(u32 sgi_num, u32 reset); 472 472 #else 473 473 static inline int zynqmp_pm_get_api_version(u32 *version) 474 474 { ··· 732 730 733 731 static inline int zynqmp_pm_get_feature_config(enum pm_feature_config_id id, 734 732 u32 *payload) 733 + { 734 + return -ENODEV; 735 + } 736 + 737 + static inline int zynqmp_pm_register_sgi(u32 sgi_num, u32 reset) 735 738 { 736 739 return -ENODEV; 737 740 }