aboutsummaryrefslogtreecommitdiffstats
path: root/arch/blackfin/kernel
diff options
context:
space:
mode:
authorJonathan Herman <hermanjl@cs.unc.edu>2013-01-17 16:15:55 -0500
committerJonathan Herman <hermanjl@cs.unc.edu>2013-01-17 16:15:55 -0500
commit8dea78da5cee153b8af9c07a2745f6c55057fe12 (patch)
treea8f4d49d63b1ecc92f2fddceba0655b2472c5bd9 /arch/blackfin/kernel
parent406089d01562f1e2bf9f089fd7637009ebaad589 (diff)
Patched in Tegra support.
Diffstat (limited to 'arch/blackfin/kernel')
-rw-r--r--arch/blackfin/kernel/Makefile7
-rw-r--r--arch/blackfin/kernel/asm-offsets.c1
-rw-r--r--arch/blackfin/kernel/bfin_dma.c612
-rw-r--r--arch/blackfin/kernel/bfin_gpio.c32
-rw-r--r--arch/blackfin/kernel/cplb-mpu/cplbmgr.c2
-rw-r--r--arch/blackfin/kernel/cplb-nompu/cplbinit.c12
-rw-r--r--arch/blackfin/kernel/cplb-nompu/cplbmgr.c6
-rw-r--r--arch/blackfin/kernel/debug-mmrs.c9
-rw-r--r--arch/blackfin/kernel/dma-mapping.c11
-rw-r--r--arch/blackfin/kernel/entry.S65
-rw-r--r--arch/blackfin/kernel/gptimers.c85
-rw-r--r--arch/blackfin/kernel/ipipe.c1
-rw-r--r--arch/blackfin/kernel/kgdb.c13
-rw-r--r--arch/blackfin/kernel/kgdb_test.c4
-rw-r--r--arch/blackfin/kernel/perf_event.c1
-rw-r--r--arch/blackfin/kernel/process.c111
-rw-r--r--arch/blackfin/kernel/ptrace.c1
-rw-r--r--arch/blackfin/kernel/reboot.c8
-rw-r--r--arch/blackfin/kernel/setup.c143
-rw-r--r--arch/blackfin/kernel/shadow_console.c6
-rw-r--r--arch/blackfin/kernel/signal.c87
-rw-r--r--arch/blackfin/kernel/sys_bfin.c1
-rw-r--r--arch/blackfin/kernel/time-ts.c41
-rw-r--r--arch/blackfin/kernel/time.c1
-rw-r--r--arch/blackfin/kernel/trace.c33
-rw-r--r--arch/blackfin/kernel/traps.c1
26 files changed, 288 insertions, 1006 deletions
diff --git a/arch/blackfin/kernel/Makefile b/arch/blackfin/kernel/Makefile
index 735f24e0742..b7bdc42fe1a 100644
--- a/arch/blackfin/kernel/Makefile
+++ b/arch/blackfin/kernel/Makefile
@@ -2,12 +2,12 @@
2# arch/blackfin/kernel/Makefile 2# arch/blackfin/kernel/Makefile
3# 3#
4 4
5extra-y := vmlinux.lds 5extra-y := init_task.o vmlinux.lds
6 6
7obj-y := \ 7obj-y := \
8 entry.o process.o bfin_ksyms.o ptrace.o setup.o signal.o \ 8 entry.o process.o bfin_ksyms.o ptrace.o setup.o signal.o \
9 sys_bfin.o traps.o irqchip.o dma-mapping.o flat.o \ 9 sys_bfin.o traps.o irqchip.o dma-mapping.o flat.o \
10 fixed_code.o reboot.o bfin_gpio.o bfin_dma.o \ 10 fixed_code.o reboot.o bfin_gpio.o bfin_dma_5xx.o \
11 exception.o dumpstack.o 11 exception.o dumpstack.o
12 12
13ifeq ($(CONFIG_GENERIC_CLOCKEVENTS),y) 13ifeq ($(CONFIG_GENERIC_CLOCKEVENTS),y)
@@ -21,6 +21,7 @@ obj-$(CONFIG_FUNCTION_TRACER) += ftrace-entry.o
21obj-$(CONFIG_FUNCTION_GRAPH_TRACER) += ftrace.o 21obj-$(CONFIG_FUNCTION_GRAPH_TRACER) += ftrace.o
22CFLAGS_REMOVE_ftrace.o = -pg 22CFLAGS_REMOVE_ftrace.o = -pg
23 23
24obj-$(CONFIG_HAVE_PWM) += pwm.o
24obj-$(CONFIG_IPIPE) += ipipe.o 25obj-$(CONFIG_IPIPE) += ipipe.o
25obj-$(CONFIG_BFIN_GPTIMERS) += gptimers.o 26obj-$(CONFIG_BFIN_GPTIMERS) += gptimers.o
26obj-$(CONFIG_CPLB_INFO) += cplbinfo.o 27obj-$(CONFIG_CPLB_INFO) += cplbinfo.o
@@ -37,6 +38,6 @@ obj-$(CONFIG_PERF_EVENTS) += perf_event.o
37 38
38# the kgdb test puts code into L2 and without linker 39# the kgdb test puts code into L2 and without linker
39# relaxation, we need to force long calls to/from it 40# relaxation, we need to force long calls to/from it
40CFLAGS_kgdb_test.o := -mlong-calls 41CFLAGS_kgdb_test.o := -mlong-calls -O0
41 42
42obj-$(CONFIG_DEBUG_MMRS) += debug-mmrs.o 43obj-$(CONFIG_DEBUG_MMRS) += debug-mmrs.o
diff --git a/arch/blackfin/kernel/asm-offsets.c b/arch/blackfin/kernel/asm-offsets.c
index 37fcae95021..17e35465a41 100644
--- a/arch/blackfin/kernel/asm-offsets.c
+++ b/arch/blackfin/kernel/asm-offsets.c
@@ -14,7 +14,6 @@
14#include <linux/irq.h> 14#include <linux/irq.h>
15#include <linux/thread_info.h> 15#include <linux/thread_info.h>
16#include <linux/kbuild.h> 16#include <linux/kbuild.h>
17#include <asm/pda.h>
18 17
19int main(void) 18int main(void)
20{ 19{
diff --git a/arch/blackfin/kernel/bfin_dma.c b/arch/blackfin/kernel/bfin_dma.c
deleted file mode 100644
index 4a32f2dd5dd..00000000000
--- a/arch/blackfin/kernel/bfin_dma.c
+++ /dev/null
@@ -1,612 +0,0 @@
1/*
2 * bfin_dma.c - Blackfin DMA implementation
3 *
4 * Copyright 2004-2008 Analog Devices Inc.
5 *
6 * Licensed under the GPL-2 or later.
7 */
8
9#include <linux/errno.h>
10#include <linux/interrupt.h>
11#include <linux/kernel.h>
12#include <linux/module.h>
13#include <linux/param.h>
14#include <linux/proc_fs.h>
15#include <linux/sched.h>
16#include <linux/seq_file.h>
17#include <linux/spinlock.h>
18
19#include <asm/blackfin.h>
20#include <asm/cacheflush.h>
21#include <asm/dma.h>
22#include <asm/uaccess.h>
23#include <asm/early_printk.h>
24
25/*
26 * To make sure we work around 05000119 - we always check DMA_DONE bit,
27 * never the DMA_RUN bit
28 */
29
30struct dma_channel dma_ch[MAX_DMA_CHANNELS];
31EXPORT_SYMBOL(dma_ch);
32
33static int __init blackfin_dma_init(void)
34{
35 int i;
36
37 printk(KERN_INFO "Blackfin DMA Controller\n");
38
39
40#if ANOMALY_05000480
41 bfin_write_DMAC_TC_PER(0x0111);
42#endif
43
44 for (i = 0; i < MAX_DMA_CHANNELS; i++) {
45 atomic_set(&dma_ch[i].chan_status, 0);
46 dma_ch[i].regs = dma_io_base_addr[i];
47 }
48#if defined(CH_MEM_STREAM3_SRC) && defined(CONFIG_BF60x)
49 /* Mark MEMDMA Channel 3 as requested since we're using it internally */
50 request_dma(CH_MEM_STREAM3_DEST, "Blackfin dma_memcpy");
51 request_dma(CH_MEM_STREAM3_SRC, "Blackfin dma_memcpy");
52#else
53 /* Mark MEMDMA Channel 0 as requested since we're using it internally */
54 request_dma(CH_MEM_STREAM0_DEST, "Blackfin dma_memcpy");
55 request_dma(CH_MEM_STREAM0_SRC, "Blackfin dma_memcpy");
56#endif
57
58#if defined(CONFIG_DEB_DMA_URGENT)
59 bfin_write_EBIU_DDRQUE(bfin_read_EBIU_DDRQUE()
60 | DEB1_URGENT | DEB2_URGENT | DEB3_URGENT);
61#endif
62
63 return 0;
64}
65arch_initcall(blackfin_dma_init);
66
67#ifdef CONFIG_PROC_FS
68static int proc_dma_show(struct seq_file *m, void *v)
69{
70 int i;
71
72 for (i = 0; i < MAX_DMA_CHANNELS; ++i)
73 if (dma_channel_active(i))
74 seq_printf(m, "%2d: %s\n", i, dma_ch[i].device_id);
75
76 return 0;
77}
78
79static int proc_dma_open(struct inode *inode, struct file *file)
80{
81 return single_open(file, proc_dma_show, NULL);
82}
83
84static const struct file_operations proc_dma_operations = {
85 .open = proc_dma_open,
86 .read = seq_read,
87 .llseek = seq_lseek,
88 .release = single_release,
89};
90
91static int __init proc_dma_init(void)
92{
93 proc_create("dma", 0, NULL, &proc_dma_operations);
94 return 0;
95}
96late_initcall(proc_dma_init);
97#endif
98
99static void set_dma_peripheral_map(unsigned int channel, const char *device_id)
100{
101#ifdef CONFIG_BF54x
102 unsigned int per_map;
103
104 switch (channel) {
105 case CH_UART2_RX: per_map = 0xC << 12; break;
106 case CH_UART2_TX: per_map = 0xD << 12; break;
107 case CH_UART3_RX: per_map = 0xE << 12; break;
108 case CH_UART3_TX: per_map = 0xF << 12; break;
109 default: return;
110 }
111
112 if (strncmp(device_id, "BFIN_UART", 9) == 0)
113 dma_ch[channel].regs->peripheral_map = per_map;
114#endif
115}
116
117/**
118 * request_dma - request a DMA channel
119 *
120 * Request the specific DMA channel from the system if it's available.
121 */
122int request_dma(unsigned int channel, const char *device_id)
123{
124 pr_debug("request_dma() : BEGIN\n");
125
126 if (device_id == NULL)
127 printk(KERN_WARNING "request_dma(%u): no device_id given\n", channel);
128
129#if defined(CONFIG_BF561) && ANOMALY_05000182
130 if (channel >= CH_IMEM_STREAM0_DEST && channel <= CH_IMEM_STREAM1_DEST) {
131 if (get_cclk() > 500000000) {
132 printk(KERN_WARNING
133 "Request IMDMA failed due to ANOMALY 05000182\n");
134 return -EFAULT;
135 }
136 }
137#endif
138
139 if (atomic_cmpxchg(&dma_ch[channel].chan_status, 0, 1)) {
140 pr_debug("DMA CHANNEL IN USE\n");
141 return -EBUSY;
142 }
143
144 set_dma_peripheral_map(channel, device_id);
145 dma_ch[channel].device_id = device_id;
146 dma_ch[channel].irq = 0;
147
148 /* This is to be enabled by putting a restriction -
149 * you have to request DMA, before doing any operations on
150 * descriptor/channel
151 */
152 pr_debug("request_dma() : END\n");
153 return 0;
154}
155EXPORT_SYMBOL(request_dma);
156
157int set_dma_callback(unsigned int channel, irq_handler_t callback, void *data)
158{
159 int ret;
160 unsigned int irq;
161
162 BUG_ON(channel >= MAX_DMA_CHANNELS || !callback ||
163 !atomic_read(&dma_ch[channel].chan_status));
164
165 irq = channel2irq(channel);
166 ret = request_irq(irq, callback, 0, dma_ch[channel].device_id, data);
167 if (ret)
168 return ret;
169
170 dma_ch[channel].irq = irq;
171 dma_ch[channel].data = data;
172
173 return 0;
174}
175EXPORT_SYMBOL(set_dma_callback);
176
177/**
178 * clear_dma_buffer - clear DMA fifos for specified channel
179 *
180 * Set the Buffer Clear bit in the Configuration register of specific DMA
181 * channel. This will stop the descriptor based DMA operation.
182 */
183static void clear_dma_buffer(unsigned int channel)
184{
185 dma_ch[channel].regs->cfg |= RESTART;
186 SSYNC();
187 dma_ch[channel].regs->cfg &= ~RESTART;
188}
189
190void free_dma(unsigned int channel)
191{
192 pr_debug("freedma() : BEGIN\n");
193 BUG_ON(channel >= MAX_DMA_CHANNELS ||
194 !atomic_read(&dma_ch[channel].chan_status));
195
196 /* Halt the DMA */
197 disable_dma(channel);
198 clear_dma_buffer(channel);
199
200 if (dma_ch[channel].irq)
201 free_irq(dma_ch[channel].irq, dma_ch[channel].data);
202
203 /* Clear the DMA Variable in the Channel */
204 atomic_set(&dma_ch[channel].chan_status, 0);
205
206 pr_debug("freedma() : END\n");
207}
208EXPORT_SYMBOL(free_dma);
209
210#ifdef CONFIG_PM
211# ifndef MAX_DMA_SUSPEND_CHANNELS
212# define MAX_DMA_SUSPEND_CHANNELS MAX_DMA_CHANNELS
213# endif
214# ifndef CONFIG_BF60x
215int blackfin_dma_suspend(void)
216{
217 int i;
218
219 for (i = 0; i < MAX_DMA_CHANNELS; ++i) {
220 if (dma_ch[i].regs->cfg & DMAEN) {
221 printk(KERN_ERR "DMA Channel %d failed to suspend\n", i);
222 return -EBUSY;
223 }
224 if (i < MAX_DMA_SUSPEND_CHANNELS)
225 dma_ch[i].saved_peripheral_map = dma_ch[i].regs->peripheral_map;
226 }
227
228#if ANOMALY_05000480
229 bfin_write_DMAC_TC_PER(0x0);
230#endif
231 return 0;
232}
233
234void blackfin_dma_resume(void)
235{
236 int i;
237
238 for (i = 0; i < MAX_DMA_CHANNELS; ++i) {
239 dma_ch[i].regs->cfg = 0;
240 if (i < MAX_DMA_SUSPEND_CHANNELS)
241 dma_ch[i].regs->peripheral_map = dma_ch[i].saved_peripheral_map;
242 }
243#if ANOMALY_05000480
244 bfin_write_DMAC_TC_PER(0x0111);
245#endif
246}
247# else
248int blackfin_dma_suspend(void)
249{
250 return 0;
251}
252
253void blackfin_dma_resume(void)
254{
255}
256#endif
257#endif
258
259/**
260 * blackfin_dma_early_init - minimal DMA init
261 *
262 * Setup a few DMA registers so we can safely do DMA transfers early on in
263 * the kernel booting process. Really this just means using dma_memcpy().
264 */
265void __init blackfin_dma_early_init(void)
266{
267 early_shadow_stamp();
268 bfin_write_MDMA_S0_CONFIG(0);
269 bfin_write_MDMA_S1_CONFIG(0);
270}
271
272void __init early_dma_memcpy(void *pdst, const void *psrc, size_t size)
273{
274 unsigned long dst = (unsigned long)pdst;
275 unsigned long src = (unsigned long)psrc;
276 struct dma_register *dst_ch, *src_ch;
277
278 early_shadow_stamp();
279
280 /* We assume that everything is 4 byte aligned, so include
281 * a basic sanity check
282 */
283 BUG_ON(dst % 4);
284 BUG_ON(src % 4);
285 BUG_ON(size % 4);
286
287 src_ch = 0;
288 /* Find an avalible memDMA channel */
289 while (1) {
290 if (src_ch == (struct dma_register *)MDMA_S0_NEXT_DESC_PTR) {
291 dst_ch = (struct dma_register *)MDMA_D1_NEXT_DESC_PTR;
292 src_ch = (struct dma_register *)MDMA_S1_NEXT_DESC_PTR;
293 } else {
294 dst_ch = (struct dma_register *)MDMA_D0_NEXT_DESC_PTR;
295 src_ch = (struct dma_register *)MDMA_S0_NEXT_DESC_PTR;
296 }
297
298 if (!DMA_MMR_READ(&src_ch->cfg))
299 break;
300 else if (DMA_MMR_READ(&dst_ch->irq_status) & DMA_DONE) {
301 DMA_MMR_WRITE(&src_ch->cfg, 0);
302 break;
303 }
304 }
305
306 /* Force a sync in case a previous config reset on this channel
307 * occurred. This is needed so subsequent writes to DMA registers
308 * are not spuriously lost/corrupted.
309 */
310 __builtin_bfin_ssync();
311
312 /* Destination */
313 bfin_write32(&dst_ch->start_addr, dst);
314 DMA_MMR_WRITE(&dst_ch->x_count, size >> 2);
315 DMA_MMR_WRITE(&dst_ch->x_modify, 1 << 2);
316 DMA_MMR_WRITE(&dst_ch->irq_status, DMA_DONE | DMA_ERR);
317
318 /* Source */
319 bfin_write32(&src_ch->start_addr, src);
320 DMA_MMR_WRITE(&src_ch->x_count, size >> 2);
321 DMA_MMR_WRITE(&src_ch->x_modify, 1 << 2);
322 DMA_MMR_WRITE(&src_ch->irq_status, DMA_DONE | DMA_ERR);
323
324 /* Enable */
325 DMA_MMR_WRITE(&src_ch->cfg, DMAEN | WDSIZE_32);
326 DMA_MMR_WRITE(&dst_ch->cfg, WNR | DI_EN_X | DMAEN | WDSIZE_32);
327
328 /* Since we are atomic now, don't use the workaround ssync */
329 __builtin_bfin_ssync();
330
331#ifdef CONFIG_BF60x
332 /* Work around a possible MDMA anomaly. Running 2 MDMA channels to
333 * transfer DDR data to L1 SRAM may corrupt data.
334 * Should be reverted after this issue is root caused.
335 */
336 while (!(DMA_MMR_READ(&dst_ch->irq_status) & DMA_DONE))
337 continue;
338#endif
339}
340
341void __init early_dma_memcpy_done(void)
342{
343 early_shadow_stamp();
344
345 while ((bfin_read_MDMA_S0_CONFIG() && !(bfin_read_MDMA_D0_IRQ_STATUS() & DMA_DONE)) ||
346 (bfin_read_MDMA_S1_CONFIG() && !(bfin_read_MDMA_D1_IRQ_STATUS() & DMA_DONE)))
347 continue;
348
349 bfin_write_MDMA_D0_IRQ_STATUS(DMA_DONE | DMA_ERR);
350 bfin_write_MDMA_D1_IRQ_STATUS(DMA_DONE | DMA_ERR);
351 /*
352 * Now that DMA is done, we would normally flush cache, but
353 * i/d cache isn't running this early, so we don't bother,
354 * and just clear out the DMA channel for next time
355 */
356 bfin_write_MDMA_S0_CONFIG(0);
357 bfin_write_MDMA_S1_CONFIG(0);
358 bfin_write_MDMA_D0_CONFIG(0);
359 bfin_write_MDMA_D1_CONFIG(0);
360
361 __builtin_bfin_ssync();
362}
363
364#if defined(CH_MEM_STREAM3_SRC) && defined(CONFIG_BF60x)
365#define bfin_read_MDMA_S_CONFIG bfin_read_MDMA_S3_CONFIG
366#define bfin_write_MDMA_S_CONFIG bfin_write_MDMA_S3_CONFIG
367#define bfin_write_MDMA_S_START_ADDR bfin_write_MDMA_S3_START_ADDR
368#define bfin_write_MDMA_S_IRQ_STATUS bfin_write_MDMA_S3_IRQ_STATUS
369#define bfin_write_MDMA_S_X_COUNT bfin_write_MDMA_S3_X_COUNT
370#define bfin_write_MDMA_S_X_MODIFY bfin_write_MDMA_S3_X_MODIFY
371#define bfin_write_MDMA_S_Y_COUNT bfin_write_MDMA_S3_Y_COUNT
372#define bfin_write_MDMA_S_Y_MODIFY bfin_write_MDMA_S3_Y_MODIFY
373#define bfin_write_MDMA_D_CONFIG bfin_write_MDMA_D3_CONFIG
374#define bfin_write_MDMA_D_START_ADDR bfin_write_MDMA_D3_START_ADDR
375#define bfin_read_MDMA_D_IRQ_STATUS bfin_read_MDMA_D3_IRQ_STATUS
376#define bfin_write_MDMA_D_IRQ_STATUS bfin_write_MDMA_D3_IRQ_STATUS
377#define bfin_write_MDMA_D_X_COUNT bfin_write_MDMA_D3_X_COUNT
378#define bfin_write_MDMA_D_X_MODIFY bfin_write_MDMA_D3_X_MODIFY
379#define bfin_write_MDMA_D_Y_COUNT bfin_write_MDMA_D3_Y_COUNT
380#define bfin_write_MDMA_D_Y_MODIFY bfin_write_MDMA_D3_Y_MODIFY
381#else
382#define bfin_read_MDMA_S_CONFIG bfin_read_MDMA_S0_CONFIG
383#define bfin_write_MDMA_S_CONFIG bfin_write_MDMA_S0_CONFIG
384#define bfin_write_MDMA_S_START_ADDR bfin_write_MDMA_S0_START_ADDR
385#define bfin_write_MDMA_S_IRQ_STATUS bfin_write_MDMA_S0_IRQ_STATUS
386#define bfin_write_MDMA_S_X_COUNT bfin_write_MDMA_S0_X_COUNT
387#define bfin_write_MDMA_S_X_MODIFY bfin_write_MDMA_S0_X_MODIFY
388#define bfin_write_MDMA_S_Y_COUNT bfin_write_MDMA_S0_Y_COUNT
389#define bfin_write_MDMA_S_Y_MODIFY bfin_write_MDMA_S0_Y_MODIFY
390#define bfin_write_MDMA_D_CONFIG bfin_write_MDMA_D0_CONFIG
391#define bfin_write_MDMA_D_START_ADDR bfin_write_MDMA_D0_START_ADDR
392#define bfin_read_MDMA_D_IRQ_STATUS bfin_read_MDMA_D0_IRQ_STATUS
393#define bfin_write_MDMA_D_IRQ_STATUS bfin_write_MDMA_D0_IRQ_STATUS
394#define bfin_write_MDMA_D_X_COUNT bfin_write_MDMA_D0_X_COUNT
395#define bfin_write_MDMA_D_X_MODIFY bfin_write_MDMA_D0_X_MODIFY
396#define bfin_write_MDMA_D_Y_COUNT bfin_write_MDMA_D0_Y_COUNT
397#define bfin_write_MDMA_D_Y_MODIFY bfin_write_MDMA_D0_Y_MODIFY
398#endif
399
400/**
401 * __dma_memcpy - program the MDMA registers
402 *
403 * Actually program MDMA0 and wait for the transfer to finish. Disable IRQs
404 * while programming registers so that everything is fully configured. Wait
405 * for DMA to finish with IRQs enabled. If interrupted, the initial DMA_DONE
406 * check will make sure we don't clobber any existing transfer.
407 */
408static void __dma_memcpy(u32 daddr, s16 dmod, u32 saddr, s16 smod, size_t cnt, u32 conf)
409{
410 static DEFINE_SPINLOCK(mdma_lock);
411 unsigned long flags;
412
413 spin_lock_irqsave(&mdma_lock, flags);
414
415 /* Force a sync in case a previous config reset on this channel
416 * occurred. This is needed so subsequent writes to DMA registers
417 * are not spuriously lost/corrupted. Do it under irq lock and
418 * without the anomaly version (because we are atomic already).
419 */
420 __builtin_bfin_ssync();
421
422 if (bfin_read_MDMA_S_CONFIG())
423 while (!(bfin_read_MDMA_D_IRQ_STATUS() & DMA_DONE))
424 continue;
425
426 if (conf & DMA2D) {
427 /* For larger bit sizes, we've already divided down cnt so it
428 * is no longer a multiple of 64k. So we have to break down
429 * the limit here so it is a multiple of the incoming size.
430 * There is no limitation here in terms of total size other
431 * than the hardware though as the bits lost in the shift are
432 * made up by MODIFY (== we can hit the whole address space).
433 * X: (2^(16 - 0)) * 1 == (2^(16 - 1)) * 2 == (2^(16 - 2)) * 4
434 */
435 u32 shift = abs(dmod) >> 1;
436 size_t ycnt = cnt >> (16 - shift);
437 cnt = 1 << (16 - shift);
438 bfin_write_MDMA_D_Y_COUNT(ycnt);
439 bfin_write_MDMA_S_Y_COUNT(ycnt);
440 bfin_write_MDMA_D_Y_MODIFY(dmod);
441 bfin_write_MDMA_S_Y_MODIFY(smod);
442 }
443
444 bfin_write_MDMA_D_START_ADDR(daddr);
445 bfin_write_MDMA_D_X_COUNT(cnt);
446 bfin_write_MDMA_D_X_MODIFY(dmod);
447 bfin_write_MDMA_D_IRQ_STATUS(DMA_DONE | DMA_ERR);
448
449 bfin_write_MDMA_S_START_ADDR(saddr);
450 bfin_write_MDMA_S_X_COUNT(cnt);
451 bfin_write_MDMA_S_X_MODIFY(smod);
452 bfin_write_MDMA_S_IRQ_STATUS(DMA_DONE | DMA_ERR);
453
454 bfin_write_MDMA_S_CONFIG(DMAEN | conf);
455 if (conf & DMA2D)
456 bfin_write_MDMA_D_CONFIG(WNR | DI_EN_Y | DMAEN | conf);
457 else
458 bfin_write_MDMA_D_CONFIG(WNR | DI_EN_X | DMAEN | conf);
459
460 spin_unlock_irqrestore(&mdma_lock, flags);
461
462 SSYNC();
463
464 while (!(bfin_read_MDMA_D_IRQ_STATUS() & DMA_DONE))
465 if (bfin_read_MDMA_S_CONFIG())
466 continue;
467 else
468 return;
469
470 bfin_write_MDMA_D_IRQ_STATUS(DMA_DONE | DMA_ERR);
471
472 bfin_write_MDMA_S_CONFIG(0);
473 bfin_write_MDMA_D_CONFIG(0);
474}
475
476/**
477 * _dma_memcpy - translate C memcpy settings into MDMA settings
478 *
479 * Handle all the high level steps before we touch the MDMA registers. So
480 * handle direction, tweaking of sizes, and formatting of addresses.
481 */
482static void *_dma_memcpy(void *pdst, const void *psrc, size_t size)
483{
484 u32 conf, shift;
485 s16 mod;
486 unsigned long dst = (unsigned long)pdst;
487 unsigned long src = (unsigned long)psrc;
488
489 if (size == 0)
490 return NULL;
491
492 if (dst % 4 == 0 && src % 4 == 0 && size % 4 == 0) {
493 conf = WDSIZE_32;
494 shift = 2;
495 } else if (dst % 2 == 0 && src % 2 == 0 && size % 2 == 0) {
496 conf = WDSIZE_16;
497 shift = 1;
498 } else {
499 conf = WDSIZE_8;
500 shift = 0;
501 }
502
503 /* If the two memory regions have a chance of overlapping, make
504 * sure the memcpy still works as expected. Do this by having the
505 * copy run backwards instead.
506 */
507 mod = 1 << shift;
508 if (src < dst) {
509 mod *= -1;
510 dst += size + mod;
511 src += size + mod;
512 }
513 size >>= shift;
514
515#ifndef DMA_MMR_SIZE_32
516 if (size > 0x10000)
517 conf |= DMA2D;
518#endif
519
520 __dma_memcpy(dst, mod, src, mod, size, conf);
521
522 return pdst;
523}
524
525/**
526 * dma_memcpy - DMA memcpy under mutex lock
527 *
528 * Do not check arguments before starting the DMA memcpy. Break the transfer
529 * up into two pieces. The first transfer is in multiples of 64k and the
530 * second transfer is the piece smaller than 64k.
531 */
532void *dma_memcpy(void *pdst, const void *psrc, size_t size)
533{
534 unsigned long dst = (unsigned long)pdst;
535 unsigned long src = (unsigned long)psrc;
536
537 if (bfin_addr_dcacheable(src))
538 blackfin_dcache_flush_range(src, src + size);
539
540 if (bfin_addr_dcacheable(dst))
541 blackfin_dcache_invalidate_range(dst, dst + size);
542
543 return dma_memcpy_nocache(pdst, psrc, size);
544}
545EXPORT_SYMBOL(dma_memcpy);
546
547/**
548 * dma_memcpy_nocache - DMA memcpy under mutex lock
549 * - No cache flush/invalidate
550 *
551 * Do not check arguments before starting the DMA memcpy. Break the transfer
552 * up into two pieces. The first transfer is in multiples of 64k and the
553 * second transfer is the piece smaller than 64k.
554 */
555void *dma_memcpy_nocache(void *pdst, const void *psrc, size_t size)
556{
557#ifdef DMA_MMR_SIZE_32
558 _dma_memcpy(pdst, psrc, size);
559#else
560 size_t bulk, rest;
561
562 bulk = size & ~0xffff;
563 rest = size - bulk;
564 if (bulk)
565 _dma_memcpy(pdst, psrc, bulk);
566 _dma_memcpy(pdst + bulk, psrc + bulk, rest);
567#endif
568 return pdst;
569}
570EXPORT_SYMBOL(dma_memcpy_nocache);
571
572/**
573 * safe_dma_memcpy - DMA memcpy w/argument checking
574 *
575 * Verify arguments are safe before heading to dma_memcpy().
576 */
577void *safe_dma_memcpy(void *dst, const void *src, size_t size)
578{
579 if (!access_ok(VERIFY_WRITE, dst, size))
580 return NULL;
581 if (!access_ok(VERIFY_READ, src, size))
582 return NULL;
583 return dma_memcpy(dst, src, size);
584}
585EXPORT_SYMBOL(safe_dma_memcpy);
586
587static void _dma_out(unsigned long addr, unsigned long buf, unsigned DMA_MMR_SIZE_TYPE len,
588 u16 size, u16 dma_size)
589{
590 blackfin_dcache_flush_range(buf, buf + len * size);
591 __dma_memcpy(addr, 0, buf, size, len, dma_size);
592}
593
594static void _dma_in(unsigned long addr, unsigned long buf, unsigned DMA_MMR_SIZE_TYPE len,
595 u16 size, u16 dma_size)
596{
597 blackfin_dcache_invalidate_range(buf, buf + len * size);
598 __dma_memcpy(buf, size, addr, 0, len, dma_size);
599}
600
601#define MAKE_DMA_IO(io, bwl, isize, dmasize, cnst) \
602void dma_##io##s##bwl(unsigned long addr, cnst void *buf, unsigned DMA_MMR_SIZE_TYPE len) \
603{ \
604 _dma_##io(addr, (unsigned long)buf, len, isize, WDSIZE_##dmasize); \
605} \
606EXPORT_SYMBOL(dma_##io##s##bwl)
607MAKE_DMA_IO(out, b, 1, 8, const);
608MAKE_DMA_IO(in, b, 1, 8, );
609MAKE_DMA_IO(out, w, 2, 16, const);
610MAKE_DMA_IO(in, w, 2, 16, );
611MAKE_DMA_IO(out, l, 4, 32, const);
612MAKE_DMA_IO(in, l, 4, 32, );
diff --git a/arch/blackfin/kernel/bfin_gpio.c b/arch/blackfin/kernel/bfin_gpio.c
index ed978f1c5cb..02796b88443 100644
--- a/arch/blackfin/kernel/bfin_gpio.c
+++ b/arch/blackfin/kernel/bfin_gpio.c
@@ -58,7 +58,7 @@ static struct gpio_port_t * const gpio_array[] = {
58 (struct gpio_port_t *) FIO0_FLAG_D, 58 (struct gpio_port_t *) FIO0_FLAG_D,
59 (struct gpio_port_t *) FIO1_FLAG_D, 59 (struct gpio_port_t *) FIO1_FLAG_D,
60 (struct gpio_port_t *) FIO2_FLAG_D, 60 (struct gpio_port_t *) FIO2_FLAG_D,
61#elif defined(CONFIG_BF54x) || defined(CONFIG_BF60x) 61#elif defined(CONFIG_BF54x)
62 (struct gpio_port_t *)PORTA_FER, 62 (struct gpio_port_t *)PORTA_FER,
63 (struct gpio_port_t *)PORTB_FER, 63 (struct gpio_port_t *)PORTB_FER,
64 (struct gpio_port_t *)PORTC_FER, 64 (struct gpio_port_t *)PORTC_FER,
@@ -66,11 +66,9 @@ static struct gpio_port_t * const gpio_array[] = {
66 (struct gpio_port_t *)PORTE_FER, 66 (struct gpio_port_t *)PORTE_FER,
67 (struct gpio_port_t *)PORTF_FER, 67 (struct gpio_port_t *)PORTF_FER,
68 (struct gpio_port_t *)PORTG_FER, 68 (struct gpio_port_t *)PORTG_FER,
69# if defined(CONFIG_BF54x)
70 (struct gpio_port_t *)PORTH_FER, 69 (struct gpio_port_t *)PORTH_FER,
71 (struct gpio_port_t *)PORTI_FER, 70 (struct gpio_port_t *)PORTI_FER,
72 (struct gpio_port_t *)PORTJ_FER, 71 (struct gpio_port_t *)PORTJ_FER,
73# endif
74#else 72#else
75# error no gpio arrays defined 73# error no gpio arrays defined
76#endif 74#endif
@@ -212,7 +210,7 @@ static void port_setup(unsigned gpio, unsigned short usage)
212 else 210 else
213 *port_fer[gpio_bank(gpio)] |= gpio_bit(gpio); 211 *port_fer[gpio_bank(gpio)] |= gpio_bit(gpio);
214 SSYNC(); 212 SSYNC();
215#elif defined(CONFIG_BF54x) || defined(CONFIG_BF60x) 213#elif defined(CONFIG_BF54x)
216 if (usage == GPIO_USAGE) 214 if (usage == GPIO_USAGE)
217 gpio_array[gpio_bank(gpio)]->port_fer &= ~gpio_bit(gpio); 215 gpio_array[gpio_bank(gpio)]->port_fer &= ~gpio_bit(gpio);
218 else 216 else
@@ -301,7 +299,7 @@ static void portmux_setup(unsigned short per)
301 pmux |= (function << offset); 299 pmux |= (function << offset);
302 bfin_write_PORT_MUX(pmux); 300 bfin_write_PORT_MUX(pmux);
303} 301}
304#elif defined(CONFIG_BF54x) || defined(CONFIG_BF60x) 302#elif defined(CONFIG_BF54x)
305inline void portmux_setup(unsigned short per) 303inline void portmux_setup(unsigned short per)
306{ 304{
307 u16 ident = P_IDENT(per); 305 u16 ident = P_IDENT(per);
@@ -379,7 +377,7 @@ static int portmux_group_check(unsigned short per)
379} 377}
380#endif 378#endif
381 379
382#if !(defined(CONFIG_BF54x) || defined(CONFIG_BF60x)) 380#ifndef CONFIG_BF54x
383/*********************************************************** 381/***********************************************************
384* 382*
385* FUNCTIONS: Blackfin General Purpose Ports Access Functions 383* FUNCTIONS: Blackfin General Purpose Ports Access Functions
@@ -682,7 +680,7 @@ void bfin_gpio_pm_hibernate_restore(void)
682 680
683 681
684#endif 682#endif
685#else /* CONFIG_BF54x || CONFIG_BF60x */ 683#else /* CONFIG_BF54x */
686#ifdef CONFIG_PM 684#ifdef CONFIG_PM
687 685
688int bfin_pm_standby_ctrl(unsigned ctrl) 686int bfin_pm_standby_ctrl(unsigned ctrl)
@@ -728,7 +726,7 @@ unsigned short get_gpio_dir(unsigned gpio)
728} 726}
729EXPORT_SYMBOL(get_gpio_dir); 727EXPORT_SYMBOL(get_gpio_dir);
730 728
731#endif /* CONFIG_BF54x || CONFIG_BF60x */ 729#endif /* CONFIG_BF54x */
732 730
733/*********************************************************** 731/***********************************************************
734* 732*
@@ -785,7 +783,7 @@ int peripheral_request(unsigned short per, const char *label)
785 * be requested and used by several drivers 783 * be requested and used by several drivers
786 */ 784 */
787 785
788#if defined(CONFIG_BF54x) || defined(CONFIG_BF60x) 786#ifdef CONFIG_BF54x
789 if (!((per & P_MAYSHARE) && get_portmux(per) == P_FUNCT2MUX(per))) { 787 if (!((per & P_MAYSHARE) && get_portmux(per) == P_FUNCT2MUX(per))) {
790#else 788#else
791 if (!(per & P_MAYSHARE)) { 789 if (!(per & P_MAYSHARE)) {
@@ -939,7 +937,7 @@ int bfin_gpio_request(unsigned gpio, const char *label)
939 printk(KERN_NOTICE "bfin-gpio: GPIO %d is already reserved as gpio-irq!" 937 printk(KERN_NOTICE "bfin-gpio: GPIO %d is already reserved as gpio-irq!"
940 " (Documentation/blackfin/bfin-gpio-notes.txt)\n", gpio); 938 " (Documentation/blackfin/bfin-gpio-notes.txt)\n", gpio);
941 } 939 }
942#if !(defined(CONFIG_BF54x) || defined(CONFIG_BF60x)) 940#ifndef CONFIG_BF54x
943 else { /* Reset POLAR setting when acquiring a gpio for the first time */ 941 else { /* Reset POLAR setting when acquiring a gpio for the first time */
944 set_gpio_polar(gpio, 0); 942 set_gpio_polar(gpio, 0);
945 } 943 }
@@ -1112,7 +1110,7 @@ void bfin_gpio_irq_free(unsigned gpio)
1112 1110
1113static inline void __bfin_gpio_direction_input(unsigned gpio) 1111static inline void __bfin_gpio_direction_input(unsigned gpio)
1114{ 1112{
1115#if defined(CONFIG_BF54x) || defined(CONFIG_BF60x) 1113#ifdef CONFIG_BF54x
1116 gpio_array[gpio_bank(gpio)]->dir_clear = gpio_bit(gpio); 1114 gpio_array[gpio_bank(gpio)]->dir_clear = gpio_bit(gpio);
1117#else 1115#else
1118 gpio_array[gpio_bank(gpio)]->dir &= ~gpio_bit(gpio); 1116 gpio_array[gpio_bank(gpio)]->dir &= ~gpio_bit(gpio);
@@ -1140,13 +1138,13 @@ EXPORT_SYMBOL(bfin_gpio_direction_input);
1140 1138
1141void bfin_gpio_irq_prepare(unsigned gpio) 1139void bfin_gpio_irq_prepare(unsigned gpio)
1142{ 1140{
1143#if defined(CONFIG_BF54x) || defined(CONFIG_BF60x) 1141#ifdef CONFIG_BF54x
1144 unsigned long flags; 1142 unsigned long flags;
1145#endif 1143#endif
1146 1144
1147 port_setup(gpio, GPIO_USAGE); 1145 port_setup(gpio, GPIO_USAGE);
1148 1146
1149#if defined(CONFIG_BF54x) || defined(CONFIG_BF60x) 1147#ifdef CONFIG_BF54x
1150 flags = hard_local_irq_save(); 1148 flags = hard_local_irq_save();
1151 __bfin_gpio_direction_input(gpio); 1149 __bfin_gpio_direction_input(gpio);
1152 hard_local_irq_restore(flags); 1150 hard_local_irq_restore(flags);
@@ -1175,7 +1173,7 @@ int bfin_gpio_direction_output(unsigned gpio, int value)
1175 1173
1176 gpio_array[gpio_bank(gpio)]->inen &= ~gpio_bit(gpio); 1174 gpio_array[gpio_bank(gpio)]->inen &= ~gpio_bit(gpio);
1177 gpio_set_value(gpio, value); 1175 gpio_set_value(gpio, value);
1178#if defined(CONFIG_BF54x) || defined(CONFIG_BF60x) 1176#ifdef CONFIG_BF54x
1179 gpio_array[gpio_bank(gpio)]->dir_set = gpio_bit(gpio); 1177 gpio_array[gpio_bank(gpio)]->dir_set = gpio_bit(gpio);
1180#else 1178#else
1181 gpio_array[gpio_bank(gpio)]->dir |= gpio_bit(gpio); 1179 gpio_array[gpio_bank(gpio)]->dir |= gpio_bit(gpio);
@@ -1190,7 +1188,7 @@ EXPORT_SYMBOL(bfin_gpio_direction_output);
1190 1188
1191int bfin_gpio_get_value(unsigned gpio) 1189int bfin_gpio_get_value(unsigned gpio)
1192{ 1190{
1193#if defined(CONFIG_BF54x) || defined(CONFIG_BF60x) 1191#ifdef CONFIG_BF54x
1194 return (1 & (gpio_array[gpio_bank(gpio)]->data >> gpio_sub_n(gpio))); 1192 return (1 & (gpio_array[gpio_bank(gpio)]->data >> gpio_sub_n(gpio)));
1195#else 1193#else
1196 unsigned long flags; 1194 unsigned long flags;
@@ -1265,8 +1263,8 @@ static __init int gpio_register_proc(void)
1265{ 1263{
1266 struct proc_dir_entry *proc_gpio; 1264 struct proc_dir_entry *proc_gpio;
1267 1265
1268 proc_gpio = proc_create("gpio", 0, NULL, &gpio_proc_ops); 1266 proc_gpio = proc_create("gpio", S_IRUGO, NULL, &gpio_proc_ops);
1269 return proc_gpio == NULL; 1267 return proc_gpio != NULL;
1270} 1268}
1271__initcall(gpio_register_proc); 1269__initcall(gpio_register_proc);
1272#endif 1270#endif
diff --git a/arch/blackfin/kernel/cplb-mpu/cplbmgr.c b/arch/blackfin/kernel/cplb-mpu/cplbmgr.c
index b56bd8514b7..8de92299b3e 100644
--- a/arch/blackfin/kernel/cplb-mpu/cplbmgr.c
+++ b/arch/blackfin/kernel/cplb-mpu/cplbmgr.c
@@ -120,7 +120,6 @@ MGR_ATTR static noinline int dcplb_miss(unsigned int cpu)
120 d_data = L2_DMEMORY; 120 d_data = L2_DMEMORY;
121 } else if (addr >= physical_mem_end) { 121 } else if (addr >= physical_mem_end) {
122 if (addr >= ASYNC_BANK0_BASE && addr < ASYNC_BANK3_BASE + ASYNC_BANK3_SIZE) { 122 if (addr >= ASYNC_BANK0_BASE && addr < ASYNC_BANK3_BASE + ASYNC_BANK3_SIZE) {
123#if defined(CONFIG_ROMFS_ON_MTD) && defined(CONFIG_MTD_ROM)
124 mask = current_rwx_mask[cpu]; 123 mask = current_rwx_mask[cpu];
125 if (mask) { 124 if (mask) {
126 int page = (addr - (ASYNC_BANK0_BASE - _ramend)) >> PAGE_SHIFT; 125 int page = (addr - (ASYNC_BANK0_BASE - _ramend)) >> PAGE_SHIFT;
@@ -130,7 +129,6 @@ MGR_ATTR static noinline int dcplb_miss(unsigned int cpu)
130 if (mask[idx] & bit) 129 if (mask[idx] & bit)
131 d_data |= CPLB_USER_RD; 130 d_data |= CPLB_USER_RD;
132 } 131 }
133#endif
134 } else if (addr >= BOOT_ROM_START && addr < BOOT_ROM_START + BOOT_ROM_LENGTH 132 } else if (addr >= BOOT_ROM_START && addr < BOOT_ROM_START + BOOT_ROM_LENGTH
135 && (status & (FAULT_RW | FAULT_USERSUPV)) == FAULT_USERSUPV) { 133 && (status & (FAULT_RW | FAULT_USERSUPV)) == FAULT_USERSUPV) {
136 addr &= ~(1 * 1024 * 1024 - 1); 134 addr &= ~(1 * 1024 * 1024 - 1);
diff --git a/arch/blackfin/kernel/cplb-nompu/cplbinit.c b/arch/blackfin/kernel/cplb-nompu/cplbinit.c
index 34e96ce02aa..886e00014d7 100644
--- a/arch/blackfin/kernel/cplb-nompu/cplbinit.c
+++ b/arch/blackfin/kernel/cplb-nompu/cplbinit.c
@@ -58,20 +58,12 @@ void __init generate_cplb_tables_cpu(unsigned int cpu)
58 58
59#ifdef CONFIG_ROMKERNEL 59#ifdef CONFIG_ROMKERNEL
60 /* Cover kernel XIP flash area */ 60 /* Cover kernel XIP flash area */
61#ifdef CONFIG_BF60x
62 addr = CONFIG_ROM_BASE & ~(16 * 1024 * 1024 - 1);
63 d_tbl[i_d].addr = addr;
64 d_tbl[i_d++].data = SDRAM_DGENERIC | PAGE_SIZE_16MB;
65 i_tbl[i_i].addr = addr;
66 i_tbl[i_i++].data = SDRAM_IGENERIC | PAGE_SIZE_16MB;
67#else
68 addr = CONFIG_ROM_BASE & ~(4 * 1024 * 1024 - 1); 61 addr = CONFIG_ROM_BASE & ~(4 * 1024 * 1024 - 1);
69 d_tbl[i_d].addr = addr; 62 d_tbl[i_d].addr = addr;
70 d_tbl[i_d++].data = SDRAM_DGENERIC | PAGE_SIZE_4MB; 63 d_tbl[i_d++].data = SDRAM_DGENERIC | PAGE_SIZE_4MB;
71 i_tbl[i_i].addr = addr; 64 i_tbl[i_i].addr = addr;
72 i_tbl[i_i++].data = SDRAM_IGENERIC | PAGE_SIZE_4MB; 65 i_tbl[i_i++].data = SDRAM_IGENERIC | PAGE_SIZE_4MB;
73#endif 66#endif
74#endif
75 67
76 /* Cover L1 memory. One 4M area for code and data each is enough. */ 68 /* Cover L1 memory. One 4M area for code and data each is enough. */
77 if (cpu == 0) { 69 if (cpu == 0) {
@@ -147,7 +139,7 @@ void __init generate_cplb_tables_all(void)
147 dcplb_bounds[i_d].eaddr = BOOT_ROM_START; 139 dcplb_bounds[i_d].eaddr = BOOT_ROM_START;
148 dcplb_bounds[i_d++].data = 0; 140 dcplb_bounds[i_d++].data = 0;
149 /* BootROM -- largest one should be less than 1 meg. */ 141 /* BootROM -- largest one should be less than 1 meg. */
150 dcplb_bounds[i_d].eaddr = BOOT_ROM_START + BOOT_ROM_LENGTH; 142 dcplb_bounds[i_d].eaddr = BOOT_ROM_START + (1 * 1024 * 1024);
151 dcplb_bounds[i_d++].data = SDRAM_DGENERIC; 143 dcplb_bounds[i_d++].data = SDRAM_DGENERIC;
152 if (L2_LENGTH) { 144 if (L2_LENGTH) {
153 /* Addressing hole up to L2 SRAM. */ 145 /* Addressing hole up to L2 SRAM. */
@@ -186,7 +178,7 @@ void __init generate_cplb_tables_all(void)
186 icplb_bounds[i_i].eaddr = BOOT_ROM_START; 178 icplb_bounds[i_i].eaddr = BOOT_ROM_START;
187 icplb_bounds[i_i++].data = 0; 179 icplb_bounds[i_i++].data = 0;
188 /* BootROM -- largest one should be less than 1 meg. */ 180 /* BootROM -- largest one should be less than 1 meg. */
189 icplb_bounds[i_i].eaddr = BOOT_ROM_START + BOOT_ROM_LENGTH; 181 icplb_bounds[i_i].eaddr = BOOT_ROM_START + (1 * 1024 * 1024);
190 icplb_bounds[i_i++].data = SDRAM_IGENERIC; 182 icplb_bounds[i_i++].data = SDRAM_IGENERIC;
191 183
192 if (L2_LENGTH) { 184 if (L2_LENGTH) {
diff --git a/arch/blackfin/kernel/cplb-nompu/cplbmgr.c b/arch/blackfin/kernel/cplb-nompu/cplbmgr.c
index e854f9066cb..5b88861d618 100644
--- a/arch/blackfin/kernel/cplb-nompu/cplbmgr.c
+++ b/arch/blackfin/kernel/cplb-nompu/cplbmgr.c
@@ -179,12 +179,6 @@ MGR_ATTR static int dcplb_miss(int cpu)
179 addr = addr1; 179 addr = addr1;
180 } 180 }
181 181
182#ifdef CONFIG_BF60x
183 if ((addr >= ASYNC_BANK0_BASE)
184 && (addr < ASYNC_BANK3_BASE + ASYNC_BANK3_SIZE))
185 d_data |= PAGE_SIZE_64MB;
186#endif
187
188 /* Pick entry to evict */ 182 /* Pick entry to evict */
189 idx = evict_one_dcplb(cpu); 183 idx = evict_one_dcplb(cpu);
190 184
diff --git a/arch/blackfin/kernel/debug-mmrs.c b/arch/blackfin/kernel/debug-mmrs.c
index 01232a13470..92f66482628 100644
--- a/arch/blackfin/kernel/debug-mmrs.c
+++ b/arch/blackfin/kernel/debug-mmrs.c
@@ -105,7 +105,6 @@ DEFINE_SYSREG(seqstat, , );
105DEFINE_SYSREG(syscfg, , CSYNC()); 105DEFINE_SYSREG(syscfg, , CSYNC());
106#define D_SYSREG(sr) debugfs_create_file(#sr, S_IRUSR|S_IWUSR, parent, NULL, &fops_sysreg_##sr) 106#define D_SYSREG(sr) debugfs_create_file(#sr, S_IRUSR|S_IWUSR, parent, NULL, &fops_sysreg_##sr)
107 107
108#ifndef CONFIG_BF60x
109/* 108/*
110 * CAN 109 * CAN
111 */ 110 */
@@ -224,10 +223,8 @@ bfin_debug_mmrs_dma(struct dentry *parent, unsigned long base, int num, char mdm
224 __DMA(CURR_DESC_PTR, curr_desc_ptr); 223 __DMA(CURR_DESC_PTR, curr_desc_ptr);
225 __DMA(CURR_ADDR, curr_addr); 224 __DMA(CURR_ADDR, curr_addr);
226 __DMA(IRQ_STATUS, irq_status); 225 __DMA(IRQ_STATUS, irq_status);
227#ifndef CONFIG_BF60x
228 if (strcmp(pfx, "IMDMA") != 0) 226 if (strcmp(pfx, "IMDMA") != 0)
229 __DMA(PERIPHERAL_MAP, peripheral_map); 227 __DMA(PERIPHERAL_MAP, peripheral_map);
230#endif
231 __DMA(CURR_X_COUNT, curr_x_count); 228 __DMA(CURR_X_COUNT, curr_x_count);
232 __DMA(CURR_Y_COUNT, curr_y_count); 229 __DMA(CURR_Y_COUNT, curr_y_count);
233} 230}
@@ -571,7 +568,7 @@ bfin_debug_mmrs_uart(struct dentry *parent, unsigned long base, int num)
571#endif 568#endif
572} 569}
573#define UART(num) bfin_debug_mmrs_uart(parent, UART##num##_DLL, num) 570#define UART(num) bfin_debug_mmrs_uart(parent, UART##num##_DLL, num)
574#endif /* CONFIG_BF60x */ 571
575/* 572/*
576 * The actual debugfs generation 573 * The actual debugfs generation
577 */ 574 */
@@ -743,7 +740,7 @@ static int __init bfin_debug_mmrs_init(void)
743 D32(WPDACNT0); 740 D32(WPDACNT0);
744 D32(WPDACNT1); 741 D32(WPDACNT1);
745 D32(WPSTAT); 742 D32(WPSTAT);
746#ifndef CONFIG_BF60x 743
747 /* System MMRs */ 744 /* System MMRs */
748#ifdef ATAPI_CONTROL 745#ifdef ATAPI_CONTROL
749 parent = debugfs_create_dir("atapi", top); 746 parent = debugfs_create_dir("atapi", top);
@@ -1876,7 +1873,7 @@ static int __init bfin_debug_mmrs_init(void)
1876 1873
1877 } 1874 }
1878#endif /* BF54x */ 1875#endif /* BF54x */
1879#endif /* CONFIG_BF60x */ 1876
1880 debug_mmrs_dentry = top; 1877 debug_mmrs_dentry = top;
1881 1878
1882 return 0; 1879 return 0;
diff --git a/arch/blackfin/kernel/dma-mapping.c b/arch/blackfin/kernel/dma-mapping.c
index e7be6532d6a..04ddcfeb798 100644
--- a/arch/blackfin/kernel/dma-mapping.c
+++ b/arch/blackfin/kernel/dma-mapping.c
@@ -12,7 +12,6 @@
12#include <linux/spinlock.h> 12#include <linux/spinlock.h>
13#include <linux/dma-mapping.h> 13#include <linux/dma-mapping.h>
14#include <linux/scatterlist.h> 14#include <linux/scatterlist.h>
15#include <linux/export.h>
16 15
17static spinlock_t dma_page_lock; 16static spinlock_t dma_page_lock;
18static unsigned long *dma_page; 17static unsigned long *dma_page;
@@ -122,13 +121,12 @@ void __dma_sync(dma_addr_t addr, size_t size,
122EXPORT_SYMBOL(__dma_sync); 121EXPORT_SYMBOL(__dma_sync);
123 122
124int 123int
125dma_map_sg(struct device *dev, struct scatterlist *sg_list, int nents, 124dma_map_sg(struct device *dev, struct scatterlist *sg, int nents,
126 enum dma_data_direction direction) 125 enum dma_data_direction direction)
127{ 126{
128 struct scatterlist *sg;
129 int i; 127 int i;
130 128
131 for_each_sg(sg_list, sg, nents, i) { 129 for (i = 0; i < nents; i++, sg++) {
132 sg->dma_address = (dma_addr_t) sg_virt(sg); 130 sg->dma_address = (dma_addr_t) sg_virt(sg);
133 __dma_sync(sg_dma_address(sg), sg_dma_len(sg), direction); 131 __dma_sync(sg_dma_address(sg), sg_dma_len(sg), direction);
134 } 132 }
@@ -137,13 +135,12 @@ dma_map_sg(struct device *dev, struct scatterlist *sg_list, int nents,
137} 135}
138EXPORT_SYMBOL(dma_map_sg); 136EXPORT_SYMBOL(dma_map_sg);
139 137
140void dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg_list, 138void dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg,
141 int nelems, enum dma_data_direction direction) 139 int nelems, enum dma_data_direction direction)
142{ 140{
143 struct scatterlist *sg;
144 int i; 141 int i;
145 142
146 for_each_sg(sg_list, sg, nelems, i) { 143 for (i = 0; i < nelems; i++, sg++) {
147 sg->dma_address = (dma_addr_t) sg_virt(sg); 144 sg->dma_address = (dma_addr_t) sg_virt(sg);
148 __dma_sync(sg_dma_address(sg), sg_dma_len(sg), direction); 145 __dma_sync(sg_dma_address(sg), sg_dma_len(sg), direction);
149 } 146 }
diff --git a/arch/blackfin/kernel/entry.S b/arch/blackfin/kernel/entry.S
index 4071265fc4f..686478f5f66 100644
--- a/arch/blackfin/kernel/entry.S
+++ b/arch/blackfin/kernel/entry.S
@@ -46,14 +46,63 @@ ENTRY(_ret_from_fork)
46 SP += -12; 46 SP += -12;
47 pseudo_long_call _schedule_tail, p5; 47 pseudo_long_call _schedule_tail, p5;
48 SP += 12; 48 SP += 12;
49 p1 = [sp++]; 49 r0 = [sp + PT_IPEND];
50 r0 = [sp++]; 50 cc = bittst(r0,1);
51 cc = p1 == 0; 51 if cc jump .Lin_kernel;
52 if cc jump .Lfork;
53 sp += -12;
54 call (p1);
55 sp += 12;
56.Lfork:
57 RESTORE_CONTEXT 52 RESTORE_CONTEXT
58 rti; 53 rti;
54.Lin_kernel:
55 bitclr(r0,1);
56 [sp + PT_IPEND] = r0;
57 /* do a 'fake' RTI by jumping to [RETI]
58 * to avoid clearing supervisor mode in child
59 */
60 r0 = [sp + PT_PC];
61 [sp + PT_P0] = r0;
62
63 RESTORE_ALL_SYS
64 jump (p0);
59ENDPROC(_ret_from_fork) 65ENDPROC(_ret_from_fork)
66
67ENTRY(_sys_fork)
68 r0 = -EINVAL;
69#if (ANOMALY_05000371)
70 nop;
71 nop;
72 nop;
73#endif
74 rts;
75ENDPROC(_sys_fork)
76
77ENTRY(_sys_vfork)
78 r0 = sp;
79 r0 += 24;
80 [--sp] = rets;
81 SP += -12;
82 pseudo_long_call _bfin_vfork, p2;
83 SP += 12;
84 rets = [sp++];
85 rts;
86ENDPROC(_sys_vfork)
87
88ENTRY(_sys_clone)
89 r0 = sp;
90 r0 += 24;
91 [--sp] = rets;
92 SP += -12;
93 pseudo_long_call _bfin_clone, p2;
94 SP += 12;
95 rets = [sp++];
96 rts;
97ENDPROC(_sys_clone)
98
99ENTRY(_sys_rt_sigreturn)
100 r0 = sp;
101 r0 += 24;
102 [--sp] = rets;
103 SP += -12;
104 pseudo_long_call _do_rt_sigreturn, p2;
105 SP += 12;
106 rets = [sp++];
107 rts;
108ENDPROC(_sys_rt_sigreturn)
diff --git a/arch/blackfin/kernel/gptimers.c b/arch/blackfin/kernel/gptimers.c
index d776773d386..06459f4bf43 100644
--- a/arch/blackfin/kernel/gptimers.c
+++ b/arch/blackfin/kernel/gptimers.c
@@ -23,11 +23,7 @@
23 printk(KERN_DEBUG "%s:%s:%i: Assertion failed: " #expr "\n", __FILE__, __func__, __LINE__); 23 printk(KERN_DEBUG "%s:%s:%i: Assertion failed: " #expr "\n", __FILE__, __func__, __LINE__);
24#endif 24#endif
25 25
26#ifndef CONFIG_BF60x 26#define BFIN_TIMER_NUM_GROUP (BFIN_TIMER_OCTET(MAX_BLACKFIN_GPTIMERS - 1) + 1)
27# define BFIN_TIMER_NUM_GROUP (BFIN_TIMER_OCTET(MAX_BLACKFIN_GPTIMERS - 1) + 1)
28#else
29# define BFIN_TIMER_NUM_GROUP 1
30#endif
31 27
32static struct bfin_gptimer_regs * const timer_regs[MAX_BLACKFIN_GPTIMERS] = 28static struct bfin_gptimer_regs * const timer_regs[MAX_BLACKFIN_GPTIMERS] =
33{ 29{
@@ -162,74 +158,6 @@ uint32_t get_gptimer_count(unsigned int timer_id)
162} 158}
163EXPORT_SYMBOL(get_gptimer_count); 159EXPORT_SYMBOL(get_gptimer_count);
164 160
165#ifdef CONFIG_BF60x
166void set_gptimer_delay(unsigned int timer_id, uint32_t delay)
167{
168 tassert(timer_id < MAX_BLACKFIN_GPTIMERS);
169 bfin_write(&timer_regs[timer_id]->delay, delay);
170 SSYNC();
171}
172EXPORT_SYMBOL(set_gptimer_delay);
173
174uint32_t get_gptimer_delay(unsigned int timer_id)
175{
176 tassert(timer_id < MAX_BLACKFIN_GPTIMERS);
177 return bfin_read(&timer_regs[timer_id]->delay);
178}
179EXPORT_SYMBOL(get_gptimer_delay);
180#endif
181
182#ifdef CONFIG_BF60x
183int get_gptimer_intr(unsigned int timer_id)
184{
185 tassert(timer_id < MAX_BLACKFIN_GPTIMERS);
186 return !!(bfin_read(&group_regs[BFIN_TIMER_OCTET(timer_id)]->data_ilat) & timil_mask[timer_id]);
187}
188EXPORT_SYMBOL(get_gptimer_intr);
189
190void clear_gptimer_intr(unsigned int timer_id)
191{
192 tassert(timer_id < MAX_BLACKFIN_GPTIMERS);
193 bfin_write(&group_regs[BFIN_TIMER_OCTET(timer_id)]->data_ilat, timil_mask[timer_id]);
194}
195EXPORT_SYMBOL(clear_gptimer_intr);
196
197int get_gptimer_over(unsigned int timer_id)
198{
199 tassert(timer_id < MAX_BLACKFIN_GPTIMERS);
200 return !!(bfin_read(&group_regs[BFIN_TIMER_OCTET(timer_id)]->stat_ilat) & tovf_mask[timer_id]);
201}
202EXPORT_SYMBOL(get_gptimer_over);
203
204void clear_gptimer_over(unsigned int timer_id)
205{
206 tassert(timer_id < MAX_BLACKFIN_GPTIMERS);
207 bfin_write(&group_regs[BFIN_TIMER_OCTET(timer_id)]->stat_ilat, tovf_mask[timer_id]);
208}
209EXPORT_SYMBOL(clear_gptimer_over);
210
211int get_gptimer_run(unsigned int timer_id)
212{
213 tassert(timer_id < MAX_BLACKFIN_GPTIMERS);
214 return !!(bfin_read(&group_regs[BFIN_TIMER_OCTET(timer_id)]->run) & trun_mask[timer_id]);
215}
216EXPORT_SYMBOL(get_gptimer_run);
217
218uint32_t get_gptimer_status(unsigned int group)
219{
220 tassert(group < BFIN_TIMER_NUM_GROUP);
221 return bfin_read(&group_regs[group]->data_ilat);
222}
223EXPORT_SYMBOL(get_gptimer_status);
224
225void set_gptimer_status(unsigned int group, uint32_t value)
226{
227 tassert(group < BFIN_TIMER_NUM_GROUP);
228 bfin_write(&group_regs[group]->data_ilat, value);
229 SSYNC();
230}
231EXPORT_SYMBOL(set_gptimer_status);
232#else
233uint32_t get_gptimer_status(unsigned int group) 161uint32_t get_gptimer_status(unsigned int group)
234{ 162{
235 tassert(group < BFIN_TIMER_NUM_GROUP); 163 tassert(group < BFIN_TIMER_NUM_GROUP);
@@ -284,7 +212,6 @@ int get_gptimer_run(unsigned int timer_id)
284 return !!(read_gptimer_status(timer_id) & trun_mask[timer_id]); 212 return !!(read_gptimer_status(timer_id) & trun_mask[timer_id]);
285} 213}
286EXPORT_SYMBOL(get_gptimer_run); 214EXPORT_SYMBOL(get_gptimer_run);
287#endif
288 215
289void set_gptimer_config(unsigned int timer_id, uint16_t config) 216void set_gptimer_config(unsigned int timer_id, uint16_t config)
290{ 217{
@@ -304,12 +231,6 @@ EXPORT_SYMBOL(get_gptimer_config);
304void enable_gptimers(uint16_t mask) 231void enable_gptimers(uint16_t mask)
305{ 232{
306 int i; 233 int i;
307#ifdef CONFIG_BF60x
308 uint16_t imask;
309 imask = bfin_read16(TIMER_DATA_IMSK);
310 imask &= ~mask;
311 bfin_write16(TIMER_DATA_IMSK, imask);
312#endif
313 tassert((mask & ~BLACKFIN_GPTIMER_IDMASK) == 0); 234 tassert((mask & ~BLACKFIN_GPTIMER_IDMASK) == 0);
314 for (i = 0; i < BFIN_TIMER_NUM_GROUP; ++i) { 235 for (i = 0; i < BFIN_TIMER_NUM_GROUP; ++i) {
315 bfin_write(&group_regs[i]->enable, mask & 0xFF); 236 bfin_write(&group_regs[i]->enable, mask & 0xFF);
@@ -332,16 +253,12 @@ static void _disable_gptimers(uint16_t mask)
332 253
333void disable_gptimers(uint16_t mask) 254void disable_gptimers(uint16_t mask)
334{ 255{
335#ifndef CONFIG_BF60x
336 int i; 256 int i;
337 _disable_gptimers(mask); 257 _disable_gptimers(mask);
338 for (i = 0; i < MAX_BLACKFIN_GPTIMERS; ++i) 258 for (i = 0; i < MAX_BLACKFIN_GPTIMERS; ++i)
339 if (mask & (1 << i)) 259 if (mask & (1 << i))
340 bfin_write(&group_regs[BFIN_TIMER_OCTET(i)]->status, trun_mask[i]); 260 bfin_write(&group_regs[BFIN_TIMER_OCTET(i)]->status, trun_mask[i]);
341 SSYNC(); 261 SSYNC();
342#else
343 _disable_gptimers(mask);
344#endif
345} 262}
346EXPORT_SYMBOL(disable_gptimers); 263EXPORT_SYMBOL(disable_gptimers);
347 264
diff --git a/arch/blackfin/kernel/ipipe.c b/arch/blackfin/kernel/ipipe.c
index f657b38163e..dbe11220cc5 100644
--- a/arch/blackfin/kernel/ipipe.c
+++ b/arch/blackfin/kernel/ipipe.c
@@ -31,6 +31,7 @@
31#include <linux/kthread.h> 31#include <linux/kthread.h>
32#include <linux/unistd.h> 32#include <linux/unistd.h>
33#include <linux/io.h> 33#include <linux/io.h>
34#include <asm/system.h>
34#include <linux/atomic.h> 35#include <linux/atomic.h>
35#include <asm/irq_handler.h> 36#include <asm/irq_handler.h>
36 37
diff --git a/arch/blackfin/kernel/kgdb.c b/arch/blackfin/kernel/kgdb.c
index b882ce22c34..9b80b152435 100644
--- a/arch/blackfin/kernel/kgdb.c
+++ b/arch/blackfin/kernel/kgdb.c
@@ -329,9 +329,6 @@ static void bfin_disable_hw_debug(struct pt_regs *regs)
329} 329}
330 330
331#ifdef CONFIG_SMP 331#ifdef CONFIG_SMP
332extern void generic_exec_single(int cpu, struct call_single_data *data, int wait);
333static struct call_single_data kgdb_smp_ipi_data[NR_CPUS];
334
335void kgdb_passive_cpu_callback(void *info) 332void kgdb_passive_cpu_callback(void *info)
336{ 333{
337 kgdb_nmicallback(raw_smp_processor_id(), get_irq_regs()); 334 kgdb_nmicallback(raw_smp_processor_id(), get_irq_regs());
@@ -339,18 +336,12 @@ void kgdb_passive_cpu_callback(void *info)
339 336
340void kgdb_roundup_cpus(unsigned long flags) 337void kgdb_roundup_cpus(unsigned long flags)
341{ 338{
342 unsigned int cpu; 339 smp_call_function(kgdb_passive_cpu_callback, NULL, 0);
343
344 for (cpu = cpumask_first(cpu_online_mask); cpu < nr_cpu_ids;
345 cpu = cpumask_next(cpu, cpu_online_mask)) {
346 kgdb_smp_ipi_data[cpu].func = kgdb_passive_cpu_callback;
347 generic_exec_single(cpu, &kgdb_smp_ipi_data[cpu], 0);
348 }
349} 340}
350 341
351void kgdb_roundup_cpu(int cpu, unsigned long flags) 342void kgdb_roundup_cpu(int cpu, unsigned long flags)
352{ 343{
353 generic_exec_single(cpu, &kgdb_smp_ipi_data[cpu], 0); 344 smp_call_function_single(cpu, kgdb_passive_cpu_callback, NULL, 0);
354} 345}
355#endif 346#endif
356 347
diff --git a/arch/blackfin/kernel/kgdb_test.c b/arch/blackfin/kernel/kgdb_test.c
index 18ab004aea1..2a6e9dbb62a 100644
--- a/arch/blackfin/kernel/kgdb_test.c
+++ b/arch/blackfin/kernel/kgdb_test.c
@@ -13,6 +13,7 @@
13 13
14#include <asm/current.h> 14#include <asm/current.h>
15#include <asm/uaccess.h> 15#include <asm/uaccess.h>
16#include <asm/system.h>
16 17
17#include <asm/blackfin.h> 18#include <asm/blackfin.h>
18 19
@@ -49,7 +50,8 @@ void kgdb_l2_test(void)
49 50
50#endif 51#endif
51 52
52noinline int kgdb_test(char *name, int len, int count, int z) 53
54int kgdb_test(char *name, int len, int count, int z)
53{ 55{
54 pr_alert("kgdb name(%d): %s, %d, %d\n", len, name, count, z); 56 pr_alert("kgdb name(%d): %s, %d, %d\n", len, name, count, z);
55 count = z; 57 count = z;
diff --git a/arch/blackfin/kernel/perf_event.c b/arch/blackfin/kernel/perf_event.c
index e47d19ae3e0..04300f29c0e 100644
--- a/arch/blackfin/kernel/perf_event.c
+++ b/arch/blackfin/kernel/perf_event.c
@@ -24,7 +24,6 @@
24 */ 24 */
25 25
26#include <linux/kernel.h> 26#include <linux/kernel.h>
27#include <linux/export.h>
28#include <linux/init.h> 27#include <linux/init.h>
29#include <linux/perf_event.h> 28#include <linux/perf_event.h>
30#include <asm/bfin_pfmon.h> 29#include <asm/bfin_pfmon.h>
diff --git a/arch/blackfin/kernel/process.c b/arch/blackfin/kernel/process.c
index 3e16ad9b0a9..6a80a9e9fc4 100644
--- a/arch/blackfin/kernel/process.c
+++ b/arch/blackfin/kernel/process.c
@@ -19,7 +19,6 @@
19#include <asm/blackfin.h> 19#include <asm/blackfin.h>
20#include <asm/fixed_code.h> 20#include <asm/fixed_code.h>
21#include <asm/mem_map.h> 21#include <asm/mem_map.h>
22#include <asm/irq.h>
23 22
24asmlinkage void ret_from_fork(void); 23asmlinkage void ret_from_fork(void);
25 24
@@ -89,12 +88,10 @@ void cpu_idle(void)
89#endif 88#endif
90 if (!idle) 89 if (!idle)
91 idle = default_idle; 90 idle = default_idle;
92 tick_nohz_idle_enter(); 91 tick_nohz_stop_sched_tick(1);
93 rcu_idle_enter();
94 while (!need_resched()) 92 while (!need_resched())
95 idle(); 93 idle();
96 rcu_idle_exit(); 94 tick_nohz_restart_sched_tick();
97 tick_nohz_idle_exit();
98 preempt_enable_no_resched(); 95 preempt_enable_no_resched();
99 schedule(); 96 schedule();
100 preempt_disable(); 97 preempt_disable();
@@ -102,6 +99,40 @@ void cpu_idle(void)
102} 99}
103 100
104/* 101/*
102 * This gets run with P1 containing the
103 * function to call, and R1 containing
104 * the "args". Note P0 is clobbered on the way here.
105 */
106void kernel_thread_helper(void);
107__asm__(".section .text\n"
108 ".align 4\n"
109 "_kernel_thread_helper:\n\t"
110 "\tsp += -12;\n\t"
111 "\tr0 = r1;\n\t" "\tcall (p1);\n\t" "\tcall _do_exit;\n" ".previous");
112
113/*
114 * Create a kernel thread.
115 */
116pid_t kernel_thread(int (*fn) (void *), void *arg, unsigned long flags)
117{
118 struct pt_regs regs;
119
120 memset(&regs, 0, sizeof(regs));
121
122 regs.r1 = (unsigned long)arg;
123 regs.p1 = (unsigned long)fn;
124 regs.pc = (unsigned long)kernel_thread_helper;
125 regs.orig_p0 = -1;
126 /* Set bit 2 to tell ret_from_fork we should be returning to kernel
127 mode. */
128 regs.ipend = 0x8002;
129 __asm__ __volatile__("%0 = syscfg;":"=da"(regs.syscfg):);
130 return do_fork(flags | CLONE_VM | CLONE_UNTRACED, 0, &regs, 0, NULL,
131 NULL);
132}
133EXPORT_SYMBOL(kernel_thread);
134
135/*
105 * Do necessary setup to start up a newly executed thread. 136 * Do necessary setup to start up a newly executed thread.
106 * 137 *
107 * pass the data segment into user programs if it exists, 138 * pass the data segment into user programs if it exists,
@@ -127,48 +158,70 @@ void flush_thread(void)
127{ 158{
128} 159}
129 160
130asmlinkage int bfin_clone(unsigned long clone_flags, unsigned long newsp) 161asmlinkage int bfin_vfork(struct pt_regs *regs)
162{
163 return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, rdusp(), regs, 0, NULL,
164 NULL);
165}
166
167asmlinkage int bfin_clone(struct pt_regs *regs)
131{ 168{
169 unsigned long clone_flags;
170 unsigned long newsp;
171
132#ifdef __ARCH_SYNC_CORE_DCACHE 172#ifdef __ARCH_SYNC_CORE_DCACHE
133 if (current->nr_cpus_allowed == num_possible_cpus()) 173 if (current->rt.nr_cpus_allowed == num_possible_cpus())
134 set_cpus_allowed_ptr(current, cpumask_of(smp_processor_id())); 174 set_cpus_allowed_ptr(current, cpumask_of(smp_processor_id()));
135#endif 175#endif
136 if (newsp) 176
177 /* syscall2 puts clone_flags in r0 and usp in r1 */
178 clone_flags = regs->r0;
179 newsp = regs->r1;
180 if (!newsp)
181 newsp = rdusp();
182 else
137 newsp -= 12; 183 newsp -= 12;
138 return do_fork(clone_flags, newsp, 0, NULL, NULL); 184 return do_fork(clone_flags, newsp, regs, 0, NULL, NULL);
139} 185}
140 186
141int 187int
142copy_thread(unsigned long clone_flags, 188copy_thread(unsigned long clone_flags,
143 unsigned long usp, unsigned long topstk, 189 unsigned long usp, unsigned long topstk,
144 struct task_struct *p) 190 struct task_struct *p, struct pt_regs *regs)
145{ 191{
146 struct pt_regs *childregs; 192 struct pt_regs *childregs;
147 unsigned long *v;
148 193
149 childregs = (struct pt_regs *) (task_stack_page(p) + THREAD_SIZE) - 1; 194 childregs = (struct pt_regs *) (task_stack_page(p) + THREAD_SIZE) - 1;
150 v = ((unsigned long *)childregs) - 2; 195 *childregs = *regs;
151 if (unlikely(p->flags & PF_KTHREAD)) { 196 childregs->r0 = 0;
152 memset(childregs, 0, sizeof(struct pt_regs));
153 v[0] = usp;
154 v[1] = topstk;
155 childregs->orig_p0 = -1;
156 childregs->ipend = 0x8000;
157 __asm__ __volatile__("%0 = syscfg;":"=da"(childregs->syscfg):);
158 p->thread.usp = 0;
159 } else {
160 *childregs = *current_pt_regs();
161 childregs->r0 = 0;
162 p->thread.usp = usp ? : rdusp();
163 v[0] = v[1] = 0;
164 }
165 197
166 p->thread.ksp = (unsigned long)v; 198 p->thread.usp = usp;
199 p->thread.ksp = (unsigned long)childregs;
167 p->thread.pc = (unsigned long)ret_from_fork; 200 p->thread.pc = (unsigned long)ret_from_fork;
168 201
169 return 0; 202 return 0;
170} 203}
171 204
205/*
206 * sys_execve() executes a new program.
207 */
208asmlinkage int sys_execve(const char __user *name,
209 const char __user *const __user *argv,
210 const char __user *const __user *envp)
211{
212 int error;
213 char *filename;
214 struct pt_regs *regs = (struct pt_regs *)((&name) + 6);
215
216 filename = getname(name);
217 error = PTR_ERR(filename);
218 if (IS_ERR(filename))
219 return error;
220 error = do_execve(filename, argv, envp, regs);
221 putname(filename);
222 return error;
223}
224
172unsigned long get_wchan(struct task_struct *p) 225unsigned long get_wchan(struct task_struct *p)
173{ 226{
174 unsigned long fp, pc; 227 unsigned long fp, pc;
@@ -275,16 +328,12 @@ int in_mem_const(unsigned long addr, unsigned long size,
275{ 328{
276 return in_mem_const_off(addr, size, 0, const_addr, const_size); 329 return in_mem_const_off(addr, size, 0, const_addr, const_size);
277} 330}
278#ifdef CONFIG_BF60x
279#define ASYNC_ENABLED(bnum, bctlnum) 1
280#else
281#define ASYNC_ENABLED(bnum, bctlnum) \ 331#define ASYNC_ENABLED(bnum, bctlnum) \
282({ \ 332({ \
283 (bfin_read_EBIU_AMGCTL() & 0xe) < ((bnum + 1) << 1) ? 0 : \ 333 (bfin_read_EBIU_AMGCTL() & 0xe) < ((bnum + 1) << 1) ? 0 : \
284 bfin_read_EBIU_AMBCTL##bctlnum() & B##bnum##RDYEN ? 0 : \ 334 bfin_read_EBIU_AMBCTL##bctlnum() & B##bnum##RDYEN ? 0 : \
285 1; \ 335 1; \
286}) 336})
287#endif
288/* 337/*
289 * We can't read EBIU banks that aren't enabled or we end up hanging 338 * We can't read EBIU banks that aren't enabled or we end up hanging
290 * on the access to the async space. Make sure we validate accesses 339 * on the access to the async space. Make sure we validate accesses
diff --git a/arch/blackfin/kernel/ptrace.c b/arch/blackfin/kernel/ptrace.c
index e1f88e028cf..75089f80855 100644
--- a/arch/blackfin/kernel/ptrace.c
+++ b/arch/blackfin/kernel/ptrace.c
@@ -20,6 +20,7 @@
20 20
21#include <asm/page.h> 21#include <asm/page.h>
22#include <asm/pgtable.h> 22#include <asm/pgtable.h>
23#include <asm/system.h>
23#include <asm/processor.h> 24#include <asm/processor.h>
24#include <asm/asm-offsets.h> 25#include <asm/asm-offsets.h>
25#include <asm/dma.h> 26#include <asm/dma.h>
diff --git a/arch/blackfin/kernel/reboot.c b/arch/blackfin/kernel/reboot.c
index c4f50a32850..c4c0081b199 100644
--- a/arch/blackfin/kernel/reboot.c
+++ b/arch/blackfin/kernel/reboot.c
@@ -9,6 +9,7 @@
9#include <linux/interrupt.h> 9#include <linux/interrupt.h>
10#include <asm/bfin-global.h> 10#include <asm/bfin-global.h>
11#include <asm/reboot.h> 11#include <asm/reboot.h>
12#include <asm/system.h>
12#include <asm/bfrom.h> 13#include <asm/bfrom.h>
13 14
14/* A system soft reset makes external memory unusable so force 15/* A system soft reset makes external memory unusable so force
@@ -22,7 +23,6 @@
22__attribute__ ((__l1_text__, __noreturn__)) 23__attribute__ ((__l1_text__, __noreturn__))
23static void bfin_reset(void) 24static void bfin_reset(void)
24{ 25{
25#ifndef CONFIG_BF60x
26 if (!ANOMALY_05000353 && !ANOMALY_05000386) 26 if (!ANOMALY_05000353 && !ANOMALY_05000386)
27 bfrom_SoftReset((void *)(L1_SCRATCH_START + L1_SCRATCH_LENGTH - 20)); 27 bfrom_SoftReset((void *)(L1_SCRATCH_START + L1_SCRATCH_LENGTH - 20));
28 28
@@ -58,6 +58,7 @@ static void bfin_reset(void)
58 if (__SILICON_REVISION__ < 1 && bfin_revid() < 1) 58 if (__SILICON_REVISION__ < 1 && bfin_revid() < 1)
59 bfin_read_SWRST(); 59 bfin_read_SWRST();
60#endif 60#endif
61
61 /* Wait for the SWRST write to complete. Cannot rely on SSYNC 62 /* Wait for the SWRST write to complete. Cannot rely on SSYNC
62 * though as the System state is all reset now. 63 * though as the System state is all reset now.
63 */ 64 */
@@ -72,10 +73,6 @@ static void bfin_reset(void)
72 while (1) 73 while (1)
73 /* Issue core reset */ 74 /* Issue core reset */
74 asm("raise 1"); 75 asm("raise 1");
75#else
76 while (1)
77 bfin_write_RCU0_CTL(0x1);
78#endif
79} 76}
80 77
81__attribute__((weak)) 78__attribute__((weak))
@@ -86,6 +83,7 @@ void native_machine_restart(char *cmd)
86void machine_restart(char *cmd) 83void machine_restart(char *cmd)
87{ 84{
88 native_machine_restart(cmd); 85 native_machine_restart(cmd);
86 local_irq_disable();
89 if (smp_processor_id()) 87 if (smp_processor_id())
90 smp_call_function((void *)bfin_reset, 0, 1); 88 smp_call_function((void *)bfin_reset, 0, 1);
91 else 89 else
diff --git a/arch/blackfin/kernel/setup.c b/arch/blackfin/kernel/setup.c
index fb96e607adc..dfa2525a442 100644
--- a/arch/blackfin/kernel/setup.c
+++ b/arch/blackfin/kernel/setup.c
@@ -25,16 +25,11 @@
25#include <asm/cacheflush.h> 25#include <asm/cacheflush.h>
26#include <asm/blackfin.h> 26#include <asm/blackfin.h>
27#include <asm/cplbinit.h> 27#include <asm/cplbinit.h>
28#include <asm/clocks.h>
29#include <asm/div64.h> 28#include <asm/div64.h>
30#include <asm/cpu.h> 29#include <asm/cpu.h>
31#include <asm/fixed_code.h> 30#include <asm/fixed_code.h>
32#include <asm/early_printk.h> 31#include <asm/early_printk.h>
33#include <asm/irq_handler.h> 32#include <asm/irq_handler.h>
34#include <asm/pda.h>
35#ifdef CONFIG_BF60x
36#include <mach/pm.h>
37#endif
38 33
39u16 _bfin_swrst; 34u16 _bfin_swrst;
40EXPORT_SYMBOL(_bfin_swrst); 35EXPORT_SYMBOL(_bfin_swrst);
@@ -52,6 +47,7 @@ EXPORT_SYMBOL(reserved_mem_dcache_on);
52#ifdef CONFIG_MTD_UCLINUX 47#ifdef CONFIG_MTD_UCLINUX
53extern struct map_info uclinux_ram_map; 48extern struct map_info uclinux_ram_map;
54unsigned long memory_mtd_end, memory_mtd_start, mtd_size; 49unsigned long memory_mtd_end, memory_mtd_start, mtd_size;
50unsigned long _ebss;
55EXPORT_SYMBOL(memory_mtd_end); 51EXPORT_SYMBOL(memory_mtd_end);
56EXPORT_SYMBOL(memory_mtd_start); 52EXPORT_SYMBOL(memory_mtd_start);
57EXPORT_SYMBOL(mtd_size); 53EXPORT_SYMBOL(mtd_size);
@@ -614,8 +610,7 @@ static __init void memory_setup(void)
614 610
615 /* ROM_FS is XIP, so if we found it, we need to limit memory */ 611 /* ROM_FS is XIP, so if we found it, we need to limit memory */
616 if (memory_end > max_mem) { 612 if (memory_end > max_mem) {
617 pr_info("Limiting kernel memory to %liMB due to anomaly 05000263\n", 613 pr_info("Limiting kernel memory to %liMB due to anomaly 05000263\n", max_mem >> 20);
618 (max_mem - CONFIG_PHY_RAM_BASE_ADDRESS) >> 20);
619 memory_end = max_mem; 614 memory_end = max_mem;
620 } 615 }
621 } 616 }
@@ -645,8 +640,7 @@ static __init void memory_setup(void)
645 * doesn't exist, or we don't need to - then dont. 640 * doesn't exist, or we don't need to - then dont.
646 */ 641 */
647 if (memory_end > max_mem) { 642 if (memory_end > max_mem) {
648 pr_info("Limiting kernel memory to %liMB due to anomaly 05000263\n", 643 pr_info("Limiting kernel memory to %liMB due to anomaly 05000263\n", max_mem >> 20);
649 (max_mem - CONFIG_PHY_RAM_BASE_ADDRESS) >> 20);
650 memory_end = max_mem; 644 memory_end = max_mem;
651 } 645 }
652 646
@@ -665,8 +659,8 @@ static __init void memory_setup(void)
665 init_mm.end_data = (unsigned long)_edata; 659 init_mm.end_data = (unsigned long)_edata;
666 init_mm.brk = (unsigned long)0; 660 init_mm.brk = (unsigned long)0;
667 661
668 printk(KERN_INFO "Board Memory: %ldMB\n", (physical_mem_end - CONFIG_PHY_RAM_BASE_ADDRESS) >> 20); 662 printk(KERN_INFO "Board Memory: %ldMB\n", physical_mem_end >> 20);
669 printk(KERN_INFO "Kernel Managed Memory: %ldMB\n", (_ramend - CONFIG_PHY_RAM_BASE_ADDRESS) >> 20); 663 printk(KERN_INFO "Kernel Managed Memory: %ldMB\n", _ramend >> 20);
670 664
671 printk(KERN_INFO "Memory map:\n" 665 printk(KERN_INFO "Memory map:\n"
672 " fixedcode = 0x%p-0x%p\n" 666 " fixedcode = 0x%p-0x%p\n"
@@ -709,7 +703,7 @@ void __init find_min_max_pfn(void)
709 int i; 703 int i;
710 704
711 max_pfn = 0; 705 max_pfn = 0;
712 min_low_pfn = PFN_DOWN(memory_end); 706 min_low_pfn = memory_end;
713 707
714 for (i = 0; i < bfin_memmap.nr_map; i++) { 708 for (i = 0; i < bfin_memmap.nr_map; i++) {
715 unsigned long start, end; 709 unsigned long start, end;
@@ -752,7 +746,8 @@ static __init void setup_bootmem_allocator(void)
752 /* pfn of the first usable page frame after kernel image*/ 746 /* pfn of the first usable page frame after kernel image*/
753 if (min_low_pfn < memory_start >> PAGE_SHIFT) 747 if (min_low_pfn < memory_start >> PAGE_SHIFT)
754 min_low_pfn = memory_start >> PAGE_SHIFT; 748 min_low_pfn = memory_start >> PAGE_SHIFT;
755 start_pfn = CONFIG_PHY_RAM_BASE_ADDRESS >> PAGE_SHIFT; 749
750 start_pfn = PAGE_OFFSET >> PAGE_SHIFT;
756 end_pfn = memory_end >> PAGE_SHIFT; 751 end_pfn = memory_end >> PAGE_SHIFT;
757 752
758 /* 753 /*
@@ -797,8 +792,8 @@ static __init void setup_bootmem_allocator(void)
797 } 792 }
798 793
799 /* reserve memory before memory_start, including bootmap */ 794 /* reserve memory before memory_start, including bootmap */
800 reserve_bootmem(CONFIG_PHY_RAM_BASE_ADDRESS, 795 reserve_bootmem(PAGE_OFFSET,
801 memory_start + bootmap_size + PAGE_SIZE - 1 - CONFIG_PHY_RAM_BASE_ADDRESS, 796 memory_start + bootmap_size + PAGE_SIZE - 1 - PAGE_OFFSET,
802 BOOTMEM_DEFAULT); 797 BOOTMEM_DEFAULT);
803} 798}
804 799
@@ -833,54 +828,19 @@ static inline int __init get_mem_size(void)
833 u32 ddrctl = bfin_read_EBIU_DDRCTL1(); 828 u32 ddrctl = bfin_read_EBIU_DDRCTL1();
834 int ret = 0; 829 int ret = 0;
835 switch (ddrctl & 0xc0000) { 830 switch (ddrctl & 0xc0000) {
836 case DEVSZ_64: 831 case DEVSZ_64: ret = 64 / 8;
837 ret = 64 / 8; 832 case DEVSZ_128: ret = 128 / 8;
838 break; 833 case DEVSZ_256: ret = 256 / 8;
839 case DEVSZ_128: 834 case DEVSZ_512: ret = 512 / 8;
840 ret = 128 / 8;
841 break;
842 case DEVSZ_256:
843 ret = 256 / 8;
844 break;
845 case DEVSZ_512:
846 ret = 512 / 8;
847 break;
848 } 835 }
849 switch (ddrctl & 0x30000) { 836 switch (ddrctl & 0x30000) {
850 case DEVWD_4: 837 case DEVWD_4: ret *= 2;
851 ret *= 2; 838 case DEVWD_8: ret *= 2;
852 case DEVWD_8: 839 case DEVWD_16: break;
853 ret *= 2;
854 case DEVWD_16:
855 break;
856 } 840 }
857 if ((ddrctl & 0xc000) == 0x4000) 841 if ((ddrctl & 0xc000) == 0x4000)
858 ret *= 2; 842 ret *= 2;
859 return ret; 843 return ret;
860#elif defined(CONFIG_BF60x)
861 u32 ddrctl = bfin_read_DMC0_CFG();
862 int ret;
863 switch (ddrctl & 0xf00) {
864 case DEVSZ_64:
865 ret = 64 / 8;
866 break;
867 case DEVSZ_128:
868 ret = 128 / 8;
869 break;
870 case DEVSZ_256:
871 ret = 256 / 8;
872 break;
873 case DEVSZ_512:
874 ret = 512 / 8;
875 break;
876 case DEVSZ_1G:
877 ret = 1024 / 8;
878 break;
879 case DEVSZ_2G:
880 ret = 2048 / 8;
881 break;
882 }
883 return ret;
884#endif 844#endif
885 BUG(); 845 BUG();
886} 846}
@@ -890,22 +850,6 @@ void __init native_machine_early_platform_add_devices(void)
890{ 850{
891} 851}
892 852
893#ifdef CONFIG_BF60x
894static inline u_long bfin_get_clk(char *name)
895{
896 struct clk *clk;
897 u_long clk_rate;
898
899 clk = clk_get(NULL, name);
900 if (IS_ERR(clk))
901 return 0;
902
903 clk_rate = clk_get_rate(clk);
904 clk_put(clk);
905 return clk_rate;
906}
907#endif
908
909void __init setup_arch(char **cmdline_p) 853void __init setup_arch(char **cmdline_p)
910{ 854{
911 u32 mmr; 855 u32 mmr;
@@ -916,7 +860,6 @@ void __init setup_arch(char **cmdline_p)
916 enable_shadow_console(); 860 enable_shadow_console();
917 861
918 /* Check to make sure we are running on the right processor */ 862 /* Check to make sure we are running on the right processor */
919 mmr = bfin_cpuid();
920 if (unlikely(CPUID != bfin_cpuid())) 863 if (unlikely(CPUID != bfin_cpuid()))
921 printk(KERN_ERR "ERROR: Not running on ADSP-%s: unknown CPUID 0x%04x Rev 0.%d\n", 864 printk(KERN_ERR "ERROR: Not running on ADSP-%s: unknown CPUID 0x%04x Rev 0.%d\n",
922 CPU, bfin_cpuid(), bfin_revid()); 865 CPU, bfin_cpuid(), bfin_revid());
@@ -937,10 +880,6 @@ void __init setup_arch(char **cmdline_p)
937 880
938 memset(&bfin_memmap, 0, sizeof(bfin_memmap)); 881 memset(&bfin_memmap, 0, sizeof(bfin_memmap));
939 882
940#ifdef CONFIG_BF60x
941 /* Should init clock device before parse command early */
942 clk_init();
943#endif
944 /* If the user does not specify things on the command line, use 883 /* If the user does not specify things on the command line, use
945 * what the bootloader set things up as 884 * what the bootloader set things up as
946 */ 885 */
@@ -955,7 +894,6 @@ void __init setup_arch(char **cmdline_p)
955 894
956 memory_setup(); 895 memory_setup();
957 896
958#ifndef CONFIG_BF60x
959 /* Initialize Async memory banks */ 897 /* Initialize Async memory banks */
960 bfin_write_EBIU_AMBCTL0(AMBCTL0VAL); 898 bfin_write_EBIU_AMBCTL0(AMBCTL0VAL);
961 bfin_write_EBIU_AMBCTL1(AMBCTL1VAL); 899 bfin_write_EBIU_AMBCTL1(AMBCTL1VAL);
@@ -965,7 +903,6 @@ void __init setup_arch(char **cmdline_p)
965 bfin_write_EBIU_MODE(CONFIG_EBIU_MODEVAL); 903 bfin_write_EBIU_MODE(CONFIG_EBIU_MODEVAL);
966 bfin_write_EBIU_FCTL(CONFIG_EBIU_FCTLVAL); 904 bfin_write_EBIU_FCTL(CONFIG_EBIU_FCTLVAL);
967#endif 905#endif
968#endif
969#ifdef CONFIG_BFIN_HYSTERESIS_CONTROL 906#ifdef CONFIG_BFIN_HYSTERESIS_CONTROL
970 bfin_write_PORTF_HYSTERESIS(HYST_PORTF_0_15); 907 bfin_write_PORTF_HYSTERESIS(HYST_PORTF_0_15);
971 bfin_write_PORTG_HYSTERESIS(HYST_PORTG_0_15); 908 bfin_write_PORTG_HYSTERESIS(HYST_PORTG_0_15);
@@ -991,7 +928,7 @@ void __init setup_arch(char **cmdline_p)
991 printk(KERN_INFO "Hardware Trace %s and %sabled\n", 928 printk(KERN_INFO "Hardware Trace %s and %sabled\n",
992 (mmr & 0x1) ? "active" : "off", 929 (mmr & 0x1) ? "active" : "off",
993 (mmr & 0x2) ? "en" : "dis"); 930 (mmr & 0x2) ? "en" : "dis");
994#ifndef CONFIG_BF60x 931
995 mmr = bfin_read_SYSCR(); 932 mmr = bfin_read_SYSCR();
996 printk(KERN_INFO "Boot Mode: %i\n", mmr & 0xF); 933 printk(KERN_INFO "Boot Mode: %i\n", mmr & 0xF);
997 934
@@ -1033,7 +970,7 @@ void __init setup_arch(char **cmdline_p)
1033 printk(KERN_INFO "Recovering from Watchdog event\n"); 970 printk(KERN_INFO "Recovering from Watchdog event\n");
1034 else if (_bfin_swrst & RESET_SOFTWARE) 971 else if (_bfin_swrst & RESET_SOFTWARE)
1035 printk(KERN_NOTICE "Reset caused by Software reset\n"); 972 printk(KERN_NOTICE "Reset caused by Software reset\n");
1036#endif 973
1037 printk(KERN_INFO "Blackfin support (C) 2004-2010 Analog Devices, Inc.\n"); 974 printk(KERN_INFO "Blackfin support (C) 2004-2010 Analog Devices, Inc.\n");
1038 if (bfin_compiled_revid() == 0xffff) 975 if (bfin_compiled_revid() == 0xffff)
1039 printk(KERN_INFO "Compiled for ADSP-%s Rev any, running on 0.%d\n", CPU, bfin_revid()); 976 printk(KERN_INFO "Compiled for ADSP-%s Rev any, running on 0.%d\n", CPU, bfin_revid());
@@ -1061,13 +998,8 @@ void __init setup_arch(char **cmdline_p)
1061 998
1062 printk(KERN_INFO "Blackfin Linux support by http://blackfin.uclinux.org/\n"); 999 printk(KERN_INFO "Blackfin Linux support by http://blackfin.uclinux.org/\n");
1063 1000
1064#ifdef CONFIG_BF60x
1065 printk(KERN_INFO "Processor Speed: %lu MHz core clock, %lu MHz SCLk, %lu MHz SCLK0, %lu MHz SCLK1 and %lu MHz DCLK\n",
1066 cclk / 1000000, bfin_get_clk("SYSCLK") / 1000000, get_sclk0() / 1000000, get_sclk1() / 1000000, get_dclk() / 1000000);
1067#else
1068 printk(KERN_INFO "Processor Speed: %lu MHz core clock and %lu MHz System Clock\n", 1001 printk(KERN_INFO "Processor Speed: %lu MHz core clock and %lu MHz System Clock\n",
1069 cclk / 1000000, sclk / 1000000); 1002 cclk / 1000000, sclk / 1000000);
1070#endif
1071 1003
1072 setup_bootmem_allocator(); 1004 setup_bootmem_allocator();
1073 1005
@@ -1118,12 +1050,10 @@ subsys_initcall(topology_init);
1118 1050
1119/* Get the input clock frequency */ 1051/* Get the input clock frequency */
1120static u_long cached_clkin_hz = CONFIG_CLKIN_HZ; 1052static u_long cached_clkin_hz = CONFIG_CLKIN_HZ;
1121#ifndef CONFIG_BF60x
1122static u_long get_clkin_hz(void) 1053static u_long get_clkin_hz(void)
1123{ 1054{
1124 return cached_clkin_hz; 1055 return cached_clkin_hz;
1125} 1056}
1126#endif
1127static int __init early_init_clkin_hz(char *buf) 1057static int __init early_init_clkin_hz(char *buf)
1128{ 1058{
1129 cached_clkin_hz = simple_strtoul(buf, NULL, 0); 1059 cached_clkin_hz = simple_strtoul(buf, NULL, 0);
@@ -1135,7 +1065,6 @@ static int __init early_init_clkin_hz(char *buf)
1135} 1065}
1136early_param("clkin_hz=", early_init_clkin_hz); 1066early_param("clkin_hz=", early_init_clkin_hz);
1137 1067
1138#ifndef CONFIG_BF60x
1139/* Get the voltage input multiplier */ 1068/* Get the voltage input multiplier */
1140static u_long get_vco(void) 1069static u_long get_vco(void)
1141{ 1070{
@@ -1158,14 +1087,10 @@ static u_long get_vco(void)
1158 cached_vco *= msel; 1087 cached_vco *= msel;
1159 return cached_vco; 1088 return cached_vco;
1160} 1089}
1161#endif
1162 1090
1163/* Get the Core clock */ 1091/* Get the Core clock */
1164u_long get_cclk(void) 1092u_long get_cclk(void)
1165{ 1093{
1166#ifdef CONFIG_BF60x
1167 return bfin_get_clk("CCLK");
1168#else
1169 static u_long cached_cclk_pll_div, cached_cclk; 1094 static u_long cached_cclk_pll_div, cached_cclk;
1170 u_long csel, ssel; 1095 u_long csel, ssel;
1171 1096
@@ -1185,39 +1110,12 @@ u_long get_cclk(void)
1185 else 1110 else
1186 cached_cclk = get_vco() >> csel; 1111 cached_cclk = get_vco() >> csel;
1187 return cached_cclk; 1112 return cached_cclk;
1188#endif
1189} 1113}
1190EXPORT_SYMBOL(get_cclk); 1114EXPORT_SYMBOL(get_cclk);
1191 1115
1192#ifdef CONFIG_BF60x 1116/* Get the System clock */
1193/* Get the bf60x clock of SCLK0 domain */
1194u_long get_sclk0(void)
1195{
1196 return bfin_get_clk("SCLK0");
1197}
1198EXPORT_SYMBOL(get_sclk0);
1199
1200/* Get the bf60x clock of SCLK1 domain */
1201u_long get_sclk1(void)
1202{
1203 return bfin_get_clk("SCLK1");
1204}
1205EXPORT_SYMBOL(get_sclk1);
1206
1207/* Get the bf60x DRAM clock */
1208u_long get_dclk(void)
1209{
1210 return bfin_get_clk("DCLK");
1211}
1212EXPORT_SYMBOL(get_dclk);
1213#endif
1214
1215/* Get the default system clock */
1216u_long get_sclk(void) 1117u_long get_sclk(void)
1217{ 1118{
1218#ifdef CONFIG_BF60x
1219 return get_sclk0();
1220#else
1221 static u_long cached_sclk; 1119 static u_long cached_sclk;
1222 u_long ssel; 1120 u_long ssel;
1223 1121
@@ -1238,7 +1136,6 @@ u_long get_sclk(void)
1238 1136
1239 cached_sclk = get_vco() / ssel; 1137 cached_sclk = get_vco() / ssel;
1240 return cached_sclk; 1138 return cached_sclk;
1241#endif
1242} 1139}
1243EXPORT_SYMBOL(get_sclk); 1140EXPORT_SYMBOL(get_sclk);
1244 1141
diff --git a/arch/blackfin/kernel/shadow_console.c b/arch/blackfin/kernel/shadow_console.c
index aeb8343eeb0..557e9fef406 100644
--- a/arch/blackfin/kernel/shadow_console.c
+++ b/arch/blackfin/kernel/shadow_console.c
@@ -15,9 +15,9 @@
15#include <asm/irq_handler.h> 15#include <asm/irq_handler.h>
16#include <asm/early_printk.h> 16#include <asm/early_printk.h>
17 17
18#define SHADOW_CONSOLE_START (CONFIG_PHY_RAM_BASE_ADDRESS + 0x500) 18#define SHADOW_CONSOLE_START (0x500)
19#define SHADOW_CONSOLE_END (CONFIG_PHY_RAM_BASE_ADDRESS + 0x1000) 19#define SHADOW_CONSOLE_END (0x1000)
20#define SHADOW_CONSOLE_MAGIC_LOC (CONFIG_PHY_RAM_BASE_ADDRESS + 0x4F0) 20#define SHADOW_CONSOLE_MAGIC_LOC (0x4F0)
21#define SHADOW_CONSOLE_MAGIC (0xDEADBEEF) 21#define SHADOW_CONSOLE_MAGIC (0xDEADBEEF)
22 22
23static __initdata char *shadow_console_buffer = (char *)SHADOW_CONSOLE_START; 23static __initdata char *shadow_console_buffer = (char *)SHADOW_CONSOLE_START;
diff --git a/arch/blackfin/kernel/signal.c b/arch/blackfin/kernel/signal.c
index 84b4be05840..d536f35d1f4 100644
--- a/arch/blackfin/kernel/signal.c
+++ b/arch/blackfin/kernel/signal.c
@@ -10,6 +10,7 @@
10#include <linux/tty.h> 10#include <linux/tty.h>
11#include <linux/personality.h> 11#include <linux/personality.h>
12#include <linux/binfmts.h> 12#include <linux/binfmts.h>
13#include <linux/freezer.h>
13#include <linux/uaccess.h> 14#include <linux/uaccess.h>
14#include <linux/tracehook.h> 15#include <linux/tracehook.h>
15 16
@@ -18,6 +19,8 @@
18#include <asm/fixed_code.h> 19#include <asm/fixed_code.h>
19#include <asm/syscall.h> 20#include <asm/syscall.h>
20 21
22#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
23
21/* Location of the trace bit in SYSCFG. */ 24/* Location of the trace bit in SYSCFG. */
22#define TRACE_BITS 0x0001 25#define TRACE_BITS 0x0001
23 26
@@ -82,9 +85,9 @@ rt_restore_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc, int *p
82 return err; 85 return err;
83} 86}
84 87
85asmlinkage int sys_rt_sigreturn(void) 88asmlinkage int do_rt_sigreturn(unsigned long __unused)
86{ 89{
87 struct pt_regs *regs = current_pt_regs(); 90 struct pt_regs *regs = (struct pt_regs *)__unused;
88 unsigned long usp = rdusp(); 91 unsigned long usp = rdusp();
89 struct rt_sigframe *frame = (struct rt_sigframe *)(usp); 92 struct rt_sigframe *frame = (struct rt_sigframe *)(usp);
90 sigset_t set; 93 sigset_t set;
@@ -95,7 +98,11 @@ asmlinkage int sys_rt_sigreturn(void)
95 if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set))) 98 if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set)))
96 goto badframe; 99 goto badframe;
97 100
98 set_current_blocked(&set); 101 sigdelsetmask(&set, ~_BLOCKABLE);
102 spin_lock_irq(&current->sighand->siglock);
103 current->blocked = set;
104 recalc_sigpending();
105 spin_unlock_irq(&current->sighand->siglock);
99 106
100 if (rt_restore_sigcontext(regs, &frame->uc.uc_mcontext, &r0)) 107 if (rt_restore_sigcontext(regs, &frame->uc.uc_mcontext, &r0))
101 goto badframe; 108 goto badframe;
@@ -186,22 +193,17 @@ setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t * info,
186 err |= copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set)); 193 err |= copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
187 194
188 if (err) 195 if (err)
189 return -EFAULT; 196 goto give_sigsegv;
190 197
191 /* Set up registers for signal handler */ 198 /* Set up registers for signal handler */
199 wrusp((unsigned long)frame);
192 if (current->personality & FDPIC_FUNCPTRS) { 200 if (current->personality & FDPIC_FUNCPTRS) {
193 struct fdpic_func_descriptor __user *funcptr = 201 struct fdpic_func_descriptor __user *funcptr =
194 (struct fdpic_func_descriptor *) ka->sa.sa_handler; 202 (struct fdpic_func_descriptor *) ka->sa.sa_handler;
195 u32 pc, p3; 203 __get_user(regs->pc, &funcptr->text);
196 err |= __get_user(pc, &funcptr->text); 204 __get_user(regs->p3, &funcptr->GOT);
197 err |= __get_user(p3, &funcptr->GOT);
198 if (err)
199 return -EFAULT;
200 regs->pc = pc;
201 regs->p3 = p3;
202 } else 205 } else
203 regs->pc = (unsigned long)ka->sa.sa_handler; 206 regs->pc = (unsigned long)ka->sa.sa_handler;
204 wrusp((unsigned long)frame);
205 regs->rets = SIGRETURN_STUB; 207 regs->rets = SIGRETURN_STUB;
206 208
207 regs->r0 = frame->sig; 209 regs->r0 = frame->sig;
@@ -209,6 +211,12 @@ setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t * info,
209 regs->r2 = (unsigned long)(&frame->uc); 211 regs->r2 = (unsigned long)(&frame->uc);
210 212
211 return 0; 213 return 0;
214
215 give_sigsegv:
216 if (sig == SIGSEGV)
217 ka->sa.sa_handler = SIG_DFL;
218 force_sig(SIGSEGV, current);
219 return -EFAULT;
212} 220}
213 221
214static inline void 222static inline void
@@ -244,21 +252,30 @@ handle_restart(struct pt_regs *regs, struct k_sigaction *ka, int has_handler)
244/* 252/*
245 * OK, we're invoking a handler 253 * OK, we're invoking a handler
246 */ 254 */
247static void 255static int
248handle_signal(int sig, siginfo_t *info, struct k_sigaction *ka, 256handle_signal(int sig, siginfo_t *info, struct k_sigaction *ka,
249 struct pt_regs *regs) 257 sigset_t *oldset, struct pt_regs *regs)
250{ 258{
259 int ret;
260
251 /* are we from a system call? to see pt_regs->orig_p0 */ 261 /* are we from a system call? to see pt_regs->orig_p0 */
252 if (regs->orig_p0 >= 0) 262 if (regs->orig_p0 >= 0)
253 /* If so, check system call restarting.. */ 263 /* If so, check system call restarting.. */
254 handle_restart(regs, ka, 1); 264 handle_restart(regs, ka, 1);
255 265
256 /* set up the stack frame */ 266 /* set up the stack frame */
257 if (setup_rt_frame(sig, ka, info, sigmask_to_save(), regs) < 0) 267 ret = setup_rt_frame(sig, ka, info, oldset, regs);
258 force_sigsegv(sig, current); 268
259 else 269 if (ret == 0) {
260 signal_delivered(sig, info, ka, regs, 270 spin_lock_irq(&current->sighand->siglock);
261 test_thread_flag(TIF_SINGLESTEP)); 271 sigorsets(&current->blocked, &current->blocked,
272 &ka->sa.sa_mask);
273 if (!(ka->sa.sa_flags & SA_NODEFER))
274 sigaddset(&current->blocked, sig);
275 recalc_sigpending();
276 spin_unlock_irq(&current->sighand->siglock);
277 }
278 return ret;
262} 279}
263 280
264/* 281/*
@@ -275,16 +292,37 @@ asmlinkage void do_signal(struct pt_regs *regs)
275 siginfo_t info; 292 siginfo_t info;
276 int signr; 293 int signr;
277 struct k_sigaction ka; 294 struct k_sigaction ka;
295 sigset_t *oldset;
278 296
279 current->thread.esp0 = (unsigned long)regs; 297 current->thread.esp0 = (unsigned long)regs;
280 298
299 if (try_to_freeze())
300 goto no_signal;
301
302 if (test_thread_flag(TIF_RESTORE_SIGMASK))
303 oldset = &current->saved_sigmask;
304 else
305 oldset = &current->blocked;
306
281 signr = get_signal_to_deliver(&info, &ka, regs, NULL); 307 signr = get_signal_to_deliver(&info, &ka, regs, NULL);
282 if (signr > 0) { 308 if (signr > 0) {
283 /* Whee! Actually deliver the signal. */ 309 /* Whee! Actually deliver the signal. */
284 handle_signal(signr, &info, &ka, regs); 310 if (handle_signal(signr, &info, &ka, oldset, regs) == 0) {
311 /* a signal was successfully delivered; the saved
312 * sigmask will have been stored in the signal frame,
313 * and will be restored by sigreturn, so we can simply
314 * clear the TIF_RESTORE_SIGMASK flag */
315 if (test_thread_flag(TIF_RESTORE_SIGMASK))
316 clear_thread_flag(TIF_RESTORE_SIGMASK);
317
318 tracehook_signal_handler(signr, &info, &ka, regs,
319 test_thread_flag(TIF_SINGLESTEP));
320 }
321
285 return; 322 return;
286 } 323 }
287 324
325 no_signal:
288 /* Did we come from a system call? */ 326 /* Did we come from a system call? */
289 if (regs->orig_p0 >= 0) 327 if (regs->orig_p0 >= 0)
290 /* Restart the system call - no handlers present */ 328 /* Restart the system call - no handlers present */
@@ -292,7 +330,10 @@ asmlinkage void do_signal(struct pt_regs *regs)
292 330
293 /* if there's no signal to deliver, we just put the saved sigmask 331 /* if there's no signal to deliver, we just put the saved sigmask
294 * back */ 332 * back */
295 restore_saved_sigmask(); 333 if (test_thread_flag(TIF_RESTORE_SIGMASK)) {
334 clear_thread_flag(TIF_RESTORE_SIGMASK);
335 sigprocmask(SIG_SETMASK, &current->saved_sigmask, NULL);
336 }
296} 337}
297 338
298/* 339/*
@@ -300,12 +341,14 @@ asmlinkage void do_signal(struct pt_regs *regs)
300 */ 341 */
301asmlinkage void do_notify_resume(struct pt_regs *regs) 342asmlinkage void do_notify_resume(struct pt_regs *regs)
302{ 343{
303 if (test_thread_flag(TIF_SIGPENDING)) 344 if (test_thread_flag(TIF_SIGPENDING) || test_thread_flag(TIF_RESTORE_SIGMASK))
304 do_signal(regs); 345 do_signal(regs);
305 346
306 if (test_thread_flag(TIF_NOTIFY_RESUME)) { 347 if (test_thread_flag(TIF_NOTIFY_RESUME)) {
307 clear_thread_flag(TIF_NOTIFY_RESUME); 348 clear_thread_flag(TIF_NOTIFY_RESUME);
308 tracehook_notify_resume(regs); 349 tracehook_notify_resume(regs);
350 if (current->replacement_session_keyring)
351 key_replace_session_keyring();
309 } 352 }
310} 353}
311 354
diff --git a/arch/blackfin/kernel/sys_bfin.c b/arch/blackfin/kernel/sys_bfin.c
index d998383cb95..89448ed7065 100644
--- a/arch/blackfin/kernel/sys_bfin.c
+++ b/arch/blackfin/kernel/sys_bfin.c
@@ -41,7 +41,6 @@ asmlinkage void *sys_dma_memcpy(void *dest, const void *src, size_t len)
41 41
42#if defined(CONFIG_FB) || defined(CONFIG_FB_MODULE) 42#if defined(CONFIG_FB) || defined(CONFIG_FB_MODULE)
43#include <linux/fb.h> 43#include <linux/fb.h>
44#include <linux/export.h>
45unsigned long get_fb_unmapped_area(struct file *filp, unsigned long orig_addr, 44unsigned long get_fb_unmapped_area(struct file *filp, unsigned long orig_addr,
46 unsigned long len, unsigned long pgoff, unsigned long flags) 45 unsigned long len, unsigned long pgoff, unsigned long flags)
47{ 46{
diff --git a/arch/blackfin/kernel/time-ts.c b/arch/blackfin/kernel/time-ts.c
index f608f02f29a..9e9b60d969d 100644
--- a/arch/blackfin/kernel/time-ts.c
+++ b/arch/blackfin/kernel/time-ts.c
@@ -66,14 +66,8 @@ void __init setup_gptimer0(void)
66{ 66{
67 disable_gptimers(TIMER0bit); 67 disable_gptimers(TIMER0bit);
68 68
69#ifdef CONFIG_BF60x
70 bfin_write16(TIMER_DATA_IMSK, 0);
71 set_gptimer_config(TIMER0_id, TIMER_OUT_DIS
72 | TIMER_MODE_PWM_CONT | TIMER_PULSE_HI | TIMER_IRQ_PER);
73#else
74 set_gptimer_config(TIMER0_id, \ 69 set_gptimer_config(TIMER0_id, \
75 TIMER_OUT_DIS | TIMER_PERIOD_CNT | TIMER_MODE_PWM); 70 TIMER_OUT_DIS | TIMER_PERIOD_CNT | TIMER_MODE_PWM);
76#endif
77 set_gptimer_period(TIMER0_id, -1); 71 set_gptimer_period(TIMER0_id, -1);
78 set_gptimer_pwidth(TIMER0_id, -2); 72 set_gptimer_pwidth(TIMER0_id, -2);
79 SSYNC(); 73 SSYNC();
@@ -141,15 +135,9 @@ static void bfin_gptmr0_set_mode(enum clock_event_mode mode,
141{ 135{
142 switch (mode) { 136 switch (mode) {
143 case CLOCK_EVT_MODE_PERIODIC: { 137 case CLOCK_EVT_MODE_PERIODIC: {
144#ifndef CONFIG_BF60x
145 set_gptimer_config(TIMER0_id, \ 138 set_gptimer_config(TIMER0_id, \
146 TIMER_OUT_DIS | TIMER_IRQ_ENA | \ 139 TIMER_OUT_DIS | TIMER_IRQ_ENA | \
147 TIMER_PERIOD_CNT | TIMER_MODE_PWM); 140 TIMER_PERIOD_CNT | TIMER_MODE_PWM);
148#else
149 set_gptimer_config(TIMER0_id, TIMER_OUT_DIS
150 | TIMER_MODE_PWM_CONT | TIMER_PULSE_HI | TIMER_IRQ_PER);
151#endif
152
153 set_gptimer_period(TIMER0_id, get_sclk() / HZ); 141 set_gptimer_period(TIMER0_id, get_sclk() / HZ);
154 set_gptimer_pwidth(TIMER0_id, get_sclk() / HZ - 1); 142 set_gptimer_pwidth(TIMER0_id, get_sclk() / HZ - 1);
155 enable_gptimers(TIMER0bit); 143 enable_gptimers(TIMER0bit);
@@ -157,14 +145,8 @@ static void bfin_gptmr0_set_mode(enum clock_event_mode mode,
157 } 145 }
158 case CLOCK_EVT_MODE_ONESHOT: 146 case CLOCK_EVT_MODE_ONESHOT:
159 disable_gptimers(TIMER0bit); 147 disable_gptimers(TIMER0bit);
160#ifndef CONFIG_BF60x
161 set_gptimer_config(TIMER0_id, \ 148 set_gptimer_config(TIMER0_id, \
162 TIMER_OUT_DIS | TIMER_IRQ_ENA | TIMER_MODE_PWM); 149 TIMER_OUT_DIS | TIMER_IRQ_ENA | TIMER_MODE_PWM);
163#else
164 set_gptimer_config(TIMER0_id, TIMER_OUT_DIS | TIMER_MODE_PWM
165 | TIMER_PULSE_HI | TIMER_IRQ_WID_DLY);
166#endif
167
168 set_gptimer_period(TIMER0_id, 0); 150 set_gptimer_period(TIMER0_id, 0);
169 break; 151 break;
170 case CLOCK_EVT_MODE_UNUSED: 152 case CLOCK_EVT_MODE_UNUSED:
@@ -178,7 +160,7 @@ static void bfin_gptmr0_set_mode(enum clock_event_mode mode,
178 160
179static void bfin_gptmr0_ack(void) 161static void bfin_gptmr0_ack(void)
180{ 162{
181 clear_gptimer_intr(TIMER0_id); 163 set_gptimer_status(TIMER_GROUP1, TIMER_STATUS_TIMIL0);
182} 164}
183 165
184static void __init bfin_gptmr0_init(void) 166static void __init bfin_gptmr0_init(void)
@@ -206,7 +188,8 @@ irqreturn_t bfin_gptmr0_interrupt(int irq, void *dev_id)
206 188
207static struct irqaction gptmr0_irq = { 189static struct irqaction gptmr0_irq = {
208 .name = "Blackfin GPTimer0", 190 .name = "Blackfin GPTimer0",
209 .flags = IRQF_TIMER | IRQF_IRQPOLL | IRQF_PERCPU, 191 .flags = IRQF_DISABLED | IRQF_TIMER | \
192 IRQF_IRQPOLL | IRQF_PERCPU,
210 .handler = bfin_gptmr0_interrupt, 193 .handler = bfin_gptmr0_interrupt,
211}; 194};
212 195
@@ -215,7 +198,7 @@ static struct clock_event_device clockevent_gptmr0 = {
215 .rating = 300, 198 .rating = 300,
216 .irq = IRQ_TIMER0, 199 .irq = IRQ_TIMER0,
217 .shift = 32, 200 .shift = 32,
218 .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT, 201 .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT,
219 .set_next_event = bfin_gptmr0_set_next_event, 202 .set_next_event = bfin_gptmr0_set_next_event,
220 .set_mode = bfin_gptmr0_set_mode, 203 .set_mode = bfin_gptmr0_set_mode,
221}; 204};
@@ -237,7 +220,7 @@ static void __init bfin_gptmr0_clockevent_init(struct clock_event_device *evt)
237 220
238#if defined(CONFIG_TICKSOURCE_CORETMR) 221#if defined(CONFIG_TICKSOURCE_CORETMR)
239/* per-cpu local core timer */ 222/* per-cpu local core timer */
240DEFINE_PER_CPU(struct clock_event_device, coretmr_events); 223static DEFINE_PER_CPU(struct clock_event_device, coretmr_events);
241 224
242static int bfin_coretmr_set_next_event(unsigned long cycles, 225static int bfin_coretmr_set_next_event(unsigned long cycles,
243 struct clock_event_device *evt) 226 struct clock_event_device *evt)
@@ -299,7 +282,6 @@ void bfin_coretmr_init(void)
299#ifdef CONFIG_CORE_TIMER_IRQ_L1 282#ifdef CONFIG_CORE_TIMER_IRQ_L1
300__attribute__((l1_text)) 283__attribute__((l1_text))
301#endif 284#endif
302
303irqreturn_t bfin_coretmr_interrupt(int irq, void *dev_id) 285irqreturn_t bfin_coretmr_interrupt(int irq, void *dev_id)
304{ 286{
305 int cpu = smp_processor_id(); 287 int cpu = smp_processor_id();
@@ -315,7 +297,8 @@ irqreturn_t bfin_coretmr_interrupt(int irq, void *dev_id)
315 297
316static struct irqaction coretmr_irq = { 298static struct irqaction coretmr_irq = {
317 .name = "Blackfin CoreTimer", 299 .name = "Blackfin CoreTimer",
318 .flags = IRQF_TIMER | IRQF_IRQPOLL | IRQF_PERCPU, 300 .flags = IRQF_DISABLED | IRQF_TIMER | \
301 IRQF_IRQPOLL | IRQF_PERCPU,
319 .handler = bfin_coretmr_interrupt, 302 .handler = bfin_coretmr_interrupt,
320}; 303};
321 304
@@ -325,16 +308,6 @@ void bfin_coretmr_clockevent_init(void)
325 unsigned int cpu = smp_processor_id(); 308 unsigned int cpu = smp_processor_id();
326 struct clock_event_device *evt = &per_cpu(coretmr_events, cpu); 309 struct clock_event_device *evt = &per_cpu(coretmr_events, cpu);
327 310
328#ifdef CONFIG_SMP
329 evt->broadcast = smp_timer_broadcast;
330#endif
331
332
333#ifdef CONFIG_SMP
334 evt->broadcast = smp_timer_broadcast;
335#endif
336
337
338 evt->name = "bfin_core_timer"; 311 evt->name = "bfin_core_timer";
339 evt->rating = 350; 312 evt->rating = 350;
340 evt->irq = -1; 313 evt->irq = -1;
diff --git a/arch/blackfin/kernel/time.c b/arch/blackfin/kernel/time.c
index 2310b249675..ceb2bf63dfe 100644
--- a/arch/blackfin/kernel/time.c
+++ b/arch/blackfin/kernel/time.c
@@ -25,6 +25,7 @@
25 25
26static struct irqaction bfin_timer_irq = { 26static struct irqaction bfin_timer_irq = {
27 .name = "Blackfin Timer Tick", 27 .name = "Blackfin Timer Tick",
28 .flags = IRQF_DISABLED
28}; 29};
29 30
30#if defined(CONFIG_IPIPE) 31#if defined(CONFIG_IPIPE)
diff --git a/arch/blackfin/kernel/trace.c b/arch/blackfin/kernel/trace.c
index f7f7a18abca..050db44fe91 100644
--- a/arch/blackfin/kernel/trace.c
+++ b/arch/blackfin/kernel/trace.c
@@ -10,8 +10,6 @@
10#include <linux/hardirq.h> 10#include <linux/hardirq.h>
11#include <linux/thread_info.h> 11#include <linux/thread_info.h>
12#include <linux/mm.h> 12#include <linux/mm.h>
13#include <linux/oom.h>
14#include <linux/sched.h>
15#include <linux/uaccess.h> 13#include <linux/uaccess.h>
16#include <linux/module.h> 14#include <linux/module.h>
17#include <linux/kallsyms.h> 15#include <linux/kallsyms.h>
@@ -23,13 +21,13 @@
23#include <asm/fixed_code.h> 21#include <asm/fixed_code.h>
24#include <asm/traps.h> 22#include <asm/traps.h>
25#include <asm/irq_handler.h> 23#include <asm/irq_handler.h>
26#include <asm/pda.h>
27 24
28void decode_address(char *buf, unsigned long address) 25void decode_address(char *buf, unsigned long address)
29{ 26{
30 struct task_struct *p; 27 struct task_struct *p;
31 struct mm_struct *mm; 28 struct mm_struct *mm;
32 unsigned long offset; 29 unsigned long flags, offset;
30 unsigned char in_atomic = (bfin_read_IPEND() & 0x10) || in_atomic();
33 struct rb_node *n; 31 struct rb_node *n;
34 32
35#ifdef CONFIG_KALLSYMS 33#ifdef CONFIG_KALLSYMS
@@ -113,17 +111,17 @@ void decode_address(char *buf, unsigned long address)
113 * mappings of all our processes and see if we can't be a whee 111 * mappings of all our processes and see if we can't be a whee
114 * bit more specific 112 * bit more specific
115 */ 113 */
116 read_lock(&tasklist_lock); 114 write_lock_irqsave(&tasklist_lock, flags);
117 for_each_process(p) { 115 for_each_process(p) {
118 struct task_struct *t; 116 mm = (in_atomic ? p->mm : get_task_mm(p));
119 117 if (!mm)
120 t = find_lock_task_mm(p);
121 if (!t)
122 continue; 118 continue;
123 119
124 mm = t->mm; 120 if (!down_read_trylock(&mm->mmap_sem)) {
125 if (!down_read_trylock(&mm->mmap_sem)) 121 if (!in_atomic)
126 goto __continue; 122 mmput(mm);
123 continue;
124 }
127 125
128 for (n = rb_first(&mm->mm_rb); n; n = rb_next(n)) { 126 for (n = rb_first(&mm->mm_rb); n; n = rb_next(n)) {
129 struct vm_area_struct *vma; 127 struct vm_area_struct *vma;
@@ -132,7 +130,7 @@ void decode_address(char *buf, unsigned long address)
132 130
133 if (address >= vma->vm_start && address < vma->vm_end) { 131 if (address >= vma->vm_start && address < vma->vm_end) {
134 char _tmpbuf[256]; 132 char _tmpbuf[256];
135 char *name = t->comm; 133 char *name = p->comm;
136 struct file *file = vma->vm_file; 134 struct file *file = vma->vm_file;
137 135
138 if (file) { 136 if (file) {
@@ -165,7 +163,8 @@ void decode_address(char *buf, unsigned long address)
165 name, vma->vm_start, vma->vm_end); 163 name, vma->vm_start, vma->vm_end);
166 164
167 up_read(&mm->mmap_sem); 165 up_read(&mm->mmap_sem);
168 task_unlock(t); 166 if (!in_atomic)
167 mmput(mm);
169 168
170 if (buf[0] == '\0') 169 if (buf[0] == '\0')
171 sprintf(buf, "[ %s ] dynamic memory", name); 170 sprintf(buf, "[ %s ] dynamic memory", name);
@@ -175,8 +174,8 @@ void decode_address(char *buf, unsigned long address)
175 } 174 }
176 175
177 up_read(&mm->mmap_sem); 176 up_read(&mm->mmap_sem);
178__continue: 177 if (!in_atomic)
179 task_unlock(t); 178 mmput(mm);
180 } 179 }
181 180
182 /* 181 /*
@@ -186,7 +185,7 @@ __continue:
186 sprintf(buf, "/* kernel dynamic memory */"); 185 sprintf(buf, "/* kernel dynamic memory */");
187 186
188done: 187done:
189 read_unlock(&tasklist_lock); 188 write_unlock_irqrestore(&tasklist_lock, flags);
190} 189}
191 190
192#define EXPAND_LEN ((1 << CONFIG_DEBUG_BFIN_HWTRACE_EXPAND_LEN) * 256 - 1) 191#define EXPAND_LEN ((1 << CONFIG_DEBUG_BFIN_HWTRACE_EXPAND_LEN) * 256 - 1)
diff --git a/arch/blackfin/kernel/traps.c b/arch/blackfin/kernel/traps.c
index de5c2c3ebd9..655f25d139a 100644
--- a/arch/blackfin/kernel/traps.c
+++ b/arch/blackfin/kernel/traps.c
@@ -17,7 +17,6 @@
17#include <asm/trace.h> 17#include <asm/trace.h>
18#include <asm/fixed_code.h> 18#include <asm/fixed_code.h>
19#include <asm/pseudo_instructions.h> 19#include <asm/pseudo_instructions.h>
20#include <asm/pda.h>
21 20
22#ifdef CONFIG_KGDB 21#ifdef CONFIG_KGDB
23# include <linux/kgdb.h> 22# include <linux/kgdb.h>