10c9fd821SClément Léger // SPDX-License-Identifier: GPL-2.0-or-later 20c9fd821SClément Léger /* 30c9fd821SClément Léger * Copyright (C) 2022, Microchip 40c9fd821SClément Léger */ 50c9fd821SClément Léger 60c9fd821SClément Léger #include <linux/arm-smccc.h> 70c9fd821SClément Léger #include <linux/of.h> 80c9fd821SClément Léger 90c9fd821SClément Léger #include "sam_secure.h" 100c9fd821SClément Léger 110c9fd821SClément Léger static bool optee_available; 120c9fd821SClément Léger 130c9fd821SClément Léger #define SAM_SIP_SMC_STD_CALL_VAL(func_num) \ 140c9fd821SClément Léger ARM_SMCCC_CALL_VAL(ARM_SMCCC_STD_CALL, ARM_SMCCC_SMC_32, \ 150c9fd821SClément Léger ARM_SMCCC_OWNER_SIP, (func_num)) 160c9fd821SClément Léger 170c9fd821SClément Léger struct arm_smccc_res sam_smccc_call(u32 fn, u32 arg0, u32 arg1) 180c9fd821SClément Léger { 190c9fd821SClément Léger struct arm_smccc_res res = {.a0 = -1}; 200c9fd821SClément Léger 210c9fd821SClément Léger if (WARN_ON(!optee_available)) 220c9fd821SClément Léger return res; 230c9fd821SClément Léger 240c9fd821SClément Léger arm_smccc_smc(SAM_SIP_SMC_STD_CALL_VAL(fn), arg0, arg1, 0, 0, 0, 0, 0, 250c9fd821SClément Léger &res); 260c9fd821SClément Léger 270c9fd821SClément Léger return res; 280c9fd821SClément Léger } 290c9fd821SClément Léger 30*c71572aaSClément Léger bool sam_linux_is_optee_available(void) 31*c71572aaSClément Léger { 32*c71572aaSClément Léger /* If optee has been detected, then we are running in normal world */ 33*c71572aaSClément Léger return optee_available; 34*c71572aaSClément Léger } 35*c71572aaSClément Léger 360c9fd821SClément Léger void __init sam_secure_init(void) 370c9fd821SClément Léger { 380c9fd821SClément Léger struct device_node *np; 390c9fd821SClément Léger 400c9fd821SClément Léger /* 410c9fd821SClément Léger * We only check that the OP-TEE node is present and available. The 420c9fd821SClément Léger * OP-TEE kernel driver is not needed for the type of interaction made 430c9fd821SClément Léger * with OP-TEE here so the driver's status is not checked. 440c9fd821SClément Léger */ 450c9fd821SClément Léger np = of_find_node_by_path("/firmware/optee"); 460c9fd821SClément Léger if (np && of_device_is_available(np)) 470c9fd821SClément Léger optee_available = true; 480c9fd821SClément Léger of_node_put(np); 490c9fd821SClément Léger 500c9fd821SClément Léger if (optee_available) 510c9fd821SClément Léger pr_info("Running under OP-TEE firmware\n"); 520c9fd821SClément Léger } 53