All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 1/2] clocksource/drivers/timer-tegra186: Avoid 64-bit divide operation
@ 2025-06-14 17:55 Guenter Roeck
  2025-06-14 17:55 ` [PATCH 2/2] clocksource/drivers/timer-tegra186: Simplify calculating timeleft Guenter Roeck
                   ` (5 more replies)
  0 siblings, 6 replies; 12+ messages in thread
From: Guenter Roeck @ 2025-06-14 17:55 UTC (permalink / raw)
  To: Daniel Lezcano
  Cc: Thomas Gleixner, Thierry Reding, Jonathan Hunter, linux-kernel,
	linux-tegra, Guenter Roeck, Pohsun Su, Robert Lin

Building the driver on xtensa fails with

tensa-linux-ld: drivers/clocksource/timer-tegra186.o:
	in function `tegra186_timer_remove':
timer-tegra186.c:(.text+0x350):
	undefined reference to `__udivdi3'

Avoid the problem by rearranging the offending code to avoid the 64-bit
divide operation.

Fixes: 28c842c8b0f5 ("clocksource/drivers/timer-tegra186: Add WDIOC_GETTIMELEFT support")
Cc: Pohsun Su <pohsuns@nvidia.com>
Cc: Robert Lin <robelin@nvidia.com>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
 drivers/clocksource/timer-tegra186.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/clocksource/timer-tegra186.c b/drivers/clocksource/timer-tegra186.c
index e5394f98a02e..7b506de65438 100644
--- a/drivers/clocksource/timer-tegra186.c
+++ b/drivers/clocksource/timer-tegra186.c
@@ -267,7 +267,7 @@ static unsigned int tegra186_wdt_get_timeleft(struct watchdog_device *wdd)
 	 * counter value to the time of the counter expirations that
 	 * remain.
 	 */
-	timeleft += (((u64)wdt->base.timeout * USEC_PER_SEC) / 5) * (4 - expiration);
+	timeleft += ((u64)wdt->base.timeout * (USEC_PER_SEC / 5)) * (4 - expiration);
 
 	/*
 	 * Convert the current counter value to seconds,
-- 
2.45.2


^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH 2/2] clocksource/drivers/timer-tegra186: Simplify calculating timeleft
  2025-06-14 17:55 [PATCH 1/2] clocksource/drivers/timer-tegra186: Avoid 64-bit divide operation Guenter Roeck
@ 2025-06-14 17:55 ` Guenter Roeck
  2025-06-19  7:25   ` Jon Hunter
                     ` (2 more replies)
  2025-06-19  7:17 ` [PATCH 1/2] clocksource/drivers/timer-tegra186: Avoid 64-bit divide operation Jon Hunter
                   ` (4 subsequent siblings)
  5 siblings, 3 replies; 12+ messages in thread
From: Guenter Roeck @ 2025-06-14 17:55 UTC (permalink / raw)
  To: Daniel Lezcano
  Cc: Thomas Gleixner, Thierry Reding, Jonathan Hunter, linux-kernel,
	linux-tegra, Guenter Roeck, Pohsun Su, Robert Lin

It is not necessary to use 64-bit operations to calculate the
remaining watchdog timeout. Simplify to use 32-bit operations,
and add comments explaining why there will be no overflow.

Cc: Pohsun Su <pohsuns@nvidia.com>
Cc: Robert Lin <robelin@nvidia.com>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
 drivers/clocksource/timer-tegra186.c | 25 +++++++++++++++----------
 1 file changed, 15 insertions(+), 10 deletions(-)

diff --git a/drivers/clocksource/timer-tegra186.c b/drivers/clocksource/timer-tegra186.c
index 7b506de65438..6ed319bb4e06 100644
--- a/drivers/clocksource/timer-tegra186.c
+++ b/drivers/clocksource/timer-tegra186.c
@@ -231,7 +231,7 @@ static unsigned int tegra186_wdt_get_timeleft(struct watchdog_device *wdd)
 {
 	struct tegra186_wdt *wdt = to_tegra186_wdt(wdd);
 	u32 expiration, val;
-	u64 timeleft;
+	u32 timeleft;
 
 	if (!watchdog_active(&wdt->base)) {
 		/* return zero if the watchdog timer is not activated. */
@@ -266,21 +266,26 @@ static unsigned int tegra186_wdt_get_timeleft(struct watchdog_device *wdd)
 	 * Calculate the time remaining by adding the time for the
 	 * counter value to the time of the counter expirations that
 	 * remain.
+	 * Note: Since wdt->base.timeout is bound to 255, the maximum
+	 * value added to timeleft is
+	 *   255 * (1,000,000 / 5) * 4
+	 * = 255 * 200,000 * 4
+	 * = 204,000,000
+	 * TMRSR_PCV is a 29-bit field.
+	 * Its maximum value is 0x1fffffff = 536,870,911.
+	 * 204,000,000 + 536,870,911 = 740,870,911 = 0x2C28CAFF.
+	 * timeleft can therefore not overflow, and 64-bit calculations
+	 * are not necessary.
 	 */
