Message ID | 20250314160248.502324-1-arnd@kernel.org (mailing list archive) |
---|---|
State | New |
Headers | show |
Series | watchdog: aspeed: fix 64-bit division | expand |
On 3/14/25 09:02, Arnd Bergmann wrote: > From: Arnd Bergmann <arnd@arndb.de> > > On 32-bit architectures, the new calculation causes a build failure: > > ld.lld-21: error: undefined symbol: __aeabi_uldivmod > > Since neither value is ever larger than a register, cast both > sides into a uintptr_t. > > Fixes: 5c03f9f4d362 ("watchdog: aspeed: Update bootstatus handling") > Signed-off-by: Arnd Bergmann <arnd@arndb.de> > --- > drivers/watchdog/aspeed_wdt.c | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > > diff --git a/drivers/watchdog/aspeed_wdt.c b/drivers/watchdog/aspeed_wdt.c > index 369635b38ca0..837e15701c0e 100644 > --- a/drivers/watchdog/aspeed_wdt.c > +++ b/drivers/watchdog/aspeed_wdt.c > @@ -254,7 +254,7 @@ static void aspeed_wdt_update_bootstatus(struct platform_device *pdev, > > if (!of_device_is_compatible(pdev->dev.of_node, "aspeed,ast2400-wdt")) { > res = platform_get_resource(pdev, IORESOURCE_MEM, 0); > - idx = ((intptr_t)wdt->base & 0x00000fff) / resource_size(res); > + idx = ((intptr_t)wdt->base & 0x00000fff) / (uintptr_t)resource_size(res); > } > > scu_base = syscon_regmap_lookup_by_compatible(scu.compatible); Does that help if the pointers are 64-bit on a 32-bit platform (multi_v7_lpae_defconfig) ? Guenter
On Fri, Mar 14, 2025, at 18:37, Guenter Roeck wrote: > On 3/14/25 09:02, Arnd Bergmann wrote: >> >> if (!of_device_is_compatible(pdev->dev.of_node, "aspeed,ast2400-wdt")) { >> res = platform_get_resource(pdev, IORESOURCE_MEM, 0); >> - idx = ((intptr_t)wdt->base & 0x00000fff) / resource_size(res); >> + idx = ((intptr_t)wdt->base & 0x00000fff) / (uintptr_t)resource_size(res); >> } >> >> scu_base = syscon_regmap_lookup_by_compatible(scu.compatible); > Does that help if the pointers are 64-bit on a 32-bit platform > (multi_v7_lpae_defconfig) ? Yes, that is the problem: resource_size() returns a resource_size_t, so this is a 32-bit by 64-bit division. Pointers are always 32-bit, CONFIG_LPAE only changes phys_addr_t and resource_size_t. Arnd
On 3/14/25 10:39, Arnd Bergmann wrote: > On Fri, Mar 14, 2025, at 18:37, Guenter Roeck wrote: >> On 3/14/25 09:02, Arnd Bergmann wrote: >>> >>> if (!of_device_is_compatible(pdev->dev.of_node, "aspeed,ast2400-wdt")) { >>> res = platform_get_resource(pdev, IORESOURCE_MEM, 0); >>> - idx = ((intptr_t)wdt->base & 0x00000fff) / resource_size(res); >>> + idx = ((intptr_t)wdt->base & 0x00000fff) / (uintptr_t)resource_size(res); >>> } >>> >>> scu_base = syscon_regmap_lookup_by_compatible(scu.compatible); >> Does that help if the pointers are 64-bit on a 32-bit platform >> (multi_v7_lpae_defconfig) ? > > Yes, that is the problem: resource_size() returns a resource_size_t, > so this is a 32-bit by 64-bit division. > > Pointers are always 32-bit, CONFIG_LPAE only changes phys_addr_t > and resource_size_t. > Ok. Thanks for the clarification. Guenter
On 3/14/25 09:02, Arnd Bergmann wrote: > From: Arnd Bergmann <arnd@arndb.de> > > On 32-bit architectures, the new calculation causes a build failure: > > ld.lld-21: error: undefined symbol: __aeabi_uldivmod > > Since neither value is ever larger than a register, cast both > sides into a uintptr_t. > > Fixes: 5c03f9f4d362 ("watchdog: aspeed: Update bootstatus handling") > Signed-off-by: Arnd Bergmann <arnd@arndb.de> Reviewed-by: Guenter Roeck <linux@roeck-us.net> > --- > drivers/watchdog/aspeed_wdt.c | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > > diff --git a/drivers/watchdog/aspeed_wdt.c b/drivers/watchdog/aspeed_wdt.c > index 369635b38ca0..837e15701c0e 100644 > --- a/drivers/watchdog/aspeed_wdt.c > +++ b/drivers/watchdog/aspeed_wdt.c > @@ -254,7 +254,7 @@ static void aspeed_wdt_update_bootstatus(struct platform_device *pdev, > > if (!of_device_is_compatible(pdev->dev.of_node, "aspeed,ast2400-wdt")) { > res = platform_get_resource(pdev, IORESOURCE_MEM, 0); > - idx = ((intptr_t)wdt->base & 0x00000fff) / resource_size(res); > + idx = ((intptr_t)wdt->base & 0x00000fff) / (uintptr_t)resource_size(res); > } > > scu_base = syscon_regmap_lookup_by_compatible(scu.compatible);
diff --git a/drivers/watchdog/aspeed_wdt.c b/drivers/watchdog/aspeed_wdt.c index 369635b38ca0..837e15701c0e 100644 --- a/drivers/watchdog/aspeed_wdt.c +++ b/drivers/watchdog/aspeed_wdt.c @@ -254,7 +254,7 @@ static void aspeed_wdt_update_bootstatus(struct platform_device *pdev, if (!of_device_is_compatible(pdev->dev.of_node, "aspeed,ast2400-wdt")) { res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - idx = ((intptr_t)wdt->base & 0x00000fff) / resource_size(res); + idx = ((intptr_t)wdt->base & 0x00000fff) / (uintptr_t)resource_size(res); } scu_base = syscon_regmap_lookup_by_compatible(scu.compatible);