]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
reset: mpfs: add non-auxiliary bus probing
authorConor Dooley <conor.dooley@microchip.com>
Mon, 10 Nov 2025 11:23:50 +0000 (11:23 +0000)
committerConor Dooley <conor.dooley@microchip.com>
Tue, 11 Nov 2025 16:47:24 +0000 (16:47 +0000)
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.

Reviewed-by: Philipp Zabel <p.zabel@pengutronix.de>
Acked-by: Philipp Zabel <p.zabel@pengutronix.de>
Signed-off-by: Conor Dooley <conor.dooley@microchip.com>
drivers/clk/microchip/clk-mpfs.c
drivers/reset/Kconfig
drivers/reset/reset-mpfs.c
include/soc/microchip/mpfs.h

index 484893e68b67721e19e7d5b1be81a9f2eeb8d1a9..ee58304913ef1dbe38c3306f3ab5d33c2c27333b 100644 (file)
@@ -38,7 +38,7 @@ static const struct regmap_config mpfs_clk_regmap_config = {
        .reg_stride = 4,
        .val_bits = 32,
        .val_format_endian = REGMAP_ENDIAN_LITTLE,
-       .max_register = REG_SUBBLK_CLOCK_CR,
+       .max_register = REG_SUBBLK_RESET_CR,
 };
 
 /*
@@ -502,7 +502,7 @@ static inline int mpfs_clk_old_format_probe(struct mpfs_clock_data *clk_data,
        if (IS_ERR(clk_data->regmap))
                return PTR_ERR(clk_data->regmap);
 
-       return mpfs_reset_controller_register(dev, clk_data->base + REG_SUBBLK_RESET_CR);
+       return mpfs_reset_controller_register(dev, clk_data->regmap);
 }
 
 static int mpfs_clk_probe(struct platform_device *pdev)
index 78b7078478d46d484ce031f527a933c81a838b1d..0ec4b7cd08d652168974839516e464daa019388b 100644 (file)
@@ -200,6 +200,7 @@ config RESET_PISTACHIO
 config RESET_POLARFIRE_SOC
        bool "Microchip PolarFire SoC (MPFS) Reset Driver"
        depends on MCHP_CLK_MPFS
+       depends on MFD_SYSCON
        select AUXILIARY_BUS
        default MCHP_CLK_MPFS
        help
index f6fa10e03ea889e5434110156f7bece808a6ae92..8ffcc54ee6f696df372178239317177eadd91122 100644 (file)
@@ -9,11 +9,13 @@
 #include <linux/auxiliary_bus.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 <linux/slab.h>
 #include <dt-bindings/clock/microchip,mpfs-clock.h>
 #include <soc/microchip/mpfs.h>
 
 #define MPFS_SLEEP_MIN_US      100
 #define MPFS_SLEEP_MAX_US      200
 
-/* block concurrent access to the soft reset register */
-static DEFINE_SPINLOCK(mpfs_reset_lock);
+#define REG_SUBBLK_RESET_CR    0x88u
 
 struct mpfs_reset {
-       void __iomem *base;
+       struct regmap *regmap;
        struct reset_controller_dev rcdev;
 };
 
@@ -46,41 +47,25 @@ 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);
-
-       reg = readl(rst->base);
-       reg |= BIT(id);
-       writel(reg, rst->base);
 
-       spin_unlock_irqrestore(&mpfs_reset_lock, flags);
+       return regmap_set_bits(rst->regmap, REG_SUBBLK_RESET_CR, BIT(id));
 
-       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);
 
-       reg = readl(rst->base);
-       reg &= ~BIT(id);
-       writel(reg, rst->base);
+       return regmap_clear_bits(rst->regmap, REG_SUBBLK_RESET_CR, BIT(id));
 
-       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;
+
+       regmap_read(rst->regmap, REG_SUBBLK_RESET_CR, &reg);
 
        /*
         * It is safe to return here as MPFS_NUM_RESETS makes sure the sign bit
@@ -130,23 +115,58 @@ 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 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))
+               return 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 device *dev = &adev->dev;
        struct reset_controller_dev *rcdev;
+       struct device *dev = &adev->dev;
        struct mpfs_reset *rst;
 
        rst = devm_kzalloc(dev, sizeof(*rst), GFP_KERNEL);
        if (!rst)
                return -ENOMEM;
 
-       rst->base = (void __iomem *)adev->dev.platform_data;
+       rst->regmap = (struct regmap *)adev->dev.platform_data;
 
        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;
@@ -155,12 +175,11 @@ static int mpfs_reset_probe(struct auxiliary_device *adev,
        return devm_reset_controller_register(dev, rcdev);
 }
 
-int mpfs_reset_controller_register(struct device *clk_dev, void __iomem *base)
+int mpfs_reset_controller_register(struct device *clk_dev, struct regmap *map)
 {
        struct auxiliary_device *adev;
 
-       adev = devm_auxiliary_device_create(clk_dev, "reset-mpfs",
-                                           (__force void *)base);
+       adev = devm_auxiliary_device_create(clk_dev, "reset-mpfs", (void *)map);
        if (!adev)
                return -ENODEV;
 
@@ -176,12 +195,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>");
index 0bd67e10b7049b9bf9897f96f6c15730ccc977d9..ec04c98a8b63bd4fb6c7b242d2df7819773512a5 100644 (file)
@@ -14,6 +14,7 @@
 
 #include <linux/types.h>
 #include <linux/of_device.h>
+#include <linux/regmap.h>
 
 struct mpfs_sys_controller;
 
@@ -44,7 +45,7 @@ struct mtd_info *mpfs_sys_controller_get_flash(struct mpfs_sys_controller *mpfs_
 
 #if IS_ENABLED(CONFIG_MCHP_CLK_MPFS)
 #if IS_ENABLED(CONFIG_RESET_POLARFIRE_SOC)
-int mpfs_reset_controller_register(struct device *clk_dev, void __iomem *base);
+int mpfs_reset_controller_register(struct device *clk_dev, struct regmap *map);
 #else
 static inline int mpfs_reset_controller_register(struct device *clk_dev, void __iomem *base) { return 0; }
 #endif /* if IS_ENABLED(CONFIG_RESET_POLARFIRE_SOC) */