summaryrefslogtreecommitdiff
path: root/drivers/usb/dwc3/dwc3-msm.c
diff options
context:
space:
mode:
authorJack Pham <jackp@codeaurora.org>2016-08-09 11:36:34 -0700
committerJack Pham <jackp@codeaurora.org>2016-08-10 09:47:37 -0700
commit3acfc4ffecb1bbf3e38e90ba3f45fec04fa7143c (patch)
tree41a8030f96a1985fb8e42bc5db1f44f4f67538c7 /drivers/usb/dwc3/dwc3-msm.c
parente94b446eac88a43e42ecde105275d48b677ea5b3 (diff)
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>
Diffstat (limited to 'drivers/usb/dwc3/dwc3-msm.c')
-rw-r--r--drivers/usb/dwc3/dwc3-msm.c13
1 files changed, 12 insertions, 1 deletions
diff --git a/drivers/usb/dwc3/dwc3-msm.c b/drivers/usb/dwc3/dwc3-msm.c
index 4d35de1c14c5..c40c61b184b9 100644
--- a/drivers/usb/dwc3/dwc3-msm.c
+++ b/drivers/usb/dwc3/dwc3-msm.c
@@ -187,6 +187,7 @@ struct dwc3_msm {
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;
@@ -1595,6 +1596,15 @@ static void dwc3_msm_qscratch_reg_init(struct dwc3_msm *mdwc)
}
+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 event)
{
struct dwc3_msm *mdwc = dev_get_drvdata(dwc->dev->parent);
@@ -1680,7 +1690,7 @@ static void dwc3_msm_notify_event(struct dwc3 *dwc, unsigned event)
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");
@@ -2582,6 +2592,7 @@ static int dwc3_msm_probe(struct platform_device *pdev)
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);