hwspinlock: qcom: Provide function to bust hwspinlock

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.

Change-Id: I0486d5345a47007f254f17c4b88f802a6c962e3a
Signed-off-by: Richard Maina <quic_rmaina@quicinc.com>
Reviewed-by: Bjorn Andersson <andersson@kernel.org>
Signed-off-by: Chris Lew <quic_clew@quicinc.com>
Link: https://lore.kernel.org/r/20240529-hwspinlock-bust-v3-1-c8b924ffa5a2@quicinc.com
Signed-off-by: Bjorn Andersson <andersson@kernel.org>
Git-commit: 73100deb59c3892e280234fcc0171a5376c71788
Git-repo: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
[quic_deesin@quicinc.com: Adding bust api in core hwspinlock module
 is breaking KMI, so exporting bust function from qcom hwspilock module
 to avoid dependency on core hwspinlock function]
Signed-off-by: Deepak Kumar Singh <quic_deesin@quicinc.com>
This commit is contained in:
Richard Maina 2024-08-07 00:38:09 -07:00 committed by Deepak Kumar Singh
parent 8fff36db32
commit 422eacf6fc
2 changed files with 62 additions and 0 deletions

View File

@ -12,6 +12,7 @@
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/platform_device.h>
#include <linux/soc/qcom/qcom_hwspinlock.h>
#include <linux/regmap.h>
#include "hwspinlock_internal.h"
@ -25,6 +26,43 @@ struct qcom_hwspinlock_of_data {
const struct regmap_config *regmap_config;
};
/**
* qcom_hwspinlock_bust() - bust qcom specific hwspinlock
* @hwlock: a previously-acquired hwspinlock which we want to bust
* @id: identifier of the remote lock holder, if applicable
*
* This function will bust a hwspinlock that was previously acquired as
* long as the current owner of the lock matches the id given by the caller.
*
* Context: Process context.
*
* Returns: 0 on success, or error if bust operation fails
*/
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) {
pr_err("%s: unable to query spinlock owner\n", __func__);
return ret;
}
if (owner != id)
return 0;
ret = regmap_field_write(field, 0);
if (ret) {
pr_err("%s: failed to bust spinlock\n", __func__);
return ret;
}
return 0;
}
EXPORT_SYMBOL_GPL(qcom_hwspinlock_bust);
static int qcom_hwspinlock_trylock(struct hwspinlock *lock)
{
struct regmap_field *field = lock->priv;

View File

@ -0,0 +1,24 @@
/* SPDX-License-Identifier: GPL-2.0 */
/*
* Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved.
*/
#ifndef __QCOM_HWSPINLOCK_H
#define __QCOM_HWSPINLOCK_H
struct hwspinlock;
#if IS_ENABLED(CONFIG_HWSPINLOCK_QCOM)
int qcom_hwspinlock_bust(struct hwspinlock *hwlock, unsigned int id);
#else /* !CONFIG_HWSPINLOCK_QCOM */
static inline int qcom_hwspinlock_bust(struct hwspinlock *hwlock, unsigned int id)
{
return 0;
}
#endif /* CONFIG_HWSPINLOCK_QCOM */
#endif /* __QCOM_HWSPINLOCK_H */