From: Conor Dooley <conor@kernel.org>
To: sboyd@kernel.org
Cc: conor@kernel.org, Conor Dooley <conor.dooley@microchip.com>,
Daire McNamara <daire.mcnamara@microchip.com>,
pierre-henry.moussay@microchip.com,
valentina.fernandezalanis@microchip.com,
Michael Turquette <mturquette@baylibre.com>,
Rob Herring <robh@kernel.org>,
Krzysztof Kozlowski <krzk+dt@kernel.org>,
Jassi Brar <jassisinghbrar@gmail.com>, Lee Jones <lee@kernel.org>,
Paul Walmsley <paul.walmsley@sifive.com>,
Palmer Dabbelt <palmer@dabbelt.com>,
Philipp Zabel <p.zabel@pengutronix.de>,
linux-riscv@lists.infradead.org, linux-clk@vger.kernel.org,
devicetree@vger.kernel.org, linux-kernel@vger.kernel.org
Subject: [PATCH v3 4/9] reset: mpfs: add non-auxiliary bus probing
Date: Mon, 23 Jun 2025 13:56:18 +0100 [thread overview]
Message-ID: <20250623-equate-ogle-0ce3293567e2@spud> (raw)
In-Reply-To: <20250623-levitate-nugget-08c9a01f401d@spud>
From: Conor Dooley <conor.dooley@microchip.com>
While the auxiliary bus was a nice bandaid, and meant that re-writing
the representation of the clock regions in devicetree was not required,
it has run its course. The "mss_top_sysreg" region that contains the
clock and reset regions, also contains pinctrl and an interrupt
controller, so the time has come rewrite the devicetree and probe the
reset controller from an mfd devicetree node, rather than implement
those drivers using the auxiliary bus. Wanting to avoid propagating this
naive/incorrect description of the hardware to the new pic64gx SoC is a
major motivating factor here.
Signed-off-by: Conor Dooley <conor.dooley@microchip.com>
---
v2:
Implement the request to use regmap_update_bits(). I found that I then
hated the read/write helpers since they were just bloat, so I ripped
them out. I replaced the regular spin_lock_irqsave() stuff with a
guard(spinlock_irqsave), since that's a simpler way of handling the two
different paths through such a trivial pair of functions.
---
drivers/reset/reset-mpfs.c | 81 ++++++++++++++++++++++++++++++--------
1 file changed, 65 insertions(+), 16 deletions(-)
diff --git a/drivers/reset/reset-mpfs.c b/drivers/reset/reset-mpfs.c
index 574e59db83a4f..9c3e996f3a099 100644
--- a/drivers/reset/reset-mpfs.c
+++ b/drivers/reset/reset-mpfs.c
@@ -7,12 +7,15 @@
*
*/
#include <linux/auxiliary_bus.h>
+#include <linux/cleanup.h>
#include <linux/delay.h>
#include <linux/io.h>
+#include <linux/mfd/syscon.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/platform_device.h>
#include <linux/slab.h>
+#include <linux/regmap.h>
#include <linux/reset-controller.h>
#include <dt-bindings/clock/microchip,mpfs-clock.h>
#include <soc/microchip/mpfs.h>
@@ -27,11 +30,14 @@
#define MPFS_SLEEP_MIN_US 100
#define MPFS_SLEEP_MAX_US 200
+#define REG_SUBBLK_RESET_CR 0x88u
+
/* block concurrent access to the soft reset register */
static DEFINE_SPINLOCK(mpfs_reset_lock);
struct mpfs_reset {
void __iomem *base;
+ struct regmap *regmap;
struct reset_controller_dev rcdev;
};
@@ -46,41 +52,50 @@ static inline struct mpfs_reset *to_mpfs_reset(struct reset_controller_dev *rcde
static int mpfs_assert(struct reset_controller_dev *rcdev, unsigned long id)
{
struct mpfs_reset *rst = to_mpfs_reset(rcdev);
- unsigned long flags;
u32 reg;
- spin_lock_irqsave(&mpfs_reset_lock, flags);
+ guard(spinlock_irqsave)(&mpfs_reset_lock);
+
+ if (rst->regmap) {
+ regmap_update_bits(rst->regmap, REG_SUBBLK_RESET_CR, BIT(id), BIT(id));
+ return 0;
+ }
reg = readl(rst->base);
reg |= BIT(id);
writel(reg, rst->base);
- spin_unlock_irqrestore(&mpfs_reset_lock, flags);
-
return 0;
}
static int mpfs_deassert(struct reset_controller_dev *rcdev, unsigned long id)
{
struct mpfs_reset *rst = to_mpfs_reset(rcdev);
- unsigned long flags;
u32 reg;
- spin_lock_irqsave(&mpfs_reset_lock, flags);
+ guard(spinlock_irqsave)(&mpfs_reset_lock);
+
+ if (rst->regmap) {
+ regmap_update_bits(rst->regmap, REG_SUBBLK_RESET_CR, BIT(id), 0);
+ return 0;
+ }
reg = readl(rst->base);
reg &= ~BIT(id);
writel(reg, rst->base);
- spin_unlock_irqrestore(&mpfs_reset_lock, flags);
-
return 0;
}
static int mpfs_status(struct reset_controller_dev *rcdev, unsigned long id)
{
struct mpfs_reset *rst = to_mpfs_reset(rcdev);
- u32 reg = readl(rst->base);
+ u32 reg;
+
+ if (rst->regmap)
+ regmap_read(rst->regmap, REG_SUBBLK_RESET_CR, ®);
+ else
+ reg = readl(rst->base);
/*
* It is safe to return here as MPFS_NUM_RESETS makes sure the sign bit
@@ -130,11 +145,45 @@ static int mpfs_reset_xlate(struct reset_controller_dev *rcdev,
return index - MPFS_PERIPH_OFFSET;
}
-static int mpfs_reset_probe(struct auxiliary_device *adev,
- const struct auxiliary_device_id *id)
+static int mpfs_reset_mfd_probe(struct platform_device *pdev)
{
- struct device *dev = &adev->dev;
struct reset_controller_dev *rcdev;
+ struct device *dev = &pdev->dev;
+ struct mpfs_reset *rst;
+
+ rst = devm_kzalloc(dev, sizeof(*rst), GFP_KERNEL);
+ if (!rst)
+ return -ENOMEM;
+
+ rcdev = &rst->rcdev;
+ rcdev->dev = dev;
+ rcdev->ops = &mpfs_reset_ops;
+
+ rcdev->of_node = pdev->dev.parent->of_node;
+ rcdev->of_reset_n_cells = 1;
+ rcdev->of_xlate = mpfs_reset_xlate;
+ rcdev->nr_resets = MPFS_NUM_RESETS;
+
+ rst->regmap = device_node_to_regmap(pdev->dev.parent->of_node);
+ if (IS_ERR(rst->regmap))
+ dev_err_probe(dev, PTR_ERR(rst->regmap), "Failed to find syscon regmap\n");
+
+ return devm_reset_controller_register(dev, rcdev);
+}
+
+static struct platform_driver mpfs_reset_mfd_driver = {
+ .probe = mpfs_reset_mfd_probe,
+ .driver = {
+ .name = "mpfs-reset",
+ },
+};
+module_platform_driver(mpfs_reset_mfd_driver);
+
+static int mpfs_reset_adev_probe(struct auxiliary_device *adev,
+ const struct auxiliary_device_id *id)
+{
+ struct reset_controller_dev *rcdev;
+ struct device *dev = &adev->dev;
struct mpfs_reset *rst;
rst = devm_kzalloc(dev, sizeof(*rst), GFP_KERNEL);
@@ -145,8 +194,8 @@ static int mpfs_reset_probe(struct auxiliary_device *adev,
rcdev = &rst->rcdev;
rcdev->dev = dev;
- rcdev->dev->parent = dev->parent;
rcdev->ops = &mpfs_reset_ops;
+
rcdev->of_node = dev->parent->of_node;
rcdev->of_reset_n_cells = 1;
rcdev->of_xlate = mpfs_reset_xlate;
@@ -222,12 +271,12 @@ static const struct auxiliary_device_id mpfs_reset_ids[] = {
};
MODULE_DEVICE_TABLE(auxiliary, mpfs_reset_ids);
-static struct auxiliary_driver mpfs_reset_driver = {
- .probe = mpfs_reset_probe,
+static struct auxiliary_driver mpfs_reset_aux_driver = {
+ .probe = mpfs_reset_adev_probe,
.id_table = mpfs_reset_ids,
};
-module_auxiliary_driver(mpfs_reset_driver);
+module_auxiliary_driver(mpfs_reset_aux_driver);
MODULE_DESCRIPTION("Microchip PolarFire SoC Reset Driver");
MODULE_AUTHOR("Conor Dooley <conor.dooley@microchip.com>");
--
2.45.2
next prev parent reply other threads:[~2025-06-23 12:57 UTC|newest]
Thread overview: 14+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-06-23 12:56 [PATCH v3 0/9] Redo PolarFire SoC's mailbox/clock devicestrees and related code Conor Dooley
2025-06-23 12:56 ` [PATCH v3 1/9] dt-bindings: mfd: syscon document the control-scb syscon on PolarFire SoC Conor Dooley
2025-06-23 12:56 ` [PATCH v3 2/9] dt-bindings: soc: microchip: document the simple-mfd " Conor Dooley
2025-06-27 7:04 ` Krzysztof Kozlowski
2025-06-23 12:56 ` [PATCH v3 3/9] soc: microchip: add mfd drivers for two syscon regions " Conor Dooley
2025-06-23 12:56 ` Conor Dooley [this message]
2025-06-27 16:01 ` [PATCH v3 4/9] reset: mpfs: add non-auxiliary bus probing Philipp Zabel
2025-06-23 12:56 ` [PATCH v3 5/9] dt-bindings: clk: microchip: mpfs: remove first reg region Conor Dooley
2025-06-23 12:56 ` [PATCH v3 6/9] riscv: dts: microchip: fix mailbox description Conor Dooley
2025-06-23 12:56 ` [PATCH v3 7/9] riscv: dts: microchip: convert clock and reset to use syscon Conor Dooley
2025-06-23 12:56 ` [PATCH v3 8/9] clk: divider, gate: create regmap-backed copies of gate and divider clocks Conor Dooley
2025-07-31 11:23 ` Gabriel FERNANDEZ
2025-08-05 17:13 ` Conor Dooley
2025-06-23 12:56 ` [PATCH v3 9/9] clk: microchip: mpfs: use regmap clock types Conor Dooley
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=20250623-equate-ogle-0ce3293567e2@spud \
--to=conor@kernel.org \
--cc=conor.dooley@microchip.com \
--cc=daire.mcnamara@microchip.com \
--cc=devicetree@vger.kernel.org \
--cc=jassisinghbrar@gmail.com \
--cc=krzk+dt@kernel.org \
--cc=lee@kernel.org \
--cc=linux-clk@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-riscv@lists.infradead.org \
--cc=mturquette@baylibre.com \
--cc=p.zabel@pengutronix.de \
--cc=palmer@dabbelt.com \
--cc=paul.walmsley@sifive.com \
--cc=pierre-henry.moussay@microchip.com \
--cc=robh@kernel.org \
--cc=sboyd@kernel.org \
--cc=valentina.fernandezalanis@microchip.com \
/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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).