--- zzzz-none-000/linux-3.10.107/arch/xtensa/include/asm/delay.h 2017-06-27 09:49:32.000000000 +0000 +++ scorpion-7490-727/linux-3.10.107/arch/xtensa/include/asm/delay.h 2021-02-04 17:41:59.000000000 +0000 @@ -12,37 +12,64 @@ #ifndef _XTENSA_DELAY_H #define _XTENSA_DELAY_H -#include +#include #include extern unsigned long loops_per_jiffy; static inline void __delay(unsigned long loops) { - /* 2 cycles per loop. */ - __asm__ __volatile__ ("1: addi %0, %0, -2; bgeui %0, 2, 1b" - : "=r" (loops) : "0" (loops)); + if (__builtin_constant_p(loops) && loops < 2) + __asm__ __volatile__ ("nop"); + else if (loops >= 2) + /* 2 cycles per loop. */ + __asm__ __volatile__ ("1: addi %0, %0, -2; bgeui %0, 2, 1b" + : "+r" (loops)); } -static __inline__ u32 xtensa_get_ccount(void) +/* Undefined function to get compile-time error */ +void __bad_udelay(void); +void __bad_ndelay(void); + +#define __MAX_UDELAY 30000 +#define __MAX_NDELAY 30000 + +static inline void __udelay(unsigned long usecs) { - u32 ccount; - asm volatile ("rsr %0, ccount\n" : "=r" (ccount)); - return ccount; + unsigned long start = get_ccount(); + unsigned long cycles = (usecs * (ccount_freq >> 15)) >> 5; + + /* Note: all variables are unsigned (can wrap around)! */ + while (((unsigned long)get_ccount()) - start < cycles) + cpu_relax(); } -/* For SMP/NUMA systems, change boot_cpu_data to something like - * local_cpu_data->... where local_cpu_data points to the current - * cpu. */ +static inline void udelay(unsigned long usec) +{ + if (__builtin_constant_p(usec) && usec >= __MAX_UDELAY) + __bad_udelay(); + else + __udelay(usec); +} -static __inline__ void udelay (unsigned long usecs) +static inline void __ndelay(unsigned long nsec) { - unsigned long start = xtensa_get_ccount(); - unsigned long cycles = usecs * (loops_per_jiffy / (1000000UL / HZ)); + /* + * Inner shift makes sure multiplication doesn't overflow + * for legitimate nsec values + */ + unsigned long cycles = (nsec * (ccount_freq >> 15)) >> 15; + __delay(cycles); +} - /* Note: all variables are unsigned (can wrap around)! */ - while (((unsigned long)xtensa_get_ccount()) - start < cycles) - ; +#define ndelay(n) ndelay(n) + +static inline void ndelay(unsigned long nsec) +{ + if (__builtin_constant_p(nsec) && nsec >= __MAX_NDELAY) + __bad_ndelay(); + else + __ndelay(nsec); } #endif