USB: gadget: Add HSUART transport for RMNET & DUN

HSUART transport can be used for communication
between MSM and MDM. Modify RMNET & DUN drivers to
support communication over HSUART transport.

CRs-Fixed: 355162
Change-Id: Idad2ab1b32d873cc055436537eed1715c92ceb90
Signed-off-by: Vijayavardhan Vennapusa <vvreddy@codeaurora.org>
Signed-off-by: Chiranjeevi Velempati <cvelempa@codeaurora.org>
diff --git a/drivers/usb/gadget/f_serial.c b/drivers/usb/gadget/f_serial.c
index 8d9f090..08a1712 100644
--- a/drivers/usb/gadget/f_serial.c
+++ b/drivers/usb/gadget/f_serial.c
@@ -27,7 +27,7 @@
  * CDC ACM driver.  However, for many purposes it's just as functional
  * if you can arrange appropriate host side drivers.
  */
-#define GSERIAL_NO_PORTS 2
+#define GSERIAL_NO_PORTS 3
 
 
 struct f_gser {
@@ -67,6 +67,7 @@
 static unsigned int no_sdio_ports;
 static unsigned int no_smd_ports;
 static unsigned int no_hsic_sports;
+static unsigned int no_hsuart_sports;
 static unsigned int nr_ports;
 
 static struct port_info {
@@ -249,9 +250,9 @@
 	int i;
 
 	pr_debug("%s: no_tty_ports: %u no_sdio_ports: %u"
-		" no_smd_ports: %u no_hsic_sports: %u nr_ports: %u\n",
+		" no_smd_ports: %u no_hsic_sports: %u no_hsuart_ports: %u nr_ports: %u\n",
 			__func__, no_tty_ports, no_sdio_ports, no_smd_ports,
-			no_hsic_sports, nr_ports);
+			no_hsic_sports, no_hsuart_sports, nr_ports);
 
 	if (no_tty_ports)
 		ret = gserial_setup(c->cdev->gadget, no_tty_ports);
@@ -278,6 +279,22 @@
 			return ret;
 		return 0;
 	}
+	if (no_hsuart_sports) {
+		port_idx = ghsuart_data_setup(no_hsuart_sports,
+					USB_GADGET_SERIAL);
+		if (port_idx < 0)
+			return port_idx;
+
+		for (i = 0; i < nr_ports; i++) {
+			if (gserial_ports[i].transport ==
+					USB_GADGET_XPORT_HSUART) {
+				gserial_ports[i].client_port_num = port_idx;
+				port_idx++;
+			}
+		}
+
+		return 0;
+	}
 	return ret;
 }
 
@@ -317,6 +334,14 @@
 			return ret;
 		}
 		break;
+	case USB_GADGET_XPORT_HSUART:
+		ret = ghsuart_data_connect(&gser->port, port_num);
+		if (ret) {
+			pr_err("%s: ghsuart_data_connect failed: err:%d\n",
+					__func__, ret);
+			return ret;
+		}
+		break;
 	default:
 		pr_err("%s: Un-supported transport: %s\n", __func__,
 				xport_to_str(gser->transport));
@@ -350,6 +375,9 @@
 		ghsic_ctrl_disconnect(&gser->port, port_num);
 		ghsic_data_disconnect(&gser->port, port_num);
 		break;
+	case USB_GADGET_XPORT_HSUART:
+		ghsuart_data_disconnect(&gser->port, port_num);
+		break;
 	default:
 		pr_err("%s: Un-supported transport:%s\n", __func__,
 				xport_to_str(gser->transport));
@@ -854,11 +882,13 @@
 	gser->port.func.disable = gser_disable;
 	gser->transport		= gserial_ports[port_num].transport;
 #ifdef CONFIG_MODEM_SUPPORT
-	/* We support only two ports for now */
+	/* We support only three ports for now */
 	if (port_num == 0)
 		gser->port.func.name = "modem";
-	else
+	else if (port_num == 1)
 		gser->port.func.name = "nmea";
+	else
+		gser->port.func.name = "modem2";
 	gser->port.func.setup = gser_setup;
 	gser->port.connect = gser_connect;
 	gser->port.get_dtr = gser_get_dtr;
@@ -910,6 +940,10 @@
 		/*client port number will be updated in gport_setup*/
 		no_hsic_sports++;
 		break;
+	case USB_GADGET_XPORT_HSUART:
+		/*client port number will be updated in gport_setup*/
+		no_hsuart_sports++;
+		break;
 	default:
 		pr_err("%s: Un-supported transport transport: %u\n",
 				__func__, gserial_ports[port_num].transport);