-	timeleft += ((u64)wdt->base.timeout * (USEC_PER_SEC / 5)) * (4 - expiration);
+	timeleft += (wdt->base.timeout * (USEC_PER_SEC / 5)) * (4 - expiration);
 
 	/*
 	 * Convert the current counter value to seconds,
-	 * rounding up to the nearest second. Cast u64 to
-	 * u32 under the assumption that no overflow happens
-	 * when coverting to seconds.
+	 * rounding to the nearest second.
 	 */
-	timeleft = DIV_ROUND_CLOSEST_ULL(timeleft, USEC_PER_SEC);
+	timeleft = DIV_ROUND_CLOSEST(timeleft, USEC_PER_SEC);
 
-	if (WARN_ON_ONCE(timeleft > U32_MAX))
-		return U32_MAX;
-
-	return lower_32_bits(timeleft);
+	return timeleft;
 }
 
 static const struct watchdog_ops tegra186_wdt_ops = {
-- 
2.45.2


^ permalink raw reply related	[flat|nested] 12+ messages in thread

* Re: [PATCH 1/2] clocksource/drivers/timer-tegra186: Avoid 64-bit divide operation
  2025-06-14 17:55 [PATCH 1/2] clocksource/drivers/timer-tegra186: Avoid 64-bit divide operation Guenter Roeck
  2025-06-14 17:55 ` [PATCH 2/2] clocksource/drivers/timer-tegra186: Simplify calculating timeleft Guenter Roeck
@ 2025-06-19  7:17 ` Jon Hunter
  2025-06-24 14:32 ` Daniel Lezcano
                   ` (3 subsequent siblings)
  5 siblings, 0 replies; 12+ messages in thread
From: Jon Hunter @ 2025-06-19  7:17 UTC (permalink / raw)
  To: Guenter Roeck, Daniel Lezcano
  Cc: Thomas Gleixner, Thierry Reding, linux-kernel, linux-tegra,
	Pohsun Su, Robert Lin


On 14/06/2025 18:55, Guenter Roeck wrote:
> Building the driver on xtensa fails with
> 
> tensa-linux-ld: drivers/clocksource/timer-tegra186.o:
> 	in function `tegra186_timer_remove':
> timer-tegra186.c:(.text+0x350):
> 	undefined reference to `__udivdi3'
> 
> Avoid the problem by rearranging the offending code to avoid the 64-bit
> divide operation.
> 
> Fixes: 28c842c8b0f5 ("clocksource/drivers/timer-tegra186: Add WDIOC_GETTIMELEFT support")
> Cc: Pohsun Su <pohsuns@nvidia.com>
> Cc: Robert Lin <robelin@nvidia.com>
> Signed-off-by: Guenter Roeck <linux@roeck-us.net>
> ---
>   drivers/clocksource/timer-tegra186.c | 2 +-
>   1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/clocksource/timer-tegra186.c b/drivers/clocksource/timer-tegra186.c
> index e5394f98a02e..7b506de65438 100644
> --- a/drivers/clocksource/timer-tegra186.c
> +++ b/drivers/clocksource/timer-tegra186.c
> @@ -267,7 +267,7 @@ static unsigned int tegra186_wdt_get_timeleft(struct watchdog_device *wdd)
>   	 * counter value to the time of the counter expirations that
>   	 * remain.
>   	 */
> -	timeleft += (((u64)wdt->base.timeout * USEC_PER_SEC) / 5) * (4 - expiration);
> +	timeleft += ((u64)wdt->base.timeout * (USEC_PER_SEC / 5)) * (4 - expiration);
>   
>   	/*
>   	 * Convert the current counter value to seconds,


Reviewed-by: Jon Hunter <jonathanh@nvidia.com>

Thanks!
Jon

-- 
nvpublic


^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH 2/2] clocksource/drivers/timer-tegra186: Simplify calculating timeleft
  2025-06-14 17:55 ` [PATCH 2/2] clocksource/drivers/timer-tegra186: Simplify calculating timeleft Guenter Roeck
@ 2025-06-19  7:25   ` Jon Hunter
  2025-07-23  7:17   ` [tip: timers/clocksource] " tip-bot2 for Guenter Roeck
  2025-07-25 10:31   ` tip-bot2 for Guenter Roeck
  2 siblings, 0 replies; 12+ messages in thread
From: Jon Hunter @ 2025-06-19  7:25 UTC (permalink / raw)
  To: Guenter Roeck, Daniel Lezcano
  Cc: Thomas Gleixner, Thierry Reding, linux-kernel, linux-tegra,
	Pohsun Su, Robert Lin


On 14/06/2025 18:55, Guenter Roeck wrote:
> It is not necessary to use 64-bit operations to calculate the
> remaining watchdog timeout. Simplify to use 32-bit operations,
> and add comments explaining why there will be no overflow.
> 
> Cc: Pohsun Su <pohsuns@nvidia.com>
> Cc: Robert Lin <robelin@nvidia.com>
> Signed-off-by: Guenter Roeck <linux@roeck-us.net>
> ---
>   drivers/clocksource/timer-tegra186.c | 25 +++++++++++++++----------
>   1 file changed, 15 insertions(+), 10 deletions(-)
> 
> diff --git a/drivers/clocksource/timer-tegra186.c b/drivers/clocksource/timer-tegra186.c
> index 7b506de65438..6ed319bb4e06 100644
> --- a/drivers/clocksource/timer-tegra186.c
> +++ b/drivers/clocksource/timer-tegra186.c
> @@ -231,7 +231,7 @@ static unsigned int tegra186_wdt_get_timeleft(struct watchdog_device *wdd)
>   {
>   	struct tegra186_wdt *wdt = to_tegra186_wdt(wdd);
>   	u32 expiration, val;
> -	u64 timeleft;
> +	u32 timeleft;
>   
>   	if (!watchdog_active(&wdt->base)) {
>   		/* return zero if the watchdog timer is not activated. */
> @@ -266,21 +266,26 @@ static unsigned int tegra186_wdt_get_timeleft(struct watchdog_device *wdd)
>   	 * Calculate the time remaining by adding the time for the
>   	 * counter value to the time of the counter expirations that
>   	 * remain.
> +	 * Note: Since wdt->base.timeout is bound to 255, the maximum
> +	 * value added to timeleft is
> +	 *   255 * (1,000,000 / 5) * 4
> +	 * = 255 * 200,000 * 4
> +	 * = 204,000,000
> +	 * TMRSR_PCV is a 29-bit field.
> +	 * Its maximum value is 0x1fffffff = 536,870,911.
> +	 * 204,000,000 + 536,870,911 = 740,870,911 = 0x2C28CAFF.
> +	 * timeleft can therefore not overflow, and 64-bit calculations
> +	 * are not necessary.

Nit, I may have worded this the other way around and said that 'timeleft 
  cannot overflow a 32-bit type and so 32-bit variables are sufficient 
for this calculation'. Simply because there are no longer any 64-bit 
variables used now. Anyway from the history of the change it will be 
clear where this came from.

>   	 */
> -	timeleft += ((u64)wdt->base.timeout * (USEC_PER_SEC / 5)) * (4 - expiration);
> +	timeleft += (wdt->base.timeout * (USEC_PER_SEC / 5)) * (4 - expiration);
>   
>   	/*
>   	 * Convert the current counter value to seconds,
> -	 * rounding up to the nearest second. Cast u64 to
> -	 * u32 under the assumption that no overflow happens
> -	 * when coverting to seconds.
> +	 * rounding to the nearest second.
>   	 */
> -	timeleft = DIV_ROUND_CLOSEST_ULL(timeleft, USEC_PER_SEC);
> +	timeleft = DIV_ROUND_CLOSEST(timeleft, USEC_PER_SEC);
>   
> -	if (WARN_ON_ONCE(timeleft > U32_MAX))
> -		return U32_MAX;
> -
> -	return lower_32_bits(timeleft);
> +	return timeleft;
>   }
>   
>   static const struct watchdog_ops tegra186_wdt_ops = {

Otherwise ...

Reviewed-by: Jon Hunter <jonathanh@nvidia.com>

Thanks!
Jon

-- 
nvpublic


^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH 1/2] clocksource/drivers/timer-tegra186: Avoid 64-bit divide operation
  2025-06-14 17:55 [PATCH 1/2] clocksource/drivers/timer-tegra186: Avoid 64-bit divide operation Guenter Roeck
  2025-06-14 17:55 ` [PATCH 2/2] clocksource/drivers/timer-tegra186: Simplify calculating timeleft Guenter Roeck
  2025-06-19  7:17 ` [PATCH 1/2] clocksource/drivers/timer-tegra186: Avoid 64-bit divide operation Jon Hunter
