aboutsummaryrefslogtreecommitdiffstats
path: root/arch/blackfin/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'arch/blackfin/kernel')
-rw-r--r--arch/blackfin/kernel/Makefile5
-rw-r--r--arch/blackfin/kernel/bfin_dma_5xx.c81
-rw-r--r--arch/blackfin/kernel/bfin_gpio.c549
-rw-r--r--arch/blackfin/kernel/bfin_ksyms.c1
-rw-r--r--arch/blackfin/kernel/cacheinit.c5
-rw-r--r--arch/blackfin/kernel/cplbinit.c7
-rw-r--r--arch/blackfin/kernel/early_printk.c214
-rw-r--r--arch/blackfin/kernel/irqchip.c12
-rw-r--r--arch/blackfin/kernel/process.c28
-rw-r--r--arch/blackfin/kernel/ptrace.c24
-rw-r--r--arch/blackfin/kernel/reboot.c78
-rw-r--r--arch/blackfin/kernel/setup.c90
-rw-r--r--arch/blackfin/kernel/traps.c110
-rw-r--r--arch/blackfin/kernel/vmlinux.lds.S48
14 files changed, 1001 insertions, 251 deletions
diff --git a/arch/blackfin/kernel/Makefile b/arch/blackfin/kernel/Makefile
index f429ebc3a961..8aeb6066b19b 100644
--- a/arch/blackfin/kernel/Makefile
+++ b/arch/blackfin/kernel/Makefile
@@ -7,11 +7,10 @@ extra-y := init_task.o vmlinux.lds
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 time.o traps.o irqchip.o dma-mapping.o flat.o \ 9 sys_bfin.o time.o traps.o irqchip.o dma-mapping.o flat.o \
10 fixed_code.o cplbinit.o cacheinit.o 10 fixed_code.o cplbinit.o cacheinit.o reboot.o bfin_gpio.o
11 11
12obj-$(CONFIG_BF53x) += bfin_gpio.o
13obj-$(CONFIG_BF561) += bfin_gpio.o
14obj-$(CONFIG_MODULES) += module.o 12obj-$(CONFIG_MODULES) += module.o
15obj-$(CONFIG_BFIN_DMA_5XX) += bfin_dma_5xx.o 13obj-$(CONFIG_BFIN_DMA_5XX) += bfin_dma_5xx.o
16obj-$(CONFIG_DUAL_CORE_TEST_MODULE) += dualcore_test.o 14obj-$(CONFIG_DUAL_CORE_TEST_MODULE) += dualcore_test.o
17obj-$(CONFIG_KGDB) += kgdb.o 15obj-$(CONFIG_KGDB) += kgdb.o
16obj-$(CONFIG_EARLY_PRINTK) += early_printk.o
diff --git a/arch/blackfin/kernel/bfin_dma_5xx.c b/arch/blackfin/kernel/bfin_dma_5xx.c
index 7cf02f02a1db..e19164fb4cd1 100644
--- a/arch/blackfin/kernel/bfin_dma_5xx.c
+++ b/arch/blackfin/kernel/bfin_dma_5xx.c
@@ -73,6 +73,11 @@ static int __init blackfin_dma_init(void)
73 /* Mark MEMDMA Channel 0 as requested since we're using it internally */ 73 /* Mark MEMDMA Channel 0 as requested since we're using it internally */
74 dma_ch[CH_MEM_STREAM0_DEST].chan_status = DMA_CHANNEL_REQUESTED; 74 dma_ch[CH_MEM_STREAM0_DEST].chan_status = DMA_CHANNEL_REQUESTED;
75 dma_ch[CH_MEM_STREAM0_SRC].chan_status = DMA_CHANNEL_REQUESTED; 75 dma_ch[CH_MEM_STREAM0_SRC].chan_status = DMA_CHANNEL_REQUESTED;
76
77#if defined(CONFIG_DEB_DMA_URGENT)
78 bfin_write_EBIU_DDRQUE(bfin_read_EBIU_DDRQUE()
79 | DEB1_URGENT | DEB2_URGENT | DEB3_URGENT);
80#endif
76 return 0; 81 return 0;
77} 82}
78 83
@@ -265,10 +270,23 @@ void set_dma_next_desc_addr(unsigned int channel, unsigned long addr)
265 270
266 dma_ch[channel].regs->next_desc_ptr = addr; 271 dma_ch[channel].regs->next_desc_ptr = addr;
267 SSYNC(); 272 SSYNC();
268 pr_debug("set_dma_start_addr() : END\n"); 273 pr_debug("set_dma_next_desc_addr() : END\n");
269} 274}
270EXPORT_SYMBOL(set_dma_next_desc_addr); 275EXPORT_SYMBOL(set_dma_next_desc_addr);
271 276
277void set_dma_curr_desc_addr(unsigned int channel, unsigned long addr)
278{
279 pr_debug("set_dma_curr_desc_addr() : BEGIN \n");
280
281 BUG_ON(!(dma_ch[channel].chan_status != DMA_CHANNEL_FREE
282 && channel < MAX_BLACKFIN_DMA_CHANNEL));
283
284 dma_ch[channel].regs->curr_desc_ptr = addr;
285 SSYNC();
286 pr_debug("set_dma_curr_desc_addr() : END\n");
287}
288EXPORT_SYMBOL(set_dma_curr_desc_addr);
289
272void set_dma_x_count(unsigned int channel, unsigned short x_count) 290void set_dma_x_count(unsigned int channel, unsigned short x_count)
273{ 291{
274 BUG_ON(!(dma_ch[channel].chan_status != DMA_CHANNEL_FREE 292 BUG_ON(!(dma_ch[channel].chan_status != DMA_CHANNEL_FREE
@@ -345,6 +363,16 @@ void set_dma_sg(unsigned int channel, struct dmasg *sg, int nr_sg)
345} 363}
346EXPORT_SYMBOL(set_dma_sg); 364EXPORT_SYMBOL(set_dma_sg);
347 365
366void set_dma_curr_addr(unsigned int channel, unsigned long addr)
367{
368 BUG_ON(!(dma_ch[channel].chan_status != DMA_CHANNEL_FREE
369 && channel < MAX_BLACKFIN_DMA_CHANNEL));
370
371 dma_ch[channel].regs->curr_addr_ptr = addr;
372 SSYNC();
373}
374EXPORT_SYMBOL(set_dma_curr_addr);
375
348/*------------------------------------------------------------------------------ 376/*------------------------------------------------------------------------------
349 * Get the DMA status of a specific DMA channel from the system. 377 * Get the DMA status of a specific DMA channel from the system.
350 *-----------------------------------------------------------------------------*/ 378 *-----------------------------------------------------------------------------*/
@@ -408,6 +436,10 @@ static void *__dma_memcpy(void *dest, const void *src, size_t size)
408 blackfin_dcache_flush_range((unsigned int)src, 436 blackfin_dcache_flush_range((unsigned int)src,
409 (unsigned int)(src + size)); 437 (unsigned int)(src + size));
410 438
439 if ((unsigned long)dest < memory_end)
440 blackfin_dcache_invalidate_range((unsigned int)dest,
441 (unsigned int)(dest + size));
442
411 bfin_write_MDMA_D0_IRQ_STATUS(DMA_DONE | DMA_ERR); 443 bfin_write_MDMA_D0_IRQ_STATUS(DMA_DONE | DMA_ERR);
412 444
413 if ((unsigned long)src < (unsigned long)dest) 445 if ((unsigned long)src < (unsigned long)dest)
@@ -515,6 +547,8 @@ static void *__dma_memcpy(void *dest, const void *src, size_t size)
515 } 547 }
516 } 548 }
517 549
550 SSYNC();
551
518 while (!(bfin_read_MDMA_D0_IRQ_STATUS() & DMA_DONE)) 552 while (!(bfin_read_MDMA_D0_IRQ_STATUS() & DMA_DONE))
519 ; 553 ;
520 554
@@ -524,9 +558,6 @@ static void *__dma_memcpy(void *dest, const void *src, size_t size)
524 bfin_write_MDMA_S0_CONFIG(0); 558 bfin_write_MDMA_S0_CONFIG(0);
525 bfin_write_MDMA_D0_CONFIG(0); 559 bfin_write_MDMA_D0_CONFIG(0);
526 560
527 if ((unsigned long)dest < memory_end)
528 blackfin_dcache_invalidate_range((unsigned int)dest,
529 (unsigned int)(dest + size));
530 local_irq_restore(flags); 561 local_irq_restore(flags);
531 562
532 return dest; 563 return dest;
@@ -555,13 +586,14 @@ void *safe_dma_memcpy(void *dest, const void *src, size_t size)
555} 586}
556EXPORT_SYMBOL(safe_dma_memcpy); 587EXPORT_SYMBOL(safe_dma_memcpy);
557 588
558void dma_outsb(void __iomem *addr, const void *buf, unsigned short len) 589void dma_outsb(unsigned long addr, const void *buf, unsigned short len)
559{ 590{
560 unsigned long flags; 591 unsigned long flags;
561 592
562 local_irq_save(flags); 593 local_irq_save(flags);
563 594
564 blackfin_dcache_flush_range((unsigned int)buf, (unsigned int)(buf) + len); 595 blackfin_dcache_flush_range((unsigned int)buf,
596 (unsigned int)(buf) + len);
565 597
566 bfin_write_MDMA_D0_START_ADDR(addr); 598 bfin_write_MDMA_D0_START_ADDR(addr);
567 bfin_write_MDMA_D0_X_COUNT(len); 599 bfin_write_MDMA_D0_X_COUNT(len);
@@ -576,6 +608,8 @@ void dma_outsb(void __iomem *addr, const void *buf, unsigned short len)
576 bfin_write_MDMA_S0_CONFIG(DMAEN | WDSIZE_8); 608 bfin_write_MDMA_S0_CONFIG(DMAEN | WDSIZE_8);
577 bfin_write_MDMA_D0_CONFIG(WNR | DI_EN | DMAEN | WDSIZE_8); 609 bfin_write_MDMA_D0_CONFIG(WNR | DI_EN | DMAEN | WDSIZE_8);
578 610
611 SSYNC();
612
579 while (!(bfin_read_MDMA_D0_IRQ_STATUS() & DMA_DONE)); 613 while (!(bfin_read_MDMA_D0_IRQ_STATUS() & DMA_DONE));
580 614
581 bfin_write_MDMA_D0_IRQ_STATUS(DMA_DONE | DMA_ERR); 615 bfin_write_MDMA_D0_IRQ_STATUS(DMA_DONE | DMA_ERR);
@@ -588,10 +622,13 @@ void dma_outsb(void __iomem *addr, const void *buf, unsigned short len)
588EXPORT_SYMBOL(dma_outsb); 622EXPORT_SYMBOL(dma_outsb);
589 623
590 624
591void dma_insb(const void __iomem *addr, void *buf, unsigned short len) 625void dma_insb(unsigned long addr, void *buf, unsigned short len)
592{ 626{
593 unsigned long flags; 627 unsigned long flags;
594 628
629 blackfin_dcache_invalidate_range((unsigned int)buf,
630 (unsigned int)(buf) + len);
631
595 local_irq_save(flags); 632 local_irq_save(flags);
596 bfin_write_MDMA_D0_START_ADDR(buf); 633 bfin_write_MDMA_D0_START_ADDR(buf);
597 bfin_write_MDMA_D0_X_COUNT(len); 634 bfin_write_MDMA_D0_X_COUNT(len);
@@ -606,7 +643,7 @@ void dma_insb(const void __iomem *addr, void *buf, unsigned short len)
606 bfin_write_MDMA_S0_CONFIG(DMAEN | WDSIZE_8); 643 bfin_write_MDMA_S0_CONFIG(DMAEN | WDSIZE_8);
607 bfin_write_MDMA_D0_CONFIG(WNR | DI_EN | DMAEN | WDSIZE_8); 644 bfin_write_MDMA_D0_CONFIG(WNR | DI_EN | DMAEN | WDSIZE_8);
608 645
609 blackfin_dcache_invalidate_range((unsigned int)buf, (unsigned int)(buf) + len); 646 SSYNC();
610 647
611 while (!(bfin_read_MDMA_D0_IRQ_STATUS() & DMA_DONE)); 648 while (!(bfin_read_MDMA_D0_IRQ_STATUS() & DMA_DONE));
612 649
@@ -619,13 +656,14 @@ void dma_insb(const void __iomem *addr, void *buf, unsigned short len)
619} 656}
620EXPORT_SYMBOL(dma_insb); 657EXPORT_SYMBOL(dma_insb);
621 658
622void dma_outsw(void __iomem *addr, const void *buf, unsigned short len) 659void dma_outsw(unsigned long addr, const void *buf, unsigned short len)
623{ 660{
624 unsigned long flags; 661 unsigned long flags;
625 662
626 local_irq_save(flags); 663 local_irq_save(flags);
627 664
628 blackfin_dcache_flush_range((unsigned int)buf, (unsigned int)(buf) + len); 665 blackfin_dcache_flush_range((unsigned int)buf,
666 (unsigned int)(buf) + len * sizeof(short));
629 667
630 bfin_write_MDMA_D0_START_ADDR(addr); 668 bfin_write_MDMA_D0_START_ADDR(addr);
631 bfin_write_MDMA_D0_X_COUNT(len); 669 bfin_write_MDMA_D0_X_COUNT(len);
@@ -640,6 +678,8 @@ void dma_outsw(void __iomem *addr, const void *buf, unsigned short len)
640 bfin_write_MDMA_S0_CONFIG(DMAEN | WDSIZE_16); 678 bfin_write_MDMA_S0_CONFIG(DMAEN | WDSIZE_16);
641 bfin_write_MDMA_D0_CONFIG(WNR | DI_EN | DMAEN | WDSIZE_16); 679 bfin_write_MDMA_D0_CONFIG(WNR | DI_EN | DMAEN | WDSIZE_16);
642 680
681 SSYNC();
682
643 while (!(bfin_read_MDMA_D0_IRQ_STATUS() & DMA_DONE)); 683 while (!(bfin_read_MDMA_D0_IRQ_STATUS() & DMA_DONE));
644 684
645 bfin_write_MDMA_D0_IRQ_STATUS(DMA_DONE | DMA_ERR); 685 bfin_write_MDMA_D0_IRQ_STATUS(DMA_DONE | DMA_ERR);
@@ -651,10 +691,13 @@ void dma_outsw(void __iomem *addr, const void *buf, unsigned short len)
651} 691}
652EXPORT_SYMBOL(dma_outsw); 692EXPORT_SYMBOL(dma_outsw);
653 693
654void dma_insw(const void __iomem *addr, void *buf, unsigned short len) 694void dma_insw(unsigned long addr, void *buf, unsigned short len)
655{ 695{
656 unsigned long flags; 696 unsigned long flags;
657 697
698 blackfin_dcache_invalidate_range((unsigned int)buf,
699 (unsigned int)(buf) + len * sizeof(short));
700
658 local_irq_save(flags); 701 local_irq_save(flags);
659 702
660 bfin_write_MDMA_D0_START_ADDR(buf); 703 bfin_write_MDMA_D0_START_ADDR(buf);
@@ -670,7 +713,7 @@ void dma_insw(const void __iomem *addr, void *buf, unsigned short len)
670 bfin_write_MDMA_S0_CONFIG(DMAEN | WDSIZE_16); 713 bfin_write_MDMA_S0_CONFIG(DMAEN | WDSIZE_16);
671 bfin_write_MDMA_D0_CONFIG(WNR | DI_EN | DMAEN | WDSIZE_16); 714 bfin_write_MDMA_D0_CONFIG(WNR | DI_EN | DMAEN | WDSIZE_16);
672 715
673 blackfin_dcache_invalidate_range((unsigned int)buf, (unsigned int)(buf) + len); 716 SSYNC();
674 717
675 while (!(bfin_read_MDMA_D0_IRQ_STATUS() & DMA_DONE)); 718 while (!(bfin_read_MDMA_D0_IRQ_STATUS() & DMA_DONE));
676 719
@@ -683,13 +726,14 @@ void dma_insw(const void __iomem *addr, void *buf, unsigned short len)
683} 726}
684EXPORT_SYMBOL(dma_insw); 727EXPORT_SYMBOL(dma_insw);
685 728
686void dma_outsl(void __iomem *addr, const void *buf, unsigned short len) 729void dma_outsl(unsigned long addr, const void *buf, unsigned short len)
687{ 730{
688 unsigned long flags; 731 unsigned long flags;
689 732
690 local_irq_save(flags); 733 local_irq_save(flags);
691 734
692 blackfin_dcache_flush_range((unsigned int)buf, (unsigned int)(buf) + len); 735 blackfin_dcache_flush_range((unsigned int)buf,
736 (unsigned int)(buf) + len * sizeof(long));
693 737
694 bfin_write_MDMA_D0_START_ADDR(addr); 738 bfin_write_MDMA_D0_START_ADDR(addr);
695 bfin_write_MDMA_D0_X_COUNT(len); 739 bfin_write_MDMA_D0_X_COUNT(len);
@@ -704,6 +748,8 @@ void dma_outsl(void __iomem *addr, const void *buf, unsigned short len)
704 bfin_write_MDMA_S0_CONFIG(DMAEN | WDSIZE_32); 748 bfin_write_MDMA_S0_CONFIG(DMAEN | WDSIZE_32);
705 bfin_write_MDMA_D0_CONFIG(WNR | DI_EN | DMAEN | WDSIZE_32); 749 bfin_write_MDMA_D0_CONFIG(WNR | DI_EN | DMAEN | WDSIZE_32);
706 750
751 SSYNC();
752
707 while (!(bfin_read_MDMA_D0_IRQ_STATUS() & DMA_DONE)); 753 while (!(bfin_read_MDMA_D0_IRQ_STATUS() & DMA_DONE));
708 754
709 bfin_write_MDMA_D0_IRQ_STATUS(DMA_DONE | DMA_ERR); 755 bfin_write_MDMA_D0_IRQ_STATUS(DMA_DONE | DMA_ERR);
@@ -715,10 +761,13 @@ void dma_outsl(void __iomem *addr, const void *buf, unsigned short len)
715} 761}
716EXPORT_SYMBOL(dma_outsl); 762EXPORT_SYMBOL(dma_outsl);
717 763
718void dma_insl(const void __iomem *addr, void *buf, unsigned short len) 764void dma_insl(unsigned long addr, void *buf, unsigned short len)
719{ 765{
720 unsigned long flags; 766 unsigned long flags;
721 767
768 blackfin_dcache_invalidate_range((unsigned int)buf,
769 (unsigned int)(buf) + len * sizeof(long));
770
722 local_irq_save(flags); 771 local_irq_save(flags);
723 772
724 bfin_write_MDMA_D0_START_ADDR(buf); 773 bfin_write_MDMA_D0_START_ADDR(buf);
@@ -734,7 +783,7 @@ void dma_insl(const void __iomem *addr, void *buf, unsigned short len)
734 bfin_write_MDMA_S0_CONFIG(DMAEN | WDSIZE_32); 783 bfin_write_MDMA_S0_CONFIG(DMAEN | WDSIZE_32);
735 bfin_write_MDMA_D0_CONFIG(WNR | DI_EN | DMAEN | WDSIZE_32); 784 bfin_write_MDMA_D0_CONFIG(WNR | DI_EN | DMAEN | WDSIZE_32);
736 785
737 blackfin_dcache_invalidate_range((unsigned int)buf, (unsigned int)(buf) + len); 786 SSYNC();
738 787
739 while (!(bfin_read_MDMA_D0_IRQ_STATUS() & DMA_DONE)); 788 while (!(bfin_read_MDMA_D0_IRQ_STATUS() & DMA_DONE));
740 789
diff --git a/arch/blackfin/kernel/bfin_gpio.c b/arch/blackfin/kernel/bfin_gpio.c
index 5d488ef965ce..3fe0cd49e8db 100644
--- a/arch/blackfin/kernel/bfin_gpio.c
+++ b/arch/blackfin/kernel/bfin_gpio.c
@@ -7,7 +7,7 @@
7 * Description: GPIO Abstraction Layer 7 * Description: GPIO Abstraction Layer
8 * 8 *
9 * Modified: 9 * Modified:
10 * Copyright 2006 Analog Devices Inc. 10 * Copyright 2007 Analog Devices Inc.
11 * 11 *
12 * Bugs: Enter bugs at http://blackfin.uclinux.org/ 12 * Bugs: Enter bugs at http://blackfin.uclinux.org/
13 * 13 *
@@ -28,9 +28,9 @@
28 */ 28 */
29 29
30/* 30/*
31* Number BF537/6/4 BF561 BF533/2/1 31* Number BF537/6/4 BF561 BF533/2/1 BF549/8/4/2
32* 32*
33* GPIO_0 PF0 PF0 PF0 33* GPIO_0 PF0 PF0 PF0 PA0...PJ13
34* GPIO_1 PF1 PF1 PF1 34* GPIO_1 PF1 PF1 PF1
35* GPIO_2 PF2 PF2 PF2 35* GPIO_2 PF2 PF2 PF2
36* GPIO_3 PF3 PF3 PF3 36* GPIO_3 PF3 PF3 PF3
@@ -80,6 +80,7 @@
80* GPIO_47 PH15 PF47 80* GPIO_47 PH15 PF47
81*/ 81*/
82 82
83#include <linux/delay.h>
83#include <linux/module.h> 84#include <linux/module.h>
84#include <linux/err.h> 85#include <linux/err.h>
85#include <asm/blackfin.h> 86#include <asm/blackfin.h>
@@ -87,6 +88,36 @@
87#include <asm/portmux.h> 88#include <asm/portmux.h>
88#include <linux/irq.h> 89#include <linux/irq.h>
89 90
91#if ANOMALY_05000311 || ANOMALY_05000323
92enum {
93 AWA_data = SYSCR,
94 AWA_data_clear = SYSCR,
95 AWA_data_set = SYSCR,
96 AWA_toggle = SYSCR,
97 AWA_maska = UART_SCR,
98 AWA_maska_clear = UART_SCR,
99 AWA_maska_set = UART_SCR,
100 AWA_maska_toggle = UART_SCR,
101 AWA_maskb = UART_GCTL,
102 AWA_maskb_clear = UART_GCTL,
103 AWA_maskb_set = UART_GCTL,
104 AWA_maskb_toggle = UART_GCTL,
105 AWA_dir = SPORT1_STAT,
106 AWA_polar = SPORT1_STAT,
107 AWA_edge = SPORT1_STAT,
108 AWA_both = SPORT1_STAT,
109#if ANOMALY_05000311
110 AWA_inen = TIMER_ENABLE,
111#elif ANOMALY_05000323
112 AWA_inen = DMA1_1_CONFIG,
113#endif
114};
115 /* Anomaly Workaround */
116#define AWA_DUMMY_READ(name) bfin_read16(AWA_ ## name)
117#else
118#define AWA_DUMMY_READ(...) do { } while (0)
119#endif
120
90#ifdef BF533_FAMILY 121#ifdef BF533_FAMILY
91static struct gpio_port_t *gpio_bankb[gpio_bank(MAX_BLACKFIN_GPIOS)] = { 122static struct gpio_port_t *gpio_bankb[gpio_bank(MAX_BLACKFIN_GPIOS)] = {
92 (struct gpio_port_t *) FIO_FLAG_D, 123 (struct gpio_port_t *) FIO_FLAG_D,
@@ -116,11 +147,31 @@ static struct gpio_port_t *gpio_bankb[gpio_bank(MAX_BLACKFIN_GPIOS)] = {
116}; 147};
117#endif 148#endif
118 149
150#ifdef BF548_FAMILY
151static struct gpio_port_t *gpio_array[gpio_bank(MAX_BLACKFIN_GPIOS)] = {
152 (struct gpio_port_t *)PORTA_FER,
153 (struct gpio_port_t *)PORTB_FER,
154 (struct gpio_port_t *)PORTC_FER,
155 (struct gpio_port_t *)PORTD_FER,
156 (struct gpio_port_t *)PORTE_FER,
157 (struct gpio_port_t *)PORTF_FER,
158 (struct gpio_port_t *)PORTG_FER,
159 (struct gpio_port_t *)PORTH_FER,
160 (struct gpio_port_t *)PORTI_FER,
161 (struct gpio_port_t *)PORTJ_FER,
162};
163#endif
164
119static unsigned short reserved_gpio_map[gpio_bank(MAX_BLACKFIN_GPIOS)]; 165static unsigned short reserved_gpio_map[gpio_bank(MAX_BLACKFIN_GPIOS)];
120static unsigned short reserved_peri_map[gpio_bank(MAX_BLACKFIN_GPIOS + 16)]; 166static unsigned short reserved_peri_map[gpio_bank(MAX_BLACKFIN_GPIOS + 16)];
121char *str_ident = NULL;
122 167
123#define RESOURCE_LABEL_SIZE 16 168#define MAX_RESOURCES 256
169#define RESOURCE_LABEL_SIZE 16
170
171struct str_ident {
172 char name[RESOURCE_LABEL_SIZE];
173} *str_ident;
174
124 175
125#ifdef CONFIG_PM 176#ifdef CONFIG_PM
126static unsigned short wakeup_map[gpio_bank(MAX_BLACKFIN_GPIOS)]; 177static unsigned short wakeup_map[gpio_bank(MAX_BLACKFIN_GPIOS)];
@@ -141,21 +192,32 @@ static unsigned int sic_iwr_irqs[gpio_bank(MAX_BLACKFIN_GPIOS)] = {IRQ_PROG0_INT
141 192
142#endif /* CONFIG_PM */ 193#endif /* CONFIG_PM */
143 194
195#if defined(BF548_FAMILY)
196inline int check_gpio(unsigned short gpio)
197{
198 if (gpio == GPIO_PB15 || gpio == GPIO_PC14 || gpio == GPIO_PC15
199 || gpio == GPIO_PH14 || gpio == GPIO_PH15
200 || gpio == GPIO_PJ14 || gpio == GPIO_PJ15
201 || gpio > MAX_BLACKFIN_GPIOS)
202 return -EINVAL;
203 return 0;
204}
205#else
144inline int check_gpio(unsigned short gpio) 206inline int check_gpio(unsigned short gpio)
145{ 207{
146 if (gpio >= MAX_BLACKFIN_GPIOS) 208 if (gpio >= MAX_BLACKFIN_GPIOS)
147 return -EINVAL; 209 return -EINVAL;
148 return 0; 210 return 0;
149} 211}
212#endif
150 213
151static void set_label(unsigned short ident, const char *label) 214static void set_label(unsigned short ident, const char *label)
152{ 215{
153 216
154 if (label && str_ident) { 217 if (label && str_ident) {
155 strncpy(str_ident + ident * RESOURCE_LABEL_SIZE, label, 218 strncpy(str_ident[ident].name, label,
156 RESOURCE_LABEL_SIZE); 219 RESOURCE_LABEL_SIZE);
157 str_ident[ident * RESOURCE_LABEL_SIZE + 220 str_ident[ident].name[RESOURCE_LABEL_SIZE - 1] = 0;
158 RESOURCE_LABEL_SIZE - 1] = 0;
159 } 221 }
160} 222}
161 223
@@ -164,14 +226,13 @@ static char *get_label(unsigned short ident)
164 if (!str_ident) 226 if (!str_ident)
165 return "UNKNOWN"; 227 return "UNKNOWN";
166 228
167 return (str_ident[ident * RESOURCE_LABEL_SIZE] ? 229 return (*str_ident[ident].name ? str_ident[ident].name : "UNKNOWN");
168 (str_ident + ident * RESOURCE_LABEL_SIZE) : "UNKNOWN");
169} 230}
170 231
171static int cmp_label(unsigned short ident, const char *label) 232static int cmp_label(unsigned short ident, const char *label)
172{ 233{
173 if (label && str_ident) 234 if (label && str_ident)
174 return strncmp(str_ident + ident * RESOURCE_LABEL_SIZE, 235 return strncmp(str_ident[ident].name,
175 label, strlen(label)); 236 label, strlen(label));
176 else 237 else
177 return -EINVAL; 238 return -EINVAL;
@@ -181,50 +242,84 @@ static int cmp_label(unsigned short ident, const char *label)
181static void port_setup(unsigned short gpio, unsigned short usage) 242static void port_setup(unsigned short gpio, unsigned short usage)
182{ 243{
183 if (!check_gpio(gpio)) { 244 if (!check_gpio(gpio)) {
184 if (usage == GPIO_USAGE) { 245 if (usage == GPIO_USAGE)
185 *port_fer[gpio_bank(gpio)] &= ~gpio_bit(gpio); 246 *port_fer[gpio_bank(gpio)] &= ~gpio_bit(gpio);
186 } else 247 else
187 *port_fer[gpio_bank(gpio)] |= gpio_bit(gpio); 248 *port_fer[gpio_bank(gpio)] |= gpio_bit(gpio);
188 SSYNC(); 249 SSYNC();
189 } 250 }
190} 251}
252#elif defined(BF548_FAMILY)
253static void port_setup(unsigned short gpio, unsigned short usage)
254{
255 if (usage == GPIO_USAGE)
256 gpio_array[gpio_bank(gpio)]->port_fer &= ~gpio_bit(gpio);
257 else
258 gpio_array[gpio_bank(gpio)]->port_fer |= gpio_bit(gpio);
259 SSYNC();
260}
191#else 261#else
192# define port_setup(...) do { } while (0) 262# define port_setup(...) do { } while (0)
193#endif 263#endif
194 264
195#ifdef BF537_FAMILY 265#ifdef BF537_FAMILY
196 266static struct {
197#define PMUX_LUT_RES 0 267 unsigned short res;
198#define PMUX_LUT_OFFSET 1 268 unsigned short offset;
199#define PMUX_LUT_ENTRIES 41 269} port_mux_lut[] = {
200#define PMUX_LUT_SIZE 2 270 {.res = P_PPI0_D13, .offset = 11},
201 271 {.res = P_PPI0_D14, .offset = 11},
202static unsigned short port_mux_lut[PMUX_LUT_ENTRIES][PMUX_LUT_SIZE] = { 272 {.res = P_PPI0_D15, .offset = 11},
203 {P_PPI0_D13, 11}, {P_PPI0_D14, 11}, {P_PPI0_D15, 11}, 273 {.res = P_SPORT1_TFS, .offset = 11},
204 {P_SPORT1_TFS, 11}, {P_SPORT1_TSCLK, 11}, {P_SPORT1_DTPRI, 11}, 274 {.res = P_SPORT1_TSCLK, .offset = 11},
205 {P_PPI0_D10, 10}, {P_PPI0_D11, 10}, {P_PPI0_D12, 10}, 275 {.res = P_SPORT1_DTPRI, .offset = 11},
206 {P_SPORT1_RSCLK, 10}, {P_SPORT1_RFS, 10}, {P_SPORT1_DRPRI, 10}, 276 {.res = P_PPI0_D10, .offset = 10},
207 {P_PPI0_D8, 9}, {P_PPI0_D9, 9}, {P_SPORT1_DRSEC, 9}, 277 {.res = P_PPI0_D11, .offset = 10},
208 {P_SPORT1_DTSEC, 9}, {P_TMR2, 8}, {P_PPI0_FS3, 8}, {P_TMR3, 7}, 278 {.res = P_PPI0_D12, .offset = 10},
209 {P_SPI0_SSEL4, 7}, {P_TMR4, 6}, {P_SPI0_SSEL5, 6}, {P_TMR5, 5}, 279 {.res = P_SPORT1_RSCLK, .offset = 10},
210 {P_SPI0_SSEL6, 5}, {P_UART1_RX, 4}, {P_UART1_TX, 4}, {P_TMR6, 4}, 280 {.res = P_SPORT1_RFS, .offset = 10},
211 {P_TMR7, 4}, {P_UART0_RX, 3}, {P_UART0_TX, 3}, {P_DMAR0, 3}, 281 {.res = P_SPORT1_DRPRI, .offset = 10},
212 {P_DMAR1, 3}, {P_SPORT0_DTSEC, 1}, {P_SPORT0_DRSEC, 1}, 282 {.res = P_PPI0_D8, .offset = 9},
213 {P_CAN0_RX, 1}, {P_CAN0_TX, 1}, {P_SPI0_SSEL7, 1}, 283 {.res = P_PPI0_D9, .offset = 9},
214 {P_SPORT0_TFS, 0}, {P_SPORT0_DTPRI, 0}, {P_SPI0_SSEL2, 0}, 284 {.res = P_SPORT1_DRSEC, .offset = 9},
215 {P_SPI0_SSEL3, 0} 285 {.res = P_SPORT1_DTSEC, .offset = 9},
286 {.res = P_TMR2, .offset = 8},
287 {.res = P_PPI0_FS3, .offset = 8},
288 {.res = P_TMR3, .offset = 7},
289 {.res = P_SPI0_SSEL4, .offset = 7},
290 {.res = P_TMR4, .offset = 6},
291 {.res = P_SPI0_SSEL5, .offset = 6},
292 {.res = P_TMR5, .offset = 5},
293 {.res = P_SPI0_SSEL6, .offset = 5},
294 {.res = P_UART1_RX, .offset = 4},
295 {.res = P_UART1_TX, .offset = 4},
296 {.res = P_TMR6, .offset = 4},
297 {.res = P_TMR7, .offset = 4},
298 {.res = P_UART0_RX, .offset = 3},
299 {.res = P_UART0_TX, .offset = 3},
300 {.res = P_DMAR0, .offset = 3},
301 {.res = P_DMAR1, .offset = 3},
302 {.res = P_SPORT0_DTSEC, .offset = 1},
303 {.res = P_SPORT0_DRSEC, .offset = 1},
304 {.res = P_CAN0_RX, .offset = 1},
305 {.res = P_CAN0_TX, .offset = 1},
306 {.res = P_SPI0_SSEL7, .offset = 1},
307 {.res = P_SPORT0_TFS, .offset = 0},
308 {.res = P_SPORT0_DTPRI, .offset = 0},
309 {.res = P_SPI0_SSEL2, .offset = 0},
310 {.res = P_SPI0_SSEL3, .offset = 0},
216}; 311};
217 312
218static void portmux_setup(unsigned short per, unsigned short function) 313static void portmux_setup(unsigned short per, unsigned short function)
219{ 314{
220 u16 y, muxreg, offset; 315 u16 y, offset, muxreg;
221 316
222 for (y = 0; y < PMUX_LUT_ENTRIES; y++) { 317 for (y = 0; y < ARRAY_SIZE(port_mux_lut); y++) {
223 if (port_mux_lut[y][PMUX_LUT_RES] == per) { 318 if (port_mux_lut[y].res == per) {
224 319
225 /* SET PORTMUX REG */ 320 /* SET PORTMUX REG */
226 321
227 offset = port_mux_lut[y][PMUX_LUT_OFFSET]; 322 offset = port_mux_lut[y].offset;
228 muxreg = bfin_read_PORT_MUX(); 323 muxreg = bfin_read_PORT_MUX();
229 324
230 if (offset != 1) { 325 if (offset != 1) {
@@ -238,18 +333,42 @@ static void portmux_setup(unsigned short per, unsigned short function)
238 } 333 }
239 } 334 }
240} 335}
336#elif defined(BF548_FAMILY)
337inline void portmux_setup(unsigned short portno, unsigned short function)
338{
339 u32 pmux;
340
341 pmux = gpio_array[gpio_bank(portno)]->port_mux;
342
343 pmux &= ~(0x3 << (2 * gpio_sub_n(portno)));
344 pmux |= (function & 0x3) << (2 * gpio_sub_n(portno));
241 345
346 gpio_array[gpio_bank(portno)]->port_mux = pmux;
347}
348
349inline u16 get_portmux(unsigned short portno)
350{
351 u32 pmux;
352
353 pmux = gpio_array[gpio_bank(portno)]->port_mux;
354
355 return (pmux >> (2 * gpio_sub_n(portno)) & 0x3);
356}
242#else 357#else
243# define portmux_setup(...) do { } while (0) 358# define portmux_setup(...) do { } while (0)
244#endif 359#endif
245 360
361#ifndef BF548_FAMILY
246static void default_gpio(unsigned short gpio) 362static void default_gpio(unsigned short gpio)
247{ 363{
248 unsigned short bank, bitmask; 364 unsigned short bank, bitmask;
365 unsigned long flags;
249 366
250 bank = gpio_bank(gpio); 367 bank = gpio_bank(gpio);
251 bitmask = gpio_bit(gpio); 368 bitmask = gpio_bit(gpio);
252 369
370 local_irq_save(flags);
371
253 gpio_bankb[bank]->maska_clear = bitmask; 372 gpio_bankb[bank]->maska_clear = bitmask;
254 gpio_bankb[bank]->maskb_clear = bitmask; 373 gpio_bankb[bank]->maskb_clear = bitmask;
255 SSYNC(); 374 SSYNC();
@@ -258,24 +377,32 @@ static void default_gpio(unsigned short gpio)
258 gpio_bankb[bank]->polar &= ~bitmask; 377 gpio_bankb[bank]->polar &= ~bitmask;
259 gpio_bankb[bank]->both &= ~bitmask; 378 gpio_bankb[bank]->both &= ~bitmask;
260 gpio_bankb[bank]->edge &= ~bitmask; 379 gpio_bankb[bank]->edge &= ~bitmask;
380 AWA_DUMMY_READ(edge);
381 local_irq_restore(flags);
382
261} 383}
384#else
385# define default_gpio(...) do { } while (0)
386#endif
262 387
263static int __init bfin_gpio_init(void) 388static int __init bfin_gpio_init(void)
264{ 389{
265 390 str_ident = kcalloc(MAX_RESOURCES,
266 str_ident = kzalloc(RESOURCE_LABEL_SIZE * 256, GFP_KERNEL); 391 sizeof(struct str_ident), GFP_KERNEL);
267 if (!str_ident) 392 if (str_ident == NULL)
268 return -ENOMEM; 393 return -ENOMEM;
269 394
395 memset(str_ident, 0, MAX_RESOURCES * sizeof(struct str_ident));
396
270 printk(KERN_INFO "Blackfin GPIO Controller\n"); 397 printk(KERN_INFO "Blackfin GPIO Controller\n");
271 398
272 return 0; 399 return 0;
273 400
274} 401}
275
276arch_initcall(bfin_gpio_init); 402arch_initcall(bfin_gpio_init);
277 403
278 404
405#ifndef BF548_FAMILY
279/*********************************************************** 406/***********************************************************
280* 407*
281* FUNCTIONS: Blackfin General Purpose Ports Access Functions 408* FUNCTIONS: Blackfin General Purpose Ports Access Functions
@@ -305,6 +432,7 @@ void set_gpio_ ## name(unsigned short gpio, unsigned short arg) \
305 gpio_bankb[gpio_bank(gpio)]->name |= gpio_bit(gpio); \ 432 gpio_bankb[gpio_bank(gpio)]->name |= gpio_bit(gpio); \
306 else \ 433 else \
307 gpio_bankb[gpio_bank(gpio)]->name &= ~gpio_bit(gpio); \ 434 gpio_bankb[gpio_bank(gpio)]->name &= ~gpio_bit(gpio); \
435 AWA_DUMMY_READ(name); \
308 local_irq_restore(flags); \ 436 local_irq_restore(flags); \
309} \ 437} \
310EXPORT_SYMBOL(set_gpio_ ## name); 438EXPORT_SYMBOL(set_gpio_ ## name);
@@ -316,6 +444,22 @@ SET_GPIO(edge)
316SET_GPIO(both) 444SET_GPIO(both)
317 445
318 446
447#if ANOMALY_05000311 || ANOMALY_05000323
448#define SET_GPIO_SC(name) \
449void set_gpio_ ## name(unsigned short gpio, unsigned short arg) \
450{ \
451 unsigned long flags; \
452 BUG_ON(!(reserved_gpio_map[gpio_bank(gpio)] & gpio_bit(gpio))); \
453 local_irq_save(flags); \
454 if (arg) \
455 gpio_bankb[gpio_bank(gpio)]->name ## _set = gpio_bit(gpio); \
456 else \
457 gpio_bankb[gpio_bank(gpio)]->name ## _clear = gpio_bit(gpio); \
458 AWA_DUMMY_READ(name); \
459 local_irq_restore(flags); \
460} \
461EXPORT_SYMBOL(set_gpio_ ## name);
462#else
319#define SET_GPIO_SC(name) \ 463#define SET_GPIO_SC(name) \
320void set_gpio_ ## name(unsigned short gpio, unsigned short arg) \ 464void set_gpio_ ## name(unsigned short gpio, unsigned short arg) \
321{ \ 465{ \
@@ -326,37 +470,20 @@ void set_gpio_ ## name(unsigned short gpio, unsigned short arg) \
326 gpio_bankb[gpio_bank(gpio)]->name ## _clear = gpio_bit(gpio); \ 470 gpio_bankb[gpio_bank(gpio)]->name ## _clear = gpio_bit(gpio); \
327} \ 471} \
328EXPORT_SYMBOL(set_gpio_ ## name); 472EXPORT_SYMBOL(set_gpio_ ## name);
473#endif
329 474
330SET_GPIO_SC(maska) 475SET_GPIO_SC(maska)
331SET_GPIO_SC(maskb) 476SET_GPIO_SC(maskb)
332
333#if defined(ANOMALY_05000311)
334void set_gpio_data(unsigned short gpio, unsigned short arg)
335{
336 unsigned long flags;
337 BUG_ON(!(reserved_gpio_map[gpio_bank(gpio)] & gpio_bit(gpio)));
338 local_irq_save(flags);
339 if (arg)
340 gpio_bankb[gpio_bank(gpio)]->data_set = gpio_bit(gpio);
341 else
342 gpio_bankb[gpio_bank(gpio)]->data_clear = gpio_bit(gpio);
343 bfin_read_CHIPID();
344 local_irq_restore(flags);
345}
346EXPORT_SYMBOL(set_gpio_data);
347#else
348SET_GPIO_SC(data) 477SET_GPIO_SC(data)
349#endif
350
351 478
352#if defined(ANOMALY_05000311) 479#if ANOMALY_05000311 || ANOMALY_05000323
353void set_gpio_toggle(unsigned short gpio) 480void set_gpio_toggle(unsigned short gpio)
354{ 481{
355 unsigned long flags; 482 unsigned long flags;
356 BUG_ON(!(reserved_gpio_map[gpio_bank(gpio)] & gpio_bit(gpio))); 483 BUG_ON(!(reserved_gpio_map[gpio_bank(gpio)] & gpio_bit(gpio)));
357 local_irq_save(flags); 484 local_irq_save(flags);
358 gpio_bankb[gpio_bank(gpio)]->toggle = gpio_bit(gpio); 485 gpio_bankb[gpio_bank(gpio)]->toggle = gpio_bit(gpio);
359 bfin_read_CHIPID(); 486 AWA_DUMMY_READ(toggle);
360 local_irq_restore(flags); 487 local_irq_restore(flags);
361} 488}
362#else 489#else
@@ -371,13 +498,27 @@ EXPORT_SYMBOL(set_gpio_toggle);
371 498
372/*Set current PORT date (16-bit word)*/ 499/*Set current PORT date (16-bit word)*/
373 500
501#if ANOMALY_05000311 || ANOMALY_05000323
374#define SET_GPIO_P(name) \ 502#define SET_GPIO_P(name) \
375void set_gpiop_ ## name(unsigned short gpio, unsigned short arg) \ 503void set_gpiop_ ## name(unsigned short gpio, unsigned short arg) \
376{ \ 504{ \
505 unsigned long flags; \
506 local_irq_save(flags); \
377 gpio_bankb[gpio_bank(gpio)]->name = arg; \ 507 gpio_bankb[gpio_bank(gpio)]->name = arg; \
508 AWA_DUMMY_READ(name); \
509 local_irq_restore(flags); \
378} \ 510} \
379EXPORT_SYMBOL(set_gpiop_ ## name); 511EXPORT_SYMBOL(set_gpiop_ ## name);
512#else
513#define SET_GPIO_P(name) \
514void set_gpiop_ ## name(unsigned short gpio, unsigned short arg) \
515{ \
516 gpio_bankb[gpio_bank(gpio)]->name = arg; \
517} \
518EXPORT_SYMBOL(set_gpiop_ ## name);
519#endif
380 520
521SET_GPIO_P(data)
381SET_GPIO_P(dir) 522SET_GPIO_P(dir)
382SET_GPIO_P(inen) 523SET_GPIO_P(inen)
383SET_GPIO_P(polar) 524SET_GPIO_P(polar)
@@ -387,31 +528,30 @@ SET_GPIO_P(maska)
387SET_GPIO_P(maskb) 528SET_GPIO_P(maskb)
388 529
389 530
390#if defined(ANOMALY_05000311)
391void set_gpiop_data(unsigned short gpio, unsigned short arg)
392{
393 unsigned long flags;
394 local_irq_save(flags);
395 gpio_bankb[gpio_bank(gpio)]->data = arg;
396 bfin_read_CHIPID();
397 local_irq_restore(flags);
398}
399EXPORT_SYMBOL(set_gpiop_data);
400#else
401SET_GPIO_P(data)
402#endif
403
404
405
406/* Get a specific bit */ 531/* Get a specific bit */
407 532#if ANOMALY_05000311 || ANOMALY_05000323
533#define GET_GPIO(name) \
534unsigned short get_gpio_ ## name(unsigned short gpio) \
535{ \
536 unsigned long flags; \
537 unsigned short ret; \
538 local_irq_save(flags); \
539 ret = 0x01 & (gpio_bankb[gpio_bank(gpio)]->name >> gpio_sub_n(gpio)); \
540 AWA_DUMMY_READ(name); \
541 local_irq_restore(flags); \
542 return ret; \
543} \
544EXPORT_SYMBOL(get_gpio_ ## name);
545#else
408#define GET_GPIO(name) \ 546#define GET_GPIO(name) \
409unsigned short get_gpio_ ## name(unsigned short gpio) \ 547unsigned short get_gpio_ ## name(unsigned short gpio) \
410{ \ 548{ \
411 return (0x01 & (gpio_bankb[gpio_bank(gpio)]->name >> gpio_sub_n(gpio))); \ 549 return (0x01 & (gpio_bankb[gpio_bank(gpio)]->name >> gpio_sub_n(gpio))); \
412} \ 550} \
413EXPORT_SYMBOL(get_gpio_ ## name); 551EXPORT_SYMBOL(get_gpio_ ## name);
552#endif
414 553
554GET_GPIO(data)
415GET_GPIO(dir) 555GET_GPIO(dir)
416GET_GPIO(inen) 556GET_GPIO(inen)
417GET_GPIO(polar) 557GET_GPIO(polar)
@@ -420,33 +560,31 @@ GET_GPIO(both)
420GET_GPIO(maska) 560GET_GPIO(maska)
421GET_GPIO(maskb) 561GET_GPIO(maskb)
422 562
423
424#if defined(ANOMALY_05000311)
425unsigned short get_gpio_data(unsigned short gpio)
426{
427 unsigned long flags;
428 unsigned short ret;
429 BUG_ON(!(reserved_gpio_map[gpio_bank(gpio)] & gpio_bit(gpio)));
430 local_irq_save(flags);
431 ret = 0x01 & (gpio_bankb[gpio_bank(gpio)]->data >> gpio_sub_n(gpio));
432 bfin_read_CHIPID();
433 local_irq_restore(flags);
434 return ret;
435}
436EXPORT_SYMBOL(get_gpio_data);
437#else
438GET_GPIO(data)
439#endif
440
441/*Get current PORT date (16-bit word)*/ 563/*Get current PORT date (16-bit word)*/
442 564
565#if ANOMALY_05000311 || ANOMALY_05000323
566#define GET_GPIO_P(name) \
567unsigned short get_gpiop_ ## name(unsigned short gpio) \
568{ \
569 unsigned long flags; \
570 unsigned short ret; \
571 local_irq_save(flags); \
572 ret = (gpio_bankb[gpio_bank(gpio)]->name); \
573 AWA_DUMMY_READ(name); \
574 local_irq_restore(flags); \
575 return ret; \
576} \
577EXPORT_SYMBOL(get_gpiop_ ## name);
578#else
443#define GET_GPIO_P(name) \ 579#define GET_GPIO_P(name) \
444unsigned short get_gpiop_ ## name(unsigned short gpio) \ 580unsigned short get_gpiop_ ## name(unsigned short gpio) \
445{ \ 581{ \
446 return (gpio_bankb[gpio_bank(gpio)]->name);\ 582 return (gpio_bankb[gpio_bank(gpio)]->name);\
447} \ 583} \
448EXPORT_SYMBOL(get_gpiop_ ## name); 584EXPORT_SYMBOL(get_gpiop_ ## name);
585#endif
449 586
587GET_GPIO_P(data)
450GET_GPIO_P(dir) 588GET_GPIO_P(dir)
451GET_GPIO_P(inen) 589GET_GPIO_P(inen)
452GET_GPIO_P(polar) 590GET_GPIO_P(polar)
@@ -455,21 +593,6 @@ GET_GPIO_P(both)
455GET_GPIO_P(maska) 593GET_GPIO_P(maska)
456GET_GPIO_P(maskb) 594GET_GPIO_P(maskb)
457 595
458#if defined(ANOMALY_05000311)
459unsigned short get_gpiop_data(unsigned short gpio)
460{
461 unsigned long flags;
462 unsigned short ret;
463 local_irq_save(flags);
464 ret = gpio_bankb[gpio_bank(gpio)]->data;
465 bfin_read_CHIPID();
466 local_irq_restore(flags);
467 return ret;
468}
469EXPORT_SYMBOL(get_gpiop_data);
470#else
471GET_GPIO_P(data)
472#endif
473 596
474#ifdef CONFIG_PM 597#ifdef CONFIG_PM
475/*********************************************************** 598/***********************************************************
@@ -593,6 +716,8 @@ u32 gpio_pm_setup(void)
593 } 716 }
594 } 717 }
595 718
719 AWA_DUMMY_READ(maskb_set);
720
596 if (sic_iwr) 721 if (sic_iwr)
597 return sic_iwr; 722 return sic_iwr;
598 else 723 else
@@ -624,12 +749,99 @@ void gpio_pm_restore(void)
624 749
625 gpio_bankb[bank]->maskb = gpio_bank_saved[bank].maskb; 750 gpio_bankb[bank]->maskb = gpio_bank_saved[bank].maskb;
626 } 751 }
752 AWA_DUMMY_READ(maskb);
627} 753}
628 754
629#endif 755#endif
756#endif /* BF548_FAMILY */
630 757
758/***********************************************************
759*
760* FUNCTIONS: Blackfin Peripheral Resource Allocation
761* and PortMux Setup
762*
763* INPUTS/OUTPUTS:
764* per Peripheral Identifier
765* label String
766*
767* DESCRIPTION: Blackfin Peripheral Resource Allocation and Setup API
768*
769* CAUTION:
770*************************************************************
771* MODIFICATION HISTORY :
772**************************************************************/
773
774#ifdef BF548_FAMILY
775int peripheral_request(unsigned short per, const char *label)
776{
777 unsigned long flags;
778 unsigned short ident = P_IDENT(per);
779
780 /*
781 * Don't cares are pins with only one dedicated function
782 */
783
784 if (per & P_DONTCARE)
785 return 0;
786
787 if (!(per & P_DEFINED))
788 return -ENODEV;
789
790 if (check_gpio(ident) < 0)
791 return -EINVAL;
792
793 local_irq_save(flags);
794
795 if (unlikely(reserved_gpio_map[gpio_bank(ident)] & gpio_bit(ident))) {
796 printk(KERN_ERR
797 "%s: Peripheral %d is already reserved as GPIO by %s !\n",
798 __FUNCTION__, ident, get_label(ident));
799 dump_stack();
800 local_irq_restore(flags);
801 return -EBUSY;
802 }
803
804 if (unlikely(reserved_peri_map[gpio_bank(ident)] & gpio_bit(ident))) {
805
806 u16 funct = get_portmux(ident);
807
808 /*
809 * Pin functions like AMC address strobes my
810 * be requested and used by several drivers
811 */
812
813 if (!((per & P_MAYSHARE) && (funct == P_FUNCT2MUX(per)))) {
814
815 /*
816 * Allow that the identical pin function can
817 * be requested from the same driver twice
818 */
819
820 if (cmp_label(ident, label) == 0)
821 goto anyway;
631 822
823 printk(KERN_ERR
824 "%s: Peripheral %d function %d is already reserved by %s !\n",
825 __FUNCTION__, ident, P_FUNCT2MUX(per), get_label(ident));
826 dump_stack();
827 local_irq_restore(flags);
828 return -EBUSY;
829 }
830 }
632 831
832anyway:
833 reserved_peri_map[gpio_bank(ident)] |= gpio_bit(ident);
834
835 portmux_setup(ident, P_FUNCT2MUX(per));
836 port_setup(ident, PERIPHERAL_USAGE);
837
838 local_irq_restore(flags);
839 set_label(ident, label);
840
841 return 0;
842}
843EXPORT_SYMBOL(peripheral_request);
844#else
633 845
634int peripheral_request(unsigned short per, const char *label) 846int peripheral_request(unsigned short per, const char *label)
635{ 847{
@@ -680,7 +892,7 @@ int peripheral_request(unsigned short per, const char *label)
680 892
681 printk(KERN_ERR 893 printk(KERN_ERR
682 "%s: Peripheral %d function %d is already" 894 "%s: Peripheral %d function %d is already"
683 "reserved by %s !\n", 895 " reserved by %s !\n",
684 __FUNCTION__, ident, P_FUNCT2MUX(per), 896 __FUNCTION__, ident, P_FUNCT2MUX(per),
685 get_label(ident)); 897 get_label(ident));
686 dump_stack(); 898 dump_stack();
@@ -691,8 +903,6 @@ int peripheral_request(unsigned short per, const char *label)
691 } 903 }
692 904
693anyway: 905anyway:
694
695
696 portmux_setup(per, P_FUNCT2MUX(per)); 906 portmux_setup(per, P_FUNCT2MUX(per));
697 907
698 port_setup(ident, PERIPHERAL_USAGE); 908 port_setup(ident, PERIPHERAL_USAGE);
@@ -704,6 +914,7 @@ anyway:
704 return 0; 914 return 0;
705} 915}
706EXPORT_SYMBOL(peripheral_request); 916EXPORT_SYMBOL(peripheral_request);
917#endif
707 918
708int peripheral_request_list(unsigned short per[], const char *label) 919int peripheral_request_list(unsigned short per[], const char *label)
709{ 920{
@@ -711,9 +922,15 @@ int peripheral_request_list(unsigned short per[], const char *label)
711 int ret; 922 int ret;
712 923
713 for (cnt = 0; per[cnt] != 0; cnt++) { 924 for (cnt = 0; per[cnt] != 0; cnt++) {
925
714 ret = peripheral_request(per[cnt], label); 926 ret = peripheral_request(per[cnt], label);
715 if (ret < 0) 927
716 return ret; 928 if (ret < 0) {
929 for ( ; cnt > 0; cnt--) {
930 peripheral_free(per[cnt - 1]);
931 }
932 return ret;
933 }
717 } 934 }
718 935
719 return 0; 936 return 0;
@@ -748,6 +965,8 @@ void peripheral_free(unsigned short per)
748 965
749 reserved_peri_map[gpio_bank(ident)] &= ~gpio_bit(ident); 966 reserved_peri_map[gpio_bank(ident)] &= ~gpio_bit(ident);
750 967
968 set_label(ident, "free");
969
751 local_irq_restore(flags); 970 local_irq_restore(flags);
752} 971}
753EXPORT_SYMBOL(peripheral_free); 972EXPORT_SYMBOL(peripheral_free);
@@ -768,8 +987,8 @@ EXPORT_SYMBOL(peripheral_free_list);
768* FUNCTIONS: Blackfin GPIO Driver 987* FUNCTIONS: Blackfin GPIO Driver
769* 988*
770* INPUTS/OUTPUTS: 989* INPUTS/OUTPUTS:
771* gpio - GPIO Number between 0 and MAX_BLACKFIN_GPIOS 990* gpio PIO Number between 0 and MAX_BLACKFIN_GPIOS
772* 991* label String
773* 992*
774* DESCRIPTION: Blackfin GPIO Driver API 993* DESCRIPTION: Blackfin GPIO Driver API
775* 994*
@@ -787,17 +1006,39 @@ int gpio_request(unsigned short gpio, const char *label)
787 1006
788 local_irq_save(flags); 1007 local_irq_save(flags);
789 1008
1009 /*
1010 * Allow that the identical GPIO can
1011 * be requested from the same driver twice
1012 * Do nothing and return -
1013 */
1014
1015 if (cmp_label(gpio, label) == 0) {
1016 local_irq_restore(flags);
1017 return 0;
1018 }
1019
790 if (unlikely(reserved_gpio_map[gpio_bank(gpio)] & gpio_bit(gpio))) { 1020 if (unlikely(reserved_gpio_map[gpio_bank(gpio)] & gpio_bit(gpio))) {
791 printk(KERN_ERR "bfin-gpio: GPIO %d is already reserved!\n", gpio); 1021 printk(KERN_ERR "bfin-gpio: GPIO %d is already reserved by %s !\n",
1022 gpio, get_label(gpio));
792 dump_stack(); 1023 dump_stack();
793 local_irq_restore(flags); 1024 local_irq_restore(flags);
794 return -EBUSY; 1025 return -EBUSY;
795 } 1026 }
1027 if (unlikely(reserved_peri_map[gpio_bank(gpio)] & gpio_bit(gpio))) {
1028 printk(KERN_ERR
1029 "bfin-gpio: GPIO %d is already reserved as Peripheral by %s !\n",
1030 gpio, get_label(gpio));
1031 dump_stack();
1032 local_irq_restore(flags);
1033 return -EBUSY;
1034 }
1035
796 reserved_gpio_map[gpio_bank(gpio)] |= gpio_bit(gpio); 1036 reserved_gpio_map[gpio_bank(gpio)] |= gpio_bit(gpio);
797 1037
798 local_irq_restore(flags); 1038 local_irq_restore(flags);
799 1039
800 port_setup(gpio, GPIO_USAGE); 1040 port_setup(gpio, GPIO_USAGE);
1041 set_label(gpio, label);
801 1042
802 return 0; 1043 return 0;
803} 1044}
@@ -823,10 +1064,57 @@ void gpio_free(unsigned short gpio)
823 1064
824 reserved_gpio_map[gpio_bank(gpio)] &= ~gpio_bit(gpio); 1065 reserved_gpio_map[gpio_bank(gpio)] &= ~gpio_bit(gpio);
825 1066
1067 set_label(gpio, "free");
1068
826 local_irq_restore(flags); 1069 local_irq_restore(flags);
827} 1070}
828EXPORT_SYMBOL(gpio_free); 1071EXPORT_SYMBOL(gpio_free);
829 1072
1073#ifdef BF548_FAMILY
1074void gpio_direction_input(unsigned short gpio)
1075{
1076 unsigned long flags;
1077
1078 BUG_ON(!(reserved_gpio_map[gpio_bank(gpio)] & gpio_bit(gpio)));
1079
1080 local_irq_save(flags);
1081 gpio_array[gpio_bank(gpio)]->port_dir_clear = gpio_bit(gpio);
1082 gpio_array[gpio_bank(gpio)]->port_inen |= gpio_bit(gpio);
1083 local_irq_restore(flags);
1084}
1085EXPORT_SYMBOL(gpio_direction_input);
1086
1087void gpio_direction_output(unsigned short gpio)
1088{
1089 unsigned long flags;
1090
1091 BUG_ON(!(reserved_gpio_map[gpio_bank(gpio)] & gpio_bit(gpio)));
1092
1093 local_irq_save(flags);
1094 gpio_array[gpio_bank(gpio)]->port_inen &= ~gpio_bit(gpio);
1095 gpio_array[gpio_bank(gpio)]->port_dir_set = gpio_bit(gpio);
1096 local_irq_restore(flags);
1097}
1098EXPORT_SYMBOL(gpio_direction_output);
1099
1100void gpio_set_value(unsigned short gpio, unsigned short arg)
1101{
1102 if (arg)
1103 gpio_array[gpio_bank(gpio)]->port_set = gpio_bit(gpio);
1104 else
1105 gpio_array[gpio_bank(gpio)]->port_clear = gpio_bit(gpio);
1106
1107}
1108EXPORT_SYMBOL(gpio_set_value);
1109
1110unsigned short gpio_get_value(unsigned short gpio)
1111{
1112 return (1 & (gpio_array[gpio_bank(gpio)]->port_data >> gpio_sub_n(gpio)));
1113}
1114EXPORT_SYMBOL(gpio_get_value);
1115
1116#else
1117
830void gpio_direction_input(unsigned short gpio) 1118void gpio_direction_input(unsigned short gpio)
831{ 1119{
832 unsigned long flags; 1120 unsigned long flags;
@@ -836,6 +1124,7 @@ void gpio_direction_input(unsigned short gpio)
836 local_irq_save(flags); 1124 local_irq_save(flags);
837 gpio_bankb[gpio_bank(gpio)]->dir &= ~gpio_bit(gpio); 1125 gpio_bankb[gpio_bank(gpio)]->dir &= ~gpio_bit(gpio);
838 gpio_bankb[gpio_bank(gpio)]->inen |= gpio_bit(gpio); 1126 gpio_bankb[gpio_bank(gpio)]->inen |= gpio_bit(gpio);
1127 AWA_DUMMY_READ(inen);
839 local_irq_restore(flags); 1128 local_irq_restore(flags);
840} 1129}
841EXPORT_SYMBOL(gpio_direction_input); 1130EXPORT_SYMBOL(gpio_direction_input);
@@ -849,6 +1138,28 @@ void gpio_direction_output(unsigned short gpio)
849 local_irq_save(flags); 1138 local_irq_save(flags);
850 gpio_bankb[gpio_bank(gpio)]->inen &= ~gpio_bit(gpio); 1139 gpio_bankb[gpio_bank(gpio)]->inen &= ~gpio_bit(gpio);
851 gpio_bankb[gpio_bank(gpio)]->dir |= gpio_bit(gpio); 1140 gpio_bankb[gpio_bank(gpio)]->dir |= gpio_bit(gpio);
1141 AWA_DUMMY_READ(dir);
852 local_irq_restore(flags); 1142 local_irq_restore(flags);
853} 1143}
854EXPORT_SYMBOL(gpio_direction_output); 1144EXPORT_SYMBOL(gpio_direction_output);
1145
1146/* If we are booting from SPI and our board lacks a strong enough pull up,
1147 * the core can reset and execute the bootrom faster than the resistor can
1148 * pull the signal logically high. To work around this (common) error in
1149 * board design, we explicitly set the pin back to GPIO mode, force /CS
1150 * high, and wait for the electrons to do their thing.
1151 *
1152 * This function only makes sense to be called from reset code, but it
1153 * lives here as we need to force all the GPIO states w/out going through
1154 * BUG() checks and such.
1155 */
1156void bfin_gpio_reset_spi0_ssel1(void)
1157{
1158 u16 gpio = P_IDENT(P_SPI0_SSEL1);
1159
1160 port_setup(gpio, GPIO_USAGE);
1161 gpio_bankb[gpio_bank(gpio)]->data_set = gpio_bit(gpio);
1162 udelay(1);
1163}
1164
1165#endif /*BF548_FAMILY */
diff --git a/arch/blackfin/kernel/bfin_ksyms.c b/arch/blackfin/kernel/bfin_ksyms.c
index 70455949cfd2..2198afe40f33 100644
--- a/arch/blackfin/kernel/bfin_ksyms.c
+++ b/arch/blackfin/kernel/bfin_ksyms.c
@@ -60,6 +60,7 @@ EXPORT_SYMBOL(csum_partial_copy);
60 * their interface isn't gonna change any time soon now, so 60 * their interface isn't gonna change any time soon now, so
61 * it's OK to leave it out of version control. 61 * it's OK to leave it out of version control.
62 */ 62 */
63EXPORT_SYMBOL(strcpy);
63EXPORT_SYMBOL(memcpy); 64EXPORT_SYMBOL(memcpy);
64EXPORT_SYMBOL(memset); 65EXPORT_SYMBOL(memset);
65EXPORT_SYMBOL(memcmp); 66EXPORT_SYMBOL(memcmp);
diff --git a/arch/blackfin/kernel/cacheinit.c b/arch/blackfin/kernel/cacheinit.c
index 4d41a40e8133..62cbba7364b0 100644
--- a/arch/blackfin/kernel/cacheinit.c
+++ b/arch/blackfin/kernel/cacheinit.c
@@ -21,9 +21,10 @@
21 21
22#include <asm/cacheflush.h> 22#include <asm/cacheflush.h>
23#include <asm/blackfin.h> 23#include <asm/blackfin.h>
24#include <asm/cplb.h>
24#include <asm/cplbinit.h> 25#include <asm/cplbinit.h>
25 26
26#if defined(CONFIG_BLKFIN_CACHE) 27#if defined(CONFIG_BFIN_ICACHE)
27void bfin_icache_init(void) 28void bfin_icache_init(void)
28{ 29{
29 unsigned long *table = icplb_table; 30 unsigned long *table = icplb_table;
@@ -44,7 +45,7 @@ void bfin_icache_init(void)
44} 45}
45#endif 46#endif
46 47
47#if defined(CONFIG_BLKFIN_DCACHE) 48#if defined(CONFIG_BFIN_DCACHE)
48void bfin_dcache_init(void) 49void bfin_dcache_init(void)
49{ 50{
50 unsigned long *table = dcplb_table; 51 unsigned long *table = dcplb_table;
diff --git a/arch/blackfin/kernel/cplbinit.c b/arch/blackfin/kernel/cplbinit.c
index bbdb403fcb55..f2db6a5e2b5b 100644
--- a/arch/blackfin/kernel/cplbinit.c
+++ b/arch/blackfin/kernel/cplbinit.c
@@ -23,6 +23,7 @@
23#include <linux/module.h> 23#include <linux/module.h>
24 24
25#include <asm/blackfin.h> 25#include <asm/blackfin.h>
26#include <asm/cplb.h>
26#include <asm/cplbinit.h> 27#include <asm/cplbinit.h>
27 28
28u_long icplb_table[MAX_CPLBS+1]; 29u_long icplb_table[MAX_CPLBS+1];
@@ -56,7 +57,7 @@ struct s_cplb {
56 struct cplb_tab switch_d; 57 struct cplb_tab switch_d;
57}; 58};
58 59
59#if defined(CONFIG_BLKFIN_DCACHE) || defined(CONFIG_BLKFIN_CACHE) 60#if defined(CONFIG_BFIN_DCACHE) || defined(CONFIG_BFIN_ICACHE)
60static struct cplb_desc cplb_data[] = { 61static struct cplb_desc cplb_data[] = {
61 { 62 {
62 .start = 0, 63 .start = 0,
@@ -230,8 +231,8 @@ static void __fill_code_cplbtab(struct cplb_tab *t, int i, u32 a_start, u32 a_en
230 cplb_data[i].psize, 231 cplb_data[i].psize,
231 cplb_data[i].i_conf); 232 cplb_data[i].i_conf);
232 } else { 233 } else {
233#if (defined(CONFIG_BLKFIN_CACHE) && defined(ANOMALY_05000263)) 234#if defined(CONFIG_BFIN_ICACHE)
234 if (i == SDRAM_KERN) { 235 if (ANOMALY_05000263 && i == SDRAM_KERN) {
235 fill_cplbtab(t, 236 fill_cplbtab(t,
236 cplb_data[i].start, 237 cplb_data[i].start,
237 cplb_data[i].end, 238 cplb_data[i].end,
diff --git a/arch/blackfin/kernel/early_printk.c b/arch/blackfin/kernel/early_printk.c
new file mode 100644
index 000000000000..6ec518a81113
--- /dev/null
+++ b/arch/blackfin/kernel/early_printk.c
@@ -0,0 +1,214 @@
1/*
2 * File: arch/blackfin/kernel/early_printk.c
3 * Based on: arch/x86_64/kernel/early_printk.c
4 * Author: Robin Getz <rgetz@blackfin.uclinux.org
5 *
6 * Created: 14Aug2007
7 * Description: allow a console to be used for early printk
8 *
9 * Modified:
10 * Copyright 2004-2007 Analog Devices Inc.
11 *
12 * Bugs: Enter bugs at http://blackfin.uclinux.org/
13 *
14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by
16 * the Free Software Foundation; either version 2 of the License, or
17 * (at your option) any later version.
18 *
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
23 */
24
25#include <linux/kernel.h>
26#include <linux/init.h>
27#include <linux/serial_core.h>
28#include <linux/console.h>
29#include <linux/string.h>
30#include <asm/blackfin.h>
31#include <asm/irq_handler.h>
32#include <asm/early_printk.h>
33
34#ifdef CONFIG_SERIAL_BFIN
35extern struct console *bfin_earlyserial_init(unsigned int port,
36 unsigned int cflag);
37#endif
38
39static struct console *early_console;
40
41/* Default console */
42#define DEFAULT_PORT 0
43#define DEFAULT_CFLAG CS8|B57600
44
45/* Default console for early crashes */
46#define DEFAULT_EARLY_PORT "serial,uart0,57600"
47
48#ifdef CONFIG_SERIAL_CORE
49/* What should get here is "0,57600" */
50static struct console * __init earlyserial_init(char *buf)
51{
52 int baud, bit;
53 char parity;
54 unsigned int serial_port = DEFAULT_PORT;
55 unsigned int cflag = DEFAULT_CFLAG;
56
57 serial_port = simple_strtoul(buf, &buf, 10);
58 buf++;
59
60 cflag = 0;
61 baud = simple_strtoul(buf, &buf, 10);
62 switch (baud) {
63 case 1200:
64 cflag |= B1200;
65 break;
66 case 2400:
67 cflag |= B2400;
68 break;
69 case 4800:
70 cflag |= B4800;
71 break;
72 case 9600:
73 cflag |= B9600;
74 break;
75 case 19200:
76 cflag |= B19200;
77 break;
78 case 38400:
79 cflag |= B38400;
80 break;
81 case 115200:
82 cflag |= B115200;
83 break;
84 default:
85 cflag |= B57600;
86 }
87
88 parity = buf[0];
89 buf++;
90 switch (parity) {
91 case 'e':
92 cflag |= PARENB;
93 break;
94 case 'o':
95 cflag |= PARODD;
96 break;
97 }
98
99 bit = simple_strtoul(buf, &buf, 10);
100 switch (bit) {
101 case 5:
102 cflag |= CS5;
103 break;
104 case 6:
105 cflag |= CS5;
106 break;
107 case 7:
108 cflag |= CS5;
109 break;
110 default:
111 cflag |= CS8;
112 }
113
114#ifdef CONFIG_SERIAL_BFIN
115 return bfin_earlyserial_init(serial_port, cflag);
116#else
117 return NULL;
118#endif
119
120}
121#endif
122
123int __init setup_early_printk(char *buf)
124{
125
126 /* Crashing in here would be really bad, so check both the var
127 and the pointer before we start using it
128 */
129 if (!buf)
130 return 0;
131
132 if (!*buf)
133 return 0;
134
135 if (early_console != NULL)
136 return 0;
137
138#ifdef CONFIG_SERIAL_BFIN
139 /* Check for Blackfin Serial */
140 if (!strncmp(buf, "serial,uart", 11)) {
141 buf += 11;
142 early_console = earlyserial_init(buf);
143 }
144#endif
145#ifdef CONFIG_FB
146 /* TODO: add framebuffer console support */
147#endif
148
149 if (likely(early_console)) {
150 early_console->flags |= CON_BOOT;
151
152 register_console(early_console);
153 printk(KERN_INFO "early printk enabled on %s%d\n",
154 early_console->name,
155 early_console->index);
156 }
157
158 return 0;
159}
160
161/*
162 * Set up a temporary Event Vector Table, so if something bad happens before
163 * the kernel is fully started, it doesn't vector off into somewhere we don't
164 * know
165 */
166
167asmlinkage void __init init_early_exception_vectors(void)
168{
169 SSYNC();
170
171 /* cannot program in software:
172 * evt0 - emulation (jtag)
173 * evt1 - reset
174 */
175 bfin_write_EVT2(early_trap);
176 bfin_write_EVT3(early_trap);
177 bfin_write_EVT5(early_trap);
178 bfin_write_EVT6(early_trap);
179 bfin_write_EVT7(early_trap);
180 bfin_write_EVT8(early_trap);
181 bfin_write_EVT9(early_trap);
182 bfin_write_EVT10(early_trap);
183 bfin_write_EVT11(early_trap);
184 bfin_write_EVT12(early_trap);
185 bfin_write_EVT13(early_trap);
186 bfin_write_EVT14(early_trap);
187 bfin_write_EVT15(early_trap);
188 CSYNC();
189
190 /* Set all the return from interupt, exception, NMI to a known place
191 * so if we do a RETI, RETX or RETN by mistake - we go somewhere known
192 * Note - don't change RETS - we are in a subroutine, or
193 * RETE - since it might screw up if emulator is attached
194 */
195 asm("\tRETI = %0; RETX = %0; RETN = %0;\n"
196 : : "p"(early_trap));
197
198}
199
200asmlinkage void __init early_trap_c(struct pt_regs *fp, void *retaddr)
201{
202 /* This can happen before the uart is initialized, so initialize
203 * the UART now
204 */
205 if (likely(early_console == NULL))
206 setup_early_printk(DEFAULT_EARLY_PORT);
207
208 dump_bfin_regs(fp, retaddr);
209 dump_bfin_trace_buffer();
210
211 panic("Died early");
212}
213
214early_param("earlyprintk", setup_early_printk);
diff --git a/arch/blackfin/kernel/irqchip.c b/arch/blackfin/kernel/irqchip.c
index 1fc001c7abda..73647c158774 100644
--- a/arch/blackfin/kernel/irqchip.c
+++ b/arch/blackfin/kernel/irqchip.c
@@ -34,6 +34,7 @@
34#include <linux/kallsyms.h> 34#include <linux/kallsyms.h>
35#include <linux/interrupt.h> 35#include <linux/interrupt.h>
36#include <linux/irq.h> 36#include <linux/irq.h>
37#include <asm/trace.h>
37 38
38static unsigned long irq_err_count; 39static unsigned long irq_err_count;
39static spinlock_t irq_controller_lock; 40static spinlock_t irq_controller_lock;
@@ -97,9 +98,8 @@ int show_interrupts(struct seq_file *p, void *v)
97 */ 98 */
98 99
99#ifdef CONFIG_DO_IRQ_L1 100#ifdef CONFIG_DO_IRQ_L1
100asmlinkage void asm_do_IRQ(unsigned int irq, struct pt_regs *regs)__attribute__((l1_text)); 101__attribute__((l1_text))
101#endif 102#endif
102
103asmlinkage void asm_do_IRQ(unsigned int irq, struct pt_regs *regs) 103asmlinkage void asm_do_IRQ(unsigned int irq, struct pt_regs *regs)
104{ 104{
105 struct pt_regs *old_regs; 105 struct pt_regs *old_regs;
@@ -144,4 +144,12 @@ void __init init_IRQ(void)
144 } 144 }
145 145
146 init_arch_irq(); 146 init_arch_irq();
147
148#ifdef CONFIG_DEBUG_BFIN_HWTRACE_EXPAND
149 /* Now that evt_ivhw is set up, turn this on */
150 trace_buff_offset = 0;
151 bfin_write_TBUFCTL(BFIN_TRACE_ON);
152 printk(KERN_INFO "Hardware Trace expanded to %ik\n",
153 1 << CONFIG_DEBUG_BFIN_HWTRACE_EXPAND_LEN);
154#endif
147} 155}
diff --git a/arch/blackfin/kernel/process.c b/arch/blackfin/kernel/process.c
index 6a7aefe48346..9124467651c4 100644
--- a/arch/blackfin/kernel/process.c
+++ b/arch/blackfin/kernel/process.c
@@ -134,31 +134,6 @@ void cpu_idle(void)
134 } 134 }
135} 135}
136 136
137void machine_restart(char *__unused)
138{
139#if defined(CONFIG_BLKFIN_CACHE)
140 bfin_write_IMEM_CONTROL(0x01);
141 SSYNC();
142#endif
143 bfin_reset();
144 /* Dont do anything till the reset occurs */
145 while (1) {
146 SSYNC();
147 }
148}
149
150void machine_halt(void)
151{
152 for (;;)
153 asm volatile ("idle");
154}
155
156void machine_power_off(void)
157{
158 for (;;)
159 asm volatile ("idle");
160}
161
162void show_regs(struct pt_regs *regs) 137void show_regs(struct pt_regs *regs)
163{ 138{
164 printk(KERN_NOTICE "\n"); 139 printk(KERN_NOTICE "\n");
@@ -420,7 +395,8 @@ void finish_atomic_sections (struct pt_regs *regs)
420#if defined(CONFIG_ACCESS_CHECK) 395#if defined(CONFIG_ACCESS_CHECK)
421int _access_ok(unsigned long addr, unsigned long size) 396int _access_ok(unsigned long addr, unsigned long size)
422{ 397{
423 398 if (size == 0)
399 return 1;
424 if (addr > (addr + size)) 400 if (addr > (addr + size))
425 return 0; 401 return 0;
426 if (segment_eq(get_fs(), KERNEL_DS)) 402 if (segment_eq(get_fs(), KERNEL_DS))
diff --git a/arch/blackfin/kernel/ptrace.c b/arch/blackfin/kernel/ptrace.c
index ed800c7456dd..64ce5fea8609 100644
--- a/arch/blackfin/kernel/ptrace.c
+++ b/arch/blackfin/kernel/ptrace.c
@@ -44,6 +44,7 @@
44#include <asm/processor.h> 44#include <asm/processor.h>
45#include <asm/asm-offsets.h> 45#include <asm/asm-offsets.h>
46#include <asm/dma.h> 46#include <asm/dma.h>
47#include <asm/fixed_code.h>
47 48
48#define MAX_SHARED_LIBS 3 49#define MAX_SHARED_LIBS 3
49#define TEXT_OFFSET 0 50#define TEXT_OFFSET 0
@@ -169,6 +170,9 @@ static inline int is_user_addr_valid(struct task_struct *child,
169 && start + len <= (unsigned long)sraml->addr + sraml->length) 170 && start + len <= (unsigned long)sraml->addr + sraml->length)
170 return 0; 171 return 0;
171 172
173 if (start >= FIXED_CODE_START && start + len <= FIXED_CODE_END)
174 return 0;
175
172 return -EIO; 176 return -EIO;
173} 177}
174 178
@@ -215,9 +219,13 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
215 copied = sizeof(tmp); 219 copied = sizeof(tmp);
216 } else 220 } else
217#endif 221#endif
218 copied = 222 if (addr + add >= FIXED_CODE_START
219 access_process_vm(child, addr + add, &tmp, 223 && addr + add + sizeof(tmp) <= FIXED_CODE_END) {
220 sizeof(tmp), 0); 224 memcpy(&tmp, (const void *)(addr + add), sizeof(tmp));
225 copied = sizeof(tmp);
226 } else
227 copied = access_process_vm(child, addr + add, &tmp,
228 sizeof(tmp), 0);
221 pr_debug("ptrace: copied size %d [0x%08lx]\n", copied, tmp); 229 pr_debug("ptrace: copied size %d [0x%08lx]\n", copied, tmp);
222 if (copied != sizeof(tmp)) 230 if (copied != sizeof(tmp))
223 break; 231 break;
@@ -281,9 +289,13 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
281 copied = sizeof(data); 289 copied = sizeof(data);
282 } else 290 } else
283#endif 291#endif
284 copied = 292 if (addr + add >= FIXED_CODE_START
285 access_process_vm(child, addr + add, &data, 293 && addr + add + sizeof(data) <= FIXED_CODE_END) {
286 sizeof(data), 1); 294 memcpy((void *)(addr + add), &data, sizeof(data));
295 copied = sizeof(data);
296 } else
297 copied = access_process_vm(child, addr + add, &data,
298 sizeof(data), 1);
287 pr_debug("ptrace: copied size %d\n", copied); 299 pr_debug("ptrace: copied size %d\n", copied);
288 if (copied != sizeof(data)) 300 if (copied != sizeof(data))
289 break; 301 break;
diff --git a/arch/blackfin/kernel/reboot.c b/arch/blackfin/kernel/reboot.c
new file mode 100644
index 000000000000..356078ec462b
--- /dev/null
+++ b/arch/blackfin/kernel/reboot.c
@@ -0,0 +1,78 @@
1/*
2 * arch/blackfin/kernel/reboot.c - handle shutdown/reboot
3 *
4 * Copyright 2004-2007 Analog Devices Inc.
5 *
6 * Licensed under the GPL-2 or later.
7 */
8
9#include <linux/interrupt.h>
10#include <asm/bfin-global.h>
11#include <asm/reboot.h>
12#include <asm/system.h>
13
14#if defined(BF537_FAMILY) || defined(BF533_FAMILY)
15#define SYSCR_VAL 0x0
16#elif defined(BF561_FAMILY)
17#define SYSCR_VAL 0x20
18#elif defined(BF548_FAMILY)
19#define SYSCR_VAL 0x10
20#endif
21
22/* A system soft reset makes external memory unusable
23 * so force this function into L1.
24 */
25__attribute__((l1_text))
26void bfin_reset(void)
27{
28 /* force BMODE and disable Core B (as needed) */
29 bfin_write_SYSCR(SYSCR_VAL);
30
31 /* we use asm ssync here because it's save and we save some L1 */
32 asm("ssync;");
33
34 while (1) {
35 /* initiate system soft reset with magic 0x7 */
36 bfin_write_SWRST(0x7);
37 asm("ssync;");
38 /* clear system soft reset */
39 bfin_write_SWRST(0);
40 asm("ssync;");
41 /* issue core reset */
42 asm("raise 1");
43 }
44}
45
46__attribute__((weak))
47void native_machine_restart(char *cmd)
48{
49}
50
51void machine_restart(char *cmd)
52{
53 native_machine_restart(cmd);
54 local_irq_disable();
55 bfin_reset();
56}
57
58__attribute__((weak))
59void native_machine_halt(void)
60{
61 idle_with_irq_disabled();
62}
63
64void machine_halt(void)
65{
66 native_machine_halt();
67}
68
69__attribute__((weak))
70void native_machine_power_off(void)
71{
72 idle_with_irq_disabled();
73}
74
75void machine_power_off(void)
76{
77 native_machine_power_off();
78}
diff --git a/arch/blackfin/kernel/setup.c b/arch/blackfin/kernel/setup.c
index 88f221b89b33..8dcd76e87ed5 100644
--- a/arch/blackfin/kernel/setup.c
+++ b/arch/blackfin/kernel/setup.c
@@ -39,10 +39,12 @@
39#include <linux/cramfs_fs.h> 39#include <linux/cramfs_fs.h>
40#include <linux/romfs_fs.h> 40#include <linux/romfs_fs.h>
41 41
42#include <asm/cplb.h>
42#include <asm/cacheflush.h> 43#include <asm/cacheflush.h>
43#include <asm/blackfin.h> 44#include <asm/blackfin.h>
44#include <asm/cplbinit.h> 45#include <asm/cplbinit.h>
45#include <asm/fixed_code.h> 46#include <asm/fixed_code.h>
47#include <asm/early_printk.h>
46 48
47u16 _bfin_swrst; 49u16 _bfin_swrst;
48 50
@@ -66,21 +68,21 @@ char __initdata command_line[COMMAND_LINE_SIZE];
66 68
67void __init bf53x_cache_init(void) 69void __init bf53x_cache_init(void)
68{ 70{
69#if defined(CONFIG_BLKFIN_DCACHE) || defined(CONFIG_BLKFIN_CACHE) 71#if defined(CONFIG_BFIN_DCACHE) || defined(CONFIG_BFIN_ICACHE)
70 generate_cpl_tables(); 72 generate_cpl_tables();
71#endif 73#endif
72 74
73#ifdef CONFIG_BLKFIN_CACHE 75#ifdef CONFIG_BFIN_ICACHE
74 bfin_icache_init(); 76 bfin_icache_init();
75 printk(KERN_INFO "Instruction Cache Enabled\n"); 77 printk(KERN_INFO "Instruction Cache Enabled\n");
76#endif 78#endif
77 79
78#ifdef CONFIG_BLKFIN_DCACHE 80#ifdef CONFIG_BFIN_DCACHE
79 bfin_dcache_init(); 81 bfin_dcache_init();
80 printk(KERN_INFO "Data Cache Enabled" 82 printk(KERN_INFO "Data Cache Enabled"
81# if defined CONFIG_BLKFIN_WB 83# if defined CONFIG_BFIN_WB
82 " (write-back)" 84 " (write-back)"
83# elif defined CONFIG_BLKFIN_WT 85# elif defined CONFIG_BFIN_WT
84 " (write-through)" 86 " (write-through)"
85# endif 87# endif
86 "\n"); 88 "\n");
@@ -156,8 +158,10 @@ static __init void parse_cmdline_early(char *cmdline_p)
156 1; 158 1;
157 } 159 }
158 } 160 }
161 } else if (!memcmp(to, "earlyprintk=", 12)) {
162 to += 12;
163 setup_early_printk(to);
159 } 164 }
160
161 } 165 }
162 c = *(to++); 166 c = *(to++);
163 if (!c) 167 if (!c)
@@ -176,22 +180,36 @@ void __init setup_arch(char **cmdline_p)
176#ifdef CONFIG_DUMMY_CONSOLE 180#ifdef CONFIG_DUMMY_CONSOLE
177 conswitchp = &dummy_con; 181 conswitchp = &dummy_con;
178#endif 182#endif
183
184#if defined(CONFIG_CMDLINE_BOOL)
185 strncpy(&command_line[0], CONFIG_CMDLINE, sizeof(command_line));
186 command_line[sizeof(command_line) - 1] = 0;
187#endif
188
189 /* Keep a copy of command line */
190 *cmdline_p = &command_line[0];
191 memcpy(boot_command_line, command_line, COMMAND_LINE_SIZE);
192 boot_command_line[COMMAND_LINE_SIZE - 1] = '\0';
193
194 /* setup memory defaults from the user config */
195 physical_mem_end = 0;
196 _ramend = CONFIG_MEM_SIZE * 1024 * 1024;
197
198 parse_cmdline_early(&command_line[0]);
199
179 cclk = get_cclk(); 200 cclk = get_cclk();
180 sclk = get_sclk(); 201 sclk = get_sclk();
181 202
182#if !defined(CONFIG_BFIN_KERNEL_CLOCK) && defined(ANOMALY_05000273) 203#if !defined(CONFIG_BFIN_KERNEL_CLOCK)
183 if (cclk == sclk) 204 if (ANOMALY_05000273 && cclk == sclk)
184 panic("ANOMALY 05000273, SCLK can not be same as CCLK"); 205 panic("ANOMALY 05000273, SCLK can not be same as CCLK");
185#endif 206#endif
186 207
187#if defined(ANOMALY_05000266) 208#ifdef BF561_FAMILY
188 bfin_read_IMDMA_D0_IRQ_STATUS(); 209 if (ANOMALY_05000266) {
189 bfin_read_IMDMA_D1_IRQ_STATUS(); 210 bfin_read_IMDMA_D0_IRQ_STATUS();
190#endif 211 bfin_read_IMDMA_D1_IRQ_STATUS();
191 212 }
192#ifdef DEBUG_SERIAL_EARLY_INIT
193 bfin_console_init(); /* early console registration */
194 /* this give a chance to get printk() working before crash. */
195#endif 213#endif
196 214
197 printk(KERN_INFO "Hardware Trace "); 215 printk(KERN_INFO "Hardware Trace ");
@@ -212,22 +230,6 @@ void __init setup_arch(char **cmdline_p)
212 flash_probe(); 230 flash_probe();
213#endif 231#endif
214 232
215#if defined(CONFIG_CMDLINE_BOOL)
216 strncpy(&command_line[0], CONFIG_CMDLINE, sizeof(command_line));
217 command_line[sizeof(command_line) - 1] = 0;
218#endif
219
220 /* Keep a copy of command line */
221 *cmdline_p = &command_line[0];
222 memcpy(boot_command_line, command_line, COMMAND_LINE_SIZE);
223 boot_command_line[COMMAND_LINE_SIZE - 1] = '\0';
224
225 /* setup memory defaults from the user config */
226 physical_mem_end = 0;
227 _ramend = CONFIG_MEM_SIZE * 1024 * 1024;
228
229 parse_cmdline_early(&command_line[0]);
230
231 if (physical_mem_end == 0) 233 if (physical_mem_end == 0)
232 physical_mem_end = _ramend; 234 physical_mem_end = _ramend;
233 235
@@ -260,7 +262,7 @@ void __init setup_arch(char **cmdline_p)
260 && ((unsigned long *)mtd_phys)[1] == ROMSB_WORD1) 262 && ((unsigned long *)mtd_phys)[1] == ROMSB_WORD1)
261 mtd_size = 263 mtd_size =
262 PAGE_ALIGN(be32_to_cpu(((unsigned long *)mtd_phys)[2])); 264 PAGE_ALIGN(be32_to_cpu(((unsigned long *)mtd_phys)[2]));
263# if (defined(CONFIG_BLKFIN_CACHE) && defined(ANOMALY_05000263)) 265# if (defined(CONFIG_BFIN_ICACHE) && ANOMALY_05000263)
264 /* Due to a Hardware Anomaly we need to limit the size of usable 266 /* Due to a Hardware Anomaly we need to limit the size of usable
265 * instruction memory to max 60MB, 56 if HUNT_FOR_ZERO is on 267 * instruction memory to max 60MB, 56 if HUNT_FOR_ZERO is on
266 * 05000263 - Hardware loop corrupted when taking an ICPLB exception 268 * 05000263 - Hardware loop corrupted when taking an ICPLB exception
@@ -289,7 +291,7 @@ void __init setup_arch(char **cmdline_p)
289 _ebss = memory_mtd_start; /* define _ebss for compatible */ 291 _ebss = memory_mtd_start; /* define _ebss for compatible */
290#endif /* CONFIG_MTD_UCLINUX */ 292#endif /* CONFIG_MTD_UCLINUX */
291 293
292#if (defined(CONFIG_BLKFIN_CACHE) && defined(ANOMALY_05000263)) 294#if (defined(CONFIG_BFIN_ICACHE) && ANOMALY_05000263)
293 /* Due to a Hardware Anomaly we need to limit the size of usable 295 /* Due to a Hardware Anomaly we need to limit the size of usable
294 * instruction memory to max 60MB, 56 if HUNT_FOR_ZERO is on 296 * instruction memory to max 60MB, 56 if HUNT_FOR_ZERO is on
295 * 05000263 - Hardware loop corrupted when taking an ICPLB exception 297 * 05000263 - Hardware loop corrupted when taking an ICPLB exception
@@ -334,13 +336,11 @@ void __init setup_arch(char **cmdline_p)
334 CPU, bfin_revid()); 336 CPU, bfin_revid());
335 printk(KERN_INFO "Blackfin Linux support by http://blackfin.uclinux.org/\n"); 337 printk(KERN_INFO "Blackfin Linux support by http://blackfin.uclinux.org/\n");
336 338
337 printk(KERN_INFO "Processor Speed: %lu MHz core clock and %lu Mhz System Clock\n", 339 printk(KERN_INFO "Processor Speed: %lu MHz core clock and %lu MHz System Clock\n",
338 cclk / 1000000, sclk / 1000000); 340 cclk / 1000000, sclk / 1000000);
339 341
340#if defined(ANOMALY_05000273) 342 if (ANOMALY_05000273 && (cclk >> 1) <= sclk)
341 if ((cclk >> 1) <= sclk)
342 printk("\n\n\nANOMALY_05000273: CCLK must be >= 2*SCLK !!!\n\n\n"); 343 printk("\n\n\nANOMALY_05000273: CCLK must be >= 2*SCLK !!!\n\n\n");
343#endif
344 344
345 printk(KERN_INFO "Board Memory: %ldMB\n", physical_mem_end >> 20); 345 printk(KERN_INFO "Board Memory: %ldMB\n", physical_mem_end >> 20);
346 printk(KERN_INFO "Kernel Managed Memory: %ldMB\n", _ramend >> 20); 346 printk(KERN_INFO "Kernel Managed Memory: %ldMB\n", _ramend >> 20);
@@ -535,9 +535,9 @@ static int show_cpuinfo(struct seq_file *m, void *v)
535 seq_printf(m, "I-CACHE:\tOFF\n"); 535 seq_printf(m, "I-CACHE:\tOFF\n");
536 if ((bfin_read_DMEM_CONTROL()) & (ENDCPLB | DMC_ENABLE)) 536 if ((bfin_read_DMEM_CONTROL()) & (ENDCPLB | DMC_ENABLE))
537 seq_printf(m, "D-CACHE:\tON" 537 seq_printf(m, "D-CACHE:\tON"
538#if defined CONFIG_BLKFIN_WB 538#if defined CONFIG_BFIN_WB
539 " (write-back)" 539 " (write-back)"
540#elif defined CONFIG_BLKFIN_WT 540#elif defined CONFIG_BFIN_WT
541 " (write-through)" 541 " (write-through)"
542#endif 542#endif
543 "\n"); 543 "\n");
@@ -566,15 +566,15 @@ static int show_cpuinfo(struct seq_file *m, void *v)
566 } 566 }
567 567
568 568
569 seq_printf(m, "I-CACHE Size:\t%dKB\n", BLKFIN_ICACHESIZE / 1024); 569 seq_printf(m, "I-CACHE Size:\t%dKB\n", BFIN_ICACHESIZE / 1024);
570 seq_printf(m, "D-CACHE Size:\t%dKB\n", dcache_size); 570 seq_printf(m, "D-CACHE Size:\t%dKB\n", dcache_size);
571 seq_printf(m, "I-CACHE Setup:\t%d Sub-banks/%d Ways, %d Lines/Way\n", 571 seq_printf(m, "I-CACHE Setup:\t%d Sub-banks/%d Ways, %d Lines/Way\n",
572 BLKFIN_ISUBBANKS, BLKFIN_IWAYS, BLKFIN_ILINES); 572 BFIN_ISUBBANKS, BFIN_IWAYS, BFIN_ILINES);
573 seq_printf(m, 573 seq_printf(m,
574 "D-CACHE Setup:\t%d Super-banks/%d Sub-banks/%d Ways, %d Lines/Way\n", 574 "D-CACHE Setup:\t%d Super-banks/%d Sub-banks/%d Ways, %d Lines/Way\n",
575 dsup_banks, BLKFIN_DSUBBANKS, BLKFIN_DWAYS, 575 dsup_banks, BFIN_DSUBBANKS, BFIN_DWAYS,
576 BLKFIN_DLINES); 576 BFIN_DLINES);
577#ifdef CONFIG_BLKFIN_CACHE_LOCK 577#ifdef CONFIG_BFIN_ICACHE_LOCK
578 switch (read_iloc()) { 578 switch (read_iloc()) {
579 case WAY0_L: 579 case WAY0_L:
580 seq_printf(m, "Way0 Locked-Down\n"); 580 seq_printf(m, "Way0 Locked-Down\n");
diff --git a/arch/blackfin/kernel/traps.c b/arch/blackfin/kernel/traps.c
index 792a8416fe10..8823e9ade584 100644
--- a/arch/blackfin/kernel/traps.c
+++ b/arch/blackfin/kernel/traps.c
@@ -51,10 +51,9 @@ void __init trap_init(void)
51 CSYNC(); 51 CSYNC();
52} 52}
53 53
54asmlinkage void trap_c(struct pt_regs *fp);
55
56int kstack_depth_to_print = 48; 54int kstack_depth_to_print = 48;
57 55
56#ifdef CONFIG_DEBUG_BFIN_HWTRACE_ON
58static int printk_address(unsigned long address) 57static int printk_address(unsigned long address)
59{ 58{
60 struct vm_list_struct *vml; 59 struct vm_list_struct *vml;
@@ -131,10 +130,22 @@ static int printk_address(unsigned long address)
131 /* we were unable to find this address anywhere */ 130 /* we were unable to find this address anywhere */
132 return printk("[<0x%p>]", (void *)address); 131 return printk("[<0x%p>]", (void *)address);
133} 132}
133#endif
134
135asmlinkage void double_fault_c(struct pt_regs *fp)
136{
137 printk(KERN_EMERG "\n" KERN_EMERG "Double Fault\n");
138 dump_bfin_regs(fp, (void *)fp->retx);
139 panic("Double Fault - unrecoverable event\n");
140
141}
134 142
135asmlinkage void trap_c(struct pt_regs *fp) 143asmlinkage void trap_c(struct pt_regs *fp)
136{ 144{
137 int j, sig = 0; 145#ifdef CONFIG_DEBUG_BFIN_HWTRACE_ON
146 int j;
147#endif
148 int sig = 0;
138 siginfo_t info; 149 siginfo_t info;
139 unsigned long trapnr = fp->seqstat & SEQSTAT_EXCAUSE; 150 unsigned long trapnr = fp->seqstat & SEQSTAT_EXCAUSE;
140 151
@@ -391,10 +402,6 @@ asmlinkage void trap_c(struct pt_regs *fp)
391 break; 402 break;
392 } 403 }
393 404
394 info.si_signo = sig;
395 info.si_errno = 0;
396 info.si_addr = (void *)fp->pc;
397 force_sig_info(sig, &info, current);
398 if (sig != 0 && sig != SIGTRAP) { 405 if (sig != 0 && sig != SIGTRAP) {
399 unsigned long stack; 406 unsigned long stack;
400 dump_bfin_regs(fp, (void *)fp->retx); 407 dump_bfin_regs(fp, (void *)fp->retx);
@@ -403,6 +410,10 @@ asmlinkage void trap_c(struct pt_regs *fp)
403 if (current->mm == NULL) 410 if (current->mm == NULL)
404 panic("Kernel exception"); 411 panic("Kernel exception");
405 } 412 }
413 info.si_signo = sig;
414 info.si_errno = 0;
415 info.si_addr = (void *)fp->pc;
416 force_sig_info(sig, &info, current);
406 417
407 /* if the address that we are about to return to is not valid, set it 418 /* if the address that we are about to return to is not valid, set it
408 * to a valid address, if we have a current application or panic 419 * to a valid address, if we have a current application or panic
@@ -429,24 +440,56 @@ asmlinkage void trap_c(struct pt_regs *fp)
429 440
430/* Typical exception handling routines */ 441/* Typical exception handling routines */
431 442
443#define EXPAND_LEN ((1 << CONFIG_DEBUG_BFIN_HWTRACE_EXPAND_LEN) * 256 - 1)
444
432void dump_bfin_trace_buffer(void) 445void dump_bfin_trace_buffer(void)
433{ 446{
434 int tflags; 447#ifdef CONFIG_DEBUG_BFIN_HWTRACE_ON
448 int tflags, i = 0;
449#ifdef CONFIG_DEBUG_BFIN_HWTRACE_EXPAND
450 int j, index;
451#endif
452
435 trace_buffer_save(tflags); 453 trace_buffer_save(tflags);
436 454
455 printk(KERN_EMERG "Hardware Trace:\n");
456
437 if (likely(bfin_read_TBUFSTAT() & TBUFCNT)) { 457 if (likely(bfin_read_TBUFSTAT() & TBUFCNT)) {
438 int i; 458 for (; bfin_read_TBUFSTAT() & TBUFCNT; i++) {
439 printk(KERN_EMERG "Hardware Trace:\n"); 459 printk(KERN_EMERG "%4i Target : ", i);
440 for (i = 0; bfin_read_TBUFSTAT() & TBUFCNT; i++) {
441 printk(KERN_EMERG "%2i Target : ", i);
442 printk_address((unsigned long)bfin_read_TBUF()); 460 printk_address((unsigned long)bfin_read_TBUF());
443 printk("\n" KERN_EMERG " Source : "); 461 printk("\n" KERN_EMERG " Source : ");
444 printk_address((unsigned long)bfin_read_TBUF()); 462 printk_address((unsigned long)bfin_read_TBUF());
445 printk("\n"); 463 printk("\n");
446 } 464 }
447 } 465 }
448 466
467#ifdef CONFIG_DEBUG_BFIN_HWTRACE_EXPAND
468 if (trace_buff_offset)
469 index = trace_buff_offset/4 - 1;
470 else
471 index = EXPAND_LEN;
472
473 j = (1 << CONFIG_DEBUG_BFIN_HWTRACE_EXPAND_LEN) * 128;
474 while (j) {
475 printk(KERN_EMERG "%4i Target : ", i);
476 printk_address(software_trace_buff[index]);
477 index -= 1;
478 if (index < 0 )
479 index = EXPAND_LEN;
480 printk("\n" KERN_EMERG " Source : ");
481 printk_address(software_trace_buff[index]);
482 index -= 1;
483 if (index < 0)
484 index = EXPAND_LEN;
485 printk("\n");
486 j--;
487 i++;
488 }
489#endif
490
449 trace_buffer_restore(tflags); 491 trace_buffer_restore(tflags);
492#endif
450} 493}
451EXPORT_SYMBOL(dump_bfin_trace_buffer); 494EXPORT_SYMBOL(dump_bfin_trace_buffer);
452 495
@@ -510,7 +553,9 @@ void show_stack(struct task_struct *task, unsigned long *stack)
510void dump_stack(void) 553void dump_stack(void)
511{ 554{
512 unsigned long stack; 555 unsigned long stack;
556#ifdef CONFIG_DEBUG_BFIN_HWTRACE_ON
513 int tflags; 557 int tflags;
558#endif
514 trace_buffer_save(tflags); 559 trace_buffer_save(tflags);
515 dump_bfin_trace_buffer(); 560 dump_bfin_trace_buffer();
516 show_stack(current, &stack); 561 show_stack(current, &stack);
@@ -559,8 +604,7 @@ void dump_bfin_regs(struct pt_regs *fp, void *retaddr)
559 unsigned short x = 0; 604 unsigned short x = 0;
560 for (; i < ((unsigned int)retaddr & 0xFFFFFFF0) + 32; i += 2) { 605 for (; i < ((unsigned int)retaddr & 0xFFFFFFF0) + 32; i += 2) {
561 if (!(i & 0xF)) 606 if (!(i & 0xF))
562 printk(KERN_EMERG "\n" KERN_EMERG 607 printk("\n" KERN_EMERG "0x%08x: ", i);
563 "0x%08x: ", i);
564 608
565 if (get_user(x, (unsigned short *)i)) 609 if (get_user(x, (unsigned short *)i))
566 break; 610 break;
@@ -655,6 +699,42 @@ asmlinkage int sys_bfin_spinlock(int *spinlock)
655 return ret; 699 return ret;
656} 700}
657 701
702int bfin_request_exception(unsigned int exception, void (*handler)(void))
703{
704 void (*curr_handler)(void);
705
706 if (exception > 0x3F)
707 return -EINVAL;
708
709 curr_handler = ex_table[exception];
710
711 if (curr_handler != ex_replaceable)
712 return -EBUSY;
713
714 ex_table[exception] = handler;
715
716 return 0;
717}
718EXPORT_SYMBOL(bfin_request_exception);
719
720int bfin_free_exception(unsigned int exception, void (*handler)(void))
721{
722 void (*curr_handler)(void);
723
724 if (exception > 0x3F)
725 return -EINVAL;
726
727 curr_handler = ex_table[exception];
728
729 if (curr_handler != handler)
730 return -EBUSY;
731
732 ex_table[exception] = ex_replaceable;
733
734 return 0;
735}
736EXPORT_SYMBOL(bfin_free_exception);
737
658void panic_cplb_error(int cplb_panic, struct pt_regs *fp) 738void panic_cplb_error(int cplb_panic, struct pt_regs *fp)
659{ 739{
660 switch (cplb_panic) { 740 switch (cplb_panic) {
diff --git a/arch/blackfin/kernel/vmlinux.lds.S b/arch/blackfin/kernel/vmlinux.lds.S
index fb53780247bc..eec43674a465 100644
--- a/arch/blackfin/kernel/vmlinux.lds.S
+++ b/arch/blackfin/kernel/vmlinux.lds.S
@@ -49,7 +49,8 @@ SECTIONS
49 TEXT_TEXT 49 TEXT_TEXT
50 SCHED_TEXT 50 SCHED_TEXT
51 LOCK_TEXT 51 LOCK_TEXT
52 *(.text.lock) 52 KPROBES_TEXT
53 *(.text.*)
53 *(.fixup) 54 *(.fixup)
54 55
55 . = ALIGN(16); 56 . = ALIGN(16);
@@ -61,7 +62,7 @@ SECTIONS
61 __etext = .; 62 __etext = .;
62 } 63 }
63 64
64 RODATA 65 RO_DATA(PAGE_SIZE)
65 66
66 .data : 67 .data :
67 { 68 {
@@ -72,50 +73,63 @@ SECTIONS
72 __sdata = .; 73 __sdata = .;
73 . = ALIGN(THREAD_SIZE); 74 . = ALIGN(THREAD_SIZE);
74 *(.data.init_task) 75 *(.data.init_task)
75 DATA_DATA
76 CONSTRUCTORS
77 76
78 . = ALIGN(32); 77 . = ALIGN(32);
79 *(.data.cacheline_aligned) 78 *(.data.cacheline_aligned)
80 79
80 DATA_DATA
81 *(.data.*)
82 CONSTRUCTORS
83
81 . = ALIGN(THREAD_SIZE); 84 . = ALIGN(THREAD_SIZE);
82 __edata = .; 85 __edata = .;
83 } 86 }
84 87
85 ___init_begin = .; 88 ___init_begin = .;
86 .init : 89
90 .init.text :
87 { 91 {
88 . = ALIGN(PAGE_SIZE); 92 . = ALIGN(PAGE_SIZE);
89 __sinittext = .; 93 __sinittext = .;
90 *(.init.text) 94 *(.init.text)
91 __einittext = .; 95 __einittext = .;
96 }
97 .init.data :
98 {
99 . = ALIGN(16);
92 *(.init.data) 100 *(.init.data)
101 }
102 .init.setup :
103 {
93 . = ALIGN(16); 104 . = ALIGN(16);
94 ___setup_start = .; 105 ___setup_start = .;
95 *(.init.setup) 106 *(.init.setup)
96 ___setup_end = .; 107 ___setup_end = .;
97 ___start___param = .; 108 }
98 *(__param) 109 .initcall.init :
99 ___stop___param = .; 110 {
100 ___initcall_start = .; 111 ___initcall_start = .;
101 INITCALLS 112 INITCALLS
102 ___initcall_end = .; 113 ___initcall_end = .;
114 }
115 .con_initcall.init :
116 {
103 ___con_initcall_start = .; 117 ___con_initcall_start = .;
104 *(.con_initcall.init) 118 *(.con_initcall.init)
105 ___con_initcall_end = .; 119 ___con_initcall_end = .;
106 ___security_initcall_start = .; 120 }
107 *(.security_initcall.init) 121 SECURITY_INIT
108 ___security_initcall_end = .; 122 .init.ramfs :
123 {
109 . = ALIGN(4); 124 . = ALIGN(4);
110 ___initramfs_start = .; 125 ___initramfs_start = .;
111 *(.init.ramfs) 126 *(.init.ramfs)
112 ___initramfs_end = .; 127 ___initramfs_end = .;
113 . = ALIGN(4);
114 } 128 }
115 129
116 __l1_lma_start = .; 130 __l1_lma_start = .;
117 131
118 .text_l1 L1_CODE_START : AT(LOADADDR(.init) + SIZEOF(.init)) 132 .text_l1 L1_CODE_START : AT(LOADADDR(.init.ramfs) + SIZEOF(.init.ramfs))
119 { 133 {
120 . = ALIGN(4); 134 . = ALIGN(4);
121 __stext_l1 = .; 135 __stext_l1 = .;
@@ -164,13 +178,19 @@ SECTIONS
164 { 178 {
165 . = ALIGN(4); 179 . = ALIGN(4);
166 ___bss_start = .; 180 ___bss_start = .;
167 *(.bss) 181 *(.bss .bss.*)
168 *(COMMON) 182 *(COMMON)
169 . = ALIGN(4); 183 . = ALIGN(4);
170 ___bss_stop = .; 184 ___bss_stop = .;
171 __end = .; 185 __end = .;
172 } 186 }
173 187
188 STABS_DEBUG
189
190 DWARF_DEBUG
191
192 NOTES
193
174 /DISCARD/ : 194 /DISCARD/ :
175 { 195 {
176 *(.exit.text) 196 *(.exit.text)