Loading drivers/usb/phy/phy-msm-usb.c +58 −32 Original line number Diff line number Diff line Loading @@ -1420,6 +1420,7 @@ static irqreturn_t msm_otg_phy_irq_handler(int irq, void *data) static void msm_otg_set_vbus_state(int online); static void msm_otg_perf_vote_update(struct msm_otg *motg, bool perf_mode); static int get_psy_type(struct msm_otg *motg); #ifdef CONFIG_PM_SLEEP static int msm_otg_suspend(struct msm_otg *motg) Loading Loading @@ -1458,7 +1459,11 @@ static int msm_otg_suspend(struct msm_otg *motg) msm_otg_perf_vote_update(motg, false); host_pc_charger = (motg->chg_type == USB_SDP_CHARGER) || (motg->chg_type == USB_CDP_CHARGER); (motg->chg_type == USB_CDP_CHARGER) || (get_psy_type(motg) == POWER_SUPPLY_TYPE_USB) || (get_psy_type(motg) == POWER_SUPPLY_TYPE_USB_CDP); msm_otg_dbg_log_event(phy, "CHARGER CONNECTED", host_pc_charger, motg->inputs); /* !BSV, but its handling is in progress by otg sm_work */ sm_work_busy = !test_bit(B_SESS_VLD, &motg->inputs) && Loading @@ -1468,17 +1473,6 @@ static int msm_otg_suspend(struct msm_otg *motg) if (motg->err_event_seen) msm_otg_reset(phy); /* Enable line state difference wakeup fix for only device and host * bus suspend scenarios. Otherwise PHY can not be suspended when * a charger that pulls DP/DM high is connected. */ config2 = readl_relaxed(USB_GENCONFIG_2); if (device_bus_suspend) config2 |= GENCONFIG_2_LINESTATE_DIFF_WAKEUP_EN; else config2 &= ~GENCONFIG_2_LINESTATE_DIFF_WAKEUP_EN; writel_relaxed(config2, USB_GENCONFIG_2); /* * Abort suspend when, * 1. host mode activation in progress due to Micro-A cable insertion Loading @@ -1496,6 +1490,17 @@ static int msm_otg_suspend(struct msm_otg *motg) return -EBUSY; } /* Enable line state difference wakeup fix for only device and host * bus suspend scenarios. Otherwise PHY can not be suspended when * a charger that pulls DP/DM high is connected. */ config2 = readl_relaxed(USB_GENCONFIG_2); if (device_bus_suspend) config2 |= GENCONFIG_2_LINESTATE_DIFF_WAKEUP_EN; else config2 &= ~GENCONFIG_2_LINESTATE_DIFF_WAKEUP_EN; writel_relaxed(config2, USB_GENCONFIG_2); if (motg->caps & ALLOW_VDD_MIN_WITH_RETENTION_DISABLED) { /* put the controller in non-driving mode */ func_ctrl = ulpi_read(phy, ULPI_FUNC_CTRL); Loading Loading @@ -2862,6 +2867,10 @@ static void check_for_sdp_connection(struct work_struct *w) msm_otg_set_vbus_state(motg->vbus_state); } #define DP_PULSE_WIDTH_MSEC 200 static int msm_otg_phy_drive_dp_pulse(struct msm_otg *motg, unsigned int pulse_width); static void msm_otg_sm_work(struct work_struct *w) { struct msm_otg *motg = container_of(w, struct msm_otg, sm_work); Loading Loading @@ -2905,6 +2914,9 @@ static void msm_otg_sm_work(struct work_struct *w) get_pm_runtime_counter(dev), 0); pm_runtime_put_sync(dev); break; } else if (get_psy_type(motg) == POWER_SUPPLY_TYPE_USB_CDP) { pr_debug("Connected to CDP, pull DP up from sm_work\n"); msm_otg_phy_drive_dp_pulse(motg, DP_PULSE_WIDTH_MSEC); } pm_runtime_put(dev); /* FALL THROUGH */ Loading Loading @@ -3073,9 +3085,14 @@ msm_otg_phy_drive_dp_pulse(struct msm_otg *motg, unsigned int pulse_width) { int ret = 0; u32 val; bool in_lpm = false; msm_otg_dbg_log_event(&motg->phy, "DRIVE DP PULSE", motg->inputs, 0); if (atomic_read(&motg->in_lpm)) in_lpm = true; if (in_lpm) { ret = msm_hsusb_ldo_enable(motg, USB_PHY_REG_ON); if (ret) return ret; Loading @@ -3086,6 +3103,7 @@ msm_otg_phy_drive_dp_pulse(struct msm_otg *motg, unsigned int pulse_width) clk_prepare_enable(motg->phy_csr_clk); clk_prepare_enable(motg->core_clk); clk_prepare_enable(motg->pclk); } msm_otg_exit_phy_retention(motg); Loading Loading @@ -3131,6 +3149,7 @@ msm_otg_phy_drive_dp_pulse(struct msm_otg *motg, unsigned int pulse_width) /* Make sure above writes are completed before clks off */ mb(); if (in_lpm) { clk_disable_unprepare(motg->pclk); clk_disable_unprepare(motg->core_clk); clk_disable_unprepare(motg->phy_csr_clk); Loading @@ -3138,17 +3157,19 @@ msm_otg_phy_drive_dp_pulse(struct msm_otg *motg, unsigned int pulse_width) regulator_disable(hsusb_vdd); msm_hsusb_config_vddcx(0); msm_hsusb_ldo_enable(motg, USB_PHY_REG_OFF); } else { msm_otg_reset(&motg->phy); } msm_otg_dbg_log_event(&motg->phy, "DP PULSE DRIVEN", motg->inputs, 0); return 0; } #define DP_PULSE_WIDTH_MSEC 200 static void msm_otg_set_vbus_state(int online) { struct msm_otg *motg = the_msm_otg; struct usb_otg *otg = motg->phy.otg; motg->vbus_state = online; Loading @@ -3161,7 +3182,12 @@ static void msm_otg_set_vbus_state(int online) motg->inputs, 0); if (test_and_set_bit(B_SESS_VLD, &motg->inputs)) return; if (get_psy_type(motg) == POWER_SUPPLY_TYPE_USB_CDP) { /* * It might race with block reset happening in sm_work, while * state machine is in undefined state. Add check to avoid it. */ if ((get_psy_type(motg) == POWER_SUPPLY_TYPE_USB_CDP) && (otg->state != OTG_STATE_UNDEFINED)) { pr_debug("Connected to CDP, pull DP up\n"); msm_otg_phy_drive_dp_pulse(motg, DP_PULSE_WIDTH_MSEC); } Loading Loading
drivers/usb/phy/phy-msm-usb.c +58 −32 Original line number Diff line number Diff line Loading @@ -1420,6 +1420,7 @@ static irqreturn_t msm_otg_phy_irq_handler(int irq, void *data) static void msm_otg_set_vbus_state(int online); static void msm_otg_perf_vote_update(struct msm_otg *motg, bool perf_mode); static int get_psy_type(struct msm_otg *motg); #ifdef CONFIG_PM_SLEEP static int msm_otg_suspend(struct msm_otg *motg) Loading Loading @@ -1458,7 +1459,11 @@ static int msm_otg_suspend(struct msm_otg *motg) msm_otg_perf_vote_update(motg, false); host_pc_charger = (motg->chg_type == USB_SDP_CHARGER) || (motg->chg_type == USB_CDP_CHARGER); (motg->chg_type == USB_CDP_CHARGER) || (get_psy_type(motg) == POWER_SUPPLY_TYPE_USB) || (get_psy_type(motg) == POWER_SUPPLY_TYPE_USB_CDP); msm_otg_dbg_log_event(phy, "CHARGER CONNECTED", host_pc_charger, motg->inputs); /* !BSV, but its handling is in progress by otg sm_work */ sm_work_busy = !test_bit(B_SESS_VLD, &motg->inputs) && Loading @@ -1468,17 +1473,6 @@ static int msm_otg_suspend(struct msm_otg *motg) if (motg->err_event_seen) msm_otg_reset(phy); /* Enable line state difference wakeup fix for only device and host * bus suspend scenarios. Otherwise PHY can not be suspended when * a charger that pulls DP/DM high is connected. */ config2 = readl_relaxed(USB_GENCONFIG_2); if (device_bus_suspend) config2 |= GENCONFIG_2_LINESTATE_DIFF_WAKEUP_EN; else config2 &= ~GENCONFIG_2_LINESTATE_DIFF_WAKEUP_EN; writel_relaxed(config2, USB_GENCONFIG_2); /* * Abort suspend when, * 1. host mode activation in progress due to Micro-A cable insertion Loading @@ -1496,6 +1490,17 @@ static int msm_otg_suspend(struct msm_otg *motg) return -EBUSY; } /* Enable line state difference wakeup fix for only device and host * bus suspend scenarios. Otherwise PHY can not be suspended when * a charger that pulls DP/DM high is connected. */ config2 = readl_relaxed(USB_GENCONFIG_2); if (device_bus_suspend) config2 |= GENCONFIG_2_LINESTATE_DIFF_WAKEUP_EN; else config2 &= ~GENCONFIG_2_LINESTATE_DIFF_WAKEUP_EN; writel_relaxed(config2, USB_GENCONFIG_2); if (motg->caps & ALLOW_VDD_MIN_WITH_RETENTION_DISABLED) { /* put the controller in non-driving mode */ func_ctrl = ulpi_read(phy, ULPI_FUNC_CTRL); Loading Loading @@ -2862,6 +2867,10 @@ static void check_for_sdp_connection(struct work_struct *w) msm_otg_set_vbus_state(motg->vbus_state); } #define DP_PULSE_WIDTH_MSEC 200 static int msm_otg_phy_drive_dp_pulse(struct msm_otg *motg, unsigned int pulse_width); static void msm_otg_sm_work(struct work_struct *w) { struct msm_otg *motg = container_of(w, struct msm_otg, sm_work); Loading Loading @@ -2905,6 +2914,9 @@ static void msm_otg_sm_work(struct work_struct *w) get_pm_runtime_counter(dev), 0); pm_runtime_put_sync(dev); break; } else if (get_psy_type(motg) == POWER_SUPPLY_TYPE_USB_CDP) { pr_debug("Connected to CDP, pull DP up from sm_work\n"); msm_otg_phy_drive_dp_pulse(motg, DP_PULSE_WIDTH_MSEC); } pm_runtime_put(dev); /* FALL THROUGH */ Loading Loading @@ -3073,9 +3085,14 @@ msm_otg_phy_drive_dp_pulse(struct msm_otg *motg, unsigned int pulse_width) { int ret = 0; u32 val; bool in_lpm = false; msm_otg_dbg_log_event(&motg->phy, "DRIVE DP PULSE", motg->inputs, 0); if (atomic_read(&motg->in_lpm)) in_lpm = true; if (in_lpm) { ret = msm_hsusb_ldo_enable(motg, USB_PHY_REG_ON); if (ret) return ret; Loading @@ -3086,6 +3103,7 @@ msm_otg_phy_drive_dp_pulse(struct msm_otg *motg, unsigned int pulse_width) clk_prepare_enable(motg->phy_csr_clk); clk_prepare_enable(motg->core_clk); clk_prepare_enable(motg->pclk); } msm_otg_exit_phy_retention(motg); Loading Loading @@ -3131,6 +3149,7 @@ msm_otg_phy_drive_dp_pulse(struct msm_otg *motg, unsigned int pulse_width) /* Make sure above writes are completed before clks off */ mb(); if (in_lpm) { clk_disable_unprepare(motg->pclk); clk_disable_unprepare(motg->core_clk); clk_disable_unprepare(motg->phy_csr_clk); Loading @@ -3138,17 +3157,19 @@ msm_otg_phy_drive_dp_pulse(struct msm_otg *motg, unsigned int pulse_width) regulator_disable(hsusb_vdd); msm_hsusb_config_vddcx(0); msm_hsusb_ldo_enable(motg, USB_PHY_REG_OFF); } else { msm_otg_reset(&motg->phy); } msm_otg_dbg_log_event(&motg->phy, "DP PULSE DRIVEN", motg->inputs, 0); return 0; } #define DP_PULSE_WIDTH_MSEC 200 static void msm_otg_set_vbus_state(int online) { struct msm_otg *motg = the_msm_otg; struct usb_otg *otg = motg->phy.otg; motg->vbus_state = online; Loading @@ -3161,7 +3182,12 @@ static void msm_otg_set_vbus_state(int online) motg->inputs, 0); if (test_and_set_bit(B_SESS_VLD, &motg->inputs)) return; if (get_psy_type(motg) == POWER_SUPPLY_TYPE_USB_CDP) { /* * It might race with block reset happening in sm_work, while * state machine is in undefined state. Add check to avoid it. */ if ((get_psy_type(motg) == POWER_SUPPLY_TYPE_USB_CDP) && (otg->state != OTG_STATE_UNDEFINED)) { pr_debug("Connected to CDP, pull DP up\n"); msm_otg_phy_drive_dp_pulse(motg, DP_PULSE_WIDTH_MSEC); } Loading