From 73100deb59c3892e280234fcc0171a5376c71788 Mon Sep 17 00:00:00 2001 From: Richard Maina Date: Wed, 29 May 2024 11:09:56 -0700 Subject: [PATCH] hwspinlock: qcom: implement bust operation Implement a new operation qcom_hwspinlock_bust() which can be invoked to bust any locks that are in use when a remoteproc is stopped or crashed. Signed-off-by: Richard Maina Reviewed-by: Bjorn Andersson Signed-off-by: Chris Lew Link: https://lore.kernel.org/r/20240529-hwspinlock-bust-v3-2-c8b924ffa5a2@quicinc.com Signed-off-by: Bjorn Andersson --- drivers/hwspinlock/qcom_hwspinlock.c | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/drivers/hwspinlock/qcom_hwspinlock.c b/drivers/hwspinlock/qcom_hwspinlock.c index 814dfe8697bf..0390979fd765 100644 --- a/drivers/hwspinlock/qcom_hwspinlock.c +++ b/drivers/hwspinlock/qcom_hwspinlock.c @@ -64,9 +64,34 @@ static void qcom_hwspinlock_unlock(struct hwspinlock *lock) pr_err("%s: failed to unlock spinlock\n", __func__); } +static int qcom_hwspinlock_bust(struct hwspinlock *lock, unsigned int id) +{ + struct regmap_field *field = lock->priv; + u32 owner; + int ret; + + ret = regmap_field_read(field, &owner); + if (ret) { + dev_err(lock->bank->dev, "unable to query spinlock owner\n"); + return ret; + } + + if (owner != id) + return 0; + + ret = regmap_field_write(field, 0); + if (ret) { + dev_err(lock->bank->dev, "failed to bust spinlock\n"); + return ret; + } + + return 0; +} + static const struct hwspinlock_ops qcom_hwspinlock_ops = { .trylock = qcom_hwspinlock_trylock, .unlock = qcom_hwspinlock_unlock, + .bust = qcom_hwspinlock_bust, }; static const struct regmap_config sfpb_mutex_config = {