From b3f06e85218243adf893ea11fa8010aff110dbe4 Mon Sep 17 00:00:00 2001 From: Lionel VITTE Date: Tue, 3 Dec 2024 14:44:47 +0100 Subject: [PATCH] v6.6-stm32mp-rt-r1 --- .../configs/fragment-07-rt-sysvinit.config | 12 ++++ arch/arm/configs/fragment-07-rt.config | 32 ++++++++++ .../configs/fragment-07-rt-sysvinit.config | 12 ++++ arch/arm64/configs/fragment-07-rt.config | 33 ++++++++++ drivers/hwtracing/coresight/coresight-cti.h | 10 +++ drivers/mfd/stm32-lptimer.c | 55 ++++++++++++++++ drivers/mfd/syscon.c | 3 + drivers/soc/st/Kconfig | 6 ++ drivers/soc/st/Makefile | 1 + drivers/soc/st/stm32_hog.c | 64 +++++++++++++++++++ drivers/watchdog/stm32_iwdg.c | 2 +- 11 files changed, 229 insertions(+), 1 deletion(-) create mode 100644 arch/arm/configs/fragment-07-rt-sysvinit.config create mode 100644 arch/arm/configs/fragment-07-rt.config create mode 100644 arch/arm64/configs/fragment-07-rt-sysvinit.config create mode 100644 arch/arm64/configs/fragment-07-rt.config create mode 100644 drivers/soc/st/stm32_hog.c diff --git a/arch/arm/configs/fragment-07-rt-sysvinit.config b/arch/arm/configs/fragment-07-rt-sysvinit.config new file mode 100644 index 000000000..49a4baf60 --- /dev/null +++ b/arch/arm/configs/fragment-07-rt-sysvinit.config @@ -0,0 +1,12 @@ +CONFIG_CGROUPS=y +# CONFIG_CGROUP_SCHED is not set +# CONFIG_CGROUP_PIDS is not set +# CONFIG_CGROUP_RDMA is not set +# CONFIG_CGROUP_FREEZER is not set +# CONFIG_CGROUP_DEVICE is not set +# CONFIG_CGROUP_CPUACCT is not set +# CONFIG_CGROUP_PERF is not set +# CONFIG_CGROUP_DEBUG is not set +# CONFIG_CGROUP_NET_PRIO is not set +# CONFIG_CGROUP_NET_CLASSID is not set + diff --git a/arch/arm/configs/fragment-07-rt.config b/arch/arm/configs/fragment-07-rt.config new file mode 100644 index 000000000..98bb8735f --- /dev/null +++ b/arch/arm/configs/fragment-07-rt.config @@ -0,0 +1,32 @@ +CONFIG_PREEMPT_RT=y + +# disable SCHED_MC +# CONFIG_MCPM is not set + +# Disable CPUFREQ and CPUIDLE +# CONFIG_CPU_FREQ is not set +# CONFIG_CPU_IDLE is not set + +# Force to have HIGH_RES_TIMERS +CONFIG_HIGH_RES_TIMERS=y + +# force do not go to sleep +# For multiple core, you should set the specific boot options +# for isolate the core and render it tickless: "isolcpus=2,3 nohz_full=2,3" +# Warning: to active only if SMP are present +# CONFIG_HZ_PERIODIC=y + +# to Enable ftrace, you need to enable the following configuraiton: +# CONFIG_FTRACE=y +# CONFIG_IRQSOFF_TRACER=y +# CONFIG_PREEMPT_TRACER=y +# CONFIG_SCHED_TRACER=y +# CONFIG_FUNCTION_TRACER=y +# By default, the ftrace for RT kernel are disabled +# CONFIG_FTRACE is not set +# CONFIG_IRQSOFF_TRACER is not set +# CONFIG_PREEMPT_TRACER is not set +# CONFIG_SCHED_TRACER is not set +# CONFIG_FUNCTION_TRACER is not set + + diff --git a/arch/arm64/configs/fragment-07-rt-sysvinit.config b/arch/arm64/configs/fragment-07-rt-sysvinit.config new file mode 100644 index 000000000..49a4baf60 --- /dev/null +++ b/arch/arm64/configs/fragment-07-rt-sysvinit.config @@ -0,0 +1,12 @@ +CONFIG_CGROUPS=y +# CONFIG_CGROUP_SCHED is not set +# CONFIG_CGROUP_PIDS is not set +# CONFIG_CGROUP_RDMA is not set +# CONFIG_CGROUP_FREEZER is not set +# CONFIG_CGROUP_DEVICE is not set +# CONFIG_CGROUP_CPUACCT is not set +# CONFIG_CGROUP_PERF is not set +# CONFIG_CGROUP_DEBUG is not set +# CONFIG_CGROUP_NET_PRIO is not set +# CONFIG_CGROUP_NET_CLASSID is not set + diff --git a/arch/arm64/configs/fragment-07-rt.config b/arch/arm64/configs/fragment-07-rt.config new file mode 100644 index 000000000..8451ff348 --- /dev/null +++ b/arch/arm64/configs/fragment-07-rt.config @@ -0,0 +1,33 @@ +CONFIG_EXPERT=y +CONFIG_PREEMPT_RT=y + +# disable SCHED_MC +# CONFIG_MCPM is not set + +# Disable CPUFREQ and CPUIDLE +# CONFIG_CPU_FREQ is not set +# CONFIG_CPU_IDLE is not set + +# Force to have HIGH_RES_TIMERS +CONFIG_HIGH_RES_TIMERS=y + +# force do not go to sleep +# For multiple core, you should set the specific boot options +# for isolate the core and render it tickless: "isolcpus=2,3 nohz_full=2,3" +# Warning: to active only if SMP are present +# CONFIG_HZ_PERIODIC=y + +# to Enable ftrace, you need to enable the following configuraiton: +# CONFIG_FTRACE=y +# CONFIG_IRQSOFF_TRACER=y +# CONFIG_PREEMPT_TRACER=y +# CONFIG_SCHED_TRACER=y +# CONFIG_FUNCTION_TRACER=y +# By default, the ftrace for RT kernel are disabled +# CONFIG_FTRACE is not set +# CONFIG_IRQSOFF_TRACER is not set +# CONFIG_PREEMPT_TRACER is not set +# CONFIG_SCHED_TRACER is not set +# CONFIG_FUNCTION_TRACER is not set + + diff --git a/drivers/hwtracing/coresight/coresight-cti.h b/drivers/hwtracing/coresight/coresight-cti.h index cb9ee616d..9f9eaaf29 100644 --- a/drivers/hwtracing/coresight/coresight-cti.h +++ b/drivers/hwtracing/coresight/coresight-cti.h @@ -17,6 +17,16 @@ #include "coresight-priv.h" +#ifdef CONFIG_PREEMPT_RT +#undef spin_lock_init +#define spin_lock_init raw_spin_lock_init +#define spin_lock raw_spin_lock +#define spin_unlock raw_spin_unlock +#undef spin_lock_irqsave +#define spin_lock_irqsave raw_spin_lock_irqsave +#define spin_unlock_irqrestore raw_spin_unlock_irqrestore +#define spinlock_t raw_spinlock_t +#endif /* * Device registers * 0x000 - 0x144: CTI programming and status diff --git a/drivers/mfd/stm32-lptimer.c b/drivers/mfd/stm32-lptimer.c index 9fc94122f..8df3b70f1 100644 --- a/drivers/mfd/stm32-lptimer.c +++ b/drivers/mfd/stm32-lptimer.c @@ -21,6 +21,9 @@ static const struct regmap_config stm32_lptimer_regmap_cfg = { .reg_stride = sizeof(u32), .max_register = STM32_LPTIM_MAX_REGISTER, .fast_io = true, +#ifdef CONFIG_PREEMPT_RT + .use_raw_spinlock = true, +#endif }; static int stm32_lptimer_detect_encoder(struct stm32_lptimer *ddata) @@ -85,6 +88,13 @@ static int stm32_lptimer_detect_hwcfgr(struct device *dev, struct stm32_lptimer return 0; } +#ifdef CONFIG_PREEMPT_RT +static void stm32_lptimer_clk_disable_unprepare(void *data) +{ + clk_disable_unprepare(data); +} +#endif + static int stm32_lptimer_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; @@ -100,8 +110,13 @@ static int stm32_lptimer_probe(struct platform_device *pdev) if (IS_ERR(mmio)) return PTR_ERR(mmio); +#ifdef CONFIG_PREEMPT_RT + ddata->regmap = devm_regmap_init_mmio(dev, mmio, + &stm32_lptimer_regmap_cfg); +#else ddata->regmap = devm_regmap_init_mmio_clk(dev, "mux", mmio, &stm32_lptimer_regmap_cfg); +#endif if (IS_ERR(ddata->regmap)) return PTR_ERR(ddata->regmap); @@ -109,6 +124,16 @@ static int stm32_lptimer_probe(struct platform_device *pdev) if (IS_ERR(ddata->clk)) return PTR_ERR(ddata->clk); +#ifdef CONFIG_PREEMPT_RT + ret = clk_prepare_enable(ddata->clk); + if (ret) + return ret; + + ret = devm_add_action_or_reset(dev, stm32_lptimer_clk_disable_unprepare, ddata->clk); + if (ret) + return ret; +#endif + ret = stm32_lptimer_detect_hwcfgr(dev, ddata); if (ret) return ret; @@ -122,6 +147,33 @@ static int stm32_lptimer_probe(struct platform_device *pdev) return devm_of_platform_populate(&pdev->dev); } +#ifdef CONFIG_PREEMPT_RT +static int stm32_lptimer_suspend(struct device *dev) +{ + struct stm32_lptimer *priv = dev_get_drvdata(dev); + + clk_disable(priv->clk); + + return 0; +} + +static int stm32_lptimer_resume(struct device *dev) +{ + struct stm32_lptimer *priv = dev_get_drvdata(dev); + int ret; + + ret = clk_enable(priv->clk); + if (ret) + dev_err(dev, "failed to enable clock. Error [%d]\n", ret); + + return ret; +} + +static const struct dev_pm_ops stm32_lptim_pm_ops = { + SYSTEM_SLEEP_PM_OPS(stm32_lptimer_suspend, stm32_lptimer_resume) +}; +#endif + static const struct of_device_id stm32_lptimer_of_match[] = { { .compatible = "st,stm32-lptimer", }, { .compatible = "st,stm32mp21-lptimer", }, @@ -135,6 +187,9 @@ static struct platform_driver stm32_lptimer_driver = { .driver = { .name = "stm32-lptimer", .of_match_table = stm32_lptimer_of_match, +#ifdef CONFIG_PREEMPT_RT + .pm = pm_ptr(&stm32_lptim_pm_ops), +#endif }, }; module_platform_driver(stm32_lptimer_driver); diff --git a/drivers/mfd/syscon.c b/drivers/mfd/syscon.c index 7d0e91164..a5746d117 100644 --- a/drivers/mfd/syscon.c +++ b/drivers/mfd/syscon.c @@ -40,6 +40,9 @@ static const struct regmap_config syscon_regmap_config = { .reg_bits = 32, .val_bits = 32, .reg_stride = 4, +#ifdef CONFIG_PREEMPT_RT + .use_raw_spinlock = true, +#endif }; static struct syscon *of_syscon_register(struct device_node *np, bool check_res) diff --git a/drivers/soc/st/Kconfig b/drivers/soc/st/Kconfig index 1bde2c16c..704a19692 100644 --- a/drivers/soc/st/Kconfig +++ b/drivers/soc/st/Kconfig @@ -1,5 +1,11 @@ if ARCH_STM32 +config STM32_HOG + tristate "STM32 hog" + default y + help + Say y to enable clock(s) at the start of the Kernel. + config STM32_PM_DOMAINS bool "STM32 PM domains" depends on MACH_STM32MP157 diff --git a/drivers/soc/st/Makefile b/drivers/soc/st/Makefile index 6c71607f6..11f056bfc 100644 --- a/drivers/soc/st/Makefile +++ b/drivers/soc/st/Makefile @@ -1,3 +1,4 @@ +obj-$(CONFIG_STM32_HOG) += stm32_hog.o obj-$(CONFIG_STM32_PM_DOMAINS) += stm32_pm_domain.o obj-$(CONFIG_STM32_RISAB) += stm32_risab.o obj-$(CONFIG_STM32_RISAF) += stm32_risaf.o diff --git a/drivers/soc/st/stm32_hog.c b/drivers/soc/st/stm32_hog.c new file mode 100644 index 000000000..c8fbf8d5e --- /dev/null +++ b/drivers/soc/st/stm32_hog.c @@ -0,0 +1,64 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (C) 2024, STMicroelectronics - All Rights Reserved + */ + +#include +#include "linux/device.h" +#include +#include + +struct stm32_hog_pdata { + struct clk_bulk_data *clks; + int num_clks; +}; + +static void stm32_hog_remove(struct platform_device *pdev) +{ + struct stm32_hog_pdata *priv = platform_get_drvdata(pdev); + + clk_bulk_disable_unprepare(priv->num_clks, priv->clks); +} + +static int stm32_hog_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct stm32_hog_pdata *priv; + int ret; + + priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); + if (!priv) + return -ENOMEM; + + priv->num_clks = devm_clk_bulk_get_all(dev, &priv->clks); + if (priv->num_clks < 1) + return -ENODEV; + + ret = clk_bulk_prepare_enable(priv->num_clks, priv->clks); + if (ret) { + dev_err(dev, "failed to enable bulk clks %d\n", ret); + return ret; + } + + platform_set_drvdata(pdev, priv); + + return 0; +} + +static const struct of_device_id stm32_hog_match[] = { + { .compatible = "st,stm32-hog", }, + {} +}; +MODULE_DEVICE_TABLE(of, stm32_hog_match); + +static struct platform_driver stm32_hog_driver = { + .probe = stm32_hog_probe, + .remove_new = stm32_hog_remove, + .driver = { + .name = "stm32-hog", + .of_match_table = stm32_hog_match, + }, +}; +module_platform_driver(stm32_hog_driver); +MODULE_AUTHOR("Gabriel Fernandez "); +MODULE_LICENSE("GPL"); diff --git a/drivers/watchdog/stm32_iwdg.c b/drivers/watchdog/stm32_iwdg.c index d7dfab2d3..d6a7b74db 100644 --- a/drivers/watchdog/stm32_iwdg.c +++ b/drivers/watchdog/stm32_iwdg.c @@ -320,7 +320,7 @@ static int stm32_iwdg_irq_init(struct platform_device *pdev, if (!wdt->data->has_early_wakeup) return 0; - irq = platform_get_irq(pdev, 0); + irq = platform_get_irq_optional(pdev, 0); if (irq <= 0) return 0; -- 2.34.1