From eb43534ee4bbfdd0fc134ee245a773555480937b Mon Sep 17 00:00:00 2001 From: Conor Dooley Date: Wed, 29 Oct 2025 16:11:18 +0000 Subject: dt-bindings: clk: microchip: mpfs: remove first reg region The first reg region in this binding is not exclusively for clocks, as evidenced by the dual role of this device as a reset controller at present. The first region is however better described by a simple-mfd syscon, but this would have require a significant re-write of the devicetree for the platform, so the easy way out was chosen when reset support was first introduced. The region doesn't just contain clock and reset registers, it also contains pinctrl and interrupt controller functionality, so drop the region from the clock binding so that it can be described instead by a simple-mfd syscon rather than propagate this incorrect description of the hardware to the new pic64gx SoC. Acked-by: Rob Herring (Arm) Signed-off-by: Conor Dooley Link: https://lore.kernel.org/r/20251029-unwatched-family-e47cb29ea815@spud Signed-off-by: Claudiu Beznea --- .../bindings/clock/microchip,mpfs-clkcfg.yaml | 36 +++++++++++++--------- 1 file changed, 22 insertions(+), 14 deletions(-) diff --git a/Documentation/devicetree/bindings/clock/microchip,mpfs-clkcfg.yaml b/Documentation/devicetree/bindings/clock/microchip,mpfs-clkcfg.yaml index e4e1c31267d2..ee4f31596d97 100644 --- a/Documentation/devicetree/bindings/clock/microchip,mpfs-clkcfg.yaml +++ b/Documentation/devicetree/bindings/clock/microchip,mpfs-clkcfg.yaml @@ -22,16 +22,23 @@ properties: const: microchip,mpfs-clkcfg reg: - items: - - description: | - clock config registers: - These registers contain enable, reset & divider tables for the, cpu, - axi, ahb and rtc/mtimer reference clocks as well as enable and reset - for the peripheral clocks. - - description: | - mss pll dri registers: - Block of registers responsible for dynamic reconfiguration of the mss - pll + oneOf: + - items: + - description: | + clock config registers: + These registers contain enable, reset & divider tables for the, cpu, + axi, ahb and rtc/mtimer reference clocks as well as enable and reset + for the peripheral clocks. + - description: | + mss pll dri registers: + Block of registers responsible for dynamic reconfiguration of the mss + pll + deprecated: true + - items: + - description: | + mss pll dri registers: + Block of registers responsible for dynamic reconfiguration of the mss + pll clocks: maxItems: 1 @@ -69,11 +76,12 @@ examples: - | #include soc { - #address-cells = <2>; - #size-cells = <2>; - clkcfg: clock-controller@20002000 { + #address-cells = <1>; + #size-cells = <1>; + + clkcfg: clock-controller@3E001000 { compatible = "microchip,mpfs-clkcfg"; - reg = <0x0 0x20002000 0x0 0x1000>, <0x0 0x3E001000 0x0 0x1000>; + reg = <0x3E001000 0x1000>; clocks = <&ref>; #clock-cells = <1>; }; -- cgit From c6f2dddfa7f9579eeab67690def4be8094b4336d Mon Sep 17 00:00:00 2001 From: Conor Dooley Date: Wed, 29 Oct 2025 16:11:19 +0000 Subject: clk: microchip: mpfs: use regmap for clocks Convert the PolarFire SoC clock driver to use regmaps instead of iomem addresses as a preparatory work for supporting the new binding for this device that will only provide the second of the two register regions, and will require the use of syscon regmap to access the "cfg" and "periph" clocks currently supported by the driver. This is effectively a revert of commit 4da2404bb003 ("clk: microchip: mpfs: convert cfg_clk to clk_divider") and commit d815569783e6 ("clk: microchip: mpfs: convert periph_clk to clk_gate") as it resurrects the ops structures removed in those commits, with the readl()s and writel()s replaced by regmap_read()s and regmap_writes()s. Signed-off-by: Conor Dooley Reviewed-by: Claudiu Beznea Link: https://lore.kernel.org/r/20251029-surfboard-refocus-ca9b135ab123@spud Signed-off-by: Claudiu Beznea --- drivers/clk/microchip/Kconfig | 2 + drivers/clk/microchip/clk-mpfs.c | 227 +++++++++++++++++++++++++++++++-------- 2 files changed, 186 insertions(+), 43 deletions(-) diff --git a/drivers/clk/microchip/Kconfig b/drivers/clk/microchip/Kconfig index 0724ce65898f..1b9e43eb5497 100644 --- a/drivers/clk/microchip/Kconfig +++ b/drivers/clk/microchip/Kconfig @@ -7,6 +7,8 @@ config MCHP_CLK_MPFS bool "Clk driver for PolarFire SoC" depends on ARCH_MICROCHIP_POLARFIRE || COMPILE_TEST default ARCH_MICROCHIP_POLARFIRE + depends on MFD_SYSCON select AUXILIARY_BUS + select REGMAP_MMIO help Supports Clock Configuration for PolarFire SoC diff --git a/drivers/clk/microchip/clk-mpfs.c b/drivers/clk/microchip/clk-mpfs.c index c22632a7439c..484893e68b67 100644 --- a/drivers/clk/microchip/clk-mpfs.c +++ b/drivers/clk/microchip/clk-mpfs.c @@ -4,10 +4,13 @@ * * Copyright (C) 2020-2022 Microchip Technology Inc. All rights reserved. */ +#include #include #include +#include #include #include +#include #include #include @@ -30,6 +33,14 @@ #define MSSPLL_POSTDIV_WIDTH 0x07u #define MSSPLL_FIXED_DIV 4u +static const struct regmap_config mpfs_clk_regmap_config = { + .reg_bits = 32, + .reg_stride = 4, + .val_bits = 32, + .val_format_endian = REGMAP_ENDIAN_LITTLE, + .max_register = REG_SUBBLK_CLOCK_CR, +}; + /* * This clock ID is defined here, rather than the binding headers, as it is an * internal clock only, and therefore has no consumers in other peripheral @@ -39,6 +50,7 @@ struct mpfs_clock_data { struct device *dev; + struct regmap *regmap; void __iomem *base; void __iomem *msspll_base; struct clk_hw_onecell_data hw_data; @@ -67,21 +79,39 @@ struct mpfs_msspll_out_hw_clock { #define to_mpfs_msspll_out_clk(_hw) container_of(_hw, struct mpfs_msspll_out_hw_clock, hw) +struct mpfs_cfg_clock { + struct regmap *map; + const struct clk_div_table *table; + u8 map_offset; + u8 shift; + u8 width; + u8 flags; +}; + struct mpfs_cfg_hw_clock { - struct clk_divider cfg; - struct clk_init_data init; + struct clk_hw hw; + struct mpfs_cfg_clock cfg; unsigned int id; - u32 reg_offset; +}; + +#define to_mpfs_cfg_clk(_hw) container_of(_hw, struct mpfs_cfg_hw_clock, hw) + +struct mpfs_periph_clock { + struct regmap *map; + u8 map_offset; + u8 shift; }; struct mpfs_periph_hw_clock { - struct clk_gate periph; + struct clk_hw hw; + struct mpfs_periph_clock periph; unsigned int id; }; +#define to_mpfs_periph_clk(_hw) container_of(_hw, struct mpfs_periph_hw_clock, hw) + /* - * mpfs_clk_lock prevents anything else from writing to the - * mpfs clk block while a software locked register is being written. + * Protects MSSPLL outputs, since there's two to a register */ static DEFINE_SPINLOCK(mpfs_clk_lock); @@ -219,16 +249,61 @@ static int mpfs_clk_register_msspll_outs(struct device *dev, /* * "CFG" clocks */ +static unsigned long mpfs_cfg_clk_recalc_rate(struct clk_hw *hw, unsigned long prate) +{ + struct mpfs_cfg_hw_clock *cfg_hw = to_mpfs_cfg_clk(hw); + struct mpfs_cfg_clock *cfg = &cfg_hw->cfg; + u32 val; -#define CLK_CFG(_id, _name, _parent, _shift, _width, _table, _flags, _offset) { \ - .id = _id, \ - .cfg.shift = _shift, \ - .cfg.width = _width, \ - .cfg.table = _table, \ - .reg_offset = _offset, \ - .cfg.flags = _flags, \ - .cfg.hw.init = CLK_HW_INIT(_name, _parent, &clk_divider_ops, 0), \ - .cfg.lock = &mpfs_clk_lock, \ + regmap_read(cfg->map, cfg->map_offset, &val); + val >>= cfg->shift; + val &= clk_div_mask(cfg->width); + + return divider_recalc_rate(hw, prate, val, cfg->table, cfg->flags, cfg->width); +} + +static int mpfs_cfg_clk_determine_rate(struct clk_hw *hw, struct clk_rate_request *req) +{ + struct mpfs_cfg_hw_clock *cfg_hw = to_mpfs_cfg_clk(hw); + struct mpfs_cfg_clock *cfg = &cfg_hw->cfg; + + return divider_determine_rate(hw, req, cfg->table, cfg->width, 0); +} + +static int mpfs_cfg_clk_set_rate(struct clk_hw *hw, unsigned long rate, unsigned long prate) +{ + struct mpfs_cfg_hw_clock *cfg_hw = to_mpfs_cfg_clk(hw); + struct mpfs_cfg_clock *cfg = &cfg_hw->cfg; + int divider_setting; + u32 val; + u32 mask; + + divider_setting = divider_get_val(rate, prate, cfg->table, cfg->width, 0); + + if (divider_setting < 0) + return divider_setting; + + mask = clk_div_mask(cfg->width) << cfg->shift; + val = divider_setting << cfg->shift; + regmap_update_bits(cfg->map, cfg->map_offset, val, mask); + + return 0; +} + +static const struct clk_ops mpfs_clk_cfg_ops = { + .recalc_rate = mpfs_cfg_clk_recalc_rate, + .determine_rate = mpfs_cfg_clk_determine_rate, + .set_rate = mpfs_cfg_clk_set_rate, +}; + +#define CLK_CFG(_id, _name, _parent, _shift, _width, _table, _flags, _offset) { \ + .id = _id, \ + .cfg.shift = _shift, \ + .cfg.width = _width, \ + .cfg.table = _table, \ + .cfg.map_offset = _offset, \ + .cfg.flags = _flags, \ + .hw.init = CLK_HW_INIT(_name, _parent, &mpfs_clk_cfg_ops, 0), \ } #define CLK_CPU_OFFSET 0u @@ -248,10 +323,10 @@ static struct mpfs_cfg_hw_clock mpfs_cfg_clks[] = { .cfg.shift = 0, .cfg.width = 12, .cfg.table = mpfs_div_rtcref_table, - .reg_offset = REG_RTC_CLOCK_CR, + .cfg.map_offset = REG_RTC_CLOCK_CR, .cfg.flags = CLK_DIVIDER_ONE_BASED, - .cfg.hw.init = - CLK_HW_INIT_PARENTS_DATA("clk_rtcref", mpfs_ext_ref, &clk_divider_ops, 0), + .hw.init = + CLK_HW_INIT_PARENTS_DATA("clk_rtcref", mpfs_ext_ref, &mpfs_clk_cfg_ops, 0), } }; @@ -264,14 +339,14 @@ static int mpfs_clk_register_cfgs(struct device *dev, struct mpfs_cfg_hw_clock * for (i = 0; i < num_clks; i++) { struct mpfs_cfg_hw_clock *cfg_hw = &cfg_hws[i]; - cfg_hw->cfg.reg = data->base + cfg_hw->reg_offset; - ret = devm_clk_hw_register(dev, &cfg_hw->cfg.hw); + cfg_hw->cfg.map = data->regmap; + ret = devm_clk_hw_register(dev, &cfg_hw->hw); if (ret) return dev_err_probe(dev, ret, "failed to register clock id: %d\n", cfg_hw->id); id = cfg_hw->id; - data->hw_data.hws[id] = &cfg_hw->cfg.hw; + data->hw_data.hws[id] = &cfg_hw->hw; } return 0; @@ -281,15 +356,50 @@ static int mpfs_clk_register_cfgs(struct device *dev, struct mpfs_cfg_hw_clock * * peripheral clocks - devices connected to axi or ahb buses. */ -#define CLK_PERIPH(_id, _name, _parent, _shift, _flags) { \ - .id = _id, \ - .periph.bit_idx = _shift, \ - .periph.hw.init = CLK_HW_INIT_HW(_name, _parent, &clk_gate_ops, \ - _flags), \ - .periph.lock = &mpfs_clk_lock, \ +static int mpfs_periph_clk_enable(struct clk_hw *hw) +{ + struct mpfs_periph_hw_clock *periph_hw = to_mpfs_periph_clk(hw); + struct mpfs_periph_clock *periph = &periph_hw->periph; + + regmap_update_bits(periph->map, periph->map_offset, + BIT(periph->shift), BIT(periph->shift)); + + return 0; } -#define PARENT_CLK(PARENT) (&mpfs_cfg_clks[CLK_##PARENT##_OFFSET].cfg.hw) +static void mpfs_periph_clk_disable(struct clk_hw *hw) +{ + struct mpfs_periph_hw_clock *periph_hw = to_mpfs_periph_clk(hw); + struct mpfs_periph_clock *periph = &periph_hw->periph; + + regmap_update_bits(periph->map, periph->map_offset, BIT(periph->shift), 0); +} + +static int mpfs_periph_clk_is_enabled(struct clk_hw *hw) +{ + struct mpfs_periph_hw_clock *periph_hw = to_mpfs_periph_clk(hw); + struct mpfs_periph_clock *periph = &periph_hw->periph; + u32 val; + + regmap_read(periph->map, periph->map_offset, &val); + + return !!(val & BIT(periph->shift)); +} + +static const struct clk_ops mpfs_periph_clk_ops = { + .enable = mpfs_periph_clk_enable, + .disable = mpfs_periph_clk_disable, + .is_enabled = mpfs_periph_clk_is_enabled, +}; + +#define CLK_PERIPH(_id, _name, _parent, _shift, _flags) { \ + .id = _id, \ + .periph.map_offset = REG_SUBBLK_CLOCK_CR, \ + .periph.shift = _shift, \ + .hw.init = CLK_HW_INIT_HW(_name, _parent, &mpfs_periph_clk_ops, _flags), \ +} + +#define PARENT_CLK(PARENT) (&mpfs_cfg_clks[CLK_##PARENT##_OFFSET].hw) /* * Critical clocks: @@ -346,19 +456,55 @@ static int mpfs_clk_register_periphs(struct device *dev, struct mpfs_periph_hw_c for (i = 0; i < num_clks; i++) { struct mpfs_periph_hw_clock *periph_hw = &periph_hws[i]; - periph_hw->periph.reg = data->base + REG_SUBBLK_CLOCK_CR; - ret = devm_clk_hw_register(dev, &periph_hw->periph.hw); + periph_hw->periph.map = data->regmap; + ret = devm_clk_hw_register(dev, &periph_hw->hw); if (ret) return dev_err_probe(dev, ret, "failed to register clock id: %d\n", periph_hw->id); id = periph_hws[i].id; - data->hw_data.hws[id] = &periph_hw->periph.hw; + data->hw_data.hws[id] = &periph_hw->hw; } return 0; } +static inline int mpfs_clk_syscon_probe(struct mpfs_clock_data *clk_data, + struct platform_device *pdev) +{ + clk_data->regmap = syscon_regmap_lookup_by_compatible("microchip,mpfs-mss-top-sysreg"); + if (IS_ERR(clk_data->regmap)) + return PTR_ERR(clk_data->regmap); + + clk_data->msspll_base = devm_platform_ioremap_resource(pdev, 0); + if (IS_ERR(clk_data->msspll_base)) + return PTR_ERR(clk_data->msspll_base); + + return 0; +} + +static inline int mpfs_clk_old_format_probe(struct mpfs_clock_data *clk_data, + struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + + dev_warn(&pdev->dev, "falling back to old devicetree format"); + + clk_data->base = devm_platform_ioremap_resource(pdev, 0); + if (IS_ERR(clk_data->base)) + return PTR_ERR(clk_data->base); + + clk_data->msspll_base = devm_platform_ioremap_resource(pdev, 1); + if (IS_ERR(clk_data->msspll_base)) + return PTR_ERR(clk_data->msspll_base); + + clk_data->regmap = devm_regmap_init_mmio(dev, clk_data->base, &mpfs_clk_regmap_config); + 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); +} + static int mpfs_clk_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; @@ -374,13 +520,12 @@ static int mpfs_clk_probe(struct platform_device *pdev) if (!clk_data) return -ENOMEM; - clk_data->base = devm_platform_ioremap_resource(pdev, 0); - if (IS_ERR(clk_data->base)) - return PTR_ERR(clk_data->base); - - clk_data->msspll_base = devm_platform_ioremap_resource(pdev, 1); - if (IS_ERR(clk_data->msspll_base)) - return PTR_ERR(clk_data->msspll_base); + ret = mpfs_clk_syscon_probe(clk_data, pdev); + if (ret) { + ret = mpfs_clk_old_format_probe(clk_data, pdev); + if (ret) + return ret; + } clk_data->hw_data.num = num_clks; clk_data->dev = dev; @@ -406,11 +551,7 @@ static int mpfs_clk_probe(struct platform_device *pdev) if (ret) return ret; - ret = devm_of_clk_add_hw_provider(dev, of_clk_hw_onecell_get, &clk_data->hw_data); - if (ret) - return ret; - - return mpfs_reset_controller_register(dev, clk_data->base + REG_SUBBLK_RESET_CR); + return devm_of_clk_add_hw_provider(dev, of_clk_hw_onecell_get, &clk_data->hw_data); } static const struct of_device_id mpfs_clk_of_match_table[] = { -- cgit From bab55c25f2ebed2608e053183146893b63d6f078 Mon Sep 17 00:00:00 2001 From: Robert Marko Date: Wed, 24 Sep 2025 22:27:15 +0200 Subject: clk: lan966x: remove unused dt-bindings include In preparation for LAN969x support, all instances referring to defines in the LAN966x specific header were dropped, so its safe to drop its inclusion in the driver. Signed-off-by: Robert Marko Reviewed-by: Daniel Machon Link: https://lore.kernel.org/r/20250924202810.1641883-1-robert.marko@sartura.hr Signed-off-by: Claudiu Beznea --- drivers/clk/clk-lan966x.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/clk/clk-lan966x.c b/drivers/clk/clk-lan966x.c index 16e0405fe28b..3c7a48c616bb 100644 --- a/drivers/clk/clk-lan966x.c +++ b/drivers/clk/clk-lan966x.c @@ -16,8 +16,6 @@ #include #include -#include - #define GCK_ENA BIT(0) #define GCK_SRC_SEL GENMASK(9, 8) #define GCK_PRESCALER GENMASK(23, 16) -- cgit From 781f60e45bdfe351aad692ac0fa89e36f8bf4a36 Mon Sep 17 00:00:00 2001 From: Conor Dooley Date: Mon, 10 Nov 2025 11:23:50 +0000 Subject: reset: mpfs: add non-auxiliary bus probing 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 Acked-by: Philipp Zabel Signed-off-by: Conor Dooley --- drivers/clk/microchip/clk-mpfs.c | 4 +- drivers/reset/Kconfig | 1 + drivers/reset/reset-mpfs.c | 91 ++++++++++++++++++++++++---------------- include/soc/microchip/mpfs.h | 3 +- 4 files changed, 60 insertions(+), 39 deletions(-) diff --git a/drivers/clk/microchip/clk-mpfs.c b/drivers/clk/microchip/clk-mpfs.c index 484893e68b67..ee58304913ef 100644 --- a/drivers/clk/microchip/clk-mpfs.c +++ b/drivers/clk/microchip/clk-mpfs.c @@ -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) diff --git a/drivers/reset/Kconfig b/drivers/reset/Kconfig index 78b7078478d4..0ec4b7cd08d6 100644 --- a/drivers/reset/Kconfig +++ b/drivers/reset/Kconfig @@ -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 diff --git a/drivers/reset/reset-mpfs.c b/drivers/reset/reset-mpfs.c index f6fa10e03ea8..8ffcc54ee6f6 100644 --- a/drivers/reset/reset-mpfs.c +++ b/drivers/reset/reset-mpfs.c @@ -9,11 +9,13 @@ #include #include #include +#include #include #include #include -#include +#include #include +#include #include #include @@ -27,11 +29,10 @@ #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, ®); /* * 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 "); diff --git a/include/soc/microchip/mpfs.h b/include/soc/microchip/mpfs.h index 0bd67e10b704..ec04c98a8b63 100644 --- a/include/soc/microchip/mpfs.h +++ b/include/soc/microchip/mpfs.h @@ -14,6 +14,7 @@ #include #include +#include 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) */ -- cgit