All of lore.kernel.org
 help / color / mirror / Atom feed
From: Serge Semin <Sergey.Semin@baikalelectronics.ru>
To: Damien Le Moal <damien.lemoal@opensource.wdc.com>,
	Hans de Goede <hdegoede@redhat.com>, Jens Axboe <axboe@kernel.dk>
Cc: Serge Semin <Sergey.Semin@baikalelectronics.ru>,
	Serge Semin <fancer.lancer@gmail.com>,
	Alexey Malahov <Alexey.Malahov@baikalelectronics.ru>,
	Pavel Parkhomenko <Pavel.Parkhomenko@baikalelectronics.ru>,
	Rob Herring <robh+dt@kernel.org>, <linux-ide@vger.kernel.org>,
	<linux-kernel@vger.kernel.org>, <devicetree@vger.kernel.org>
Subject: [PATCH v3 11/23] ata: libahci_platform: Introduce reset assertion/deassertion methods
Date: Thu, 12 May 2022 02:17:58 +0300	[thread overview]
Message-ID: <20220511231810.4928-12-Sergey.Semin@baikalelectronics.ru> (raw)
In-Reply-To: <20220511231810.4928-1-Sergey.Semin@baikalelectronics.ru>

Currently the ACHI-platform library supports only the assert and deassert
reset signals and ignores the platforms with self-deasserting reset lines.
That prone to having the platforms with self-deasserting reset method
misbehaviour when it comes to resuming from sleep state after the clocks
have been fully disabled. For such cases the controller needs to be fully
reset all over after the reference clocks are enabled and stable,
otherwise the controller state machine might be in an undetermined state.

The best solution would be to auto-detect which reset method is supported
by the particular platform and use it implicitly in the framework of the
ahci_platform_enable_resources()/ahci_platform_disable_resources()
methods. Alas it can't be implemented due to the AHCI-platform library
already supporting the shared reset control lines. As [1] says in such
case we have to use only one of the next methods:
+ reset_control_assert()/reset_control_deassert();
+ reset_control_reset()/reset_control_rearm().
If the driver had an exclusive control over the reset lines we could have
been able to manipulate the lines with no much limitation and just used
the combination of the methods above to cover all the possible
reset-control cases. Since the shared reset control has already been
advertised and couldn't be changed with no risk to breaking the platforms
relying on it, we have no choice but to make the platform drivers to
determine which reset methods the platform reset system supports.

In order to implement both types of reset control support we suggest to
introduce the new AHCI-platform flag: AHCI_PLATFORM_RST_TRIGGER, which
when passed to the ahci_platform_get_resources() method together with the
AHCI_PLATFORM_GET_RESETS flag will indicate that the reset lines are
self-deasserting thus the reset_control_reset()/reset_control_rearm() will
be used to control the reset state. Otherwise the
reset_control_deassert()/reset_control_assert() methods will be utilized.

[1] Documentation/driver-api/reset.rst

Signed-off-by: Serge Semin <Sergey.Semin@baikalelectronics.ru>

---

Changelog v2:
- Convert the ahci_platform_assert_rsts() method to returning int status
  (@Damien).
- Fix some grammar mistakes in the ahci_platform_deassert_rsts() doc
  (@Damien).
---
 drivers/ata/ahci.h             |  1 +
 drivers/ata/libahci_platform.c | 50 ++++++++++++++++++++++++++++++----
 include/linux/ahci_platform.h  |  5 +++-
 3 files changed, 50 insertions(+), 6 deletions(-)

diff --git a/drivers/ata/ahci.h b/drivers/ata/ahci.h
index c3770a19781b..7d834deefeb9 100644
--- a/drivers/ata/ahci.h
+++ b/drivers/ata/ahci.h
@@ -340,6 +340,7 @@ struct ahci_host_priv {
 	bool			got_runtime_pm; /* Did we do pm_runtime_get? */
 	unsigned int		n_clks;
 	struct clk_bulk_data	*clks;		/* Optional */
+	unsigned int		f_rsts;
 	struct reset_control	*rsts;		/* Optional */
 	struct regulator	**target_pwrs;	/* Optional */
 	struct regulator	*ahci_regulator;/* Optional */
diff --git a/drivers/ata/libahci_platform.c b/drivers/ata/libahci_platform.c
index f7f9cac10cb1..f5ee2f9d014b 100644
--- a/drivers/ata/libahci_platform.c
+++ b/drivers/ata/libahci_platform.c
@@ -150,6 +150,44 @@ void ahci_platform_disable_clks(struct ahci_host_priv *hpriv)
 }
 EXPORT_SYMBOL_GPL(ahci_platform_disable_clks);
 