@ 2025-06-24 14:32 ` Daniel Lezcano
  2025-07-03 12:34   ` Jon Hunter
  2025-07-15 11:11 ` Daniel Lezcano
                   ` (2 subsequent siblings)
  5 siblings, 1 reply; 12+ messages in thread
From: Daniel Lezcano @ 2025-06-24 14:32 UTC (permalink / raw)
  To: Guenter Roeck
  Cc: Thomas Gleixner, Thierry Reding, Jonathan Hunter, linux-kernel,
	linux-tegra, Pohsun Su, Robert Lin, Arnd Bergmann

On Sat, Jun 14, 2025 at 10:55:55AM -0700, Guenter Roeck wrote:
> Building the driver on xtensa fails with
> 
> tensa-linux-ld: drivers/clocksource/timer-tegra186.o:
> 	in function `tegra186_timer_remove':
> timer-tegra186.c:(.text+0x350):
> 	undefined reference to `__udivdi3'
> 
> Avoid the problem by rearranging the offending code to avoid the 64-bit
> divide operation.
> 

Hi Guenter,

Arnd posted a version which seems more complete.

https://lore.kernel.org/all/20250620111939.3395525-1-arnd@kernel.org/

> Fixes: 28c842c8b0f5 ("clocksource/drivers/timer-tegra186: Add WDIOC_GETTIMELEFT support")
> Cc: Pohsun Su <pohsuns@nvidia.com>
> Cc: Robert Lin <robelin@nvidia.com>
> Signed-off-by: Guenter Roeck <linux@roeck-us.net>
> ---
>  drivers/clocksource/timer-tegra186.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/clocksource/timer-tegra186.c b/drivers/clocksource/timer-tegra186.c
> index e5394f98a02e..7b506de65438 100644
> --- a/drivers/clocksource/timer-tegra186.c
> +++ b/drivers/clocksource/timer-tegra186.c
> @@ -267,7 +267,7 @@ static unsigned int tegra186_wdt_get_timeleft(struct watchdog_device *wdd)
>  	 * counter value to the time of the counter expirations that
>  	 * remain.
>  	 */
> -	timeleft += (((u64)wdt->base.timeout * USEC_PER_SEC) / 5) * (4 - expiration);
> +	timeleft += ((u64)wdt->base.timeout * (USEC_PER_SEC / 5)) * (4 - expiration);
>  
>  	/*
>  	 * Convert the current counter value to seconds,
> -- 
> 2.45.2
> 

-- 

 <http://www.linaro.org/> Linaro.org │ Open source software for ARM SoCs

Follow Linaro:  <http://www.facebook.com/pages/Linaro> Facebook |
<http://twitter.com/#!/linaroorg> Twitter |
<http://www.linaro.org/linaro-blog/> Blog

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH 1/2] clocksource/drivers/timer-tegra186: Avoid 64-bit divide operation
  2025-06-24 14:32 ` Daniel Lezcano
@ 2025-07-03 12:34   ` Jon Hunter
  2025-07-03 12:42     ` Daniel Lezcano
  0 siblings, 1 reply; 12+ messages in thread
From: Jon Hunter @ 2025-07-03 12:34 UTC (permalink / raw)
  To: Daniel Lezcano, Guenter Roeck
  Cc: Thomas Gleixner, Thierry Reding, linux-kernel, linux-tegra,
	Pohsun Su, Robert Lin, Arnd Bergmann

Hi Daniel,

On 24/06/2025 15:32, Daniel Lezcano wrote:
> On Sat, Jun 14, 2025 at 10:55:55AM -0700, Guenter Roeck wrote:
>> Building the driver on xtensa fails with
>>
>> tensa-linux-ld: drivers/clocksource/timer-tegra186.o:
>> 	in function `tegra186_timer_remove':
>> timer-tegra186.c:(.text+0x350):
>> 	undefined reference to `__udivdi3'
>>
>> Avoid the problem by rearranging the offending code to avoid the 64-bit
>> divide operation.
>>
> 
> Hi Guenter,
> 
> Arnd posted a version which seems more complete.
> 
> https://lore.kernel.org/all/20250620111939.3395525-1-arnd@kernel.org/

Actually Arnd responded here saying this version looks better :-)

https://lore.kernel.org/all/5a571236-7de0-42bc-bfb2-52a57e210852@app.fastmail.com/

OK, to pick up this series now?

Thanks
Jon

-- 
nvpublic


^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH 1/2] clocksource/drivers/timer-tegra186: Avoid 64-bit divide operation
  2025-07-03 12:34   ` Jon Hunter
@ 2025-07-03 12:42     ` Daniel Lezcano
  0 siblings, 0 replies; 12+ messages in thread
From: Daniel Lezcano @ 2025-07-03 12:42 UTC (permalink / raw)
  To: Jon Hunter, Guenter Roeck
  Cc: Thomas Gleixner, Thierry Reding, linux-kernel, linux-tegra,
	Pohsun Su, Robert Lin, Arnd Bergmann

On 03/07/2025 14:34, Jon Hunter wrote:
> Hi Daniel,
> 
> On 24/06/2025 15:32, Daniel Lezcano wrote:
>> On Sat, Jun 14, 2025 at 10:55:55AM -0700, Guenter Roeck wrote:
>>> Building the driver on xtensa fails with
>>>
>>> tensa-linux-ld: drivers/clocksource/timer-tegra186.o:
>>>     in function `tegra186_timer_remove':
>>> timer-tegra186.c:(.text+0x350):
>>>     undefined reference to `__udivdi3'
>>>
>>> Avoid the problem by rearranging the offending code to avoid the 64-bit
>>> divide operation.
>>>
>>
>> Hi Guenter,
>>
>> Arnd posted a version which seems more complete.
>>
>> https://lore.kernel.org/all/20250620111939.3395525-1-arnd@kernel.org/
> 
> Actually Arnd responded here saying this version looks better :-)
> 
> https://lore.kernel.org/all/5a571236-7de0-42bc- 
> bfb2-52a57e210852@app.fastmail.com/
> 
> OK, to pick up this series now?

Yes, I'm ok.

May be Thomas can pick them up for the next -rc ?

-- 
<http://www.linaro.org/> Linaro.org │ Open source software for ARM SoCs

Follow Linaro:  <http://www.facebook.com/pages/Linaro> Facebook |
<http://twitter.com/#!/linaroorg> Twitter |
<http://www.linaro.org/linaro-blog/> Blog

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH 1/2] clocksource/drivers/timer-tegra186: Avoid 64-bit divide operation
  2025-06-14 17:55 [PATCH 1/2] clocksource/drivers/timer-tegra186: Avoid 64-bit divide operation Guenter Roeck
                   ` (2 preceding siblings ...)
  2025-06-24 14:32 ` Daniel Lezcano
@ 2025-07-15 11:11 ` Daniel Lezcano
  2025-07-23  7:17 ` [tip: timers/clocksource] " tip-bot2 for Guenter Roeck
  2025-07-25 10:31 ` tip-bot2 for Guenter Roeck
  5 siblings, 0 replies; 12+ messages in thread
From: Daniel Lezcano @ 2025-07-15 11:11 UTC (permalink / raw)
  To: Guenter Roeck
  Cc: Thomas Gleixner, Thierry Reding, Jonathan Hunter, linux-kernel,
	linux-tegra, Pohsun Su, Robert Lin

On Sat, Jun 14, 2025 at 10:55:55AM -0700, Guenter Roeck wrote:
> Building the driver on xtensa fails with
> 
> tensa-linux-ld: drivers/clocksource/timer-tegra186.o:
> 	in function `tegra186_timer_remove':
> timer-tegra186.c:(.text+0x350):
> 	undefined reference to `__udivdi3'
> 
> Avoid the problem by rearranging the offending code to avoid the 64-bit
> divide operation.
> 
> Fixes: 28c842c8b0f5 ("clocksource/drivers/timer-tegra186: Add WDIOC_GETTIMELEFT support")
> Cc: Pohsun Su <pohsuns@nvidia.com>
> Cc: Robert Lin <robelin@nvidia.com>
> Signed-off-by: Guenter Roeck <linux@roeck-us.net>
> ---

Applied, thanks

-- 

 <http://www.linaro.org/> Linaro.org │ Open source software for ARM SoCs

Follow Linaro:  <http://www.facebook.com/pages/Linaro> Facebook |
<http://twitter.com/#!/linaroorg> Twitter |
<http://www.linaro.org/linaro-blog/> Blog

^ permalink raw reply	[flat|nested] 12+ messages in thread

* [tip: timers/clocksource] clocksource/drivers/timer-tegra186: Simplify calculating timeleft
  2025-06-14 17:55 ` [PATCH 2/2] clocksource/drivers/timer-tegra186: Simplify calculating timeleft Guenter Roeck
  2025-06-19  7:25   ` Jon Hunter
@ 2025-07-23  7:17   ` tip-bot2 for Guenter Roeck
  2025-07-25 10:31   ` tip-bot2 for Guenter Roeck
  2 siblings, 0 replies; 12+ messages in thread
From: tip-bot2 for Guenter Roeck @ 2025-07-23  7:17 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: Pohsun Su, Robert Lin, Guenter Roeck, Jon Hunter, Daniel Lezcano,
	x86, linux-kernel

The following commit has been merged into the timers/clocksource branch of tip:

Commit-ID:     05065b2a86f86603e5c35dad4274e66be25b2d88
Gitweb:        https://git.kernel.org/tip/05065b2a86f86603e5c35dad4274e66be25b2d88
Author:        Guenter Roeck <linux@roeck-us.net>
AuthorDate:    Sat, 14 Jun 2025 10:55:56 -07:00
Committer:     Daniel Lezcano <daniel.lezcano@linaro.org>
CommitterDate: Tue, 15 Jul 2025 13:08:07 +02:00

clocksource/drivers/timer-tegra186: Simplify calculating timeleft

It is not necessary to use 64-bit operations to calculate the
remaining watchdog timeout. Simplify to use 32-bit operations,
and add comments explaining why there will be no overflow.

Cc: Pohsun Su <pohsuns@nvidia.com>
Cc: Robert Lin <robelin@nvidia.com>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
Reviewed-by: Jon Hunter <jonathanh@nvidia.com>
Link: https://lore.kernel.org/r/20250614175556.922159-2-linux@roeck-us.net
Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
---
 drivers/clocksource/timer-tegra186.c | 25 +++++++++++++++----------
 1 file changed, 15 insertions(+), 10 deletions(-)

diff --git a/drivers/clocksource/timer-tegra186.c b/drivers/clocksource/timer-tegra186.c
index 76a5481..d403a3f 100644
--- a/drivers/clocksource/timer-tegra186.c
+++ b/drivers/clocksource/timer-tegra186.c
@@ -231,7 +231,7 @@ static unsigned int tegra186_wdt_get_timeleft(struct watchdog_device *wdd)
 {
 	struct tegra186_wdt *wdt = to_tegra186_wdt(wdd);
 	u32 expiration, val;
-	u64 timeleft;
+	u32 timeleft;
 
 	if (!watchdog_active(&wdt->base)) {
 		/* return zero if the watchdog timer is not activated. */
