[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