diff options
author | Albert Wang <albertccwang@google.com> | 2021-03-18 18:13:03 +0800 |
---|---|---|
committer | Michael Bestas <mkbestas@lineageos.org> | 2024-03-21 17:43:49 +0200 |
commit | e08bc0c0312b3e91fe5b752768608e4a209182f6 (patch) | |
tree | 73507fb9cb4b045304161d4bf5eb4c5b01891178 | |
parent | 069ac1bc7175e12f6d2d9f92be4687146918da86 (diff) |
usb: new attributes implementation to enable/disable usb data
Bug: 184613044
Test: driver probe and attributes access normally
Signed-off-by: Albert Wang <albertccwang@google.com>
Change-Id: Ia34cfd8e76a21f7239e356608e46ddeebd6fa10a
-rw-r--r-- | Documentation/ABI/testing/sysfs-class-udc | 16 | ||||
-rw-r--r-- | drivers/usb/dwc3/dwc3-msm.c | 39 |
2 files changed, 54 insertions, 1 deletions
diff --git a/Documentation/ABI/testing/sysfs-class-udc b/Documentation/ABI/testing/sysfs-class-udc new file mode 100644 index 000000000000..1b9c566d0552 --- /dev/null +++ b/Documentation/ABI/testing/sysfs-class-udc @@ -0,0 +1,16 @@ +What: /sys/class/udc/<udc name>/device/usb_data_enabled +Date: December 2020 +Contact: "Ray Chi" <raychi@google.com> +Description: + The attribute can allow user space can check and modify + the value to enable or disable usb functionality. Therefore, + if the attritube is set to 0, USB host and USB peripheral + modes wouldn't be working. + + Example: + Enable USB data functionality + # echo 1 > /sys/class/udc/.../device/usb_data_enabled + + Disable USB data functionality + # echo 0 > /sys/class/udc/.../device/usb_data_enabled + diff --git a/drivers/usb/dwc3/dwc3-msm.c b/drivers/usb/dwc3/dwc3-msm.c index b6b25c75b80c..561b109c3442 100644 --- a/drivers/usb/dwc3/dwc3-msm.c +++ b/drivers/usb/dwc3/dwc3-msm.c @@ -278,6 +278,7 @@ struct dwc3_msm { enum usb_device_speed override_usb_speed; bool core_init_failed; + bool usb_data_enabled; }; #define USB_HSPHY_3P3_VOL_MIN 3050000 /* uV */ @@ -2692,6 +2693,9 @@ static int dwc3_msm_id_notifier(struct notifier_block *nb, goto done; } + if (!mdwc->usb_data_enabled) + return NOTIFY_DONE; + id = event ? DWC3_ID_GROUND : DWC3_ID_FLOAT; dev_dbg(mdwc->dev, "host:%ld (id:%d) event received\n", event, id); @@ -2769,6 +2773,9 @@ static int dwc3_msm_vbus_notifier(struct notifier_block *nb, goto done; } + if (!mdwc->usb_data_enabled) + return NOTIFY_DONE; + dev_dbg(mdwc->dev, "vbus:%ld event received\n", event); if (mdwc->vbus_active == event) @@ -2977,7 +2984,6 @@ static ssize_t xhci_link_compliance_store(struct device *dev, return ret; } - static DEVICE_ATTR_RW(xhci_link_compliance); static ssize_t usb_compliance_mode_show(struct device *dev, @@ -3004,6 +3010,33 @@ static ssize_t usb_compliance_mode_store(struct device *dev, } static DEVICE_ATTR_RW(usb_compliance_mode); +static ssize_t usb_data_enabled_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct dwc3_msm *mdwc = dev_get_drvdata(dev); + + return sysfs_emit(buf, "%s\n", + mdwc->usb_data_enabled ? "enabled" : "disabled"); +} + +static ssize_t usb_data_enabled_store(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count) +{ + struct dwc3_msm *mdwc = dev_get_drvdata(dev); + + if (kstrtobool(buf, &mdwc->usb_data_enabled)) + return -EINVAL; + + if (!mdwc->usb_data_enabled) { + mdwc->vbus_active = false; + mdwc->id_state = DWC3_ID_FLOAT; + dwc3_ext_event_notify(mdwc); + } + + return count; +} +static DEVICE_ATTR_RW(usb_data_enabled); + static int dwc3_msm_probe(struct platform_device *pdev) { struct device_node *node = pdev->dev.of_node, *dwc3_node; @@ -3361,10 +3394,13 @@ static int dwc3_msm_probe(struct platform_device *pdev) dev_info(mdwc->dev, "charger detection in progress\n"); } + /* set the initial value */ + mdwc->usb_data_enabled = true; device_create_file(&pdev->dev, &dev_attr_mode); device_create_file(&pdev->dev, &dev_attr_speed); device_create_file(&pdev->dev, &dev_attr_xhci_link_compliance); device_create_file(&pdev->dev, &dev_attr_usb_compliance_mode); + device_create_file(&pdev->dev, &dev_attr_usb_data_enabled); host_mode = usb_get_dr_mode(&mdwc->dwc3->dev) == USB_DR_MODE_HOST; if (host_mode || @@ -3400,6 +3436,7 @@ static int dwc3_msm_remove(struct platform_device *pdev) device_remove_file(&pdev->dev, &dev_attr_mode); device_remove_file(&pdev->dev, &dev_attr_xhci_link_compliance); + device_create_file(&pdev->dev, &dev_attr_usb_data_enabled); if (cpu_to_affin) unregister_cpu_notifier(&mdwc->dwc3_cpu_notifier); |