diff --git a/drivers/usb/dwc3/dwc3-msm.c b/drivers/usb/dwc3/dwc3-msm.c index e3848b885b95..211e1945962c 100644 --- a/drivers/usb/dwc3/dwc3-msm.c +++ b/drivers/usb/dwc3/dwc3-msm.c @@ -2754,6 +2754,39 @@ static ssize_t mode_store(struct device *dev, struct device_attribute *attr, } static DEVICE_ATTR_RW(mode); + +static ssize_t speed_show(struct device *dev, struct device_attribute *attr, + char *buf) +{ + struct dwc3_msm *mdwc = dev_get_drvdata(dev); + struct dwc3 *dwc = platform_get_drvdata(mdwc->dwc3); + + return snprintf(buf, PAGE_SIZE, "%s", + usb_speed_string(dwc->max_hw_supp_speed)); +} + +static ssize_t speed_store(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count) +{ + struct dwc3_msm *mdwc = dev_get_drvdata(dev); + struct dwc3 *dwc = platform_get_drvdata(mdwc->dwc3); + enum usb_device_speed req_speed = USB_SPEED_UNKNOWN; + + if (sysfs_streq(buf, "high")) + req_speed = USB_SPEED_HIGH; + else if (sysfs_streq(buf, "super")) + req_speed = USB_SPEED_SUPER; + + if (req_speed != USB_SPEED_UNKNOWN && + req_speed != dwc->max_hw_supp_speed) { + dwc->maximum_speed = dwc->max_hw_supp_speed = req_speed; + schedule_work(&mdwc->restart_usb_work); + } + + return count; +} +static DEVICE_ATTR_RW(speed); + static void msm_dwc3_perf_vote_work(struct work_struct *w); static int dwc3_msm_probe(struct platform_device *pdev) @@ -3097,6 +3130,7 @@ static int dwc3_msm_probe(struct platform_device *pdev) } device_create_file(&pdev->dev, &dev_attr_mode); + device_create_file(&pdev->dev, &dev_attr_speed); host_mode = usb_get_dr_mode(&mdwc->dwc3->dev) == USB_DR_MODE_HOST; if (!dwc->is_drd && host_mode) {