@@ -266,21 +266,26 @@ static unsigned int tegra186_wdt_get_timeleft(struct watchdog_device *wdd)
 	 * Calculate the time remaining by adding the time for the
 	 * counter value to the time of the counter expirations that
 	 * remain.
+	 * Note: Since wdt->base.timeout is bound to 255, the maximum
+	 * value added to timeleft is
+	 *   255 * (1,000,000 / 5) * 4
+	 * = 255 * 200,000 * 4
+	 * = 204,000,000
+	 * TMRSR_PCV is a 29-bit field.
+	 * Its maximum value is 0x1fffffff = 536,870,911.
+	 * 204,000,000 + 536,870,911 = 740,870,911 = 0x2C28CAFF.
+	 * timeleft can therefore not overflow, and 64-bit calculations
+	 * are not necessary.
 	 */
-	timeleft += ((u64)wdt->base.timeout * (USEC_PER_SEC / 5)) * (4 - expiration);
+	timeleft += (wdt->base.timeout * (USEC_PER_SEC / 5)) * (4 - expiration);
 
 	/*
 	 * Convert the current counter value to seconds,
-	 * rounding up to the nearest second. Cast u64 to
-	 * u32 under the assumption that no overflow happens
-	 * when coverting to seconds.
+	 * rounding to the nearest second.
 	 */
