@@ -2093,6 +2093,122 @@ static int qcom_scm_qseecom_init(struct qcom_scm *scm)
20932093
20942094#endif /* CONFIG_QCOM_QSEECOM */
20952095
2096+ /**
2097+ * qcom_scm_qtee_invoke_smc() - Invoke a QTEE object.
2098+ * @inbuf: start address of memory area used for inbound buffer.
2099+ * @inbuf_size: size of the memory area used for inbound buffer.
2100+ * @outbuf: start address of memory area used for outbound buffer.
2101+ * @outbuf_size: size of the memory area used for outbound buffer.
2102+ * @result: result of QTEE object invocation.
2103+ * @response_type: response type returned by QTEE.
2104+ *
2105+ * @response_type determines how the contents of @inbuf and @outbuf
2106+ * should be processed.
2107+ *
2108+ * Return: On success, return 0 or <0 on failure.
2109+ */
2110+ int qcom_scm_qtee_invoke_smc (phys_addr_t inbuf , size_t inbuf_size ,
2111+ phys_addr_t outbuf , size_t outbuf_size ,
2112+ u64 * result , u64 * response_type )
2113+ {
2114+ struct qcom_scm_desc desc = {
2115+ .svc = QCOM_SCM_SVC_SMCINVOKE ,
2116+ .cmd = QCOM_SCM_SMCINVOKE_INVOKE ,
2117+ .owner = ARM_SMCCC_OWNER_TRUSTED_OS ,
2118+ .args [0 ] = inbuf ,
2119+ .args [1 ] = inbuf_size ,
2120+ .args [2 ] = outbuf ,
2121+ .args [3 ] = outbuf_size ,
2122+ .arginfo = QCOM_SCM_ARGS (4 , QCOM_SCM_RW , QCOM_SCM_VAL ,
2123+ QCOM_SCM_RW , QCOM_SCM_VAL ),
2124+ };
2125+ struct qcom_scm_res res ;
2126+ int ret ;
2127+
2128+ ret = qcom_scm_call (__scm -> dev , & desc , & res );
2129+ if (ret )
2130+ return ret ;
2131+
2132+ if (response_type )
2133+ * response_type = res .result [0 ];
2134+
2135+ if (result )
2136+ * result = res .result [1 ];
2137+
2138+ return 0 ;
2139+ }
2140+ EXPORT_SYMBOL (qcom_scm_qtee_invoke_smc );
2141+
2142+ /**
2143+ * qcom_scm_qtee_callback_response() - Submit response for callback request.
2144+ * @buf: start address of memory area used for outbound buffer.
2145+ * @buf_size: size of the memory area used for outbound buffer.
2146+ * @result: Result of QTEE object invocation.
2147+ * @response_type: Response type returned by QTEE.
2148+ *
2149+ * @response_type determines how the contents of @buf should be processed.
2150+ *
2151+ * Return: On success, return 0 or <0 on failure.
2152+ */
2153+ int qcom_scm_qtee_callback_response (phys_addr_t buf , size_t buf_size ,
2154+ u64 * result , u64 * response_type )
2155+ {
2156+ struct qcom_scm_desc desc = {
2157+ .svc = QCOM_SCM_SVC_SMCINVOKE ,
2158+ .cmd = QCOM_SCM_SMCINVOKE_CB_RSP ,
2159+ .owner = ARM_SMCCC_OWNER_TRUSTED_OS ,
2160+ .args [0 ] = buf ,
2161+ .args [1 ] = buf_size ,
2162+ .arginfo = QCOM_SCM_ARGS (2 , QCOM_SCM_RW , QCOM_SCM_VAL ),
2163+ };
2164+ struct qcom_scm_res res ;
2165+ int ret ;
2166+
2167+ ret = qcom_scm_call (__scm -> dev , & desc , & res );
2168+ if (ret )
2169+ return ret ;
2170+
2171+ if (response_type )
2172+ * response_type = res .result [0 ];
2173+
2174+ if (result )
2175+ * result = res .result [1 ];
2176+
2177+ return 0 ;
2178+ }
2179+ EXPORT_SYMBOL (qcom_scm_qtee_callback_response );
2180+
2181+ static void qcom_scm_qtee_free (void * data )
2182+ {
2183+ struct platform_device * qtee_dev = data ;
2184+
2185+ platform_device_unregister (qtee_dev );
2186+ }
2187+
2188+ static void qcom_scm_qtee_init (struct qcom_scm * scm )
2189+ {
2190+ struct platform_device * qtee_dev ;
2191+ u64 result , response_type ;
2192+ int ret ;
2193+
2194+ /*
2195+ * Probe for smcinvoke support. This will fail due to invalid buffers,
2196+ * but first, it checks whether the call is supported in QTEE syscall
2197+ * handler. If it is not supported, -EIO is returned.
2198+ */
2199+ ret = qcom_scm_qtee_invoke_smc (0 , 0 , 0 , 0 , & result , & response_type );
2200+ if (ret == - EIO )
2201+ return ;
2202+
2203+ /* Setup QTEE interface device. */
2204+ qtee_dev = platform_device_register_data (scm -> dev , "qcomtee" ,
2205+ PLATFORM_DEVID_NONE , NULL , 0 );
2206+ if (IS_ERR (qtee_dev ))
2207+ return ;
2208+
2209+ devm_add_action_or_reset (scm -> dev , qcom_scm_qtee_free , qtee_dev );
2210+ }
2211+
20962212/**
20972213 * qcom_scm_is_available() - Checks if SCM is available
20982214 */
@@ -2325,6 +2441,9 @@ static int qcom_scm_probe(struct platform_device *pdev)
23252441 ret = qcom_scm_qseecom_init (scm );
23262442 WARN (ret < 0 , "failed to initialize qseecom: %d\n" , ret );
23272443
2444+ /* Initialize the QTEE object interface. */
2445+ qcom_scm_qtee_init (scm );
2446+
23282447 return 0 ;
23292448}
23302449
0 commit comments