1 // SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause
3 * Copyright (C) 2018, STMicroelectronics - All Rights Reserved
9 #include <hwspinlock.h>
13 #define STM32_MUTEX_COREID BIT(8)
14 #define STM32_MUTEX_LOCK_BIT BIT(31)
15 #define STM32_MUTEX_NUM_LOCKS 32
17 struct stm32mp1_hws_priv {
21 static int stm32mp1_lock(struct udevice *dev, int index)
23 struct stm32mp1_hws_priv *priv = dev_get_priv(dev);
26 if (index >= STM32_MUTEX_NUM_LOCKS)
29 status = readl(priv->base + index * sizeof(u32));
30 if (status == (STM32_MUTEX_LOCK_BIT | STM32_MUTEX_COREID))
33 writel(STM32_MUTEX_LOCK_BIT | STM32_MUTEX_COREID,
34 priv->base + index * sizeof(u32));
36 status = readl(priv->base + index * sizeof(u32));
37 if (status != (STM32_MUTEX_LOCK_BIT | STM32_MUTEX_COREID))
43 static int stm32mp1_unlock(struct udevice *dev, int index)
45 struct stm32mp1_hws_priv *priv = dev_get_priv(dev);
47 if (index >= STM32_MUTEX_NUM_LOCKS)
50 writel(STM32_MUTEX_COREID, priv->base + index * sizeof(u32));
55 static int stm32mp1_hwspinlock_probe(struct udevice *dev)
57 struct stm32mp1_hws_priv *priv = dev_get_priv(dev);
61 priv->base = dev_read_addr(dev);
62 if (priv->base == FDT_ADDR_T_NONE)
65 ret = clk_get_by_index(dev, 0, &clk);
69 ret = clk_enable(&clk);
76 static const struct hwspinlock_ops stm32mp1_hwspinlock_ops = {
77 .lock = stm32mp1_lock,
78 .unlock = stm32mp1_unlock,
81 static const struct udevice_id stm32mp1_hwspinlock_ids[] = {
82 { .compatible = "st,stm32-hwspinlock" },
86 U_BOOT_DRIVER(hwspinlock_stm32mp1) = {
87 .name = "hwspinlock_stm32mp1",
88 .id = UCLASS_HWSPINLOCK,
89 .of_match = stm32mp1_hwspinlock_ids,
90 .ops = &stm32mp1_hwspinlock_ops,
91 .probe = stm32mp1_hwspinlock_probe,
92 .priv_auto_alloc_size = sizeof(struct stm32mp1_hws_priv),