+/**
+ * ahci_platform_deassert_rsts - Deassert/trigger platform resets
+ * @hpriv: host private area to store config values
+ *
+ * This function deasserts or triggers all the reset lines found for
+ * the AHCI device.
+ *
+ * RETURNS:
+ * 0 on success otherwise a negative error code
+ */
+int ahci_platform_deassert_rsts(struct ahci_host_priv *hpriv)
+{
+	if (hpriv->f_rsts & AHCI_PLATFORM_RST_TRIGGER)
+		return reset_control_reset(hpriv->rsts);
+
+	return reset_control_deassert(hpriv->rsts);
+}
+EXPORT_SYMBOL_GPL(ahci_platform_deassert_rsts);
+
+/**
+ * ahci_platform_assert_rsts - Assert/rearm platform resets
+ * @hpriv: host private area to store config values
+ *
+ * This function asserts or rearms (for self-deasserting resets) all
+ * the reset controls found for the AHCI device.
+ *
+ * RETURNS:
+ * 0 on success otherwise a negative error code
+ */
+int ahci_platform_assert_rsts(struct ahci_host_priv *hpriv)
+{
+	if (hpriv->f_rsts & AHCI_PLATFORM_RST_TRIGGER)
+		return reset_control_rearm(hpriv->rsts);
+
+	return reset_control_assert(hpriv->rsts);
+}
+EXPORT_SYMBOL_GPL(ahci_platform_assert_rsts);
+
 /**
  * ahci_platform_enable_regulators - Enable regulators
  * @hpriv: host private area to store config values
@@ -247,18 +285,18 @@ int ahci_platform_enable_resources(struct ahci_host_priv *hpriv)
 	if (rc)
 		goto disable_regulator;
 
-	rc = reset_control_deassert(hpriv->rsts);
+	rc = ahci_platform_deassert_rsts(hpriv);
 	if (rc)
 		goto disable_clks;
 
 	rc = ahci_platform_enable_phys(hpriv);
 	if (rc)
-		goto disable_resets;
+		goto disable_rsts;
 
 	return 0;
 
-disable_resets:
-	reset_control_assert(hpriv->rsts);
+disable_rsts:
+	ahci_platform_assert_rsts(hpriv);
 
 disable_clks:
 	ahci_platform_disable_clks(hpriv);
@@ -285,7 +323,7 @@ void ahci_platform_disable_resources(struct ahci_host_priv *hpriv)
 {
 	ahci_platform_disable_phys(hpriv);
 
-	reset_control_assert(hpriv->rsts);
+	ahci_platform_assert_rsts(hpriv);
 
 	ahci_platform_disable_clks(hpriv);
 
@@ -478,6 +516,8 @@ struct ahci_host_priv *ahci_platform_get_resources(struct platform_device *pdev,
 			rc = PTR_ERR(hpriv->rsts);
 			goto err_out;
 		}
+
+		hpriv->f_rsts = flags & AHCI_PLATFORM_RST_TRIGGER;
 	}
 
 	/*
diff --git a/include/linux/ahci_platform.h b/include/linux/ahci_platform.h
index fd964e6a68d6..3418980b0341 100644
--- a/include/linux/ahci_platform.h
+++ b/include/linux/ahci_platform.h
@@ -26,6 +26,8 @@ struct clk *
 ahci_platform_find_clk(struct ahci_host_priv *hpriv, const char *con_id);
 int ahci_platform_enable_clks(struct ahci_host_priv *hpriv);
 void ahci_platform_disable_clks(struct ahci_host_priv *hpriv);
+int ahci_platform_deassert_rsts(struct ahci_host_priv *hpriv);
+int ahci_platform_assert_rsts(struct ahci_host_priv *hpriv);
 int ahci_platform_enable_regulators(struct ahci_host_priv *hpriv);
 void ahci_platform_disable_regulators(struct ahci_host_priv *hpriv);
 int ahci_platform_enable_resources(struct ahci_host_priv *hpriv);
@@ -44,6 +46,7 @@ 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
+#define AHCI_PLATFORM_GET_RESETS	BIT(0)
+#define AHCI_PLATFORM_RST_TRIGGER	BIT(1)
 
 #endif /* _AHCI_PLATFORM_H */
