@@ -728,12 +728,21 @@ static bool optee_ffa_exchange_caps(struct ffa_device *ffa_dev,
728728 return true;
729729}
730730
731+ static void notif_work_fn (struct work_struct * work )
732+ {
733+ struct optee_ffa * optee_ffa = container_of (work , struct optee_ffa ,
734+ notif_work );
735+ struct optee * optee = container_of (optee_ffa , struct optee , ffa );
736+
737+ optee_do_bottom_half (optee -> ctx );
738+ }
739+
731740static void notif_callback (int notify_id , void * cb_data )
732741{
733742 struct optee * optee = cb_data ;
734743
735744 if (notify_id == optee -> ffa .bottom_half_value )
736- optee_do_bottom_half (optee -> ctx );
745+ queue_work (optee -> ffa . notif_wq , & optee -> ffa . notif_work );
737746 else
738747 optee_notif_send (optee , notify_id );
739748}
@@ -817,9 +826,11 @@ static void optee_ffa_remove(struct ffa_device *ffa_dev)
817826 struct optee * optee = ffa_dev_get_drvdata (ffa_dev );
818827 u32 bottom_half_id = optee -> ffa .bottom_half_value ;
819828
820- if (bottom_half_id != U32_MAX )
829+ if (bottom_half_id != U32_MAX ) {
821830 ffa_dev -> ops -> notifier_ops -> notify_relinquish (ffa_dev ,
822831 bottom_half_id );
832+ destroy_workqueue (optee -> ffa .notif_wq );
833+ }
823834 optee_remove_common (optee );
824835
825836 mutex_destroy (& optee -> ffa .mutex );
@@ -835,6 +846,13 @@ static int optee_ffa_async_notif_init(struct ffa_device *ffa_dev,
835846 u32 notif_id = 0 ;
836847 int rc ;
837848
849+ INIT_WORK (& optee -> ffa .notif_work , notif_work_fn );
850+ optee -> ffa .notif_wq = create_workqueue ("optee_notification" );
851+ if (!optee -> ffa .notif_wq ) {
852+ rc = - EINVAL ;
853+ goto err ;
854+ }
855+
838856 while (true) {
839857 rc = ffa_dev -> ops -> notifier_ops -> notify_request (ffa_dev ,
840858 is_per_vcpu ,
@@ -851,19 +869,24 @@ static int optee_ffa_async_notif_init(struct ffa_device *ffa_dev,
851869 * notifications in that case.
852870 */
853871 if (rc != - EACCES )
854- return rc ;
872+ goto err_wq ;
855873 notif_id ++ ;
856874 if (notif_id >= OPTEE_FFA_MAX_ASYNC_NOTIF_VALUE )
857- return rc ;
875+ goto err_wq ;
858876 }
859877 optee -> ffa .bottom_half_value = notif_id ;
860878
861879 rc = enable_async_notif (optee );
862- if (rc < 0 ) {
863- ffa_dev -> ops -> notifier_ops -> notify_relinquish (ffa_dev ,
864- notif_id );
865- optee -> ffa .bottom_half_value = U32_MAX ;
866- }
880+ if (rc < 0 )
881+ goto err_rel ;
882+
883+ return 0 ;
884+ err_rel :
885+ ffa_dev -> ops -> notifier_ops -> notify_relinquish (ffa_dev , notif_id );
886+ err_wq :
887+ destroy_workqueue (optee -> ffa .notif_wq );
888+ err :
889+ optee -> ffa .bottom_half_value = U32_MAX ;
867890
868891 return rc ;
869892}
0 commit comments