aboutsummaryrefslogtreecommitdiffstats
path: root/arch/microblaze/kernel
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2014-04-11 14:53:45 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2014-04-11 14:53:45 -0400
commitb42e6dc66bf379d7d44d419dda8733c890838751 (patch)
treeb3e4ff991ccac1eaf683fc7eb8dbe0e98aa8d042 /arch/microblaze/kernel
parent9e897e13bd46fa03485468609741974259a8c573 (diff)
parenta66a626538af65cbfc611e2b2fce500ed3f24518 (diff)
Merge tag 'microblaze-3.15-rc1' of git://git.monstr.eu/linux-2.6-microblaze
Pull Microblaze updates from Michal Simek: - use asm-generic/io.h and fix intc/timer code - clean platform handling - enable some syscalls * tag 'microblaze-3.15-rc1' of git://git.monstr.eu/linux-2.6-microblaze: microblaze: Use asm-generic/io.h microblaze: Remove platform folder microblaze: Remove generic platform microblaze: Sort Kconfig options microblaze: Move DTS file to common location at boot/dts folder microblaze: Fix compilation failure because of release_thread microblaze: Fix sparse warning because of missing cpu.h header microblaze: Make timer driver endian aware microblaze: Make intc driver endian aware microblaze: Wire-up new system calls sched_setattr/getattr microblaze: Wire-up preadv/pwritev in syscall table microblaze: Enable pselect6 syscall microblaze: Drop architecture-specific declaration of early_printk microblaze: Rename global function heartbeat()
Diffstat (limited to 'arch/microblaze/kernel')
-rw-r--r--arch/microblaze/kernel/Makefile2
-rw-r--r--arch/microblaze/kernel/heartbeat.c4
-rw-r--r--arch/microblaze/kernel/intc.c51
-rw-r--r--arch/microblaze/kernel/platform.c30
-rw-r--r--arch/microblaze/kernel/process.c1
-rw-r--r--arch/microblaze/kernel/signal.c2
-rw-r--r--arch/microblaze/kernel/syscall_table.S8
-rw-r--r--arch/microblaze/kernel/timer.c66
8 files changed, 130 insertions, 34 deletions
diff --git a/arch/microblaze/kernel/Makefile b/arch/microblaze/kernel/Makefile
index 5b0e512c78e5..08d50cc55e7d 100644
--- a/arch/microblaze/kernel/Makefile
+++ b/arch/microblaze/kernel/Makefile
@@ -16,7 +16,7 @@ extra-y := head.o vmlinux.lds
16 16
17obj-y += dma.o exceptions.o \ 17obj-y += dma.o exceptions.o \
18 hw_exception_handler.o intc.o irq.o \ 18 hw_exception_handler.o intc.o irq.o \
19 process.o prom.o prom_parse.o ptrace.o \ 19 platform.o process.o prom.o prom_parse.o ptrace.o \
20 reset.o setup.o signal.o sys_microblaze.o timer.o traps.o unwind.o 20 reset.o setup.o signal.o sys_microblaze.o timer.o traps.o unwind.o
21 21
22obj-y += cpu/ 22obj-y += cpu/
diff --git a/arch/microblaze/kernel/heartbeat.c b/arch/microblaze/kernel/heartbeat.c
index 1879a0527776..4643e3ab9414 100644
--- a/arch/microblaze/kernel/heartbeat.c
+++ b/arch/microblaze/kernel/heartbeat.c
@@ -17,7 +17,7 @@
17 17
18static unsigned int base_addr; 18static unsigned int base_addr;
19 19
20void heartbeat(void) 20void microblaze_heartbeat(void)
21{ 21{
22 static unsigned int cnt, period, dist; 22 static unsigned int cnt, period, dist;
23 23
@@ -42,7 +42,7 @@ void heartbeat(void)
42 } 42 }
43} 43}
44 44
45void setup_heartbeat(void) 45void microblaze_setup_heartbeat(void)
46{ 46{
47 struct device_node *gpio = NULL; 47 struct device_node *gpio = NULL;
48 int *prop; 48 int *prop;
diff --git a/arch/microblaze/kernel/intc.c b/arch/microblaze/kernel/intc.c
index 581451ad4687..15c7c12ea0e7 100644
--- a/arch/microblaze/kernel/intc.c
+++ b/arch/microblaze/kernel/intc.c
@@ -32,6 +32,29 @@ static void __iomem *intc_baseaddr;
32#define MER_ME (1<<0) 32#define MER_ME (1<<0)
33#define MER_HIE (1<<1) 33#define MER_HIE (1<<1)
34 34
35static unsigned int (*read_fn)(void __iomem *);
36static void (*write_fn)(u32, void __iomem *);
37
38static void intc_write32(u32 val, void __iomem *addr)
39{
40 iowrite32(val, addr);
41}
42
43static unsigned int intc_read32(void __iomem *addr)
44{
45 return ioread32(addr);
46}
47
48static void intc_write32_be(u32 val, void __iomem *addr)
49{
50 iowrite32be(val, addr);
51}
52
53static unsigned int intc_read32_be(void __iomem *addr)
54{
55 return ioread32be(addr);
56}
57
35static void intc_enable_or_unmask(struct irq_data *d) 58static void intc_enable_or_unmask(struct irq_data *d)
36{ 59{
37 unsigned long mask = 1 << d->hwirq; 60 unsigned long mask = 1 << d->hwirq;
@@ -43,21 +66,21 @@ static void intc_enable_or_unmask(struct irq_data *d)
43 * acks the irq before calling the interrupt handler 66 * acks the irq before calling the interrupt handler
44 */ 67 */
45 if (irqd_is_level_type(d)) 68 if (irqd_is_level_type(d))
46 out_be32(intc_baseaddr + IAR, mask); 69 write_fn(mask, intc_baseaddr + IAR);
47 70
48 out_be32(intc_baseaddr + SIE, mask); 71 write_fn(mask, intc_baseaddr + SIE);
49} 72}
50 73
51static void intc_disable_or_mask(struct irq_data *d) 74static void intc_disable_or_mask(struct irq_data *d)
52{ 75{
53 pr_debug("disable: %ld\n", d->hwirq); 76 pr_debug("disable: %ld\n", d->hwirq);
54 out_be32(intc_baseaddr + CIE, 1 << d->hwirq); 77 write_fn(1 << d->hwirq, intc_baseaddr + CIE);
55} 78}
56 79
57static void intc_ack(struct irq_data *d) 80static void intc_ack(struct irq_data *d)
58{ 81{
59 pr_debug("ack: %ld\n", d->hwirq); 82 pr_debug("ack: %ld\n", d->hwirq);
60 out_be32(intc_baseaddr + IAR, 1 << d->hwirq); 83 write_fn(1 << d->hwirq, intc_baseaddr + IAR);
61} 84}
62 85
63static void intc_mask_ack(struct irq_data *d) 86static void intc_mask_ack(struct irq_data *d)
@@ -65,8 +88,8 @@ static void intc_mask_ack(struct irq_data *d)
65 unsigned long mask = 1 << d->hwirq; 88 unsigned long mask = 1 << d->hwirq;
66 89
67 pr_debug("disable_and_ack: %ld\n", d->hwirq); 90 pr_debug("disable_and_ack: %ld\n", d->hwirq);
68 out_be32(intc_baseaddr + CIE, mask); 91 write_fn(mask, intc_baseaddr + CIE);
69 out_be32(intc_baseaddr + IAR, mask); 92 write_fn(mask, intc_baseaddr + IAR);
70} 93}
71 94
72static struct irq_chip intc_dev = { 95static struct irq_chip intc_dev = {
@@ -83,7 +106,7 @@ unsigned int get_irq(void)
83{ 106{
84 unsigned int hwirq, irq = -1; 107 unsigned int hwirq, irq = -1;
85 108
86 hwirq = in_be32(intc_baseaddr + IVR); 109 hwirq = read_fn(intc_baseaddr + IVR);
87 if (hwirq != -1U) 110 if (hwirq != -1U)
88 irq = irq_find_mapping(root_domain, hwirq); 111 irq = irq_find_mapping(root_domain, hwirq);
89 112
@@ -140,17 +163,25 @@ static int __init xilinx_intc_of_init(struct device_node *intc,
140 pr_info("%s: num_irq=%d, edge=0x%x\n", 163 pr_info("%s: num_irq=%d, edge=0x%x\n",
141 intc->full_name, nr_irq, intr_mask); 164 intc->full_name, nr_irq, intr_mask);
142 165
166 write_fn = intc_write32;
167 read_fn = intc_read32;
168
143 /* 169 /*
144 * Disable all external interrupts until they are 170 * Disable all external interrupts until they are
145 * explicity requested. 171 * explicity requested.
146 */ 172 */
147 out_be32(intc_baseaddr + IER, 0); 173 write_fn(0, intc_baseaddr + IER);
148 174
149 /* Acknowledge any pending interrupts just in case. */ 175 /* Acknowledge any pending interrupts just in case. */
150 out_be32(intc_baseaddr + IAR, 0xffffffff); 176 write_fn(0xffffffff, intc_baseaddr + IAR);
151 177
152 /* Turn on the Master Enable. */ 178 /* Turn on the Master Enable. */
153 out_be32(intc_baseaddr + MER, MER_HIE | MER_ME); 179 write_fn(MER_HIE | MER_ME, intc_baseaddr + MER);
180 if (!(read_fn(intc_baseaddr + MER) & (MER_HIE | MER_ME))) {
181 write_fn = intc_write32_be;
182 read_fn = intc_read32_be;
183 write_fn(MER_HIE | MER_ME, intc_baseaddr + MER);
184 }
154 185
155 /* Yeah, okay, casting the intr_mask to a void* is butt-ugly, but I'm 186 /* Yeah, okay, casting the intr_mask to a void* is butt-ugly, but I'm
156 * lazy and Michal can clean it up to something nicer when he tests 187 * lazy and Michal can clean it up to something nicer when he tests
diff --git a/arch/microblaze/kernel/platform.c b/arch/microblaze/kernel/platform.c
new file mode 100644
index 000000000000..b9529caa507a
--- /dev/null
+++ b/arch/microblaze/kernel/platform.c
@@ -0,0 +1,30 @@
1/*
2 * Copyright 2008 Michal Simek <monstr@monstr.eu>
3 *
4 * based on virtex.c file
5 *
6 * Copyright 2007 Secret Lab Technologies Ltd.
7 *
8 * This file is licensed under the terms of the GNU General Public License
9 * version 2. This program is licensed "as is" without any warranty of any
10 * kind, whether express or implied.
11 */
12
13#include <linux/init.h>
14#include <linux/of_platform.h>
15#include <asm/prom.h>
16#include <asm/setup.h>
17
18static struct of_device_id xilinx_of_bus_ids[] __initdata = {
19 { .compatible = "simple-bus", },
20 { .compatible = "xlnx,compound", },
21 {}
22};
23
24static int __init microblaze_device_probe(void)
25{
26 of_platform_bus_probe(NULL, xilinx_of_bus_ids, NULL);
27 of_platform_reset_gpio_probe();
28 return 0;
29}
30device_initcall(microblaze_device_probe);
diff --git a/arch/microblaze/kernel/process.c b/arch/microblaze/kernel/process.c
index 7d1a9c8b1f3d..b2dd37196b3b 100644
--- a/arch/microblaze/kernel/process.c
+++ b/arch/microblaze/kernel/process.c
@@ -8,6 +8,7 @@
8 * for more details. 8 * for more details.
9 */ 9 */
10 10
11#include <linux/cpu.h>
11#include <linux/export.h> 12#include <linux/export.h>
12#include <linux/sched.h> 13#include <linux/sched.h>
13#include <linux/pm.h> 14#include <linux/pm.h>
diff --git a/arch/microblaze/kernel/signal.c b/arch/microblaze/kernel/signal.c
index d26d7e7a6913..49a07a4d76d0 100644
--- a/arch/microblaze/kernel/signal.c
+++ b/arch/microblaze/kernel/signal.c
@@ -216,7 +216,7 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
216 /* MS: I need add offset in page */ 216 /* MS: I need add offset in page */
217 address += ((unsigned long)frame->tramp) & ~PAGE_MASK; 217 address += ((unsigned long)frame->tramp) & ~PAGE_MASK;
218 /* MS address is virtual */ 218 /* MS address is virtual */
219 address = virt_to_phys(address); 219 address = __virt_to_phys(address);
220 invalidate_icache_range(address, address + 8); 220 invalidate_icache_range(address, address + 8);
221 flush_dcache_range(address, address + 8); 221 flush_dcache_range(address, address + 8);
222 } 222 }
diff --git a/arch/microblaze/kernel/syscall_table.S b/arch/microblaze/kernel/syscall_table.S
index b882ad50535b..329dfbad810b 100644
--- a/arch/microblaze/kernel/syscall_table.S
+++ b/arch/microblaze/kernel/syscall_table.S
@@ -308,7 +308,7 @@ ENTRY(sys_call_table)
308 .long sys_readlinkat /* 305 */ 308 .long sys_readlinkat /* 305 */
309 .long sys_fchmodat 309 .long sys_fchmodat
310 .long sys_faccessat 310 .long sys_faccessat
311 .long sys_ni_syscall /* pselect6 */ 311 .long sys_pselect6
312 .long sys_ppoll 312 .long sys_ppoll
313 .long sys_unshare /* 310 */ 313 .long sys_unshare /* 310 */
314 .long sys_set_robust_list 314 .long sys_set_robust_list
@@ -363,8 +363,8 @@ ENTRY(sys_call_table)
363 .long sys_sendmsg /* 360 */ 363 .long sys_sendmsg /* 360 */
364 .long sys_recvmsg 364 .long sys_recvmsg
365 .long sys_accept4 365 .long sys_accept4
366 .long sys_ni_syscall 366 .long sys_preadv
367 .long sys_ni_syscall 367 .long sys_pwritev
368 .long sys_rt_tgsigqueueinfo /* 365 */ 368 .long sys_rt_tgsigqueueinfo /* 365 */
369 .long sys_perf_event_open 369 .long sys_perf_event_open
370 .long sys_recvmmsg 370 .long sys_recvmmsg
@@ -381,3 +381,5 @@ ENTRY(sys_call_table)
381 .long sys_process_vm_writev 381 .long sys_process_vm_writev
382 .long sys_kcmp 382 .long sys_kcmp
383 .long sys_finit_module 383 .long sys_finit_module
384 .long sys_sched_setattr
385 .long sys_sched_getattr
diff --git a/arch/microblaze/kernel/timer.c b/arch/microblaze/kernel/timer.c
index fb0c61443f19..dd96f0e4bfa2 100644
--- a/arch/microblaze/kernel/timer.c
+++ b/arch/microblaze/kernel/timer.c
@@ -43,10 +43,33 @@ static unsigned int timer_clock_freq;
43#define TCSR_PWMA (1<<9) 43#define TCSR_PWMA (1<<9)
44#define TCSR_ENALL (1<<10) 44#define TCSR_ENALL (1<<10)
45 45
46static unsigned int (*read_fn)(void __iomem *);
47static void (*write_fn)(u32, void __iomem *);
48
49static void timer_write32(u32 val, void __iomem *addr)
50{
51 iowrite32(val, addr);
52}
53
54static unsigned int timer_read32(void __iomem *addr)
55{
56 return ioread32(addr);
57}
58
59static void timer_write32_be(u32 val, void __iomem *addr)
60{
61 iowrite32be(val, addr);
62}
63
64static unsigned int timer_read32_be(void __iomem *addr)
65{
66 return ioread32be(addr);
67}
68
46static inline void xilinx_timer0_stop(void) 69static inline void xilinx_timer0_stop(void)
47{ 70{
48 out_be32(timer_baseaddr + TCSR0, 71 write_fn(read_fn(timer_baseaddr + TCSR0) & ~TCSR_ENT,
49 in_be32(timer_baseaddr + TCSR0) & ~TCSR_ENT); 72 timer_baseaddr + TCSR0);
50} 73}
51 74
52static inline void xilinx_timer0_start_periodic(unsigned long load_val) 75static inline void xilinx_timer0_start_periodic(unsigned long load_val)
@@ -54,10 +77,10 @@ static inline void xilinx_timer0_start_periodic(unsigned long load_val)
54 if (!load_val) 77 if (!load_val)
55 load_val = 1; 78 load_val = 1;
56 /* loading value to timer reg */ 79 /* loading value to timer reg */
57 out_be32(timer_baseaddr + TLR0, load_val); 80 write_fn(load_val, timer_baseaddr + TLR0);
58 81
59 /* load the initial value */ 82 /* load the initial value */
60 out_be32(timer_baseaddr + TCSR0, TCSR_LOAD); 83 write_fn(TCSR_LOAD, timer_baseaddr + TCSR0);
61 84
62 /* see timer data sheet for detail 85 /* see timer data sheet for detail
63 * !ENALL - don't enable 'em all 86 * !ENALL - don't enable 'em all
@@ -72,8 +95,8 @@ static inline void xilinx_timer0_start_periodic(unsigned long load_val)
72 * UDT - set the timer as down counter 95 * UDT - set the timer as down counter
73 * !MDT0 - generate mode 96 * !MDT0 - generate mode
74 */ 97 */
75 out_be32(timer_baseaddr + TCSR0, 98 write_fn(TCSR_TINT|TCSR_ENIT|TCSR_ENT|TCSR_ARHT|TCSR_UDT,
76 TCSR_TINT|TCSR_ENIT|TCSR_ENT|TCSR_ARHT|TCSR_UDT); 99 timer_baseaddr + TCSR0);
77} 100}
78 101
79static inline void xilinx_timer0_start_oneshot(unsigned long load_val) 102static inline void xilinx_timer0_start_oneshot(unsigned long load_val)
@@ -81,13 +104,13 @@ static inline void xilinx_timer0_start_oneshot(unsigned long load_val)
81 if (!load_val) 104 if (!load_val)
82 load_val = 1; 105 load_val = 1;
83 /* loading value to timer reg */ 106 /* loading value to timer reg */
84 out_be32(timer_baseaddr + TLR0, load_val); 107 write_fn(load_val, timer_baseaddr + TLR0);
85 108
86 /* load the initial value */ 109 /* load the initial value */
87 out_be32(timer_baseaddr + TCSR0, TCSR_LOAD); 110 write_fn(TCSR_LOAD, timer_baseaddr + TCSR0);
88 111
89 out_be32(timer_baseaddr + TCSR0, 112 write_fn(TCSR_TINT|TCSR_ENIT|TCSR_ENT|TCSR_ARHT|TCSR_UDT,
90 TCSR_TINT|TCSR_ENIT|TCSR_ENT|TCSR_ARHT|TCSR_UDT); 113 timer_baseaddr + TCSR0);
91} 114}
92 115
93static int xilinx_timer_set_next_event(unsigned long delta, 116static int xilinx_timer_set_next_event(unsigned long delta,
@@ -133,14 +156,14 @@ static struct clock_event_device clockevent_xilinx_timer = {
133 156
134static inline void timer_ack(void) 157static inline void timer_ack(void)
135{ 158{
136 out_be32(timer_baseaddr + TCSR0, in_be32(timer_baseaddr + TCSR0)); 159 write_fn(read_fn(timer_baseaddr + TCSR0), timer_baseaddr + TCSR0);
137} 160}
138 161
139static irqreturn_t timer_interrupt(int irq, void *dev_id) 162static irqreturn_t timer_interrupt(int irq, void *dev_id)
140{ 163{
141 struct clock_event_device *evt = &clockevent_xilinx_timer; 164 struct clock_event_device *evt = &clockevent_xilinx_timer;
142#ifdef CONFIG_HEART_BEAT 165#ifdef CONFIG_HEART_BEAT
143 heartbeat(); 166 microblaze_heartbeat();
144#endif 167#endif
145 timer_ack(); 168 timer_ack();
146 evt->event_handler(evt); 169 evt->event_handler(evt);
@@ -169,7 +192,7 @@ static __init void xilinx_clockevent_init(void)
169 192
170static u64 xilinx_clock_read(void) 193static u64 xilinx_clock_read(void)
171{ 194{
172 return in_be32(timer_baseaddr + TCR1); 195 return read_fn(timer_baseaddr + TCR1);
173} 196}
174 197
175static cycle_t xilinx_read(struct clocksource *cs) 198static cycle_t xilinx_read(struct clocksource *cs)
@@ -217,10 +240,10 @@ static int __init xilinx_clocksource_init(void)
217 panic("failed to register clocksource"); 240 panic("failed to register clocksource");
218 241
219 /* stop timer1 */ 242 /* stop timer1 */
220 out_be32(timer_baseaddr + TCSR1, 243 write_fn(read_fn(timer_baseaddr + TCSR1) & ~TCSR_ENT,
221 in_be32(timer_baseaddr + TCSR1) & ~TCSR_ENT); 244 timer_baseaddr + TCSR1);
222 /* start timer1 - up counting without interrupt */ 245 /* start timer1 - up counting without interrupt */
223 out_be32(timer_baseaddr + TCSR1, TCSR_TINT|TCSR_ENT|TCSR_ARHT); 246 write_fn(TCSR_TINT|TCSR_ENT|TCSR_ARHT, timer_baseaddr + TCSR1);
224 247
225 /* register timecounter - for ftrace support */ 248 /* register timecounter - for ftrace support */
226 init_xilinx_timecounter(); 249 init_xilinx_timecounter();
@@ -245,6 +268,15 @@ static void __init xilinx_timer_init(struct device_node *timer)
245 BUG(); 268 BUG();
246 } 269 }
247 270
271 write_fn = timer_write32;
272 read_fn = timer_read32;
273
274 write_fn(TCSR_MDT, timer_baseaddr + TCSR0);
275 if (!(read_fn(timer_baseaddr + TCSR0) & TCSR_MDT)) {
276 write_fn = timer_write32_be;
277 read_fn = timer_read32_be;
278 }
279
248 irq = irq_of_parse_and_map(timer, 0); 280 irq = irq_of_parse_and_map(timer, 0);
249 281
250 of_property_read_u32(timer, "xlnx,one-timer-only", &timer_num); 282 of_property_read_u32(timer, "xlnx,one-timer-only", &timer_num);
@@ -274,7 +306,7 @@ static void __init xilinx_timer_init(struct device_node *timer)
274 306
275 setup_irq(irq, &timer_irqaction); 307 setup_irq(irq, &timer_irqaction);
276#ifdef CONFIG_HEART_BEAT 308#ifdef CONFIG_HEART_BEAT
277 setup_heartbeat(); 309 microblaze_setup_heartbeat();
278#endif 310#endif
279 xilinx_clocksource_init(); 311 xilinx_clocksource_init();
280 xilinx_clockevent_init(); 312 xilinx_clockevent_init();