--- zzzz-none-000/linux-4.4.271/arch/mips/include/asm/atomic.h 2021-06-03 06:22:09.000000000 +0000 +++ hawkeye-5590-750/linux-4.4.271/arch/mips/include/asm/atomic.h 2023-04-19 10:22:28.000000000 +0000 @@ -212,6 +212,87 @@ return result; } +/* + * return the incremented value if value < max_value + * if incremented value == max_value so do not write and return -1 + */ +static __inline__ int atomic_inc_with_max_return(atomic_t * v, unsigned int max_value) +{ + int result; + max_value -= 1; /* exclusiv */ + + smp_mb__before_llsc(); + + if (kernel_uses_llsc && R10000_LLSC_WAR) { + panic("atomic_inc_with_max_return not implemented\n"); + } else if (kernel_uses_llsc) { + int temp; + int inc; + + do { + __asm__ __volatile__( + " .set push \n" + " .set mips32r2 \n" + " ll %[temp], %[counter] # atomic_add_return \n" + " sltu %[inc], %[temp], %[max_value] # temp kleiner max_value \n" + " addu %[result], %[temp], %[inc] \n" + " sc %[result], %[counter] \n" + " .set pop \n" + : [inc] "=&r" (inc), [result] "=&r" (result), [temp] "=&r" (temp), [counter] "+m" (v->counter) + : [max_value] "Ir" (max_value) + ); + } while (unlikely(!result)); + if(inc == 0) + result = -1; + else + result = temp + inc; + } else { + panic("atomic_inc_with_max_return not implemented\n"); + } + + smp_llsc_mb(); + + return result; +} + +/* + * return the incremented value if value < max_value + * if incremented value == max_value so write and return zero + */ +static __inline__ int atomic_inc_with_wrap_return(atomic_t * v, unsigned int max_value) +{ + int result; + max_value -= 1; /* exclusiv */ + + smp_mb__before_llsc(); + if (kernel_uses_llsc && R10000_LLSC_WAR) { + panic("atomic_inc_with_max_return not implemented\n"); + } else if (kernel_uses_llsc) { + int temp; + int inc; + + do { + __asm__ __volatile__( + " .set push \n" + " .set mips32r2 \n" + " ll %[temp], %[counter] # atomic_add_return \n" + " sltu %[inc], %[temp], %[max_value] # temp kleiner max_value \n" + " movz %[temp], %[inc], %[inc] \n" + " addu %[result], %[temp], %[inc] \n" + " sc %[result], %[counter] \n" + " .set pop \n" + : [inc] "=&r" (inc), [result] "=&r" (result), [temp] "=&r" (temp), [counter] "+m" (v->counter) + : [max_value] "Ir" (max_value) + ); + } while (unlikely(!result)); + result = temp + inc; + } else { + panic("atomic_inc_with_max_return not implemented\n"); + } + smp_llsc_mb(); + return result; +} + #define atomic_cmpxchg(v, o, n) (cmpxchg(&((v)->counter), (o), (n))) #define atomic_xchg(v, new) (xchg(&((v)->counter), (new)))