Loading drivers/usb/dwc3/dwc3-msm.c +60 −2 Original line number Diff line number Diff line Loading @@ -87,6 +87,8 @@ MODULE_PARM_DESC(dcp_max_current, "max current drawn for DCP charger"); /* XHCI registers */ #define USB3_HCSPARAMS1 (0x4) #define USB3_HCCPARAMS2 (0x1c) #define HCC_CTC(p) ((p) & (1 << 3)) #define USB3_PORTSC (0x420) /** Loading Loading @@ -258,6 +260,7 @@ struct dwc3_msm { bool no_wakeup_src_in_hostmode; bool host_only_mode; bool psy_not_used; bool xhci_ss_compliance_enable; int pwr_event_irq; atomic_t in_p3; Loading Loading @@ -2853,6 +2856,35 @@ static ssize_t mode_store(struct device *dev, struct device_attribute *attr, static DEVICE_ATTR_RW(mode); static ssize_t xhci_link_compliance_show(struct device *dev, struct device_attribute *attr, char *buf) { struct dwc3_msm *mdwc = dev_get_drvdata(dev); if (mdwc->xhci_ss_compliance_enable) return snprintf(buf, PAGE_SIZE, "y\n"); else return snprintf(buf, PAGE_SIZE, "n\n"); } static ssize_t xhci_link_compliance_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { struct dwc3_msm *mdwc = dev_get_drvdata(dev); bool value; int ret; ret = strtobool(buf, &value); if (!ret) { mdwc->xhci_ss_compliance_enable = value; return count; } return ret; } static DEVICE_ATTR_RW(xhci_link_compliance); static int dwc3_msm_probe(struct platform_device *pdev) { struct device_node *node = pdev->dev.of_node, *dwc3_node; Loading Loading @@ -3238,13 +3270,16 @@ static int dwc3_msm_probe(struct platform_device *pdev) enable_irq_wake(mdwc->pmic_id_irq); } if (dwc->is_drd) if (dwc->is_drd) { device_create_file(&pdev->dev, &dev_attr_mode); device_create_file(&pdev->dev, &dev_attr_xhci_link_compliance); } if (!dwc->is_drd && host_mode) { dev_dbg(&pdev->dev, "DWC3 in host only mode\n"); mdwc->host_only_mode = true; mdwc->id_state = DWC3_ID_GROUND; device_create_file(&pdev->dev, &dev_attr_xhci_link_compliance); dwc3_ext_event_notify(mdwc); } Loading Loading @@ -3283,8 +3318,12 @@ static int dwc3_msm_remove(struct platform_device *pdev) struct dwc3 *dwc = platform_get_drvdata(mdwc->dwc3); int ret_pm; if (dwc->is_drd) if (dwc->is_drd) { device_remove_file(&pdev->dev, &dev_attr_mode); device_remove_file(&pdev->dev, &dev_attr_xhci_link_compliance); } else if (mdwc->host_only_mode) { device_remove_file(&pdev->dev, &dev_attr_xhci_link_compliance); } if (cpu_to_affin) unregister_cpu_notifier(&mdwc->dwc3_cpu_notifier); Loading Loading @@ -3541,6 +3580,25 @@ static int dwc3_otg_start_host(struct dwc3_msm *mdwc, int on) return ret; } /* * If the Compliance Transition Capability(CTC) flag of * HCCPARAMS2 register is set and xhci_link_compliance sysfs * param has been enabled by the user for the SuperSpeed host * controller, then write 10 (Link in Compliance Mode State) * onto the Port Link State(PLS) field of the PORTSC register * for 3.0 host controller which is at an offset of USB3_PORTSC * + 0x10 from the DWC3 base address. Also, disable the runtime * PM of 3.0 root hub (root hub of shared_hcd of xhci device) */ if (HCC_CTC(dwc3_msm_read_reg(mdwc->base, USB3_HCCPARAMS2)) && mdwc->xhci_ss_compliance_enable && dwc->maximum_speed == USB_SPEED_SUPER) { dwc3_msm_write_reg(mdwc->base, USB3_PORTSC + 0x10, 0x10340); pm_runtime_disable(&hcd_to_xhci(platform_get_drvdata( dwc->xhci))->shared_hcd->self.root_hub->dev); } /* * In some cases it is observed that USB PHY is not going into * suspend with host mode suspend functionality. Hence disable Loading Loading
drivers/usb/dwc3/dwc3-msm.c +60 −2 Original line number Diff line number Diff line Loading @@ -87,6 +87,8 @@ MODULE_PARM_DESC(dcp_max_current, "max current drawn for DCP charger"); /* XHCI registers */ #define USB3_HCSPARAMS1 (0x4) #define USB3_HCCPARAMS2 (0x1c) #define HCC_CTC(p) ((p) & (1 << 3)) #define USB3_PORTSC (0x420) /** Loading Loading @@ -258,6 +260,7 @@ struct dwc3_msm { bool no_wakeup_src_in_hostmode; bool host_only_mode; bool psy_not_used; bool xhci_ss_compliance_enable; int pwr_event_irq; atomic_t in_p3; Loading Loading @@ -2853,6 +2856,35 @@ static ssize_t mode_store(struct device *dev, struct device_attribute *attr, static DEVICE_ATTR_RW(mode); static ssize_t xhci_link_compliance_show(struct device *dev, struct device_attribute *attr, char *buf) { struct dwc3_msm *mdwc = dev_get_drvdata(dev); if (mdwc->xhci_ss_compliance_enable) return snprintf(buf, PAGE_SIZE, "y\n"); else return snprintf(buf, PAGE_SIZE, "n\n"); } static ssize_t xhci_link_compliance_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { struct dwc3_msm *mdwc = dev_get_drvdata(dev); bool value; int ret; ret = strtobool(buf, &value); if (!ret) { mdwc->xhci_ss_compliance_enable = value; return count; } return ret; } static DEVICE_ATTR_RW(xhci_link_compliance); static int dwc3_msm_probe(struct platform_device *pdev) { struct device_node *node = pdev->dev.of_node, *dwc3_node; Loading Loading @@ -3238,13 +3270,16 @@ static int dwc3_msm_probe(struct platform_device *pdev) enable_irq_wake(mdwc->pmic_id_irq); } if (dwc->is_drd) if (dwc->is_drd) { device_create_file(&pdev->dev, &dev_attr_mode); device_create_file(&pdev->dev, &dev_attr_xhci_link_compliance); } if (!dwc->is_drd && host_mode) { dev_dbg(&pdev->dev, "DWC3 in host only mode\n"); mdwc->host_only_mode = true; mdwc->id_state = DWC3_ID_GROUND; device_create_file(&pdev->dev, &dev_attr_xhci_link_compliance); dwc3_ext_event_notify(mdwc); } Loading Loading @@ -3283,8 +3318,12 @@ static int dwc3_msm_remove(struct platform_device *pdev) struct dwc3 *dwc = platform_get_drvdata(mdwc->dwc3); int ret_pm; if (dwc->is_drd) if (dwc->is_drd) { device_remove_file(&pdev->dev, &dev_attr_mode); device_remove_file(&pdev->dev, &dev_attr_xhci_link_compliance); } else if (mdwc->host_only_mode) { device_remove_file(&pdev->dev, &dev_attr_xhci_link_compliance); } if (cpu_to_affin) unregister_cpu_notifier(&mdwc->dwc3_cpu_notifier); Loading Loading @@ -3541,6 +3580,25 @@ static int dwc3_otg_start_host(struct dwc3_msm *mdwc, int on) return ret; } /* * If the Compliance Transition Capability(CTC) flag of * HCCPARAMS2 register is set and xhci_link_compliance sysfs * param has been enabled by the user for the SuperSpeed host * controller, then write 10 (Link in Compliance Mode State) * onto the Port Link State(PLS) field of the PORTSC register * for 3.0 host controller which is at an offset of USB3_PORTSC * + 0x10 from the DWC3 base address. Also, disable the runtime * PM of 3.0 root hub (root hub of shared_hcd of xhci device) */ if (HCC_CTC(dwc3_msm_read_reg(mdwc->base, USB3_HCCPARAMS2)) && mdwc->xhci_ss_compliance_enable && dwc->maximum_speed == USB_SPEED_SUPER) { dwc3_msm_write_reg(mdwc->base, USB3_PORTSC + 0x10, 0x10340); pm_runtime_disable(&hcd_to_xhci(platform_get_drvdata( dwc->xhci))->shared_hcd->self.root_hub->dev); } /* * In some cases it is observed that USB PHY is not going into * suspend with host mode suspend functionality. Hence disable Loading