1010#define pr_fmt (fmt ) "CRB_FFA: " fmt
1111
1212#include <linux/arm_ffa.h>
13+ #include <linux/delay.h>
14+ #include <linux/moduleparam.h>
1315#include "tpm_crb_ffa.h"
1416
17+ static unsigned int busy_timeout_ms = 2000 ;
18+
19+ module_param (busy_timeout_ms , uint , 0644 );
20+ MODULE_PARM_DESC (busy_timeout_ms ,
21+ "Maximum time in ms to retry before giving up on busy" );
22+
1523/* TPM service function status codes */
1624#define CRB_FFA_OK 0x05000001
1725#define CRB_FFA_OK_RESULTS_RETURNED 0x05000002
@@ -115,6 +123,7 @@ struct tpm_crb_ffa {
115123};
116124
117125static struct tpm_crb_ffa * tpm_crb_ffa ;
126+ static struct ffa_driver tpm_crb_ffa_driver ;
118127
119128static int tpm_crb_ffa_to_linux_errno (int errno )
120129{
@@ -168,57 +177,85 @@ static int tpm_crb_ffa_to_linux_errno(int errno)
168177 */
169178int tpm_crb_ffa_init (void )
170179{
180+ int ret = 0 ;
181+
182+ if (!IS_MODULE (CONFIG_TCG_ARM_CRB_FFA )) {
183+ ret = ffa_register (& tpm_crb_ffa_driver );
184+ if (ret ) {
185+ tpm_crb_ffa = ERR_PTR (- ENODEV );
186+ return ret ;
187+ }
188+ }
189+
171190 if (!tpm_crb_ffa )
172- return - ENOENT ;
191+ ret = - ENOENT ;
173192
174193 if (IS_ERR_VALUE (tpm_crb_ffa ))
175- return - ENODEV ;
194+ ret = - ENODEV ;
176195
177- return 0 ;
196+ return ret ;
178197}
179198EXPORT_SYMBOL_GPL (tpm_crb_ffa_init );
180199
181- static int __tpm_crb_ffa_send_recieve (unsigned long func_id ,
182- unsigned long a0 ,
183- unsigned long a1 ,
184- unsigned long a2 )
200+ static int __tpm_crb_ffa_try_send_receive (unsigned long func_id ,
201+ unsigned long a0 , unsigned long a1 ,
202+ unsigned long a2 )
185203{
186204 const struct ffa_msg_ops * msg_ops ;
187205 int ret ;
188206
189- if (!tpm_crb_ffa )
190- return - ENOENT ;
191-
192207 msg_ops = tpm_crb_ffa -> ffa_dev -> ops -> msg_ops ;
193208
194209 if (ffa_partition_supports_direct_req2_recv (tpm_crb_ffa -> ffa_dev )) {
195- memset (& tpm_crb_ffa -> direct_msg_data2 , 0x00 ,
196- sizeof (struct ffa_send_direct_data2 ));
197-
198- tpm_crb_ffa -> direct_msg_data2 .data [0 ] = func_id ;
199- tpm_crb_ffa -> direct_msg_data2 .data [1 ] = a0 ;
200- tpm_crb_ffa -> direct_msg_data2 .data [2 ] = a1 ;
201- tpm_crb_ffa -> direct_msg_data2 .data [3 ] = a2 ;
210+ tpm_crb_ffa -> direct_msg_data2 = (struct ffa_send_direct_data2 ){
211+ .data = { func_id , a0 , a1 , a2 },
212+ };
202213
203214 ret = msg_ops -> sync_send_receive2 (tpm_crb_ffa -> ffa_dev ,
204215 & tpm_crb_ffa -> direct_msg_data2 );
205216 if (!ret )
206217 ret = tpm_crb_ffa_to_linux_errno (tpm_crb_ffa -> direct_msg_data2 .data [0 ]);
207218 } else {
208- memset (& tpm_crb_ffa -> direct_msg_data , 0x00 ,
209- sizeof (struct ffa_send_direct_data ));
210-
211- tpm_crb_ffa -> direct_msg_data .data1 = func_id ;
212- tpm_crb_ffa -> direct_msg_data .data2 = a0 ;
213- tpm_crb_ffa -> direct_msg_data .data3 = a1 ;
214- tpm_crb_ffa -> direct_msg_data .data4 = a2 ;
219+ tpm_crb_ffa -> direct_msg_data = (struct ffa_send_direct_data ){
220+ .data1 = func_id ,
221+ .data2 = a0 ,
222+ .data3 = a1 ,
223+ .data4 = a2 ,
224+ };
215225
216226 ret = msg_ops -> sync_send_receive (tpm_crb_ffa -> ffa_dev ,
217227 & tpm_crb_ffa -> direct_msg_data );
218228 if (!ret )
219229 ret = tpm_crb_ffa_to_linux_errno (tpm_crb_ffa -> direct_msg_data .data1 );
220230 }
221231
232+ return ret ;
233+ }
234+
235+ static int __tpm_crb_ffa_send_receive (unsigned long func_id , unsigned long a0 ,
236+ unsigned long a1 , unsigned long a2 )
237+ {
238+ ktime_t start , stop ;
239+ int ret ;
240+
241+ if (!tpm_crb_ffa )
242+ return - ENOENT ;
243+
244+ start = ktime_get ();
245+ stop = ktime_add (start , ms_to_ktime (busy_timeout_ms ));
246+
247+ for (;;) {
248+ ret = __tpm_crb_ffa_try_send_receive (func_id , a0 , a1 , a2 );
249+ if (ret != - EBUSY )
250+ break ;
251+
252+ usleep_range (50 , 100 );
253+ if (ktime_after (ktime_get (), stop )) {
254+ dev_warn (& tpm_crb_ffa -> ffa_dev -> dev ,
255+ "Busy retry timed out\n" );
256+ break ;
257+ }
258+ }
222259
223260 return ret ;
224261}
@@ -236,7 +273,7 @@ static int __tpm_crb_ffa_send_recieve(unsigned long func_id,
236273 *
237274 * Return: 0 on success, negative error code on failure.
238275 */
239- int tpm_crb_ffa_get_interface_version (u16 * major , u16 * minor )
276+ static int tpm_crb_ffa_get_interface_version (u16 * major , u16 * minor )
240277{
241278 int rc ;
242279
@@ -251,7 +288,7 @@ int tpm_crb_ffa_get_interface_version(u16 *major, u16 *minor)
251288
252289 guard (mutex )(& tpm_crb_ffa -> msg_data_lock );
253290
254- rc = __tpm_crb_ffa_send_recieve (CRB_FFA_GET_INTERFACE_VERSION , 0x00 , 0x00 , 0x00 );
291+ rc = __tpm_crb_ffa_send_receive (CRB_FFA_GET_INTERFACE_VERSION , 0x00 , 0x00 , 0x00 );
255292 if (!rc ) {
256293 if (ffa_partition_supports_direct_req2_recv (tpm_crb_ffa -> ffa_dev )) {
257294 * major = CRB_FFA_MAJOR_VERSION (tpm_crb_ffa -> direct_msg_data2 .data [1 ]);
@@ -264,7 +301,6 @@ int tpm_crb_ffa_get_interface_version(u16 *major, u16 *minor)
264301
265302 return rc ;
266303}
267- EXPORT_SYMBOL_GPL (tpm_crb_ffa_get_interface_version );
268304
269305/**
270306 * tpm_crb_ffa_start() - signals the TPM that a field has changed in the CRB
@@ -289,7 +325,7 @@ int tpm_crb_ffa_start(int request_type, int locality)
289325
290326 guard (mutex )(& tpm_crb_ffa -> msg_data_lock );
291327
292- return __tpm_crb_ffa_send_recieve (CRB_FFA_START , request_type , locality , 0x00 );
328+ return __tpm_crb_ffa_send_receive (CRB_FFA_START , request_type , locality , 0x00 );
293329}
294330EXPORT_SYMBOL_GPL (tpm_crb_ffa_start );
295331
@@ -369,7 +405,9 @@ static struct ffa_driver tpm_crb_ffa_driver = {
369405 .id_table = tpm_crb_ffa_device_id ,
370406};
371407
408+ #ifdef MODULE
372409module_ffa_driver (tpm_crb_ffa_driver );
410+ #endif
373411
374412MODULE_AUTHOR ("Arm" );
375413MODULE_DESCRIPTION ("TPM CRB FFA driver" );
0 commit comments