* [U-Boot] [RFC PATCH v1] mips: add atomic operations
@ 2018-09-07 8:24 Chris Packham
2018-09-07 10:24 ` Stefan
0 siblings, 1 reply; 3+ messages in thread
From: Chris Packham @ 2018-09-07 8:24 UTC (permalink / raw)
To: u-boot
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@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.
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
--
2.18.0
^ permalink raw reply related [flat|nested] 3+ messages in thread
* [U-Boot] [RFC PATCH v1] mips: add atomic operations
2018-09-07 8:24 [U-Boot] [RFC PATCH v1] mips: add atomic operations Chris Packham
@ 2018-09-07 10:24 ` Stefan
2018-09-07 12:08 ` Chris Packham
0 siblings, 1 reply; 3+ messages in thread
From: Stefan @ 2018-09-07 10:24 UTC (permalink / raw)
To: u-boot
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@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
>
^ permalink raw reply [flat|nested] 3+ messages in thread
* [U-Boot] [RFC PATCH v1] mips: add atomic operations
2018-09-07 10:24 ` Stefan
@ 2018-09-07 12:08 ` Chris Packham
0 siblings, 0 replies; 3+ messages in thread
From: Chris Packham @ 2018-09-07 12:08 UTC (permalink / raw)
To: u-boot
On Fri, 7 Sep 2018, 10:24 PM Stefan, <sr@denx.de> wrote:
> 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@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/
Weird coincidence. I figured noone had needed ubifs on mips since the need
for atomic.h has been there for a while.
I'm more than happy for your version to go in since it's part of a bigger
series. The only thing missing is 64 bit support (our platform happens to
be mips64) but i don't think ubifs cares.
> 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.
>
Given that the arm, xtensa and now mips are so similar it's probably worth
it. I'll see if i can find some cycles to spend on it.
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2018-09-07 12:08 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2018-09-07 8:24 [U-Boot] [RFC PATCH v1] mips: add atomic operations Chris Packham
2018-09-07 10:24 ` Stefan
2018-09-07 12:08 ` Chris Packham
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox