Loading Documentation/devicetree/bindings/usb/msm-phy.txt +1 −1 Original line number Original line Diff line number Diff line Loading @@ -43,7 +43,7 @@ Optional properties: - clocks: a list of phandles to the PHY clocks. Use as per - clocks: a list of phandles to the PHY clocks. Use as per Documentation/devicetree/bindings/clock/clock-bindings.txt Documentation/devicetree/bindings/clock/clock-bindings.txt - clock-names: Names of the clocks in 1-1 correspondence with the "clocks" - clock-names: Names of the clocks in 1-1 correspondence with the "clocks" property. "cfg_ahb_clk" is an optional clock. property. "cfg_ahb_clk" and "com_aux_clk" are an optional clocks. - qcom,vbus-valid-override: If present, indicates VBUS pin is not connected to - qcom,vbus-valid-override: If present, indicates VBUS pin is not connected to the USB PHY and the controller must rely on external VBUS notification in the USB PHY and the controller must rely on external VBUS notification in order to manually relay the notification to the SSPHY. order to manually relay the notification to the SSPHY. Loading drivers/usb/phy/phy-msm-ssusb-qmp.c +93 −55 Original line number Original line Diff line number Diff line Loading @@ -84,6 +84,7 @@ struct msm_ssphy_qmp { struct clk *ref_clk_src; struct clk *ref_clk_src; struct clk *ref_clk; struct clk *ref_clk; struct clk *aux_clk; struct clk *aux_clk; struct clk *com_aux_clk; struct clk *cfg_ahb_clk; struct clk *cfg_ahb_clk; struct clk *pipe_clk; struct clk *pipe_clk; struct reset_control *phy_reset; struct reset_control *phy_reset; Loading Loading @@ -114,6 +115,8 @@ static const struct of_device_id msm_usb_id_table[] = { }; }; MODULE_DEVICE_TABLE(of, msm_usb_id_table); MODULE_DEVICE_TABLE(of, msm_usb_id_table); static void msm_ssphy_qmp_enable_clks(struct msm_ssphy_qmp *phy, bool on); static inline char *get_cable_status_str(struct msm_ssphy_qmp *phy) static inline char *get_cable_status_str(struct msm_ssphy_qmp *phy) { { return phy->cable_connected ? "connected" : "disconnected"; return phy->cable_connected ? "connected" : "disconnected"; Loading Loading @@ -292,17 +295,7 @@ static int msm_ssphy_qmp_init(struct usb_phy *uphy) return ret; return ret; } } if (!phy->clk_enabled) { msm_ssphy_qmp_enable_clks(phy, true); if (phy->ref_clk_src) clk_prepare_enable(phy->ref_clk_src); if (phy->ref_clk) clk_prepare_enable(phy->ref_clk); clk_prepare_enable(phy->aux_clk); clk_prepare_enable(phy->cfg_ahb_clk); clk_set_rate(phy->pipe_clk, 125000000); clk_prepare_enable(phy->pipe_clk); phy->clk_enabled = true; } writel_relaxed(0x01, writel_relaxed(0x01, phy->base + phy->phy_reg[USB3_PHY_POWER_DOWN_CONTROL]); phy->base + phy->phy_reg[USB3_PHY_POWER_DOWN_CONTROL]); Loading Loading @@ -469,29 +462,13 @@ static int msm_ssphy_qmp_set_suspend(struct usb_phy *uphy, int suspend) /* Make sure above write completed with PHY */ /* Make sure above write completed with PHY */ wmb(); wmb(); clk_disable_unprepare(phy->cfg_ahb_clk); msm_ssphy_qmp_enable_clks(phy, false); clk_disable_unprepare(phy->aux_clk); clk_disable_unprepare(phy->pipe_clk); if (phy->ref_clk) clk_disable_unprepare(phy->ref_clk); if (phy->ref_clk_src) clk_disable_unprepare(phy->ref_clk_src); phy->clk_enabled = false; phy->in_suspend = true; phy->in_suspend = true; msm_ssphy_power_enable(phy, 0); msm_ssphy_power_enable(phy, 0); dev_dbg(uphy->dev, "QMP PHY is suspend\n"); dev_dbg(uphy->dev, "QMP PHY is suspend\n"); } else { } else { msm_ssphy_power_enable(phy, 1); msm_ssphy_power_enable(phy, 1); clk_prepare_enable(phy->pipe_clk); msm_ssphy_qmp_enable_clks(phy, true); if (!phy->clk_enabled) { if (phy->ref_clk_src) clk_prepare_enable(phy->ref_clk_src); if (phy->ref_clk) clk_prepare_enable(phy->ref_clk); clk_prepare_enable(phy->aux_clk); clk_prepare_enable(phy->cfg_ahb_clk); phy->clk_enabled = true; } if (!phy->cable_connected) { if (!phy->cable_connected) { writel_relaxed(0x01, writel_relaxed(0x01, phy->base + phy->phy_reg[USB3_PHY_POWER_DOWN_CONTROL]); phy->base + phy->phy_reg[USB3_PHY_POWER_DOWN_CONTROL]); Loading Loading @@ -533,16 +510,9 @@ static int msm_ssphy_qmp_notify_disconnect(struct usb_phy *uphy, return 0; return 0; } } static int msm_ssphy_qmp_probe(struct platform_device *pdev) static int msm_ssphy_qmp_get_clks(struct msm_ssphy_qmp *phy, struct device *dev) { { struct msm_ssphy_qmp *phy; int ret = 0; struct device *dev = &pdev->dev; struct resource *res; int ret = 0, size = 0, len; phy = devm_kzalloc(dev, sizeof(*phy), GFP_KERNEL); if (!phy) return -ENOMEM; phy->aux_clk = devm_clk_get(dev, "aux_clk"); phy->aux_clk = devm_clk_get(dev, "aux_clk"); if (IS_ERR(phy->aux_clk)) { if (IS_ERR(phy->aux_clk)) { Loading @@ -552,10 +522,9 @@ static int msm_ssphy_qmp_probe(struct platform_device *pdev) dev_err(dev, "failed to get aux_clk\n"); dev_err(dev, "failed to get aux_clk\n"); goto err; goto err; } } clk_set_rate(phy->aux_clk, clk_round_rate(phy->aux_clk, ULONG_MAX)); clk_set_rate(phy->aux_clk, clk_round_rate(phy->aux_clk, ULONG_MAX)); if (of_property_match_string(pdev->dev.of_node, if (of_property_match_string(dev->of_node, "clock-names", "cfg_ahb_clk") >= 0) { "clock-names", "cfg_ahb_clk") >= 0) { phy->cfg_ahb_clk = devm_clk_get(dev, "cfg_ahb_clk"); phy->cfg_ahb_clk = devm_clk_get(dev, "cfg_ahb_clk"); if (IS_ERR(phy->cfg_ahb_clk)) { if (IS_ERR(phy->cfg_ahb_clk)) { Loading @@ -576,6 +545,88 @@ static int msm_ssphy_qmp_probe(struct platform_device *pdev) goto err; goto err; } } phy->ref_clk_src = devm_clk_get(dev, "ref_clk_src"); if (IS_ERR(phy->ref_clk_src)) phy->ref_clk_src = NULL; phy->ref_clk = devm_clk_get(dev, "ref_clk"); if (IS_ERR(phy->ref_clk)) phy->ref_clk = NULL; if (of_property_match_string(dev->of_node, "clock-names", "com_aux_clk") >= 0) { phy->com_aux_clk = devm_clk_get(dev, "com_aux_clk"); if (IS_ERR(phy->com_aux_clk)) { ret = PTR_ERR(phy->com_aux_clk); if (ret != -EPROBE_DEFER) dev_err(dev, "failed to get com_aux_clk ret %d\n", ret); goto err; } } err: return ret; } static void msm_ssphy_qmp_enable_clks(struct msm_ssphy_qmp *phy, bool on) { dev_dbg(phy->phy.dev, "%s(): clk_enabled:%d on:%d\n", __func__, phy->clk_enabled, on); if (!phy->clk_enabled && on) { if (phy->ref_clk_src) clk_prepare_enable(phy->ref_clk_src); if (phy->ref_clk) clk_prepare_enable(phy->ref_clk); if (phy->com_aux_clk) clk_prepare_enable(phy->com_aux_clk); clk_prepare_enable(phy->aux_clk); if (phy->cfg_ahb_clk) clk_prepare_enable(phy->cfg_ahb_clk); clk_prepare_enable(phy->pipe_clk); phy->clk_enabled = true; } if (phy->clk_enabled && !on) { clk_disable_unprepare(phy->pipe_clk); if (phy->cfg_ahb_clk) clk_disable_unprepare(phy->cfg_ahb_clk); clk_disable_unprepare(phy->aux_clk); if (phy->com_aux_clk) clk_disable_unprepare(phy->com_aux_clk); if (phy->ref_clk) clk_disable_unprepare(phy->ref_clk); if (phy->ref_clk_src) clk_disable_unprepare(phy->ref_clk_src); phy->clk_enabled = false; } } static int msm_ssphy_qmp_probe(struct platform_device *pdev) { struct msm_ssphy_qmp *phy; struct device *dev = &pdev->dev; struct resource *res; int ret = 0, size = 0, len; phy = devm_kzalloc(dev, sizeof(*phy), GFP_KERNEL); if (!phy) return -ENOMEM; ret = msm_ssphy_qmp_get_clks(phy, dev); if (ret) goto err; phy->phy_reset = devm_reset_control_get(dev, "phy_reset"); phy->phy_reset = devm_reset_control_get(dev, "phy_reset"); if (IS_ERR(phy->phy_reset)) { if (IS_ERR(phy->phy_reset)) { ret = PTR_ERR(phy->phy_reset); ret = PTR_ERR(phy->phy_reset); Loading Loading @@ -726,13 +777,6 @@ static int msm_ssphy_qmp_probe(struct platform_device *pdev) goto err; goto err; } } phy->ref_clk_src = devm_clk_get(dev, "ref_clk_src"); if (IS_ERR(phy->ref_clk_src)) phy->ref_clk_src = NULL; phy->ref_clk = devm_clk_get(dev, "ref_clk"); if (IS_ERR(phy->ref_clk)) phy->ref_clk = NULL; platform_set_drvdata(pdev, phy); platform_set_drvdata(pdev, phy); if (of_property_read_bool(dev->of_node, "qcom,vbus-valid-override")) if (of_property_read_bool(dev->of_node, "qcom,vbus-valid-override")) Loading Loading @@ -760,14 +804,8 @@ static int msm_ssphy_qmp_remove(struct platform_device *pdev) return 0; return 0; usb_remove_phy(&phy->phy); usb_remove_phy(&phy->phy); if (phy->ref_clk) msm_ssphy_qmp_enable_clks(phy, false); clk_disable_unprepare(phy->ref_clk); if (phy->ref_clk_src) clk_disable_unprepare(phy->ref_clk_src); msm_ssusb_qmp_ldo_enable(phy, 0); msm_ssusb_qmp_ldo_enable(phy, 0); clk_disable_unprepare(phy->aux_clk); clk_disable_unprepare(phy->cfg_ahb_clk); clk_disable_unprepare(phy->pipe_clk); kfree(phy); kfree(phy); return 0; return 0; } } Loading Loading
Documentation/devicetree/bindings/usb/msm-phy.txt +1 −1 Original line number Original line Diff line number Diff line Loading @@ -43,7 +43,7 @@ Optional properties: - clocks: a list of phandles to the PHY clocks. Use as per - clocks: a list of phandles to the PHY clocks. Use as per Documentation/devicetree/bindings/clock/clock-bindings.txt Documentation/devicetree/bindings/clock/clock-bindings.txt - clock-names: Names of the clocks in 1-1 correspondence with the "clocks" - clock-names: Names of the clocks in 1-1 correspondence with the "clocks" property. "cfg_ahb_clk" is an optional clock. property. "cfg_ahb_clk" and "com_aux_clk" are an optional clocks. - qcom,vbus-valid-override: If present, indicates VBUS pin is not connected to - qcom,vbus-valid-override: If present, indicates VBUS pin is not connected to the USB PHY and the controller must rely on external VBUS notification in the USB PHY and the controller must rely on external VBUS notification in order to manually relay the notification to the SSPHY. order to manually relay the notification to the SSPHY. Loading
drivers/usb/phy/phy-msm-ssusb-qmp.c +93 −55 Original line number Original line Diff line number Diff line Loading @@ -84,6 +84,7 @@ struct msm_ssphy_qmp { struct clk *ref_clk_src; struct clk *ref_clk_src; struct clk *ref_clk; struct clk *ref_clk; struct clk *aux_clk; struct clk *aux_clk; struct clk *com_aux_clk; struct clk *cfg_ahb_clk; struct clk *cfg_ahb_clk; struct clk *pipe_clk; struct clk *pipe_clk; struct reset_control *phy_reset; struct reset_control *phy_reset; Loading Loading @@ -114,6 +115,8 @@ static const struct of_device_id msm_usb_id_table[] = { }; }; MODULE_DEVICE_TABLE(of, msm_usb_id_table); MODULE_DEVICE_TABLE(of, msm_usb_id_table); static void msm_ssphy_qmp_enable_clks(struct msm_ssphy_qmp *phy, bool on); static inline char *get_cable_status_str(struct msm_ssphy_qmp *phy) static inline char *get_cable_status_str(struct msm_ssphy_qmp *phy) { { return phy->cable_connected ? "connected" : "disconnected"; return phy->cable_connected ? "connected" : "disconnected"; Loading Loading @@ -292,17 +295,7 @@ static int msm_ssphy_qmp_init(struct usb_phy *uphy) return ret; return ret; } } if (!phy->clk_enabled) { msm_ssphy_qmp_enable_clks(phy, true); if (phy->ref_clk_src) clk_prepare_enable(phy->ref_clk_src); if (phy->ref_clk) clk_prepare_enable(phy->ref_clk); clk_prepare_enable(phy->aux_clk); clk_prepare_enable(phy->cfg_ahb_clk); clk_set_rate(phy->pipe_clk, 125000000); clk_prepare_enable(phy->pipe_clk); phy->clk_enabled = true; } writel_relaxed(0x01, writel_relaxed(0x01, phy->base + phy->phy_reg[USB3_PHY_POWER_DOWN_CONTROL]); phy->base + phy->phy_reg[USB3_PHY_POWER_DOWN_CONTROL]); Loading Loading @@ -469,29 +462,13 @@ static int msm_ssphy_qmp_set_suspend(struct usb_phy *uphy, int suspend) /* Make sure above write completed with PHY */ /* Make sure above write completed with PHY */ wmb(); wmb(); clk_disable_unprepare(phy->cfg_ahb_clk); msm_ssphy_qmp_enable_clks(phy, false); clk_disable_unprepare(phy->aux_clk); clk_disable_unprepare(phy->pipe_clk); if (phy->ref_clk) clk_disable_unprepare(phy->ref_clk); if (phy->ref_clk_src) clk_disable_unprepare(phy->ref_clk_src); phy->clk_enabled = false; phy->in_suspend = true; phy->in_suspend = true; msm_ssphy_power_enable(phy, 0); msm_ssphy_power_enable(phy, 0); dev_dbg(uphy->dev, "QMP PHY is suspend\n"); dev_dbg(uphy->dev, "QMP PHY is suspend\n"); } else { } else { msm_ssphy_power_enable(phy, 1); msm_ssphy_power_enable(phy, 1); clk_prepare_enable(phy->pipe_clk); msm_ssphy_qmp_enable_clks(phy, true); if (!phy->clk_enabled) { if (phy->ref_clk_src) clk_prepare_enable(phy->ref_clk_src); if (phy->ref_clk) clk_prepare_enable(phy->ref_clk); clk_prepare_enable(phy->aux_clk); clk_prepare_enable(phy->cfg_ahb_clk); phy->clk_enabled = true; } if (!phy->cable_connected) { if (!phy->cable_connected) { writel_relaxed(0x01, writel_relaxed(0x01, phy->base + phy->phy_reg[USB3_PHY_POWER_DOWN_CONTROL]); phy->base + phy->phy_reg[USB3_PHY_POWER_DOWN_CONTROL]); Loading Loading @@ -533,16 +510,9 @@ static int msm_ssphy_qmp_notify_disconnect(struct usb_phy *uphy, return 0; return 0; } } static int msm_ssphy_qmp_probe(struct platform_device *pdev) static int msm_ssphy_qmp_get_clks(struct msm_ssphy_qmp *phy, struct device *dev) { { struct msm_ssphy_qmp *phy; int ret = 0; struct device *dev = &pdev->dev; struct resource *res; int ret = 0, size = 0, len; phy = devm_kzalloc(dev, sizeof(*phy), GFP_KERNEL); if (!phy) return -ENOMEM; phy->aux_clk = devm_clk_get(dev, "aux_clk"); phy->aux_clk = devm_clk_get(dev, "aux_clk"); if (IS_ERR(phy->aux_clk)) { if (IS_ERR(phy->aux_clk)) { Loading @@ -552,10 +522,9 @@ static int msm_ssphy_qmp_probe(struct platform_device *pdev) dev_err(dev, "failed to get aux_clk\n"); dev_err(dev, "failed to get aux_clk\n"); goto err; goto err; } } clk_set_rate(phy->aux_clk, clk_round_rate(phy->aux_clk, ULONG_MAX)); clk_set_rate(phy->aux_clk, clk_round_rate(phy->aux_clk, ULONG_MAX)); if (of_property_match_string(pdev->dev.of_node, if (of_property_match_string(dev->of_node, "clock-names", "cfg_ahb_clk") >= 0) { "clock-names", "cfg_ahb_clk") >= 0) { phy->cfg_ahb_clk = devm_clk_get(dev, "cfg_ahb_clk"); phy->cfg_ahb_clk = devm_clk_get(dev, "cfg_ahb_clk"); if (IS_ERR(phy->cfg_ahb_clk)) { if (IS_ERR(phy->cfg_ahb_clk)) { Loading @@ -576,6 +545,88 @@ static int msm_ssphy_qmp_probe(struct platform_device *pdev) goto err; goto err; } } phy->ref_clk_src = devm_clk_get(dev, "ref_clk_src"); if (IS_ERR(phy->ref_clk_src)) phy->ref_clk_src = NULL; phy->ref_clk = devm_clk_get(dev, "ref_clk"); if (IS_ERR(phy->ref_clk)) phy->ref_clk = NULL; if (of_property_match_string(dev->of_node, "clock-names", "com_aux_clk") >= 0) { phy->com_aux_clk = devm_clk_get(dev, "com_aux_clk"); if (IS_ERR(phy->com_aux_clk)) { ret = PTR_ERR(phy->com_aux_clk); if (ret != -EPROBE_DEFER) dev_err(dev, "failed to get com_aux_clk ret %d\n", ret); goto err; } } err: return ret; } static void msm_ssphy_qmp_enable_clks(struct msm_ssphy_qmp *phy, bool on) { dev_dbg(phy->phy.dev, "%s(): clk_enabled:%d on:%d\n", __func__, phy->clk_enabled, on); if (!phy->clk_enabled && on) { if (phy->ref_clk_src) clk_prepare_enable(phy->ref_clk_src); if (phy->ref_clk) clk_prepare_enable(phy->ref_clk); if (phy->com_aux_clk) clk_prepare_enable(phy->com_aux_clk); clk_prepare_enable(phy->aux_clk); if (phy->cfg_ahb_clk) clk_prepare_enable(phy->cfg_ahb_clk); clk_prepare_enable(phy->pipe_clk); phy->clk_enabled = true; } if (phy->clk_enabled && !on) { clk_disable_unprepare(phy->pipe_clk); if (phy->cfg_ahb_clk) clk_disable_unprepare(phy->cfg_ahb_clk); clk_disable_unprepare(phy->aux_clk); if (phy->com_aux_clk) clk_disable_unprepare(phy->com_aux_clk); if (phy->ref_clk) clk_disable_unprepare(phy->ref_clk); if (phy->ref_clk_src) clk_disable_unprepare(phy->ref_clk_src); phy->clk_enabled = false; } } static int msm_ssphy_qmp_probe(struct platform_device *pdev) { struct msm_ssphy_qmp *phy; struct device *dev = &pdev->dev; struct resource *res; int ret = 0, size = 0, len; phy = devm_kzalloc(dev, sizeof(*phy), GFP_KERNEL); if (!phy) return -ENOMEM; ret = msm_ssphy_qmp_get_clks(phy, dev); if (ret) goto err; phy->phy_reset = devm_reset_control_get(dev, "phy_reset"); phy->phy_reset = devm_reset_control_get(dev, "phy_reset"); if (IS_ERR(phy->phy_reset)) { if (IS_ERR(phy->phy_reset)) { ret = PTR_ERR(phy->phy_reset); ret = PTR_ERR(phy->phy_reset); Loading Loading @@ -726,13 +777,6 @@ static int msm_ssphy_qmp_probe(struct platform_device *pdev) goto err; goto err; } } phy->ref_clk_src = devm_clk_get(dev, "ref_clk_src"); if (IS_ERR(phy->ref_clk_src)) phy->ref_clk_src = NULL; phy->ref_clk = devm_clk_get(dev, "ref_clk"); if (IS_ERR(phy->ref_clk)) phy->ref_clk = NULL; platform_set_drvdata(pdev, phy); platform_set_drvdata(pdev, phy); if (of_property_read_bool(dev->of_node, "qcom,vbus-valid-override")) if (of_property_read_bool(dev->of_node, "qcom,vbus-valid-override")) Loading Loading @@ -760,14 +804,8 @@ static int msm_ssphy_qmp_remove(struct platform_device *pdev) return 0; return 0; usb_remove_phy(&phy->phy); usb_remove_phy(&phy->phy); if (phy->ref_clk) msm_ssphy_qmp_enable_clks(phy, false); clk_disable_unprepare(phy->ref_clk); if (phy->ref_clk_src) clk_disable_unprepare(phy->ref_clk_src); msm_ssusb_qmp_ldo_enable(phy, 0); msm_ssusb_qmp_ldo_enable(phy, 0); clk_disable_unprepare(phy->aux_clk); clk_disable_unprepare(phy->cfg_ahb_clk); clk_disable_unprepare(phy->pipe_clk); kfree(phy); kfree(phy); return 0; return 0; } } Loading