diff options
Diffstat (limited to 'drivers/usb/dwc3/dwc3-msm.c')
| -rw-r--r-- | drivers/usb/dwc3/dwc3-msm.c | 79 |
1 files changed, 40 insertions, 39 deletions
diff --git a/drivers/usb/dwc3/dwc3-msm.c b/drivers/usb/dwc3/dwc3-msm.c index 4d35de1c14c5..37a3c954a1dd 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"); @@ -1927,6 +1937,12 @@ static int dwc3_msm_suspend(struct dwc3_msm *mdwc) clk_disable_unprepare(mdwc->bus_aggr_clk); clk_disable_unprepare(mdwc->utmi_clk); + /* Memory core: OFF, Memory periphery: OFF */ + if (!mdwc->in_host_mode && !mdwc->vbus_active) { + clk_set_flags(mdwc->core_clk, CLKFLAG_NORETAIN_MEM); + clk_set_flags(mdwc->core_clk, CLKFLAG_NORETAIN_PERIPH); + } + clk_set_rate(mdwc->core_clk, 19200000); clk_disable_unprepare(mdwc->core_clk); /* @@ -2338,14 +2354,23 @@ static int dwc3_msm_get_clk_gdsc(struct dwc3_msm *mdwc) return ret; } - /* - * Get Max supported clk frequency for USB Core CLK and request - * to set the same. - */ - mdwc->core_clk_rate = clk_round_rate(mdwc->core_clk, LONG_MAX); + if (!of_property_read_u32(mdwc->dev->of_node, "qcom,core-clk-rate", + (u32 *)&mdwc->core_clk_rate)) { + mdwc->core_clk_rate = clk_round_rate(mdwc->core_clk, + mdwc->core_clk_rate); + } else { + /* + * Get Max supported clk frequency for USB Core CLK and request + * to set the same. + */ + mdwc->core_clk_rate = clk_round_rate(mdwc->core_clk, LONG_MAX); + } + if (IS_ERR_VALUE(mdwc->core_clk_rate)) { dev_err(mdwc->dev, "fail to get core clk max freq.\n"); } else { + dev_dbg(mdwc->dev, "USB core frequency = %ld\n", + mdwc->core_clk_rate); ret = clk_set_rate(mdwc->core_clk, mdwc->core_clk_rate); if (ret) dev_err(mdwc->dev, "fail to set core_clk freq:%d\n", @@ -2582,6 +2607,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); @@ -3165,7 +3191,8 @@ static int dwc3_otg_start_peripheral(struct dwc3_msm *mdwc, int on) static int dwc3_msm_gadget_vbus_draw(struct dwc3_msm *mdwc, unsigned mA) { - union power_supply_propval pval = {0,}; + union power_supply_propval pval = {1000 * mA}; + int ret; if (mdwc->charging_disabled) return 0; @@ -3183,42 +3210,16 @@ static int dwc3_msm_gadget_vbus_draw(struct dwc3_msm *mdwc, unsigned mA) dev_info(mdwc->dev, "Avail curr from USB = %u\n", mA); - if (mdwc->max_power <= 2 && mA > 2) { - /* Enable Charging */ - pval.intval = true; - if (power_supply_set_property(mdwc->usb_psy, - POWER_SUPPLY_PROP_ONLINE, &pval)) - goto psy_error; - pval.intval = 1000 * mA; - if (power_supply_set_property(mdwc->usb_psy, - POWER_SUPPLY_PROP_CURRENT_MAX, &pval)) - goto psy_error; - } else if (mdwc->max_power > 0 && (mA == 0 || mA == 2)) { - /* Disable charging */ - pval.intval = false; - if (power_supply_set_property(mdwc->usb_psy, - POWER_SUPPLY_PROP_ONLINE, &pval)) - goto psy_error; - } else { - /* Enable charging */ - pval.intval = true; - if (power_supply_set_property(mdwc->usb_psy, - POWER_SUPPLY_PROP_ONLINE, &pval)) - goto psy_error; - } - /* Set max current limit in uA */ - pval.intval = 1000 * mA; - if (power_supply_set_property(mdwc->usb_psy, - POWER_SUPPLY_PROP_CURRENT_MAX, &pval)) - goto psy_error; + ret = power_supply_set_property(mdwc->usb_psy, + POWER_SUPPLY_PROP_CURRENT_MAX, &pval); + if (ret) { + dev_dbg(mdwc->dev, "power supply error when setting property\n"); + return ret; + } mdwc->max_power = mA; return 0; - -psy_error: - dev_dbg(mdwc->dev, "power supply error when setting property\n"); - return -ENXIO; } |
