aboutsummaryrefslogtreecommitdiffstats
path: root/arch/blackfin/kernel
diff options
context:
space:
mode:
authorPatrick McHardy <kaber@trash.net>2011-04-13 07:32:28 -0400
committerPatrick McHardy <kaber@trash.net>2011-04-13 07:32:28 -0400
commitb32e3dc7860d00124fa432dba09667e647cb9bcc (patch)
tree2fa6e56f389431dfb84609d3d7572cad76e88e71 /arch/blackfin/kernel
parent6604271c5bc658a6067ed0c3deba4d89e0e50382 (diff)
parent96120d86fe302c006259baee9061eea9e1b9e486 (diff)
Merge branch 'master' of ssh://master.kernel.org/pub/scm/linux/kernel/git/kaber/nf-2.6
Diffstat (limited to 'arch/blackfin/kernel')
-rw-r--r--arch/blackfin/kernel/bfin_dma_5xx.c32
-rw-r--r--arch/blackfin/kernel/ipipe.c84
-rw-r--r--arch/blackfin/kernel/irqchip.c10
-rw-r--r--arch/blackfin/kernel/kgdb.c4
-rw-r--r--arch/blackfin/kernel/setup.c37
-rw-r--r--arch/blackfin/kernel/trace.c7
-rw-r--r--arch/blackfin/kernel/vmlinux.lds.S3
7 files changed, 107 insertions, 70 deletions
diff --git a/arch/blackfin/kernel/bfin_dma_5xx.c b/arch/blackfin/kernel/bfin_dma_5xx.c
index 1e485dfdc9f2..6ce8dce753c9 100644
--- a/arch/blackfin/kernel/bfin_dma_5xx.c
+++ b/arch/blackfin/kernel/bfin_dma_5xx.c
@@ -84,6 +84,24 @@ static int __init proc_dma_init(void)
84late_initcall(proc_dma_init); 84late_initcall(proc_dma_init);
85#endif 85#endif
86 86
87static void set_dma_peripheral_map(unsigned int channel, const char *device_id)
88{
89#ifdef CONFIG_BF54x
90 unsigned int per_map;
91
92 switch (channel) {
93 case CH_UART2_RX: per_map = 0xC << 12; break;
94 case CH_UART2_TX: per_map = 0xD << 12; break;
95 case CH_UART3_RX: per_map = 0xE << 12; break;
96 case CH_UART3_TX: per_map = 0xF << 12; break;
97 default: return;
98 }
99
100 if (strncmp(device_id, "BFIN_UART", 9) == 0)
101 dma_ch[channel].regs->peripheral_map = per_map;
102#endif
103}
104
87/** 105/**
88 * request_dma - request a DMA channel 106 * request_dma - request a DMA channel
89 * 107 *
@@ -111,19 +129,7 @@ int request_dma(unsigned int channel, const char *device_id)
111 return -EBUSY; 129 return -EBUSY;
112 } 130 }
113 131
114#ifdef CONFIG_BF54x 132 set_dma_peripheral_map(channel, device_id);
115 if (channel >= CH_UART2_RX && channel <= CH_UART3_TX) {
116 unsigned int per_map;
117 per_map = dma_ch[channel].regs->peripheral_map & 0xFFF;
118 if (strncmp(device_id, "BFIN_UART", 9) == 0)
119 dma_ch[channel].regs->peripheral_map = per_map |
120 ((channel - CH_UART2_RX + 0xC)<<12);
121 else
122 dma_ch[channel].regs->peripheral_map = per_map |
123 ((channel - CH_UART2_RX + 0x6)<<12);
124 }
125#endif
126
127 dma_ch[channel].device_id = device_id; 133 dma_ch[channel].device_id = device_id;
128 dma_ch[channel].irq = 0; 134 dma_ch[channel].irq = 0;
129 135
diff --git a/arch/blackfin/kernel/ipipe.c b/arch/blackfin/kernel/ipipe.c
index 3b1da4aff2a1..f37019c847c9 100644
--- a/arch/blackfin/kernel/ipipe.c
+++ b/arch/blackfin/kernel/ipipe.c
@@ -154,7 +154,7 @@ void __ipipe_handle_irq(unsigned irq, struct pt_regs *regs)
154 * pending for it. 154 * pending for it.
155 */ 155 */
156 if (test_bit(IPIPE_AHEAD_FLAG, &this_domain->flags) && 156 if (test_bit(IPIPE_AHEAD_FLAG, &this_domain->flags) &&
157 ipipe_head_cpudom_var(irqpend_himask) == 0) 157 !__ipipe_ipending_p(ipipe_head_cpudom_ptr()))
158 goto out; 158 goto out;
159 159
160 __ipipe_walk_pipeline(head); 160 __ipipe_walk_pipeline(head);
@@ -185,25 +185,21 @@ void __ipipe_disable_irqdesc(struct ipipe_domain *ipd, unsigned irq)
185} 185}
186EXPORT_SYMBOL(__ipipe_disable_irqdesc); 186EXPORT_SYMBOL(__ipipe_disable_irqdesc);
187 187
188int __ipipe_syscall_root(struct pt_regs *regs) 188asmlinkage int __ipipe_syscall_root(struct pt_regs *regs)
189{ 189{
190 struct ipipe_percpu_domain_data *p; 190 struct ipipe_percpu_domain_data *p;
191 unsigned long flags; 191 void (*hook)(void);
192 int ret; 192 int ret;
193 193
194 WARN_ON_ONCE(irqs_disabled_hw());
195
194 /* 196 /*
195 * We need to run the IRQ tail hook whenever we don't 197 * We need to run the IRQ tail hook each time we intercept a
196 * propagate a syscall to higher domains, because we know that 198 * syscall, because we know that important operations might be
197 * important operations might be pending there (e.g. Xenomai 199 * pending there (e.g. Xenomai deferred rescheduling).
198 * deferred rescheduling).
199 */ 200 */
200 201 hook = (__typeof__(hook))__ipipe_irq_tail_hook;
201 if (regs->orig_p0 < NR_syscalls) { 202 hook();
202 void (*hook)(void) = (void (*)(void))__ipipe_irq_tail_hook;
203 hook();
204 if ((current->flags & PF_EVNOTIFY) == 0)
205 return 0;
206 }
207 203
208 /* 204 /*
209 * This routine either returns: 205 * This routine either returns:
@@ -214,51 +210,47 @@ int __ipipe_syscall_root(struct pt_regs *regs)
214 * tail work has to be performed (for handling signals etc). 210 * tail work has to be performed (for handling signals etc).
215 */ 211 */
216 212
217 if (!__ipipe_event_monitored_p(IPIPE_EVENT_SYSCALL)) 213 if (!__ipipe_syscall_watched_p(current, regs->orig_p0) ||
214 !__ipipe_event_monitored_p(IPIPE_EVENT_SYSCALL))
218 return 0; 215 return 0;
219 216
220 ret = __ipipe_dispatch_event(IPIPE_EVENT_SYSCALL, regs); 217 ret = __ipipe_dispatch_event(IPIPE_EVENT_SYSCALL, regs);
221 218
222 flags = hard_local_irq_save(); 219 hard_local_irq_disable();
223 220
224 if (!__ipipe_root_domain_p) { 221 /*
225 hard_local_irq_restore(flags); 222 * This is the end of the syscall path, so we may
226 return 1; 223 * safely assume a valid Linux task stack here.
224 */
225 if (current->ipipe_flags & PF_EVTRET) {
226 current->ipipe_flags &= ~PF_EVTRET;
227 __ipipe_dispatch_event(IPIPE_EVENT_RETURN, regs);
227 } 228 }
228 229
229 p = ipipe_root_cpudom_ptr(); 230 if (!__ipipe_root_domain_p)
230 if ((p->irqpend_himask & IPIPE_IRQMASK_VIRT) != 0) 231 ret = -1;
231 __ipipe_sync_pipeline(IPIPE_IRQMASK_VIRT); 232 else {
233 p = ipipe_root_cpudom_ptr();
234 if (__ipipe_ipending_p(p))
235 __ipipe_sync_pipeline();
236 }
232 237
233 hard_local_irq_restore(flags); 238 hard_local_irq_enable();
234 239
235 return -ret; 240 return -ret;
236} 241}
237 242
238unsigned long ipipe_critical_enter(void (*syncfn) (void))
239{
240 unsigned long flags;
241
242 flags = hard_local_irq_save();
243
244 return flags;
245}
246
247void ipipe_critical_exit(unsigned long flags)
248{
249 hard_local_irq_restore(flags);
250}
251
252static void __ipipe_no_irqtail(void) 243static void __ipipe_no_irqtail(void)
253{ 244{
254} 245}
255 246
256int ipipe_get_sysinfo(struct ipipe_sysinfo *info) 247int ipipe_get_sysinfo(struct ipipe_sysinfo *info)
257{ 248{
258 info->ncpus = num_online_cpus(); 249 info->sys_nr_cpus = num_online_cpus();
259 info->cpufreq = ipipe_cpu_freq(); 250 info->sys_cpu_freq = ipipe_cpu_freq();
260 info->archdep.tmirq = IPIPE_TIMER_IRQ; 251 info->sys_hrtimer_irq = IPIPE_TIMER_IRQ;
261 info->archdep.tmfreq = info->cpufreq; 252 info->sys_hrtimer_freq = __ipipe_core_clock;
253 info->sys_hrclock_freq = __ipipe_core_clock;
262 254
263 return 0; 255 return 0;
264} 256}
@@ -289,6 +281,7 @@ int ipipe_trigger_irq(unsigned irq)
289asmlinkage void __ipipe_sync_root(void) 281asmlinkage void __ipipe_sync_root(void)
290{ 282{
291 void (*irq_tail_hook)(void) = (void (*)(void))__ipipe_irq_tail_hook; 283 void (*irq_tail_hook)(void) = (void (*)(void))__ipipe_irq_tail_hook;
284 struct ipipe_percpu_domain_data *p;
292 unsigned long flags; 285 unsigned long flags;
293 286
294 BUG_ON(irqs_disabled()); 287 BUG_ON(irqs_disabled());
@@ -300,19 +293,20 @@ asmlinkage void __ipipe_sync_root(void)
300 293
301 clear_thread_flag(TIF_IRQ_SYNC); 294 clear_thread_flag(TIF_IRQ_SYNC);
302 295
303 if (ipipe_root_cpudom_var(irqpend_himask) != 0) 296 p = ipipe_root_cpudom_ptr();
304 __ipipe_sync_pipeline(IPIPE_IRQMASK_ANY); 297 if (__ipipe_ipending_p(p))
298 __ipipe_sync_pipeline();
305 299
306 hard_local_irq_restore(flags); 300 hard_local_irq_restore(flags);
307} 301}
308 302
309void ___ipipe_sync_pipeline(unsigned long syncmask) 303void ___ipipe_sync_pipeline(void)
310{ 304{
311 if (__ipipe_root_domain_p && 305 if (__ipipe_root_domain_p &&
312 test_bit(IPIPE_SYNCDEFER_FLAG, &ipipe_root_cpudom_var(status))) 306 test_bit(IPIPE_SYNCDEFER_FLAG, &ipipe_root_cpudom_var(status)))
313 return; 307 return;
314 308
315 __ipipe_sync_stage(syncmask); 309 __ipipe_sync_stage();
316} 310}
317 311
318void __ipipe_disable_root_irqs_hw(void) 312void __ipipe_disable_root_irqs_hw(void)
diff --git a/arch/blackfin/kernel/irqchip.c b/arch/blackfin/kernel/irqchip.c
index 64cff54a8a58..1696d34f51c2 100644
--- a/arch/blackfin/kernel/irqchip.c
+++ b/arch/blackfin/kernel/irqchip.c
@@ -39,21 +39,23 @@ int show_interrupts(struct seq_file *p, void *v)
39 unsigned long flags; 39 unsigned long flags;
40 40
41 if (i < NR_IRQS) { 41 if (i < NR_IRQS) {
42 raw_spin_lock_irqsave(&irq_desc[i].lock, flags); 42 struct irq_desc *desc = irq_to_desc(i);
43 action = irq_desc[i].action; 43
44 raw_spin_lock_irqsave(&desc->lock, flags);
45 action = desc->action;
44 if (!action) 46 if (!action)
45 goto skip; 47 goto skip;
46 seq_printf(p, "%3d: ", i); 48 seq_printf(p, "%3d: ", i);
47 for_each_online_cpu(j) 49 for_each_online_cpu(j)
48 seq_printf(p, "%10u ", kstat_irqs_cpu(i, j)); 50 seq_printf(p, "%10u ", kstat_irqs_cpu(i, j));
49 seq_printf(p, " %8s", irq_desc[i].chip->name); 51 seq_printf(p, " %8s", irq_desc_get_chip(desc)->name);
50 seq_printf(p, " %s", action->name); 52 seq_printf(p, " %s", action->name);
51 for (action = action->next; action; action = action->next) 53 for (action = action->next; action; action = action->next)
52 seq_printf(p, " %s", action->name); 54 seq_printf(p, " %s", action->name);
53 55
54 seq_putc(p, '\n'); 56 seq_putc(p, '\n');
55 skip: 57 skip:
56 raw_spin_unlock_irqrestore(&irq_desc[i].lock, flags); 58 raw_spin_unlock_irqrestore(&desc->lock, flags);
57 } else if (i == NR_IRQS) { 59 } else if (i == NR_IRQS) {
58 seq_printf(p, "NMI: "); 60 seq_printf(p, "NMI: ");
59 for_each_online_cpu(j) 61 for_each_online_cpu(j)
diff --git a/arch/blackfin/kernel/kgdb.c b/arch/blackfin/kernel/kgdb.c
index eb92592fd80c..b8cfe34989e4 100644
--- a/arch/blackfin/kernel/kgdb.c
+++ b/arch/blackfin/kernel/kgdb.c
@@ -422,11 +422,7 @@ int kgdb_arch_handle_exception(int vector, int signo,
422 422
423struct kgdb_arch arch_kgdb_ops = { 423struct kgdb_arch arch_kgdb_ops = {
424 .gdb_bpt_instr = {0xa1}, 424 .gdb_bpt_instr = {0xa1},
425#ifdef CONFIG_SMP
426 .flags = KGDB_HW_BREAKPOINT|KGDB_THR_PROC_SWAP,
427#else
428 .flags = KGDB_HW_BREAKPOINT, 425 .flags = KGDB_HW_BREAKPOINT,
429#endif
430 .set_hw_breakpoint = bfin_set_hw_break, 426 .set_hw_breakpoint = bfin_set_hw_break,
431 .remove_hw_breakpoint = bfin_remove_hw_break, 427 .remove_hw_breakpoint = bfin_remove_hw_break,
432 .disable_hw_break = bfin_disable_hw_debug, 428 .disable_hw_break = bfin_disable_hw_debug,
diff --git a/arch/blackfin/kernel/setup.c b/arch/blackfin/kernel/setup.c
index ac71dc15cbdb..805c6132c779 100644
--- a/arch/blackfin/kernel/setup.c
+++ b/arch/blackfin/kernel/setup.c
@@ -215,11 +215,48 @@ void __init bfin_relocate_l1_mem(void)
215 215
216 early_dma_memcpy_done(); 216 early_dma_memcpy_done();
217 217
218#if defined(CONFIG_SMP) && defined(CONFIG_ICACHE_FLUSH_L1)
219 blackfin_iflush_l1_entry[0] = (unsigned long)blackfin_icache_flush_range_l1;
220#endif
221
218 /* if necessary, copy L2 text/data to L2 SRAM */ 222 /* if necessary, copy L2 text/data to L2 SRAM */
219 if (L2_LENGTH && l2_len) 223 if (L2_LENGTH && l2_len)
220 memcpy(_stext_l2, _l2_lma, l2_len); 224 memcpy(_stext_l2, _l2_lma, l2_len);
221} 225}
222 226
227#ifdef CONFIG_SMP
228void __init bfin_relocate_coreb_l1_mem(void)
229{
230 unsigned long text_l1_len = (unsigned long)_text_l1_len;
231 unsigned long data_l1_len = (unsigned long)_data_l1_len;
232 unsigned long data_b_l1_len = (unsigned long)_data_b_l1_len;
233
234 blackfin_dma_early_init();
235
236 /* if necessary, copy L1 text to L1 instruction SRAM */
237 if (L1_CODE_LENGTH && text_l1_len)
238 early_dma_memcpy((void *)COREB_L1_CODE_START, _text_l1_lma,
239 text_l1_len);
240
241 /* if necessary, copy L1 data to L1 data bank A SRAM */
242 if (L1_DATA_A_LENGTH && data_l1_len)
243 early_dma_memcpy((void *)COREB_L1_DATA_A_START, _data_l1_lma,
244 data_l1_len);
245
246 /* if necessary, copy L1 data B to L1 data bank B SRAM */
247 if (L1_DATA_B_LENGTH && data_b_l1_len)
248 early_dma_memcpy((void *)COREB_L1_DATA_B_START, _data_b_l1_lma,
249 data_b_l1_len);
250
251 early_dma_memcpy_done();
252
253#ifdef CONFIG_ICACHE_FLUSH_L1
254 blackfin_iflush_l1_entry[1] = (unsigned long)blackfin_icache_flush_range_l1 -
255 (unsigned long)_stext_l1 + COREB_L1_CODE_START;
256#endif
257}
258#endif
259
223#ifdef CONFIG_ROMKERNEL 260#ifdef CONFIG_ROMKERNEL
224void __init bfin_relocate_xip_data(void) 261void __init bfin_relocate_xip_data(void)
225{ 262{
diff --git a/arch/blackfin/kernel/trace.c b/arch/blackfin/kernel/trace.c
index 05b550891ce5..050db44fe919 100644
--- a/arch/blackfin/kernel/trace.c
+++ b/arch/blackfin/kernel/trace.c
@@ -912,10 +912,11 @@ void show_regs(struct pt_regs *fp)
912 /* if no interrupts are going off, don't print this out */ 912 /* if no interrupts are going off, don't print this out */
913 if (fp->ipend & ~0x3F) { 913 if (fp->ipend & ~0x3F) {
914 for (i = 0; i < (NR_IRQS - 1); i++) { 914 for (i = 0; i < (NR_IRQS - 1); i++) {
915 struct irq_desc *desc = irq_to_desc(i);
915 if (!in_atomic) 916 if (!in_atomic)
916 raw_spin_lock_irqsave(&irq_desc[i].lock, flags); 917 raw_spin_lock_irqsave(&desc->lock, flags);
917 918
918 action = irq_desc[i].action; 919 action = desc->action;
919 if (!action) 920 if (!action)
920 goto unlock; 921 goto unlock;
921 922
@@ -928,7 +929,7 @@ void show_regs(struct pt_regs *fp)
928 pr_cont("\n"); 929 pr_cont("\n");
929unlock: 930unlock:
930 if (!in_atomic) 931 if (!in_atomic)
931 raw_spin_unlock_irqrestore(&irq_desc[i].lock, flags); 932 raw_spin_unlock_irqrestore(&desc->lock, flags);
932 } 933 }
933 } 934 }
934 935
diff --git a/arch/blackfin/kernel/vmlinux.lds.S b/arch/blackfin/kernel/vmlinux.lds.S
index c40d07f708e8..854fa49f1c3e 100644
--- a/arch/blackfin/kernel/vmlinux.lds.S
+++ b/arch/blackfin/kernel/vmlinux.lds.S
@@ -136,7 +136,7 @@ SECTIONS
136 136
137 . = ALIGN(16); 137 . = ALIGN(16);
138 INIT_DATA_SECTION(16) 138 INIT_DATA_SECTION(16)
139 PERCPU(32, 4) 139 PERCPU(32, PAGE_SIZE)
140 140
141 .exit.data : 141 .exit.data :
142 { 142 {
@@ -176,6 +176,7 @@ SECTIONS
176 { 176 {
177 . = ALIGN(4); 177 . = ALIGN(4);
178 __stext_l1 = .; 178 __stext_l1 = .;
179 *(.l1.text.head)
179 *(.l1.text) 180 *(.l1.text)
180#ifdef CONFIG_SCHEDULE_L1 181#ifdef CONFIG_SCHEDULE_L1
181 SCHED_TEXT 182 SCHED_TEXT