445 lines
16 KiB
Diff
445 lines
16 KiB
Diff
Add an extra argument to ahci_platform_get_resources(), that is
|
|
for the bitmap representing the resource to get in this function.
|
|
|
|
Currently there is no resources to be defined, so all the callers set
|
|
'0' to the argument.
|
|
|
|
Suggested-by: Hans de Goede <hdegoede@redhat.com>
|
|
Cc: Thierry Reding <thierry.reding@gmail.com>
|
|
Cc: Matthias Brugger <matthias.bgg@gmail.com>
|
|
Cc: Patrice Chotard <patrice.chotard@st.com>
|
|
Cc: Maxime Ripard <maxime.ripard@free-electrons.com>
|
|
Signed-off-by: Kunihiko Hayashi <hayashi.kunihiko@socionext.com>
|
|
---
|
|
drivers/ata/ahci_brcm.c | 2 +-
|
|
drivers/ata/ahci_ceva.c | 2 +-
|
|
drivers/ata/ahci_da850.c | 2 +-
|
|
drivers/ata/ahci_dm816.c | 2 +-
|
|
drivers/ata/ahci_imx.c | 2 +-
|
|
drivers/ata/ahci_mtk.c | 2 +-
|
|
drivers/ata/ahci_mvebu.c | 2 +-
|
|
drivers/ata/ahci_platform.c | 2 +-
|
|
drivers/ata/ahci_qoriq.c | 2 +-
|
|
drivers/ata/ahci_seattle.c | 2 +-
|
|
drivers/ata/ahci_st.c | 2 +-
|
|
drivers/ata/ahci_sunxi.c | 2 +-
|
|
drivers/ata/ahci_tegra.c | 2 +-
|
|
drivers/ata/ahci_xgene.c | 2 +-
|
|
drivers/ata/libahci_platform.c | 4 +++-
|
|
include/linux/ahci_platform.h | 2 +-
|
|
16 files changed, 18 insertions(+), 16 deletions(-)
|
|
|
|
diff --git a/drivers/ata/ahci_brcm.c b/drivers/ata/ahci_brcm.c
|
|
index ea43081..f3d5577 100644
|
|
--- a/drivers/ata/ahci_brcm.c
|
|
+++ b/drivers/ata/ahci_brcm.c
|
|
@@ -425,7 +425,7 @@ static int brcm_ahci_probe(struct platform_device *pdev)
|
|
|
|
brcm_sata_phys_enable(priv);
|
|
|
|
- hpriv = ahci_platform_get_resources(pdev);
|
|
+ hpriv = ahci_platform_get_resources(pdev, 0);
|
|
if (IS_ERR(hpriv))
|
|
return PTR_ERR(hpriv);
|
|
hpriv->plat_data = priv;
|
|
diff --git a/drivers/ata/ahci_ceva.c b/drivers/ata/ahci_ceva.c
|
|
index 5ecc9d4..dc78c98 100644
|
|
--- a/drivers/ata/ahci_ceva.c
|
|
+++ b/drivers/ata/ahci_ceva.c
|
|
@@ -213,7 +213,7 @@ static int ceva_ahci_probe(struct platform_device *pdev)
|
|
|
|
cevapriv->ahci_pdev = pdev;
|
|
|
|
- hpriv = ahci_platform_get_resources(pdev);
|
|
+ hpriv = ahci_platform_get_resources(pdev, 0);
|
|
if (IS_ERR(hpriv))
|
|
return PTR_ERR(hpriv);
|
|
|
|
diff --git a/drivers/ata/ahci_da850.c b/drivers/ata/ahci_da850.c
|
|
index 9b34dff..ebaa657 100644
|
|
--- a/drivers/ata/ahci_da850.c
|
|
+++ b/drivers/ata/ahci_da850.c
|
|
@@ -171,7 +171,7 @@ static int ahci_da850_probe(struct platform_device *pdev)
|
|
u32 mpy;
|
|
int rc;
|
|
|
|
- hpriv = ahci_platform_get_resources(pdev);
|
|
+ hpriv = ahci_platform_get_resources(pdev, 0);
|
|
if (IS_ERR(hpriv))
|
|
return PTR_ERR(hpriv);
|
|
|
|
diff --git a/drivers/ata/ahci_dm816.c b/drivers/ata/ahci_dm816.c
|
|
index fbd827c..89509c3 100644
|
|
--- a/drivers/ata/ahci_dm816.c
|
|
+++ b/drivers/ata/ahci_dm816.c
|
|
@@ -148,7 +148,7 @@ static int ahci_dm816_probe(struct platform_device *pdev)
|
|
struct ahci_host_priv *hpriv;
|
|
int rc;
|
|
|
|
- hpriv = ahci_platform_get_resources(pdev);
|
|
+ hpriv = ahci_platform_get_resources(pdev, 0);
|
|
if (IS_ERR(hpriv))
|
|
return PTR_ERR(hpriv);
|
|
|
|
diff --git a/drivers/ata/ahci_imx.c b/drivers/ata/ahci_imx.c
|
|
index 6822e2f..b00799d 100644
|
|
--- a/drivers/ata/ahci_imx.c
|
|
+++ b/drivers/ata/ahci_imx.c
|
|
@@ -1127,7 +1127,7 @@ static int imx_ahci_probe(struct platform_device *pdev)
|
|
return ret;
|
|
}
|
|
|
|
- hpriv = ahci_platform_get_resources(pdev);
|
|
+ hpriv = ahci_platform_get_resources(pdev, 0);
|
|
if (IS_ERR(hpriv))
|
|
return PTR_ERR(hpriv);
|
|
|
|
diff --git a/drivers/ata/ahci_mtk.c b/drivers/ata/ahci_mtk.c
|
|
index 0ae6971..8bc1a26 100644
|
|
--- a/drivers/ata/ahci_mtk.c
|
|
+++ b/drivers/ata/ahci_mtk.c
|
|
@@ -142,7 +142,7 @@ static int mtk_ahci_probe(struct platform_device *pdev)
|
|
if (!plat)
|
|
return -ENOMEM;
|
|
|
|
- hpriv = ahci_platform_get_resources(pdev);
|
|
+ hpriv = ahci_platform_get_resources(pdev, 0);
|
|
if (IS_ERR(hpriv))
|
|
return PTR_ERR(hpriv);
|
|
|
|
diff --git a/drivers/ata/ahci_mvebu.c b/drivers/ata/ahci_mvebu.c
|
|
index 72d90b4..f9cb51b 100644
|
|
--- a/drivers/ata/ahci_mvebu.c
|
|
+++ b/drivers/ata/ahci_mvebu.c
|
|
@@ -158,7 +158,7 @@ static int ahci_mvebu_probe(struct platform_device *pdev)
|
|
const struct mbus_dram_target_info *dram;
|
|
int rc;
|
|
|
|
- hpriv = ahci_platform_get_resources(pdev);
|
|
+ hpriv = ahci_platform_get_resources(pdev, 0);
|
|
if (IS_ERR(hpriv))
|
|
return PTR_ERR(hpriv);
|
|
|
|
diff --git a/drivers/ata/ahci_platform.c b/drivers/ata/ahci_platform.c
|
|
index 99f9a89..5709273 100644
|
|
--- a/drivers/ata/ahci_platform.c
|
|
+++ b/drivers/ata/ahci_platform.c
|
|
@@ -43,7 +43,7 @@ static int ahci_probe(struct platform_device *pdev)
|
|
struct ahci_host_priv *hpriv;
|
|
int rc;
|
|
|
|
- hpriv = ahci_platform_get_resources(pdev);
|
|
+ hpriv = ahci_platform_get_resources(pdev, 0);
|
|
if (IS_ERR(hpriv))
|
|
return PTR_ERR(hpriv);
|
|
|
|
diff --git a/drivers/ata/ahci_qoriq.c b/drivers/ata/ahci_qoriq.c
|
|
index cfdef4d..ce59253 100644
|
|
--- a/drivers/ata/ahci_qoriq.c
|
|
+++ b/drivers/ata/ahci_qoriq.c
|
|
@@ -250,7 +250,7 @@ static int ahci_qoriq_probe(struct platform_device *pdev)
|
|
struct resource *res;
|
|
int rc;
|
|
|
|
- hpriv = ahci_platform_get_resources(pdev);
|
|
+ hpriv = ahci_platform_get_resources(pdev, 0);
|
|
if (IS_ERR(hpriv))
|
|
return PTR_ERR(hpriv);
|
|
|
|
diff --git a/drivers/ata/ahci_seattle.c b/drivers/ata/ahci_seattle.c
|
|
index 1d31c0c..e57b6f9 100644
|
|
--- a/drivers/ata/ahci_seattle.c
|
|
+++ b/drivers/ata/ahci_seattle.c
|
|
@@ -164,7 +164,7 @@ static int ahci_seattle_probe(struct platform_device *pdev)
|
|
int rc;
|
|
struct ahci_host_priv *hpriv;
|
|
|
|
- hpriv = ahci_platform_get_resources(pdev);
|
|
+ hpriv = ahci_platform_get_resources(pdev, 0);
|
|
if (IS_ERR(hpriv))
|
|
return PTR_ERR(hpriv);
|
|
|
|
diff --git a/drivers/ata/ahci_st.c b/drivers/ata/ahci_st.c
|
|
index bc345f2..21c5c44 100644
|
|
--- a/drivers/ata/ahci_st.c
|
|
+++ b/drivers/ata/ahci_st.c
|
|
@@ -156,7 +156,7 @@ static int st_ahci_probe(struct platform_device *pdev)
|
|
if (!drv_data)
|
|
return -ENOMEM;
|
|
|
|
- hpriv = ahci_platform_get_resources(pdev);
|
|
+ hpriv = ahci_platform_get_resources(pdev, 0);
|
|
if (IS_ERR(hpriv))
|
|
return PTR_ERR(hpriv);
|
|
hpriv->plat_data = drv_data;
|
|
diff --git a/drivers/ata/ahci_sunxi.c b/drivers/ata/ahci_sunxi.c
|
|
index b264374..631610b 100644
|
|
--- a/drivers/ata/ahci_sunxi.c
|
|
+++ b/drivers/ata/ahci_sunxi.c
|
|
@@ -181,7 +181,7 @@ static int ahci_sunxi_probe(struct platform_device *pdev)
|
|
struct ahci_host_priv *hpriv;
|
|
int rc;
|
|
|
|
- hpriv = ahci_platform_get_resources(pdev);
|
|
+ hpriv = ahci_platform_get_resources(pdev, 0);
|
|
if (IS_ERR(hpriv))
|
|
return PTR_ERR(hpriv);
|
|
|
|
diff --git a/drivers/ata/ahci_tegra.c b/drivers/ata/ahci_tegra.c
|
|
index 64d8484..004f260 100644
|
|
--- a/drivers/ata/ahci_tegra.c
|
|
+++ b/drivers/ata/ahci_tegra.c
|
|
@@ -494,7 +494,7 @@ static int tegra_ahci_probe(struct platform_device *pdev)
|
|
int ret;
|
|
unsigned int i;
|
|
|
|
- hpriv = ahci_platform_get_resources(pdev);
|
|
+ hpriv = ahci_platform_get_resources(pdev, 0);
|
|
if (IS_ERR(hpriv))
|
|
return PTR_ERR(hpriv);
|
|
|
|
diff --git a/drivers/ata/ahci_xgene.c b/drivers/ata/ahci_xgene.c
|
|
index ad58da7..7e157e1 100644
|
|
--- a/drivers/ata/ahci_xgene.c
|
|
+++ b/drivers/ata/ahci_xgene.c
|
|
@@ -759,7 +759,7 @@ static int xgene_ahci_probe(struct platform_device *pdev)
|
|
&xgene_ahci_v2_port_info };
|
|
int rc;
|
|
|
|
- hpriv = ahci_platform_get_resources(pdev);
|
|
+ hpriv = ahci_platform_get_resources(pdev, 0);
|
|
if (IS_ERR(hpriv))
|
|
return PTR_ERR(hpriv);
|
|
|
|
diff --git a/drivers/ata/libahci_platform.c b/drivers/ata/libahci_platform.c
|
|
index 30cc8f1..6abc1cd 100644
|
|
--- a/drivers/ata/libahci_platform.c
|
|
+++ b/drivers/ata/libahci_platform.c
|
|
@@ -332,6 +332,7 @@ static int ahci_platform_get_regulator(struct ahci_host_priv *hpriv, u32 port,
|
|
/**
|
|
* ahci_platform_get_resources - Get platform resources
|
|
* @pdev: platform device to get resources for
|
|
+ * @flags: bitmap representing the resource to get
|
|
*
|
|
* This function allocates an ahci_host_priv struct, and gets the following
|
|
* resources, storing a reference to them inside the returned struct:
|
|
@@ -345,7 +346,8 @@ static int ahci_platform_get_regulator(struct ahci_host_priv *hpriv, u32 port,
|
|
* RETURNS:
|
|
* The allocated ahci_host_priv on success, otherwise an ERR_PTR value
|
|
*/
|
|
-struct ahci_host_priv *ahci_platform_get_resources(struct platform_device *pdev)
|
|
+struct ahci_host_priv *ahci_platform_get_resources(struct platform_device *pdev,
|
|
+ unsigned int flags)
|
|
{
|
|
struct device *dev = &pdev->dev;
|
|
struct ahci_host_priv *hpriv;
|
|
diff --git a/include/linux/ahci_platform.h b/include/linux/ahci_platform.h
|
|
index 1b0a17b..6490be1 100644
|
|
--- a/include/linux/ahci_platform.h
|
|
+++ b/include/linux/ahci_platform.h
|
|
@@ -30,7 +30,7 @@ void ahci_platform_disable_regulators(struct ahci_host_priv *hpriv);
|
|
int ahci_platform_enable_resources(struct ahci_host_priv *hpriv);
|
|
void ahci_platform_disable_resources(struct ahci_host_priv *hpriv);
|
|
struct ahci_host_priv *ahci_platform_get_resources(
|
|
- struct platform_device *pdev);
|
|
+ struct platform_device *pdev, unsigned int flags);
|
|
int ahci_platform_init_host(struct platform_device *pdev,
|
|
struct ahci_host_priv *hpriv,
|
|
const struct ata_port_info *pi_template,
|
|
|
|
From patchwork Wed Aug 22 12:13:02 2018
|
|
Content-Type: text/plain; charset="utf-8"
|
|
MIME-Version: 1.0
|
|
Content-Transfer-Encoding: 7bit
|
|
Subject: [v2,2/3] ata: libahci_platform: add reset control support
|
|
X-Patchwork-Submitter: Kunihiko Hayashi <hayashi.kunihiko@socionext.com>
|
|
X-Patchwork-Id: 960932
|
|
X-Patchwork-Delegate: davem@davemloft.net
|
|
Message-Id: <1534939983-16264-3-git-send-email-hayashi.kunihiko@socionext.com>
|
|
To: Tejun Heo <tj@kernel.org>, Hans de Goede <hdegoede@redhat.com>,
|
|
Rob Herring <robh+dt@kernel.org>,
|
|
Mark Rutland <mark.rutland@arm.com>, linux-ide@vger.kernel.org
|
|
Cc: devicetree@vger.kernel.org, linux-kernel@vger.kernel.org,
|
|
Kunihiko Hayashi <hayashi.kunihiko@socionext.com>,
|
|
Thierry Reding <thierry.reding@gmail.com>
|
|
Date: Wed, 22 Aug 2018 21:13:02 +0900
|
|
From: Kunihiko Hayashi <hayashi.kunihiko@socionext.com>
|
|
List-Id: <linux-ide.vger.kernel.org>
|
|
|
|
Add support to get and control a list of resets for the device
|
|
as optional and shared. These resets must be kept de-asserted until
|
|
the device is enabled.
|
|
|
|
This is specified as shared because some SoCs like UniPhier series
|
|
have common reset controls with all ahci controller instances.
|
|
|
|
However, according to Thierry's view,
|
|
https://www.spinics.net/lists/linux-ide/msg55357.html
|
|
some hardware-specific drivers already use their own resets,
|
|
and the common reset make a path to occur double controls of resets.
|
|
|
|
The ahci_platform_get_resources() can get and control the reset
|
|
only when the second argument includes AHCI_PLATFORM_GET_RESETS bit.
|
|
|
|
Suggested-by: Hans de Goede <hdegoede@redhat.com>
|
|
Cc: Thierry Reding <thierry.reding@gmail.com>
|
|
Signed-off-by: Kunihiko Hayashi <hayashi.kunihiko@socionext.com>
|
|
Acked-by: Rob Herring <robh@kernel.org>
|
|
---
|
|
.../devicetree/bindings/ata/ahci-platform.txt | 1 +
|
|
drivers/ata/ahci.h | 1 +
|
|
drivers/ata/libahci_platform.c | 31 ++++++++++++++++++----
|
|
include/linux/ahci_platform.h | 2 ++
|
|
4 files changed, 30 insertions(+), 5 deletions(-)
|
|
|
|
diff --git a/Documentation/devicetree/bindings/ata/ahci-platform.txt b/Documentation/devicetree/bindings/ata/ahci-platform.txt
|
|
index c760ecb..f4006d3 100644
|
|
--- a/Documentation/devicetree/bindings/ata/ahci-platform.txt
|
|
+++ b/Documentation/devicetree/bindings/ata/ahci-platform.txt
|
|
@@ -30,6 +30,7 @@ compatible:
|
|
Optional properties:
|
|
- dma-coherent : Present if dma operations are coherent
|
|
- clocks : a list of phandle + clock specifier pairs
|
|
+- resets : a list of phandle + reset specifier pairs
|
|
- target-supply : regulator for SATA target power
|
|
- phys : reference to the SATA PHY node
|
|
- phy-names : must be "sata-phy"
|
|
diff --git a/drivers/ata/ahci.h b/drivers/ata/ahci.h
|
|
index 1609eba..6a1515f 100644
|
|
--- a/drivers/ata/ahci.h
|
|
+++ b/drivers/ata/ahci.h
|
|
@@ -350,6 +350,7 @@ struct ahci_host_priv {
|
|
u32 em_msg_type; /* EM message type */
|
|
bool got_runtime_pm; /* Did we do pm_runtime_get? */
|
|
struct clk *clks[AHCI_MAX_CLKS]; /* Optional */
|
|
+ struct reset_control *rsts; /* Optional */
|
|
struct regulator **target_pwrs; /* Optional */
|
|
/*
|
|
* If platform uses PHYs. There is a 1:1 relation between the port number and
|
|
diff --git a/drivers/ata/libahci_platform.c b/drivers/ata/libahci_platform.c
|
|
index 6abc1cd..6817143 100644
|
|
--- a/drivers/ata/libahci_platform.c
|
|
+++ b/drivers/ata/libahci_platform.c
|
|
@@ -25,6 +25,7 @@
|
|
#include <linux/phy/phy.h>
|
|
#include <linux/pm_runtime.h>
|
|
#include <linux/of_platform.h>
|
|
+#include <linux/reset.h>
|
|
#include "ahci.h"
|
|
|
|
static void ahci_host_stop(struct ata_host *host);
|
|
@@ -195,7 +196,8 @@ EXPORT_SYMBOL_GPL(ahci_platform_disable_regulators);
|
|
* following order:
|
|
* 1) Regulator
|
|
* 2) Clocks (through ahci_platform_enable_clks)
|
|
- * 3) Phys
|
|
+ * 3) Resets
|
|
+ * 4) Phys
|
|
*
|
|
* If resource enabling fails at any point the previous enabled resources
|
|
* are disabled in reverse order.
|
|
@@ -215,12 +217,19 @@ int ahci_platform_enable_resources(struct ahci_host_priv *hpriv)
|
|
if (rc)
|
|
goto disable_regulator;
|
|
|
|
- rc = ahci_platform_enable_phys(hpriv);
|
|
+ rc = reset_control_deassert(hpriv->rsts);
|
|
if (rc)
|
|
goto disable_clks;
|
|
|
|
+ rc = ahci_platform_enable_phys(hpriv);
|
|
+ if (rc)
|
|
+ goto disable_resets;
|
|
+
|
|
return 0;
|
|
|
|
+disable_resets:
|
|
+ reset_control_assert(hpriv->rsts);
|
|
+
|
|
disable_clks:
|
|
ahci_platform_disable_clks(hpriv);
|
|
|
|
@@ -238,13 +247,16 @@ EXPORT_SYMBOL_GPL(ahci_platform_enable_resources);
|
|
* This function disables all ahci_platform managed resources in the
|
|
* following order:
|
|
* 1) Phys
|
|
- * 2) Clocks (through ahci_platform_disable_clks)
|
|
- * 3) Regulator
|
|
+ * 2) Resets
|
|
+ * 3) Clocks (through ahci_platform_disable_clks)
|
|
+ * 4) Regulator
|
|
*/
|
|
void ahci_platform_disable_resources(struct ahci_host_priv *hpriv)
|
|
{
|
|
ahci_platform_disable_phys(hpriv);
|
|
|
|
+ reset_control_assert(hpriv->rsts);
|
|
+
|
|
ahci_platform_disable_clks(hpriv);
|
|
|
|
ahci_platform_disable_regulators(hpriv);
|
|
@@ -341,7 +353,8 @@ static int ahci_platform_get_regulator(struct ahci_host_priv *hpriv, u32 port,
|
|
* 2) regulator for controlling the targets power (optional)
|
|
* 3) 0 - AHCI_MAX_CLKS clocks, as specified in the devs devicetree node,
|
|
* or for non devicetree enabled platforms a single clock
|
|
- * 4) phys (optional)
|
|
+ * 4) resets, if flags has AHCI_PLATFORM_GET_RESETS (optional)
|
|
+ * 5) phys (optional)
|
|
*
|
|
* RETURNS:
|
|
* The allocated ahci_host_priv on success, otherwise an ERR_PTR value
|
|
@@ -395,6 +408,14 @@ struct ahci_host_priv *ahci_platform_get_resources(struct platform_device *pdev,
|
|
hpriv->clks[i] = clk;
|
|
}
|
|
|
|
+ if (flags & AHCI_PLATFORM_GET_RESETS) {
|
|
+ hpriv->rsts = devm_reset_control_array_get_optional_shared(dev);
|
|
+ if (IS_ERR(hpriv->rsts)) {
|
|
+ rc = PTR_ERR(hpriv->rsts);
|
|
+ goto err_out;
|
|
+ }
|
|
+ }
|
|
+
|
|
hpriv->nports = child_nodes = of_get_child_count(dev->of_node);
|
|
|
|
/*
|
|
diff --git a/include/linux/ahci_platform.h b/include/linux/ahci_platform.h
|
|
index 6490be1..eaedca5f 100644
|
|
--- a/include/linux/ahci_platform.h
|
|
+++ b/include/linux/ahci_platform.h
|
|
@@ -43,4 +43,6 @@ int ahci_platform_resume_host(struct device *dev);
|
|
int ahci_platform_suspend(struct device *dev);
|
|
int ahci_platform_resume(struct device *dev);
|
|
|
|
+#define AHCI_PLATFORM_GET_RESETS 0x01
|
|
+
|
|
#endif /* _AHCI_PLATFORM_H */
|
|
|
|
Unlike SoC-specific driver, generic ahci_platform driver doesn't
|
|
have any chances to control resets.
|
|
|
|
This adds AHCI_PLATFORM_GET_RESETS to ahci_platform_get_resources()
|
|
on the generic driver to enable reset control support.
|
|
|
|
Suggested-by: Hans de Goede <hdegoede@redhat.com>
|
|
Cc: Thierry Reding <thierry.reding@gmail.com>
|
|
Signed-off-by: Kunihiko Hayashi <hayashi.kunihiko@socionext.com>
|
|
---
|
|
drivers/ata/ahci_platform.c | 3 ++-
|
|
1 file changed, 2 insertions(+), 1 deletion(-)
|
|
|
|
diff --git a/drivers/ata/ahci_platform.c b/drivers/ata/ahci_platform.c
|
|
index 5709273..ddd9308 100644
|
|
--- a/drivers/ata/ahci_platform.c
|
|
+++ b/drivers/ata/ahci_platform.c
|
|
@@ -43,7 +43,8 @@ static int ahci_probe(struct platform_device *pdev)
|
|
struct ahci_host_priv *hpriv;
|
|
int rc;
|
|
|
|
- hpriv = ahci_platform_get_resources(pdev, 0);
|
|
+ hpriv = ahci_platform_get_resources(pdev,
|
|
+ AHCI_PLATFORM_GET_RESETS);
|
|
if (IS_ERR(hpriv))
|
|
return PTR_ERR(hpriv);
|
|
|