Loading Documentation/devicetree/bindings/usb/msm-ssusb.txt +12 −4 Original line number Diff line number Diff line Loading @@ -65,15 +65,23 @@ Optional properties : - qcom,use-pdc-interrupts: It present, it configures provided PDC IRQ with required configuration for wakeup functionality. - extcon: phandles to external connector devices. First phandle should point to external connector, which provide "USB" cable events, the second should point to external connector device, which provide "USB-HOST" cable events. A single phandle may be specified if a single connector device provides both "USB" and "USB-HOST" events. external connector, which provide type-C based "USB" cable events, the second should point to external connector device, which provide type-C "USB-HOST" cable events. A single phandle may be specified if a single connector device provides both "USB" and "USB-HOST" events. An optional third phandle may be specified for EUD based attach/detach events. A mandatory fourth phandle has to be specified to provide microUSB based "USB" cable events. An optional fifth phandle may be specified to provide microUSB based "USB-HOST" cable events. Only the fourth phandle may be specified if a single connector device provides both "USB" and "USB-HOST" events. - qcom,num-gsi-evt-buffs: If present, specifies number of GSI based hardware accelerated event buffers. 1 event buffer is needed per h/w accelerated endpoint. - qcom,pm-qos-latency: This represents max tolerable CPU latency in microsecs, which is used as a vote by driver to get max performance in perf mode. - qcom,smmu-s1-bypass: If present, configure SMMU to bypass stage 1 translation. - qcom,no-vbus-vote-with-type-C: If present, then do not try to get and enable VBUS regulator in type-C host mode from dwc3-msm driver. Sub nodes: - Sub node for "DWC3- USB3 controller". Loading drivers/usb/dwc3/dwc3-msm.c +50 −16 Original line number Diff line number Diff line Loading @@ -245,6 +245,10 @@ struct dwc3_msm { struct notifier_block dwc3_cpu_notifier; struct notifier_block usbdev_nb; bool hc_died; /* for usb connector either type-C or microAB */ bool type_c; /* whether to vote for VBUS reg in host mode */ bool no_vbus_vote_type_c; struct extcon_dev *extcon_vbus; struct extcon_dev *extcon_id; Loading Loading @@ -2898,7 +2902,7 @@ static int dwc3_msm_eud_notifier(struct notifier_block *nb, return NOTIFY_DONE; } static int dwc3_msm_extcon_register(struct dwc3_msm *mdwc) static int dwc3_msm_extcon_register(struct dwc3_msm *mdwc, int start_idx) { struct device_node *node = mdwc->dev->of_node; struct extcon_dev *edev; Loading @@ -2907,8 +2911,11 @@ static int dwc3_msm_extcon_register(struct dwc3_msm *mdwc) if (!of_property_read_bool(node, "extcon")) return 0; /* Use first phandle (mandatory) for USB vbus status notification */ edev = extcon_get_edev_by_phandle(mdwc->dev, 0); /* * Use mandatory phandle (index 0 for type-C; index 3 for microUSB) * for USB vbus status notification */ edev = extcon_get_edev_by_phandle(mdwc->dev, start_idx); if (IS_ERR(edev) && PTR_ERR(edev) != -ENODEV) return PTR_ERR(edev); Loading @@ -2923,9 +2930,12 @@ static int dwc3_msm_extcon_register(struct dwc3_msm *mdwc) } } /* Use second phandle (optional) for USB ID status notification */ if (of_count_phandle_with_args(node, "extcon", NULL) > 1) { edev = extcon_get_edev_by_phandle(mdwc->dev, 1); /* * Use optional phandle (index 1 for type-C; index 4 for microUSB) * for USB ID status notification */ if (of_count_phandle_with_args(node, "extcon", NULL) > start_idx + 1) { edev = extcon_get_edev_by_phandle(mdwc->dev, start_idx + 1); if (IS_ERR(edev) && PTR_ERR(edev) != -ENODEV) { ret = PTR_ERR(edev); goto err; Loading Loading @@ -2953,12 +2963,12 @@ static int dwc3_msm_extcon_register(struct dwc3_msm *mdwc) } edev = NULL; /* Use third phandle (optional) for EUD based detach/attach events */ /* Use optional phandle (index 2) for EUD based detach/attach events */ if (of_count_phandle_with_args(node, "extcon", NULL) > 2) { edev = extcon_get_edev_by_phandle(mdwc->dev, 2); if (IS_ERR(edev) && PTR_ERR(edev) != -ENODEV) { ret = PTR_ERR(edev); goto err1; goto err2; } } Loading Loading @@ -3408,10 +3418,6 @@ static int dwc3_msm_probe(struct platform_device *pdev) if (of_property_read_bool(node, "qcom,disable-dev-mode-pm")) pm_runtime_get_noresume(mdwc->dev); ret = dwc3_msm_extcon_register(mdwc); if (ret) goto put_dwc3; ret = of_property_read_u32(node, "qcom,pm-qos-latency", &mdwc->pm_qos_latency); if (ret) { Loading @@ -3419,15 +3425,34 @@ static int dwc3_msm_probe(struct platform_device *pdev) mdwc->pm_qos_latency = 0; } mdwc->no_vbus_vote_type_c = of_property_read_bool(node, "qcom,no-vbus-vote-with-type-C"); /* Mark type-C as true by default */ mdwc->type_c = true; mdwc->usb_psy = power_supply_get_by_name("usb"); if (!mdwc->usb_psy) { dev_warn(mdwc->dev, "Could not get usb power_supply\n"); pval.intval = -EINVAL; } else { power_supply_get_property(mdwc->usb_psy, POWER_SUPPLY_PROP_CONNECTOR_TYPE, &pval); if (pval.intval == POWER_SUPPLY_CONNECTOR_MICRO_USB) mdwc->type_c = false; power_supply_get_property(mdwc->usb_psy, POWER_SUPPLY_PROP_PRESENT, &pval); } /* * Extcon phandles starting indices in DT: * type-C : 0 * microUSB : 3 */ ret = dwc3_msm_extcon_register(mdwc, mdwc->type_c ? 0 : 3); if (ret) goto put_psy; mutex_init(&mdwc->suspend_resume_mutex); /* Update initial VBUS/ID state from extcon */ if (mdwc->extcon_vbus && extcon_get_state(mdwc->extcon_vbus, Loading Loading @@ -3456,6 +3481,12 @@ static int dwc3_msm_probe(struct platform_device *pdev) return 0; put_psy: if (mdwc->usb_psy) power_supply_put(mdwc->usb_psy); if (cpu_to_affin) unregister_cpu_notifier(&mdwc->dwc3_cpu_notifier); put_dwc3: if (mdwc->bus_perf_client) msm_bus_scale_unregister_client(mdwc->bus_perf_client); Loading @@ -3478,6 +3509,8 @@ static int dwc3_msm_remove(struct platform_device *pdev) int ret_pm; device_remove_file(&pdev->dev, &dev_attr_mode); if (mdwc->usb_psy) power_supply_put(mdwc->usb_psy); if (cpu_to_affin) unregister_cpu_notifier(&mdwc->dwc3_cpu_notifier); Loading Loading @@ -3680,7 +3713,8 @@ static int dwc3_otg_start_host(struct dwc3_msm *mdwc, int on) * IS_ERR: regulator could not be obtained, so skip using it * Valid pointer otherwise */ if (!mdwc->vbus_reg) { if (!mdwc->vbus_reg && (!mdwc->type_c || (mdwc->type_c && !mdwc->no_vbus_vote_type_c))) { mdwc->vbus_reg = devm_regulator_get_optional(mdwc->dev, "vbus_dwc3"); if (IS_ERR(mdwc->vbus_reg) && Loading @@ -3705,7 +3739,7 @@ static int dwc3_otg_start_host(struct dwc3_msm *mdwc, int on) pm_runtime_get_sync(mdwc->dev); dbg_event(0xFF, "StrtHost gync", atomic_read(&mdwc->dev->power.usage_count)); if (!IS_ERR(mdwc->vbus_reg)) if (!IS_ERR_OR_NULL(mdwc->vbus_reg)) ret = regulator_enable(mdwc->vbus_reg); if (ret) { dev_err(mdwc->dev, "unable to enable vbus_reg\n"); Loading @@ -3729,7 +3763,7 @@ static int dwc3_otg_start_host(struct dwc3_msm *mdwc, int on) dev_err(mdwc->dev, "%s: failed to add XHCI pdev ret=%d\n", __func__, ret); if (!IS_ERR(mdwc->vbus_reg)) if (!IS_ERR_OR_NULL(mdwc->vbus_reg)) regulator_disable(mdwc->vbus_reg); mdwc->hs_phy->flags &= ~PHY_HOST_MODE; mdwc->ss_phy->flags &= ~PHY_HOST_MODE; Loading Loading @@ -3770,7 +3804,7 @@ static int dwc3_otg_start_host(struct dwc3_msm *mdwc, int on) dev_dbg(mdwc->dev, "%s: turn off host\n", __func__); usb_unregister_atomic_notify(&mdwc->usbdev_nb); if (!IS_ERR(mdwc->vbus_reg)) if (!IS_ERR_OR_NULL(mdwc->vbus_reg)) ret = regulator_disable(mdwc->vbus_reg); if (ret) { dev_err(mdwc->dev, "unable to disable vbus_reg\n"); Loading Loading
Documentation/devicetree/bindings/usb/msm-ssusb.txt +12 −4 Original line number Diff line number Diff line Loading @@ -65,15 +65,23 @@ Optional properties : - qcom,use-pdc-interrupts: It present, it configures provided PDC IRQ with required configuration for wakeup functionality. - extcon: phandles to external connector devices. First phandle should point to external connector, which provide "USB" cable events, the second should point to external connector device, which provide "USB-HOST" cable events. A single phandle may be specified if a single connector device provides both "USB" and "USB-HOST" events. external connector, which provide type-C based "USB" cable events, the second should point to external connector device, which provide type-C "USB-HOST" cable events. A single phandle may be specified if a single connector device provides both "USB" and "USB-HOST" events. An optional third phandle may be specified for EUD based attach/detach events. A mandatory fourth phandle has to be specified to provide microUSB based "USB" cable events. An optional fifth phandle may be specified to provide microUSB based "USB-HOST" cable events. Only the fourth phandle may be specified if a single connector device provides both "USB" and "USB-HOST" events. - qcom,num-gsi-evt-buffs: If present, specifies number of GSI based hardware accelerated event buffers. 1 event buffer is needed per h/w accelerated endpoint. - qcom,pm-qos-latency: This represents max tolerable CPU latency in microsecs, which is used as a vote by driver to get max performance in perf mode. - qcom,smmu-s1-bypass: If present, configure SMMU to bypass stage 1 translation. - qcom,no-vbus-vote-with-type-C: If present, then do not try to get and enable VBUS regulator in type-C host mode from dwc3-msm driver. Sub nodes: - Sub node for "DWC3- USB3 controller". Loading
drivers/usb/dwc3/dwc3-msm.c +50 −16 Original line number Diff line number Diff line Loading @@ -245,6 +245,10 @@ struct dwc3_msm { struct notifier_block dwc3_cpu_notifier; struct notifier_block usbdev_nb; bool hc_died; /* for usb connector either type-C or microAB */ bool type_c; /* whether to vote for VBUS reg in host mode */ bool no_vbus_vote_type_c; struct extcon_dev *extcon_vbus; struct extcon_dev *extcon_id; Loading Loading @@ -2898,7 +2902,7 @@ static int dwc3_msm_eud_notifier(struct notifier_block *nb, return NOTIFY_DONE; } static int dwc3_msm_extcon_register(struct dwc3_msm *mdwc) static int dwc3_msm_extcon_register(struct dwc3_msm *mdwc, int start_idx) { struct device_node *node = mdwc->dev->of_node; struct extcon_dev *edev; Loading @@ -2907,8 +2911,11 @@ static int dwc3_msm_extcon_register(struct dwc3_msm *mdwc) if (!of_property_read_bool(node, "extcon")) return 0; /* Use first phandle (mandatory) for USB vbus status notification */ edev = extcon_get_edev_by_phandle(mdwc->dev, 0); /* * Use mandatory phandle (index 0 for type-C; index 3 for microUSB) * for USB vbus status notification */ edev = extcon_get_edev_by_phandle(mdwc->dev, start_idx); if (IS_ERR(edev) && PTR_ERR(edev) != -ENODEV) return PTR_ERR(edev); Loading @@ -2923,9 +2930,12 @@ static int dwc3_msm_extcon_register(struct dwc3_msm *mdwc) } } /* Use second phandle (optional) for USB ID status notification */ if (of_count_phandle_with_args(node, "extcon", NULL) > 1) { edev = extcon_get_edev_by_phandle(mdwc->dev, 1); /* * Use optional phandle (index 1 for type-C; index 4 for microUSB) * for USB ID status notification */ if (of_count_phandle_with_args(node, "extcon", NULL) > start_idx + 1) { edev = extcon_get_edev_by_phandle(mdwc->dev, start_idx + 1); if (IS_ERR(edev) && PTR_ERR(edev) != -ENODEV) { ret = PTR_ERR(edev); goto err; Loading Loading @@ -2953,12 +2963,12 @@ static int dwc3_msm_extcon_register(struct dwc3_msm *mdwc) } edev = NULL; /* Use third phandle (optional) for EUD based detach/attach events */ /* Use optional phandle (index 2) for EUD based detach/attach events */ if (of_count_phandle_with_args(node, "extcon", NULL) > 2) { edev = extcon_get_edev_by_phandle(mdwc->dev, 2); if (IS_ERR(edev) && PTR_ERR(edev) != -ENODEV) { ret = PTR_ERR(edev); goto err1; goto err2; } } Loading Loading @@ -3408,10 +3418,6 @@ static int dwc3_msm_probe(struct platform_device *pdev) if (of_property_read_bool(node, "qcom,disable-dev-mode-pm")) pm_runtime_get_noresume(mdwc->dev); ret = dwc3_msm_extcon_register(mdwc); if (ret) goto put_dwc3; ret = of_property_read_u32(node, "qcom,pm-qos-latency", &mdwc->pm_qos_latency); if (ret) { Loading @@ -3419,15 +3425,34 @@ static int dwc3_msm_probe(struct platform_device *pdev) mdwc->pm_qos_latency = 0; } mdwc->no_vbus_vote_type_c = of_property_read_bool(node, "qcom,no-vbus-vote-with-type-C"); /* Mark type-C as true by default */ mdwc->type_c = true; mdwc->usb_psy = power_supply_get_by_name("usb"); if (!mdwc->usb_psy) { dev_warn(mdwc->dev, "Could not get usb power_supply\n"); pval.intval = -EINVAL; } else { power_supply_get_property(mdwc->usb_psy, POWER_SUPPLY_PROP_CONNECTOR_TYPE, &pval); if (pval.intval == POWER_SUPPLY_CONNECTOR_MICRO_USB) mdwc->type_c = false; power_supply_get_property(mdwc->usb_psy, POWER_SUPPLY_PROP_PRESENT, &pval); } /* * Extcon phandles starting indices in DT: * type-C : 0 * microUSB : 3 */ ret = dwc3_msm_extcon_register(mdwc, mdwc->type_c ? 0 : 3); if (ret) goto put_psy; mutex_init(&mdwc->suspend_resume_mutex); /* Update initial VBUS/ID state from extcon */ if (mdwc->extcon_vbus && extcon_get_state(mdwc->extcon_vbus, Loading Loading @@ -3456,6 +3481,12 @@ static int dwc3_msm_probe(struct platform_device *pdev) return 0; put_psy: if (mdwc->usb_psy) power_supply_put(mdwc->usb_psy); if (cpu_to_affin) unregister_cpu_notifier(&mdwc->dwc3_cpu_notifier); put_dwc3: if (mdwc->bus_perf_client) msm_bus_scale_unregister_client(mdwc->bus_perf_client); Loading @@ -3478,6 +3509,8 @@ static int dwc3_msm_remove(struct platform_device *pdev) int ret_pm; device_remove_file(&pdev->dev, &dev_attr_mode); if (mdwc->usb_psy) power_supply_put(mdwc->usb_psy); if (cpu_to_affin) unregister_cpu_notifier(&mdwc->dwc3_cpu_notifier); Loading Loading @@ -3680,7 +3713,8 @@ static int dwc3_otg_start_host(struct dwc3_msm *mdwc, int on) * IS_ERR: regulator could not be obtained, so skip using it * Valid pointer otherwise */ if (!mdwc->vbus_reg) { if (!mdwc->vbus_reg && (!mdwc->type_c || (mdwc->type_c && !mdwc->no_vbus_vote_type_c))) { mdwc->vbus_reg = devm_regulator_get_optional(mdwc->dev, "vbus_dwc3"); if (IS_ERR(mdwc->vbus_reg) && Loading @@ -3705,7 +3739,7 @@ static int dwc3_otg_start_host(struct dwc3_msm *mdwc, int on) pm_runtime_get_sync(mdwc->dev); dbg_event(0xFF, "StrtHost gync", atomic_read(&mdwc->dev->power.usage_count)); if (!IS_ERR(mdwc->vbus_reg)) if (!IS_ERR_OR_NULL(mdwc->vbus_reg)) ret = regulator_enable(mdwc->vbus_reg); if (ret) { dev_err(mdwc->dev, "unable to enable vbus_reg\n"); Loading @@ -3729,7 +3763,7 @@ static int dwc3_otg_start_host(struct dwc3_msm *mdwc, int on) dev_err(mdwc->dev, "%s: failed to add XHCI pdev ret=%d\n", __func__, ret); if (!IS_ERR(mdwc->vbus_reg)) if (!IS_ERR_OR_NULL(mdwc->vbus_reg)) regulator_disable(mdwc->vbus_reg); mdwc->hs_phy->flags &= ~PHY_HOST_MODE; mdwc->ss_phy->flags &= ~PHY_HOST_MODE; Loading Loading @@ -3770,7 +3804,7 @@ static int dwc3_otg_start_host(struct dwc3_msm *mdwc, int on) dev_dbg(mdwc->dev, "%s: turn off host\n", __func__); usb_unregister_atomic_notify(&mdwc->usbdev_nb); if (!IS_ERR(mdwc->vbus_reg)) if (!IS_ERR_OR_NULL(mdwc->vbus_reg)) ret = regulator_disable(mdwc->vbus_reg); if (ret) { dev_err(mdwc->dev, "unable to disable vbus_reg\n"); Loading