From patchwork Wed May 18 21:24:11 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Arnd Bergmann X-Patchwork-Id: 102323 Delivered-To: patch@linaro.org Received: by 10.140.92.199 with SMTP id b65csp2858582qge; Wed, 18 May 2016 14:25:09 -0700 (PDT) X-Received: by 10.66.123.105 with SMTP id lz9mr14189681pab.37.1463606709484; Wed, 18 May 2016 14:25:09 -0700 (PDT) Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id r4si14462644paa.218.2016.05.18.14.25.09; Wed, 18 May 2016 14:25:09 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S932180AbcERVYx (ORCPT + 29 others); Wed, 18 May 2016 17:24:53 -0400 Received: from mout.kundenserver.de ([212.227.126.187]:58650 "EHLO mout.kundenserver.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752609AbcERVYv (ORCPT ); Wed, 18 May 2016 17:24:51 -0400 Received: from wuerfel.lan. ([78.42.132.4]) by mrelayeu.kundenserver.de (mreue004) with ESMTPA (Nemesis) id 0MPbr3-1az05R3pcf-004fwM; Wed, 18 May 2016 23:24:41 +0200 From: Arnd Bergmann To: Felipe Balbi Cc: Arnd Bergmann , Andy Gross , David Brown , Peter Chen , Greg Kroah-Hartman , Alan Stern , Mark Brown , Bjorn Andersson , linux-kernel@vger.kernel.org, linux-arm-msm@vger.kernel.org, linux-soc@vger.kernel.org, linux-usb@vger.kernel.org Subject: [RFC 6/8] usb: phy: qcom: use bulk regulator interfaces Date: Wed, 18 May 2016 23:24:11 +0200 Message-Id: <1463606653-325131-7-git-send-email-arnd@arndb.de> X-Mailer: git-send-email 2.7.0 In-Reply-To: <1463606653-325131-1-git-send-email-arnd@arndb.de> References: <1463606653-325131-1-git-send-email-arnd@arndb.de> X-Provags-ID: V03:K0:AlWWmv7llrkSLnTYmL/IaARqhGyDpGHPAkm8UgwHVMmZHoHsI47 VobQcNg0GeLjmoYfMx754DFB9fycQaT45QSyoOaOZZrb2WEQbFCTWOCpWSc/HBEzWeesuYI LawRx/fMg8289nuDHF1SgrkIpoJA3Wtmx8RxQaityrVFFprxDH4klkYJTEIcxwjqWuBsTFQ K7wWJJss46pcQh7Dm+/ng== X-UI-Out-Filterresults: notjunk:1; V01:K0:USzZ8bJ9//0=:+/DJZwRZl71RA0ZqvG/O+w 1AMCU7KlLJ6LxFcXsbR514ch4RSWUqJzu1o4tVlrYWhKPJ3g31w6JqyfJLo0pPK/5L1ExOw5t 6YNvGo+olIyGvDQPUR2nf/IUMRjeBeyf/B2EkGSlUbAdCH/FOoxZn9TN7X9QvcWpFjDxECuem 2rphoWyCbCmMq3LOgmrA4Hk3jXDmOIOx+L98FgG0XPaA2V7V3C42qxtbT2Bi8NF+xSFjfTw44 cAhBFPsLR/qDJXT83xixGAw2qFVWFSY6SDR37HsPnFu9E9wwfVeiP2XOafcF2ZXQ7o3G2ge9l mWor9PIHH7MrKrhKIayvm5k5wCJvnIDeDp5mWxYzJ/qokmxXMQ3aSEleHCVqxfIXuwc6ABFeI lrQxLoWL7ViVseLfHb1TN4Wd0sMHF1Qn4Of29tytm2edUIA51gDD3/DujEIs9ubszKQlek04T 6WQhUozllQ+OCDd6upaunRNj+nk+dAyyk7NKceWl++aDQ9E6OKKGj/3ZboR/Qq3joSActCZ9h asnypBAmzCZSuLCT2wANrH8PaNIkenvl5ZxhFuky3d7QeddnGg7LUH4P/1wyCguOC5XB41Tyd n4yWUBE+YycOgTbkJzg5qA6A7yTkRwy86ao4NPOpAn1+PHcF8Wx+RzDuoHgGOMNpDDDEIwneX MF47je3PtR2WQslYz/K2WivJh1X+dlyZGO2cIfWhE1rfOzTundj33THMmeBPoyMlVEjw= Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org When build-testing the phy-msm-usb driver, we can run into a gcc warning: drivers/usb/phy/phy-msm-usb.c: In function 'msm_otg_probe': drivers/usb/phy/phy-msm-usb.c:1735:14: error: 'regs[0].consumer' may be used uninitialized in this function [-Werror=maybe-uninitialized] drivers/usb/phy/phy-msm-usb.c:1736:14: error: 'regs[1].consumer' may be used uninitialized in this function [-Werror=maybe-uninitialized] drivers/usb/phy/phy-msm-usb.c:1737:14: error: 'regs[2].consumer' may be used uninitialized in this function [-Werror=maybe-uninitialized] Like in the phy-qcom-8x16-usb.c driver that was reworked in 7e8ac87a4474 ("usb: phy: qcom-8x16: fix regulator API abuse"), this warning goes away once we consistently use the bulk regulator API, which also simplifies the driver a bit. This patch should not change the behavior of the driver, other than how we now first set the voltage on all regulators and then enable or disable them, rather than doing it one regulator at a time. In particular, it looks like a mistake that msm_otg_remove() disables only two of the three regulators that are enabled in msm_otg_probe(), but changing that is left for another patch. Signed-off-by: Arnd Bergmann --- drivers/usb/phy/phy-msm-usb.c | 155 ++++++++++++++++++------------------------ 1 file changed, 65 insertions(+), 90 deletions(-) -- 2.7.0 diff --git a/drivers/usb/phy/phy-msm-usb.c b/drivers/usb/phy/phy-msm-usb.c index ea4ed6c17b00..bdcf049e465f 100644 --- a/drivers/usb/phy/phy-msm-usb.c +++ b/drivers/usb/phy/phy-msm-usb.c @@ -260,9 +260,7 @@ struct msm_otg { enum usb_chg_state chg_state; enum usb_chg_type chg_type; u8 dcd_retries; - struct regulator *v3p3; - struct regulator *v1p8; - struct regulator *vddcx; + struct regulator_bulk_data regulators[3]; struct reset_control *phy_rst; struct reset_control *link_rst; @@ -303,96 +301,69 @@ enum vdd_levels { VDD_LEVEL_MAX, }; +enum regulators { + VDDCX = 0, + V3P3 = 1, + V1P8 = 2, +}; + static int msm_hsusb_init_vddcx(struct msm_otg *motg, int init) { int ret = 0; + struct regulator *vddcx = motg->regulators[VDDCX].consumer; - if (init) { - ret = regulator_set_voltage(motg->vddcx, + if (init) + ret = regulator_set_voltage(vddcx, motg->vdd_levels[VDD_LEVEL_MIN], motg->vdd_levels[VDD_LEVEL_MAX]); - if (ret) { - dev_err(motg->phy.dev, "Cannot set vddcx voltage\n"); - return ret; - } - - ret = regulator_enable(motg->vddcx); - if (ret) - dev_err(motg->phy.dev, "unable to enable hsusb vddcx\n"); - } else { - ret = regulator_set_voltage(motg->vddcx, 0, + else + ret = regulator_set_voltage(vddcx, 0, motg->vdd_levels[VDD_LEVEL_MAX]); - if (ret) - dev_err(motg->phy.dev, "Cannot set vddcx voltage\n"); - ret = regulator_disable(motg->vddcx); - if (ret) - dev_err(motg->phy.dev, "unable to disable hsusb vddcx\n"); - } + + + if (ret) + dev_err(motg->phy.dev, "Cannot set vddcx voltage\n"); return ret; } -static int msm_hsusb_ldo_init(struct msm_otg *motg, int init) +static int msm_hsusb_ldo_init(struct msm_otg *motg) { int rc = 0; - if (init) { - rc = regulator_set_voltage(motg->v3p3, USB_PHY_3P3_VOL_MIN, - USB_PHY_3P3_VOL_MAX); - if (rc) { - dev_err(motg->phy.dev, "Cannot set v3p3 voltage\n"); - goto exit; - } - rc = regulator_enable(motg->v3p3); - if (rc) { - dev_err(motg->phy.dev, "unable to enable the hsusb 3p3\n"); - goto exit; - } - rc = regulator_set_voltage(motg->v1p8, USB_PHY_1P8_VOL_MIN, - USB_PHY_1P8_VOL_MAX); - if (rc) { - dev_err(motg->phy.dev, "Cannot set v1p8 voltage\n"); - goto disable_3p3; - } - rc = regulator_enable(motg->v1p8); - if (rc) { - dev_err(motg->phy.dev, "unable to enable the hsusb 1p8\n"); - goto disable_3p3; - } - - return 0; + rc = regulator_set_voltage(motg->regulators[V3P3].consumer, + USB_PHY_3P3_VOL_MIN, USB_PHY_3P3_VOL_MAX); + if (rc) { + dev_err(motg->phy.dev, "Cannot set v3p3 voltage\n"); + goto exit; + } + rc = regulator_set_voltage(motg->regulators[V1P8].consumer, + USB_PHY_1P8_VOL_MIN, USB_PHY_1P8_VOL_MAX); + if (rc) { + dev_err(motg->phy.dev, "Cannot set v1p8 voltage\n"); } - - regulator_disable(motg->v1p8); -disable_3p3: - regulator_disable(motg->v3p3); exit: return rc; } static int msm_hsusb_ldo_set_mode(struct msm_otg *motg, int on) { - int ret = 0; + int ret; + int load_v1p8 = on ? USB_PHY_1P8_HPM_LOAD : USB_PHY_1P8_LPM_LOAD; + int load_v3p3 = on ? USB_PHY_3P3_HPM_LOAD : USB_PHY_3P3_LPM_LOAD; + const char *state = on ? "HPM" : "LPM"; - if (on) { - ret = regulator_set_load(motg->v1p8, USB_PHY_1P8_HPM_LOAD); - if (ret < 0) { - pr_err("Could not set HPM for v1p8\n"); - return ret; - } - ret = regulator_set_load(motg->v3p3, USB_PHY_3P3_HPM_LOAD); - if (ret < 0) { - pr_err("Could not set HPM for v3p3\n"); - regulator_set_load(motg->v1p8, USB_PHY_1P8_LPM_LOAD); - return ret; - } - } else { - ret = regulator_set_load(motg->v1p8, USB_PHY_1P8_LPM_LOAD); - if (ret < 0) - pr_err("Could not set LPM for v1p8\n"); - ret = regulator_set_load(motg->v3p3, USB_PHY_3P3_LPM_LOAD); - if (ret < 0) - pr_err("Could not set LPM for v3p3\n"); + ret = regulator_set_load(motg->regulators[V1P8].consumer, load_v1p8); + if (ret < 0) { + pr_err("Could not set %s for v1p8\n", state); + return ret; + } + ret = regulator_set_load(motg->regulators[V3P3].consumer, load_v3p3); + if (ret < 0) { + pr_err("Could not set %s for v3p3\n", state); + regulator_set_load(motg->regulators[V1P8].consumer, + USB_PHY_1P8_LPM_LOAD); + return ret; } pr_debug("reg (%s)\n", on ? "HPM" : "LPM"); @@ -701,7 +672,8 @@ static int msm_hsusb_config_vddcx(struct msm_otg *motg, int high) else min_vol = motg->vdd_levels[VDD_LEVEL_NONE]; - ret = regulator_set_voltage(motg->vddcx, min_vol, max_vol); + ret = regulator_set_voltage(motg->regulators[VDDCX].consumer, + min_vol, max_vol); if (ret) { pr_err("Cannot set vddcx voltage\n"); return ret; @@ -1868,7 +1840,6 @@ static int msm_otg_reboot_notify(struct notifier_block *this, static int msm_otg_probe(struct platform_device *pdev) { - struct regulator_bulk_data regs[3]; int ret = 0; struct device_node *np = pdev->dev.of_node; struct msm_otg_platform_data *pdata; @@ -1950,18 +1921,16 @@ static int msm_otg_probe(struct platform_device *pdev) goto unregister_extcon; } - regs[0].supply = "vddcx"; - regs[1].supply = "v3p3"; - regs[2].supply = "v1p8"; + motg->regulators[VDDCX].supply = "vddcx"; + motg->regulators[V3P3].supply = "v3p3"; + motg->regulators[V1P8].supply = "v1p8"; - ret = devm_regulator_bulk_get(motg->phy.dev, ARRAY_SIZE(regs), regs); + ret = devm_regulator_bulk_get(motg->phy.dev, + ARRAY_SIZE(motg->regulators), + motg->regulators); if (ret) goto unregister_extcon; - motg->vddcx = regs[0].consumer; - motg->v3p3 = regs[1].consumer; - motg->v1p8 = regs[2].consumer; - clk_set_rate(motg->clk, 60000000); clk_prepare_enable(motg->clk); @@ -1976,15 +1945,21 @@ static int msm_otg_probe(struct platform_device *pdev) goto disable_clks; } - ret = msm_hsusb_ldo_init(motg, 1); + ret = msm_hsusb_ldo_init(motg); if (ret) { dev_err(&pdev->dev, "hsusb vreg configuration failed\n"); - goto disable_vddcx; + goto disable_clks; + } + ret = regulator_bulk_enable(ARRAY_SIZE(motg->regulators), motg->regulators); + if (ret) + { + dev_err(&pdev->dev, "hsusb could not enable regulators\n"); + goto disable_clks; } ret = msm_hsusb_ldo_set_mode(motg, 1); if (ret) { dev_err(&pdev->dev, "hsusb vreg enable failed\n"); - goto disable_ldo; + goto disable_regulators; } writel(0, USB_USBINTR); @@ -1996,7 +1971,7 @@ static int msm_otg_probe(struct platform_device *pdev) "msm_otg", motg); if (ret) { dev_err(&pdev->dev, "request irq failed\n"); - goto disable_ldo; + goto disable_regulators; } phy->init = msm_phy_init; @@ -2015,7 +1990,7 @@ static int msm_otg_probe(struct platform_device *pdev) ret = usb_add_phy_dev(&motg->phy); if (ret) { dev_err(&pdev->dev, "usb_add_phy failed\n"); - goto disable_ldo; + goto disable_regulators; } platform_set_drvdata(pdev, motg); @@ -2044,10 +2019,9 @@ static int msm_otg_probe(struct platform_device *pdev) return 0; -disable_ldo: - msm_hsusb_ldo_init(motg, 0); -disable_vddcx: +disable_regulators: msm_hsusb_init_vddcx(motg, 0); + regulator_bulk_disable(ARRAY_SIZE(motg->regulators), motg->regulators); disable_clks: clk_disable_unprepare(motg->pclk); clk_disable_unprepare(motg->clk); @@ -2114,7 +2088,8 @@ static int msm_otg_remove(struct platform_device *pdev) clk_disable_unprepare(motg->clk); if (!IS_ERR(motg->core_clk)) clk_disable_unprepare(motg->core_clk); - msm_hsusb_ldo_init(motg, 0); + /* vddcx is left active */ + regulator_bulk_disable(2, &motg->regulators[V3P3]); pm_runtime_set_suspended(&pdev->dev);