usb: Add mutex to usb_enable

The purpose of this commit is to prevent user from
calling usb_enable() twice from different contexes.

If for example user configures composite device with hid
and USB uart console (CONFIG_USB_UART_CONSOLE=y)
then introduced mutex will prevent from calling
usb_enable twice and thus lead to undefined behaviour of
usb driver controller.

usb_enable shall always be called once as it refers to usb driver
and for now only one USB driver instance is supported in Zephyr.
This mechanism ensures that.

Signed-off-by: Emil Obalski <emil.obalski@nordicsemi.no>
diff --git a/subsys/usb/usb_device.c b/subsys/usb/usb_device.c
index 0a7fba6..6cbda2c 100644
--- a/subsys/usb/usb_device.c
+++ b/subsys/usb/usb_device.c
@@ -110,6 +110,8 @@
 extern struct usb_cfg_data __usb_data_start[];
 extern struct usb_cfg_data __usb_data_end[];
 
+K_MUTEX_DEFINE(usb_enable_lock);
+
 struct usb_transfer_data {
 	/** endpoint associated to the transfer */
 	u8_t ep;
@@ -1537,14 +1539,21 @@
 	u32_t i;
 	struct usb_dc_ep_cfg_data ep0_cfg;
 
+	/* Prevent from calling usb_enable form different contex.
+	 * This should only be called once.
+	 */
+	LOG_DBG("lock usb_enable_lock mutex");
+	k_mutex_lock(&usb_enable_lock, K_FOREVER);
+
 	if (usb_dev.enabled == true) {
-		return 0;
+		ret = 0;
+		goto out;
 	}
 
 	/* Enable VBUS if needed */
 	ret = usb_vbus_set(true);
 	if (ret < 0) {
-		return ret;
+		goto out;
 	}
 
 	usb_register_status_callback(forward_status_cb);
@@ -1552,7 +1561,7 @@
 
 	ret = usb_dc_attach();
 	if (ret < 0) {
-		return ret;
+		goto out;
 	}
 
 	/* Configure control EP */
@@ -1562,32 +1571,32 @@
 	ep0_cfg.ep_addr = USB_CONTROL_OUT_EP0;
 	ret = usb_dc_ep_configure(&ep0_cfg);
 	if (ret < 0) {
-		return ret;
+		goto out;
 	}
 
 	ep0_cfg.ep_addr = USB_CONTROL_IN_EP0;
 	ret = usb_dc_ep_configure(&ep0_cfg);
 	if (ret < 0) {
-		return ret;
+		goto out;
 	}
 
 	/* Register endpoint 0 handlers*/
 	ret = usb_dc_ep_set_callback(USB_CONTROL_OUT_EP0,
 				     usb_handle_control_transfer);
 	if (ret < 0) {
-		return ret;
+		goto out;
 	}
 
 	ret = usb_dc_ep_set_callback(USB_CONTROL_IN_EP0,
 				     usb_handle_control_transfer);
 	if (ret < 0) {
-		return ret;
+		goto out;
 	}
 
 	/* Register endpoint handlers*/
 	ret = composite_setup_ep_cb();
 	if (ret < 0) {
-		return ret;
+		goto out;
 	}
 
 	/* Init transfer slots */
@@ -1599,17 +1608,20 @@
 	/* Enable control EP */
 	ret = usb_dc_ep_enable(USB_CONTROL_OUT_EP0);
 	if (ret < 0) {
-		return ret;
+		goto out;
 	}
 
 	ret = usb_dc_ep_enable(USB_CONTROL_IN_EP0);
 	if (ret < 0) {
-		return ret;
+		goto out;
 	}
 
 	usb_dev.enabled = true;
-
-	return 0;
+	ret = 0;
+out:
+	LOG_DBG("unlock usb_enable_lock mutex");
+	k_mutex_unlock(&usb_enable_lock);
+	return ret;
 }
 
 /*