-- 
2.35.1


  parent reply	other threads:[~2022-05-11 23:19 UTC|newest]

Thread overview: 93+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-05-11 23:17 [PATCH v3 00/23] ata: ahci: Add DWC/Baikal-T1 AHCI SATA support Serge Semin
2022-05-11 23:17 ` [PATCH v3 01/23] dt-bindings: ata: ahci-platform: Drop dma-coherent property declaration Serge Semin
2022-05-12  6:14   ` Hannes Reinecke
2022-05-17 18:58   ` Rob Herring
2022-05-21  9:22     ` Serge Semin
2022-05-24 14:57       ` Rob Herring
2022-05-25 10:01         ` Serge Semin
2022-05-11 23:17 ` [PATCH v3 02/23] dt-bindings: ata: ahci-platform: Detach common AHCI bindings Serge Semin
2022-05-12  6:19   ` Hannes Reinecke
2022-05-12 11:51     ` Serge Semin
2022-05-17 19:10   ` Rob Herring
2022-05-22 15:02     ` Serge Semin
2022-05-24 15:19       ` Rob Herring
2022-05-27 10:10         ` Serge Semin
2022-06-01  0:51           ` Rob Herring
2022-05-11 23:17 ` [PATCH v3 03/23] dt-bindings: ata: ahci-platform: Clarify common AHCI props constraints Serge Semin
2022-05-12  6:21   ` Hannes Reinecke
2022-05-12 12:01     ` Serge Semin
2022-05-12  8:11   ` Sergei Shtylyov
2022-05-12 12:04     ` Serge Semin
2022-05-17 19:14   ` Rob Herring
2022-05-22 15:08     ` Serge Semin
2022-05-11 23:17 ` [PATCH v3 04/23] dt-bindings: ata: sata: Extend number of SATA ports Serge Semin
2022-05-12  6:23   ` Hannes Reinecke
2022-05-17 19:15   ` Rob Herring
2022-05-11 23:17 ` [PATCH v3 05/23] ata: libahci_platform: Explicitly set rc on devres_alloc failure Serge Semin
2022-05-12  6:27   ` Hannes Reinecke
2022-05-12 10:32     ` Damien Le Moal
2022-05-12 12:31       ` Serge Semin
2022-05-11 23:17 ` [PATCH v3 06/23] ata: libahci_platform: Convert to using platform devm-ioremap methods Serge Semin
2022-05-12  6:31   ` Hannes Reinecke
2022-05-11 23:17 ` [PATCH v3 07/23] ata: libahci_platform: Convert to using devm bulk clocks API Serge Semin
2022-05-12  6:31   ` Hannes Reinecke
2022-05-12 18:32   ` kernel test robot
2022-05-11 23:17 ` [PATCH v3 08/23] ata: libahci_platform: Add function returning a clock-handle by id Serge Semin
2022-05-12  6:32   ` Hannes Reinecke
2022-05-12 14:26     ` Serge Semin
2022-05-13  9:32       ` Damien Le Moal
2022-05-13 13:31         ` Serge Semin
2022-05-11 23:17 ` [PATCH v3 09/23] ata: libahci_platform: Sanity check the DT child nodes number Serge Semin
2022-05-12  6:34   ` Hannes Reinecke
2022-05-12  8:24   ` Sergei Shtylyov
2022-05-12 14:40     ` Serge Semin
2022-05-11 23:17 ` [PATCH v3 10/23] ata: libahci_platform: Parse ports-implemented property in resources getter Serge Semin
2022-05-11 23:17   ` Serge Semin
2022-05-11 23:17   ` Serge Semin
2022-05-12  6:48   ` Hannes Reinecke
2022-05-12  6:48     ` Hannes Reinecke
2022-05-12  6:48     ` Hannes Reinecke
2022-05-12 14:31     ` Serge Semin
2022-05-12 14:31       ` Serge Semin
2022-05-12 14:31       ` Serge Semin
2022-05-11 23:17 ` Serge Semin [this message]
2022-05-12  6:54   ` [PATCH v3 11/23] ata: libahci_platform: Introduce reset assertion/deassertion methods Hannes Reinecke
2022-05-11 23:17 ` [PATCH v3 12/23] dt-bindings: ata: ahci: Add platform capability properties Serge Semin
2022-05-12  6:56   ` Hannes Reinecke
2022-05-17 19:20   ` Rob Herring
2022-05-22 17:43     ` Serge Semin
2022-05-11 23:18 ` [PATCH v3 13/23] ata: libahci: Extend port-cmd flags set with port capabilities Serge Semin
2022-05-12  6:57   ` Hannes Reinecke
2022-05-12 15:05     ` Serge Semin
2022-05-13  8:22   ` Sergei Shtylyov
2022-05-13 12:13     ` Serge Semin
2022-05-11 23:18 ` [PATCH v3 14/23] ata: libahci: Discard redundant force_port_map parameter Serge Semin
2022-05-12  7:00   ` Hannes Reinecke
2022-05-11 23:18 ` [PATCH v3 15/23] ata: libahci: Don't read AHCI version twice in the save-config method Serge Semin
2022-05-12  7:00   ` Hannes Reinecke
2022-05-11 23:18 ` [PATCH v3 16/23] ata: ahci: Convert __ahci_port_base to accepting hpriv as arguments Serge Semin
2022-05-12  7:08   ` Hannes Reinecke
2022-05-11 23:18 ` [PATCH v3 17/23] ata: ahci: Introduce firmware-specific caps initialization Serge Semin
2022-05-12  7:05   ` Hannes Reinecke
2022-05-12 15:54     ` Serge Semin
2022-05-11 23:18 ` [PATCH v3 18/23] dt-bindings: ata: ahci: Add DWC AHCI SATA controller DT schema Serge Semin
2022-05-12  7:08   ` Hannes Reinecke
2022-05-17 20:04   ` Rob Herring
2022-05-22 17:51     ` Serge Semin
2022-05-11 23:18 ` [PATCH v3 19/23] ata: ahci: Add DWC AHCI SATA controller support Serge Semin
2022-05-12  7:09   ` Hannes Reinecke
2022-05-11 23:18 ` [PATCH v3 20/23] dt-bindings: ata: ahci: Add Baikal-T1 AHCI SATA controller DT schema Serge Semin
2022-05-12  7:10   ` Hannes Reinecke
2022-05-17 20:13   ` Rob Herring
2022-05-22 20:49     ` Serge Semin
2022-05-24 15:33       ` Rob Herring
2022-05-27 10:55         ` Serge Semin
2022-05-11 23:18 ` [PATCH v3 21/23] ata: ahci-dwc: Add platform-specific quirks support Serge Semin
2022-05-12  7:12   ` Hannes Reinecke
2022-05-12 16:29     ` Serge Semin
2022-05-14  0:30   ` kernel test robot
2022-05-11 23:18 ` [PATCH v3 22/23] ata: ahci-dwc: Add Baikal-T1 AHCI SATA interface support Serge Semin
2022-05-12  7:13   ` Hannes Reinecke
2022-05-11 23:18 ` [PATCH v3 23/23] MAINTAINERS: Add maintainers for DWC AHCI SATA driver Serge Semin
2022-05-12  7:16   ` Hannes Reinecke
2022-05-12 16:47     ` Serge Semin

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20220511231810.4928-12-Sergey.Semin@baikalelectronics.ru \
    --to=sergey.semin@baikalelectronics.ru \
    --cc=Alexey.Malahov@baikalelectronics.ru \
    --cc=Pavel.Parkhomenko@baikalelectronics.ru \
    --cc=axboe@kernel.dk \
    --cc=damien.lemoal@opensource.wdc.com \
    --cc=devicetree@vger.kernel.org \
    --cc=fancer.lancer@gmail.com \
    --cc=hdegoede@redhat.com \
    --cc=linux-ide@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=robh+dt@kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.