diag: hsic: Fix improper opening/closing of diag_bridge

diag_bridge_open/close should not be called multiple times, as it
would incorrectly increase/decrease the internal reference counter.
This could respectively lead to either a stale device structure when
HSIC is disconnected, or a NULL pointer when HSIC is reconnected.

Fix this by adding a check in the bridge open routine to disallow
further calls if the bridge is already open, and similarly in close
to no-op if the bridge isn't open. Also add a mutex to the diagfwd
driver to serialize access to the various state variables such as
hsic_device_enabled and hsic_device_opened and to prevent near-
simultaneous calls to diag_bridge_open. In particular, the platform
device probe (or remove) and the callback for cable connect
(disconnect) could potentially execute concurrently; only one should
"win" calling diag_bridge_open (or close) successfully.

CRs-fixed: 395637
Change-Id: I5674285065cd63f89bf657cad770f04d53efb247
Signed-off-by: Jack Pham <jackp@codeaurora.org>
diff --git a/drivers/usb/misc/diag_bridge.c b/drivers/usb/misc/diag_bridge.c
index cad411d..b1b7763 100644
--- a/drivers/usb/misc/diag_bridge.c
+++ b/drivers/usb/misc/diag_bridge.c
@@ -60,6 +60,11 @@
 		return -ENODEV;
 	}
 
+	if (dev->ops) {
+		pr_err("bridge already opened");
+		return -EALREADY;
+	}
+
 	dev->ops = ops;
 	dev->err = 0;
 
@@ -82,6 +87,16 @@
 {
 	struct diag_bridge	*dev = __dev;
 
+	if (!dev) {
+		pr_err("dev is null");
+		return;
+	}
+
+	if (!dev->ops) {
+		pr_err("can't close bridge that was not open");
+		return;
+	}
+
 	dev_dbg(&dev->ifc->dev, "%s:\n", __func__);
 
 	usb_kill_anchored_urbs(&dev->submitted);