usb: dwc3-msm: Do dwc3_msm_gadget_vbus_draw() in sleepable context

The gadget mode notification to draw a specific current may
occur in context with interrupts disabled, however the charger
driver's implementation of power_supply_set_property() for
POWER_SUPPLY_CURRENT_MAX currently uses a mutex. Since
sleeping is disallowed in this case, instead schedule a
work function to do the call.

Change-Id: I810ad8c102124ce22de72d83b6df58c8fc991251
Signed-off-by: Jack Pham <jackp@codeaurora.org>
Signed-off-by: Mayank Rana <mrana@codeaurora.org>
diff --git a/drivers/usb/dwc3/dwc3-msm.c b/drivers/usb/dwc3/dwc3-msm.c
index bee16ac..ea36f41 100644
--- a/drivers/usb/dwc3/dwc3-msm.c
+++ b/drivers/usb/dwc3/dwc3-msm.c
@@ -186,6 +186,7 @@
 	u32			bus_perf_client;
 	struct msm_bus_scale_pdata	*bus_scale_table;
 	struct power_supply	*usb_psy;
+	struct work_struct	vbus_draw_work;
 	bool			in_host_mode;
 	unsigned int		tx_fifo_size;
 	bool			vbus_active;
@@ -1585,6 +1586,15 @@
 
 }
 
+static void dwc3_msm_vbus_draw_work(struct work_struct *w)
+{
+	struct dwc3_msm *mdwc = container_of(w, struct dwc3_msm,
+			vbus_draw_work);
+	struct dwc3 *dwc = platform_get_drvdata(mdwc->dwc3);
+
+	dwc3_msm_gadget_vbus_draw(mdwc, dwc->vbus_draw);
+}
+
 static void dwc3_msm_notify_event(struct dwc3 *dwc, unsigned int event)
 {
 	struct dwc3_msm *mdwc = dev_get_drvdata(dwc->dev->parent);
@@ -1670,7 +1680,7 @@
 		break;
 	case DWC3_CONTROLLER_SET_CURRENT_DRAW_EVENT:
 		dev_dbg(mdwc->dev, "DWC3_CONTROLLER_SET_CURRENT_DRAW_EVENT received\n");
-		dwc3_msm_gadget_vbus_draw(mdwc, dwc->vbus_draw);
+		schedule_work(&mdwc->vbus_draw_work);
 		break;
 	case DWC3_CONTROLLER_RESTART_USB_SESSION:
 		dev_dbg(mdwc->dev, "DWC3_CONTROLLER_RESTART_USB_SESSION received\n");
@@ -2568,6 +2578,7 @@
 	INIT_WORK(&mdwc->resume_work, dwc3_resume_work);
 	INIT_WORK(&mdwc->restart_usb_work, dwc3_restart_usb_work);
 	INIT_WORK(&mdwc->bus_vote_w, dwc3_msm_bus_vote_w);
+	INIT_WORK(&mdwc->vbus_draw_work, dwc3_msm_vbus_draw_work);
 	INIT_DELAYED_WORK(&mdwc->sm_work, dwc3_otg_sm_work);
 
 	mdwc->dwc3_wq = alloc_ordered_workqueue("dwc3_wq", 0);