aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJayachandran C <jchandra@broadcom.com>2013-03-23 13:27:57 -0400
committerRalf Baechle <ralf@linux-mips.org>2013-05-07 19:19:05 -0400
commit1ad4af852bc3b352ac36ceffd2e30dbba413bc1a (patch)
tree0b5791f08708f54b14bee1be76a089d75e13bfab
parent3c0553e7347a96519ea232a9235dfb0eb1c6d3ec (diff)
MIPS: Netlogic: Add 32-bit support for XLP
Update asm/netlogic/haldefs.h to extend register access functions nlm_{read,write}_reg64() for 32-bit compilation. When compiled for 32-bit the functions will read 64 IO registers with interrupts disabled. Signed-off-by: Jayachandran C <jchandra@broadcom.com> Patchwork: http://patchwork.linux-mips.org/patch/5026/ Acked-by: John Crispin <blogic@openwrt.org>
-rw-r--r--arch/mips/include/asm/netlogic/haldefs.h56
1 files changed, 50 insertions, 6 deletions
diff --git a/arch/mips/include/asm/netlogic/haldefs.h b/arch/mips/include/asm/netlogic/haldefs.h
index 419d8aef8569..61fecb85e66f 100644
--- a/arch/mips/include/asm/netlogic/haldefs.h
+++ b/arch/mips/include/asm/netlogic/haldefs.h
@@ -35,14 +35,13 @@
35#ifndef __NLM_HAL_HALDEFS_H__ 35#ifndef __NLM_HAL_HALDEFS_H__
36#define __NLM_HAL_HALDEFS_H__ 36#define __NLM_HAL_HALDEFS_H__
37 37
38#include <linux/irqflags.h> /* for local_irq_disable */
39
38/* 40/*
39 * This file contains platform specific memory mapped IO implementation 41 * This file contains platform specific memory mapped IO implementation
40 * and will provide a way to read 32/64 bit memory mapped registers in 42 * and will provide a way to read 32/64 bit memory mapped registers in
41 * all ABIs 43 * all ABIs
42 */ 44 */
43#if !defined(CONFIG_64BIT) && defined(CONFIG_CPU_XLP)
44#error "o32 compile not supported on XLP yet"
45#endif
46/* 45/*
47 * For o32 compilation, we have to disable interrupts and enable KX bit to 46 * For o32 compilation, we have to disable interrupts and enable KX bit to
48 * access 64 bit addresses or data. 47 * access 64 bit addresses or data.
@@ -87,13 +86,40 @@ nlm_write_reg(uint64_t base, uint32_t reg, uint32_t val)
87 *addr = val; 86 *addr = val;
88} 87}
89 88
89/*
90 * For o32 compilation, we have to disable interrupts to access 64 bit
91 * registers
92 *
93 * We need to disable interrupts because we save just the lower 32 bits of
94 * registers in interrupt handling. So if we get hit by an interrupt while
95 * using the upper 32 bits of a register, we lose.
96 */
97
90static inline uint64_t 98static inline uint64_t
91nlm_read_reg64(uint64_t base, uint32_t reg) 99nlm_read_reg64(uint64_t base, uint32_t reg)
92{ 100{
93 uint64_t addr = base + (reg >> 1) * sizeof(uint64_t); 101 uint64_t addr = base + (reg >> 1) * sizeof(uint64_t);
94 volatile uint64_t *ptr = (volatile uint64_t *)(long)addr; 102 volatile uint64_t *ptr = (volatile uint64_t *)(long)addr;
95 103 uint64_t val;
96 return *ptr; 104
105 if (sizeof(unsigned long) == 4) {
106 unsigned long flags;
107
108 local_irq_save(flags);
109 __asm__ __volatile__(
110 ".set push" "\n\t"
111 ".set mips64" "\n\t"
112 "ld %L0, %1" "\n\t"
113 "dsra32 %M0, %L0, 0" "\n\t"
114 "sll %L0, %L0, 0" "\n\t"
115 ".set pop" "\n"
116 : "=r" (val)
117 : "m" (*ptr));
118 local_irq_restore(flags);
119 } else
120 val = *ptr;
121
122 return val;
97} 123}
98 124
99static inline void 125static inline void
@@ -102,7 +128,25 @@ nlm_write_reg64(uint64_t base, uint32_t reg, uint64_t val)
102 uint64_t addr = base + (reg >> 1) * sizeof(uint64_t); 128 uint64_t addr = base + (reg >> 1) * sizeof(uint64_t);
103 volatile uint64_t *ptr = (volatile uint64_t *)(long)addr; 129 volatile uint64_t *ptr = (volatile uint64_t *)(long)addr;
104 130
105 *ptr = val; 131 if (sizeof(unsigned long) == 4) {
132 unsigned long flags;
133 uint64_t tmp;
134
135 local_irq_save(flags);
136 __asm__ __volatile__(
137 ".set push" "\n\t"
138 ".set mips64" "\n\t"
139 "dsll32 %L0, %L0, 0" "\n\t"
140 "dsrl32 %L0, %L0, 0" "\n\t"
141 "dsll32 %M0, %M0, 0" "\n\t"
142 "or %L0, %L0, %M0" "\n\t"
143 "sd %L0, %2" "\n\t"
144 ".set pop" "\n"
145 : "=r" (tmp)
146 : "0" (val), "m" (*ptr));
147 local_irq_restore(flags);
148 } else
149 *ptr = val;
106} 150}
107 151
108/* 152/*