From bf3159c0ef1fd2bc999e3a4910b1c610949ae333 Mon Sep 17 00:00:00 2001 From: Daniel Lezcano Date: Wed, 27 Dec 2023 15:35:46 +0100 Subject: clocksource/drivers/imx: Fix -Wunused-but-set-variable warning All warnings (new ones prefixed by >>): drivers/clocksource/timer-imx-gpt.c: In function 'mxc_timer_interrupt': >> drivers/clocksource/timer-imx-gpt.c:279:18: warning: variable 'tstat' set but not used [-Wunused-but-set-variable] 279 | uint32_t tstat; | ^~~~~ vim +/tstat +279 drivers/clocksource/timer-imx-gpt.c The change remove the tstats assignment but not the reading of the register, assuming the register may be a ROR (Reset On Read) which happens in the driver's interrupt registers. Fixes: df181e382816 ("clocksource/drivers/imx-gpt: Add support for ARM64") Reported-by: kernel test robot Closes: https://lore.kernel.org/oe-kbuild-all/202312231803.XzPddRa5-lkp@intel.com/ Signed-off-by: Daniel Lezcano Link: https://lore.kernel.org/r/20231227143546.2823683-1-daniel.lezcano@linaro.org --- drivers/clocksource/timer-imx-gpt.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers/clocksource') diff --git a/drivers/clocksource/timer-imx-gpt.c b/drivers/clocksource/timer-imx-gpt.c index 6a878d227a13..489e69169ed4 100644 --- a/drivers/clocksource/timer-imx-gpt.c +++ b/drivers/clocksource/timer-imx-gpt.c @@ -258,9 +258,8 @@ static irqreturn_t mxc_timer_interrupt(int irq, void *dev_id) { struct clock_event_device *ced = dev_id; struct imx_timer *imxtm = to_imx_timer(ced); - uint32_t tstat; - tstat = readl_relaxed(imxtm->base + imxtm->gpt->reg_tstat); + readl_relaxed(imxtm->base + imxtm->gpt->reg_tstat); imxtm->gpt->gpt_irq_acknowledge(imxtm); -- cgit v1.2.3-70-g09d2 From 906fed29f4527e60db30d4eaa4b5b06a92447c69 Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Sat, 20 Jan 2024 09:36:15 -0800 Subject: clocksource/drivers/stm32: Fix all kernel-doc warnings Add a "Returns:" section in one function description. Use the correct function name in another function description. These changes prevent 2 warnings: timer-stm32.c:79: warning: No description found for return value of 'stm32_timer_of_bits_get' timer-stm32.c:189: warning: expecting prototype for stm32_timer_width(). Prototype was for stm32_timer_set_width() instead Signed-off-by: Randy Dunlap Cc: Daniel Lezcano Cc: Thomas Gleixner Cc: Fabrice Gasnier Cc: linux-stm32@st-md-mailman.stormreply.com Cc: linux-arm-kernel@lists.infradead.org Signed-off-by: Daniel Lezcano Link: https://lore.kernel.org/r/20240120173615.14618-1-rdunlap@infradead.org --- drivers/clocksource/timer-stm32.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/clocksource') diff --git a/drivers/clocksource/timer-stm32.c b/drivers/clocksource/timer-stm32.c index c9a753f96ba1..0a4ea3288bfb 100644 --- a/drivers/clocksource/timer-stm32.c +++ b/drivers/clocksource/timer-stm32.c @@ -73,7 +73,7 @@ static void stm32_timer_of_bits_set(struct timer_of *to, int bits) * Accessor helper to get the number of bits in the timer-of private * structure. * - * Returns an integer corresponding to the number of bits. + * Returns: an integer corresponding to the number of bits. */ static int stm32_timer_of_bits_get(struct timer_of *to) { @@ -177,7 +177,7 @@ static irqreturn_t stm32_clock_event_handler(int irq, void *dev_id) } /** - * stm32_timer_width - Sort out the timer width (32/16) + * stm32_timer_set_width - Sort out the timer width (32/16) * @to: a pointer to a timer-of structure * * Write the 32-bit max value and read/return the result. If the timer -- cgit v1.2.3-70-g09d2 From 702107ed5d89e50499aa1d65fe499a028073b25e Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Sat, 20 Jan 2024 09:36:24 -0800 Subject: clocksource/drivers/ti-32K: Fix misuse of "/**" comment Change "/**" to a common "/*" comment in a non-kernel-doc comment to avoid a kernel-doc warning: timer-ti-32k.c:42: warning: expecting prototype for timer(). Prototype was for OMAP2_32KSYNCNT_REV_OFF() instead Signed-off-by: Randy Dunlap Cc: Daniel Lezcano Cc: Thomas Gleixner Signed-off-by: Daniel Lezcano Link: https://lore.kernel.org/r/20240120173624.16769-1-rdunlap@infradead.org --- drivers/clocksource/timer-ti-32k.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/clocksource') diff --git a/drivers/clocksource/timer-ti-32k.c b/drivers/clocksource/timer-ti-32k.c index 59b0be482f32..a86529a70737 100644 --- a/drivers/clocksource/timer-ti-32k.c +++ b/drivers/clocksource/timer-ti-32k.c @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GPL-2.0-only -/** +/* * timer-ti-32k.c - OMAP2 32k Timer Support * * Copyright (C) 2009 Nokia Corporation -- cgit v1.2.3-70-g09d2 From 418062b548b138a1e6a9fde3a8ddf7fa77c44c9e Mon Sep 17 00:00:00 2001 From: Peng Fan Date: Mon, 5 Feb 2024 11:17:58 +0800 Subject: clocksource/drivers/imx-sysctr: Drop use global variables Clean up code to not use global variables and introduce sysctr_private structure to prepare the support for i.MX95. Signed-off-by: Peng Fan Signed-off-by: Daniel Lezcano Link: https://lore.kernel.org/r/20240205-imx-sysctr-v4-2-ca5a6e1552e7@nxp.com --- drivers/clocksource/timer-imx-sysctr.c | 76 ++++++++++++++++++++-------------- 1 file changed, 44 insertions(+), 32 deletions(-) (limited to 'drivers/clocksource') diff --git a/drivers/clocksource/timer-imx-sysctr.c b/drivers/clocksource/timer-imx-sysctr.c index 5a7a951c4efc..c075ea89a214 100644 --- a/drivers/clocksource/timer-imx-sysctr.c +++ b/drivers/clocksource/timer-imx-sysctr.c @@ -4,6 +4,7 @@ #include #include +#include #include "timer-of.h" @@ -20,32 +21,39 @@ #define SYS_CTR_CLK_DIV 0x3 -static void __iomem *sys_ctr_base __ro_after_init; -static u32 cmpcr __ro_after_init; +struct sysctr_private { + u32 cmpcr; +}; -static void sysctr_timer_enable(bool enable) +static void sysctr_timer_enable(struct clock_event_device *evt, bool enable) { - writel(enable ? cmpcr | SYS_CTR_EN : cmpcr, sys_ctr_base + CMPCR); + struct timer_of *to = to_timer_of(evt); + struct sysctr_private *priv = to->private_data; + void __iomem *base = timer_of_base(to); + + writel(enable ? priv->cmpcr | SYS_CTR_EN : priv->cmpcr, base + CMPCR); } -static void sysctr_irq_acknowledge(void) +static void sysctr_irq_acknowledge(struct clock_event_device *evt) { /* * clear the enable bit(EN =0) will clear * the status bit(ISTAT = 0), then the interrupt * signal will be negated(acknowledged). */ - sysctr_timer_enable(false); + sysctr_timer_enable(evt, false); } -static inline u64 sysctr_read_counter(void) +static inline u64 sysctr_read_counter(struct clock_event_device *evt) { + struct timer_of *to = to_timer_of(evt); + void __iomem *base = timer_of_base(to); u32 cnt_hi, tmp_hi, cnt_lo; do { - cnt_hi = readl_relaxed(sys_ctr_base + CNTCV_HI); - cnt_lo = readl_relaxed(sys_ctr_base + CNTCV_LO); - tmp_hi = readl_relaxed(sys_ctr_base + CNTCV_HI); + cnt_hi = readl_relaxed(base + CNTCV_HI); + cnt_lo = readl_relaxed(base + CNTCV_LO); + tmp_hi = readl_relaxed(base + CNTCV_HI); } while (tmp_hi != cnt_hi); return ((u64) cnt_hi << 32) | cnt_lo; @@ -54,22 +62,24 @@ static inline u64 sysctr_read_counter(void) static int sysctr_set_next_event(unsigned long delta, struct clock_event_device *evt) { + struct timer_of *to = to_timer_of(evt); + void __iomem *base = timer_of_base(to); u32 cmp_hi, cmp_lo; u64 next; - sysctr_timer_enable(false); + sysctr_timer_enable(evt, false); - next = sysctr_read_counter(); + next = sysctr_read_counter(evt); next += delta; cmp_hi = (next >> 32) & 0x00fffff; cmp_lo = next & 0xffffffff; - writel_relaxed(cmp_hi, sys_ctr_base + CMPCV_HI); - writel_relaxed(cmp_lo, sys_ctr_base + CMPCV_LO); + writel_relaxed(cmp_hi, base + CMPCV_HI); + writel_relaxed(cmp_lo, base + CMPCV_LO); - sysctr_timer_enable(true); + sysctr_timer_enable(evt, true); return 0; } @@ -81,7 +91,7 @@ static int sysctr_set_state_oneshot(struct clock_event_device *evt) static int sysctr_set_state_shutdown(struct clock_event_device *evt) { - sysctr_timer_enable(false); + sysctr_timer_enable(evt, false); return 0; } @@ -90,7 +100,7 @@ static irqreturn_t sysctr_timer_interrupt(int irq, void *dev_id) { struct clock_event_device *evt = dev_id; - sysctr_irq_acknowledge(); + sysctr_irq_acknowledge(evt); evt->event_handler(evt); @@ -117,34 +127,36 @@ static struct timer_of to_sysctr = { }, }; -static void __init sysctr_clockevent_init(void) -{ - to_sysctr.clkevt.cpumask = cpu_possible_mask; - - clockevents_config_and_register(&to_sysctr.clkevt, - timer_of_rate(&to_sysctr), - 0xff, 0x7fffffff); -} - static int __init sysctr_timer_init(struct device_node *np) { - int ret = 0; + struct sysctr_private *priv; + void __iomem *base; + int ret; + + priv = kzalloc(sizeof(struct sysctr_private), GFP_KERNEL); + if (!priv) + return -ENOMEM; ret = timer_of_init(np, &to_sysctr); - if (ret) + if (ret) { + kfree(priv); return ret; + } if (!of_property_read_bool(np, "nxp,no-divider")) { /* system counter clock is divided by 3 internally */ to_sysctr.of_clk.rate /= SYS_CTR_CLK_DIV; } - sys_ctr_base = timer_of_base(&to_sysctr); - cmpcr = readl(sys_ctr_base + CMPCR); - cmpcr &= ~SYS_CTR_EN; + to_sysctr.clkevt.cpumask = cpu_possible_mask; + to_sysctr.private_data = priv; - sysctr_clockevent_init(); + base = timer_of_base(&to_sysctr); + priv->cmpcr = readl(base + CMPCR) & ~SYS_CTR_EN; + clockevents_config_and_register(&to_sysctr.clkevt, + timer_of_rate(&to_sysctr), + 0xff, 0x7fffffff); return 0; } TIMER_OF_DECLARE(sysctr_timer, "nxp,sysctr-timer", sysctr_timer_init); -- cgit v1.2.3-70-g09d2 From b67686e971b06eee1be363b89863bd1217f65190 Mon Sep 17 00:00:00 2001 From: Peng Fan Date: Mon, 5 Feb 2024 11:17:59 +0800 Subject: clocksource/drivers/imx-sysctr: Add i.MX95 support To i.MX95 System counter module, we use Read register space to get the counter, not the Control register space to get the counter, because System Manager firmware not allow Linux to read Control register space, so add a new TIMER_OF_DECLARE entry for i.MX95. Signed-off-by: Peng Fan Signed-off-by: Daniel Lezcano Link: https://lore.kernel.org/r/20240205-imx-sysctr-v4-3-ca5a6e1552e7@nxp.com --- drivers/clocksource/timer-imx-sysctr.c | 53 +++++++++++++++++++++++++++++++--- 1 file changed, 49 insertions(+), 4 deletions(-) (limited to 'drivers/clocksource') diff --git a/drivers/clocksource/timer-imx-sysctr.c b/drivers/clocksource/timer-imx-sysctr.c index c075ea89a214..44525813be1e 100644 --- a/drivers/clocksource/timer-imx-sysctr.c +++ b/drivers/clocksource/timer-imx-sysctr.c @@ -9,12 +9,15 @@ #include "timer-of.h" #define CMP_OFFSET 0x10000 +#define RD_OFFSET 0x20000 #define CNTCV_LO 0x8 #define CNTCV_HI 0xc #define CMPCV_LO (CMP_OFFSET + 0x20) #define CMPCV_HI (CMP_OFFSET + 0x24) #define CMPCR (CMP_OFFSET + 0x2c) +#define CNTCV_LO_IMX95 (RD_OFFSET + 0x8) +#define CNTCV_HI_IMX95 (RD_OFFSET + 0xc) #define SYS_CTR_EN 0x1 #define SYS_CTR_IRQ_MASK 0x2 @@ -23,6 +26,8 @@ struct sysctr_private { u32 cmpcr; + u32 lo_off; + u32 hi_off; }; static void sysctr_timer_enable(struct clock_event_device *evt, bool enable) @@ -47,13 +52,14 @@ static void sysctr_irq_acknowledge(struct clock_event_device *evt) static inline u64 sysctr_read_counter(struct clock_event_device *evt) { struct timer_of *to = to_timer_of(evt); + struct sysctr_private *priv = to->private_data; void __iomem *base = timer_of_base(to); u32 cnt_hi, tmp_hi, cnt_lo; do { - cnt_hi = readl_relaxed(base + CNTCV_HI); - cnt_lo = readl_relaxed(base + CNTCV_LO); - tmp_hi = readl_relaxed(base + CNTCV_HI); + cnt_hi = readl_relaxed(base + priv->hi_off); + cnt_lo = readl_relaxed(base + priv->lo_off); + tmp_hi = readl_relaxed(base + priv->hi_off); } while (tmp_hi != cnt_hi); return ((u64) cnt_hi << 32) | cnt_lo; @@ -127,7 +133,7 @@ static struct timer_of to_sysctr = { }, }; -static int __init sysctr_timer_init(struct device_node *np) +static int __init __sysctr_timer_init(struct device_node *np) { struct sysctr_private *priv; void __iomem *base; @@ -154,9 +160,48 @@ static int __init sysctr_timer_init(struct device_node *np) base = timer_of_base(&to_sysctr); priv->cmpcr = readl(base + CMPCR) & ~SYS_CTR_EN; + return 0; +} + +static int __init sysctr_timer_init(struct device_node *np) +{ + struct sysctr_private *priv; + int ret; + + ret = __sysctr_timer_init(np); + if (ret) + return ret; + + priv = to_sysctr.private_data; + priv->lo_off = CNTCV_LO; + priv->hi_off = CNTCV_HI; + clockevents_config_and_register(&to_sysctr.clkevt, timer_of_rate(&to_sysctr), 0xff, 0x7fffffff); + return 0; } + +static int __init sysctr_timer_imx95_init(struct device_node *np) +{ + struct sysctr_private *priv; + int ret; + + ret = __sysctr_timer_init(np); + if (ret) + return ret; + + priv = to_sysctr.private_data; + priv->lo_off = CNTCV_LO_IMX95; + priv->hi_off = CNTCV_HI_IMX95; + + clockevents_config_and_register(&to_sysctr.clkevt, + timer_of_rate(&to_sysctr), + 0xff, 0x7fffffff); + + return 0; +} + TIMER_OF_DECLARE(sysctr_timer, "nxp,sysctr-timer", sysctr_timer_init); +TIMER_OF_DECLARE(sysctr_timer_imx95, "nxp,imx95-sysctr-timer", sysctr_timer_imx95_init); -- cgit v1.2.3-70-g09d2 From b34b9547cee41575a4fddf390f615570759dc999 Mon Sep 17 00:00:00 2001 From: Martin Blumenstingl Date: Sun, 18 Feb 2024 18:41:37 +0100 Subject: clocksource/drivers/arm_global_timer: Fix maximum prescaler value The prescaler in the "Global Timer Control Register bit assignments" is documented to use bits [15:8], which means that the maximum prescaler register value is 0xff. Fixes: 171b45a4a70e ("clocksource/drivers/arm_global_timer: Implement rate compensation whenever source clock changes") Signed-off-by: Martin Blumenstingl Signed-off-by: Daniel Lezcano Link: https://lore.kernel.org/r/20240218174138.1942418-2-martin.blumenstingl@googlemail.com --- drivers/clocksource/arm_global_timer.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/clocksource') diff --git a/drivers/clocksource/arm_global_timer.c b/drivers/clocksource/arm_global_timer.c index 44a61dc6f932..e1c773bb5535 100644 --- a/drivers/clocksource/arm_global_timer.c +++ b/drivers/clocksource/arm_global_timer.c @@ -32,7 +32,7 @@ #define GT_CONTROL_IRQ_ENABLE BIT(2) /* banked */ #define GT_CONTROL_AUTO_INC BIT(3) /* banked */ #define GT_CONTROL_PRESCALER_SHIFT 8 -#define GT_CONTROL_PRESCALER_MAX 0xF +#define GT_CONTROL_PRESCALER_MAX 0xFF #define GT_CONTROL_PRESCALER_MASK (GT_CONTROL_PRESCALER_MAX << \ GT_CONTROL_PRESCALER_SHIFT) -- cgit v1.2.3-70-g09d2 From 9256cec7b4f3293c11585326401325b1f81670e1 Mon Sep 17 00:00:00 2001 From: Martin Blumenstingl Date: Sun, 18 Feb 2024 18:41:38 +0100 Subject: clocksource/drivers/arm_global_timer: Remove stray tab Remove a stray tab in global_timer_of_register() which is different from the coding style in the rest of the driver. Signed-off-by: Martin Blumenstingl Signed-off-by: Daniel Lezcano Link: https://lore.kernel.org/r/20240218174138.1942418-3-martin.blumenstingl@googlemail.com --- drivers/clocksource/arm_global_timer.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/clocksource') diff --git a/drivers/clocksource/arm_global_timer.c b/drivers/clocksource/arm_global_timer.c index e1c773bb5535..8dd1e46b7176 100644 --- a/drivers/clocksource/arm_global_timer.c +++ b/drivers/clocksource/arm_global_timer.c @@ -411,7 +411,7 @@ static int __init global_timer_of_register(struct device_node *np) err = gt_clocksource_init(); if (err) goto out_irq; - + err = cpuhp_setup_state(CPUHP_AP_ARM_GLOBAL_TIMER_STARTING, "clockevents/arm/global_timer:starting", gt_starting_cpu, gt_dying_cpu); -- cgit v1.2.3-70-g09d2 From 97454a65d56b240013ed8d396427b85e34384238 Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Sun, 14 Jan 2024 21:36:41 -0800 Subject: clocksource: arm_global_timer: fix non-kernel-doc comment Use a common C comment "/*" instead of a kernel-doc marker "/**" to prevent kernel-doc warnings: arm_global_timer.c:92: warning: This comment starts with '/**', but isn't a kernel-doc comment. Refer Documentation/doc-guide/kernel-doc.rst * To ensure that updates to comparator value register do not set the arm_global_timer.c:92: warning: missing initial short description on line: * To ensure that updates to comparator value register do not set the Signed-off-by: Randy Dunlap Cc: Patrice Chotard Cc: linux-arm-kernel@lists.infradead.org Cc: Daniel Lezcano Cc: Thomas Gleixner Signed-off-by: Daniel Lezcano Link: https://lore.kernel.org/r/20240115053641.29129-1-rdunlap@infradead.org --- drivers/clocksource/arm_global_timer.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/clocksource') diff --git a/drivers/clocksource/arm_global_timer.c b/drivers/clocksource/arm_global_timer.c index 8dd1e46b7176..d749dee1d41d 100644 --- a/drivers/clocksource/arm_global_timer.c +++ b/drivers/clocksource/arm_global_timer.c @@ -88,7 +88,7 @@ static u64 gt_counter_read(void) return _gt_counter_read(); } -/** +/* * To ensure that updates to comparator value register do not set the * Interrupt Status Register proceed as follows: * 1. Clear the Comp Enable bit in the Timer Control Register. -- cgit v1.2.3-70-g09d2 From f31c204850f9d93906b5ac8c203b2066524ff245 Mon Sep 17 00:00:00 2001 From: Martin Blumenstingl Date: Sun, 25 Feb 2024 16:13:34 +0100 Subject: clocksource/drivers/arm_global_timer: Make gt_target_rate unsigned long Change the data type of gt_target_rate to unsigned long as this is what we get back from clk_get_rate(). Signed-off-by: Martin Blumenstingl Signed-off-by: Daniel Lezcano Link: https://lore.kernel.org/r/20240225151336.2728533-2-martin.blumenstingl@googlemail.com --- drivers/clocksource/arm_global_timer.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers/clocksource') diff --git a/drivers/clocksource/arm_global_timer.c b/drivers/clocksource/arm_global_timer.c index d749dee1d41d..fd39cfabe526 100644 --- a/drivers/clocksource/arm_global_timer.c +++ b/drivers/clocksource/arm_global_timer.c @@ -52,7 +52,8 @@ */ static void __iomem *gt_base; static struct notifier_block gt_clk_rate_change_nb; -static u32 gt_psv_new, gt_psv_bck, gt_target_rate; +static u32 gt_psv_new, gt_psv_bck; +static unsigned long gt_target_rate; static int gt_ppi; static struct clock_event_device __percpu *gt_evt; -- cgit v1.2.3-70-g09d2 From e651f2fae33634175fae956d896277cf916f5d09 Mon Sep 17 00:00:00 2001 From: Martin Blumenstingl Date: Sun, 25 Feb 2024 16:13:35 +0100 Subject: clocksource/drivers/arm_global_timer: Guard against division by zero The result of the division of new_rate by gt_target_rate can be zero (if new_rate is smaller than gt_target_rate). Using that result as divisor without checking can result in a division by zero error. Guard against this by checking for a zero value earlier. While here, also change the psv variable to an unsigned long to make sure we don't overflow the datatype as all other types involved are also unsiged long. Signed-off-by: Martin Blumenstingl Signed-off-by: Daniel Lezcano Link: https://lore.kernel.org/r/20240225151336.2728533-3-martin.blumenstingl@googlemail.com --- drivers/clocksource/arm_global_timer.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) (limited to 'drivers/clocksource') diff --git a/drivers/clocksource/arm_global_timer.c b/drivers/clocksource/arm_global_timer.c index fd39cfabe526..4726a15b0afc 100644 --- a/drivers/clocksource/arm_global_timer.c +++ b/drivers/clocksource/arm_global_timer.c @@ -291,18 +291,17 @@ static int gt_clk_rate_change_cb(struct notifier_block *nb, switch (event) { case PRE_RATE_CHANGE: { - int psv; + unsigned long psv; - psv = DIV_ROUND_CLOSEST(ndata->new_rate, - gt_target_rate); - - if (abs(gt_target_rate - (ndata->new_rate / psv)) > MAX_F_ERR) + psv = DIV_ROUND_CLOSEST(ndata->new_rate, gt_target_rate); + if (!psv || + abs(gt_target_rate - (ndata->new_rate / psv)) > MAX_F_ERR) return NOTIFY_BAD; psv--; /* prescaler within legal range? */ - if (psv < 0 || psv > GT_CONTROL_PRESCALER_MAX) + if (psv > GT_CONTROL_PRESCALER_MAX) return NOTIFY_BAD; /* -- cgit v1.2.3-70-g09d2 From 755350bcfb4ac8cbbb62bd7ee6be8271d4b2a88a Mon Sep 17 00:00:00 2001 From: Martin Blumenstingl Date: Sun, 25 Feb 2024 16:13:36 +0100 Subject: clocksource/drivers/arm_global_timer: Simplify prescaler register access Use GENMASK() to define the prescaler mask and make the whole driver use the mask (together with helpers such as FIELD_{GET,PREP,FIT}) instead of needing an additional shift and max value constant. Signed-off-by: Martin Blumenstingl Signed-off-by: Daniel Lezcano Link: https://lore.kernel.org/r/20240225151336.2728533-4-martin.blumenstingl@googlemail.com --- drivers/clocksource/arm_global_timer.c | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) (limited to 'drivers/clocksource') diff --git a/drivers/clocksource/arm_global_timer.c b/drivers/clocksource/arm_global_timer.c index 4726a15b0afc..ab1c8c2b66b8 100644 --- a/drivers/clocksource/arm_global_timer.c +++ b/drivers/clocksource/arm_global_timer.c @@ -9,6 +9,7 @@ #include #include +#include #include #include #include @@ -31,10 +32,7 @@ #define GT_CONTROL_COMP_ENABLE BIT(1) /* banked */ #define GT_CONTROL_IRQ_ENABLE BIT(2) /* banked */ #define GT_CONTROL_AUTO_INC BIT(3) /* banked */ -#define GT_CONTROL_PRESCALER_SHIFT 8 -#define GT_CONTROL_PRESCALER_MAX 0xFF -#define GT_CONTROL_PRESCALER_MASK (GT_CONTROL_PRESCALER_MAX << \ - GT_CONTROL_PRESCALER_SHIFT) +#define GT_CONTROL_PRESCALER_MASK GENMASK(15, 8) #define GT_INT_STATUS 0x0c #define GT_INT_STATUS_EVENT_FLAG BIT(0) @@ -248,7 +246,7 @@ static void gt_write_presc(u32 psv) reg = readl(gt_base + GT_CONTROL); reg &= ~GT_CONTROL_PRESCALER_MASK; - reg |= psv << GT_CONTROL_PRESCALER_SHIFT; + reg |= FIELD_PREP(GT_CONTROL_PRESCALER_MASK, psv); writel(reg, gt_base + GT_CONTROL); } @@ -257,8 +255,7 @@ static u32 gt_read_presc(void) u32 reg; reg = readl(gt_base + GT_CONTROL); - reg &= GT_CONTROL_PRESCALER_MASK; - return reg >> GT_CONTROL_PRESCALER_SHIFT; + return FIELD_GET(GT_CONTROL_PRESCALER_MASK, reg); } static void __init gt_delay_timer_init(void) @@ -273,9 +270,9 @@ static int __init gt_clocksource_init(void) writel(0, gt_base + GT_COUNTER0); writel(0, gt_base + GT_COUNTER1); /* set prescaler and enable timer on all the cores */ - writel(((CONFIG_ARM_GT_INITIAL_PRESCALER_VAL - 1) << - GT_CONTROL_PRESCALER_SHIFT) - | GT_CONTROL_TIMER_ENABLE, gt_base + GT_CONTROL); + writel(FIELD_PREP(GT_CONTROL_PRESCALER_MASK, + CONFIG_ARM_GT_INITIAL_PRESCALER_VAL - 1) | + GT_CONTROL_TIMER_ENABLE, gt_base + GT_CONTROL); #ifdef CONFIG_CLKSRC_ARM_GLOBAL_TIMER_SCHED_CLOCK sched_clock_register(gt_sched_clock_read, 64, gt_target_rate); @@ -301,7 +298,7 @@ static int gt_clk_rate_change_cb(struct notifier_block *nb, psv--; /* prescaler within legal range? */ - if (psv > GT_CONTROL_PRESCALER_MAX) + if (!FIELD_FIT(GT_CONTROL_PRESCALER_MASK, psv)) return NOTIFY_BAD; /* -- cgit v1.2.3-70-g09d2 From 8248ca30ef89f9cc74ace62ae1b9a22b5f16736c Mon Sep 17 00:00:00 2001 From: Ley Foon Tan Date: Thu, 7 Mar 2024 01:23:30 +0800 Subject: clocksource/drivers/timer-riscv: Clear timer interrupt on timer initialization In the RISC-V specification, the stimecmp register doesn't have a default value. To prevent the timer interrupt from being triggered during timer initialization, clear the timer interrupt by writing stimecmp with a maximum value. Fixes: 9f7a8ff6391f ("RISC-V: Prefer sstc extension if available") Cc: Signed-off-by: Ley Foon Tan Reviewed-by: Samuel Holland Tested-by: Samuel Holland Reviewed-by: Atish Patra Signed-off-by: Daniel Lezcano Link: https://lore.kernel.org/r/20240306172330.255844-1-leyfoon.tan@starfivetech.com --- drivers/clocksource/timer-riscv.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers/clocksource') diff --git a/drivers/clocksource/timer-riscv.c b/drivers/clocksource/timer-riscv.c index e66dcbd66566..79bb9a98baa7 100644 --- a/drivers/clocksource/timer-riscv.c +++ b/drivers/clocksource/timer-riscv.c @@ -108,6 +108,9 @@ static int riscv_timer_starting_cpu(unsigned int cpu) { struct clock_event_device *ce = per_cpu_ptr(&riscv_clock_event, cpu); + /* Clear timer interrupt */ + riscv_clock_event_stop(); + ce->cpumask = cpumask_of(cpu); ce->irq = riscv_clock_event_irq; if (riscv_timer_cannot_wake_cpu) -- cgit v1.2.3-70-g09d2