@@ -728,12 +728,21 @@ static bool optee_ffa_exchange_caps(struct ffa_device *ffa_dev,
728
728
return true;
729
729
}
730
730
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
+
731
740
static void notif_callback (int notify_id , void * cb_data )
732
741
{
733
742
struct optee * optee = cb_data ;
734
743
735
744
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 );
737
746
else
738
747
optee_notif_send (optee , notify_id );
739
748
}
@@ -817,9 +826,11 @@ static void optee_ffa_remove(struct ffa_device *ffa_dev)
817
826
struct optee * optee = ffa_dev_get_drvdata (ffa_dev );
818
827
u32 bottom_half_id = optee -> ffa .bottom_half_value ;
819
828
820
- if (bottom_half_id != U32_MAX )
829
+ if (bottom_half_id != U32_MAX ) {
821
830
ffa_dev -> ops -> notifier_ops -> notify_relinquish (ffa_dev ,
822
831
bottom_half_id );
832
+ destroy_workqueue (optee -> ffa .notif_wq );
833
+ }
823
834
optee_remove_common (optee );
824
835
825
836
mutex_destroy (& optee -> ffa .mutex );
@@ -835,6 +846,13 @@ static int optee_ffa_async_notif_init(struct ffa_device *ffa_dev,
835
846
u32 notif_id = 0 ;
836
847
int rc ;
837
848
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
+
838
856
while (true) {
839
857
rc = ffa_dev -> ops -> notifier_ops -> notify_request (ffa_dev ,
840
858
is_per_vcpu ,
@@ -851,19 +869,24 @@ static int optee_ffa_async_notif_init(struct ffa_device *ffa_dev,
851
869
* notifications in that case.
852
870
*/
853
871
if (rc != - EACCES )
854
- return rc ;
872
+ goto err_wq ;
855
873
notif_id ++ ;
856
874
if (notif_id >= OPTEE_FFA_MAX_ASYNC_NOTIF_VALUE )
857
- return rc ;
875
+ goto err_wq ;
858
876
}
859
877
optee -> ffa .bottom_half_value = notif_id ;
860
878
861
879
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 ;
867
890
868
891
return rc ;
869
892
}
0 commit comments