usb: f_gsi: Ignore supsend/resume events if data interface is not selected

Usually the GSI disconnect handler is invoked on disconnect
and bus suspend (with remote wakeup disabled) conditions.
However, for functions such as MBIM that support alternate
data interface, suspend/resume handling becomes a no-op
if the data interface is not selected.

One such example is disabling/enabling network device from device manager
or host sending set_alt 0 before suspend. This operation explicitly
disables data interface, remains the state in STATE_CONNECT_IN_PROGRESS.
After that when set_alt 1 comes from the host ipa_work_handler does
enable the data interface in this state.

Hence post the disconnect event in set_alt 0 handling and
subsequent suspend/resume operations become no-ops.

Change-Id: Idaf240ed5253f61880c05a1b11d87d4979d474c9
Signed-off-by: Devdutt Patnaik <dpatnaik@codeaurora.org>
Signed-off-by: Chandana Kishori Chiluveru <cchiluve@codeaurora.org>
diff --git a/drivers/usb/gadget/function/f_gsi.c b/drivers/usb/gadget/function/f_gsi.c
index 5222f79..0065c06 100644
--- a/drivers/usb/gadget/function/f_gsi.c
+++ b/drivers/usb/gadget/function/f_gsi.c
@@ -2418,8 +2418,13 @@
 		if (alt == 0 && ((gsi->d_port.in_ep &&
 				!gsi->d_port.in_ep->driver_data) ||
 				(gsi->d_port.out_ep &&
-				!gsi->d_port.out_ep->driver_data)))
+				!gsi->d_port.out_ep->driver_data))) {
 			ipa_disconnect_handler(&gsi->d_port);
+			post_event(&gsi->d_port, EVT_DISCONNECTED);
+			queue_work(gsi->d_port.ipa_usb_wq,
+				&gsi->d_port.usb_ipa_w);
+			log_event_dbg("%s: Disconnecting\n", __func__);
+		}
 
 		gsi->data_interface_up = alt;
 		log_event_dbg("DATA_INTERFACE id = %d, status = %d",
@@ -2506,11 +2511,11 @@
 		return;
 	}
 
-	/*
-	 * GPS doesn't use any data interface, hence bail out as there is no
-	 * GSI specific handling needed.
+	/* For functions such as MBIM that support alternate data
+	 * interface, suspend/resume handling becomes a no-op if the
+	 * data interface is not selected.
 	 */
-	if (gsi->prot_id == USB_PROT_GPS_CTRL) {
+	if (!gsi->data_interface_up) {
 		log_event_dbg("%s: suspend done\n", __func__);
 		usb_gsi_check_pending_wakeup(f);
 		return;
@@ -2550,7 +2555,7 @@
 	/* Check any pending cpkt, and queue immediately on resume */
 	gsi_ctrl_send_notification(gsi);
 
-	if (gsi->prot_id == USB_PROT_GPS_CTRL) {
+	if (!gsi->data_interface_up) {
 		log_event_dbg("%s: resume done\n", __func__);
 		return;
 	}