summaryrefslogtreecommitdiff
path: root/drivers/hwspinlock/qcom_hwspinlock.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/hwspinlock/qcom_hwspinlock.c')
-rw-r--r--drivers/hwspinlock/qcom_hwspinlock.c37
1 files changed, 36 insertions, 1 deletions
diff --git a/drivers/hwspinlock/qcom_hwspinlock.c b/drivers/hwspinlock/qcom_hwspinlock.c
index 9cf186362ae2..0390979fd765 100644
--- a/drivers/hwspinlock/qcom_hwspinlock.c
+++ b/drivers/hwspinlock/qcom_hwspinlock.c
@@ -64,14 +64,48 @@ 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 = {
+ .reg_bits = 32,
+ .reg_stride = 4,
+ .val_bits = 32,
+ .max_register = 0x100,
+ .fast_io = true,
};
static const struct qcom_hwspinlock_of_data of_sfpb_mutex = {
.offset = 0x4,
.stride = 0x4,
+ .regmap_config = &sfpb_mutex_config,
};
static const struct regmap_config tcsr_msm8226_mutex_config = {
@@ -106,7 +140,6 @@ static const struct of_device_id qcom_hwspinlock_of_match[] = {
{ .compatible = "qcom,sfpb-mutex", .data = &of_sfpb_mutex },
{ .compatible = "qcom,tcsr-mutex", .data = &of_tcsr_mutex },
{ .compatible = "qcom,apq8084-tcsr-mutex", .data = &of_msm8226_tcsr_mutex },
- { .compatible = "qcom,ipq6018-tcsr-mutex", .data = &of_msm8226_tcsr_mutex },
{ .compatible = "qcom,msm8226-tcsr-mutex", .data = &of_msm8226_tcsr_mutex },
{ .compatible = "qcom,msm8974-tcsr-mutex", .data = &of_msm8226_tcsr_mutex },
{ .compatible = "qcom,msm8994-tcsr-mutex", .data = &of_msm8226_tcsr_mutex },
@@ -197,6 +230,8 @@ static int qcom_hwspinlock_probe(struct platform_device *pdev)
bank->lock[i].priv = devm_regmap_field_alloc(&pdev->dev,
regmap, field);
+ if (IS_ERR(bank->lock[i].priv))
+ return PTR_ERR(bank->lock[i].priv);
}
return devm_hwspin_lock_register(&pdev->dev, bank, &qcom_hwspinlock_ops,