Create asm-generic/barrier.h
[firefly-linux-kernel-4.4.55.git] / include / asm-generic / system.h
1 /* Generic system definitions, based on MN10300 definitions.
2  *
3  * It should be possible to use these on really simple architectures,
4  * but it serves more as a starting point for new ports.
5  *
6  * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.
7  * Written by David Howells (dhowells@redhat.com)
8  *
9  * This program is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU General Public Licence
11  * as published by the Free Software Foundation; either version
12  * 2 of the Licence, or (at your option) any later version.
13  */
14 #ifndef __ASM_GENERIC_SYSTEM_H
15 #define __ASM_GENERIC_SYSTEM_H
16
17 #ifndef __ASSEMBLY__
18
19 #include <linux/types.h>
20 #include <linux/irqflags.h>
21
22 #include <asm/barrier.h>
23 #include <asm/cmpxchg.h>
24
25 struct task_struct;
26
27 /* context switching is now performed out-of-line in switch_to.S */
28 extern struct task_struct *__switch_to(struct task_struct *,
29                 struct task_struct *);
30 #define switch_to(prev, next, last)                                     \
31         do {                                                            \
32                 ((last) = __switch_to((prev), (next)));                 \
33         } while (0)
34
35 #define arch_align_stack(x) (x)
36
37 /*
38  * we make sure local_irq_enable() doesn't cause priority inversion
39  */
40
41 /* This function doesn't exist, so you'll get a linker error
42  *    if something tries to do an invalid xchg().  */
43 extern void __xchg_called_with_bad_pointer(void);
44
45 static inline
46 unsigned long __xchg(unsigned long x, volatile void *ptr, int size)
47 {
48         unsigned long ret, flags;
49
50         switch (size) {
51         case 1:
52 #ifdef __xchg_u8
53                 return __xchg_u8(x, ptr);
54 #else
55                 local_irq_save(flags);
56                 ret = *(volatile u8 *)ptr;
57                 *(volatile u8 *)ptr = x;
58                 local_irq_restore(flags);
59                 return ret;
60 #endif /* __xchg_u8 */
61
62         case 2:
63 #ifdef __xchg_u16
64                 return __xchg_u16(x, ptr);
65 #else
66                 local_irq_save(flags);
67                 ret = *(volatile u16 *)ptr;
68                 *(volatile u16 *)ptr = x;
69                 local_irq_restore(flags);
70                 return ret;
71 #endif /* __xchg_u16 */
72
73         case 4:
74 #ifdef __xchg_u32
75                 return __xchg_u32(x, ptr);
76 #else
77                 local_irq_save(flags);
78                 ret = *(volatile u32 *)ptr;
79                 *(volatile u32 *)ptr = x;
80                 local_irq_restore(flags);
81                 return ret;
82 #endif /* __xchg_u32 */
83
84 #ifdef CONFIG_64BIT
85         case 8:
86 #ifdef __xchg_u64
87                 return __xchg_u64(x, ptr);
88 #else
89                 local_irq_save(flags);
90                 ret = *(volatile u64 *)ptr;
91                 *(volatile u64 *)ptr = x;
92                 local_irq_restore(flags);
93                 return ret;
94 #endif /* __xchg_u64 */
95 #endif /* CONFIG_64BIT */
96
97         default:
98                 __xchg_called_with_bad_pointer();
99                 return x;
100         }
101 }
102
103 #define xchg(ptr, x) \
104         ((__typeof__(*(ptr))) __xchg((unsigned long)(x), (ptr), sizeof(*(ptr))))
105
106 #endif /* !__ASSEMBLY__ */
107
108 #endif /* __ASM_GENERIC_SYSTEM_H */