@@ -200,6 +200,7 @@ struct qcom_smd_channel {
200
200
char * name ;
201
201
enum smd_channel_state state ;
202
202
enum smd_channel_state remote_state ;
203
+ wait_queue_head_t state_change_event ;
203
204
204
205
struct smd_channel_info_pair * info ;
205
206
struct smd_channel_info_word_pair * info_word ;
@@ -570,6 +571,8 @@ static bool qcom_smd_channel_intr(struct qcom_smd_channel *channel)
570
571
if (remote_state != channel -> remote_state ) {
571
572
channel -> remote_state = remote_state ;
572
573
need_state_scan = true;
574
+
575
+ wake_up_interruptible_all (& channel -> state_change_event );
573
576
}
574
577
/* Indicate that we have seen any state change */
575
578
SET_RX_CHANNEL_FLAG (channel , fSTATE , 0 );
@@ -786,7 +789,9 @@ static int __qcom_smd_send(struct qcom_smd_channel *channel, const void *data,
786
789
static int qcom_smd_channel_open (struct qcom_smd_channel * channel ,
787
790
rpmsg_rx_cb_t cb )
788
791
{
792
+ struct qcom_smd_edge * edge = channel -> edge ;
789
793
size_t bb_size ;
794
+ int ret ;
790
795
791
796
/*
792
797
* Packets are maximum 4k, but reduce if the fifo is smaller
@@ -798,9 +803,33 @@ static int qcom_smd_channel_open(struct qcom_smd_channel *channel,
798
803
799
804
qcom_smd_channel_set_callback (channel , cb );
800
805
qcom_smd_channel_set_state (channel , SMD_CHANNEL_OPENING );
806
+
807
+ /* Wait for remote to enter opening or opened */
808
+ ret = wait_event_interruptible_timeout (channel -> state_change_event ,
809
+ channel -> remote_state == SMD_CHANNEL_OPENING ||
810
+ channel -> remote_state == SMD_CHANNEL_OPENED ,
811
+ HZ );
812
+ if (!ret ) {
813
+ dev_err (& edge -> dev , "remote side did not enter opening state\n" );
814
+ goto out_close_timeout ;
815
+ }
816
+
801
817
qcom_smd_channel_set_state (channel , SMD_CHANNEL_OPENED );
802
818
819
+ /* Wait for remote to enter opened */
820
+ ret = wait_event_interruptible_timeout (channel -> state_change_event ,
821
+ channel -> remote_state == SMD_CHANNEL_OPENED ,
822
+ HZ );
823
+ if (!ret ) {
824
+ dev_err (& edge -> dev , "remote side did not enter open state\n" );
825
+ goto out_close_timeout ;
826
+ }
827
+
803
828
return 0 ;
829
+
830
+ out_close_timeout :
831
+ qcom_smd_channel_set_state (channel , SMD_CHANNEL_CLOSED );
832
+ return - ETIMEDOUT ;
804
833
}
805
834
806
835
/*
@@ -1055,6 +1084,7 @@ static struct qcom_smd_channel *qcom_smd_create_channel(struct qcom_smd_edge *ed
1055
1084
mutex_init (& channel -> tx_lock );
1056
1085
spin_lock_init (& channel -> recv_lock );
1057
1086
init_waitqueue_head (& channel -> fblockread_event );
1087
+ init_waitqueue_head (& channel -> state_change_event );
1058
1088
1059
1089
info = qcom_smem_get (edge -> remote_pid , smem_info_item , & info_size );
1060
1090
if (IS_ERR (info )) {
0 commit comments