[U-Boot] [RFC PATCH v1] mips: add atomic operations

Stefan sr at denx.de
Fri Sep 7 10:24:16 UTC 2018


Hi Chris,

(added Daniel)

On 07.09.2018 10:24, Chris Packham wrote:
> Add mips version of atomic.h and basic atomic operations. These aren't
> the optimised versions from the Linux kernel, just basic stubs that
> satisfy users that need something to define atomic_inc() etc.
> 
> Signed-off-by: Chris Packham <judge.packham at gmail.com>
> 
> ---
> At $dayjob we have a mips target that we want to run UBIFS on. UBIFS
> requires atomic.h. This is my naive attempt to supply enough of atomic.h
> to satisfy UBIFS.
> 
> It's no coincidence that this looks like the arm version. I am
> wondering if it's worth a asm-generic version leaving architectures that
> actually need true atomic operations able to define them.

I did a pretty similar job and copied the files from xtensa a few
weeks ago:

https://patchwork.ozlabs.org/patch/958286/

It would be better of course, to have some generic version of this
file. But frankly, I don't have the time right now for this.

Thanks,
Stefan
  
>   arch/mips/include/asm/atomic.h | 151 +++++++++++++++++++++++++++++++++
>   1 file changed, 151 insertions(+)
>   create mode 100644 arch/mips/include/asm/atomic.h
> 
> diff --git a/arch/mips/include/asm/atomic.h b/arch/mips/include/asm/atomic.h
> new file mode 100644
> index 000000000000..3ab5684fdef4
> --- /dev/null
> +++ b/arch/mips/include/asm/atomic.h
> @@ -0,0 +1,151 @@
> +/* SPDX-License-Identifier: GPL-2.0+ */
> +#ifndef _ASM_ATOMIC_H
> +#define _ASM_ATOMIC_H
> +
> +#include <asm/system.h>
> +
> +typedef struct { volatile int counter; } atomic_t;
> +#if BITS_PER_LONG == 32
> +typedef struct { volatile long long counter; } atomic64_t;
> +#else /* BIT_PER_LONG == 32 */
> +typedef struct { volatile long counter; } atomic64_t;
> +#endif
> +
> +#define ATOMIC_INIT(i)	  { (i) }
> +
> +#define atomic_read(v)	((v)->counter)
> +#define atomic_set(v, i)	(((v)->counter) = (i))
> +#define atomic64_read(v)	atomic_read(v)
> +#define atomic64_set(v, i)	atomic_set(v, i)
> +
> +static inline void atomic_add(int i, volatile atomic_t *v)
> +{
> +	unsigned long flags = 0;
> +
> +	local_irq_save(flags);
> +	v->counter += i;
> +	local_irq_restore(flags);
> +}
> +
> +static inline void atomic_sub(int i, volatile atomic_t *v)
> +{
> +	unsigned long flags = 0;
> +
> +	local_irq_save(flags);
> +	v->counter -= i;
> +	local_irq_restore(flags);
> +}
> +
> +static inline void atomic_inc(volatile atomic_t *v)
> +{
> +	unsigned long flags = 0;
> +
> +	local_irq_save(flags);
> +	v->counter += 1;
> +	local_irq_restore(flags);
> +}
> +
> +static inline void atomic_dec(volatile atomic_t *v)
> +{
> +	unsigned long flags = 0;
> +
> +	local_irq_save(flags);
> +	v->counter -= 1;
> +	local_irq_restore(flags);
> +}
> +
> +static inline int atomic_dec_and_test(volatile atomic_t *v)
> +{
> +	unsigned long flags = 0;
> +	int val;
> +
> +	local_irq_save(flags);
> +	val = v->counter;
> +	v->counter = val -= 1;
> +	local_irq_restore(flags);
> +
> +	return val == 0;
> +}
> +
> +static inline int atomic_add_negative(int i, volatile atomic_t *v)
> +{
> +	unsigned long flags = 0;
> +	int val;
> +
> +	local_irq_save(flags);
> +	val = v->counter;
> +	v->counter = val += i;
> +	local_irq_restore(flags);
> +
> +	return val < 0;
> +}
> +
> +static inline void atomic_clear_mask(unsigned long mask, unsigned long *addr)
> +{
> +	unsigned long flags = 0;
> +
> +	local_irq_save(flags);
> +	*addr &= ~mask;
> +	local_irq_restore(flags);
> +}
> +
> +#if BITS_PER_LONG == 32
> +
> +static inline void atomic64_add(long long i, volatile atomic64_t *v)
> +{
> +	unsigned long flags = 0;
> +
> +	local_irq_save(flags);
> +	v->counter += i;
> +	local_irq_restore(flags);
> +}
> +
> +static inline void atomic64_sub(long long i, volatile atomic64_t *v)
> +{
> +	unsigned long flags = 0;
> +
> +	local_irq_save(flags);
> +	v->counter -= i;
> +	local_irq_restore(flags);
> +}
> +
> +#else /* BIT_PER_LONG == 32 */
> +
> +static inline void atomic64_add(long i, volatile atomic64_t *v)
> +{
> +	unsigned long flags = 0;
> +
> +	local_irq_save(flags);
> +	v->counter += i;
> +	local_irq_restore(flags);
> +}
> +
> +static inline void atomic64_sub(long i, volatile atomic64_t *v)
> +{
> +	unsigned long flags = 0;
> +
> +	local_irq_save(flags);
> +	v->counter -= i;
> +	local_irq_restore(flags);
> +}
> +#endif /* BIT_PER_LONG == 32 */
> +
> +static inline void atomic64_inc(volatile atomic64_t *v)
> +{
> +	unsigned long flags = 0;
> +
> +	local_irq_save(flags);
> +	v->counter += 1;
> +	local_irq_restore(flags);
> +}
> +
> +static inline void atomic64_dec(volatile atomic64_t *v)
> +{
> +	unsigned long flags = 0;
> +
> +	local_irq_save(flags);
> +	v->counter -= 1;
> +	local_irq_restore(flags);
> +}
> +
> +#endif
> 



More information about the U-Boot mailing list