From patchwork Wed May 7 03:50:19 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Maxime Ripard X-Patchwork-Id: 4125391 Return-Path: X-Original-To: patchwork-linux-arm@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.19.201]) by patchwork2.web.kernel.org (Postfix) with ESMTP id A1AA2BFF02 for ; Wed, 7 May 2014 04:04:36 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id A1CDB20256 for ; Wed, 7 May 2014 04:04:34 +0000 (UTC) Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.9]) (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id B62B320254 for ; Wed, 7 May 2014 04:04:33 +0000 (UTC) Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.80.1 #2 (Red Hat Linux)) id 1Wht3j-0005bo-Dg; Wed, 07 May 2014 04:02:19 +0000 Received: from top.free-electrons.com ([176.31.233.9] helo=mail.free-electrons.com) by bombadil.infradead.org with esmtp (Exim 4.80.1 #2 (Red Hat Linux)) id 1Wht3f-0005S9-P6 for linux-arm-kernel@lists.infradead.org; Wed, 07 May 2014 04:02:16 +0000 Received: by mail.free-electrons.com (Postfix, from userid 106) id 593AE1240; Wed, 7 May 2014 06:01:54 +0200 (CEST) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Spam-Level: X-Spam-Status: No, score=-2.5 required=5.0 tests=BAYES_00,RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 Received: from localhost (unknown [189.162.6.66]) by mail.free-electrons.com (Postfix) with ESMTPSA id 00E97535; Wed, 7 May 2014 06:01:51 +0200 (CEST) From: Maxime Ripard To: Emilio Lopez , Mike Turquette , stern@rowland.harvard.edu, kishon@ti.com, hdegoede@redhat.com Subject: [PATCH 3/7] phy: usb: sunxi: Introduce Allwinner A31 USB PHY support Date: Tue, 6 May 2014 22:50:19 -0500 Message-Id: <1399434623-20383-4-git-send-email-maxime.ripard@free-electrons.com> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1399434623-20383-1-git-send-email-maxime.ripard@free-electrons.com> References: <1399434623-20383-1-git-send-email-maxime.ripard@free-electrons.com> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20140506_210216_112738_8DF3361F X-CRM114-Status: GOOD ( 14.90 ) X-Spam-Score: 0.3 (/) Cc: linux-sunxi@googlegroups.com, linux-usb@vger.kernel.org, linux-kernel@vger.kernel.org, zhuzhenhua@allwinnertech.com, Boris Brezillon , kevin.z.m.zh@gmail.com, sunny@allwinnertech.com, shuge@allwinnertech.com, Maxime Ripard , linux-arm-kernel@lists.infradead.org X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org X-Virus-Scanned: ClamAV using ClamSMTP The USB phy controller in the A31 differs mostly from the older controllers because it has a clock dedicated for each phy, while the older ones were having a single clock for all the phys. Signed-off-by: Maxime Ripard --- drivers/phy/phy-sun4i-usb.c | 35 ++++++++++++++++++++++++++--------- 1 file changed, 26 insertions(+), 9 deletions(-) diff --git a/drivers/phy/phy-sun4i-usb.c b/drivers/phy/phy-sun4i-usb.c index e6e6c4ba7145..1d83abe07a29 100644 --- a/drivers/phy/phy-sun4i-usb.c +++ b/drivers/phy/phy-sun4i-usb.c @@ -61,16 +61,17 @@ #define MAX_PHYS 3 struct sun4i_usb_phy_data { - struct clk *clk; void __iomem *base; struct mutex mutex; int num_phys; u32 disc_thresh; + bool dedicated_clocks; struct sun4i_usb_phy { struct phy *phy; void __iomem *pmu; struct regulator *vbus; struct reset_control *reset; + struct clk *clk; int index; } phys[MAX_PHYS]; }; @@ -146,13 +147,13 @@ static int sun4i_usb_phy_init(struct phy *_phy) struct sun4i_usb_phy_data *data = to_sun4i_usb_phy_data(phy); int ret; - ret = clk_prepare_enable(data->clk); + ret = clk_prepare_enable(phy->clk); if (ret) return ret; ret = reset_control_deassert(phy->reset); if (ret) { - clk_disable_unprepare(data->clk); + clk_disable_unprepare(phy->clk); return ret; } @@ -170,11 +171,10 @@ static int sun4i_usb_phy_init(struct phy *_phy) static int sun4i_usb_phy_exit(struct phy *_phy) { struct sun4i_usb_phy *phy = phy_get_drvdata(_phy); - struct sun4i_usb_phy_data *data = to_sun4i_usb_phy_data(phy); sun4i_usb_phy_passby(phy, 0); reset_control_assert(phy->reset); - clk_disable_unprepare(data->clk); + clk_disable_unprepare(phy->clk); return 0; } @@ -230,6 +230,7 @@ static int sun4i_usb_phy_probe(struct platform_device *pdev) struct regulator *vbus; struct resource *res; struct phy *phy; + struct clk *clk; char name[16]; int i; @@ -249,15 +250,20 @@ static int sun4i_usb_phy_probe(struct platform_device *pdev) else data->disc_thresh = 2; + if (of_device_is_compatible(np, "allwinner,sun6i-a31-usb-phy")) + data->dedicated_clocks = true; + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "phy_ctrl"); data->base = devm_ioremap_resource(dev, res); if (IS_ERR(data->base)) return PTR_ERR(data->base); - data->clk = devm_clk_get(dev, "usb_phy"); - if (IS_ERR(data->clk)) { - dev_err(dev, "could not get usb_phy clock\n"); - return PTR_ERR(data->clk); + if (!data->dedicated_clocks) { + clk = devm_clk_get(dev, "usb_phy"); + if (IS_ERR(clk)) { + dev_err(dev, "could not get usb_phy clock\n"); + return PTR_ERR(clk); + } } /* Skip 0, 0 is the phy for otg which is not yet supported. */ @@ -270,6 +276,15 @@ static int sun4i_usb_phy_probe(struct platform_device *pdev) vbus = NULL; } + if (data->dedicated_clocks) { + snprintf(name, sizeof(name), "usb%d_phy", i); + clk = devm_clk_get(dev, name); + if (IS_ERR(clk)) { + dev_err(dev, "failed to get clock %s\n", name); + return PTR_ERR(clk); + } + } + snprintf(name, sizeof(name), "usb%d_reset", i); reset = devm_reset_control_get(dev, name); if (IS_ERR(reset)) { @@ -296,6 +311,7 @@ static int sun4i_usb_phy_probe(struct platform_device *pdev) data->phys[i].pmu = pmu; data->phys[i].vbus = vbus; data->phys[i].reset = reset; + data->phys[i].clk = clk; data->phys[i].index = i; phy_set_drvdata(phy, &data->phys[i]); } @@ -311,6 +327,7 @@ static int sun4i_usb_phy_probe(struct platform_device *pdev) static const struct of_device_id sun4i_usb_phy_of_match[] = { { .compatible = "allwinner,sun4i-a10-usb-phy" }, { .compatible = "allwinner,sun5i-a13-usb-phy" }, + { .compatible = "allwinner,sun6i-a31-usb-phy" }, { .compatible = "allwinner,sun7i-a20-usb-phy" }, { }, };