aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2017-07-08 15:14:14 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2017-07-08 15:14:14 -0400
commitfe1b518075d86976db3a93e7e8b640d24d477519 (patch)
treee4d98d18c4637d85d279d0600afb7cac6a1759f0
parent8b6b3172ce02aef147f74b32ea11796c580f795c (diff)
parent0cd52df8a782be2e6592d331094a313d8947683a (diff)
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/sparc-next
Pull sparc updates from David Miller: 1) Queued spinlocks and rwlocks for sparc64, from Babu Moger. 2) Some const'ification from Arvind Yadav. 3) LDC/VIO driver infrastructure changes to facilitate future upcoming drivers, from Jag Raman. 4) Initialize sched_clock() et al. early so that the initial printk timestamps are all done while the implementation is available and functioning. From Pavel Tatashin. * git://git.kernel.org/pub/scm/linux/kernel/git/davem/sparc-next: (38 commits) sparc: kernel: pmc: make of_device_ids const. sparc64: fix typo in property sparc64: add port_id to VIO device metadata sparc64: Enhance search for VIO device in MDESC sparc64: enhance VIO device probing sparc64: check if a client is allowed to register for MDESC notifications sparc64: remove restriction on VIO device name size sparc64: refactor code to obtain cfg_handle property from MDESC sparc64: add MDESC node name property to VIO device metadata sparc64: mdesc: use __GFP_REPEAT action modifier for VM allocation sparc64: expand MDESC interface sparc64: skip handshake for LDC channels in RAW mode sparc64: specify the device class in VIO version info. packet sparc64: ensure VIO operations are defined while being used sparc: kernel: apc: make of_device_ids const sparc/time: make of_device_ids const sparc64: broken %tick frequency on spitfire cpus sparc64: use prom interface to get %stick frequency sparc64: optimize functions that access tick sparc64: add hot-patched and inlined get_tick() ...
-rw-r--r--arch/sparc/Kconfig5
-rw-r--r--arch/sparc/include/asm/cmpxchg_64.h76
-rw-r--r--arch/sparc/include/asm/ldc.h8
-rw-r--r--arch/sparc/include/asm/mdesc.h24
-rw-r--r--arch/sparc/include/asm/qrwlock.h7
-rw-r--r--arch/sparc/include/asm/qspinlock.h7
-rw-r--r--arch/sparc/include/asm/setup.h2
-rw-r--r--arch/sparc/include/asm/spinlock_64.h208
-rw-r--r--arch/sparc/include/asm/spinlock_types.h12
-rw-r--r--arch/sparc/include/asm/timer_64.h67
-rw-r--r--arch/sparc/include/asm/vio.h13
-rw-r--r--arch/sparc/kernel/apc.c2
-rw-r--r--arch/sparc/kernel/kernel.h3
-rw-r--r--arch/sparc/kernel/ldc.c151
-rw-r--r--arch/sparc/kernel/mdesc.c331
-rw-r--r--arch/sparc/kernel/pmc.c2
-rw-r--r--arch/sparc/kernel/prom_64.c2
-rw-r--r--arch/sparc/kernel/setup_64.c7
-rw-r--r--arch/sparc/kernel/time_32.c2
-rw-r--r--arch/sparc/kernel/time_64.c179
-rw-r--r--arch/sparc/kernel/vio.c244
-rw-r--r--arch/sparc/kernel/viohs.c24
-rw-r--r--arch/sparc/kernel/vmlinux.lds.S5
-rw-r--r--kernel/locking/qrwlock.c1
24 files changed, 890 insertions, 492 deletions
diff --git a/arch/sparc/Kconfig b/arch/sparc/Kconfig
index 5639c9fe5b55..a4a626199c47 100644
--- a/arch/sparc/Kconfig
+++ b/arch/sparc/Kconfig
@@ -83,6 +83,8 @@ config SPARC64
83 select ARCH_SUPPORTS_ATOMIC_RMW 83 select ARCH_SUPPORTS_ATOMIC_RMW
84 select HAVE_NMI 84 select HAVE_NMI
85 select HAVE_REGS_AND_STACK_ACCESS_API 85 select HAVE_REGS_AND_STACK_ACCESS_API
86 select ARCH_USE_QUEUED_RWLOCKS
87 select ARCH_USE_QUEUED_SPINLOCKS
86 88
87config ARCH_DEFCONFIG 89config ARCH_DEFCONFIG
88 string 90 string
@@ -92,6 +94,9 @@ config ARCH_DEFCONFIG
92config ARCH_PROC_KCORE_TEXT 94config ARCH_PROC_KCORE_TEXT
93 def_bool y 95 def_bool y
94 96
97config CPU_BIG_ENDIAN
98 def_bool y
99
95config ARCH_ATU 100config ARCH_ATU
96 bool 101 bool
97 default y if SPARC64 102 default y if SPARC64
diff --git a/arch/sparc/include/asm/cmpxchg_64.h b/arch/sparc/include/asm/cmpxchg_64.h
index faa2f61058c2..4028f4f1e561 100644
--- a/arch/sparc/include/asm/cmpxchg_64.h
+++ b/arch/sparc/include/asm/cmpxchg_64.h
@@ -6,6 +6,17 @@
6#ifndef __ARCH_SPARC64_CMPXCHG__ 6#ifndef __ARCH_SPARC64_CMPXCHG__
7#define __ARCH_SPARC64_CMPXCHG__ 7#define __ARCH_SPARC64_CMPXCHG__
8 8
9static inline unsigned long
10__cmpxchg_u32(volatile int *m, int old, int new)
11{
12 __asm__ __volatile__("cas [%2], %3, %0"
13 : "=&r" (new)
14 : "0" (new), "r" (m), "r" (old)
15 : "memory");
16
17 return new;
18}
19
9static inline unsigned long xchg32(__volatile__ unsigned int *m, unsigned int val) 20static inline unsigned long xchg32(__volatile__ unsigned int *m, unsigned int val)
10{ 21{
11 unsigned long tmp1, tmp2; 22 unsigned long tmp1, tmp2;
@@ -44,10 +55,38 @@ static inline unsigned long xchg64(__volatile__ unsigned long *m, unsigned long
44 55
45void __xchg_called_with_bad_pointer(void); 56void __xchg_called_with_bad_pointer(void);
46 57
58/*
59 * Use 4 byte cas instruction to achieve 2 byte xchg. Main logic
60 * here is to get the bit shift of the byte we are interested in.
61 * The XOR is handy for reversing the bits for big-endian byte order.
62 */
63static inline unsigned long
64xchg16(__volatile__ unsigned short *m, unsigned short val)
65{
66 unsigned long maddr = (unsigned long)m;
67 int bit_shift = (((unsigned long)m & 2) ^ 2) << 3;
68 unsigned int mask = 0xffff << bit_shift;
69 unsigned int *ptr = (unsigned int *) (maddr & ~2);
70 unsigned int old32, new32, load32;
71
72 /* Read the old value */
73 load32 = *ptr;
74
75 do {
76 old32 = load32;
77 new32 = (load32 & (~mask)) | val << bit_shift;
78 load32 = __cmpxchg_u32(ptr, old32, new32);
79 } while (load32 != old32);
80
81 return (load32 & mask) >> bit_shift;
82}
83
47static inline unsigned long __xchg(unsigned long x, __volatile__ void * ptr, 84static inline unsigned long __xchg(unsigned long x, __volatile__ void * ptr,
48 int size) 85 int size)
49{ 86{
50 switch (size) { 87 switch (size) {
88 case 2:
89 return xchg16(ptr, x);
51 case 4: 90 case 4:
52 return xchg32(ptr, x); 91 return xchg32(ptr, x);
53 case 8: 92 case 8:
@@ -65,10 +104,11 @@ static inline unsigned long __xchg(unsigned long x, __volatile__ void * ptr,
65 104
66#include <asm-generic/cmpxchg-local.h> 105#include <asm-generic/cmpxchg-local.h>
67 106
107
68static inline unsigned long 108static inline unsigned long
69__cmpxchg_u32(volatile int *m, int old, int new) 109__cmpxchg_u64(volatile long *m, unsigned long old, unsigned long new)
70{ 110{
71 __asm__ __volatile__("cas [%2], %3, %0" 111 __asm__ __volatile__("casx [%2], %3, %0"
72 : "=&r" (new) 112 : "=&r" (new)
73 : "0" (new), "r" (m), "r" (old) 113 : "0" (new), "r" (m), "r" (old)
74 : "memory"); 114 : "memory");
@@ -76,15 +116,31 @@ __cmpxchg_u32(volatile int *m, int old, int new)
76 return new; 116 return new;
77} 117}
78 118
119/*
120 * Use 4 byte cas instruction to achieve 1 byte cmpxchg. Main logic
121 * here is to get the bit shift of the byte we are interested in.
122 * The XOR is handy for reversing the bits for big-endian byte order
123 */
79static inline unsigned long 124static inline unsigned long
80__cmpxchg_u64(volatile long *m, unsigned long old, unsigned long new) 125__cmpxchg_u8(volatile unsigned char *m, unsigned char old, unsigned char new)
81{ 126{
82 __asm__ __volatile__("casx [%2], %3, %0" 127 unsigned long maddr = (unsigned long)m;
83 : "=&r" (new) 128 int bit_shift = (((unsigned long)m & 3) ^ 3) << 3;
84 : "0" (new), "r" (m), "r" (old) 129 unsigned int mask = 0xff << bit_shift;
85 : "memory"); 130 unsigned int *ptr = (unsigned int *) (maddr & ~3);
86 131 unsigned int old32, new32, load;
87 return new; 132 unsigned int load32 = *ptr;
133
134 do {
135 new32 = (load32 & ~mask) | (new << bit_shift);
136 old32 = (load32 & ~mask) | (old << bit_shift);
137 load32 = __cmpxchg_u32(ptr, old32, new32);
138 if (load32 == old32)
139 return old;
140 load = (load32 & mask) >> bit_shift;
141 } while (load == old);
142
143 return load;
88} 144}
89 145
90/* This function doesn't exist, so you'll get a linker error 146/* This function doesn't exist, so you'll get a linker error
@@ -95,6 +151,8 @@ static inline unsigned long
95__cmpxchg(volatile void *ptr, unsigned long old, unsigned long new, int size) 151__cmpxchg(volatile void *ptr, unsigned long old, unsigned long new, int size)
96{ 152{
97 switch (size) { 153 switch (size) {
154 case 1:
155 return __cmpxchg_u8(ptr, old, new);
98 case 4: 156 case 4:
99 return __cmpxchg_u32(ptr, old, new); 157 return __cmpxchg_u32(ptr, old, new);
100 case 8: 158 case 8:
diff --git a/arch/sparc/include/asm/ldc.h b/arch/sparc/include/asm/ldc.h
index 6e9004aa6f25..698738a10414 100644
--- a/arch/sparc/include/asm/ldc.h
+++ b/