On Tue, 12 Oct 2021 at 16:31, Philipp Zabel <p.zabel@xxxxxxxxxxxxxx> wrote: > > On Tue, 2021-10-12 at 15:40 +0200, Emil Renner Berthing wrote: > > Add a driver for the StarFive JH7100 reset controller. > > > > Signed-off-by: Emil Renner Berthing <kernel@xxxxxxxx> > > --- > > MAINTAINERS | 7 ++ > > drivers/reset/Kconfig | 8 ++ > > drivers/reset/Makefile | 1 + > > drivers/reset/reset-starfive-jh7100.c | 164 ++++++++++++++++++++++++++ > > 4 files changed, 180 insertions(+) > > create mode 100644 drivers/reset/reset-starfive-jh7100.c > > > [...] > > diff --git a/drivers/reset/reset-starfive-jh7100.c b/drivers/reset/reset-starfive-jh7100.c > > new file mode 100644 > > index 000000000000..26bc5b59c1f3 > > --- /dev/null > > +++ b/drivers/reset/reset-starfive-jh7100.c > > @@ -0,0 +1,164 @@ > [...] > > +static int jh7100_reset_update(struct reset_controller_dev *rcdev, > > + unsigned long id, bool assert) > > +{ > > + struct jh7100_reset *data = jh7100_reset_from(rcdev); > > + unsigned long offset = id / 32; > > + void __iomem *reg_assert = data->base + JH7100_RESET_ASSERT0 + 4 * offset; > > + void __iomem *reg_status = data->base + JH7100_RESET_STATUS0 + 4 * offset; > > + u32 mask = BIT(id % 32); > > + u32 done = jh7100_reset_asserted[offset] & mask; > > + unsigned long flags; > > + u32 value; > > + > > + if (!assert) > > + done ^= mask; > > + > > + spin_lock_irqsave(&data->lock, flags); > > + > > + value = readl(reg_assert); > > + if (assert) > > + value |= mask; > > + else > > + value &= ~mask; > > + writel(value, reg_assert); > > + > > + do { > > + value = readl(reg_status) & mask; > > + } while (value != done); > > Looking at the barebox driver, this could loop indefinitely if the > caller forgets to enable the corresponding peripheral clock. Maybe > use readl_poll_timeout() as a safety net. You're right. Asserting without the clock enabled is fine, but deasserting will hang forever. At least for the temperature sensor clock/resets I tried it with. I'll add the timeout, thanks! /Emil