diff options
Diffstat (limited to 'arch/blackfin/kernel')
-rw-r--r-- | arch/blackfin/kernel/bfin_dma_5xx.c | 86 | ||||
-rw-r--r-- | arch/blackfin/kernel/bfin_gpio.c | 18 | ||||
-rw-r--r-- | arch/blackfin/kernel/bfin_ksyms.c | 1 | ||||
-rw-r--r-- | arch/blackfin/kernel/cplb-mpu/cacheinit.c | 9 | ||||
-rw-r--r-- | arch/blackfin/kernel/cplb-mpu/cplbinit.c | 2 | ||||
-rw-r--r-- | arch/blackfin/kernel/cplb-nompu/cacheinit.c | 9 | ||||
-rw-r--r-- | arch/blackfin/kernel/early_printk.c | 16 | ||||
-rw-r--r-- | arch/blackfin/kernel/gptimers.c | 30 | ||||
-rw-r--r-- | arch/blackfin/kernel/ipipe.c | 9 | ||||
-rw-r--r-- | arch/blackfin/kernel/irqchip.c | 2 | ||||
-rw-r--r-- | arch/blackfin/kernel/kgdb.c | 60 | ||||
-rw-r--r-- | arch/blackfin/kernel/module.c | 22 | ||||
-rw-r--r-- | arch/blackfin/kernel/process.c | 3 | ||||
-rw-r--r-- | arch/blackfin/kernel/setup.c | 79 | ||||
-rw-r--r-- | arch/blackfin/kernel/sys_bfin.c | 5 | ||||
-rw-r--r-- | arch/blackfin/kernel/time-ts.c | 222 | ||||
-rw-r--r-- | arch/blackfin/kernel/time.c | 53 | ||||
-rw-r--r-- | arch/blackfin/kernel/traps.c | 52 | ||||
-rw-r--r-- | arch/blackfin/kernel/vmlinux.lds.S | 5 |
19 files changed, 482 insertions, 201 deletions
diff --git a/arch/blackfin/kernel/bfin_dma_5xx.c b/arch/blackfin/kernel/bfin_dma_5xx.c index 8531693fb48d..763ed84ba459 100644 --- a/arch/blackfin/kernel/bfin_dma_5xx.c +++ b/arch/blackfin/kernel/bfin_dma_5xx.c | |||
@@ -20,6 +20,11 @@ | |||
20 | #include <asm/dma.h> | 20 | #include <asm/dma.h> |
21 | #include <asm/uaccess.h> | 21 | #include <asm/uaccess.h> |
22 | 22 | ||
23 | /* | ||
24 | * To make sure we work around 05000119 - we always check DMA_DONE bit, | ||
25 | * never the DMA_RUN bit | ||
26 | */ | ||
27 | |||
23 | struct dma_channel dma_ch[MAX_DMA_CHANNELS]; | 28 | struct dma_channel dma_ch[MAX_DMA_CHANNELS]; |
24 | EXPORT_SYMBOL(dma_ch); | 29 | EXPORT_SYMBOL(dma_ch); |
25 | 30 | ||
@@ -232,6 +237,87 @@ void blackfin_dma_resume(void) | |||
232 | void __init blackfin_dma_early_init(void) | 237 | void __init blackfin_dma_early_init(void) |
233 | { | 238 | { |
234 | bfin_write_MDMA_S0_CONFIG(0); | 239 | bfin_write_MDMA_S0_CONFIG(0); |
240 | bfin_write_MDMA_S1_CONFIG(0); | ||
241 | } | ||
242 | |||
243 | void __init early_dma_memcpy(void *pdst, const void *psrc, size_t size) | ||
244 | { | ||
245 | unsigned long dst = (unsigned long)pdst; | ||
246 | unsigned long src = (unsigned long)psrc; | ||
247 | struct dma_register *dst_ch, *src_ch; | ||
248 | |||
249 | /* We assume that everything is 4 byte aligned, so include | ||
250 | * a basic sanity check | ||
251 | */ | ||
252 | BUG_ON(dst % 4); | ||
253 | BUG_ON(src % 4); | ||
254 | BUG_ON(size % 4); | ||
255 | |||
256 | /* Force a sync in case a previous config reset on this channel | ||
257 | * occurred. This is needed so subsequent writes to DMA registers | ||
258 | * are not spuriously lost/corrupted. | ||
259 | */ | ||
260 | __builtin_bfin_ssync(); | ||
261 | |||
262 | src_ch = 0; | ||
263 | /* Find an avalible memDMA channel */ | ||
264 | while (1) { | ||
265 | if (!src_ch || src_ch == (struct dma_register *)MDMA_S1_NEXT_DESC_PTR) { | ||
266 | dst_ch = (struct dma_register *)MDMA_D0_NEXT_DESC_PTR; | ||
267 | src_ch = (struct dma_register *)MDMA_S0_NEXT_DESC_PTR; | ||
268 | } else { | ||
269 | dst_ch = (struct dma_register *)MDMA_D1_NEXT_DESC_PTR; | ||
270 | src_ch = (struct dma_register *)MDMA_S1_NEXT_DESC_PTR; | ||
271 | } | ||
272 | |||
273 | if (!bfin_read16(&src_ch->cfg)) { | ||
274 | break; | ||
275 | } else { | ||
276 | if (bfin_read16(&src_ch->irq_status) & DMA_DONE) | ||
277 | bfin_write16(&src_ch->cfg, 0); | ||
278 | } | ||
279 | |||
280 | } | ||
281 | |||
282 | /* Destination */ | ||
283 | bfin_write32(&dst_ch->start_addr, dst); | ||
284 | bfin_write16(&dst_ch->x_count, size >> 2); | ||
285 | bfin_write16(&dst_ch->x_modify, 1 << 2); | ||
286 | bfin_write16(&dst_ch->irq_status, DMA_DONE | DMA_ERR); | ||
287 | |||
288 | /* Source */ | ||
289 | bfin_write32(&src_ch->start_addr, src); | ||
290 | bfin_write16(&src_ch->x_count, size >> 2); | ||
291 | bfin_write16(&src_ch->x_modify, 1 << 2); | ||
292 | bfin_write16(&src_ch->irq_status, DMA_DONE | DMA_ERR); | ||
293 | |||
294 | /* Enable */ | ||
295 | bfin_write16(&src_ch->cfg, DMAEN | WDSIZE_32); | ||
296 | bfin_write16(&dst_ch->cfg, WNR | DI_EN | DMAEN | WDSIZE_32); | ||
297 | |||
298 | /* Since we are atomic now, don't use the workaround ssync */ | ||
299 | __builtin_bfin_ssync(); | ||
300 | } | ||
301 | |||
302 | void __init early_dma_memcpy_done(void) | ||
303 | { | ||
304 | while ((bfin_read_MDMA_S0_CONFIG() && !(bfin_read_MDMA_D0_IRQ_STATUS() & DMA_DONE)) || | ||
305 | (bfin_read_MDMA_S1_CONFIG() && !(bfin_read_MDMA_D1_IRQ_STATUS() & DMA_DONE))) | ||
306 | continue; | ||
307 | |||
308 | bfin_write_MDMA_D0_IRQ_STATUS(DMA_DONE | DMA_ERR); | ||
309 | bfin_write_MDMA_D1_IRQ_STATUS(DMA_DONE | DMA_ERR); | ||
310 | /* | ||
311 | * Now that DMA is done, we would normally flush cache, but | ||
312 | * i/d cache isn't running this early, so we don't bother, | ||
313 | * and just clear out the DMA channel for next time | ||
314 | */ | ||
315 | bfin_write_MDMA_S0_CONFIG(0); | ||
316 | bfin_write_MDMA_S1_CONFIG(0); | ||
317 | bfin_write_MDMA_D0_CONFIG(0); | ||
318 | bfin_write_MDMA_D1_CONFIG(0); | ||
319 | |||
320 | __builtin_bfin_ssync(); | ||
235 | } | 321 | } |
236 | 322 | ||
237 | /** | 323 | /** |
diff --git a/arch/blackfin/kernel/bfin_gpio.c b/arch/blackfin/kernel/bfin_gpio.c index a0678da40532..beffa00a93c3 100644 --- a/arch/blackfin/kernel/bfin_gpio.c +++ b/arch/blackfin/kernel/bfin_gpio.c | |||
@@ -313,15 +313,6 @@ inline void portmux_setup(unsigned short per) | |||
313 | # define portmux_setup(...) do { } while (0) | 313 | # define portmux_setup(...) do { } while (0) |
314 | #endif | 314 | #endif |
315 | 315 | ||
316 | static int __init bfin_gpio_init(void) | ||
317 | { | ||
318 | printk(KERN_INFO "Blackfin GPIO Controller\n"); | ||
319 | |||
320 | return 0; | ||
321 | } | ||
322 | arch_initcall(bfin_gpio_init); | ||
323 | |||
324 | |||
325 | #ifndef CONFIG_BF54x | 316 | #ifndef CONFIG_BF54x |
326 | /*********************************************************** | 317 | /*********************************************************** |
327 | * | 318 | * |
@@ -1021,15 +1012,6 @@ int bfin_gpio_irq_request(unsigned gpio, const char *label) | |||
1021 | 1012 | ||
1022 | local_irq_save_hw(flags); | 1013 | local_irq_save_hw(flags); |
1023 | 1014 | ||
1024 | if (unlikely(reserved_gpio_irq_map[gpio_bank(gpio)] & gpio_bit(gpio))) { | ||
1025 | if (system_state == SYSTEM_BOOTING) | ||
1026 | dump_stack(); | ||
1027 | printk(KERN_ERR | ||
1028 | "bfin-gpio: GPIO %d is already reserved as gpio-irq !\n", | ||
1029 | gpio); | ||
1030 | local_irq_restore_hw(flags); | ||
1031 | return -EBUSY; | ||
1032 | } | ||
1033 | if (unlikely(reserved_peri_map[gpio_bank(gpio)] & gpio_bit(gpio))) { | 1015 | if (unlikely(reserved_peri_map[gpio_bank(gpio)] & gpio_bit(gpio))) { |
1034 | if (system_state == SYSTEM_BOOTING) | 1016 | if (system_state == SYSTEM_BOOTING) |
1035 | dump_stack(); | 1017 | dump_stack(); |
diff --git a/arch/blackfin/kernel/bfin_ksyms.c b/arch/blackfin/kernel/bfin_ksyms.c index 01f917d58b59..53e893ff708a 100644 --- a/arch/blackfin/kernel/bfin_ksyms.c +++ b/arch/blackfin/kernel/bfin_ksyms.c | |||
@@ -16,7 +16,6 @@ EXPORT_SYMBOL(bfin_return_from_exception); | |||
16 | 16 | ||
17 | /* All the Blackfin cache functions: mach-common/cache.S */ | 17 | /* All the Blackfin cache functions: mach-common/cache.S */ |
18 | EXPORT_SYMBOL(blackfin_dcache_invalidate_range); | 18 | EXPORT_SYMBOL(blackfin_dcache_invalidate_range); |
19 | EXPORT_SYMBOL(blackfin_icache_dcache_flush_range); | ||
20 | EXPORT_SYMBOL(blackfin_icache_flush_range); | 19 | EXPORT_SYMBOL(blackfin_icache_flush_range); |
21 | EXPORT_SYMBOL(blackfin_dcache_flush_range); | 20 | EXPORT_SYMBOL(blackfin_dcache_flush_range); |
22 | EXPORT_SYMBOL(blackfin_dflush_page); | 21 | EXPORT_SYMBOL(blackfin_dflush_page); |
diff --git a/arch/blackfin/kernel/cplb-mpu/cacheinit.c b/arch/blackfin/kernel/cplb-mpu/cacheinit.c index c6ff947f9d37..d5a86c3017f7 100644 --- a/arch/blackfin/kernel/cplb-mpu/cacheinit.c +++ b/arch/blackfin/kernel/cplb-mpu/cacheinit.c | |||
@@ -55,7 +55,14 @@ void __cpuinit bfin_dcache_init(struct cplb_entry *dcplb_tbl) | |||
55 | } | 55 | } |
56 | 56 | ||
57 | ctrl = bfin_read_DMEM_CONTROL(); | 57 | ctrl = bfin_read_DMEM_CONTROL(); |
58 | ctrl |= DMEM_CNTR; | 58 | |
59 | /* | ||
60 | * Anomaly notes: | ||
61 | * 05000287 - We implement workaround #2 - Change the DMEM_CONTROL | ||
62 | * register, so that the port preferences for DAG0 and DAG1 are set | ||
63 | * to port B | ||
64 | */ | ||
65 | ctrl |= DMEM_CNTR | PORT_PREF0 | (ANOMALY_05000287 ? PORT_PREF1 : 0); | ||
59 | bfin_write_DMEM_CONTROL(ctrl); | 66 | bfin_write_DMEM_CONTROL(ctrl); |
60 | SSYNC(); | 67 | SSYNC(); |
61 | } | 68 | } |
diff --git a/arch/blackfin/kernel/cplb-mpu/cplbinit.c b/arch/blackfin/kernel/cplb-mpu/cplbinit.c index 3e329a6ce041..c006a44527bf 100644 --- a/arch/blackfin/kernel/cplb-mpu/cplbinit.c +++ b/arch/blackfin/kernel/cplb-mpu/cplbinit.c | |||
@@ -64,7 +64,7 @@ void __init generate_cplb_tables_cpu(unsigned int cpu) | |||
64 | dcplb_tbl[cpu][i_d++].data = SDRAM_OOPS | PAGE_SIZE_1KB; | 64 | dcplb_tbl[cpu][i_d++].data = SDRAM_OOPS | PAGE_SIZE_1KB; |
65 | 65 | ||
66 | icplb_tbl[cpu][i_i].addr = 0; | 66 | icplb_tbl[cpu][i_i].addr = 0; |
67 | icplb_tbl[cpu][i_i++].data = i_cache | CPLB_USER_RD | PAGE_SIZE_1KB; | 67 | icplb_tbl[cpu][i_i++].data = CPLB_VALID | i_cache | CPLB_USER_RD | PAGE_SIZE_1KB; |
68 | 68 | ||
69 | /* Cover kernel memory with 4M pages. */ | 69 | /* Cover kernel memory with 4M pages. */ |
70 | addr = 0; | 70 | addr = 0; |
diff --git a/arch/blackfin/kernel/cplb-nompu/cacheinit.c b/arch/blackfin/kernel/cplb-nompu/cacheinit.c index c6ff947f9d37..d5a86c3017f7 100644 --- a/arch/blackfin/kernel/cplb-nompu/cacheinit.c +++ b/arch/blackfin/kernel/cplb-nompu/cacheinit.c | |||
@@ -55,7 +55,14 @@ void __cpuinit bfin_dcache_init(struct cplb_entry *dcplb_tbl) | |||
55 | } | 55 | } |
56 | 56 | ||
57 | ctrl = bfin_read_DMEM_CONTROL(); | 57 | ctrl = bfin_read_DMEM_CONTROL(); |
58 | ctrl |= DMEM_CNTR; | 58 | |
59 | /* | ||
60 | * Anomaly notes: | ||
61 | * 05000287 - We implement workaround #2 - Change the DMEM_CONTROL | ||
62 | * register, so that the port preferences for DAG0 and DAG1 are set | ||
63 | * to port B | ||
64 | */ | ||
65 | ctrl |= DMEM_CNTR | PORT_PREF0 | (ANOMALY_05000287 ? PORT_PREF1 : 0); | ||
59 | bfin_write_DMEM_CONTROL(ctrl); | 66 | bfin_write_DMEM_CONTROL(ctrl); |
60 | SSYNC(); | 67 | SSYNC(); |
61 | } | 68 | } |
diff --git a/arch/blackfin/kernel/early_printk.c b/arch/blackfin/kernel/early_printk.c index c8ad051742e2..3302719173ca 100644 --- a/arch/blackfin/kernel/early_printk.c +++ b/arch/blackfin/kernel/early_printk.c | |||
@@ -178,25 +178,15 @@ int __init setup_early_printk(char *buf) | |||
178 | 178 | ||
179 | asmlinkage void __init init_early_exception_vectors(void) | 179 | asmlinkage void __init init_early_exception_vectors(void) |
180 | { | 180 | { |
181 | u32 evt; | ||
181 | SSYNC(); | 182 | SSYNC(); |
182 | 183 | ||
183 | /* cannot program in software: | 184 | /* cannot program in software: |
184 | * evt0 - emulation (jtag) | 185 | * evt0 - emulation (jtag) |
185 | * evt1 - reset | 186 | * evt1 - reset |
186 | */ | 187 | */ |
187 | bfin_write_EVT2(early_trap); | 188 | for (evt = EVT2; evt <= EVT15; evt += 4) |
188 | bfin_write_EVT3(early_trap); | 189 | bfin_write32(evt, early_trap); |
189 | bfin_write_EVT5(early_trap); | ||
190 | bfin_write_EVT6(early_trap); | ||
191 | bfin_write_EVT7(early_trap); | ||
192 | bfin_write_EVT8(early_trap); | ||
193 | bfin_write_EVT9(early_trap); | ||
194 | bfin_write_EVT10(early_trap); | ||
195 | bfin_write_EVT11(early_trap); | ||
196 | bfin_write_EVT12(early_trap); | ||
197 | bfin_write_EVT13(early_trap); | ||
198 | bfin_write_EVT14(early_trap); | ||
199 | bfin_write_EVT15(early_trap); | ||
200 | CSYNC(); | 190 | CSYNC(); |
201 | 191 | ||
202 | /* Set all the return from interrupt, exception, NMI to a known place | 192 | /* Set all the return from interrupt, exception, NMI to a known place |
diff --git a/arch/blackfin/kernel/gptimers.c b/arch/blackfin/kernel/gptimers.c index 3a3e9615b002..7281a91d26b5 100644 --- a/arch/blackfin/kernel/gptimers.c +++ b/arch/blackfin/kernel/gptimers.c | |||
@@ -189,10 +189,10 @@ void set_gptimer_status(int group, uint32_t value) | |||
189 | } | 189 | } |
190 | EXPORT_SYMBOL(set_gptimer_status); | 190 | EXPORT_SYMBOL(set_gptimer_status); |
191 | 191 | ||
192 | uint16_t get_gptimer_intr(int timer_id) | 192 | int get_gptimer_intr(int timer_id) |
193 | { | 193 | { |
194 | tassert(timer_id < MAX_BLACKFIN_GPTIMERS); | 194 | tassert(timer_id < MAX_BLACKFIN_GPTIMERS); |
195 | return (group_regs[BFIN_TIMER_OCTET(timer_id)]->status & timil_mask[timer_id]) ? 1 : 0; | 195 | return !!(group_regs[BFIN_TIMER_OCTET(timer_id)]->status & timil_mask[timer_id]); |
196 | } | 196 | } |
197 | EXPORT_SYMBOL(get_gptimer_intr); | 197 | EXPORT_SYMBOL(get_gptimer_intr); |
198 | 198 | ||
@@ -203,10 +203,10 @@ void clear_gptimer_intr(int timer_id) | |||
203 | } | 203 | } |
204 | EXPORT_SYMBOL(clear_gptimer_intr); | 204 | EXPORT_SYMBOL(clear_gptimer_intr); |
205 | 205 | ||
206 | uint16_t get_gptimer_over(int timer_id) | 206 | int get_gptimer_over(int timer_id) |
207 | { | 207 | { |
208 | tassert(timer_id < MAX_BLACKFIN_GPTIMERS); | 208 | tassert(timer_id < MAX_BLACKFIN_GPTIMERS); |
209 | return (group_regs[BFIN_TIMER_OCTET(timer_id)]->status & tovf_mask[timer_id]) ? 1 : 0; | 209 | return !!(group_regs[BFIN_TIMER_OCTET(timer_id)]->status & tovf_mask[timer_id]); |
210 | } | 210 | } |
211 | EXPORT_SYMBOL(get_gptimer_over); | 211 | EXPORT_SYMBOL(get_gptimer_over); |
212 | 212 | ||
@@ -217,6 +217,13 @@ void clear_gptimer_over(int timer_id) | |||
217 | } | 217 | } |
218 | EXPORT_SYMBOL(clear_gptimer_over); | 218 | EXPORT_SYMBOL(clear_gptimer_over); |
219 | 219 | ||
220 | int get_gptimer_run(int timer_id) | ||
221 | { | ||
222 | tassert(timer_id < MAX_BLACKFIN_GPTIMERS); | ||
223 | return !!(group_regs[BFIN_TIMER_OCTET(timer_id)]->status & trun_mask[timer_id]); | ||
224 | } | ||
225 | EXPORT_SYMBOL(get_gptimer_run); | ||
226 | |||
220 | void set_gptimer_config(int timer_id, uint16_t config) | 227 | void set_gptimer_config(int timer_id, uint16_t config) |
221 | { | 228 | { |
222 | tassert(timer_id < MAX_BLACKFIN_GPTIMERS); | 229 | tassert(timer_id < MAX_BLACKFIN_GPTIMERS); |
@@ -244,7 +251,7 @@ void enable_gptimers(uint16_t mask) | |||
244 | } | 251 | } |
245 | EXPORT_SYMBOL(enable_gptimers); | 252 | EXPORT_SYMBOL(enable_gptimers); |
246 | 253 | ||
247 | void disable_gptimers(uint16_t mask) | 254 | static void _disable_gptimers(uint16_t mask) |
248 | { | 255 | { |
249 | int i; | 256 | int i; |
250 | uint16_t m = mask; | 257 | uint16_t m = mask; |
@@ -253,6 +260,12 @@ void disable_gptimers(uint16_t mask) | |||
253 | group_regs[i]->disable = m & 0xFF; | 260 | group_regs[i]->disable = m & 0xFF; |
254 | m >>= 8; | 261 | m >>= 8; |
255 | } | 262 | } |
263 | } | ||
264 | |||
265 | void disable_gptimers(uint16_t mask) | ||
266 | { | ||
267 | int i; | ||
268 | _disable_gptimers(mask); | ||
256 | for (i = 0; i < MAX_BLACKFIN_GPTIMERS; ++i) | 269 | for (i = 0; i < MAX_BLACKFIN_GPTIMERS; ++i) |
257 | if (mask & (1 << i)) | 270 | if (mask & (1 << i)) |
258 | group_regs[BFIN_TIMER_OCTET(i)]->status |= trun_mask[i]; | 271 | group_regs[BFIN_TIMER_OCTET(i)]->status |= trun_mask[i]; |
@@ -260,6 +273,13 @@ void disable_gptimers(uint16_t mask) | |||
260 | } | 273 | } |
261 | EXPORT_SYMBOL(disable_gptimers); | 274 | EXPORT_SYMBOL(disable_gptimers); |
262 | 275 | ||
276 | void disable_gptimers_sync(uint16_t mask) | ||
277 | { | ||
278 | _disable_gptimers(mask); | ||
279 | SSYNC(); | ||
280 | } | ||
281 | EXPORT_SYMBOL(disable_gptimers_sync); | ||
282 | |||
263 | void set_gptimer_pulse_hi(int timer_id) | 283 | void set_gptimer_pulse_hi(int timer_id) |
264 | { | 284 | { |
265 | tassert(timer_id < MAX_BLACKFIN_GPTIMERS); | 285 | tassert(timer_id < MAX_BLACKFIN_GPTIMERS); |
diff --git a/arch/blackfin/kernel/ipipe.c b/arch/blackfin/kernel/ipipe.c index a5de8d45424c..5fc424803a17 100644 --- a/arch/blackfin/kernel/ipipe.c +++ b/arch/blackfin/kernel/ipipe.c | |||
@@ -167,7 +167,7 @@ int __ipipe_check_root(void) | |||
167 | void __ipipe_enable_irqdesc(struct ipipe_domain *ipd, unsigned irq) | 167 | void __ipipe_enable_irqdesc(struct ipipe_domain *ipd, unsigned irq) |
168 | { | 168 | { |
169 | struct irq_desc *desc = irq_to_desc(irq); | 169 | struct irq_desc *desc = irq_to_desc(irq); |
170 | int prio = desc->ic_prio; | 170 | int prio = __ipipe_get_irq_priority(irq); |
171 | 171 | ||
172 | desc->depth = 0; | 172 | desc->depth = 0; |
173 | if (ipd != &ipipe_root && | 173 | if (ipd != &ipipe_root && |
@@ -178,8 +178,7 @@ EXPORT_SYMBOL(__ipipe_enable_irqdesc); | |||
178 | 178 | ||
179 | void __ipipe_disable_irqdesc(struct ipipe_domain *ipd, unsigned irq) | 179 | void __ipipe_disable_irqdesc(struct ipipe_domain *ipd, unsigned irq) |
180 | { | 180 | { |
181 | struct irq_desc *desc = irq_to_desc(irq); | 181 | int prio = __ipipe_get_irq_priority(irq); |
182 | int prio = desc->ic_prio; | ||
183 | 182 | ||
184 | if (ipd != &ipipe_root && | 183 | if (ipd != &ipipe_root && |
185 | atomic_dec_and_test(&__ipipe_irq_lvdepth[prio])) | 184 | atomic_dec_and_test(&__ipipe_irq_lvdepth[prio])) |
@@ -310,12 +309,16 @@ int ipipe_trigger_irq(unsigned irq) | |||
310 | 309 | ||
311 | asmlinkage void __ipipe_sync_root(void) | 310 | asmlinkage void __ipipe_sync_root(void) |
312 | { | 311 | { |
312 | void (*irq_tail_hook)(void) = (void (*)(void))__ipipe_irq_tail_hook; | ||
313 | unsigned long flags; | 313 | unsigned long flags; |
314 | 314 | ||
315 | BUG_ON(irqs_disabled()); | 315 | BUG_ON(irqs_disabled()); |
316 | 316 | ||
317 | local_irq_save_hw(flags); | 317 | local_irq_save_hw(flags); |
318 | 318 | ||
319 | if (irq_tail_hook) | ||
320 | irq_tail_hook(); | ||
321 | |||
319 | clear_thread_flag(TIF_IRQ_SYNC); | 322 | clear_thread_flag(TIF_IRQ_SYNC); |
320 | 323 | ||
321 | if (ipipe_root_cpudom_var(irqpend_himask) != 0) | 324 | if (ipipe_root_cpudom_var(irqpend_himask) != 0) |
diff --git a/arch/blackfin/kernel/irqchip.c b/arch/blackfin/kernel/irqchip.c index 401bd32aa499..6e31e935bb31 100644 --- a/arch/blackfin/kernel/irqchip.c +++ b/arch/blackfin/kernel/irqchip.c | |||
@@ -59,12 +59,14 @@ static struct irq_chip bad_chip = { | |||
59 | .unmask = dummy_mask_unmask_irq, | 59 | .unmask = dummy_mask_unmask_irq, |
60 | }; | 60 | }; |
61 | 61 | ||
62 | static int bad_stats; | ||
62 | static struct irq_desc bad_irq_desc = { | 63 | static struct irq_desc bad_irq_desc = { |
63 | .status = IRQ_DISABLED, | 64 | .status = IRQ_DISABLED, |
64 | .chip = &bad_chip, | 65 | .chip = &bad_chip, |
65 | .handle_irq = handle_bad_irq, | 66 | .handle_irq = handle_bad_irq, |
66 | .depth = 1, | 67 | .depth = 1, |
67 | .lock = __SPIN_LOCK_UNLOCKED(irq_desc->lock), | 68 | .lock = __SPIN_LOCK_UNLOCKED(irq_desc->lock), |
69 | .kstat_irqs = &bad_stats, | ||
68 | #ifdef CONFIG_SMP | 70 | #ifdef CONFIG_SMP |
69 | .affinity = CPU_MASK_ALL | 71 | .affinity = CPU_MASK_ALL |
70 | #endif | 72 | #endif |
diff --git a/arch/blackfin/kernel/kgdb.c b/arch/blackfin/kernel/kgdb.c index b163f6d3330d..da28f796ad78 100644 --- a/arch/blackfin/kernel/kgdb.c +++ b/arch/blackfin/kernel/kgdb.c | |||
@@ -466,7 +466,7 @@ static int validate_memory_access_address(unsigned long addr, int size) | |||
466 | int cpu = raw_smp_processor_id(); | 466 | int cpu = raw_smp_processor_id(); |
467 | 467 | ||
468 | if (size < 0) | 468 | if (size < 0) |
469 | return EFAULT; | 469 | return -EFAULT; |
470 | if (addr >= 0x1000 && (addr + size) <= physical_mem_end) | 470 | if (addr >= 0x1000 && (addr + size) <= physical_mem_end) |
471 | return 0; | 471 | return 0; |
472 | if (addr >= SYSMMR_BASE) | 472 | if (addr >= SYSMMR_BASE) |
@@ -498,7 +498,7 @@ static int validate_memory_access_address(unsigned long addr, int size) | |||
498 | if (IN_MEM(addr, size, L2_START, L2_LENGTH)) | 498 | if (IN_MEM(addr, size, L2_START, L2_LENGTH)) |
499 | return 0; | 499 | return 0; |
500 | 500 | ||
501 | return EFAULT; | 501 | return -EFAULT; |
502 | } | 502 | } |
503 | 503 | ||
504 | /* | 504 | /* |
@@ -508,14 +508,15 @@ static int validate_memory_access_address(unsigned long addr, int size) | |||
508 | int kgdb_mem2hex(char *mem, char *buf, int count) | 508 | int kgdb_mem2hex(char *mem, char *buf, int count) |
509 | { | 509 | { |
510 | char *tmp; | 510 | char *tmp; |
511 | int err = 0; | 511 | int err; |
512 | unsigned char *pch; | 512 | unsigned char *pch; |
513 | unsigned short mmr16; | 513 | unsigned short mmr16; |
514 | unsigned long mmr32; | 514 | unsigned long mmr32; |
515 | int cpu = raw_smp_processor_id(); | 515 | int cpu = raw_smp_processor_id(); |
516 | 516 | ||
517 | if (validate_memory_access_address((unsigned long)mem, count)) | 517 | err = validate_memory_access_address((unsigned long)mem, count); |
518 | return EFAULT; | 518 | if (err) |
519 | return err; | ||
519 | 520 | ||
520 | /* | 521 | /* |
521 | * We use the upper half of buf as an intermediate buffer for the | 522 | * We use the upper half of buf as an intermediate buffer for the |
@@ -533,7 +534,7 @@ int kgdb_mem2hex(char *mem, char *buf, int count) | |||
533 | *tmp++ = *pch++; | 534 | *tmp++ = *pch++; |
534 | tmp -= 2; | 535 | tmp -= 2; |
535 | } else | 536 | } else |
536 | err = EFAULT; | 537 | err = -EFAULT; |
537 | break; | 538 | break; |
538 | case 4: | 539 | case 4: |
539 | if ((unsigned int)mem % 4 == 0) { | 540 | if ((unsigned int)mem % 4 == 0) { |
@@ -545,10 +546,10 @@ int kgdb_mem2hex(char *mem, char *buf, int count) | |||
545 | *tmp++ = *pch++; | 546 | *tmp++ = *pch++; |
546 | tmp -= 4; | 547 | tmp -= 4; |
547 | } else | 548 | } else |
548 | err = EFAULT; | 549 | err = -EFAULT; |
549 | break; | 550 | break; |
550 | default: | 551 | default: |
551 | err = EFAULT; | 552 | err = -EFAULT; |
552 | } | 553 | } |
553 | } else if ((cpu == 0 && IN_MEM(mem, count, L1_CODE_START, L1_CODE_LENGTH)) | 554 | } else if ((cpu == 0 && IN_MEM(mem, count, L1_CODE_START, L1_CODE_LENGTH)) |
554 | #ifdef CONFIG_SMP | 555 | #ifdef CONFIG_SMP |
@@ -557,7 +558,7 @@ int kgdb_mem2hex(char *mem, char *buf, int count) | |||
557 | ) { | 558 | ) { |
558 | /* access L1 instruction SRAM*/ | 559 | /* access L1 instruction SRAM*/ |
559 | if (dma_memcpy(tmp, mem, count) == NULL) | 560 | if (dma_memcpy(tmp, mem, count) == NULL) |
560 | err = EFAULT; | 561 | err = -EFAULT; |
561 | } else | 562 | } else |
562 | err = probe_kernel_read(tmp, mem, count); | 563 | err = probe_kernel_read(tmp, mem, count); |
563 | 564 | ||
@@ -585,24 +586,24 @@ int kgdb_ebin2mem(char *buf, char *mem, int count) | |||
585 | char *tmp_new; | 586 | char *tmp_new; |
586 | unsigned short *mmr16; | 587 | unsigned short *mmr16; |
587 | unsigned long *mmr32; | 588 | unsigned long *mmr32; |
588 | int err = 0; | 589 | int err; |
589 | int size = 0; | 590 | int size; |
590 | int cpu = raw_smp_processor_id(); | 591 | int cpu = raw_smp_processor_id(); |
591 | 592 | ||
592 | tmp_old = tmp_new = buf; | 593 | tmp_old = tmp_new = buf; |
593 | 594 | ||
594 | while (count-- > 0) { | 595 | for (size = 0; size < count; ++size) { |
595 | if (*tmp_old == 0x7d) | 596 | if (*tmp_old == 0x7d) |
596 | *tmp_new = *(++tmp_old) ^ 0x20; | 597 | *tmp_new = *(++tmp_old) ^ 0x20; |
597 | else | 598 | else |
598 | *tmp_new = *tmp_old; | 599 | *tmp_new = *tmp_old; |
599 | tmp_new++; | 600 | tmp_new++; |
600 | tmp_old++; | 601 | tmp_old++; |
601 | size++; | ||
602 | } | 602 | } |
603 | 603 | ||
604 | if (validate_memory_access_address((unsigned long)mem, size)) | 604 | err = validate_memory_access_address((unsigned long)mem, size); |
605 | return EFAULT; | 605 | if (err) |
606 | return err; | ||
606 | 607 | ||
607 | if ((unsigned int)mem >= SYSMMR_BASE) { /*access MMR registers*/ | 608 | if ((unsigned int)mem >= SYSMMR_BASE) { /*access MMR registers*/ |
608 | switch (size) { | 609 | switch (size) { |
@@ -611,17 +612,17 @@ int kgdb_ebin2mem(char *buf, char *mem, int count) | |||
611 | mmr16 = (unsigned short *)buf; | 612 | mmr16 = (unsigned short *)buf; |
612 | *(unsigned short *)mem = *mmr16; | 613 | *(unsigned short *)mem = *mmr16; |
613 | } else | 614 | } else |
614 | return EFAULT; | 615 | err = -EFAULT; |
615 | break; | 616 | break; |
616 | case 4: | 617 | case 4: |
617 | if ((unsigned int)mem % 4 == 0) { | 618 | if ((unsigned int)mem % 4 == 0) { |
618 | mmr32 = (unsigned long *)buf; | 619 | mmr32 = (unsigned long *)buf; |
619 | *(unsigned long *)mem = *mmr32; | 620 | *(unsigned long *)mem = *mmr32; |
620 | } else | 621 | } else |
621 | return EFAULT; | 622 | err = -EFAULT; |
622 | break; | 623 | break; |
623 | default: | 624 | default: |
624 | return EFAULT; | 625 | err = -EFAULT; |
625 | } | 626 | } |
626 | } else if ((cpu == 0 && IN_MEM(mem, count, L1_CODE_START, L1_CODE_LENGTH)) | 627 | } else if ((cpu == 0 && IN_MEM(mem, count, L1_CODE_START, L1_CODE_LENGTH)) |
627 | #ifdef CONFIG_SMP | 628 | #ifdef CONFIG_SMP |
@@ -630,7 +631,7 @@ int kgdb_ebin2mem(char *buf, char *mem, int count) | |||
630 | ) { | 631 | ) { |
631 | /* access L1 instruction SRAM */ | 632 | /* access L1 instruction SRAM */ |
632 | if (dma_memcpy(mem, buf, size) == NULL) | 633 | if (dma_memcpy(mem, buf, size) == NULL) |
633 | err = EFAULT; | 634 | err = -EFAULT; |
634 | } else | 635 | } else |
635 | err = probe_kernel_write(mem, buf, size); | 636 | err = probe_kernel_write(mem, buf, size); |
636 | 637 | ||
@@ -648,10 +649,12 @@ int kgdb_hex2mem(char *buf, char *mem, int count) | |||
648 | char *tmp_hex; | 649 | char *tmp_hex; |
649 | unsigned short *mmr16; | 650 | unsigned short *mmr16; |
650 | unsigned long *mmr32; | 651 | unsigned long *mmr32; |
652 | int err; | ||
651 | int cpu = raw_smp_processor_id(); | 653 | int cpu = raw_smp_processor_id(); |
652 | 654 | ||
653 | if (validate_memory_access_address((unsigned long)mem, count)) | 655 | err = validate_memory_access_address((unsigned long)mem, count); |
654 | return EFAULT; | 656 | if (err) |
657 | return err; | ||
655 | 658 | ||
656 | /* | 659 | /* |
657 | * We use the upper half of buf as an intermediate buffer for the | 660 | * We use the upper half of buf as an intermediate buffer for the |
@@ -673,17 +676,17 @@ int kgdb_hex2mem(char *buf, char *mem, int count) | |||
673 | mmr16 = (unsigned short *)tmp_raw; | 676 | mmr16 = (unsigned short *)tmp_raw; |
674 | *(unsigned short *)mem = *mmr16; | 677 | *(unsigned short *)mem = *mmr16; |
675 | } else | 678 | } else |
676 | return EFAULT; | 679 | err = -EFAULT; |
677 | break; | 680 | break; |
678 | case 4: | 681 | case 4: |
679 | if ((unsigned int)mem % 4 == 0) { | 682 | if ((unsigned int)mem % 4 == 0) { |
680 | mmr32 = (unsigned long *)tmp_raw; | 683 | mmr32 = (unsigned long *)tmp_raw; |
681 | *(unsigned long *)mem = *mmr32; | 684 | *(unsigned long *)mem = *mmr32; |
682 | } else | 685 | } else |
683 | return EFAULT; | 686 | err = -EFAULT; |
684 | break; | 687 | break; |
685 | default: | 688 | default: |
686 | return EFAULT; | 689 | err = -EFAULT; |
687 | } | 690 | } |
688 | } else if ((cpu == 0 && IN_MEM(mem, count, L1_CODE_START, L1_CODE_LENGTH)) | 691 | } else if ((cpu == 0 && IN_MEM(mem, count, L1_CODE_START, L1_CODE_LENGTH)) |
689 | #ifdef CONFIG_SMP | 692 | #ifdef CONFIG_SMP |
@@ -692,10 +695,11 @@ int kgdb_hex2mem(char *buf, char *mem, int count) | |||
692 | ) { | 695 | ) { |
693 | /* access L1 instruction SRAM */ | 696 | /* access L1 instruction SRAM */ |
694 | if (dma_memcpy(mem, tmp_raw, count) == NULL) | 697 | if (dma_memcpy(mem, tmp_raw, count) == NULL) |
695 | return EFAULT; | 698 | err = -EFAULT; |
696 | } else | 699 | } else |
697 | return probe_kernel_write(mem, tmp_raw, count); | 700 | err = probe_kernel_write(mem, tmp_raw, count); |
698 | return 0; | 701 | |
702 | return err; | ||
699 | } | 703 | } |
700 | 704 | ||
701 | int kgdb_validate_break_address(unsigned long addr) | 705 | int kgdb_validate_break_address(unsigned long addr) |
@@ -715,7 +719,7 @@ int kgdb_validate_break_address(unsigned long addr) | |||
715 | if (IN_MEM(addr, BREAK_INSTR_SIZE, L2_START, L2_LENGTH)) | 719 | if (IN_MEM(addr, BREAK_INSTR_SIZE, L2_START, L2_LENGTH)) |
716 | return 0; | 720 | return 0; |
717 | 721 | ||
718 | return EFAULT; | 722 | return -EFAULT; |
719 | } | 723 | } |
720 | 724 | ||
721 | int kgdb_arch_set_breakpoint(unsigned long addr, char *saved_instr) | 725 | int kgdb_arch_set_breakpoint(unsigned long addr, char *saved_instr) |
diff --git a/arch/blackfin/kernel/module.c b/arch/blackfin/kernel/module.c index 1bd7f2d018a8..d5aee3626688 100644 --- a/arch/blackfin/kernel/module.c +++ b/arch/blackfin/kernel/module.c | |||
@@ -201,8 +201,8 @@ apply_relocate(Elf_Shdr * sechdrs, const char *strtab, | |||
201 | /* Arithmetic relocations are handled. */ | 201 | /* Arithmetic relocations are handled. */ |
202 | /* We do not expect LSETUP to be split and hence is not */ | 202 | /* We do not expect LSETUP to be split and hence is not */ |
203 | /* handled. */ | 203 | /* handled. */ |
204 | /* R_byte and R_byte2 are also not handled as the gas */ | 204 | /* R_BFIN_BYTE and R_BFIN_BYTE2 are also not handled as the */ |
205 | /* does not generate it. */ | 205 | /* gas does not generate it. */ |
206 | /*************************************************************************/ | 206 | /*************************************************************************/ |
207 | int | 207 | int |
208 | apply_relocate_add(Elf_Shdr * sechdrs, const char *strtab, | 208 | apply_relocate_add(Elf_Shdr * sechdrs, const char *strtab, |
@@ -243,8 +243,8 @@ apply_relocate_add(Elf_Shdr * sechdrs, const char *strtab, | |||
243 | #endif | 243 | #endif |
244 | switch (ELF32_R_TYPE(rel[i].r_info)) { | 244 | switch (ELF32_R_TYPE(rel[i].r_info)) { |
245 | 245 | ||
246 | case R_pcrel24: | 246 | case R_BFIN_PCREL24: |
247 | case R_pcrel24_jump_l: | 247 | case R_BFIN_PCREL24_JUMP_L: |
248 | /* Add the value, subtract its postition */ | 248 | /* Add the value, subtract its postition */ |
249 | location16 = | 249 | location16 = |
250 | (uint16_t *) (sechdrs[sechdrs[relsec].sh_info]. | 250 | (uint16_t *) (sechdrs[sechdrs[relsec].sh_info]. |
@@ -266,18 +266,18 @@ apply_relocate_add(Elf_Shdr * sechdrs, const char *strtab, | |||
266 | (*location16 & 0xff00) | (value >> 16 & 0x00ff); | 266 | (*location16 & 0xff00) | (value >> 16 & 0x00ff); |
267 | *(location16 + 1) = value & 0xffff; | 267 | *(location16 + 1) = value & 0xffff; |
268 | break; | 268 | break; |
269 | case R_pcrel12_jump: | 269 | case R_BFIN_PCREL12_JUMP: |
270 | case R_pcrel12_jump_s: | 270 | case R_BFIN_PCREL12_JUMP_S: |
271 | value -= (uint32_t) location32; | 271 | value -= (uint32_t) location32; |
272 | value >>= 1; | 272 | value >>= 1; |
273 | *location16 = (value & 0xfff); | 273 | *location16 = (value & 0xfff); |
274 | break; | 274 | break; |
275 | case R_pcrel10: | 275 | case R_BFIN_PCREL10: |
276 | value -= (uint32_t) location32; | 276 | value -= (uint32_t) location32; |
277 | value >>= 1; | 277 | value >>= 1; |
278 | *location16 = (value & 0x3ff); | 278 | *location16 = (value & 0x3ff); |
279 | break; | 279 | break; |
280 | case R_luimm16: | 280 | case R_BFIN_LUIMM16: |
281 | pr_debug("before %x after %x\n", *location16, | 281 | pr_debug("before %x after %x\n", *location16, |
282 | (value & 0xffff)); | 282 | (value & 0xffff)); |
283 | tmp = (value & 0xffff); | 283 | tmp = (value & 0xffff); |
@@ -286,7 +286,7 @@ apply_relocate_add(Elf_Shdr * sechdrs, const char *strtab, | |||
286 | } else | 286 | } else |
287 | *location16 = tmp; | 287 | *location16 = tmp; |
288 | break; | 288 | break; |
289 | case R_huimm16: | 289 | case R_BFIN_HUIMM16: |
290 | pr_debug("before %x after %x\n", *location16, | 290 | pr_debug("before %x after %x\n", *location16, |
291 | ((value >> 16) & 0xffff)); | 291 | ((value >> 16) & 0xffff)); |
292 | tmp = ((value >> 16) & 0xffff); | 292 | tmp = ((value >> 16) & 0xffff); |
@@ -295,10 +295,10 @@ apply_relocate_add(Elf_Shdr * sechdrs, const char *strtab, | |||
295 | } else | 295 | } else |
296 | *location16 = tmp; | 296 | *location16 = tmp; |
297 | break; | 297 | break; |
298 | case R_rimm16: | 298 | case R_BFIN_RIMM16: |
299 | *location16 = (value & 0xffff); | 299 | *location16 = (value & 0xffff); |
300 | break; | 300 | break; |
301 | case R_byte4_data: | 301 | case R_BFIN_BYTE4_DATA: |
302 | pr_debug("before %x after %x\n", *location32, value); | 302 | pr_debug("before %x after %x\n", *location32, value); |
303 | *location32 = value; | 303 | *location32 = value; |
304 | break; | 304 | break; |
diff --git a/arch/blackfin/kernel/process.c b/arch/blackfin/kernel/process.c index e040e03335ea..30d0843ed701 100644 --- a/arch/blackfin/kernel/process.c +++ b/arch/blackfin/kernel/process.c | |||
@@ -322,6 +322,9 @@ void finish_atomic_sections (struct pt_regs *regs) | |||
322 | } | 322 | } |
323 | 323 | ||
324 | #if defined(CONFIG_ACCESS_CHECK) | 324 | #if defined(CONFIG_ACCESS_CHECK) |
325 | #ifdef CONFIG_ACCESS_OK_L1 | ||
326 | __attribute__((l1_text)) | ||
327 | #endif | ||
325 | /* Return 1 if access to memory range is OK, 0 otherwise */ | 328 | /* Return 1 if access to memory range is OK, 0 otherwise */ |
326 | int _access_ok(unsigned long addr, unsigned long size) | 329 | int _access_ok(unsigned long addr, unsigned long size) |
327 | { | 330 | { |
diff --git a/arch/blackfin/kernel/setup.c b/arch/blackfin/kernel/setup.c index a58687bdee6a..80447f99c2b5 100644 --- a/arch/blackfin/kernel/setup.c +++ b/arch/blackfin/kernel/setup.c | |||
@@ -18,9 +18,12 @@ | |||
18 | #include <linux/tty.h> | 18 | #include <linux/tty.h> |
19 | #include <linux/pfn.h> | 19 | #include <linux/pfn.h> |
20 | 20 | ||
21 | #ifdef CONFIG_MTD_UCLINUX | ||
22 | #include <linux/mtd/map.h> | ||
21 | #include <linux/ext2_fs.h> | 23 | #include <linux/ext2_fs.h> |
22 | #include <linux/cramfs_fs.h> | 24 | #include <linux/cramfs_fs.h> |
23 | #include <linux/romfs_fs.h> | 25 | #include <linux/romfs_fs.h> |
26 | #endif | ||
24 | 27 | ||
25 | #include <asm/cplb.h> | 28 | #include <asm/cplb.h> |
26 | #include <asm/cacheflush.h> | 29 | #include <asm/cacheflush.h> |
@@ -45,6 +48,7 @@ EXPORT_SYMBOL(_ramend); | |||
45 | EXPORT_SYMBOL(reserved_mem_dcache_on); | 48 | EXPORT_SYMBOL(reserved_mem_dcache_on); |
46 | 49 | ||
47 | #ifdef CONFIG_MTD_UCLINUX | 50 | #ifdef CONFIG_MTD_UCLINUX |
51 | extern struct map_info uclinux_ram_map; | ||
48 | unsigned long memory_mtd_end, memory_mtd_start, mtd_size; | 52 | unsigned long memory_mtd_end, memory_mtd_start, mtd_size; |
49 | unsigned long _ebss; | 53 | unsigned long _ebss; |
50 | EXPORT_SYMBOL(memory_mtd_end); | 54 | EXPORT_SYMBOL(memory_mtd_end); |
@@ -150,40 +154,45 @@ void __init bfin_relocate_l1_mem(void) | |||
150 | unsigned long l1_data_b_length; | 154 | unsigned long l1_data_b_length; |
151 | unsigned long l2_length; | 155 | unsigned long l2_length; |
152 | 156 | ||
157 | /* | ||
158 | * due to the ALIGN(4) in the arch/blackfin/kernel/vmlinux.lds.S | ||
159 | * we know that everything about l1 text/data is nice and aligned, | ||
160 | * so copy by 4 byte chunks, and don't worry about overlapping | ||
161 | * src/dest. | ||
162 | * | ||
163 | * We can't use the dma_memcpy functions, since they can call | ||
164 | * scheduler functions which might be in L1 :( and core writes | ||
165 | * into L1 instruction cause bad access errors, so we are stuck, | ||
166 | * we are required to use DMA, but can't use the common dma | ||
167 | * functions. We can't use memcpy either - since that might be | ||
168 | * going to be in the relocated L1 | ||
169 | */ | ||
170 | |||
153 | blackfin_dma_early_init(); | 171 | blackfin_dma_early_init(); |
154 | 172 | ||
173 | /* if necessary, copy _stext_l1 to _etext_l1 to L1 instruction SRAM */ | ||
155 | l1_code_length = _etext_l1 - _stext_l1; | 174 | l1_code_length = _etext_l1 - _stext_l1; |
156 | if (l1_code_length > L1_CODE_LENGTH) | 175 | if (l1_code_length) |
157 | panic("L1 Instruction SRAM Overflow\n"); | 176 | early_dma_memcpy(_stext_l1, _l1_lma_start, l1_code_length); |
158 | /* cannot complain as printk is not available as yet. | ||
159 | * But we can continue booting and complain later! | ||
160 | */ | ||
161 | |||
162 | /* Copy _stext_l1 to _etext_l1 to L1 instruction SRAM */ | ||
163 | dma_memcpy(_stext_l1, _l1_lma_start, l1_code_length); | ||
164 | 177 | ||
178 | /* if necessary, copy _sdata_l1 to _sbss_l1 to L1 data bank A SRAM */ | ||
165 | l1_data_a_length = _sbss_l1 - _sdata_l1; | 179 | l1_data_a_length = _sbss_l1 - _sdata_l1; |
166 | if (l1_data_a_length > L1_DATA_A_LENGTH) | 180 | if (l1_data_a_length) |
167 | panic("L1 Data SRAM Bank A Overflow\n"); | 181 | early_dma_memcpy(_sdata_l1, _l1_lma_start + l1_code_length, l1_data_a_length); |
168 | |||
169 | /* Copy _sdata_l1 to _sbss_l1 to L1 data bank A SRAM */ | ||
170 | dma_memcpy(_sdata_l1, _l1_lma_start + l1_code_length, l1_data_a_length); | ||
171 | 182 | ||
183 | /* if necessary, copy _sdata_b_l1 to _sbss_b_l1 to L1 data bank B SRAM */ | ||
172 | l1_data_b_length = _sbss_b_l1 - _sdata_b_l1; | 184 | l1_data_b_length = _sbss_b_l1 - _sdata_b_l1; |
173 | if (l1_data_b_length > L1_DATA_B_LENGTH) | 185 | if (l1_data_b_length) |
174 | panic("L1 Data SRAM Bank B Overflow\n"); | 186 | early_dma_memcpy(_sdata_b_l1, _l1_lma_start + l1_code_length + |
175 | |||
176 | /* Copy _sdata_b_l1 to _sbss_b_l1 to L1 data bank B SRAM */ | ||
177 | dma_memcpy(_sdata_b_l1, _l1_lma_start + l1_code_length + | ||
178 | l1_data_a_length, l1_data_b_length); | 187 | l1_data_a_length, l1_data_b_length); |
179 | 188 | ||
189 | early_dma_memcpy_done(); | ||
190 | |||
191 | /* if necessary, copy _stext_l2 to _edata_l2 to L2 SRAM */ | ||
180 | if (L2_LENGTH != 0) { | 192 | if (L2_LENGTH != 0) { |
181 | l2_length = _sbss_l2 - _stext_l2; | 193 | l2_length = _sbss_l2 - _stext_l2; |
182 | if (l2_length > L2_LENGTH) | 194 | if (l2_length) |
183 | panic("L2 SRAM Overflow\n"); | 195 | memcpy(_stext_l2, _l2_lma_start, l2_length); |
184 | |||
185 | /* Copy _stext_l2 to _edata_l2 to L2 SRAM */ | ||
186 | dma_memcpy(_stext_l2, _l2_lma_start, l2_length); | ||
187 | } | 196 | } |
188 | } | 197 | } |
189 | 198 | ||
@@ -472,7 +481,7 @@ static __init void memory_setup(void) | |||
472 | 481 | ||
473 | if (DMA_UNCACHED_REGION > (_ramend - _ramstart)) { | 482 | if (DMA_UNCACHED_REGION > (_ramend - _ramstart)) { |
474 | console_init(); | 483 | console_init(); |
475 | panic("DMA region exceeds memory limit: %lu.\n", | 484 | panic("DMA region exceeds memory limit: %lu.", |
476 | _ramend - _ramstart); | 485 | _ramend - _ramstart); |
477 | } | 486 | } |
478 | memory_end = _ramend - DMA_UNCACHED_REGION; | 487 | memory_end = _ramend - DMA_UNCACHED_REGION; |
@@ -526,14 +535,13 @@ static __init void memory_setup(void) | |||
526 | 535 | ||
527 | if (mtd_size == 0) { | 536 | if (mtd_size == 0) { |
528 | console_init(); | 537 | console_init(); |
529 | panic("Don't boot kernel without rootfs attached.\n"); | 538 | panic("Don't boot kernel without rootfs attached."); |
530 | } | 539 | } |
531 | 540 | ||
532 | /* Relocate MTD image to the top of memory after the uncached memory area */ | 541 | /* Relocate MTD image to the top of memory after the uncached memory area */ |
533 | dma_memcpy((char *)memory_end, _end, mtd_size); | 542 | uclinux_ram_map.phys = memory_mtd_start = memory_end; |
534 | 543 | uclinux_ram_map.size = mtd_size; | |
535 | memory_mtd_start = memory_end; | 544 | dma_memcpy((void *)uclinux_ram_map.phys, _end, uclinux_ram_map.size); |
536 | _ebss = memory_mtd_start; /* define _ebss for compatible */ | ||
537 | #endif /* CONFIG_MTD_UCLINUX */ | 545 | #endif /* CONFIG_MTD_UCLINUX */ |
538 | 546 | ||
539 | #if (defined(CONFIG_BFIN_ICACHE) && ANOMALY_05000263) | 547 | #if (defined(CONFIG_BFIN_ICACHE) && ANOMALY_05000263) |
@@ -796,10 +804,8 @@ void __init setup_arch(char **cmdline_p) | |||
796 | cclk = get_cclk(); | 804 | cclk = get_cclk(); |
797 | sclk = get_sclk(); | 805 | sclk = get_sclk(); |
798 | 806 | ||
799 | #if !defined(CONFIG_BFIN_KERNEL_CLOCK) | 807 | if ((ANOMALY_05000273 || ANOMALY_05000274) && (cclk >> 1) < sclk) |
800 | if (ANOMALY_05000273 && cclk == sclk) | 808 | panic("ANOMALY 05000273 or 05000274: CCLK must be >= 2*SCLK"); |
801 | panic("ANOMALY 05000273, SCLK can not be same as CCLK"); | ||
802 | #endif | ||
803 | 809 | ||
804 | #ifdef BF561_FAMILY | 810 | #ifdef BF561_FAMILY |
805 | if (ANOMALY_05000266) { | 811 | if (ANOMALY_05000266) { |
@@ -881,7 +887,7 @@ void __init setup_arch(char **cmdline_p) | |||
881 | printk(KERN_ERR "Warning: Compiled for Rev %d, but running on Rev %d\n", | 887 | printk(KERN_ERR "Warning: Compiled for Rev %d, but running on Rev %d\n", |
882 | bfin_compiled_revid(), bfin_revid()); | 888 | bfin_compiled_revid(), bfin_revid()); |
883 | if (bfin_compiled_revid() > bfin_revid()) | 889 | if (bfin_compiled_revid() > bfin_revid()) |
884 | panic("Error: you are missing anomaly workarounds for this rev\n"); | 890 | panic("Error: you are missing anomaly workarounds for this rev"); |
885 | } | 891 | } |
886 | } | 892 | } |
887 | if (bfin_revid() < CONFIG_BF_REV_MIN || bfin_revid() > CONFIG_BF_REV_MAX) | 893 | if (bfin_revid() < CONFIG_BF_REV_MIN || bfin_revid() > CONFIG_BF_REV_MAX) |
@@ -891,16 +897,13 @@ void __init setup_arch(char **cmdline_p) | |||
891 | 897 | ||
892 | /* We can't run on BF548-0.1 due to ANOMALY 05000448 */ | 898 | /* We can't run on BF548-0.1 due to ANOMALY 05000448 */ |
893 | if (bfin_cpuid() == 0x27de && bfin_revid() == 1) | 899 | if (bfin_cpuid() == 0x27de && bfin_revid() == 1) |
894 | panic("You can't run on this processor due to 05000448\n"); | 900 | panic("You can't run on this processor due to 05000448"); |
895 | 901 | ||
896 | printk(KERN_INFO "Blackfin Linux support by http://blackfin.uclinux.org/\n"); | 902 | printk(KERN_INFO "Blackfin Linux support by http://blackfin.uclinux.org/\n"); |
897 | 903 | ||
898 | printk(KERN_INFO "Processor Speed: %lu MHz core clock and %lu MHz System Clock\n", | 904 | printk(KERN_INFO "Processor Speed: %lu MHz core clock and %lu MHz System Clock\n", |
899 | cclk / 1000000, sclk / 1000000); | 905 | cclk / 1000000, sclk / 1000000); |
900 | 906 | ||
901 | if (ANOMALY_05000273 && (cclk >> 1) <= sclk) | ||
902 | printk("\n\n\nANOMALY_05000273: CCLK must be >= 2*SCLK !!!\n\n\n"); | ||
903 | |||
904 | setup_bootmem_allocator(); | 907 | setup_bootmem_allocator(); |
905 | 908 | ||
906 | paging_init(); | 909 | paging_init(); |
diff --git a/arch/blackfin/kernel/sys_bfin.c b/arch/blackfin/kernel/sys_bfin.c index fce49d7cf001..a8f1329c15a4 100644 --- a/arch/blackfin/kernel/sys_bfin.c +++ b/arch/blackfin/kernel/sys_bfin.c | |||
@@ -78,11 +78,6 @@ asmlinkage long sys_mmap2(unsigned long addr, unsigned long len, | |||
78 | return do_mmap2(addr, len, prot, flags, fd, pgoff); | 78 | return do_mmap2(addr, len, prot, flags, fd, pgoff); |
79 | } | 79 | } |
80 | 80 | ||
81 | asmlinkage int sys_getpagesize(void) | ||
82 | { | ||
83 | return PAGE_SIZE; | ||
84 | } | ||
85 | |||
86 | asmlinkage void *sys_sram_alloc(size_t size, unsigned long flags) | 81 | asmlinkage void *sys_sram_alloc(size_t size, unsigned long flags) |
87 | { | 82 | { |
88 | return sram_alloc_with_lsl(size, flags); | 83 | return sram_alloc_with_lsl(size, flags); |
diff --git a/arch/blackfin/kernel/time-ts.c b/arch/blackfin/kernel/time-ts.c index 27646121280a..0791eba40d9f 100644 --- a/arch/blackfin/kernel/time-ts.c +++ b/arch/blackfin/kernel/time-ts.c | |||
@@ -20,8 +20,9 @@ | |||
20 | 20 | ||
21 | #include <asm/blackfin.h> | 21 | #include <asm/blackfin.h> |
22 | #include <asm/time.h> | 22 | #include <asm/time.h> |
23 | #include <asm/gptimers.h> | ||
23 | 24 | ||
24 | #ifdef CONFIG_CYCLES_CLOCKSOURCE | 25 | #if defined(CONFIG_CYCLES_CLOCKSOURCE) |
25 | 26 | ||
26 | /* Accelerators for sched_clock() | 27 | /* Accelerators for sched_clock() |
27 | * convert from cycles(64bits) => nanoseconds (64bits) | 28 | * convert from cycles(64bits) => nanoseconds (64bits) |
@@ -58,15 +59,15 @@ static inline unsigned long long cycles_2_ns(cycle_t cyc) | |||
58 | return (cyc * cyc2ns_scale) >> CYC2NS_SCALE_FACTOR; | 59 | return (cyc * cyc2ns_scale) >> CYC2NS_SCALE_FACTOR; |
59 | } | 60 | } |
60 | 61 | ||
61 | static cycle_t read_cycles(struct clocksource *cs) | 62 | static cycle_t bfin_read_cycles(struct clocksource *cs) |
62 | { | 63 | { |
63 | return __bfin_cycles_off + (get_cycles() << __bfin_cycles_mod); | 64 | return __bfin_cycles_off + (get_cycles() << __bfin_cycles_mod); |
64 | } | 65 | } |
65 | 66 | ||
66 | static struct clocksource clocksource_bfin = { | 67 | static struct clocksource bfin_cs_cycles = { |
67 | .name = "bfin_cycles", | 68 | .name = "bfin_cs_cycles", |
68 | .rating = 350, | 69 | .rating = 350, |
69 | .read = read_cycles, | 70 | .read = bfin_read_cycles, |
70 | .mask = CLOCKSOURCE_MASK(64), | 71 | .mask = CLOCKSOURCE_MASK(64), |
71 | .shift = 22, | 72 | .shift = 22, |
72 | .flags = CLOCK_SOURCE_IS_CONTINUOUS, | 73 | .flags = CLOCK_SOURCE_IS_CONTINUOUS, |
@@ -74,53 +75,198 @@ static struct clocksource clocksource_bfin = { | |||
74 | 75 | ||
75 | unsigned long long sched_clock(void) | 76 | unsigned long long sched_clock(void) |
76 | { | 77 | { |
77 | return cycles_2_ns(read_cycles(&clocksource_bfin)); | 78 | return cycles_2_ns(bfin_read_cycles(&bfin_cs_cycles)); |
78 | } | 79 | } |
79 | 80 | ||
80 | static int __init bfin_clocksource_init(void) | 81 | static int __init bfin_cs_cycles_init(void) |
81 | { | 82 | { |
82 | set_cyc2ns_scale(get_cclk() / 1000); | 83 | set_cyc2ns_scale(get_cclk() / 1000); |
83 | 84 | ||
84 | clocksource_bfin.mult = clocksource_hz2mult(get_cclk(), clocksource_bfin.shift); | 85 | bfin_cs_cycles.mult = \ |
86 | clocksource_hz2mult(get_cclk(), bfin_cs_cycles.shift); | ||
85 | 87 | ||
86 | if (clocksource_register(&clocksource_bfin)) | 88 | if (clocksource_register(&bfin_cs_cycles)) |
87 | panic("failed to register clocksource"); | 89 | panic("failed to register clocksource"); |
88 | 90 | ||
89 | return 0; | 91 | return 0; |
90 | } | 92 | } |
93 | #else | ||
94 | # define bfin_cs_cycles_init() | ||
95 | #endif | ||
96 | |||
97 | #ifdef CONFIG_GPTMR0_CLOCKSOURCE | ||
98 | |||
99 | void __init setup_gptimer0(void) | ||
100 | { | ||
101 | disable_gptimers(TIMER0bit); | ||
102 | |||
103 | set_gptimer_config(TIMER0_id, \ | ||
104 | TIMER_OUT_DIS | TIMER_PERIOD_CNT | TIMER_MODE_PWM); | ||
105 | set_gptimer_period(TIMER0_id, -1); | ||
106 | set_gptimer_pwidth(TIMER0_id, -2); | ||
107 | SSYNC(); | ||
108 | enable_gptimers(TIMER0bit); | ||
109 | } | ||
110 | |||
111 | static cycle_t bfin_read_gptimer0(void) | ||
112 | { | ||
113 | return bfin_read_TIMER0_COUNTER(); | ||
114 | } | ||
115 | |||
116 | static struct clocksource bfin_cs_gptimer0 = { | ||
117 | .name = "bfin_cs_gptimer0", | ||
118 | .rating = 400, | ||
119 | .read = bfin_read_gptimer0, | ||
120 | .mask = CLOCKSOURCE_MASK(32), | ||
121 | .shift = 22, | ||
122 | .flags = CLOCK_SOURCE_IS_CONTINUOUS, | ||
123 | }; | ||
124 | |||
125 | static int __init bfin_cs_gptimer0_init(void) | ||
126 | { | ||
127 | setup_gptimer0(); | ||
91 | 128 | ||
129 | bfin_cs_gptimer0.mult = \ | ||
130 | clocksource_hz2mult(get_sclk(), bfin_cs_gptimer0.shift); | ||
131 | |||
132 | if (clocksource_register(&bfin_cs_gptimer0)) | ||
133 | panic("failed to register clocksource"); | ||
134 | |||
135 | return 0; | ||
136 | } | ||
92 | #else | 137 | #else |
93 | # define bfin_clocksource_init() | 138 | # define bfin_cs_gptimer0_init() |
94 | #endif | 139 | #endif |
95 | 140 | ||
141 | #ifdef CONFIG_CORE_TIMER_IRQ_L1 | ||
142 | __attribute__((l1_text)) | ||
143 | #endif | ||
144 | irqreturn_t timer_interrupt(int irq, void *dev_id); | ||
145 | |||
146 | static int bfin_timer_set_next_event(unsigned long, \ | ||
147 | struct clock_event_device *); | ||
148 | |||
149 | static void bfin_timer_set_mode(enum clock_event_mode, \ | ||
150 | struct clock_event_device *); | ||
151 | |||
152 | static struct clock_event_device clockevent_bfin = { | ||
153 | #if defined(CONFIG_TICKSOURCE_GPTMR0) | ||
154 | .name = "bfin_gptimer0", | ||
155 | .rating = 300, | ||
156 | .irq = IRQ_TIMER0, | ||
157 | #else | ||
158 | .name = "bfin_core_timer", | ||
159 | .rating = 350, | ||
160 | .irq = IRQ_CORETMR, | ||
161 | #endif | ||
162 | .shift = 32, | ||
163 | .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT, | ||
164 | .set_next_event = bfin_timer_set_next_event, | ||
165 | .set_mode = bfin_timer_set_mode, | ||
166 | }; | ||
167 | |||
168 | static struct irqaction bfin_timer_irq = { | ||
169 | #if defined(CONFIG_TICKSOURCE_GPTMR0) | ||
170 | .name = "Blackfin GPTimer0", | ||
171 | #else | ||
172 | .name = "Blackfin CoreTimer", | ||
173 | #endif | ||
174 | .flags = IRQF_DISABLED | IRQF_TIMER | \ | ||
175 | IRQF_IRQPOLL | IRQF_PERCPU, | ||
176 | .handler = timer_interrupt, | ||
177 | .dev_id = &clockevent_bfin, | ||
178 | }; | ||
179 | |||
180 | #if defined(CONFIG_TICKSOURCE_GPTMR0) | ||
96 | static int bfin_timer_set_next_event(unsigned long cycles, | 181 | static int bfin_timer_set_next_event(unsigned long cycles, |
97 | struct clock_event_device *evt) | 182 | struct clock_event_device *evt) |
98 | { | 183 | { |
184 | disable_gptimers(TIMER0bit); | ||
185 | |||
186 | /* it starts counting three SCLK cycles after the TIMENx bit is set */ | ||
187 | set_gptimer_pwidth(TIMER0_id, cycles - 3); | ||
188 | enable_gptimers(TIMER0bit); | ||
189 | return 0; | ||
190 | } | ||
191 | |||
192 | static void bfin_timer_set_mode(enum clock_event_mode mode, | ||
193 | struct clock_event_device *evt) | ||
194 | { | ||
195 | switch (mode) { | ||
196 | case CLOCK_EVT_MODE_PERIODIC: { | ||
197 | set_gptimer_config(TIMER0_id, \ | ||
198 | TIMER_OUT_DIS | TIMER_IRQ_ENA | \ | ||
199 | TIMER_PERIOD_CNT | TIMER_MODE_PWM); | ||
200 | set_gptimer_period(TIMER0_id, get_sclk() / HZ); | ||
201 | set_gptimer_pwidth(TIMER0_id, get_sclk() / HZ - 1); | ||
202 | enable_gptimers(TIMER0bit); | ||
203 | break; | ||
204 | } | ||
205 | case CLOCK_EVT_MODE_ONESHOT: | ||
206 | disable_gptimers(TIMER0bit); | ||
207 | set_gptimer_config(TIMER0_id, \ | ||
208 | TIMER_OUT_DIS | TIMER_IRQ_ENA | TIMER_MODE_PWM); | ||
209 | set_gptimer_period(TIMER0_id, 0); | ||
210 | break; | ||
211 | case CLOCK_EVT_MODE_UNUSED: | ||
212 | case CLOCK_EVT_MODE_SHUTDOWN: | ||
213 | disable_gptimers(TIMER0bit); | ||
214 | break; | ||
215 | case CLOCK_EVT_MODE_RESUME: | ||
216 | break; | ||
217 | } | ||
218 | } | ||
219 | |||
220 | static void bfin_timer_ack(void) | ||
221 | { | ||
222 | set_gptimer_status(TIMER_GROUP1, TIMER_STATUS_TIMIL0); | ||
223 | } | ||
224 | |||
225 | static void __init bfin_timer_init(void) | ||
226 | { | ||
227 | disable_gptimers(TIMER0bit); | ||
228 | } | ||
229 | |||
230 | static unsigned long __init bfin_clockevent_check(void) | ||
231 | { | ||
232 | setup_irq(IRQ_TIMER0, &bfin_timer_irq); | ||
233 | return get_sclk(); | ||
234 | } | ||
235 | |||
236 | #else /* CONFIG_TICKSOURCE_CORETMR */ | ||
237 | |||
238 | static int bfin_timer_set_next_event(unsigned long cycles, | ||
239 | struct clock_event_device *evt) | ||
240 | { | ||
241 | bfin_write_TCNTL(TMPWR); | ||
242 | CSYNC(); | ||
99 | bfin_write_TCOUNT(cycles); | 243 | bfin_write_TCOUNT(cycles); |
100 | CSYNC(); | 244 | CSYNC(); |
245 | bfin_write_TCNTL(TMPWR | TMREN); | ||
101 | return 0; | 246 | return 0; |
102 | } | 247 | } |
103 | 248 | ||
104 | static void bfin_timer_set_mode(enum clock_event_mode mode, | 249 | static void bfin_timer_set_mode(enum clock_event_mode mode, |
105 | struct clock_event_device *evt) | 250 | struct clock_event_device *evt) |
106 | { | 251 | { |
107 | switch (mode) { | 252 | switch (mode) { |
108 | case CLOCK_EVT_MODE_PERIODIC: { | 253 | case CLOCK_EVT_MODE_PERIODIC: { |
109 | unsigned long tcount = ((get_cclk() / (HZ * TIME_SCALE)) - 1); | 254 | unsigned long tcount = ((get_cclk() / (HZ * TIME_SCALE)) - 1); |
110 | bfin_write_TCNTL(TMPWR); | 255 | bfin_write_TCNTL(TMPWR); |
111 | bfin_write_TSCALE(TIME_SCALE - 1); | ||
112 | CSYNC(); | 256 | CSYNC(); |
257 | bfin_write_TSCALE(TIME_SCALE - 1); | ||
113 | bfin_write_TPERIOD(tcount); | 258 | bfin_write_TPERIOD(tcount); |
114 | bfin_write_TCOUNT(tcount); | 259 | bfin_write_TCOUNT(tcount); |
115 | bfin_write_TCNTL(TMPWR | TMREN | TAUTORLD); | ||
116 | CSYNC(); | 260 | CSYNC(); |
261 | bfin_write_TCNTL(TMPWR | TMREN | TAUTORLD); | ||
117 | break; | 262 | break; |
118 | } | 263 | } |
119 | case CLOCK_EVT_MODE_ONESHOT: | 264 | case CLOCK_EVT_MODE_ONESHOT: |
265 | bfin_write_TCNTL(TMPWR); | ||
266 | CSYNC(); | ||
120 | bfin_write_TSCALE(TIME_SCALE - 1); | 267 | bfin_write_TSCALE(TIME_SCALE - 1); |
268 | bfin_write_TPERIOD(0); | ||
121 | bfin_write_TCOUNT(0); | 269 | bfin_write_TCOUNT(0); |
122 | bfin_write_TCNTL(TMPWR | TMREN); | ||
123 | CSYNC(); | ||
124 | break; | 270 | break; |
125 | case CLOCK_EVT_MODE_UNUSED: | 271 | case CLOCK_EVT_MODE_UNUSED: |
126 | case CLOCK_EVT_MODE_SHUTDOWN: | 272 | case CLOCK_EVT_MODE_SHUTDOWN: |
@@ -132,6 +278,10 @@ static void bfin_timer_set_mode(enum clock_event_mode mode, | |||
132 | } | 278 | } |
133 | } | 279 | } |
134 | 280 | ||
281 | static void bfin_timer_ack(void) | ||
282 | { | ||
283 | } | ||
284 | |||
135 | static void __init bfin_timer_init(void) | 285 | static void __init bfin_timer_init(void) |
136 | { | 286 | { |
137 | /* power up the timer, but don't enable it just yet */ | 287 | /* power up the timer, but don't enable it just yet */ |
@@ -145,38 +295,32 @@ static void __init bfin_timer_init(void) | |||
145 | bfin_write_TPERIOD(0); | 295 | bfin_write_TPERIOD(0); |
146 | bfin_write_TCOUNT(0); | 296 | bfin_write_TCOUNT(0); |
147 | 297 | ||
148 | /* now enable the timer */ | ||
149 | CSYNC(); | 298 | CSYNC(); |
150 | } | 299 | } |
151 | 300 | ||
301 | static unsigned long __init bfin_clockevent_check(void) | ||
302 | { | ||
303 | setup_irq(IRQ_CORETMR, &bfin_timer_irq); | ||
304 | return get_cclk() / TIME_SCALE; | ||
305 | } | ||
306 | |||
307 | void __init setup_core_timer(void) | ||
308 | { | ||
309 | bfin_timer_init(); | ||
310 | bfin_timer_set_mode(CLOCK_EVT_MODE_PERIODIC, NULL); | ||
311 | } | ||
312 | #endif /* CONFIG_TICKSOURCE_GPTMR0 */ | ||
313 | |||
152 | /* | 314 | /* |
153 | * timer_interrupt() needs to keep up the real-time clock, | 315 | * timer_interrupt() needs to keep up the real-time clock, |
154 | * as well as call the "do_timer()" routine every clocktick | 316 | * as well as call the "do_timer()" routine every clocktick |
155 | */ | 317 | */ |
156 | #ifdef CONFIG_CORE_TIMER_IRQ_L1 | ||
157 | __attribute__((l1_text)) | ||
158 | #endif | ||
159 | irqreturn_t timer_interrupt(int irq, void *dev_id); | ||
160 | |||
161 | static struct clock_event_device clockevent_bfin = { | ||
162 | .name = "bfin_core_timer", | ||
163 | .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT, | ||
164 | .shift = 32, | ||
165 | .set_next_event = bfin_timer_set_next_event, | ||
166 | .set_mode = bfin_timer_set_mode, | ||
167 | }; | ||
168 | |||
169 | static struct irqaction bfin_timer_irq = { | ||
170 | .name = "Blackfin Core Timer", | ||
171 | .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL, | ||
172 | .handler = timer_interrupt, | ||
173 | .dev_id = &clockevent_bfin, | ||
174 | }; | ||
175 | |||
176 | irqreturn_t timer_interrupt(int irq, void *dev_id) | 318 | irqreturn_t timer_interrupt(int irq, void *dev_id) |
177 | { | 319 | { |
178 | struct clock_event_device *evt = dev_id; | 320 | struct clock_event_device *evt = dev_id; |
321 | smp_mb(); | ||
179 | evt->event_handler(evt); | 322 | evt->event_handler(evt); |
323 | bfin_timer_ack(); | ||
180 | return IRQ_HANDLED; | 324 | return IRQ_HANDLED; |
181 | } | 325 | } |
182 | 326 | ||
@@ -184,9 +328,8 @@ static int __init bfin_clockevent_init(void) | |||
184 | { | 328 | { |
185 | unsigned long timer_clk; | 329 | unsigned long timer_clk; |
186 | 330 | ||
187 | timer_clk = get_cclk() / TIME_SCALE; | 331 | timer_clk = bfin_clockevent_check(); |
188 | 332 | ||
189 | setup_irq(IRQ_CORETMR, &bfin_timer_irq); | ||
190 | bfin_timer_init(); | 333 | bfin_timer_init(); |
191 | 334 | ||
192 | clockevent_bfin.mult = div_sc(timer_clk, NSEC_PER_SEC, clockevent_bfin.shift); | 335 | clockevent_bfin.mult = div_sc(timer_clk, NSEC_PER_SEC, clockevent_bfin.shift); |
@@ -218,6 +361,7 @@ void __init time_init(void) | |||
218 | xtime.tv_nsec = 0; | 361 | xtime.tv_nsec = 0; |
219 | set_normalized_timespec(&wall_to_monotonic, -xtime.tv_sec, -xtime.tv_nsec); | 362 | set_normalized_timespec(&wall_to_monotonic, -xtime.tv_sec, -xtime.tv_nsec); |
220 | 363 | ||
221 | bfin_clocksource_init(); | 364 | bfin_cs_cycles_init(); |
365 | bfin_cs_gptimer0_init(); | ||
222 | bfin_clockevent_init(); | 366 | bfin_clockevent_init(); |
223 | } | 367 | } |
diff --git a/arch/blackfin/kernel/time.c b/arch/blackfin/kernel/time.c index 1bbacfbd4c5d..adb54aa7d7c8 100644 --- a/arch/blackfin/kernel/time.c +++ b/arch/blackfin/kernel/time.c | |||
@@ -24,14 +24,10 @@ | |||
24 | 24 | ||
25 | static struct irqaction bfin_timer_irq = { | 25 | static struct irqaction bfin_timer_irq = { |
26 | .name = "Blackfin Timer Tick", | 26 | .name = "Blackfin Timer Tick", |
27 | #ifdef CONFIG_IRQ_PER_CPU | ||
28 | .flags = IRQF_DISABLED | IRQF_PERCPU, | ||
29 | #else | ||
30 | .flags = IRQF_DISABLED | 27 | .flags = IRQF_DISABLED |
31 | #endif | ||
32 | }; | 28 | }; |
33 | 29 | ||
34 | #if defined(CONFIG_TICK_SOURCE_SYSTMR0) || defined(CONFIG_IPIPE) | 30 | #if defined(CONFIG_IPIPE) |
35 | void __init setup_system_timer0(void) | 31 | void __init setup_system_timer0(void) |
36 | { | 32 | { |
37 | /* Power down the core timer, just to play safe. */ | 33 | /* Power down the core timer, just to play safe. */ |
@@ -74,7 +70,7 @@ void __init setup_core_timer(void) | |||
74 | static void __init | 70 | static void __init |
75 | time_sched_init(irqreturn_t(*timer_routine) (int, void *)) | 71 | time_sched_init(irqreturn_t(*timer_routine) (int, void *)) |
76 | { | 72 | { |
77 | #if defined(CONFIG_TICK_SOURCE_SYSTMR0) || defined(CONFIG_IPIPE) | 73 | #if defined(CONFIG_IPIPE) |
78 | setup_system_timer0(); | 74 | setup_system_timer0(); |
79 | bfin_timer_irq.handler = timer_routine; | 75 | bfin_timer_irq.handler = timer_routine; |
80 | setup_irq(IRQ_TIMER0, &bfin_timer_irq); | 76 | setup_irq(IRQ_TIMER0, &bfin_timer_irq); |
@@ -94,7 +90,7 @@ static unsigned long gettimeoffset(void) | |||
94 | unsigned long offset; | 90 | unsigned long offset; |
95 | unsigned long clocks_per_jiffy; | 91 | unsigned long clocks_per_jiffy; |
96 | 92 | ||
97 | #if defined(CONFIG_TICK_SOURCE_SYSTMR0) || defined(CONFIG_IPIPE) | 93 | #if defined(CONFIG_IPIPE) |
98 | clocks_per_jiffy = bfin_read_TIMER0_PERIOD(); | 94 | clocks_per_jiffy = bfin_read_TIMER0_PERIOD(); |
99 | offset = bfin_read_TIMER0_COUNTER() / \ | 95 | offset = bfin_read_TIMER0_COUNTER() / \ |
100 | (((clocks_per_jiffy + 1) * HZ) / USEC_PER_SEC); | 96 | (((clocks_per_jiffy + 1) * HZ) / USEC_PER_SEC); |
@@ -133,36 +129,25 @@ irqreturn_t timer_interrupt(int irq, void *dummy) | |||
133 | static long last_rtc_update; | 129 | static long last_rtc_update; |
134 | 130 | ||
135 | write_seqlock(&xtime_lock); | 131 | write_seqlock(&xtime_lock); |
136 | #if defined(CONFIG_TICK_SOURCE_SYSTMR0) && !defined(CONFIG_IPIPE) | 132 | do_timer(1); |
133 | |||
137 | /* | 134 | /* |
138 | * TIMIL0 is latched in __ipipe_grab_irq() when the I-Pipe is | 135 | * If we have an externally synchronized Linux clock, then update |
139 | * enabled. | 136 | * CMOS clock accordingly every ~11 minutes. Set_rtc_mmss() has to be |
137 | * called as close as possible to 500 ms before the new second starts. | ||
140 | */ | 138 | */ |
141 | if (get_gptimer_status(0) & TIMER_STATUS_TIMIL0) { | 139 | if (ntp_synced() && |
142 | #endif | 140 | xtime.tv_sec > last_rtc_update + 660 && |
143 | do_timer(1); | 141 | (xtime.tv_nsec / NSEC_PER_USEC) >= |
144 | 142 | 500000 - ((unsigned)TICK_SIZE) / 2 | |
145 | /* | 143 | && (xtime.tv_nsec / NSEC_PER_USEC) <= |
146 | * If we have an externally synchronized Linux clock, then update | 144 | 500000 + ((unsigned)TICK_SIZE) / 2) { |
147 | * CMOS clock accordingly every ~11 minutes. Set_rtc_mmss() has to be | 145 | if (set_rtc_mmss(xtime.tv_sec) == 0) |
148 | * called as close as possible to 500 ms before the new second starts. | 146 | last_rtc_update = xtime.tv_sec; |
149 | */ | 147 | else |
150 | if (ntp_synced() && | 148 | /* Do it again in 60s. */ |
151 | xtime.tv_sec > last_rtc_update + 660 && | 149 | last_rtc_update = xtime.tv_sec - 600; |
152 | (xtime.tv_nsec / NSEC_PER_USEC) >= | ||
153 | 500000 - ((unsigned)TICK_SIZE) / 2 | ||
154 | && (xtime.tv_nsec / NSEC_PER_USEC) <= | ||
155 | 500000 + ((unsigned)TICK_SIZE) / 2) { | ||
156 | if (set_rtc_mmss(xtime.tv_sec) == 0) | ||
157 | last_rtc_update = xtime.tv_sec; | ||
158 | else | ||
159 | /* Do it again in 60s. */ | ||
160 | last_rtc_update = xtime.tv_sec - 600; | ||
161 | } | ||
162 | #if defined(CONFIG_TICK_SOURCE_SYSTMR0) && !defined(CONFIG_IPIPE) | ||
163 | set_gptimer_status(0, TIMER_STATUS_TIMIL0); | ||
164 | } | 150 | } |
165 | #endif | ||
166 | write_sequnlock(&xtime_lock); | 151 | write_sequnlock(&xtime_lock); |
167 | 152 | ||
168 | #ifdef CONFIG_IPIPE | 153 | #ifdef CONFIG_IPIPE |
diff --git a/arch/blackfin/kernel/traps.c b/arch/blackfin/kernel/traps.c index ffe7fb53eccb..aa76dfb0226e 100644 --- a/arch/blackfin/kernel/traps.c +++ b/arch/blackfin/kernel/traps.c | |||
@@ -68,6 +68,13 @@ | |||
68 | ({ if (0) printk(fmt, ##arg); 0; }) | 68 | ({ if (0) printk(fmt, ##arg); 0; }) |
69 | #endif | 69 | #endif |
70 | 70 | ||
71 | #if defined(CONFIG_DEBUG_MMRS) || defined(CONFIG_DEBUG_MMRS_MODULE) | ||
72 | u32 last_seqstat; | ||
73 | #ifdef CONFIG_DEBUG_MMRS_MODULE | ||
74 | EXPORT_SYMBOL(last_seqstat); | ||
75 | #endif | ||
76 | #endif | ||
77 | |||
71 | /* Initiate the event table handler */ | 78 | /* Initiate the event table handler */ |
72 | void __init trap_init(void) | 79 | void __init trap_init(void) |
73 | { | 80 | { |
@@ -79,7 +86,6 @@ void __init trap_init(void) | |||
79 | static void decode_address(char *buf, unsigned long address) | 86 | static void decode_address(char *buf, unsigned long address) |
80 | { | 87 | { |
81 | #ifdef CONFIG_DEBUG_VERBOSE | 88 | #ifdef CONFIG_DEBUG_VERBOSE |
82 | struct vm_list_struct *vml; | ||
83 | struct task_struct *p; | 89 | struct task_struct *p; |
84 | struct mm_struct *mm; | 90 | struct mm_struct *mm; |
85 | unsigned long flags, offset; | 91 | unsigned long flags, offset; |
@@ -196,6 +202,11 @@ done: | |||
196 | 202 | ||
197 | asmlinkage void double_fault_c(struct pt_regs *fp) | 203 | asmlinkage void double_fault_c(struct pt_regs *fp) |
198 | { | 204 | { |
205 | #ifdef CONFIG_DEBUG_BFIN_HWTRACE_ON | ||
206 | int j; | ||
207 | trace_buffer_save(j); | ||
208 | #endif | ||
209 | |||
199 | console_verbose(); | 210 | console_verbose(); |
200 | oops_in_progress = 1; | 211 | oops_in_progress = 1; |
201 | #ifdef CONFIG_DEBUG_VERBOSE | 212 | #ifdef CONFIG_DEBUG_VERBOSE |
@@ -220,9 +231,10 @@ asmlinkage void double_fault_c(struct pt_regs *fp) | |||
220 | dump_bfin_process(fp); | 231 | dump_bfin_process(fp); |
221 | dump_bfin_mem(fp); | 232 | dump_bfin_mem(fp); |
222 | show_regs(fp); | 233 | show_regs(fp); |
234 | dump_bfin_trace_buffer(); | ||
223 | } | 235 | } |
224 | #endif | 236 | #endif |
225 | panic("Double Fault - unrecoverable event\n"); | 237 | panic("Double Fault - unrecoverable event"); |
226 | 238 | ||
227 | } | 239 | } |
228 | 240 | ||
@@ -239,6 +251,9 @@ asmlinkage void trap_c(struct pt_regs *fp) | |||
239 | unsigned long trapnr = fp->seqstat & SEQSTAT_EXCAUSE; | 251 | unsigned long trapnr = fp->seqstat & SEQSTAT_EXCAUSE; |
240 | 252 | ||
241 | trace_buffer_save(j); | 253 | trace_buffer_save(j); |
254 | #if defined(CONFIG_DEBUG_MMRS) || defined(CONFIG_DEBUG_MMRS_MODULE) | ||
255 | last_seqstat = (u32)fp->seqstat; | ||
256 | #endif | ||
242 | 257 | ||
243 | /* Important - be very careful dereferncing pointers - will lead to | 258 | /* Important - be very careful dereferncing pointers - will lead to |
244 | * double faults if the stack has become corrupt | 259 | * double faults if the stack has become corrupt |
@@ -588,6 +603,9 @@ asmlinkage void trap_c(struct pt_regs *fp) | |||
588 | force_sig_info(sig, &info, current); | 603 | force_sig_info(sig, &info, current); |
589 | } | 604 | } |
590 | 605 | ||
606 | if (ANOMALY_05000461 && trapnr == VEC_HWERR && !access_ok(VERIFY_READ, fp->pc, 8)) | ||
607 | fp->pc = SAFE_USER_INSTRUCTION; | ||
608 | |||
591 | trace_buffer_restore(j); | 609 | trace_buffer_restore(j); |
592 | return; | 610 | return; |
593 | } | 611 | } |
@@ -832,6 +850,11 @@ void show_stack(struct task_struct *task, unsigned long *stack) | |||
832 | decode_address(buf, (unsigned int)stack); | 850 | decode_address(buf, (unsigned int)stack); |
833 | printk(KERN_NOTICE " SP: [0x%p] %s\n", stack, buf); | 851 | printk(KERN_NOTICE " SP: [0x%p] %s\n", stack, buf); |
834 | 852 | ||
853 | if (!access_ok(VERIFY_READ, stack, (unsigned int)endstack - (unsigned int)stack)) { | ||
854 | printk(KERN_NOTICE "Invalid stack pointer\n"); | ||
855 | return; | ||
856 | } | ||
857 | |||
835 | /* First thing is to look for a frame pointer */ | 858 | /* First thing is to look for a frame pointer */ |
836 | for (addr = (unsigned int *)((unsigned int)stack & ~0xF); addr < endstack; addr++) { | 859 | for (addr = (unsigned int *)((unsigned int)stack & ~0xF); addr < endstack; addr++) { |
837 | if (*addr & 0x1) | 860 | if (*addr & 0x1) |
@@ -1066,6 +1089,29 @@ void show_regs(struct pt_regs *fp) | |||
1066 | unsigned int cpu = smp_processor_id(); | 1089 | unsigned int cpu = smp_processor_id(); |
1067 | unsigned char in_atomic = (bfin_read_IPEND() & 0x10) || in_atomic(); | 1090 | unsigned char in_atomic = (bfin_read_IPEND() & 0x10) || in_atomic(); |
1068 | 1091 | ||
1092 | verbose_printk(KERN_NOTICE "\n"); | ||
1093 | if (CPUID != bfin_cpuid()) | ||
1094 | verbose_printk(KERN_NOTICE "Compiled for cpu family 0x%04x (Rev %d), " | ||
1095 | "but running on:0x%04x (Rev %d)\n", | ||
1096 | CPUID, bfin_compiled_revid(), bfin_cpuid(), bfin_revid()); | ||
1097 | |||
1098 | verbose_printk(KERN_NOTICE "ADSP-%s-0.%d", | ||
1099 | CPU, bfin_compiled_revid()); | ||
1100 | |||
1101 | if (bfin_compiled_revid() != bfin_revid()) | ||
1102 | verbose_printk("(Detected 0.%d)", bfin_revid()); | ||
1103 | |||
1104 | verbose_printk(" %lu(MHz CCLK) %lu(MHz SCLK) (%s)\n", | ||
1105 | get_cclk()/1000000, get_sclk()/1000000, | ||
1106 | #ifdef CONFIG_MPU | ||
1107 | "mpu on" | ||
1108 | #else | ||
1109 | "mpu off" | ||
1110 | #endif | ||
1111 | ); | ||
1112 | |||
1113 | verbose_printk(KERN_NOTICE "%s", linux_banner); | ||
1114 | |||
1069 | verbose_printk(KERN_NOTICE "\n" KERN_NOTICE "SEQUENCER STATUS:\t\t%s\n", print_tainted()); | 1115 | verbose_printk(KERN_NOTICE "\n" KERN_NOTICE "SEQUENCER STATUS:\t\t%s\n", print_tainted()); |
1070 | verbose_printk(KERN_NOTICE " SEQSTAT: %08lx IPEND: %04lx SYSCFG: %04lx\n", | 1116 | verbose_printk(KERN_NOTICE " SEQSTAT: %08lx IPEND: %04lx SYSCFG: %04lx\n", |
1071 | (long)fp->seqstat, fp->ipend, fp->syscfg); | 1117 | (long)fp->seqstat, fp->ipend, fp->syscfg); |
@@ -1246,5 +1292,5 @@ void panic_cplb_error(int cplb_panic, struct pt_regs *fp) | |||
1246 | dump_bfin_mem(fp); | 1292 | dump_bfin_mem(fp); |
1247 | show_regs(fp); | 1293 | show_regs(fp); |
1248 | dump_stack(); | 1294 | dump_stack(); |
1249 | panic("Unrecoverable event\n"); | 1295 | panic("Unrecoverable event"); |
1250 | } | 1296 | } |
diff --git a/arch/blackfin/kernel/vmlinux.lds.S b/arch/blackfin/kernel/vmlinux.lds.S index 27952ae047d8..8b67167cb4f4 100644 --- a/arch/blackfin/kernel/vmlinux.lds.S +++ b/arch/blackfin/kernel/vmlinux.lds.S | |||
@@ -50,7 +50,9 @@ SECTIONS | |||
50 | _text = .; | 50 | _text = .; |
51 | __stext = .; | 51 | __stext = .; |
52 | TEXT_TEXT | 52 | TEXT_TEXT |
53 | #ifndef CONFIG_SCHEDULE_L1 | ||
53 | SCHED_TEXT | 54 | SCHED_TEXT |
55 | #endif | ||
54 | LOCK_TEXT | 56 | LOCK_TEXT |
55 | KPROBES_TEXT | 57 | KPROBES_TEXT |
56 | *(.text.*) | 58 | *(.text.*) |
@@ -180,6 +182,9 @@ SECTIONS | |||
180 | . = ALIGN(4); | 182 | . = ALIGN(4); |
181 | __stext_l1 = .; | 183 | __stext_l1 = .; |
182 | *(.l1.text) | 184 | *(.l1.text) |
185 | #ifdef CONFIG_SCHEDULE_L1 | ||
186 | SCHED_TEXT | ||
187 | #endif | ||
183 | . = ALIGN(4); | 188 | . = ALIGN(4); |
184 | __etext_l1 = .; | 189 | __etext_l1 = .; |
185 | } | 190 | } |