summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLinux Build Service Account <lnxbuild@localhost>2017-01-30 07:04:59 -0800
committerGerrit - the friendly Code Review server <code-review@localhost>2017-01-30 07:04:59 -0800
commit2026ad674d3e79bd3fea3426ab44dce5d38ba8b3 (patch)
tree54aa6ff1d4e9d396aac7c8ea540be255949ff081
parent5c307ffbc7e1de019bb8e4a27956bf97ad74562e (diff)
parent39a23b8220ad9625b74fedd6722ce1538c886676 (diff)
Merge "usb: dwc3: Reset and initiate lpm while booting up with no usb cable"
-rw-r--r--drivers/usb/dwc3/dwc3-msm.c39
1 files changed, 32 insertions, 7 deletions
diff --git a/drivers/usb/dwc3/dwc3-msm.c b/drivers/usb/dwc3/dwc3-msm.c
index bc0e0184a917..ecfee972ea56 100644
--- a/drivers/usb/dwc3/dwc3-msm.c
+++ b/drivers/usb/dwc3/dwc3-msm.c
@@ -2723,6 +2723,7 @@ static int dwc3_msm_probe(struct platform_device *pdev)
{
struct device_node *node = pdev->dev.of_node, *dwc3_node;
struct device *dev = &pdev->dev;
+ union power_supply_propval pval = {0};
struct dwc3_msm *mdwc;
struct dwc3 *dwc;
struct resource *res;
@@ -3016,10 +3017,8 @@ static int dwc3_msm_probe(struct platform_device *pdev)
*/
mdwc->lpm_flags = MDWC3_POWER_COLLAPSE | MDWC3_SS_PHY_SUSPEND;
atomic_set(&dwc->in_lpm, 1);
- pm_runtime_set_suspended(mdwc->dev);
pm_runtime_set_autosuspend_delay(mdwc->dev, 1000);
pm_runtime_use_autosuspend(mdwc->dev);
- pm_runtime_enable(mdwc->dev);
device_init_wakeup(mdwc->dev, 1);
if (of_property_read_bool(node, "qcom,disable-dev-mode-pm"))
@@ -3036,18 +3035,32 @@ static int dwc3_msm_probe(struct platform_device *pdev)
mdwc->pm_qos_latency = 0;
}
+ mdwc->usb_psy = power_supply_get_by_name("usb");
+ if (!mdwc->usb_psy) {
+ dev_warn(mdwc->dev, "Could not get usb power_supply\n");
+ pval.intval = -EINVAL;
+ } else {
+ power_supply_get_property(mdwc->usb_psy,
+ POWER_SUPPLY_PROP_PRESENT, &pval);
+ }
+
/* Update initial VBUS/ID state from extcon */
if (mdwc->extcon_vbus && extcon_get_cable_state_(mdwc->extcon_vbus,
EXTCON_USB))
dwc3_msm_vbus_notifier(&mdwc->vbus_nb, true, mdwc->extcon_vbus);
- if (mdwc->extcon_id && extcon_get_cable_state_(mdwc->extcon_id,
+ else if (mdwc->extcon_id && extcon_get_cable_state_(mdwc->extcon_id,
EXTCON_USB_HOST))
dwc3_msm_id_notifier(&mdwc->id_nb, true, mdwc->extcon_id);
+ else if (!pval.intval) {
+ /* USB cable is not connected */
+ schedule_delayed_work(&mdwc->sm_work, 0);
+ } else {
+ if (pval.intval > 0)
+ dev_info(mdwc->dev, "charger detection in progress\n");
+ }
device_create_file(&pdev->dev, &dev_attr_mode);
- schedule_delayed_work(&mdwc->sm_work, 0);
-
host_mode = usb_get_dr_mode(&mdwc->dwc3->dev) == USB_DR_MODE_HOST;
if (!dwc->is_drd && host_mode) {
dev_dbg(&pdev->dev, "DWC3 in host only mode\n");
@@ -3538,13 +3551,25 @@ static void dwc3_otg_sm_work(struct work_struct *w)
/* Check OTG state */
switch (mdwc->otg_state) {
case OTG_STATE_UNDEFINED:
- /* Do nothing if no cable connected */
+ /* put controller and phy in suspend if no cable connected */
if (test_bit(ID, &mdwc->inputs) &&
- !test_bit(B_SESS_VLD, &mdwc->inputs))
+ !test_bit(B_SESS_VLD, &mdwc->inputs)) {
+ dbg_event(0xFF, "undef_id_!bsv", 0);
+ pm_runtime_set_active(mdwc->dev);
+ pm_runtime_enable(mdwc->dev);
+ pm_runtime_get_noresume(mdwc->dev);
+ dwc3_msm_resume(mdwc);
+ pm_runtime_put_sync(mdwc->dev);
+ dbg_event(0xFF, "Undef NoUSB",
+ atomic_read(&mdwc->dev->power.usage_count));
+ mdwc->otg_state = OTG_STATE_B_IDLE;
break;
+ }
dbg_event(0xFF, "Exit UNDEF", 0);
mdwc->otg_state = OTG_STATE_B_IDLE;
+ pm_runtime_set_suspended(mdwc->dev);
+ pm_runtime_enable(mdwc->dev);
/* fall-through */
case OTG_STATE_B_IDLE:
if (!test_bit(ID, &mdwc->inputs)) {