* [PATCH v4 0/2] reset: Serialize shared resets whose ops may sleep
@ 2026-10-23 7:16 shengjiu.wang
2026-10-23 7:16 ` [PATCH v4 1/2] reset: core: Serialize concurrent deassert/reset of shared resets shengjiu.wang
` (2 more replies)
0 siblings, 3 replies; 8+ messages in thread
From: shengjiu.wang @ 2026-10-23 7:16 UTC (permalink / raw)
To: p.zabel, krzk, hansg, linux-kernel, broonie, alvin.sipraga
From: Shengjiu Wang <shengjiu.wang@nxp.com>
For a shared reset only the first caller runs the hardware op; the others
bump the refcount and return. When the op can sleep, a concurrent caller can
return before the first caller's op has finished and then touch hardware
still in reset.
Serialize the shared refcount update and the hardware op under a new
per-control mutex, but only for providers that opt in via a new
reset_controller_dev::can_sleep flag. Providers that leave it clear keep the
lockless path, so atomic callers are unaffected. reset-gpio is the first
provider to set the flag.
Changes in v4:
- Move the can_sleep/mutex description to the top of the core commit message.
- Also serialize reset_control_assert() under shared_lock.
- Split the reset-gpio can_sleep assignment into its own patch (2/2).
- Fix a kerneldoc typo; drop the Assisted-by trailer.
- Drop the Fixes: tag, present as a correctness improvement.
Changes in v3:
- Drop the reset_control_reset_atomic()/reset_control_deassert_atomic()
variants and their reset.h declarations/stubs; gate the mutex on
rcdev->can_sleep instead, so non-sleeping controllers keep the lockless
path and need no new API.
- Use a dedicated rstc->shared_lock taken inside the SRCU read-side section
instead of reusing rstc->lock before SRCU.
- Set can_sleep in reset-gpio; no other provider is converted.
- Drop the lockdep_assert_not_held() additions and the reset.rst / kerneldoc
text about sleeping-vs-atomic variants.
Changes in v2:
- Serialize only the shared may-sleep path under rstc->lock (taken before
SRCU to match reset_control_acquire()'s order); exclusive path stays
lockless, and reset_control_assert() is left unchanged.
- Add lockless reset_control_reset_atomic()/reset_control_deassert_atomic()
for atomic callers; gate the mutex on can_sleep so no shared consumer is
regressed and so it works on all configs.
- Factor the body into __reset_control_*()/__reset_control_*_locked()
helpers, and lockdep_assert_not_held() at each lock site to catch a
controller op re-entering the API on the same control.
- Declare the new variants and stubs in reset.h, and document the sleeping
vs atomic variants in the kerneldoc and reset.rst.
Shengjiu Wang (2):
reset: core: Serialize concurrent deassert/reset of shared resets
reset: gpio: Set can_sleep for the shared reset serialization
drivers/reset/core.c | 205 ++++++++++++++++++++-----------
drivers/reset/reset-gpio.c | 1 +
include/linux/reset-controller.h | 4 +
3 files changed, 139 insertions(+), 71 deletions(-)
--
2.34.1
^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH v4 1/2] reset: core: Serialize concurrent deassert/reset of shared resets
2026-10-23 7:16 [PATCH v4 0/2] reset: Serialize shared resets whose ops may sleep shengjiu.wang
@ 2026-10-23 7:16 ` shengjiu.wang
2026-10-23 8:42 ` Alvin Šipraga
2026-10-26 9:24 ` Philipp Zabel
2026-10-23 7:16 ` [PATCH v4 2/2] reset: gpio: Set can_sleep for the shared reset serialization shengjiu.wang
2026-11-03 10:31 ` [PATCH v4 0/2] reset: Serialize shared resets whose ops may sleep Philipp Zabel
2 siblings, 2 replies; 8+ messages in thread
From: shengjiu.wang @ 2026-10-23 7:16 UTC (permalink / raw)
To: p.zabel, krzk, hansg, linux-kernel, broonie, alvin.sipraga
From: Shengjiu Wang <shengjiu.wang@nxp.com>
Add a reset_controller_dev::can_sleep flag that a provider sets when its
reset ops may sleep. When it is set, serialize the shared refcount update
and the hardware op in reset_control_reset(), reset_control_deassert() and
reset_control_assert() under a new per-control mutex, taken inside the SRCU
read-side critical section. Providers that leave the flag clear keep the
existing lockless path, so callers in atomic context are unaffected.
reset_control_deassert() and reset_control_reset() are documented to
guarantee that the reset line has been deasserted, respectively that a
reset pulse has been issued, by the time they return.
For a shared reset only the first caller runs the hardware op; the other
callers just bump the refcount and return. When the op can sleep this
breaks the guarantee: a second caller can observe the bumped refcount and
return before the first caller's op has finished, and then touch hardware
that is still in reset. A reset_control_assert() racing a concurrent
reset_control_deassert() can likewise interleave the two sleeping ops and
leave the line asserted while the refcount says it is deasserted.
Suggested-by: Philipp Zabel <p.zabel@pengutronix.de>
Signed-off-by: Shengjiu Wang <shengjiu.wang@nxp.com>
Link: https://lore.kernel.org/all/aszDZlJ0KahNwgZO@analog.com/
---
drivers/reset/core.c | 205 ++++++++++++++++++++-----------
include/linux/reset-controller.h | 4 +
2 files changed, 138 insertions(+), 71 deletions(-)
diff --git a/drivers/reset/core.c b/drivers/reset/core.c
index 38e189d04d09..7eb4575413d6 100644
--- a/drivers/reset/core.c
+++ b/drivers/reset/core.c
@@ -52,6 +52,9 @@ static DEFINE_IDA(reset_gpio_ida);
* only used for shared resets, which means that the value
* will be either 0 or 1.
* @lock: serializes the internals of reset_control_acquire()
+ * @shared_lock: serializes the shared refcount update and the hardware op for
+ * controllers whose ops may sleep (rcdev->can_sleep); taken only
+ * inside the SRCU read-side critical section
*/
struct reset_control {
struct reset_controller_dev __rcu *rcdev;
@@ -65,6 +68,8 @@ struct reset_control {
atomic_t deassert_count;
atomic_t triggered_count;
struct mutex lock;
+ /* serializes the shared refcount update with its hardware op */
+ struct mutex shared_lock;
};
/**
@@ -355,6 +360,32 @@ static inline bool reset_control_is_array(struct reset_control *rstc)
return rstc->array;
}
+static int __reset_control_reset(struct reset_control *rstc,
+ struct reset_controller_dev *rcdev)
+{
+ int ret;
+
+ if (!rcdev->ops->reset)
+ return -ENOTSUPP;
+
+ if (rstc->shared) {
+ if (WARN_ON(atomic_read(&rstc->deassert_count) != 0))
+ return -EINVAL;
+
+ if (atomic_inc_return(&rstc->triggered_count) != 1)
+ return 0;
+ } else {
+ if (!rstc->acquired)
+ return -EPERM;
+ }
+
+ ret = rcdev->ops->reset(rcdev, rstc->id);
+ if (rstc->shared && ret)
+ atomic_dec(&rstc->triggered_count);
+
+ return ret;
+}
+
/**
* reset_control_reset - reset the controlled device
* @rstc: reset controller
@@ -362,6 +393,10 @@ static inline bool reset_control_is_array(struct reset_control *rstc)
* On a shared reset line the actual reset pulse is only triggered once for the
* lifetime of the reset_control instance: for all but the first caller this is
* a no-op.
+ *
+ * After calling this function, the reset line is guaranteed to have seen a
+ * reset pulse at any point in the past, not necessarily during the function
+ * call.
* Consumers must not use reset_control_(de)assert on shared reset lines when
* reset_control_reset has been used.
*
@@ -371,7 +406,6 @@ static inline bool reset_control_is_array(struct reset_control *rstc)
int reset_control_reset(struct reset_control *rstc)
{
struct reset_controller_dev *rcdev;
- int ret;
if (!rstc)
return 0;
@@ -388,25 +422,18 @@ int reset_control_reset(struct reset_control *rstc)
if (!rcdev)
return -ENODEV;
- if (!rcdev->ops->reset)
- return -ENOTSUPP;
-
- if (rstc->shared) {
- if (WARN_ON(atomic_read(&rstc->deassert_count) != 0))
- return -EINVAL;
-
- if (atomic_inc_return(&rstc->triggered_count) != 1)
- return 0;
- } else {
- if (!rstc->acquired)
- return -EPERM;
+ /*
+ * For a shared reset only the first caller runs the hardware op while
+ * concurrent callers bump the refcount and return. If the op may sleep
+ * (rcdev->can_sleep), serialize the refcount update and the op so a
+ * concurrent caller cannot return before the op has finished.
+ */
+ if (rstc->shared && rcdev->can_sleep) {
+ guard(mutex)(&rstc->shared_lock);
+ return __reset_control_reset(rstc, rcdev);
}
- ret = rcdev->ops->reset(rcdev, rstc->id);
- if (rstc->shared && ret)
- atomic_dec(&rstc->triggered_count);
-
- return ret;
+ return __reset_control_reset(rstc, rcdev);
}
EXPORT_SYMBOL_GPL(reset_control_reset);
@@ -474,6 +501,44 @@ int reset_control_rearm(struct reset_control *rstc)
}
EXPORT_SYMBOL_GPL(reset_control_rearm);
+static int __reset_control_assert(struct reset_control *rstc,
+ struct reset_controller_dev *rcdev)
+{
+ if (rstc->shared) {
+ if (WARN_ON(atomic_read(&rstc->triggered_count) != 0))
+ return -EINVAL;
+
+ if (WARN_ON(atomic_read(&rstc->deassert_count) == 0))
+ return -EINVAL;
+
+ if (atomic_dec_return(&rstc->deassert_count) != 0)
+ return 0;
+
+ /*
+ * Shared reset controls allow the reset line to be in any state
+ * after this call, so doing nothing is a valid option.
+ */
+ if (!rcdev->ops->assert)
+ return 0;
+ } else {
+ /*
+ * If the reset controller does not implement .assert(), there
+ * is no way to guarantee that the reset line is asserted after
+ * this call.
+ */
+ if (!rcdev->ops->assert)
+ return -ENOTSUPP;
+
+ if (!rstc->acquired) {
+ WARN(1, "reset %s (ID: %u) is not acquired\n",
+ rcdev_name(rcdev), rstc->id);
+ return -EPERM;
+ }
+ }
+
+ return rcdev->ops->assert(rcdev, rstc->id);
+}
+
/**
* reset_control_assert - asserts the reset line
* @rstc: reset controller
@@ -509,39 +574,18 @@ int reset_control_assert(struct reset_control *rstc)
if (!rcdev)
return -ENODEV;
- if (rstc->shared) {
- if (WARN_ON(atomic_read(&rstc->triggered_count) != 0))
- return -EINVAL;
-
- if (WARN_ON(atomic_read(&rstc->deassert_count) == 0))
- return -EINVAL;
-
- if (atomic_dec_return(&rstc->deassert_count) != 0)
- return 0;
-
- /*
- * Shared reset controls allow the reset line to be in any state
- * after this call, so doing nothing is a valid option.
- */
- if (!rcdev->ops->assert)
- return 0;
- } else {
- /*
- * If the reset controller does not implement .assert(), there
- * is no way to guarantee that the reset line is asserted after
- * this call.
- */
- if (!rcdev->ops->assert)
- return -ENOTSUPP;
-
- if (!rstc->acquired) {
- WARN(1, "reset %s (ID: %u) is not acquired\n",
- rcdev_name(rcdev), rstc->id);
- return -EPERM;
- }
+ /*
+ * For a shared reset the last caller runs the hardware op while the
+ * other callers just drop the refcount and return. If the op may sleep
+ * (rcdev->can_sleep), serialize the refcount update and the op against
+ * a concurrent reset_control_deassert() so the two cannot interleave.
+ */
+ if (rstc->shared && rcdev->can_sleep) {
+ guard(mutex)(&rstc->shared_lock);
+ return __reset_control_assert(rstc, rcdev);
}
- return rcdev->ops->assert(rcdev, rstc->id);
+ return __reset_control_assert(rstc, rcdev);
}
EXPORT_SYMBOL_GPL(reset_control_assert);
@@ -575,6 +619,36 @@ int reset_control_bulk_assert(int num_rstcs,
}
EXPORT_SYMBOL_GPL(reset_control_bulk_assert);
+static int __reset_control_deassert(struct reset_control *rstc,
+ struct reset_controller_dev *rcdev)
+{
+ if (rstc->shared) {
+ if (WARN_ON(atomic_read(&rstc->triggered_count) != 0))
+ return -EINVAL;
+
+ if (atomic_inc_return(&rstc->deassert_count) != 1)
+ return 0;
+ } else {
+ if (!rstc->acquired) {
+ WARN(1, "reset %s (ID: %u) is not acquired\n",
+ rcdev_name(rcdev), rstc->id);
+ return -EPERM;
+ }
+ }
+
+ /*
+ * If the reset controller does not implement .deassert(), we assume
+ * that it handles self-deasserting reset lines via .reset(). In that
+ * case, the reset lines are deasserted by default. If that is not the
+ * case, the reset controller driver should implement .deassert() and
+ * return -ENOTSUPP.
+ */
+ if (!rcdev->ops->deassert)
+ return 0;
+
+ return rcdev->ops->deassert(rcdev, rstc->id);
+}
+
/**
* reset_control_deassert - deasserts the reset line
* @rstc: reset controller
@@ -605,31 +679,18 @@ int reset_control_deassert(struct reset_control *rstc)
if (!rcdev)
return -ENODEV;
- if (rstc->shared) {
- if (WARN_ON(atomic_read(&rstc->triggered_count) != 0))
- return -EINVAL;
-
- if (atomic_inc_return(&rstc->deassert_count) != 1)
- return 0;
- } else {
- if (!rstc->acquired) {
- WARN(1, "reset %s (ID: %u) is not acquired\n",
- rcdev_name(rcdev), rstc->id);
- return -EPERM;
- }
- }
-
/*
- * If the reset controller does not implement .deassert(), we assume
- * that it handles self-deasserting reset lines via .reset(). In that
- * case, the reset lines are deasserted by default. If that is not the
- * case, the reset controller driver should implement .deassert() and
- * return -ENOTSUPP.
+ * For a shared reset only the first caller runs the hardware op while
+ * concurrent callers bump the refcount and return. If the op may sleep
+ * (rcdev->can_sleep), serialize the refcount update and the op so a
+ * concurrent caller cannot return before the op has finished.
*/
- if (!rcdev->ops->deassert)
- return 0;
+ if (rstc->shared && rcdev->can_sleep) {
+ guard(mutex)(&rstc->shared_lock);
+ return __reset_control_deassert(rstc, rcdev);
+ }
- return rcdev->ops->deassert(rcdev, rstc->id);
+ return __reset_control_deassert(rstc, rcdev);
}
EXPORT_SYMBOL_GPL(reset_control_deassert);
@@ -879,6 +940,7 @@ __reset_control_get_internal(struct reset_controller_dev *rcdev,
rstc->id = index;
kref_init(&rstc->refcnt);
mutex_init(&rstc->lock);
+ mutex_init(&rstc->shared_lock);
rstc->acquired = acquired;
rstc->shared = shared;
get_device(rcdev->dev);
@@ -901,6 +963,7 @@ static void __reset_control_release(struct kref *kref)
}
mutex_destroy(&rstc->lock);
+ mutex_destroy(&rstc->shared_lock);
}
static void reset_control_put_internal(struct reset_control *rstc)
diff --git a/include/linux/reset-controller.h b/include/linux/reset-controller.h
index 52a5a4e81f18..587fb57c2c52 100644
--- a/include/linux/reset-controller.h
+++ b/include/linux/reset-controller.h
@@ -47,6 +47,9 @@ struct of_phandle_args;
* id as given to the reset control ops, defaults to
* :c:func:`fwnode_reset_simple_xlate`
* @nr_resets: number of reset controls in this reset controller device
+ * @can_sleep: set by the provider if its reset ops may sleep; makes the core
+ * serialize the shared reset, assert and deassert paths under a
+ * mutex
* @lock: protects the reset control list from concurrent access
*/
struct reset_controller_dev {
@@ -64,6 +67,7 @@ struct reset_controller_dev {
int (*fwnode_xlate)(struct reset_controller_dev *rcdev,
const struct fwnode_reference_args *reset_spec);
unsigned int nr_resets;
+ bool can_sleep;
struct mutex lock;
};
--
2.34.1
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH v4 2/2] reset: gpio: Set can_sleep for the shared reset serialization
2026-10-23 7:16 [PATCH v4 0/2] reset: Serialize shared resets whose ops may sleep shengjiu.wang
2026-10-23 7:16 ` [PATCH v4 1/2] reset: core: Serialize concurrent deassert/reset of shared resets shengjiu.wang
@ 2026-10-23 7:16 ` shengjiu.wang
2026-10-23 8:43 ` Alvin Šipraga
2026-10-26 9:24 ` Philipp Zabel
2026-11-03 10:31 ` [PATCH v4 0/2] reset: Serialize shared resets whose ops may sleep Philipp Zabel
2 siblings, 2 replies; 8+ messages in thread
From: shengjiu.wang @ 2026-10-23 7:16 UTC (permalink / raw)
To: p.zabel, krzk, hansg, linux-kernel, broonie, alvin.sipraga
From: Shengjiu Wang <shengjiu.wang@nxp.com>
reset-gpio drives the line with gpiod_set_value_cansleep(), so its reset
ops may sleep. Set reset_controller_dev::can_sleep so the core serializes
the shared refcount update and the hardware op under its per-control mutex,
preventing a concurrent consumer from returning before the op has finished.
Signed-off-by: Shengjiu Wang <shengjiu.wang@nxp.com>
---
drivers/reset/reset-gpio.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/reset/reset-gpio.c b/drivers/reset/reset-gpio.c
index bf95296a512e..b4a198792107 100644
--- a/drivers/reset/reset-gpio.c
+++ b/drivers/reset/reset-gpio.c
@@ -67,6 +67,7 @@ static int reset_gpio_probe(struct auxiliary_device *adev,
"Could not get reset gpios\n");
priv->rc.ops = &reset_gpio_ops;
+ priv->rc.can_sleep = true;
priv->rc.owner = THIS_MODULE;
priv->rc.dev = dev;
--
2.34.1
^ permalink raw reply related [flat|nested] 8+ messages in thread
* Re: [PATCH v4 1/2] reset: core: Serialize concurrent deassert/reset of shared resets
2026-10-23 7:16 ` [PATCH v4 1/2] reset: core: Serialize concurrent deassert/reset of shared resets shengjiu.wang
@ 2026-10-23 8:42 ` Alvin Šipraga
2026-10-26 9:24 ` Philipp Zabel
1 sibling, 0 replies; 8+ messages in thread
From: Alvin Šipraga @ 2026-10-23 8:42 UTC (permalink / raw)
To: shengjiu.wang; +Cc: p.zabel, krzk, hansg, linux-kernel, broonie
On Fri, Oct 23, 2026 at 03:16:08PM +0800, shengjiu.wang@oss.nxp.com wrote:
> From: Shengjiu Wang <shengjiu.wang@nxp.com>
>
> Add a reset_controller_dev::can_sleep flag that a provider sets when its
> reset ops may sleep. When it is set, serialize the shared refcount update
> and the hardware op in reset_control_reset(), reset_control_deassert() and
> reset_control_assert() under a new per-control mutex, taken inside the SRCU
> read-side critical section. Providers that leave the flag clear keep the
> existing lockless path, so callers in atomic context are unaffected.
>
> reset_control_deassert() and reset_control_reset() are documented to
> guarantee that the reset line has been deasserted, respectively that a
> reset pulse has been issued, by the time they return.
>
> For a shared reset only the first caller runs the hardware op; the other
> callers just bump the refcount and return. When the op can sleep this
> breaks the guarantee: a second caller can observe the bumped refcount and
> return before the first caller's op has finished, and then touch hardware
> that is still in reset. A reset_control_assert() racing a concurrent
> reset_control_deassert() can likewise interleave the two sleeping ops and
> leave the line asserted while the refcount says it is deasserted.
>
> Suggested-by: Philipp Zabel <p.zabel@pengutronix.de>
> Signed-off-by: Shengjiu Wang <shengjiu.wang@nxp.com>
> Link: https://lore.kernel.org/all/aszDZlJ0KahNwgZO@analog.com/
Reviewed-by: Alvin Šipraga <alvin.sipraga@analog.com>
> ---
> drivers/reset/core.c | 205 ++++++++++++++++++++-----------
> include/linux/reset-controller.h | 4 +
> 2 files changed, 138 insertions(+), 71 deletions(-)
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH v4 2/2] reset: gpio: Set can_sleep for the shared reset serialization
2026-10-23 7:16 ` [PATCH v4 2/2] reset: gpio: Set can_sleep for the shared reset serialization shengjiu.wang
@ 2026-10-23 8:43 ` Alvin Šipraga
2026-10-26 9:24 ` Philipp Zabel
1 sibling, 0 replies; 8+ messages in thread
From: Alvin Šipraga @ 2026-10-23 8:43 UTC (permalink / raw)
To: shengjiu.wang; +Cc: p.zabel, krzk, hansg, linux-kernel, broonie
On Fri, Oct 23, 2026 at 03:16:09PM +0800, shengjiu.wang@oss.nxp.com wrote:
> From: Shengjiu Wang <shengjiu.wang@nxp.com>
>
> reset-gpio drives the line with gpiod_set_value_cansleep(), so its reset
> ops may sleep. Set reset_controller_dev::can_sleep so the core serializes
> the shared refcount update and the hardware op under its per-control mutex,
> preventing a concurrent consumer from returning before the op has finished.
>
> Signed-off-by: Shengjiu Wang <shengjiu.wang@nxp.com>
Reviewed-by: Alvin Šipraga <alvin.sipraga@analog.com>
> ---
> drivers/reset/reset-gpio.c | 1 +
> 1 file changed, 1 insertion(+)
>
> diff --git a/drivers/reset/reset-gpio.c b/drivers/reset/reset-gpio.c
> index bf95296a512e..b4a198792107 100644
> --- a/drivers/reset/reset-gpio.c
> +++ b/drivers/reset/reset-gpio.c
> @@ -67,6 +67,7 @@ static int reset_gpio_probe(struct auxiliary_device *adev,
> "Could not get reset gpios\n");
>
> priv->rc.ops = &reset_gpio_ops;
> + priv->rc.can_sleep = true;
> priv->rc.owner = THIS_MODULE;
> priv->rc.dev = dev;
>
> --
> 2.34.1
>
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH v4 1/2] reset: core: Serialize concurrent deassert/reset of shared resets
2026-10-23 7:16 ` [PATCH v4 1/2] reset: core: Serialize concurrent deassert/reset of shared resets shengjiu.wang
2026-10-23 8:42 ` Alvin Šipraga
@ 2026-10-26 9:24 ` Philipp Zabel
1 sibling, 0 replies; 8+ messages in thread
From: Philipp Zabel @ 2026-10-26 9:24 UTC (permalink / raw)
To: shengjiu.wang, krzk, hansg, linux-kernel, broonie, alvin.sipraga
On Fr, 2026-10-23 at 15:16 +0800, shengjiu.wang@oss.nxp.com wrote:
> From: Shengjiu Wang <shengjiu.wang@nxp.com>
>
> Add a reset_controller_dev::can_sleep flag that a provider sets when its
> reset ops may sleep. When it is set, serialize the shared refcount update
> and the hardware op in reset_control_reset(), reset_control_deassert() and
> reset_control_assert() under a new per-control mutex, taken inside the SRCU
> read-side critical section. Providers that leave the flag clear keep the
> existing lockless path, so callers in atomic context are unaffected.
>
> reset_control_deassert() and reset_control_reset() are documented to
> guarantee that the reset line has been deasserted, respectively that a
> reset pulse has been issued, by the time they return.
>
> For a shared reset only the first caller runs the hardware op; the other
> callers just bump the refcount and return. When the op can sleep this
> breaks the guarantee: a second caller can observe the bumped refcount and
> return before the first caller's op has finished, and then touch hardware
> that is still in reset. A reset_control_assert() racing a concurrent
> reset_control_deassert() can likewise interleave the two sleeping ops and
> leave the line asserted while the refcount says it is deasserted.
>
> Suggested-by: Philipp Zabel <p.zabel@pengutronix.de>
> Signed-off-by: Shengjiu Wang <shengjiu.wang@nxp.com>
> Link: https://lore.kernel.org/all/aszDZlJ0KahNwgZO@analog.com/
Reviewed-by: Philipp Zabel <p.zabel@pengutronix.de>
regards
Philipp
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH v4 2/2] reset: gpio: Set can_sleep for the shared reset serialization
2026-10-23 7:16 ` [PATCH v4 2/2] reset: gpio: Set can_sleep for the shared reset serialization shengjiu.wang
2026-10-23 8:43 ` Alvin Šipraga
@ 2026-10-26 9:24 ` Philipp Zabel
1 sibling, 0 replies; 8+ messages in thread
From: Philipp Zabel @ 2026-10-26 9:24 UTC (permalink / raw)
To: shengjiu.wang, krzk, hansg, linux-kernel, broonie, alvin.sipraga
On Fr, 2026-10-23 at 15:16 +0800, shengjiu.wang@oss.nxp.com wrote:
> From: Shengjiu Wang <shengjiu.wang@nxp.com>
>
> reset-gpio drives the line with gpiod_set_value_cansleep(), so its reset
> ops may sleep. Set reset_controller_dev::can_sleep so the core serializes
> the shared refcount update and the hardware op under its per-control mutex,
> preventing a concurrent consumer from returning before the op has finished.
>
> Signed-off-by: Shengjiu Wang <shengjiu.wang@nxp.com>
Reviewed-by: Philipp Zabel <p.zabel@pengutronix.de>
regards
Philipp
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH v4 0/2] reset: Serialize shared resets whose ops may sleep
2026-10-23 7:16 [PATCH v4 0/2] reset: Serialize shared resets whose ops may sleep shengjiu.wang
2026-10-23 7:16 ` [PATCH v4 1/2] reset: core: Serialize concurrent deassert/reset of shared resets shengjiu.wang
2026-10-23 7:16 ` [PATCH v4 2/2] reset: gpio: Set can_sleep for the shared reset serialization shengjiu.wang
@ 2026-11-03 10:31 ` Philipp Zabel
2 siblings, 0 replies; 8+ messages in thread
From: Philipp Zabel @ 2026-11-03 10:31 UTC (permalink / raw)
To: shengjiu.wang, krzk, hansg, linux-kernel, broonie, alvin.sipraga
On Fr, 2026-10-23 at 15:16 +0800, shengjiu.wang@oss.nxp.com wrote:
> From: Shengjiu Wang <shengjiu.wang@nxp.com>
>
> For a shared reset only the first caller runs the hardware op; the others
> bump the refcount and return. When the op can sleep, a concurrent caller can
> return before the first caller's op has finished and then touch hardware
> still in reset.
>
> [...]
Applied to reset/next, thanks!
[1/2] reset: core: Serialize concurrent deassert/reset of shared resets
https://git.kernel.org/pub/scm/linux/kernel/git/pza/linux.git/commit/?id=bd357ffa1145
[2/2] reset: gpio: Set can_sleep for the shared reset serialization
https://git.kernel.org/pub/scm/linux/kernel/git/pza/linux.git/commit/?id=526bed2c313b
regards
Philipp
^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2026-11-03 10:31 UTC | newest]
Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-10-23 7:16 [PATCH v4 0/2] reset: Serialize shared resets whose ops may sleep shengjiu.wang
2026-10-23 7:16 ` [PATCH v4 1/2] reset: core: Serialize concurrent deassert/reset of shared resets shengjiu.wang
2026-10-23 8:42 ` Alvin Šipraga
2026-10-26 9:24 ` Philipp Zabel
2026-10-23 7:16 ` [PATCH v4 2/2] reset: gpio: Set can_sleep for the shared reset serialization shengjiu.wang
2026-10-23 8:43 ` Alvin Šipraga
2026-10-26 9:24 ` Philipp Zabel
2026-11-03 10:31 ` [PATCH v4 0/2] reset: Serialize shared resets whose ops may sleep Philipp Zabel
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.