From patchwork Sat Jan 18 23:48:52 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Hans de Goede X-Patchwork-Id: 3509261 Return-Path: X-Original-To: patchwork-linux-arm@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.19.201]) by patchwork1.web.kernel.org (Postfix) with ESMTP id 836279F2D6 for ; Sun, 19 Jan 2014 12:00:39 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 79E8A2011E for ; Sun, 19 Jan 2014 12:00:38 +0000 (UTC) Received: from casper.infradead.org (casper.infradead.org [85.118.1.10]) (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 4A6CE2011B for ; Sun, 19 Jan 2014 12:00:37 +0000 (UTC) Received: from merlin.infradead.org ([2001:4978:20e::2]) by casper.infradead.org with esmtps (Exim 4.80.1 #2 (Red Hat Linux)) id 1W4qj5-0004sO-Bx; Sun, 19 Jan 2014 11:39:41 +0000 Received: from localhost ([::1] helo=merlin.infradead.org) by merlin.infradead.org with esmtp (Exim 4.80.1 #2 (Red Hat Linux)) id 1W4qiC-00086S-R6; Sun, 19 Jan 2014 11:38:44 +0000 Received: from mx1.redhat.com ([209.132.183.28]) by merlin.infradead.org with esmtp (Exim 4.80.1 #2 (Red Hat Linux)) id 1W4fe6-0003KK-Tk for linux-arm-kernel@lists.infradead.org; Sat, 18 Jan 2014 23:49:48 +0000 Received: from int-mx01.intmail.prod.int.phx2.redhat.com (int-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.11]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id s0INnOVK005374 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Sat, 18 Jan 2014 18:49:24 -0500 Received: from shalem.localdomain.com (vpn1-4-230.ams2.redhat.com [10.36.4.230]) by int-mx01.intmail.prod.int.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id s0INmukl020501; Sat, 18 Jan 2014 18:49:21 -0500 From: Hans de Goede To: Tejun Heo Subject: [RFC v3 10/13] ahci_imx: Adjust for ahci_platform managing the clocks Date: Sun, 19 Jan 2014 00:48:52 +0100 Message-Id: <1390088935-7193-11-git-send-email-hdegoede@redhat.com> In-Reply-To: <1390088935-7193-1-git-send-email-hdegoede@redhat.com> References: <1390088935-7193-1-git-send-email-hdegoede@redhat.com> X-Scanned-By: MIMEDefang 2.67 on 10.5.11.11 X-Bad-Reply: References and In-Reply-To but no 'Re:' in Subject. X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20140118_184947_220478_3E3A3226 X-CRM114-Status: GOOD ( 20.34 ) X-Spam-Score: -7.3 (-------) X-Mailman-Approved-At: Sun, 19 Jan 2014 06:37:13 -0500 Cc: devicetree , Hans de Goede , linux-ide@vger.kernel.org, Oliver Schinagl , Richard Zhu , linux-sunxi@googlegroups.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-Spam-Status: No, score=-4.7 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_MED, RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP ahci_platform manages all 3 clocks now, so enabling / disabling them from ahci_imx just results in the sata_ref clock getting enabled / disabled twice. Note untested, I've ordered a wandboard to be able to test these changes. Signed-off-by: Hans de Goede --- .../devicetree/bindings/ata/ahci-platform.txt | 8 ++- drivers/ata/ahci_imx.c | 82 +++++++++------------- 2 files changed, 40 insertions(+), 50 deletions(-) diff --git a/Documentation/devicetree/bindings/ata/ahci-platform.txt b/Documentation/devicetree/bindings/ata/ahci-platform.txt index f036e786..ee3a127 100644 --- a/Documentation/devicetree/bindings/ata/ahci-platform.txt +++ b/Documentation/devicetree/bindings/ata/ahci-platform.txt @@ -5,8 +5,8 @@ Each SATA controller should have its own node. Required properties: - compatible : compatible list, one of "snps,spear-ahci", - "snps,exynos5440-ahci", "ibm,476gtr-ahci", or - "allwinner,sun4i-a10-ahci" + "snps,exynos5440-ahci", "ibm,476gtr-ahci", + "allwinner,sun4i-a10-ahci" or "fsl,imx6q-ahci" - interrupts : - reg : @@ -18,6 +18,10 @@ Optional properties: allwinner,sun4i-a10-ahci required properties: - clocks : index 0 must point to the sata_ref clk, 1 to the ahb clk +fsl,imx6q-ahci required properties: +- clocks : index 0 must point to the sataf clk, 1 to the sata_ref + clk and 2 to the ahb clk + Examples: sata@ffe08000 { compatible = "snps,spear-ahci"; diff --git a/drivers/ata/ahci_imx.c b/drivers/ata/ahci_imx.c index 0051f29..8eb24a3 100644 --- a/drivers/ata/ahci_imx.c +++ b/drivers/ata/ahci_imx.c @@ -34,12 +34,15 @@ enum { HOST_TIMER1MS = 0xe0, /* Timer 1-ms */ }; +enum { + CLK_SATA, + CLK_SATA_REF, + CLK_AHB +}; + struct imx_ahci_priv { struct platform_device *ahci_pdev; - struct clk *sata_ref_clk; - struct clk *ahb_clk; struct regmap *gpr; - bool no_device; bool first_time; }; @@ -55,6 +58,7 @@ static void ahci_imx_error_handler(struct ata_port *ap) struct ahci_host_priv *hpriv = host->private_data; void __iomem *mmio = hpriv->mmio; struct imx_ahci_priv *imxpriv = dev_get_drvdata(ap->dev->parent); + int i; ahci_error_handler(ap); @@ -75,8 +79,13 @@ static void ahci_imx_error_handler(struct ata_port *ap) regmap_update_bits(imxpriv->gpr, IOMUXC_GPR13, IMX6Q_GPR13_SATA_MPLL_CLK_EN, !IMX6Q_GPR13_SATA_MPLL_CLK_EN); - clk_disable_unprepare(imxpriv->sata_ref_clk); - imxpriv->no_device = true; + + for (i = CLK_AHB; i >= 0; i--) { + clk_disable_unprepare(hpriv->clks[i]); + /* Stop ahci_platform.c from trying to use the clks */ + clk_put(hpriv->clks[i]); + hpriv->clks[i] = NULL; + } } static struct ata_port_operations ahci_imx_ops = { @@ -94,7 +103,6 @@ static const struct ata_port_info ahci_imx_port_info = { static int imx6q_sata_init(struct device *dev, struct ahci_host_priv *hpriv, void __iomem *mmio) { - int ret = 0; unsigned int reg_val; struct imx_ahci_priv *imxpriv = dev_get_drvdata(dev->parent); @@ -105,12 +113,6 @@ static int imx6q_sata_init(struct device *dev, struct ahci_host_priv *hpriv, return PTR_ERR(imxpriv->gpr); } - ret = clk_prepare_enable(imxpriv->sata_ref_clk); - if (ret < 0) { - dev_err(dev, "prepare-enable sata_ref clock err:%d\n", ret); - return ret; - } - /* * set PHY Paremeters, two steps to configure the GPR13, * one write for rest of parameters, mask of first write @@ -157,7 +159,11 @@ static int imx6q_sata_init(struct device *dev, struct ahci_host_priv *hpriv, writel(reg_val, mmio + HOST_PORTS_IMPL); } - reg_val = clk_get_rate(imxpriv->ahb_clk) / 1000; + if (!hpriv->clks[CLK_AHB]) { + dev_err(dev, "no ahb clk, need sata, sata_ref and ahb clks\n"); + return -ENOENT; + } + reg_val = clk_get_rate(hpriv->clks[CLK_AHB]) / 1000; writel(reg_val, mmio + HOST_TIMER1MS); return 0; @@ -165,41 +171,36 @@ static int imx6q_sata_init(struct device *dev, struct ahci_host_priv *hpriv, static void imx6q_sata_exit(struct device *dev) { - struct imx_ahci_priv *imxpriv = dev_get_drvdata(dev->parent); + struct ata_host *host = dev_get_drvdata(dev); + struct ahci_host_priv *hpriv = host->private_data; + struct imx_ahci_priv *imxpriv = dev_get_drvdata(dev->parent); - regmap_update_bits(imxpriv->gpr, 0x34, IMX6Q_GPR13_SATA_MPLL_CLK_EN, + if (hpriv->clks[CLK_SATA]) + regmap_update_bits(imxpriv->gpr, 0x34, + IMX6Q_GPR13_SATA_MPLL_CLK_EN, !IMX6Q_GPR13_SATA_MPLL_CLK_EN); - clk_disable_unprepare(imxpriv->sata_ref_clk); } static void imx_ahci_suspend(struct device *dev) { - struct imx_ahci_priv *imxpriv = dev_get_drvdata(dev->parent); + struct ata_host *host = dev_get_drvdata(dev); + struct ahci_host_priv *hpriv = host->private_data; + struct imx_ahci_priv *imxpriv = dev_get_drvdata(dev->parent); - /* - * If no_device is set, The CLKs had been gated off in the - * initialization so don't do it again here. - */ - if (!imxpriv->no_device) { + /* Check the CLKs have not been gated off in the initialization. */ + if (hpriv->clks[CLK_SATA]) regmap_update_bits(imxpriv->gpr, IOMUXC_GPR13, IMX6Q_GPR13_SATA_MPLL_CLK_EN, !IMX6Q_GPR13_SATA_MPLL_CLK_EN); - clk_disable_unprepare(imxpriv->sata_ref_clk); - } } static int imx_ahci_resume(struct device *dev) { - struct imx_ahci_priv *imxpriv = dev_get_drvdata(dev->parent); - int ret; - - if (!imxpriv->no_device) { - ret = clk_prepare_enable(imxpriv->sata_ref_clk); - if (ret < 0) { - dev_err(dev, "pre-enable sata_ref clock err:%d\n", ret); - return ret; - } + struct ata_host *host = dev_get_drvdata(dev); + struct ahci_host_priv *hpriv = host->private_data; + struct imx_ahci_priv *imxpriv = dev_get_drvdata(dev->parent); + if (hpriv->clks[CLK_SATA]) { regmap_update_bits(imxpriv->gpr, IOMUXC_GPR13, IMX6Q_GPR13_SATA_MPLL_CLK_EN, IMX6Q_GPR13_SATA_MPLL_CLK_EN); @@ -247,22 +248,7 @@ static int imx_ahci_probe(struct platform_device *pdev) ahci_dev = &ahci_pdev->dev; ahci_dev->parent = dev; - imxpriv->no_device = false; imxpriv->first_time = true; - imxpriv->ahb_clk = devm_clk_get(dev, "ahb"); - if (IS_ERR(imxpriv->ahb_clk)) { - dev_err(dev, "can't get ahb clock.\n"); - ret = PTR_ERR(imxpriv->ahb_clk); - goto err_out; - } - - imxpriv->sata_ref_clk = devm_clk_get(dev, "sata_ref"); - if (IS_ERR(imxpriv->sata_ref_clk)) { - dev_err(dev, "can't get sata_ref clock.\n"); - ret = PTR_ERR(imxpriv->sata_ref_clk); - goto err_out; - } - imxpriv->ahci_pdev = ahci_pdev; platform_set_drvdata(pdev, imxpriv);