Loading drivers/usb/dwc3/dwc3-msm.c +60 −0 Original line number Diff line number Diff line Loading @@ -150,6 +150,9 @@ #define DWC3_GEVNTADRHI_EVNTADRHI_GSI_IDX(n) (n << 16) #define DWC3_GEVENT_TYPE_GSI 0x3 /* BAM pipe mask */ #define MSM_PIPE_ID_MASK (0x1F) enum dbm_reg { DBM_EP_CFG, DBM_DATA_FIFO, Loading Loading @@ -3738,6 +3741,63 @@ static void dwc3_init_dbm(struct dwc3_msm *mdwc) "qcom,reset-ep-after-lpm-resume"); } static void dwc3_start_stop_host(struct dwc3_msm *mdwc, bool start) { struct dwc3 *dwc = platform_get_drvdata(mdwc->dwc3); if (start) { dbg_log_string("start host mode"); mdwc->id_state = DWC3_ID_GROUND; mdwc->vbus_active = false; } else { dbg_log_string("stop_host_mode started"); mdwc->id_state = DWC3_ID_FLOAT; mdwc->vbus_active = false; } dwc3_ext_event_notify(mdwc); dbg_event(0xFF, "flush_work", 0); flush_work(&mdwc->resume_work); drain_workqueue(mdwc->sm_usb_wq); if (start) dbg_log_string("host mode started"); else dbg_log_string("stop_host_mode completed"); } int dwc3_msm_release_ss_lane(struct device *dev) { struct dwc3_msm *mdwc = dev_get_drvdata(dev); struct dwc3 *dwc = NULL; if (mdwc == NULL) { dev_err(dev, "dwc3-msm is not initialized yet.\n"); return -EAGAIN; } dwc = platform_get_drvdata(mdwc->dwc3); if (dwc == NULL) { dev_err(dev, "dwc3 controller is not initialized yet.\n"); return -EAGAIN; } dbg_event(0xFF, "ss_lane_release", 0); if (mdwc->id_state != DWC3_ID_GROUND) { dbg_log_string("USB host mode is not active"); return 0; } /* stop USB host mode */ dwc3_start_stop_host(mdwc, false); /* restart USB host mode into high speed */ dwc->maximum_speed = USB_SPEED_HIGH; dwc3_start_stop_host(mdwc, true); return 0; } EXPORT_SYMBOL(dwc3_msm_release_ss_lane); static int dwc3_msm_probe(struct platform_device *pdev) { struct device_node *node = pdev->dev.of_node, *dwc3_node; Loading include/linux/usb/dwc3-msm.h +3 −1 Original line number Diff line number Diff line Loading @@ -22,7 +22,6 @@ * These bit fields are set by function drivers that wish to queue * usb_requests with sps/bam parameters. */ #define MSM_PIPE_ID_MASK (0x1F) #define MSM_TX_PIPE_ID_OFS (16) #define MSM_SPS_MODE BIT(5) #define MSM_IS_FINITE_TRANSFER BIT(6) Loading Loading @@ -121,6 +120,7 @@ int msm_data_fifo_config(struct usb_ep *ep, unsigned long addr, u32 size, u8 dst_pipe_idx); bool msm_dwc3_reset_ep_after_lpm(struct usb_gadget *gadget); int msm_dwc3_reset_dbm_ep(struct usb_ep *ep); int dwc3_msm_release_ss_lane(struct device *dev); #else static inline struct usb_ep *usb_ep_autoconfig_by_name( struct usb_gadget *gadget, struct usb_endpoint_descriptor *desc, Loading @@ -146,6 +146,8 @@ static inline bool msm_dwc3_reset_ep_after_lpm(struct usb_gadget *gadget) { return false; } static inline int msm_dwc3_reset_dbm_ep(struct usb_ep *ep) { return -ENODEV; } static inline int dwc3_msm_release_ss_lane(struct device *dev) { return -ENODEV; } #endif #endif /* __LINUX_USB_DWC3_MSM_H */ Loading
drivers/usb/dwc3/dwc3-msm.c +60 −0 Original line number Diff line number Diff line Loading @@ -150,6 +150,9 @@ #define DWC3_GEVNTADRHI_EVNTADRHI_GSI_IDX(n) (n << 16) #define DWC3_GEVENT_TYPE_GSI 0x3 /* BAM pipe mask */ #define MSM_PIPE_ID_MASK (0x1F) enum dbm_reg { DBM_EP_CFG, DBM_DATA_FIFO, Loading Loading @@ -3738,6 +3741,63 @@ static void dwc3_init_dbm(struct dwc3_msm *mdwc) "qcom,reset-ep-after-lpm-resume"); } static void dwc3_start_stop_host(struct dwc3_msm *mdwc, bool start) { struct dwc3 *dwc = platform_get_drvdata(mdwc->dwc3); if (start) { dbg_log_string("start host mode"); mdwc->id_state = DWC3_ID_GROUND; mdwc->vbus_active = false; } else { dbg_log_string("stop_host_mode started"); mdwc->id_state = DWC3_ID_FLOAT; mdwc->vbus_active = false; } dwc3_ext_event_notify(mdwc); dbg_event(0xFF, "flush_work", 0); flush_work(&mdwc->resume_work); drain_workqueue(mdwc->sm_usb_wq); if (start) dbg_log_string("host mode started"); else dbg_log_string("stop_host_mode completed"); } int dwc3_msm_release_ss_lane(struct device *dev) { struct dwc3_msm *mdwc = dev_get_drvdata(dev); struct dwc3 *dwc = NULL; if (mdwc == NULL) { dev_err(dev, "dwc3-msm is not initialized yet.\n"); return -EAGAIN; } dwc = platform_get_drvdata(mdwc->dwc3); if (dwc == NULL) { dev_err(dev, "dwc3 controller is not initialized yet.\n"); return -EAGAIN; } dbg_event(0xFF, "ss_lane_release", 0); if (mdwc->id_state != DWC3_ID_GROUND) { dbg_log_string("USB host mode is not active"); return 0; } /* stop USB host mode */ dwc3_start_stop_host(mdwc, false); /* restart USB host mode into high speed */ dwc->maximum_speed = USB_SPEED_HIGH; dwc3_start_stop_host(mdwc, true); return 0; } EXPORT_SYMBOL(dwc3_msm_release_ss_lane); static int dwc3_msm_probe(struct platform_device *pdev) { struct device_node *node = pdev->dev.of_node, *dwc3_node; Loading
include/linux/usb/dwc3-msm.h +3 −1 Original line number Diff line number Diff line Loading @@ -22,7 +22,6 @@ * These bit fields are set by function drivers that wish to queue * usb_requests with sps/bam parameters. */ #define MSM_PIPE_ID_MASK (0x1F) #define MSM_TX_PIPE_ID_OFS (16) #define MSM_SPS_MODE BIT(5) #define MSM_IS_FINITE_TRANSFER BIT(6) Loading Loading @@ -121,6 +120,7 @@ int msm_data_fifo_config(struct usb_ep *ep, unsigned long addr, u32 size, u8 dst_pipe_idx); bool msm_dwc3_reset_ep_after_lpm(struct usb_gadget *gadget); int msm_dwc3_reset_dbm_ep(struct usb_ep *ep); int dwc3_msm_release_ss_lane(struct device *dev); #else static inline struct usb_ep *usb_ep_autoconfig_by_name( struct usb_gadget *gadget, struct usb_endpoint_descriptor *desc, Loading @@ -146,6 +146,8 @@ static inline bool msm_dwc3_reset_ep_after_lpm(struct usb_gadget *gadget) { return false; } static inline int msm_dwc3_reset_dbm_ep(struct usb_ep *ep) { return -ENODEV; } static inline int dwc3_msm_release_ss_lane(struct device *dev) { return -ENODEV; } #endif #endif /* __LINUX_USB_DWC3_MSM_H */