Received: by 2002:ac0:a5a7:0:0:0:0:0 with SMTP id m36-v6csp653121imm; Fri, 13 Jul 2018 04:08:47 -0700 (PDT) X-Google-Smtp-Source: AAOMgpcXqceuAutau43le3p9loR37EMz+2Ok1nsnjJkMOXSjmm42hpIn7ehItwGVhXnbjfU+kULb X-Received: by 2002:a63:b00f:: with SMTP id h15-v6mr5761363pgf.442.1531480127758; Fri, 13 Jul 2018 04:08:47 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1531480127; cv=none; d=google.com; s=arc-20160816; b=buc8wiD7hIEQe8yAgoZ3Vwd1qq49X5wkL+2wEUznCY6b6FXA2uXN5593tZl/MrPHTK 0c+x5fIeW+mOKNY+1rWXH4uEftMXUk4eRipftP809PoFCw2hZr/8WSFN7uu7fhg4cxrw 4bZuK1Rs58UDlp8AI4jiGdwM4/pmVuDO4bjMdjXABDiRQlwz8pgbiUYuWWn/zQqygK3J D94vb0aJvyvC3BKGePGvzdGs7T6Zx/DDNFEwAi0SiP8k/eLgVXQaKnBl8lUrbBjbIk+s 73S8T/hz0PZ++s6r6NAvhNT6thfjukPS/OY1EfdyIX0BBgzZZ39HDmdANxEOmOUfLsJ8 3sqg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:message-id:from:cc:to:subject :content-transfer-encoding:mime-version:references:in-reply-to:date :arc-authentication-results; bh=G/p77sysDSqftEtz82HOMuuQadDzcxbMpNnJsEDj5AA=; b=acNA5k9mGOTmrDjpj7lxWg4K6fSwhWaJGsZDKiRu2EgH7GSE14C5gz8t62oSZOQFtb DijDtlrnEEcoWoGE8JvVua5GAaDSGHLB9dmYA4U7sh9pHZeh2J06i4rWkpk+bzyodRb5 2OkGS8xChaTR9d7yjG4W6ocvEgn6ufyNPjNNry4G54DZy8Fd+Z2jI3+q/dYeW4jA23DK ZlxkSTWX6yQj8D6Kgu4I6Yw14Bj9W7/p+oWGDirHmqS3hrZYHnT+DIFlzdCznothZbrU tHib0BkwObOd1+8EHORNsekBcjZBqPRNQmwqhRw9HS5U79s/Np6ACpilgKWQggRdBd0K Jxlg== ARC-Authentication-Results: i=1; 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 Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id g92-v6si23816235plg.0.2018.07.13.04.08.32; Fri, 13 Jul 2018 04:08:47 -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 S1728140AbeGMLWK convert rfc822-to-8bit (ORCPT + 99 others); Fri, 13 Jul 2018 07:22:10 -0400 Received: from hermes.aosc.io ([199.195.250.187]:55072 "EHLO hermes.aosc.io" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727306AbeGMLWK (ORCPT ); Fri, 13 Jul 2018 07:22:10 -0400 Received: from localhost (localhost [127.0.0.1]) (Authenticated sender: icenowy@aosc.io) by hermes.aosc.io (Postfix) with ESMTPSA id 02CBA64B5C; Fri, 13 Jul 2018 11:07:49 +0000 (UTC) Date: Fri, 13 Jul 2018 19:07:38 +0800 In-Reply-To: <1531479786-4911-7-git-send-email-clabbe@baylibre.com> References: <1531479786-4911-1-git-send-email-clabbe@baylibre.com> <1531479786-4911-7-git-send-email-clabbe@baylibre.com> MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8BIT Subject: Re: [PATCH v3 6/9] ata: ahci_platform: add support for port regulator To: Corentin Labbe , hdegoede@redhat.com, linux@armlinux.org.uk, mark.rutland@arm.com, maxime.ripard@free-electrons.com, robh+dt@kernel.org, tj@kernel.org, wens@csie.org CC: devicetree@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-ide@vger.kernel.org, linux-kernel@vger.kernel.org, linux-sunxi@googlegroups.com, thierry.reding@gmail.com From: Icenowy Zheng Message-ID: Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org 于 2018年7月13日 GMT+08:00 下午7:03:03, Corentin Labbe 写到: >The SoC R40 AHCI controller need a port regulator to work. In fact it should be a PHY regulator. >We cannot use the "target-supply" since it's not a target power >regulator. >So this patch add a way to add an optional port regulator. > >Signed-off-by: Corentin Labbe >--- > drivers/ata/ahci.h | 1 + >drivers/ata/libahci_platform.c | 47 >+++++++++++++++++++++++++++++++++++++----- > 2 files changed, 43 insertions(+), 5 deletions(-) > >diff --git a/drivers/ata/ahci.h b/drivers/ata/ahci.h >index 274c1885a5ad..716fd679dd3e 100644 >--- a/drivers/ata/ahci.h >+++ b/drivers/ata/ahci.h >@@ -352,6 +352,7 @@ struct ahci_host_priv { > bool got_runtime_pm; /* Did we do pm_runtime_get? */ > struct clk *clks[AHCI_MAX_CLKS]; /* Optional */ > struct regulator **target_pwrs; /* Optional */ >+ struct regulator **port_regulators;/* Optional */ > struct regulator *ahci_regulator;/* Optional */ > struct reset_control *ahci_reset; /* Optional */ > /* >diff --git a/drivers/ata/libahci_platform.c >b/drivers/ata/libahci_platform.c >index 1199ba411c15..d7574b3e1f6a 100644 >--- a/drivers/ata/libahci_platform.c >+++ b/drivers/ata/libahci_platform.c >@@ -148,7 +148,7 @@ EXPORT_SYMBOL_GPL(ahci_platform_disable_clks); > */ > int ahci_platform_enable_regulators(struct ahci_host_priv *hpriv) > { >- int rc, i; >+ int rc, i, j; > > if (hpriv->ahci_regulator) { > rc = regulator_enable(hpriv->ahci_regulator); >@@ -164,9 +164,21 @@ int ahci_platform_enable_regulators(struct >ahci_host_priv *hpriv) > if (rc) > goto disable_target_pwrs; > } >+ for (j = 0; j < hpriv->nports; j++) { >+ if (!hpriv->port_regulators[j]) >+ continue; >+ >+ rc = regulator_enable(hpriv->port_regulators[j]); >+ if (rc) >+ goto disable_port_regulators; >+ } > > return 0; > >+disable_port_regulators: >+ while (--j >= 0) >+ if (hpriv->port_regulators[j]) >+ regulator_disable(hpriv->port_regulators[j]); > disable_target_pwrs: > while (--i >= 0) > if (hpriv->target_pwrs[i]) >@@ -190,9 +202,10 @@ void ahci_platform_disable_regulators(struct >ahci_host_priv *hpriv) > int i; > > for (i = 0; i < hpriv->nports; i++) { >- if (!hpriv->target_pwrs[i]) >- continue; >- regulator_disable(hpriv->target_pwrs[i]); >+ if (hpriv->target_pwrs[i]) >+ regulator_disable(hpriv->target_pwrs[i]); >+ if (hpriv->port_regulators[i]) >+ regulator_disable(hpriv->port_regulators[i]); > } > > if (hpriv->ahci_regulator) >@@ -291,9 +304,12 @@ static void ahci_platform_put_resources(struct >device *dev, void *res) > * SATA device itself. So we can't use devm for automatically > * releasing them. We have to do it manually here. > */ >- for (c = 0; c < hpriv->nports; c++) >+ for (c = 0; c < hpriv->nports; c++) { > if (hpriv->target_pwrs && hpriv->target_pwrs[c]) > regulator_put(hpriv->target_pwrs[c]); >+ if (hpriv->port_regulators && hpriv->port_regulators[c]) >+ regulator_put(hpriv->port_regulators[c]); >+ } > } > >static int ahci_platform_get_phy(struct ahci_host_priv *hpriv, u32 >port, >@@ -338,6 +354,7 @@ static int ahci_platform_get_regulator(struct >ahci_host_priv *hpriv, u32 port, > struct device *dev) > { > struct regulator *target_pwr; >+ struct regulator *port_regulator; > int rc = 0; > > target_pwr = regulator_get_optional(dev, "target"); >@@ -346,6 +363,21 @@ static int ahci_platform_get_regulator(struct >ahci_host_priv *hpriv, u32 port, > hpriv->target_pwrs[port] = target_pwr; > else > rc = PTR_ERR(target_pwr); >+ /* Only EPROBE_DEFER is important since it's an optional regulator */ >+ if (rc != -EPROBE_DEFER) >+ rc = 0; >+ else >+ return rc; >+ >+ port_regulator = regulator_get_optional(dev, "port"); >+ >+ if (!IS_ERR(port_regulator)) >+ hpriv->port_regulators[port] = port_regulator; >+ else >+ rc = PTR_ERR(port_regulator); >+ /* Only EPROBE_DEFER is important since it's an optional regulator */ >+ if (rc != -EPROBE_DEFER) >+ rc = 0; > > return rc; > } >@@ -454,6 +486,11 @@ struct ahci_host_priv >*ahci_platform_get_resources(struct platform_device *pdev) > rc = -ENOMEM; > goto err_out; > } >+ hpriv->port_regulators = devm_kcalloc(dev, hpriv->nports, >sizeof(*hpriv->port_regulators), GFP_KERNEL); >+ if (!hpriv->port_regulators) { >+ rc = -ENOMEM; >+ goto err_out; >+ } > > if (child_nodes) { > for_each_child_of_node(dev->of_node, child) {