Change to use "do_div" macro
PATCH 1/1 Change to use "do_div" macro
I tryed to build u-boot by Sourcery G++ Lite 2008q3-41 for ARM GNU/Linux. But, it was failed with some link error of divide function. Thus, I changed to use the "do_div" macro to calculate the dividing.
In my environment, the "next" branch with this patch worked correctly.
----
Change to use the "do_div" macro.
cpu/arm1136/mx31/interrupts.c | 36 ++++++++++++++++++++++++++++++------ 1 files changed, 30 insertions(+), 6 deletions(-)
cpu/arm1136/mx31/interrupts.c +30 -6
@@ -23,6 +23,7 @@#include <common.h> #include <asm/arch/mx31-regs.h> +#include <div64.h> #define TIMER_BASE 0x53f90000/* General purpose timer 1 */
@@ -41,17 +42,40 @@/* "time" is measured in 1 / CONFIG_SYS_HZ seconds, "tick" is internal timer period */ #ifdef CONFIG_MX31_TIMER_HIGH_PRECISION /* ~0.4% error - measured with stop-watch on 100s boot-delay */ -#define TICK_TO_TIME (t) ((t) * CONFIG_SYS_HZ / CONFIG_MX31_CLK32) -#define TIME_TO_TICK (t) ((unsigned long long)(t) * CONFIG_MX31_CLK32 / CONFIG_SYS_HZ) -#define US_TO_TICK (t) (((unsigned long long)(t) * CONFIG_MX31_CLK32 + \ - 999999) / 1000000) +#define TICK_TO_TIME (t) ({ \ + unsigned long long tmp = (t); \ + t *= CONFIG_SYS_HZ; \ + do_div(tmp, CONFIG_MX31_CLK32); \ + tmp; \ + }) +#define TIME_TO_TICK (t) ({ \ + unsigned long long tmp = (t); \ + tmp *= CONFIG_MX31_CLK32; \ + do_div(tmp, CONFIG_SYS_HZ); \ + tmp; \ + }) +#define US_TO_TICK (t) ({ \ + unsigned long long tmp = (t); \ + tmp = tmp * CONFIG_MX31_CLK32 + 999999; \ + do_div(tmp, 1000000); \ + tmp; \ + })#else /* ~2% error */ #define TICK_PER_TIME ((CONFIG_MX31_CLK32 + CONFIG_SYS_HZ / 2) / CONFIG_SYS_HZ)#define US_PER_TICK (1000000 / CONFIG_MX31_CLK32) -#define TICK_TO_TIME (t) ((t) / TICK_PER_TIME) +#define TICK_TO_TIME (t) ({ \ + unsigned long long tmp = (t); \ + do_div(tmp, TICK_PER_TIME); \ + tmp; \ + })#define TIME_TO_TICK (t) ((unsigned long long)(t) * TICK_PER_TIME) -#define US_TO_TICK (t) (((t) + US_PER_TICK - 1) / US_PER_TICK) +#define US_TO_TICK (t) ({ \ + unsigned long long tmp = (t); \ + tmp += US_PER_TICK - 1; \ + do_div(tmp, US_PER_TICK); \ + tmp; \ + })#endif static ulong timestamp;
PATCH 1/1 Change to use "do_div" macro
Quoted 29 lines · Tomohiro Masubuchi
I tryed to build u-boot by Sourcery G++ Lite 2008q3-41 for ARM GNU/Linux. But, it was failed with some link error of divide function. Thus, I changed to use the "
do_div" macro to calculate the dividing.In my environment, the "next" branch with this patch worked correctly.
Signed-off-by Tomohiro Masubuchi <[email protected]>----
Change to use the "do_div" macro.cpu/arm1136/mx31/interrupts.c | 36 ++++++++++++++++++++++++++++++------ 1 files changed, 30 insertions(+), 6 deletions(-)cpu/arm1136/mx31/interrupts.c +1
-0@@ -23,6 +23,7 @@#include <common.h> #include <asm/arch/mx31-regs.h> +#include <div64.h> #define TIMER_BASE 0x53f90000/* General purpose timer 1 */ @@ -41,17 +42,40 @@/* "time" is measured in 1 / CONFIG_SYS_HZ seconds, "tick" is internal timer period */ #ifdef CONFIG_MX31_TIMER_HIGH_PRECISION /* ~0.4% error - measured with stop-watch on 100s boot-delay */
cpu/arm1136/mx31/interrupts.c line 50
Quoted 10 lines
cpu/arm1136/mx31/interrupts.c +6
-4-#define TICK_TO_TIME (t) ((t) * CONFIG_SYS_HZ / CONFIG_MX31_CLK32) -#define TIME_TO_TICK (t) ((unsigned long long)(t) * CONFIG_MX31_CLK32 / CONFIG_SYS_HZ) -#define US_TO_TICK (t) (((unsigned long long)(t) * CONFIG_MX31_CLK32 + \ - 999999) / 1000000) +#define TICK_TO_TIME (t) ({ \ + unsigned long long tmp = (t); \ + t *= CONFIG_SYS_HZ; \ + do_div(tmp, CONFIG_MX31_CLK32); \ + tmp; \ + })
IMHO implement it as inline will be better : simple to maintain and to read
Best Regards,
J.
PATCH v2 1/1 Change to use "do_div" macro
Hi,
I've fixed which Jean-Christophe pointed out.
Regards,
Tomohiro
----
Change to use the "do_div" macro.
cpu/arm1136/mx31/interrupts.c | 58 +++++++++++++++++++++++++++++++--------- 1 files changed, 45 insertions(+), 13 deletions(-)
cpu/arm1136/mx31/interrupts.c +45 -13
@@ -23,6 +23,7 @@#include <common.h> #include <asm/arch/mx31-regs.h> +#include <div64.h> #define TIMER_BASE 0x53f90000/* General purpose timer 1 */
@@ -38,24 +39,55 @@#define GPTCR_CLKSOURCE_32 (4 << 6)/* Clock source */ #define GPTCR_TEN 1/* Timer enable */ +static ulong timestamp; +static ulong lastinc; +/* "time" is measured in 1 / CONFIG_SYS_HZ seconds, "tick" is internal timer period */ #ifdef CONFIG_MX31_TIMER_HIGH_PRECISION /* ~0.4% error - measured with stop-watch on 100s boot-delay */ -#define TICK_TO_TIME (t) ((t) * CONFIG_SYS_HZ / CONFIG_MX31_CLK32) -#define TIME_TO_TICK (t) ((unsigned long long)(t) * CONFIG_MX31_CLK32 / CONFIG_SYS_HZ) -#define US_TO_TICK (t) (((unsigned long long)(t) * CONFIG_MX31_CLK32 + \ - 999999) / 1000000) +static inline unsigned long long tick_to_time (unsigned long long tick) +{ + tick *=CONFIG_SYS_HZ ; +do_div (tick,CONFIG_MX31_CLK32 ); +return tick; +} + +static inline unsigned long long time_to_tick (unsigned long long time) +{ + time *=CONFIG_MX31_CLK32 ; +do_div (time,CONFIG_SYS_HZ ); +return time; +} + +static inline unsigned long long us_to_tick (unsigned long long us) +{ + us = us *CONFIG_MX31_CLK32 +999999 ; +do_div (us,1000000 ); +return us; +}#else /* ~2% error */ #define TICK_PER_TIME ((CONFIG_MX31_CLK32 + CONFIG_SYS_HZ / 2) / CONFIG_SYS_HZ)#define US_PER_TICK (1000000 / CONFIG_MX31_CLK32) -#define TICK_TO_TIME (t) ((t) / TICK_PER_TIME) -#define TIME_TO_TICK (t) ((unsigned long long)(t) * TICK_PER_TIME) -#define US_TO_TICK (t) (((t) + US_PER_TICK - 1) / US_PER_TICK) -#endif -static ulong timestamp; -static ulong lastinc; +static inline unsigned long long tick_to_time (unsigned long long tick) +{ +do_div (tick,TICK_PER_TIME ); +return tick; +} + +static inline unsigned long long time_to_tick (unsigned long long time) +{ +return time *TICK_PER_TIME ; +} + +static inline unsigned long long us_to_tick (unsigned long long us) +{ + us +=US_PER_TICK -1 ; +do_div (us,US_PER_TICK ); +return us; +} +#endif /* nothing really to do with interrupts, just starts up a counter. */ /* The 32768Hz 32-bit timer overruns in 131072 seconds */
@@ -107,7 +139,7 @@ ulong get_timer_masked (void)* 5 * 10^9 days... and get_ticks() * CONFIG_SYS_HZ wraps in * 5 * 10^6 days - long enough. */ -return TICK_TO_TIME (get_ticks ()); +return tick_to_time (get_ticks ()); }ulong get_timer (ulong base)
@@ -117,7 +149,7 @@ ulong get_timer (ulong base)void set_timer (ulong t) { - timestamp =TIME_TO_TICK (t); + timestamp =time_to_tick (t); }/* delay x useconds AND perserve advance timstamp value */
@@ -126,7 +158,7 @@ void udelay (unsigned long usec)unsigned long long tmp;ulong tmo; - tmo =US_TO_TICK (usec); + tmo =us_to_tick (usec); tmp =get_ticks () + tmo;/* get current timestamp */ while (get_ticks () < tmp)/* loop till event */