From c2912fa76b663cc7621080f5dbdf134758c27de0 Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Sat, 9 May 2026 17:12:24 +0200 Subject: reset: ast2500: Staticize and constify driver ops Set the ops structure as static const. The structure is not accessible from outside of this driver and is not going to be modified at runtime. Signed-off-by: Marek Vasut --- drivers/reset/reset-ast2500.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/reset') diff --git a/drivers/reset/reset-ast2500.c b/drivers/reset/reset-ast2500.c index f3543fa8cc1..39b3d025713 100644 --- a/drivers/reset/reset-ast2500.c +++ b/drivers/reset/reset-ast2500.c @@ -91,7 +91,7 @@ static const struct udevice_id ast2500_reset_ids[] = { { } }; -struct reset_ops ast2500_reset_ops = { +static const struct reset_ops ast2500_reset_ops = { .rst_assert = ast2500_reset_assert, .rst_deassert = ast2500_reset_deassert, .rst_status = ast2500_reset_status, -- cgit v1.3.1 From cecdc51a4665705e9689b6780d9e0ff9dbd13421 Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Sat, 9 May 2026 17:12:25 +0200 Subject: reset: ast2600: Staticize and constify driver ops Set the ops structure as static const. The structure is not accessible from outside of this driver and is not going to be modified at runtime. Signed-off-by: Marek Vasut --- drivers/reset/reset-ast2600.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/reset') diff --git a/drivers/reset/reset-ast2600.c b/drivers/reset/reset-ast2600.c index ec7b9b6625d..9b77f6c2b71 100644 --- a/drivers/reset/reset-ast2600.c +++ b/drivers/reset/reset-ast2600.c @@ -90,7 +90,7 @@ static const struct udevice_id ast2600_reset_ids[] = { { } }; -struct reset_ops ast2600_reset_ops = { +static const struct reset_ops ast2600_reset_ops = { .rst_assert = ast2600_reset_assert, .rst_deassert = ast2600_reset_deassert, .rst_status = ast2600_reset_status, -- cgit v1.3.1 From 432749b1a3f7be53cc8b3c6156b0c6cf6612634b Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Sat, 9 May 2026 17:12:26 +0200 Subject: reset: at91: Staticize and constify driver ops Set the ops structure as static const. The structure is not accessible from outside of this driver and is not going to be modified at runtime. Signed-off-by: Marek Vasut --- drivers/reset/reset-at91.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/reset') diff --git a/drivers/reset/reset-at91.c b/drivers/reset/reset-at91.c index 165c87acdc4..ebbfae1469b 100644 --- a/drivers/reset/reset-at91.c +++ b/drivers/reset/reset-at91.c @@ -79,7 +79,7 @@ static int at91_rst_deassert(struct reset_ctl *reset_ctl) return at91_rst_update(reset, reset_ctl->id, false); } -struct reset_ops at91_reset_ops = { +static const struct reset_ops at91_reset_ops = { .of_xlate = at91_reset_of_xlate, .rst_assert = at91_rst_assert, .rst_deassert = at91_rst_deassert, -- cgit v1.3.1 From 6333bec332e87668a8a5b6b2745c81d958570e97 Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Sat, 9 May 2026 17:12:27 +0200 Subject: reset: bcm6345: Staticize and constify driver ops Set the ops structure as static const. The structure is not accessible from outside of this driver and is not going to be modified at runtime. Signed-off-by: Marek Vasut --- drivers/reset/reset-bcm6345.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/reset') diff --git a/drivers/reset/reset-bcm6345.c b/drivers/reset/reset-bcm6345.c index 6f140574216..161d00d1b0c 100644 --- a/drivers/reset/reset-bcm6345.c +++ b/drivers/reset/reset-bcm6345.c @@ -49,7 +49,7 @@ static int bcm6345_reset_request(struct reset_ctl *rst) return bcm6345_reset_assert(rst); } -struct reset_ops bcm6345_reset_reset_ops = { +static const struct reset_ops bcm6345_reset_reset_ops = { .request = bcm6345_reset_request, .rst_assert = bcm6345_reset_assert, .rst_deassert = bcm6345_reset_deassert, -- cgit v1.3.1 From 1fe34ada73ae056b8260106618a6c217f38f6b44 Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Sat, 9 May 2026 17:12:28 +0200 Subject: reset: dra7: Staticize and constify driver ops Set the ops structure as static const. The structure is not accessible from outside of this driver and is not going to be modified at runtime. Signed-off-by: Marek Vasut --- drivers/reset/reset-dra7.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/reset') diff --git a/drivers/reset/reset-dra7.c b/drivers/reset/reset-dra7.c index 2f0ec4c042f..6b570d87d23 100644 --- a/drivers/reset/reset-dra7.c +++ b/drivers/reset/reset-dra7.c @@ -51,7 +51,7 @@ static int dra7_reset_assert(struct reset_ctl *reset_ctl) return 0; } -struct reset_ops dra7_reset_ops = { +static const struct reset_ops dra7_reset_ops = { .rst_assert = dra7_reset_assert, .rst_deassert = dra7_reset_deassert, }; -- cgit v1.3.1 From 85be3b92879a2b3e2707eff9eea05977a6bb4f05 Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Sat, 9 May 2026 17:12:29 +0200 Subject: reset: mediatek: Staticize and constify driver ops Set the ops structure as static const. The structure is not accessible from outside of this driver and is not going to be modified at runtime. Signed-off-by: Marek Vasut --- drivers/reset/reset-mediatek.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/reset') diff --git a/drivers/reset/reset-mediatek.c b/drivers/reset/reset-mediatek.c index 4b3afab92ea..66bcf7c29b6 100644 --- a/drivers/reset/reset-mediatek.c +++ b/drivers/reset/reset-mediatek.c @@ -47,7 +47,7 @@ static int mediatek_reset_deassert(struct reset_ctl *reset_ctl) priv->regofs + ((id / 32) << 2), BIT(id % 32), 0); } -struct reset_ops mediatek_reset_ops = { +static const struct reset_ops mediatek_reset_ops = { .rst_assert = mediatek_reset_assert, .rst_deassert = mediatek_reset_deassert, }; -- cgit v1.3.1 From 4020549f9bbc00ba84af0dfc53ae9b859da67f4c Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Sat, 9 May 2026 17:12:30 +0200 Subject: reset: meson: Staticize and constify driver ops Set the ops structure as static const. The structure is not accessible from outside of this driver and is not going to be modified at runtime. Signed-off-by: Marek Vasut --- drivers/reset/reset-meson.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/reset') diff --git a/drivers/reset/reset-meson.c b/drivers/reset/reset-meson.c index 6337cdaaffa..8c27563ce23 100644 --- a/drivers/reset/reset-meson.c +++ b/drivers/reset/reset-meson.c @@ -66,7 +66,7 @@ static int meson_reset_deassert(struct reset_ctl *reset_ctl) return meson_reset_level(reset_ctl, false); } -struct reset_ops meson_reset_ops = { +static const struct reset_ops meson_reset_ops = { .request = meson_reset_request, .rst_assert = meson_reset_assert, .rst_deassert = meson_reset_deassert, -- cgit v1.3.1 From 35cd9d8636c25a7e9bc908db2fe8adcd87e6afc0 Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Sat, 9 May 2026 17:12:31 +0200 Subject: reset: npcm: Staticize and constify driver ops Set the ops structure as static const. The structure is not accessible from outside of this driver and is not going to be modified at runtime. Signed-off-by: Marek Vasut --- drivers/reset/reset-npcm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/reset') diff --git a/drivers/reset/reset-npcm.c b/drivers/reset/reset-npcm.c index a3b85a42250..66b541f09e6 100644 --- a/drivers/reset/reset-npcm.c +++ b/drivers/reset/reset-npcm.c @@ -126,7 +126,7 @@ static const struct udevice_id npcm_reset_ids[] = { { } }; -struct reset_ops npcm_reset_ops = { +static const struct reset_ops npcm_reset_ops = { .request = npcm_reset_request, .rfree = npcm_reset_free, .rst_assert = npcm_reset_assert, -- cgit v1.3.1 From 2a7e739c040bbeb34c39fb38d159609079109f51 Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Sat, 9 May 2026 17:12:32 +0200 Subject: reset: raspberrypi: Staticize and constify driver ops Set the ops structure as static const. The structure is not accessible from outside of this driver and is not going to be modified at runtime. Signed-off-by: Marek Vasut --- drivers/reset/reset-raspberrypi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/reset') diff --git a/drivers/reset/reset-raspberrypi.c b/drivers/reset/reset-raspberrypi.c index 1792f0813f7..73acd301e3d 100644 --- a/drivers/reset/reset-raspberrypi.c +++ b/drivers/reset/reset-raspberrypi.c @@ -28,7 +28,7 @@ static int raspberrypi_reset_assert(struct reset_ctl *reset_ctl) } } -struct reset_ops raspberrypi_reset_ops = { +static const struct reset_ops raspberrypi_reset_ops = { .request = raspberrypi_reset_request, .rst_assert = raspberrypi_reset_assert, }; -- cgit v1.3.1 From ce830106bf3b2d830e971ff622663a9c7516380b Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Sat, 9 May 2026 17:12:33 +0200 Subject: reset: sunxi: Staticize and constify driver ops Set the ops structure as static const. The structure is not accessible from outside of this driver and is not going to be modified at runtime. Signed-off-by: Marek Vasut --- drivers/reset/reset-sunxi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/reset') diff --git a/drivers/reset/reset-sunxi.c b/drivers/reset/reset-sunxi.c index fd47e1f9e37..6195edd5b2f 100644 --- a/drivers/reset/reset-sunxi.c +++ b/drivers/reset/reset-sunxi.c @@ -67,7 +67,7 @@ static int sunxi_reset_deassert(struct reset_ctl *reset_ctl) return sunxi_set_reset(reset_ctl, true); } -struct reset_ops sunxi_reset_ops = { +static const struct reset_ops sunxi_reset_ops = { .request = sunxi_reset_request, .rst_assert = sunxi_reset_assert, .rst_deassert = sunxi_reset_deassert, -- cgit v1.3.1 From 1e38a363c2ae5db7f4a64fb10051ff2321891e3e Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Sat, 9 May 2026 17:12:34 +0200 Subject: reset: sandbox: Staticize and constify driver ops Set the ops structure as static const. The structure is not accessible from outside of this driver and is not going to be modified at runtime. Signed-off-by: Marek Vasut --- drivers/reset/sandbox-reset.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/reset') diff --git a/drivers/reset/sandbox-reset.c b/drivers/reset/sandbox-reset.c index adf9eedcba6..1c0ea7390df 100644 --- a/drivers/reset/sandbox-reset.c +++ b/drivers/reset/sandbox-reset.c @@ -85,7 +85,7 @@ static const struct udevice_id sandbox_reset_ids[] = { { } }; -struct reset_ops sandbox_reset_reset_ops = { +static const struct reset_ops sandbox_reset_reset_ops = { .request = sandbox_reset_request, .rfree = sandbox_reset_free, .rst_assert = sandbox_reset_assert, -- cgit v1.3.1 From 9c631c5dbb0758753fda452f3c5c8516f986e59a Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Sat, 9 May 2026 17:12:35 +0200 Subject: reset: sti: Staticize and constify driver ops Set the ops structure as static const. The structure is not accessible from outside of this driver and is not going to be modified at runtime. Signed-off-by: Marek Vasut Reviewed-by: Patrice Chotard --- drivers/reset/sti-reset.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/reset') diff --git a/drivers/reset/sti-reset.c b/drivers/reset/sti-reset.c index 412a0c5b452..37a37a72fd3 100644 --- a/drivers/reset/sti-reset.c +++ b/drivers/reset/sti-reset.c @@ -290,7 +290,7 @@ static int sti_reset_deassert(struct reset_ctl *reset_ctl) return sti_reset_program_hw(reset_ctl, false); } -struct reset_ops sti_reset_ops = { +static const struct reset_ops sti_reset_ops = { .rst_assert = sti_reset_assert, .rst_deassert = sti_reset_deassert, }; -- cgit v1.3.1 From 6f69da0d0fd7775f77df7ff64f761d07c901d39c Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Sat, 9 May 2026 17:12:36 +0200 Subject: reset: tegra-car: Staticize and constify driver ops Set the ops structure as static const. The structure is not accessible from outside of this driver and is not going to be modified at runtime. Signed-off-by: Marek Vasut Acked-by: Svyatoslav Ryhel --- drivers/reset/tegra-car-reset.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/reset') diff --git a/drivers/reset/tegra-car-reset.c b/drivers/reset/tegra-car-reset.c index e3ecc8d3735..63f148cf3d9 100644 --- a/drivers/reset/tegra-car-reset.c +++ b/drivers/reset/tegra-car-reset.c @@ -42,7 +42,7 @@ static int tegra_car_reset_deassert(struct reset_ctl *reset_ctl) return 0; } -struct reset_ops tegra_car_reset_ops = { +static const struct reset_ops tegra_car_reset_ops = { .request = tegra_car_reset_request, .rst_assert = tegra_car_reset_assert, .rst_deassert = tegra_car_reset_deassert, -- cgit v1.3.1 From c97fbda5fab8e42ce34d75b3a61800b9fe5162d0 Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Sat, 9 May 2026 17:12:37 +0200 Subject: reset: tegra186: Staticize and constify driver ops Set the ops structure as static const. The structure is not accessible from outside of this driver and is not going to be modified at runtime. Signed-off-by: Marek Vasut Acked-by: Svyatoslav Ryhel --- drivers/reset/tegra186-reset.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/reset') diff --git a/drivers/reset/tegra186-reset.c b/drivers/reset/tegra186-reset.c index 89624227c29..1d8f40acaef 100644 --- a/drivers/reset/tegra186-reset.c +++ b/drivers/reset/tegra186-reset.c @@ -43,7 +43,7 @@ static int tegra186_reset_deassert(struct reset_ctl *reset_ctl) return tegra186_reset_common(reset_ctl, CMD_RESET_DEASSERT); } -struct reset_ops tegra186_reset_ops = { +static const struct reset_ops tegra186_reset_ops = { .rst_assert = tegra186_reset_assert, .rst_deassert = tegra186_reset_deassert, }; -- cgit v1.3.1 From 19f7def2646f2ec2926e8a0fcff50d4b754eec92 Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Mon, 25 May 2026 13:45:42 +0200 Subject: reset: Add reset_reset() and reset_reset_bulk() API Add reset_reset() and reset_reset_bulk() functions to the reset controller API. These functions assert and then deassert reset signals in a single call, providing a convenient way to pulse/toggle a reset line. This mimics the Linux kernel's reset_control_reset() and reset_control_bulk_reset() APIs. The new functions are useful for drivers that need to cycle a reset line during initialization or error recovery but with also passing delay parameter. If a driver implements the rst_reset op, it will be called directly with the delay parameter. Otherwise, the reset core performs reset_assert(), optional udelay(), and reset_deassert() as fallback. Reviewed-by: Simon Glass Signed-off-by: Michal Simek Link: https://lore.kernel.org/r/55ddd313c9e7b2d4dc79ab36bdd0040f871610f6.1779709539.git.michal.simek@amd.com --- drivers/reset/reset-uclass.c | 34 ++++++++++++++++++++++++++++++ include/reset-uclass.h | 19 +++++++++++++++++ include/reset.h | 49 ++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 102 insertions(+) (limited to 'drivers/reset') diff --git a/drivers/reset/reset-uclass.c b/drivers/reset/reset-uclass.c index fe4cebf54f1..c199e3e5da7 100644 --- a/drivers/reset/reset-uclass.c +++ b/drivers/reset/reset-uclass.c @@ -13,6 +13,7 @@ #include #include #include +#include static inline struct reset_ops *reset_dev_ops(struct udevice *dev) { @@ -225,6 +226,39 @@ int reset_deassert_bulk(struct reset_ctl_bulk *bulk) return 0; } +int reset_reset(struct reset_ctl *reset_ctl, ulong delay_us) +{ + struct reset_ops *ops = reset_dev_ops(reset_ctl->dev); + int ret; + + debug("%s(reset_ctl=%p, delay_us=%lu)\n", __func__, reset_ctl, + delay_us); + + if (ops->rst_reset) + return ops->rst_reset(reset_ctl, delay_us); + + ret = reset_assert(reset_ctl); + if (ret < 0) + return ret; + + udelay(delay_us); + + return reset_deassert(reset_ctl); +} + +int reset_reset_bulk(struct reset_ctl_bulk *bulk, ulong delay_us) +{ + int i, ret; + + for (i = 0; i < bulk->count; i++) { + ret = reset_reset(&bulk->resets[i], delay_us); + if (ret < 0) + return ret; + } + + return 0; +} + int reset_status(struct reset_ctl *reset_ctl) { struct reset_ops *ops = reset_dev_ops(reset_ctl->dev); diff --git a/include/reset-uclass.h b/include/reset-uclass.h index 9a0696dd1e3..7af090b60b5 100644 --- a/include/reset-uclass.h +++ b/include/reset-uclass.h @@ -76,6 +76,25 @@ struct reset_ops { * @return 0 if OK, or a negative error code. */ int (*rst_deassert)(struct reset_ctl *reset_ctl); + /** + * rst_reset - Reset a HW module. + * + * This optional function triggers a reset pulse on the reset line. + * If not implemented, reset_reset() falls back to rst_assert(), + * udelay(@delay_us), then rst_deassert(); that delay is therefore + * observed only on the fallback path. + * + * When rst_reset is provided, @delay_us is controller-specific: the + * implementation should honour it if the hardware needs a minimum + * assertion time before release. It may ignore @delay_us when the + * pulse shape is fixed elsewhere (for example a firmware pulse). + * + * @reset_ctl: The reset signal to pulse. + * @delay_us: Minimum delay in microseconds between assert and + * deassert where applicable; see above. + * @return 0 if OK, or a negative error code. + */ + int (*rst_reset)(struct reset_ctl *reset_ctl, ulong delay_us); /** * rst_status - Check reset signal status. * diff --git a/include/reset.h b/include/reset.h index 036a786d2ac..58574b983f6 100644 --- a/include/reset.h +++ b/include/reset.h @@ -320,6 +320,45 @@ int reset_deassert(struct reset_ctl *reset_ctl); */ int reset_deassert_bulk(struct reset_ctl_bulk *bulk); +/** + * reset_reset - Reset a HW module by asserting and deasserting a reset signal. + * + * This function will assert and then deassert the specified reset signal, + * thus resetting the affected HW module. This is a convenience function + * that combines reset_assert() and reset_deassert(). + * + * If the controller implements struct reset_ops.rst_reset, that callback + * is used and @delay_us is interpreted as documented there. Otherwise the + * core performs reset_assert(), udelay(@delay_us), then reset_deassert(). + * + * @reset_ctl: A reset control struct that was previously successfully + * requested by reset_get_by_*(). + * @delay_us: Delay in microseconds between assert and deassert on the + * fallback path; meaning is driver-specific when rst_reset is used. + * Use 0 for no delay on the fallback path. + * Return: 0 if OK, or a negative error code. + */ +int reset_reset(struct reset_ctl *reset_ctl, ulong delay_us); + +/** + * reset_reset_bulk - Reset all HW modules in a reset control bulk struct. + * + * This calls reset_reset() on each entry in order. Each line therefore + * completes its own assert/delay/deassert (or controller rst_reset) before + * the next entry starts. That matches Linux reset_control_bulk_reset(). + * + * When several lines must stay asserted together for @delay_us (typical + * multi-reset controllers), use reset_assert_bulk(), udelay(@delay_us), + * and reset_deassert_bulk() instead. + * + * @bulk: A reset control bulk struct that was previously successfully + * requested by reset_get_bulk(). + * @delay_us: Delay in microseconds passed to each reset_reset(); see + * reset_reset() and struct reset_ops.rst_reset. + * Return: 0 if OK, or a negative error code. + */ +int reset_reset_bulk(struct reset_ctl_bulk *bulk, ulong delay_us); + /** * rst_status - Check reset signal status. * @@ -443,6 +482,16 @@ static inline int reset_deassert_bulk(struct reset_ctl_bulk *bulk) return 0; } +static inline int reset_reset(struct reset_ctl *reset_ctl, ulong delay_us) +{ + return -ENOSYS; +} + +static inline int reset_reset_bulk(struct reset_ctl_bulk *bulk, ulong delay_us) +{ + return -ENOSYS; +} + static inline int reset_status(struct reset_ctl *reset_ctl) { return -ENOTSUPP; -- cgit v1.3.1 From 724d3cafe3ba8a2b3007c579bf52cd0612e6c565 Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Mon, 25 May 2026 13:45:43 +0200 Subject: reset: Add sandbox tests for reset_reset() and reset_reset_bulk() Add DM test coverage for the new reset_reset() and reset_reset_bulk() API functions. The sandbox reset driver implements rst_reset so these tests exercise that op (not the assert/udelay/deassert fallback in reset_reset()). reset_reset_bulk() calls reset_reset() on each bulk entry in order, so each line's rst_reset runs in sequence. Reviewed-by: Simon Glass Signed-off-by: Michal Simek Link: https://lore.kernel.org/r/be5411daf0de8eb64fbddf06e8ad82f50066e811.1779709539.git.michal.simek@amd.com --- arch/sandbox/include/asm/reset.h | 3 ++ drivers/reset/sandbox-reset-test.c | 14 ++++++++ drivers/reset/sandbox-reset.c | 31 ++++++++++++++++++ test/dm/reset.c | 67 ++++++++++++++++++++++++++++++++++++++ 4 files changed, 115 insertions(+) (limited to 'drivers/reset') diff --git a/arch/sandbox/include/asm/reset.h b/arch/sandbox/include/asm/reset.h index f0709b41c09..2890e0dc09b 100644 --- a/arch/sandbox/include/asm/reset.h +++ b/arch/sandbox/include/asm/reset.h @@ -10,6 +10,7 @@ struct udevice; int sandbox_reset_query(struct udevice *dev, unsigned long id); int sandbox_reset_is_requested(struct udevice *dev, unsigned long id); +int sandbox_reset_get_count(struct udevice *dev, unsigned long id); int sandbox_reset_test_get(struct udevice *dev); int sandbox_reset_test_get_devm(struct udevice *dev); @@ -19,6 +20,8 @@ int sandbox_reset_test_assert(struct udevice *dev); int sandbox_reset_test_assert_bulk(struct udevice *dev); int sandbox_reset_test_deassert(struct udevice *dev); int sandbox_reset_test_deassert_bulk(struct udevice *dev); +int sandbox_reset_test_reset(struct udevice *dev); +int sandbox_reset_test_reset_bulk(struct udevice *dev); int sandbox_reset_test_free(struct udevice *dev); int sandbox_reset_test_release_bulk(struct udevice *dev); diff --git a/drivers/reset/sandbox-reset-test.c b/drivers/reset/sandbox-reset-test.c index dfacb764bc7..64c205596c5 100644 --- a/drivers/reset/sandbox-reset-test.c +++ b/drivers/reset/sandbox-reset-test.c @@ -96,6 +96,20 @@ int sandbox_reset_test_deassert_bulk(struct udevice *dev) return reset_deassert_bulk(sbrt->bulkp); } +int sandbox_reset_test_reset(struct udevice *dev) +{ + struct sandbox_reset_test *sbrt = dev_get_priv(dev); + + return reset_reset(sbrt->ctlp, 0); +} + +int sandbox_reset_test_reset_bulk(struct udevice *dev) +{ + struct sandbox_reset_test *sbrt = dev_get_priv(dev); + + return reset_reset_bulk(sbrt->bulkp, 0); +} + int sandbox_reset_test_free(struct udevice *dev) { struct sandbox_reset_test *sbrt = dev_get_priv(dev); diff --git a/drivers/reset/sandbox-reset.c b/drivers/reset/sandbox-reset.c index 1c0ea7390df..458c332071f 100644 --- a/drivers/reset/sandbox-reset.c +++ b/drivers/reset/sandbox-reset.c @@ -9,12 +9,14 @@ #include #include #include +#include #define SANDBOX_RESET_SIGNALS 101 struct sandbox_reset_signal { bool asserted; bool requested; + int reset_count; }; struct sandbox_reset { @@ -31,6 +33,7 @@ static int sandbox_reset_request(struct reset_ctl *reset_ctl) return -EINVAL; sbr->signals[reset_ctl->id].requested = true; + sbr->signals[reset_ctl->id].reset_count = 0; return 0; } @@ -66,6 +69,21 @@ static int sandbox_reset_deassert(struct reset_ctl *reset_ctl) return 0; } +static int sandbox_reset_reset(struct reset_ctl *reset_ctl, ulong delay_us) +{ + struct sandbox_reset *sbr = dev_get_priv(reset_ctl->dev); + + debug("%s(reset_ctl=%p, delay_us=%lu)\n", __func__, reset_ctl, + delay_us); + + sbr->signals[reset_ctl->id].asserted = true; + udelay(delay_us); + sbr->signals[reset_ctl->id].asserted = false; + sbr->signals[reset_ctl->id].reset_count++; + + return 0; +} + static int sandbox_reset_bind(struct udevice *dev) { debug("%s(dev=%p)\n", __func__, dev); @@ -90,6 +108,7 @@ static const struct reset_ops sandbox_reset_reset_ops = { .rfree = sandbox_reset_free, .rst_assert = sandbox_reset_assert, .rst_deassert = sandbox_reset_deassert, + .rst_reset = sandbox_reset_reset, }; U_BOOT_DRIVER(sandbox_reset) = { @@ -125,3 +144,15 @@ int sandbox_reset_is_requested(struct udevice *dev, unsigned long id) return sbr->signals[id].requested; } + +int sandbox_reset_get_count(struct udevice *dev, unsigned long id) +{ + struct sandbox_reset *sbr = dev_get_priv(dev); + + debug("%s(dev=%p, id=%ld)\n", __func__, dev, id); + + if (id >= SANDBOX_RESET_SIGNALS) + return -EINVAL; + + return sbr->signals[id].reset_count; +} diff --git a/test/dm/reset.c b/test/dm/reset.c index dceb6a1dad3..043d7cb7e0f 100644 --- a/test/dm/reset.c +++ b/test/dm/reset.c @@ -120,6 +120,73 @@ static int dm_test_reset_devm(struct unit_test_state *uts) } DM_TEST(dm_test_reset_devm, UTF_SCAN_FDT); +static int dm_test_reset_reset(struct unit_test_state *uts) +{ + struct udevice *dev_reset; + struct udevice *dev_test; + + ut_assertok(uclass_get_device_by_name(UCLASS_RESET, "reset-ctl", + &dev_reset)); + ut_asserteq(0, sandbox_reset_query(dev_reset, TEST_RESET_ID)); + + ut_assertok(uclass_get_device_by_name(UCLASS_MISC, "reset-ctl-test", + &dev_test)); + ut_assertok(sandbox_reset_test_get(dev_test)); + + /* Verify reset_count starts at 0 */ + ut_asserteq(0, sandbox_reset_get_count(dev_reset, TEST_RESET_ID)); + + ut_assertok(sandbox_reset_test_assert(dev_test)); + ut_asserteq(1, sandbox_reset_query(dev_reset, TEST_RESET_ID)); + + ut_assertok(sandbox_reset_test_reset(dev_test)); + + /* Verify reset was pulsed (count incremented) */ + ut_asserteq(1, sandbox_reset_get_count(dev_reset, TEST_RESET_ID)); + ut_asserteq(0, sandbox_reset_query(dev_reset, TEST_RESET_ID)); + + ut_assertok(sandbox_reset_test_free(dev_test)); + + return 0; +} +DM_TEST(dm_test_reset_reset, UTF_SCAN_FDT); + +static int dm_test_reset_reset_bulk(struct unit_test_state *uts) +{ + struct udevice *dev_reset; + struct udevice *dev_test; + + ut_assertok(uclass_get_device_by_name(UCLASS_RESET, "reset-ctl", + &dev_reset)); + ut_asserteq(0, sandbox_reset_query(dev_reset, TEST_RESET_ID)); + ut_asserteq(0, sandbox_reset_query(dev_reset, OTHER_RESET_ID)); + + ut_assertok(uclass_get_device_by_name(UCLASS_MISC, "reset-ctl-test", + &dev_test)); + ut_assertok(sandbox_reset_test_get_bulk(dev_test)); + + /* Verify reset_count starts at 0 */ + ut_asserteq(0, sandbox_reset_get_count(dev_reset, TEST_RESET_ID)); + ut_asserteq(0, sandbox_reset_get_count(dev_reset, OTHER_RESET_ID)); + + ut_assertok(sandbox_reset_test_assert_bulk(dev_test)); + ut_asserteq(1, sandbox_reset_query(dev_reset, TEST_RESET_ID)); + ut_asserteq(1, sandbox_reset_query(dev_reset, OTHER_RESET_ID)); + + ut_assertok(sandbox_reset_test_reset_bulk(dev_test)); + + /* Verify resets were pulsed (counts incremented) */ + ut_asserteq(1, sandbox_reset_get_count(dev_reset, TEST_RESET_ID)); + ut_asserteq(1, sandbox_reset_get_count(dev_reset, OTHER_RESET_ID)); + ut_asserteq(0, sandbox_reset_query(dev_reset, TEST_RESET_ID)); + ut_asserteq(0, sandbox_reset_query(dev_reset, OTHER_RESET_ID)); + + ut_assertok(sandbox_reset_test_release_bulk(dev_test)); + + return 0; +} +DM_TEST(dm_test_reset_reset_bulk, UTF_SCAN_FDT); + static int dm_test_reset_bulk(struct unit_test_state *uts) { struct udevice *dev_reset; -- cgit v1.3.1 From 4e3f64c7cc0c6a5defdceb485313b8a33f231f10 Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Mon, 25 May 2026 13:45:44 +0200 Subject: reset: sandbox: Cover reset_reset() fallback with second sandbox provider Add a sandbox reset controller compatible string "sandbox,reset-ctl-fallback-only" that reuses the existing sandbox assert, deassert, request, and free helpers but omits rst_reset. That forces reset_reset() through the core assert / udelay / deassert fallback. Extend the reset-ctl-test DT node with a fifth reset line named "fallback" that points at the new provider, and add dm_test_reset_reset_fallback_path which verifies sandbox_reset_get_count() stays zero (rst_reset is never invoked) while the line ends deasserted after reset_reset(). This complements the existing rst_reset coverage on sandbox,reset-ctl and matches the approach of using a separate controller to exercise the fallback path in unit tests. Reviewed-by: Simon Glass Signed-off-by: Michal Simek Link: https://lore.kernel.org/r/c1d40db6e2332a8b23ba842385b3f8c3d0290109.1779709539.git.michal.simek@amd.com --- arch/sandbox/dts/test.dts | 10 ++++++++-- drivers/reset/sandbox-reset.c | 27 +++++++++++++++++++++++++++ test/dm/reset.c | 40 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 75 insertions(+), 2 deletions(-) (limited to 'drivers/reset') diff --git a/arch/sandbox/dts/test.dts b/arch/sandbox/dts/test.dts index 0887de4333b..074e5c06ec8 100644 --- a/arch/sandbox/dts/test.dts +++ b/arch/sandbox/dts/test.dts @@ -1530,10 +1530,16 @@ #reset-cells = <1>; }; + resetc_fb: reset-ctl-fallback { + compatible = "sandbox,reset-ctl-fallback-only"; + #reset-cells = <1>; + }; + reset-ctl-test { compatible = "sandbox,reset-ctl-test"; - resets = <&resetc 100>, <&resetc 2>, <&resetc 20>, <&resetc 40>; - reset-names = "other", "test", "test2", "test3"; + resets = <&resetc 100>, <&resetc 2>, <&resetc 20>, <&resetc 40>, + <&resetc_fb 5>; + reset-names = "other", "test", "test2", "test3", "fallback"; }; rng { diff --git a/drivers/reset/sandbox-reset.c b/drivers/reset/sandbox-reset.c index 458c332071f..12812f0f340 100644 --- a/drivers/reset/sandbox-reset.c +++ b/drivers/reset/sandbox-reset.c @@ -121,6 +121,33 @@ U_BOOT_DRIVER(sandbox_reset) = { .ops = &sandbox_reset_reset_ops, }; +/* + * Second sandbox reset controller for tests: same assert/deassert + * behaviour as sandbox_reset, but no rst_reset so reset_reset() uses + * the core assert / udelay / deassert fallback (reset_count never bumps). + */ +static const struct udevice_id sandbox_reset_fallback_ids[] = { + { .compatible = "sandbox,reset-ctl-fallback-only" }, + { } +}; + +static const struct reset_ops sandbox_reset_fallback_reset_ops = { + .request = sandbox_reset_request, + .rfree = sandbox_reset_free, + .rst_assert = sandbox_reset_assert, + .rst_deassert = sandbox_reset_deassert, +}; + +U_BOOT_DRIVER(sandbox_reset_fallback) = { + .name = "sandbox_reset_fallback", + .id = UCLASS_RESET, + .of_match = sandbox_reset_fallback_ids, + .bind = sandbox_reset_bind, + .probe = sandbox_reset_probe, + .priv_auto = sizeof(struct sandbox_reset), + .ops = &sandbox_reset_fallback_reset_ops, +}; + int sandbox_reset_query(struct udevice *dev, unsigned long id) { struct sandbox_reset *sbr = dev_get_priv(dev); diff --git a/test/dm/reset.c b/test/dm/reset.c index 043d7cb7e0f..91fa7ff723b 100644 --- a/test/dm/reset.c +++ b/test/dm/reset.c @@ -19,6 +19,9 @@ /* This is the other reset phandle specifier handled by bulk */ #define OTHER_RESET_ID 2 +/* Line on reset-ctl-fallback (sandbox,reset-ctl-fallback-only); see test.dts */ +#define FALLBACK_RESET_ID 5 + /* Base test of the reset uclass */ static int dm_test_reset_base(struct unit_test_state *uts) { @@ -151,6 +154,43 @@ static int dm_test_reset_reset(struct unit_test_state *uts) } DM_TEST(dm_test_reset_reset, UTF_SCAN_FDT); +/* + * reset_reset() fallback path: controller has no rst_reset op, so the + * core does assert -> udelay -> deassert. rst_reset-only accounting + * (reset_count) stays zero. Leave the line asserted before reset_reset() + * so we verify the fallback actually pulses it back to deasserted. + */ +static int dm_test_reset_reset_fallback_path(struct unit_test_state *uts) +{ + struct udevice *dev_reset_fb; + struct udevice *dev_test; + struct reset_ctl ctl; + + ut_assertok(uclass_get_device_by_name(UCLASS_RESET, "reset-ctl-fallback", + &dev_reset_fb)); + ut_asserteq(0, sandbox_reset_query(dev_reset_fb, FALLBACK_RESET_ID)); + ut_asserteq(0, sandbox_reset_get_count(dev_reset_fb, FALLBACK_RESET_ID)); + + ut_assertok(uclass_get_device_by_name(UCLASS_MISC, "reset-ctl-test", + &dev_test)); + ut_assertok(reset_get_by_name(dev_test, "fallback", &ctl)); + ut_asserteq_ptr(ctl.dev, dev_reset_fb); + ut_asserteq(FALLBACK_RESET_ID, ctl.id); + + ut_assertok(reset_assert(&ctl)); + ut_asserteq(1, sandbox_reset_query(dev_reset_fb, FALLBACK_RESET_ID)); + ut_asserteq(0, sandbox_reset_get_count(dev_reset_fb, FALLBACK_RESET_ID)); + + ut_assertok(reset_reset(&ctl, 1)); + ut_asserteq(0, sandbox_reset_get_count(dev_reset_fb, FALLBACK_RESET_ID)); + ut_asserteq(0, sandbox_reset_query(dev_reset_fb, FALLBACK_RESET_ID)); + + ut_assertok(reset_free(&ctl)); + + return 0; +} +DM_TEST(dm_test_reset_reset_fallback_path, UTF_SCAN_FDT); + static int dm_test_reset_reset_bulk(struct unit_test_state *uts) { struct udevice *dev_reset; -- cgit v1.3.1 From 8efa173b389e5cef6eece991351442baea0264fd Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Mon, 25 May 2026 13:45:46 +0200 Subject: reset: zynqmp: Implement rst_reset using PM_RESET_ACTION_PULSE Implement the rst_reset operation in the ZynqMP reset driver to use PM_RESET_ACTION_PULSE. This allows the reset controller to perform a reset pulse in a single firmware call instead of separate assert and deassert calls. This matches the Linux kernel implementation of zynqmp_reset_reset(). Reviewed-by: Simon Glass Signed-off-by: Michal Simek Link: https://lore.kernel.org/r/be77d6f1b60f591ef626c14229d85c5cab867967.1779709539.git.michal.simek@amd.com --- drivers/reset/reset-zynqmp.c | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'drivers/reset') diff --git a/drivers/reset/reset-zynqmp.c b/drivers/reset/reset-zynqmp.c index d04e8eef3bb..2b58f3a75b4 100644 --- a/drivers/reset/reset-zynqmp.c +++ b/drivers/reset/reset-zynqmp.c @@ -45,6 +45,16 @@ static int zynqmp_reset_deassert(struct reset_ctl *rst) PM_RESET_ACTION_RELEASE); } +static int zynqmp_reset_reset(struct reset_ctl *rst, ulong delay_us) +{ + struct zynqmp_reset_priv *priv = dev_get_priv(rst->dev); + + dev_dbg(rst->dev, "%s(rst=%p) (id=%lu)\n", __func__, rst, rst->id); + + return zynqmp_pm_reset_assert(priv->reset_id + rst->id, + PM_RESET_ACTION_PULSE); +} + static int zynqmp_reset_request(struct reset_ctl *rst) { struct zynqmp_reset_priv *priv = dev_get_priv(rst->dev); @@ -74,6 +84,7 @@ const struct reset_ops zynqmp_reset_ops = { .request = zynqmp_reset_request, .rst_assert = zynqmp_reset_assert, .rst_deassert = zynqmp_reset_deassert, + .rst_reset = zynqmp_reset_reset, }; static const struct udevice_id zynqmp_reset_ids[] = { -- cgit v1.3.1 From 305c014fdb7208ced179e47dc3634e7faa6a2502 Mon Sep 17 00:00:00 2001 From: Peng Fan Date: Tue, 26 May 2026 14:48:01 +0800 Subject: reset: ast: Use dev_read_addr_ptr() Use dev_read_addr_ptr() which supports both live device tree and flat DT backends, avoiding direct dependency on devfdt_* helpers. While at here, correct error return value, when priv->scu is NULL, PTR_ERR(priv->scu) is 0 which implies success. Change to return '-EINVAL'. No functional changes. Signed-off-by: Peng Fan --- drivers/reset/reset-ast2500.c | 4 ++-- drivers/reset/reset-ast2600.c | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers/reset') diff --git a/drivers/reset/reset-ast2500.c b/drivers/reset/reset-ast2500.c index 39b3d025713..c85906bbeb5 100644 --- a/drivers/reset/reset-ast2500.c +++ b/drivers/reset/reset-ast2500.c @@ -77,10 +77,10 @@ static int ast2500_reset_probe(struct udevice *dev) return rc; } - priv->scu = devfdt_get_addr_ptr(scu_dev); + priv->scu = dev_read_addr_ptr(scu_dev); if (IS_ERR_OR_NULL(priv->scu)) { debug("%s: invalid SCU base pointer\n", __func__); - return PTR_ERR(priv->scu); + return -EINVAL; } return 0; diff --git a/drivers/reset/reset-ast2600.c b/drivers/reset/reset-ast2600.c index 9b77f6c2b71..71b6220225a 100644 --- a/drivers/reset/reset-ast2600.c +++ b/drivers/reset/reset-ast2600.c @@ -76,10 +76,10 @@ static int ast2600_reset_probe(struct udevice *dev) return rc; } - priv->scu = devfdt_get_addr_ptr(scu_dev); + priv->scu = dev_read_addr_ptr(scu_dev); if (IS_ERR_OR_NULL(priv->scu)) { debug("%s: invalid SCU base pointer\n", __func__); - return PTR_ERR(priv->scu); + return -EINVAL; } return 0; -- cgit v1.3.1 From 6fb40812ddb846b02d585c55895242959cbb6495 Mon Sep 17 00:00:00 2001 From: Ryan Chen Date: Fri, 12 Jun 2026 17:43:12 +0800 Subject: reset: ast2700: add reset driver support Add reset controller driver for the dual-die AST2700 SoC. The controller manages module-level reset signals via the modrst register block at offset 0x200 within each SCU. Signed-off-by: Ryan Chen --- MAINTAINERS | 2 +- drivers/reset/Kconfig | 9 +++++ drivers/reset/Makefile | 1 + drivers/reset/reset-ast2700.c | 82 +++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 93 insertions(+), 1 deletion(-) create mode 100644 drivers/reset/reset-ast2700.c (limited to 'drivers/reset') diff --git a/MAINTAINERS b/MAINTAINERS index 41059979f30..6a633df499d 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -222,7 +222,7 @@ F: drivers/net/ftgmac100.[ch] F: drivers/pinctrl/aspeed/ F: drivers/pwm/pwm-aspeed.c F: drivers/ram/aspeed/ -F: drivers/reset/reset-ast2500.c +F: drivers/reset/reset-ast*.c F: drivers/watchdog/ast_wdt.c N: aspeed N: ast2700 diff --git a/drivers/reset/Kconfig b/drivers/reset/Kconfig index e7c0870c918..c851354c7a5 100644 --- a/drivers/reset/Kconfig +++ b/drivers/reset/Kconfig @@ -107,6 +107,15 @@ config RESET_AST2600 Say Y if you want to control reset signals of different peripherals through System Control Unit (SCU). +config RESET_AST2700 + bool "Reset controller driver for AST2700 SoCs" + depends on DM_RESET && ASPEED_AST2700 + default y if ASPEED_AST2700 + help + Support for reset controller on AST2700 SoC. + Say Y if you want to control reset signals of different peripherals + through System Control Unit (SCU). + config RESET_ROCKCHIP bool "Reset controller driver for Rockchip SoCs" depends on DM_RESET && ARCH_ROCKCHIP && CLK diff --git a/drivers/reset/Makefile b/drivers/reset/Makefile index 2c83f858895..3fce96509cd 100644 --- a/drivers/reset/Makefile +++ b/drivers/reset/Makefile @@ -18,6 +18,7 @@ obj-$(CONFIG_RESET_BRCMSTB_RESCAL) += reset-brcmstb-rescal.o obj-$(CONFIG_RESET_UNIPHIER) += reset-uniphier.o obj-$(CONFIG_RESET_AST2500) += reset-ast2500.o obj-$(CONFIG_RESET_AST2600) += reset-ast2600.o +obj-$(CONFIG_RESET_AST2700) += reset-ast2700.o obj-$(CONFIG_$(PHASE_)RESET_ROCKCHIP) += reset-rockchip.o rst-rk3506.o rst-rk3528.o rst-rk3576.o rst-rk3588.o obj-$(CONFIG_RESET_MESON) += reset-meson.o obj-$(CONFIG_RESET_SOCFPGA) += reset-socfpga.o diff --git a/drivers/reset/reset-ast2700.c b/drivers/reset/reset-ast2700.c new file mode 100644 index 00000000000..2dd9e36cc0a --- /dev/null +++ b/drivers/reset/reset-ast2700.c @@ -0,0 +1,82 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) ASPEED Technology Inc. + */ + +#include +#include +#include +#include +#include + +/* Offset of the modrst register block within the SCU. */ +#define AST2700_RESET_OFFSET 0x200 + +struct ast2700_reset_priv { + void __iomem *base; +}; + +static int ast2700_reset_assert(struct reset_ctl *reset_ctl) +{ + struct ast2700_reset_priv *priv = dev_get_priv(reset_ctl->dev); + + if (reset_ctl->id < 32) + writel(BIT(reset_ctl->id), priv->base); + else + writel(BIT(reset_ctl->id - 32), priv->base + 0x20); + + return 0; +} + +static int ast2700_reset_deassert(struct reset_ctl *reset_ctl) +{ + struct ast2700_reset_priv *priv = dev_get_priv(reset_ctl->dev); + + if (reset_ctl->id < 32) + writel(BIT(reset_ctl->id), priv->base + 0x04); + else + writel(BIT(reset_ctl->id - 32), priv->base + 0x24); + + return 0; +} + +static int ast2700_reset_status(struct reset_ctl *reset_ctl) +{ + struct ast2700_reset_priv *priv = dev_get_priv(reset_ctl->dev); + int status; + + if (reset_ctl->id < 32) + status = BIT(reset_ctl->id) & readl(priv->base); + else + status = BIT(reset_ctl->id - 32) & readl(priv->base + 0x20); + + return !!status; +} + +static int ast2700_reset_probe(struct udevice *dev) +{ + struct ast2700_reset_priv *priv = dev_get_priv(dev); + void __iomem *scu_base; + + scu_base = dev_read_addr_ptr(dev); + if (!scu_base) + return -EINVAL; + + priv->base = scu_base + AST2700_RESET_OFFSET; + + return 0; +} + +static const struct reset_ops ast2700_reset_ops = { + .rst_assert = ast2700_reset_assert, + .rst_deassert = ast2700_reset_deassert, + .rst_status = ast2700_reset_status, +}; + +U_BOOT_DRIVER(ast2700_reset) = { + .name = "ast2700_reset", + .id = UCLASS_RESET, + .probe = ast2700_reset_probe, + .ops = &ast2700_reset_ops, + .priv_auto = sizeof(struct ast2700_reset_priv), +}; -- cgit v1.3.1