This serie adds the support of the hardware semaphore block for stm32mp1 SoC.
version 2:
- fix comments done by Bjorn about clock naming, license terms in header,
alphabetic ordering in Makefile and Kconfig and remove function
- Do not push test module in this version while waiting for feedbacks about it
Benjamin Gaignard (4):
dt-bindings: hwlock: Document STM32 hwspinlock bindings
hwspinlock: add STM32 hwspinlock device
ARM: dts: stm32: Add hwspinlock node for stm32mp157 SoC
ARM: dts: stm32: enable hwspinlock on stm32mp157c-ed1
.../bindings/hwlock/st,stm32-hwspinlock.txt | 23 ++++
arch/arm/boot/dts/stm32mp157c-ed1.dts | 4 +
arch/arm/boot/dts/stm32mp157c.dtsi | 9 ++
drivers/hwspinlock/Kconfig | 9 ++
drivers/hwspinlock/Makefile | 1 +
drivers/hwspinlock/stm32_hwspinlock.c | 144 +++++++++++++++++++++
6 files changed, 190 insertions(+)
create mode 100644 Documentation/devicetree/bindings/hwlock/st,stm32-hwspinlock.txt
create mode 100644 drivers/hwspinlock/stm32_hwspinlock.c
--
2.15.0
Activate hwspinlock for stm32mp157c-ed1
Signed-off-by: Benjamin Gaignard <[email protected]>
---
arch/arm/boot/dts/stm32mp157c-ed1.dts | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/arch/arm/boot/dts/stm32mp157c-ed1.dts b/arch/arm/boot/dts/stm32mp157c-ed1.dts
index f77bea49c079..158a337b3129 100644
--- a/arch/arm/boot/dts/stm32mp157c-ed1.dts
+++ b/arch/arm/boot/dts/stm32mp157c-ed1.dts
@@ -94,3 +94,7 @@
vdda1v1-supply = <®11>;
vdda1v8-supply = <®18>;
};
+
+&hsem {
+ status = "okay";
+};
--
2.15.0
This patch adds support of hardware semaphores for stm32mp1 SoC.
The hardware block provides 32 semaphores.
Signed-off-by: Benjamin Gaignard <[email protected]>
---
version 2 :
- change clock name from hwspinlock to hsem to be align with hardware
documentation
- remove useless licence terms from header
- fix alphabetic order issues
- do not abort remove function if hwspin_lock_unregister() failed
drivers/hwspinlock/Kconfig | 9 +++
drivers/hwspinlock/Makefile | 1 +
drivers/hwspinlock/stm32_hwspinlock.c | 144 ++++++++++++++++++++++++++++++++++
3 files changed, 154 insertions(+)
create mode 100644 drivers/hwspinlock/stm32_hwspinlock.c
diff --git a/drivers/hwspinlock/Kconfig b/drivers/hwspinlock/Kconfig
index e895d29500ee..7869c67e5b6b 100644
--- a/drivers/hwspinlock/Kconfig
+++ b/drivers/hwspinlock/Kconfig
@@ -49,6 +49,15 @@ config HWSPINLOCK_SPRD
If unsure, say N.
+config HWSPINLOCK_STM32
+ tristate "STM32 Hardware Spinlock device"
+ depends on MACH_STM32MP157
+ depends on HWSPINLOCK
+ help
+ Say y here to support the STM32 Hardware Spinlock device.
+
+ If unsure, say N.
+
config HSEM_U8500
tristate "STE Hardware Semaphore functionality"
depends on HWSPINLOCK
diff --git a/drivers/hwspinlock/Makefile b/drivers/hwspinlock/Makefile
index b87c01a506a4..ed053e3f02be 100644
--- a/drivers/hwspinlock/Makefile
+++ b/drivers/hwspinlock/Makefile
@@ -8,4 +8,5 @@ obj-$(CONFIG_HWSPINLOCK_OMAP) += omap_hwspinlock.o
obj-$(CONFIG_HWSPINLOCK_QCOM) += qcom_hwspinlock.o
obj-$(CONFIG_HWSPINLOCK_SIRF) += sirf_hwspinlock.o
obj-$(CONFIG_HWSPINLOCK_SPRD) += sprd_hwspinlock.o
+obj-$(CONFIG_HWSPINLOCK_STM32) += stm32_hwspinlock.o
obj-$(CONFIG_HSEM_U8500) += u8500_hsem.o
diff --git a/drivers/hwspinlock/stm32_hwspinlock.c b/drivers/hwspinlock/stm32_hwspinlock.c
new file mode 100644
index 000000000000..7eb36a5bbf68
--- /dev/null
+++ b/drivers/hwspinlock/stm32_hwspinlock.c
@@ -0,0 +1,144 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) STMicroelectronics SA 2018
+ * Author: Benjamin Gaignard <[email protected]> for STMicroelectronics.
+ */
+
+#include <linux/clk.h>
+#include <linux/hwspinlock.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/pm_runtime.h>
+
+#include "hwspinlock_internal.h"
+
+#define STM32_MUTEX_COREID BIT(8)
+#define STM32_MUTEX_LOCK_BIT BIT(31)
+#define STM32_MUTEX_NUM_LOCKS 32
+
+struct stm32_hwspinlock {
+ struct clk *clk;
+ struct hwspinlock_device bank;
+};
+
+static int stm32_hwspinlock_trylock(struct hwspinlock *lock)
+{
+ void __iomem *lock_addr = lock->priv;
+ u32 status;
+
+ writel(STM32_MUTEX_LOCK_BIT | STM32_MUTEX_COREID, lock_addr);
+ status = readl(lock_addr);
+
+ return status == (STM32_MUTEX_LOCK_BIT | STM32_MUTEX_COREID);
+}
+
+static void stm32_hwspinlock_unlock(struct hwspinlock *lock)
+{
+ void __iomem *lock_addr = lock->priv;
+
+ writel(STM32_MUTEX_COREID, lock_addr);
+}
+
+static const struct hwspinlock_ops stm32_hwspinlock_ops = {
+ .trylock = stm32_hwspinlock_trylock,
+ .unlock = stm32_hwspinlock_unlock,
+};
+
+static int stm32_hwspinlock_probe(struct platform_device *pdev)
+{
+ struct stm32_hwspinlock *hw;
+ void __iomem *io_base;
+ struct resource *res;
+ size_t array_size;
+ int i, ret;
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ io_base = devm_ioremap_resource(&pdev->dev, res);
+ if (!io_base)
+ return -ENOMEM;
+
+ array_size = STM32_MUTEX_NUM_LOCKS * sizeof(struct hwspinlock);
+ hw = devm_kzalloc(&pdev->dev, sizeof(*hw) + array_size, GFP_KERNEL);
+ if (!hw)
+ return -ENOMEM;
+
+ hw->clk = devm_clk_get(&pdev->dev, "hsem");
+ if (IS_ERR(hw->clk))
+ return PTR_ERR(hw->clk);
+
+ for (i = 0; i < STM32_MUTEX_NUM_LOCKS; i++)
+ hw->bank.lock[i].priv = io_base + i * sizeof(u32);
+
+ platform_set_drvdata(pdev, hw);
+ pm_runtime_enable(&pdev->dev);
+
+ ret = hwspin_lock_register(&hw->bank, &pdev->dev, &stm32_hwspinlock_ops,
+ 0, STM32_MUTEX_NUM_LOCKS);
+
+ if (ret)
+ pm_runtime_disable(&pdev->dev);
+
+ return ret;
+}
+
+static int stm32_hwspinlock_remove(struct platform_device *pdev)
+{
+ struct stm32_hwspinlock *hw = platform_get_drvdata(pdev);
+ int ret;
+
+ ret = hwspin_lock_unregister(&hw->bank);
+ if (ret)
+ dev_err(&pdev->dev, "%s failed: %d\n", __func__, ret);
+
+ pm_runtime_disable(&pdev->dev);
+
+ return 0;
+}
+
+static int __maybe_unused stm32_hwspinlock_runtime_suspend(struct device *dev)
+{
+ struct stm32_hwspinlock *hw = dev_get_drvdata(dev);
+
+ clk_disable_unprepare(hw->clk);
+
+ return 0;
+}
+
+static int __maybe_unused stm32_hwspinlock_runtime_resume(struct device *dev)
+{
+ struct stm32_hwspinlock *hw = dev_get_drvdata(dev);
+
+ clk_prepare_enable(hw->clk);
+
+ return 0;
+}
+
+static const struct dev_pm_ops stm32_hwspinlock_pm_ops = {
+ SET_RUNTIME_PM_OPS(stm32_hwspinlock_runtime_suspend,
+ stm32_hwspinlock_runtime_resume,
+ NULL)
+};
+
+static const struct of_device_id stm32_hwpinlock_ids[] = {
+ { .compatible = "st,stm32-hwspinlock", },
+ {},
+};
+MODULE_DEVICE_TABLE(of, stm32_hwpinlock_ids);
+
+static struct platform_driver stm32_hwspinlock_driver = {
+ .probe = stm32_hwspinlock_probe,
+ .remove = stm32_hwspinlock_remove,
+ .driver = {
+ .name = "stm32_hwspinlock",
+ .of_match_table = stm32_hwpinlock_ids,
+ .pm = &stm32_hwspinlock_pm_ops,
+ },
+};
+module_platform_driver(stm32_hwspinlock_driver);
+
+MODULE_LICENSE("GPL v2");
+MODULE_DESCRIPTION("Hardware spinlock driver for STM32 SoCs");
+MODULE_AUTHOR("Benjamin Gaignard <[email protected]>");
--
2.15.0
Add bindings for STM32 hardware spinlock device
Signed-off-by: Benjamin Gaignard <[email protected]>
---
version 2 :
- change clock name from hwspinlock to hsem to be align with hardware
documentation
.../bindings/hwlock/st,stm32-hwspinlock.txt | 23 ++++++++++++++++++++++
1 file changed, 23 insertions(+)
create mode 100644 Documentation/devicetree/bindings/hwlock/st,stm32-hwspinlock.txt
diff --git a/Documentation/devicetree/bindings/hwlock/st,stm32-hwspinlock.txt b/Documentation/devicetree/bindings/hwlock/st,stm32-hwspinlock.txt
new file mode 100644
index 000000000000..6e933b218574
--- /dev/null
+++ b/Documentation/devicetree/bindings/hwlock/st,stm32-hwspinlock.txt
@@ -0,0 +1,23 @@
+STM32 Hardware Spinlock Device Binding
+-------------------------------------
+
+Required properties :
+- compatible : should be "st,stm32-hwspinlock".
+- reg : the register address of hwspinlock.
+- #hwlock-cells : hwlock users only use the hwlock id to represent a specific
+ hwlock, so the number of cells should be <1> here.
+- clock-names : Must contain "hwspinlock".
+- clocks : Must contain a phandle entry for the clock in clock-names, see the
+ common clock bindings.
+
+Please look at the generic hwlock binding for usage information for consumers,
+"Documentation/devicetree/bindings/hwlock/hwlock.txt"
+
+Example of hwlock provider:
+ hwspinlock@4c000000 {
+ compatible = "st,stm32-hwspinlock";
+ #hwlock-cells = <1>;
+ reg = <0x4c000000 0x400>;
+ clocks = <&rcc HSEM>;
+ clock-names = "hsem";
+ };
--
2.15.0
Declare hwspinlock device for stm32mp157 SoC
Signed-off-by: Benjamin Gaignard <[email protected]>
---
version 2 :
- change clock name from hwspinlock to hsem to be align with hardware
documentation
arch/arm/boot/dts/stm32mp157c.dtsi | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/arch/arm/boot/dts/stm32mp157c.dtsi b/arch/arm/boot/dts/stm32mp157c.dtsi
index 185541a5b69f..98f824d8b0f0 100644
--- a/arch/arm/boot/dts/stm32mp157c.dtsi
+++ b/arch/arm/boot/dts/stm32mp157c.dtsi
@@ -803,6 +803,15 @@
status = "disabled";
};
+ hsem: hwspinlock@4c000000 {
+ compatible = "st,stm32-hwspinlock";
+ #hwlock-cells = <1>;
+ reg = <0x4c000000 0x400>;
+ clocks = <&rcc HSEM>;
+ clock-names = "hwsem";
+ status = "disabled";
+ };
+
rcc: rcc@50000000 {
compatible = "st,stm32mp1-rcc", "syscon";
reg = <0x50000000 0x1000>;
--
2.15.0
Hi Benjamin
On 11/8/18 10:04 AM, Benjamin Gaignard wrote:
> Add bindings for STM32 hardware spinlock device
>
> Signed-off-by: Benjamin Gaignard <[email protected]>
> ---
> version 2 :
> - change clock name from hwspinlock to hsem to be align with hardware
> documentation
>
> .../bindings/hwlock/st,stm32-hwspinlock.txt | 23 ++++++++++++++++++++++
> 1 file changed, 23 insertions(+)
> create mode 100644 Documentation/devicetree/bindings/hwlock/st,stm32-hwspinlock.txt
>
> diff --git a/Documentation/devicetree/bindings/hwlock/st,stm32-hwspinlock.txt b/Documentation/devicetree/bindings/hwlock/st,stm32-hwspinlock.txt
> new file mode 100644
> index 000000000000..6e933b218574
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/hwlock/st,stm32-hwspinlock.txt
> @@ -0,0 +1,23 @@
> +STM32 Hardware Spinlock Device Binding
> +-------------------------------------
> +
> +Required properties :
> +- compatible : should be "st,stm32-hwspinlock".
> +- reg : the register address of hwspinlock.
> +- #hwlock-cells : hwlock users only use the hwlock id to represent a specific
> + hwlock, so the number of cells should be <1> here.
> +- clock-names : Must contain "hwspinlock".
"hwspinlock" --> "hsem" ?
> +- clocks : Must contain a phandle entry for the clock in clock-names, see the
> + common clock bindings.
> +
> +Please look at the generic hwlock binding for usage information for consumers,
> +"Documentation/devicetree/bindings/hwlock/hwlock.txt"
> +
> +Example of hwlock provider:
> + hwspinlock@4c000000 {
> + compatible = "st,stm32-hwspinlock";
> + #hwlock-cells = <1>;
> + reg = <0x4c000000 0x400>;
> + clocks = <&rcc HSEM>;
> + clock-names = "hsem";
> + };
>