@@ -200,9 +200,15 @@ static const struct rpmsg_endpoint_ops glink_endpoint_ops;
200
200
#define GLINK_CMD_TX_DATA_CONT 12
201
201
#define GLINK_CMD_READ_NOTIF 13
202
202
#define GLINK_CMD_RX_DONE_W_REUSE 14
203
+ #define GLINK_CMD_SIGNALS 15
203
204
204
205
#define GLINK_FEATURE_INTENTLESS BIT(1)
205
206
207
+ #define NATIVE_DTR_SIG NATIVE_DSR_SIG
208
+ #define NATIVE_DSR_SIG BIT(31)
209
+ #define NATIVE_RTS_SIG NATIVE_CTS_SIG
210
+ #define NATIVE_CTS_SIG BIT(30)
211
+
206
212
static void qcom_glink_rx_done_work (struct work_struct * work );
207
213
208
214
static struct glink_channel * qcom_glink_alloc_channel (struct qcom_glink * glink ,
@@ -1025,6 +1031,50 @@ static int qcom_glink_rx_open_ack(struct qcom_glink *glink, unsigned int lcid)
1025
1031
return 0 ;
1026
1032
}
1027
1033
1034
+ /**
1035
+ * qcom_glink_set_flow_control() - convert a signal cmd to wire format and transmit
1036
+ * @ept: Rpmsg endpoint for channel.
1037
+ * @pause: Pause transmission
1038
+ * @dst: destination address of the endpoint
1039
+ *
1040
+ * Return: 0 on success or standard Linux error code.
1041
+ */
1042
+ static int qcom_glink_set_flow_control (struct rpmsg_endpoint * ept , bool pause , u32 dst )
1043
+ {
1044
+ struct glink_channel * channel = to_glink_channel (ept );
1045
+ struct qcom_glink * glink = channel -> glink ;
1046
+ struct glink_msg msg ;
1047
+ u32 sigs = 0 ;
1048
+
1049
+ if (pause )
1050
+ sigs |= NATIVE_DTR_SIG | NATIVE_RTS_SIG ;
1051
+
1052
+ msg .cmd = cpu_to_le16 (GLINK_CMD_SIGNALS );
1053
+ msg .param1 = cpu_to_le16 (channel -> lcid );
1054
+ msg .param2 = cpu_to_le32 (sigs );
1055
+
1056
+ return qcom_glink_tx (glink , & msg , sizeof (msg ), NULL , 0 , true);
1057
+ }
1058
+
1059
+ static void qcom_glink_handle_signals (struct qcom_glink * glink ,
1060
+ unsigned int rcid , unsigned int sigs )
1061
+ {
1062
+ struct glink_channel * channel ;
1063
+ unsigned long flags ;
1064
+ bool enable ;
1065
+
1066
+ spin_lock_irqsave (& glink -> idr_lock , flags );
1067
+ channel = idr_find (& glink -> rcids , rcid );
1068
+ spin_unlock_irqrestore (& glink -> idr_lock , flags );
1069
+ if (!channel )
1070
+ dev_err (glink -> dev , "signal for non-existing channel\n" );
1071
+
1072
+ enable = sigs & NATIVE_DSR_SIG || sigs & NATIVE_CTS_SIG ;
1073
+
1074
+ if (channel -> ept .flow_cb )
1075
+ channel -> ept .flow_cb (channel -> ept .rpdev , channel -> ept .priv , enable );
1076
+ }
1077
+
1028
1078
void qcom_glink_native_rx (struct qcom_glink * glink )
1029
1079
{
1030
1080
struct glink_msg msg ;
@@ -1086,6 +1136,10 @@ void qcom_glink_native_rx(struct qcom_glink *glink)
1086
1136
qcom_glink_handle_intent_req_ack (glink , param1 , param2 );
1087
1137
qcom_glink_rx_advance (glink , ALIGN (sizeof (msg ), 8 ));
1088
1138
break ;
1139
+ case GLINK_CMD_SIGNALS :
1140
+ qcom_glink_handle_signals (glink , param1 , param2 );
1141
+ qcom_glink_rx_advance (glink , ALIGN (sizeof (msg ), 8 ));
1142
+ break ;
1089
1143
default :
1090
1144
dev_err (glink -> dev , "unhandled rx cmd: %d\n" , cmd );
1091
1145
ret = - EINVAL ;
@@ -1446,6 +1500,7 @@ static const struct rpmsg_endpoint_ops glink_endpoint_ops = {
1446
1500
.sendto = qcom_glink_sendto ,
1447
1501
.trysend = qcom_glink_trysend ,
1448
1502
.trysendto = qcom_glink_trysendto ,
1503
+ .set_flow_control = qcom_glink_set_flow_control ,
1449
1504
};
1450
1505
1451
1506
static void qcom_glink_rpdev_release (struct device * dev )
0 commit comments