-	timeleft = DIV_ROUND_CLOSEST_ULL(timeleft, USEC_PER_SEC);
+	timeleft = DIV_ROUND_CLOSEST(timeleft, USEC_PER_SEC);
 
-	if (WARN_ON_ONCE(timeleft > U32_MAX))
-		return U32_MAX;
-
-	return lower_32_bits(timeleft);
+	return timeleft;
 }
 
 static const struct watchdog_ops tegra186_wdt_ops = {

^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [tip: timers/clocksource] clocksource/drivers/timer-tegra186: Avoid 64-bit divide operation
  2025-06-14 17:55 [PATCH 1/2] clocksource/drivers/timer-tegra186: Avoid 64-bit divide operation Guenter Roeck
                   ` (3 preceding siblings ...)
  2025-07-15 11:11 ` Daniel Lezcano
@ 2025-07-23  7:17 ` tip-bot2 for Guenter Roeck
  2025-07-25 10:31 ` tip-bot2 for Guenter Roeck
  5 siblings, 0 replies; 12+ messages in thread
From: tip-bot2 for Guenter Roeck @ 2025-07-23  7:17 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: Pohsun Su, Robert Lin, Guenter Roeck, Jon Hunter, Daniel Lezcano,
	x86, linux-kernel

The following commit has been merged into the timers/clocksource branch of tip:

Commit-ID:     eda68f63d2bbc16a485f9f0f4df79253ae5353f2
Gitweb:        https://git.kernel.org/tip/eda68f63d2bbc16a485f9f0f4df79253ae5353f2
Author:        Guenter Roeck <linux@roeck-us.net>
AuthorDate:    Sat, 14 Jun 2025 10:55:55 -07:00
Committer:     Daniel Lezcano <daniel.lezcano@linaro.org>
CommitterDate: Tue, 15 Jul 2025 13:08:07 +02:00

clocksource/drivers/timer-tegra186: Avoid 64-bit divide operation

Building the driver on xtensa fails with

tensa-linux-ld: drivers/clocksource/timer-tegra186.o:
	in function `tegra186_timer_remove':
timer-tegra186.c:(.text+0x350):
	undefined reference to `__udivdi3'

Avoid the problem by rearranging the offending code to avoid the 64-bit
divide operation.

Fixes: 28c842c8b0f5 ("clocksource/drivers/timer-tegra186: Add WDIOC_GETTIMELEFT support")
Cc: Pohsun Su <pohsuns@nvidia.com>
Cc: Robert Lin <robelin@nvidia.com>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
Reviewed-by: Jon Hunter <jonathanh@nvidia.com>
Link: https://lore.kernel.org/r/20250614175556.922159-1-linux@roeck-us.net
Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
---
 drivers/clocksource/timer-tegra186.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/clocksource/timer-tegra186.c b/drivers/clocksource/timer-tegra186.c
index 56a5342..76a5481 100644
--- a/drivers/clocksource/timer-tegra186.c
+++ b/drivers/clocksource/timer-tegra186.c
@@ -267,7 +267,7 @@ static unsigned int tegra186_wdt_get_timeleft(struct watchdog_device *wdd)
 	 * counter value to the time of the counter expirations that
 	 * remain.
 	 */
-	timeleft += (((u64)wdt->base.timeout * USEC_PER_SEC) / 5) * (4 - expiration);
+	timeleft += ((u64)wdt->base.timeout * (USEC_PER_SEC / 5)) * (4 - expiration);
 
 	/*
 	 * Convert the current counter value to seconds,

^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [tip: timers/clocksource] clocksource/drivers/timer-tegra186: Simplify calculating timeleft
  2025-06-14 17:55 ` [PATCH 2/2] clocksource/drivers/timer-tegra186: Simplify calculating timeleft Guenter Roeck
  2025-06-19  7:25   ` Jon Hunter
  2025-07-23  7:17   ` [tip: timers/clocksource] " tip-bot2 for Guenter Roeck
@ 2025-07-25 10:31   ` tip-bot2 for Guenter Roeck
  2 siblings, 0 replies; 12+ messages in thread
From: tip-bot2 for Guenter Roeck @ 2025-07-25 10:31 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: Guenter Roeck, Daniel Lezcano, Ingo Molnar, Jon Hunter, Pohsun Su,
	Robert Lin, x86, linux-kernel

The following commit has been merged into the timers/clocksource branch of tip:

Commit-ID:     12c1fe0711d3de30440911f2d3e0147f9831f3c7
Gitweb:        https://git.kernel.org/tip/12c1fe0711d3de30440911f2d3e0147f9831f3c7
Author:        Guenter Roeck <linux@roeck-us.net>
AuthorDate:    Sat, 14 Jun 2025 10:55:56 -07:00
Committer:     Ingo Molnar <mingo@kernel.org>
CommitterDate: Fri, 25 Jul 2025 12:06:33 +02:00

clocksource/drivers/timer-tegra186: Simplify calculating timeleft

It is not necessary to use 64-bit operations to calculate the
remaining watchdog timeout. Simplify to use 32-bit operations,
and add comments explaining why there will be no overflow.

Signed-off-by: Guenter Roeck <linux@roeck-us.net>
Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Reviewed-by: Jon Hunter <jonathanh@nvidia.com>
Cc: Pohsun Su <pohsuns@nvidia.com>
Cc: Robert Lin <robelin@nvidia.com>
Link: https://lore.kernel.org/r/20250614175556.922159-2-linux@roeck-us.net
---
 drivers/clocksource/timer-tegra186.c | 25 +++++++++++++++----------
 1 file changed, 15 insertions(+), 10 deletions(-)

diff --git a/drivers/clocksource/timer-tegra186.c b/drivers/clocksource/timer-tegra186.c
index 76a5481..d403a3f 100644
--- a/drivers/clocksource/timer-tegra186.c
+++ b/drivers/clocksource/timer-tegra186.c
@@ -231,7 +231,7 @@ static unsigned int tegra186_wdt_get_timeleft(struct watchdog_device *wdd)
 {
 	struct tegra186_wdt *wdt = to_tegra186_wdt(wdd);
 	u32 expiration, val;
-	u64 timeleft;
+	u32 timeleft;
 
 	if (!watchdog_active(&wdt->base)) {
 		/* return zero if the watchdog timer is not activated. */
@@ -266,21 +266,26 @@ static unsigned int tegra186_wdt_get_timeleft(struct watchdog_device *wdd)
 	 * Calculate the time remaining by adding the time for the
 	 * counter value to the time of the counter expirations that
 	 * remain.
+	 * Note: Since wdt->base.timeout is bound to 255, the maximum
+	 * value added to timeleft is
+	 *   255 * (1,000,000 / 5) * 4
+	 * = 255 * 200,000 * 4
+	 * = 204,000,000
+	 * TMRSR_PCV is a 29-bit field.
+	 * Its maximum value is 0x1fffffff = 536,870,911.
+	 * 204,000,000 + 536,870,911 = 740,870,911 = 0x2C28CAFF.
+	 * timeleft can therefore not overflow, and 64-bit calculations
+	 * are not necessary.
 	 */
-	timeleft += ((u64)wdt->base.timeout * (USEC_PER_SEC / 5)) * (4 - expiration);
+	timeleft += (wdt->base.timeout * (USEC_PER_SEC / 5)) * (4 - expiration);
 
 	/*
 	 * Convert the current counter value to seconds,
-	 * rounding up to the nearest second. Cast u64 to
-	 * u32 under the assumption that no overflow happens
-	 * when coverting to seconds.
+	 * rounding to the nearest second.
 	 */
-	timeleft = DIV_ROUND_CLOSEST_ULL(timeleft, USEC_PER_SEC);
+	timeleft = DIV_ROUND_CLOSEST(timeleft, USEC_PER_SEC);
 
-	if (WARN_ON_ONCE(timeleft > U32_MAX))
-		return U32_MAX;
-
-	return lower_32_bits(timeleft);
+	return timeleft;
 }
 
 static const struct watchdog_ops tegra186_wdt_ops = {

^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [tip: timers/clocksource] clocksource/drivers/timer-tegra186: Avoid 64-bit divide operation
  2025-06-14 17:55 [PATCH 1/2] clocksource/drivers/timer-tegra186: Avoid 64-bit divide operation Guenter Roeck
                   ` (4 preceding siblings ...)
  2025-07-23  7:17 ` [tip: timers/clocksource] " tip-bot2 for Guenter Roeck
@ 2025-07-25 10:31 ` tip-bot2 for Guenter Roeck
  5 siblings, 0 replies; 12+ messages in thread
From: tip-bot2 for Guenter Roeck @ 2025-07-25 10:31 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: Guenter Roeck, Daniel Lezcano, Ingo Molnar, Jon Hunter, Pohsun Su,
	Robert Lin, x86, linux-kernel

The following commit has been merged into the timers/clocksource branch of tip:

Commit-ID:     ed1d4c331f9f161788903885ce9ddfd665bdbe18
Gitweb:        https://git.kernel.org/tip/ed1d4c331f9f161788903885ce9ddfd665bdbe18
Author:        Guenter Roeck <linux@roeck-us.net>
AuthorDate:    Sat, 14 Jun 2025 10:55:55 -07:00
Committer:     Ingo Molnar <mingo@kernel.org>
CommitterDate: Fri, 25 Jul 2025 12:06:28 +02:00

clocksource/drivers/timer-tegra186: Avoid 64-bit divide operation

Building the driver on xtensa fails with:

  tensa-linux-ld: drivers/clocksource/timer-tegra186.o:
	in function `tegra186_timer_remove':
  timer-tegra186.c:(.text+0x350):
	undefined reference to `__udivdi3'

Avoid the problem by rearranging the offending code to avoid the 64-bit
divide operation.

Fixes: 28c842c8b0f5 ("clocksource/drivers/timer-tegra186: Add WDIOC_GETTIMELEFT support")
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Reviewed-by: Jon Hunter <jonathanh@nvidia.com>
Cc: Pohsun Su <pohsuns@nvidia.com>
Cc: Robert Lin <robelin@nvidia.com>
Link: https://lore.kernel.org/r/20250614175556.922159-1-linux@roeck-us.net
---
 drivers/clocksource/timer-tegra186.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/clocksource/timer-tegra186.c b/drivers/clocksource/timer-tegra186.c
index 56a5342..76a5481 100644
--- a/drivers/clocksource/timer-tegra186.c
+++ b/drivers/clocksource/timer-tegra186.c
@@ -267,7 +267,7 @@ static unsigned int tegra186_wdt_get_timeleft(struct watchdog_device *wdd)
 	 * counter value to the time of the counter expirations that
 	 * remain.
 	 */
-	timeleft += (((u64)wdt->base.timeout * USEC_PER_SEC) / 5) * (4 - expiration);
+	timeleft += ((u64)wdt->base.timeout * (USEC_PER_SEC / 5)) * (4 - expiration);
 
 	/*
 	 * Convert the current counter value to seconds,

^ permalink raw reply related	[flat|nested] 12+ messages in thread

end of thread, other threads:[~2025-07-25 10:31 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-06-14 17:55 [PATCH 1/2] clocksource/drivers/timer-tegra186: Avoid 64-bit divide operation Guenter Roeck
2025-06-14 17:55 ` [PATCH 2/2] clocksource/drivers/timer-tegra186: Simplify calculating timeleft Guenter Roeck
2025-06-19  7:25   ` Jon Hunter
2025-07-23  7:17   ` [tip: timers/clocksource] " tip-bot2 for Guenter Roeck
2025-07-25 10:31   ` tip-bot2 for Guenter Roeck
2025-06-19  7:17 ` [PATCH 1/2] clocksource/drivers/timer-tegra186: Avoid 64-bit divide operation Jon Hunter
2025-06-24 14:32 ` Daniel Lezcano
2025-07-03 12:34   ` Jon Hunter
2025-07-03 12:42     ` Daniel Lezcano
2025-07-15 11:11 ` Daniel Lezcano
2025-07-23  7:17 ` [tip: timers/clocksource] " tip-bot2 for Guenter Roeck
2025-07-25 10:31 ` tip-bot2 for Guenter Roeck

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.