Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > linux.kernel > #1595815 > unrolled thread
| Started by | Vivek Gautam <vivek.gautam@codeaurora.org> |
|---|---|
| First post | 2017-03-09 10:10 +0100 |
| Last post | 2017-03-09 12:50 +0100 |
| Articles | 5 — 2 participants |
Back to article view | Back to linux.kernel
[PATCH v5 0/4] phy: USB and PCIe phy drivers for Qcom chipsets Vivek Gautam <vivek.gautam@codeaurora.org> - 2017-03-09 10:10 +0100
[PATCH v5 3/4] dt-bindings: phy: Add support for QMP phy Vivek Gautam <vivek.gautam@codeaurora.org> - 2017-03-09 10:20 +0100
Re: [PATCH v5 3/4] dt-bindings: phy: Add support for QMP phy Bjorn Andersson <bjorn.andersson@linaro.org> - 2017-03-09 12:10 +0100
Re: [PATCH v5 3/4] dt-bindings: phy: Add support for QMP phy Vivek Gautam <vivek.gautam@codeaurora.org> - 2017-03-10 07:20 +0100
Re: [PATCH v5 4/4] phy: qcom-qmp: new qmp phy driver for qcom-chipsets Bjorn Andersson <bjorn.andersson@linaro.org> - 2017-03-09 12:50 +0100
| From | Vivek Gautam <vivek.gautam@codeaurora.org> |
|---|---|
| Date | 2017-03-09 10:10 +0100 |
| Subject | [PATCH v5 0/4] phy: USB and PCIe phy drivers for Qcom chipsets |
| Message-ID | <tj2f8-35K-17@gated-at.bofh.it> |
This patch series adds couple of PHY drivers for Qualcomm chipsets. a) qcom-qusb2 phy driver: that provides High Speed USB functionality. b) qcom-qmp phy driver: that is a combo phy providing support for USB3, PCIe, UFS and few other controllers. The patches are based on next branch of linux-phy tree. These patches have been tested on Dragon board db820c hardware with required set of dt patches and the patches to get rpm up on msm8996. Couple of other patches [1, 2] fixing DMA config for XHCI are also pulled in for testing. The complete branch is available in github [3]. Changes since v4: - Addressed comment to add child nodes for qmp phy driver. Each phy lane now has a separate child node under the main qmp node. - Modified the clock and reset initialization and enable methods. Different phys - pcie, usb and later ufs, have varying number of clocks and resets that are mandatory. So adding provision for clocks and reset lists helps in requesting all mandatory resources for individual phys and handle their failure cases accordingly. Changes since v3: - Addressed review comments given by Rob and Stephen for qusb2 phy and qmp phy bindings respectively. - Addressed review comments given by Stephen and Bjorn for qmp phy driver. Changes since v2: - Addressed review comments given by Rob and Stephen for bindings. - Addressed the review comments given by Stephen for the qusb2 and qmp phy drivers. Changes since v1: - Moved device tree binding documentation to separate patches, as suggested by Rob. - Addressed review comment regarding qfprom accesses by qusb2 phy driver, given by Rob. - Addressed review comments from Kishon. - Addressed review comments from Srinivas for QMP phy driver. - Addressed kbuild warning. Please see individual patches for detailed changelogs. [1] https://patchwork.kernel.org/patch/9567767/ [2] https://patchwork.kernel.org/patch/9567779/ [3] https://github.com/vivekgautam1/linux/tree/linux-v4.11-rc1-qmp-phy-db820c Vivek Gautam (4): dt-bindings: phy: Add support for QUSB2 phy phy: qcom-qusb2: New driver for QUSB2 PHY on Qcom chips dt-bindings: phy: Add support for QMP phy phy: qcom-qmp: new qmp phy driver for qcom-chipsets .../devicetree/bindings/phy/qcom-qmp-phy.txt | 106 ++ .../devicetree/bindings/phy/qcom-qusb2-phy.txt | 45 + drivers/phy/Kconfig | 18 + drivers/phy/Makefile | 2 + drivers/phy/phy-qcom-qmp.c | 1191 ++++++++++++++++++++ drivers/phy/phy-qcom-qusb2.c | 539 +++++++++ 6 files changed, 1901 insertions(+) create mode 100644 Documentation/devicetree/bindings/phy/qcom-qmp-phy.txt create mode 100644 Documentation/devicetree/bindings/phy/qcom-qusb2-phy.txt create mode 100644 drivers/phy/phy-qcom-qmp.c create mode 100644 drivers/phy/phy-qcom-qusb2.c -- The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum, a Linux Foundation Collaborative Project
[toc] | [next] | [standalone]
| From | Vivek Gautam <vivek.gautam@codeaurora.org> |
|---|---|
| Date | 2017-03-09 10:20 +0100 |
| Subject | [PATCH v5 3/4] dt-bindings: phy: Add support for QMP phy |
| Message-ID | <tj2oO-397-21@gated-at.bofh.it> |
| In reply to | #1595815 |
Qualcomm chipsets have QMP phy controller that provides
support to a number of controller, viz. PCIe, UFS, and USB.
Adding dt binding information for the same.
Signed-off-by: Vivek Gautam <vivek.gautam@codeaurora.org>
Cc: Rob Herring <robh@kernel.org>
---
Hi Rob,
I have removed your Acked-by tag because of the change in bindings.
Please consider adding your Ack again if you are fine with these
updated bindings.
Changes since v4:
- Added bindings for child nodes. Each phy lane is represented by child
node with its own register space (for tx, rx and pcs blocks), and clocks
and resets for power control facility.
- Removed register space and lane offsets for tx, rx and pcs blocks from
qmp phy node.
- #phy-cells is now part of each child node and thus must be 0.
- Added information on list of mandatory clocks and resets for each phy.
Changes since v3:
- Added #clock-cells = <1>, indicating that phy is a clock provider.
Changes since v2:
- Removed binding for "ref_clk_src" since we don't request this
clock in the driver.
- Addressed s/ref_clk/ref. Don't need to add '_clk' suffix to clock names.
- Using 'phy' for the node name.
Changes since v1:
- New patch, forked out of the original driver patch:
"phy: qcom-qmp: new qmp phy driver for qcom-chipsets"
- Added 'Acked-by' from Rob.
- Updated bindings to include mem resource as a list of
offset - length pair for serdes block and for each lane.
- Added a new binding for 'lane-offsets' that contains offsets
to tx, rx and pcs blocks from each lane base address.
.../devicetree/bindings/phy/qcom-qmp-phy.txt | 106 +++++++++++++++++++++
1 file changed, 106 insertions(+)
create mode 100644 Documentation/devicetree/bindings/phy/qcom-qmp-phy.txt
diff --git a/Documentation/devicetree/bindings/phy/qcom-qmp-phy.txt b/Documentation/devicetree/bindings/phy/qcom-qmp-phy.txt
new file mode 100644
index 000000000000..5595c3fabe0a
--- /dev/null
+++ b/Documentation/devicetree/bindings/phy/qcom-qmp-phy.txt
@@ -0,0 +1,106 @@
+Qualcomm QMP PHY controller
+===========================
+
+QMP phy controller supports physical layer functionality for a number of
+controllers on Qualcomm chipsets, such as, PCIe, UFS, and USB.
+
+Required properties:
+ - compatible: compatible list, contains:
+ "qcom,msm8996-qmp-pcie-phy" for 14nm PCIe phy on msm8996,
+ "qcom,msm8996-qmp-usb3-phy" for 14nm USB3 phy on msm8996.
+
+ - reg: offset and length of register set for PHY's common serdes block.
+
+ - #clock-cells: must be 1
+ - Phy pll outputs a bunch of clocks for Tx, Rx and Pipe
+ interface (for pipe based PHYs). These clock are then gate-controlled
+ by gcc.
+ - #address-cells: must be 1
+ - #size-cells: must be 1
+ - ranges: must be present
+
+ - clocks: a list of phandles and clock-specifier pairs,
+ one for each entry in clock-names.
+ - clock-names: "cfg_ahb" for phy config clock,
+ "aux" for phy aux clock,
+ "ref" for 19.2 MHz ref clk,
+ For "qcom,msm8996-qmp-pcie-phy" must contain:
+ "aux", "cfg_ahb", "ref".
+ For "qcom,msm8996-qmp-usb3-phy" must contain:
+ "aux", "cfg_ahb", "ref".
+
+ - resets: a list of phandles and reset controller specifier pairs,
+ one for each entry in reset-names.
+ - reset-names: "phy" for reset of phy block,
+ "common" for phy common block reset,
+ "cfg" for phy's ahb cfg block reset (Optional).
+ For "qcom,msm8996-qmp-pcie-phy" must contain:
+ "phy", "common", "cfg".
+ For "qcom,msm8996-qmp-usb3-phy" must contain
+ "phy", "common".
+
+ - vdda-phy-supply: Phandle to a regulator supply to PHY core block.
+ - vdda-pll-supply: Phandle to 1.8V regulator supply to PHY refclk pll block.
+
+Optional properties:
+ - vddp-ref-clk-supply: Phandle to a regulator supply to any specific refclk
+ pll block.
+
+Required nodes:
+ - Each device node of QMP phy is required to have as many child nodes as
+ the number of lanes the PHY has.
+
+Required properties for child node:
+ - reg: list of offset and length pairs of register sets for PHY blocks -
+ tx, rx and pcs.
+
+ - #phy-cells: must be 0
+
+ - clocks: a list of phandles and clock-specifier pairs,
+ one for each entry in clock-names.
+ - clock-names: Must contain following for pcie and usb qmp phys:
+ "pipe<lane-number>" for pipe clock specific to each lane.
+
+ - resets: a list of phandles and reset controller specifier pairs,
+ one for each entry in reset-names.
+ - reset-names: Must contain following for pcie qmp phys:
+ "lane<lane-number>" for reset specific to each lane.
+
+Example:
+ phy@34000 {
+ compatible = "qcom,msm8996-qmp-pcie-phy";
+ reg = <0x034000 0x488>;
+ #clock-cells = <1>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+
+ clocks = <&gcc GCC_PCIE_PHY_AUX_CLK>,
+ <&gcc GCC_PCIE_PHY_CFG_AHB_CLK>,
+ <&gcc GCC_PCIE_CLKREF_CLK>;
+ clock-names = "aux", "cfg_ahb", "ref";
+
+ vdda-phy-supply = <&pm8994_l28>;
+ vdda-pll-supply = <&pm8994_l12>;
+
+ resets = <&gcc GCC_PCIE_PHY_BCR>,
+ <&gcc GCC_PCIE_PHY_COM_BCR>,
+ <&gcc GCC_PCIE_PHY_COM_NOCSR_BCR>;
+ reset-names = "phy", "common", "cfg";
+
+ pciephy_0: lane@0 {
+ reg = <0x035000 0x130>,
+ <0x035200 0x200>,
+ <0x035400 0x1dc>;
+ #phy-cells = <0>;
+
+ clocks = <&gcc GCC_PCIE_0_PIPE_CLK>;
+ clock-names = "pipe0";
+ resets = <&gcc GCC_PCIE_0_PHY_BCR>;
+ reset-names = "lane0";
+ };
+
+ pciephy_1: lane@1 {
+ ...
+ ...
+ };
--
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project
[toc] | [prev] | [next] | [standalone]
| From | Bjorn Andersson <bjorn.andersson@linaro.org> |
|---|---|
| Date | 2017-03-09 12:10 +0100 |
| Subject | Re: [PATCH v5 3/4] dt-bindings: phy: Add support for QMP phy |
| Message-ID | <tj47h-4lW-53@gated-at.bofh.it> |
| In reply to | #1595824 |
On Thu 09 Mar 10:07 CET 2017, Vivek Gautam wrote:
[..]
> + phy@34000 {
> + compatible = "qcom,msm8996-qmp-pcie-phy";
> + reg = <0x034000 0x488>;
Drop the leading 0 from the address.
> + #clock-cells = <1>;
> + #address-cells = <1>;
> + #size-cells = <1>;
> + ranges;
> +
> + clocks = <&gcc GCC_PCIE_PHY_AUX_CLK>,
> + <&gcc GCC_PCIE_PHY_CFG_AHB_CLK>,
> + <&gcc GCC_PCIE_CLKREF_CLK>;
> + clock-names = "aux", "cfg_ahb", "ref";
> +
> + vdda-phy-supply = <&pm8994_l28>;
> + vdda-pll-supply = <&pm8994_l12>;
> +
> + resets = <&gcc GCC_PCIE_PHY_BCR>,
> + <&gcc GCC_PCIE_PHY_COM_BCR>,
> + <&gcc GCC_PCIE_PHY_COM_NOCSR_BCR>;
> + reset-names = "phy", "common", "cfg";
> +
> + pciephy_0: lane@0 {
The "@xyz" part should match the first value in "reg", i.e. 35000 here.
> + reg = <0x035000 0x130>,
> + <0x035200 0x200>,
> + <0x035400 0x1dc>;
> + #phy-cells = <0>;
> +
> + clocks = <&gcc GCC_PCIE_0_PIPE_CLK>;
> + clock-names = "pipe0";
> + resets = <&gcc GCC_PCIE_0_PHY_BCR>;
> + reset-names = "lane0";
> + };
> +
> + pciephy_1: lane@1 {
> + ...
> + ...
> + };
Regards,
Bjorn
[toc] | [prev] | [next] | [standalone]
| From | Vivek Gautam <vivek.gautam@codeaurora.org> |
|---|---|
| Date | 2017-03-10 07:20 +0100 |
| Subject | Re: [PATCH v5 3/4] dt-bindings: phy: Add support for QMP phy |
| Message-ID | <tjm49-83z-5@gated-at.bofh.it> |
| In reply to | #1595935 |
On 03/09/2017 04:37 PM, Bjorn Andersson wrote:
> On Thu 09 Mar 10:07 CET 2017, Vivek Gautam wrote:
>
> [..]
>> + phy@34000 {
>> + compatible = "qcom,msm8996-qmp-pcie-phy";
>> + reg = <0x034000 0x488>;
> Drop the leading 0 from the address.
Okay, will drop it.
>
>> + #clock-cells = <1>;
>> + #address-cells = <1>;
>> + #size-cells = <1>;
>> + ranges;
>> +
>> + clocks = <&gcc GCC_PCIE_PHY_AUX_CLK>,
>> + <&gcc GCC_PCIE_PHY_CFG_AHB_CLK>,
>> + <&gcc GCC_PCIE_CLKREF_CLK>;
>> + clock-names = "aux", "cfg_ahb", "ref";
>> +
>> + vdda-phy-supply = <&pm8994_l28>;
>> + vdda-pll-supply = <&pm8994_l12>;
>> +
>> + resets = <&gcc GCC_PCIE_PHY_BCR>,
>> + <&gcc GCC_PCIE_PHY_COM_BCR>,
>> + <&gcc GCC_PCIE_PHY_COM_NOCSR_BCR>;
>> + reset-names = "phy", "common", "cfg";
>> +
>> + pciephy_0: lane@0 {
> The "@xyz" part should match the first value in "reg", i.e. 35000 here.
Right, i think this came from my older version of patches. Will correct it.
Regards
Vivek
>
>> + reg = <0x035000 0x130>,
>> + <0x035200 0x200>,
>> + <0x035400 0x1dc>;
>> + #phy-cells = <0>;
>> +
>> + clocks = <&gcc GCC_PCIE_0_PIPE_CLK>;
>> + clock-names = "pipe0";
>> + resets = <&gcc GCC_PCIE_0_PHY_BCR>;
>> + reset-names = "lane0";
>> + };
>> +
>> + pciephy_1: lane@1 {
>> + ...
>> + ...
>> + };
> Regards,
> Bjorn
--
The Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project
[toc] | [prev] | [next] | [standalone]
| From | Bjorn Andersson <bjorn.andersson@linaro.org> |
|---|---|
| Date | 2017-03-09 12:50 +0100 |
| Subject | Re: [PATCH v5 4/4] phy: qcom-qmp: new qmp phy driver for qcom-chipsets |
| Message-ID | <tj4JY-4BF-29@gated-at.bofh.it> |
| In reply to | #1595815 |
On Thu 09 Mar 10:07 CET 2017, Vivek Gautam wrote:
[..]
> +static inline void qphy_setbits(void __iomem *base, u32 offset, u32 val)
> +{
> + u32 reg;
> +
> + reg = readl_relaxed(base + offset);
> + reg |= val;
> + writel_relaxed(reg, base + offset);
> +
> + /* Make sure that above writes are completed */
> + mb();
Same comments as on patch 2 wrt the use of _relaxed operations and
barriers (i.e. please don't).
> +}
> +
[..]
> +static int qcom_qmp_phy_poweron(struct phy *phy)
> +{
> + struct qmp_phy *qphy = phy_get_drvdata(phy);
> + struct qcom_qmp *qmp = qphy->qmp;
> + int ret;
> +
> + dev_vdbg(&phy->dev, "Powering on QMP phy\n");
> +
> + ret = regulator_enable(qmp->vdda_phy);
> + if (ret) {
> + dev_err(qmp->dev, "%s: vdda-phy enable failed, err=%d\n",
> + __func__, ret);
> + return ret;
> + }
> +
> + ret = regulator_enable(qmp->vdda_pll);
> + if (ret) {
> + dev_err(qmp->dev, "%s: vdda-pll enable failed, err=%d\n",
> + __func__, ret);
> + goto disable_vdda_phy;
> + }
> +
> + ret = regulator_enable(qmp->vddp_ref_clk);
> + if (ret) {
> + dev_err(qmp->dev,
> + "%s: vdda-ref-clk enable failed, err=%d\n",
> + __func__, ret);
> + goto disable_vdda_pll;
> + }
Please use the regulator_bulk interface here as well.
> +
> + ret = clk_prepare_enable(qphy->pipe_clk);
> + if (ret) {
> + dev_err(qmp->dev, "%s: pipe_clk enable failed, err=%d\n",
> + __func__, ret);
> + goto disable_vddp_ref_clk;
> + }
> +
> + return 0;
> +
> +disable_vddp_ref_clk:
> + regulator_disable(qmp->vddp_ref_clk);
> +disable_vdda_pll:
> + regulator_disable(qmp->vdda_pll);
> +disable_vdda_phy:
> + regulator_disable(qmp->vdda_phy);
> + return ret;
> +}
> +
[..]
> +static int phy_pipe_clk_register(struct qcom_qmp *qmp, int id)
> +{
> + char name[24];
> + struct clk_fixed_rate *fixed;
> + struct clk_init_data init = { };
> + int ret;
> +
> + switch (qmp->cfg->type) {
> + case PHY_TYPE_USB3:
> + snprintf(name, sizeof(name), "usb3_phy_pipe_clk_src");
> + break;
> + case PHY_TYPE_PCIE:
> + snprintf(name, sizeof(name), "pcie_%d_pipe_clk_src", id);
> + break;
> + default:
> + /* not all phys register pipe clocks, so return success */
> + return 0;
> + }
> +
> + fixed = devm_kzalloc(qmp->dev, sizeof(*fixed), GFP_KERNEL);
> + if (!fixed)
> + return -ENOMEM;
> +
> + init.name = name;
> + init.ops = &clk_fixed_rate_ops;
> +
> + /* controllers using QMP phys use 125MHz pipe clock interface */
> + fixed->fixed_rate = 125000000;
> + fixed->hw.init = &init;
> +
> + ret = devm_clk_hw_register(qmp->dev, &fixed->hw);
Drop "ret" and just return devm_clk_hw_register()
> +
> + return ret;
> +}
> +
> +static const struct phy_ops qcom_qmp_phy_gen_ops = {
> + .init = qcom_qmp_phy_init,
> + .exit = qcom_qmp_phy_exit,
> + .power_on = qcom_qmp_phy_poweron,
> + .power_off = qcom_qmp_phy_poweroff,
> + .owner = THIS_MODULE,
> +};
> +
> +static
> +int qcom_qmp_phy_create(struct device *dev, struct device_node *np, int id)
> +{
> + struct qcom_qmp *qmp = dev_get_drvdata(dev);
> + struct phy *generic_phy;
> + struct qmp_phy *qphy;
> + char prop_name[MAX_PROP_NAME];
> + int ret;
> +
> + qphy = devm_kzalloc(dev, sizeof(*qphy), GFP_KERNEL);
> + if (!qphy)
> + return -ENOMEM;
> +
> + /*
> + * Get memory resources for each phy lane:
> + * Resources are indexed as: tx -> 0; rx -> 1; pcs -> 2.
> + */
> + qphy->tx = of_iomap(np, 0);
> + if (IS_ERR(qphy->tx))
> + return PTR_ERR(qphy->tx);
> +
> + qphy->rx = of_iomap(np, 1);
> + if (IS_ERR(qphy->rx))
> + return PTR_ERR(qphy->rx);
> +
> + qphy->pcs = of_iomap(np, 2);
> + if (IS_ERR(qphy->pcs))
> + return PTR_ERR(qphy->pcs);
> +
> + /*
> + * Get PHY's Pipe clock, if any. USB3 and PCIe are PIPE3
> + * based phys, so they essentially have pipe clock. So,
> + * we return error in case phy is USB3 or PIPE type.
> + * Otherwise, we initialize pipe clock to NULL for
> + * all phys that don't need this.
> + */
> + snprintf(prop_name, sizeof(prop_name), "pipe%d", id);
> + qphy->pipe_clk = of_clk_get_by_name(np, prop_name);
> + if (IS_ERR(qphy->pipe_clk)) {
> + if (qmp->cfg->type == PHY_TYPE_PCIE ||
> + qmp->cfg->type == PHY_TYPE_USB3) {
> + ret = PTR_ERR(qphy->pipe_clk);
> + if (ret != -EPROBE_DEFER)
> + dev_err(dev,
> + "failed to get lane%d pipe_clk, %d\n",
> + id, ret);
> + return ret;
> + }
> + qphy->pipe_clk = NULL;
> + }
> +
> + /* Get lane reset, if any */
> + if (qmp->cfg->has_lane_rst) {
> + snprintf(prop_name, sizeof(prop_name), "lane%d", id);
> + qphy->lane_rst = of_reset_control_get(np, prop_name);
> + if (IS_ERR(qphy->lane_rst)) {
> + dev_err(dev, "failed to get lane%d reset\n", id);
> + return PTR_ERR(qphy->lane_rst);
> + }
> + }
> +
> + generic_phy = devm_phy_create(dev, np, &qcom_qmp_phy_gen_ops);
> + if (IS_ERR(generic_phy)) {
> + ret = PTR_ERR(generic_phy);
> + dev_err(dev, "failed to create qphy %d\n", ret);
> + return ret;
> + }
> +
> + qphy->phy = generic_phy;
> + qphy->index = id;
> + qphy->qmp = qmp;
> + qmp->phys[id] = qphy;
> + phy_set_drvdata(generic_phy, qphy);
> +
> + return ret;
Afaict "ret" might not be initialized here, just return 0;
> +}
> +
> +static const struct of_device_id qcom_qmp_phy_of_match_table[] = {
> + {
> + .compatible = "qcom,msm8996-qmp-pcie-phy",
> + .data = &msm8996_pciephy_cfg,
> + }, {
> + .compatible = "qcom,msm8996-qmp-usb3-phy",
> + .data = &msm8996_usb3phy_cfg,
> + },
> + { },
> +};
> +MODULE_DEVICE_TABLE(of, qcom_qmp_phy_of_match_table);
> +
> +static int qcom_qmp_phy_probe(struct platform_device *pdev)
> +{
> + struct qcom_qmp *qmp;
> + struct device *dev = &pdev->dev;
> + struct resource *res;
> + struct device_node *child;
> + struct phy_provider *phy_provider;
> + void __iomem *base;
> + int num, id;
> + int ret;
> +
> + qmp = devm_kzalloc(dev, sizeof(*qmp), GFP_KERNEL);
> + if (!qmp)
> + return -ENOMEM;
> +
> + qmp->dev = dev;
> + dev_set_drvdata(dev, qmp);
> +
> + res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> + base = devm_ioremap_resource(dev, res);
> + if (IS_ERR(base))
> + return PTR_ERR(base);
> +
> + /* per PHY serdes; usually located at base address */
> + qmp->serdes = base;
> +
> + mutex_init(&qmp->phy_mutex);
> +
> + /* Get the specific init parameters of QMP phy */
> + qmp->cfg = of_device_get_match_data(dev);
> +
> + ret = qcom_qmp_phy_clk_init(dev);
> + if (ret)
> + return ret;
> +
> + ret = qcom_qmp_phy_regulator_init(dev);
> + if (ret)
> + return ret;
> +
> + ret = qcom_qmp_phy_reset_init(dev);
> + if (ret)
> + return ret;
> +
> + num = of_get_available_child_count(dev->of_node);
> + /* do we have a rogue child node ? */
> + if (num > qmp->cfg->nlanes)
> + return -EINVAL;
> +
> + qmp->phys = devm_kcalloc(dev, num, sizeof(*qmp->phys), GFP_KERNEL);
> + if (!qmp->phys)
> + return -ENOMEM;
> +
> + id = 0;
> + for_each_available_child_of_node(dev->of_node, child) {
> + /* Create per-lane phy */
> + ret = qcom_qmp_phy_create(dev, child, id);
> + if (ret) {
> + dev_err(dev, "failed to create lane%d phy, %d\n",
> + id, ret);
> + return ret;
> + }
> +
> + /*
> + * Register the pipe clock provided by phy.
> + * See function description to see details of this pipe clock.
> + */
> + ret = phy_pipe_clk_register(qmp, id);
> + if (ret) {
> + dev_err(qmp->dev,
> + "failed to register pipe clock source\n");
> + return ret;
> + }
> + id++;
> + }
> +
> + phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
> + if (IS_ERR(phy_provider)) {
> + ret = PTR_ERR(phy_provider);
> + dev_err(dev, "failed to register qphy, %d\n", ret);
> + }
> +
> + return ret;
Replace this as well with return 0, to not just rely on the fact that
you 45 lines up will leave ret 0.
> +}
Regards,
Bjorn
[toc] | [prev] | [standalone]
Back to top | Article view | linux.kernel
csiph-web