diff options
Diffstat (limited to 'arch/blackfin/kernel')
-rw-r--r-- | arch/blackfin/kernel/Makefile | 2 | ||||
-rw-r--r-- | arch/blackfin/kernel/bfin_dma_5xx.c | 7 | ||||
-rw-r--r-- | arch/blackfin/kernel/bfin_gpio.c | 578 | ||||
-rw-r--r-- | arch/blackfin/kernel/cplb-mpu/cplbinit.c | 4 | ||||
-rw-r--r-- | arch/blackfin/kernel/cplb-nompu/cplbmgr.c | 12 | ||||
-rw-r--r-- | arch/blackfin/kernel/irqchip.c | 8 | ||||
-rw-r--r-- | arch/blackfin/kernel/reboot.c | 30 | ||||
-rw-r--r-- | arch/blackfin/kernel/setup.c | 12 | ||||
-rw-r--r-- | arch/blackfin/kernel/traps.c | 39 |
9 files changed, 300 insertions, 392 deletions
diff --git a/arch/blackfin/kernel/Makefile b/arch/blackfin/kernel/Makefile index 38a233374f0..4a92a86824b 100644 --- a/arch/blackfin/kernel/Makefile +++ b/arch/blackfin/kernel/Makefile @@ -15,6 +15,8 @@ else obj-y += time.o endif +CFLAGS_kgdb_test.o := -mlong-calls -O0 + obj-$(CONFIG_IPIPE) += ipipe.o obj-$(CONFIG_IPIPE_TRACE_MCOUNT) += mcount.o obj-$(CONFIG_BFIN_GPTIMERS) += gptimers.o diff --git a/arch/blackfin/kernel/bfin_dma_5xx.c b/arch/blackfin/kernel/bfin_dma_5xx.c index 07e02c0d1c0..8531693fb48 100644 --- a/arch/blackfin/kernel/bfin_dma_5xx.c +++ b/arch/blackfin/kernel/bfin_dma_5xx.c @@ -249,6 +249,13 @@ static void __dma_memcpy(u32 daddr, s16 dmod, u32 saddr, s16 smod, size_t cnt, u spin_lock_irqsave(&mdma_lock, flags); + /* Force a sync in case a previous config reset on this channel + * occurred. This is needed so subsequent writes to DMA registers + * are not spuriously lost/corrupted. Do it under irq lock and + * without the anomaly version (because we are atomic already). + */ + __builtin_bfin_ssync(); + if (bfin_read_MDMA_S0_CONFIG()) while (!(bfin_read_MDMA_D0_IRQ_STATUS() & DMA_DONE)) continue; diff --git a/arch/blackfin/kernel/bfin_gpio.c b/arch/blackfin/kernel/bfin_gpio.c index 4c14331978f..51dac55c524 100644 --- a/arch/blackfin/kernel/bfin_gpio.c +++ b/arch/blackfin/kernel/bfin_gpio.c @@ -27,59 +27,6 @@ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ -/* -* Number BF537/6/4 BF561 BF533/2/1 BF549/8/4/2 -* -* GPIO_0 PF0 PF0 PF0 PA0...PJ13 -* GPIO_1 PF1 PF1 PF1 -* GPIO_2 PF2 PF2 PF2 -* GPIO_3 PF3 PF3 PF3 -* GPIO_4 PF4 PF4 PF4 -* GPIO_5 PF5 PF5 PF5 -* GPIO_6 PF6 PF6 PF6 -* GPIO_7 PF7 PF7 PF7 -* GPIO_8 PF8 PF8 PF8 -* GPIO_9 PF9 PF9 PF9 -* GPIO_10 PF10 PF10 PF10 -* GPIO_11 PF11 PF11 PF11 -* GPIO_12 PF12 PF12 PF12 -* GPIO_13 PF13 PF13 PF13 -* GPIO_14 PF14 PF14 PF14 -* GPIO_15 PF15 PF15 PF15 -* GPIO_16 PG0 PF16 -* GPIO_17 PG1 PF17 -* GPIO_18 PG2 PF18 -* GPIO_19 PG3 PF19 -* GPIO_20 PG4 PF20 -* GPIO_21 PG5 PF21 -* GPIO_22 PG6 PF22 -* GPIO_23 PG7 PF23 -* GPIO_24 PG8 PF24 -* GPIO_25 PG9 PF25 -* GPIO_26 PG10 PF26 -* GPIO_27 PG11 PF27 -* GPIO_28 PG12 PF28 -* GPIO_29 PG13 PF29 -* GPIO_30 PG14 PF30 -* GPIO_31 PG15 PF31 -* GPIO_32 PH0 PF32 -* GPIO_33 PH1 PF33 -* GPIO_34 PH2 PF34 -* GPIO_35 PH3 PF35 -* GPIO_36 PH4 PF36 -* GPIO_37 PH5 PF37 -* GPIO_38 PH6 PF38 -* GPIO_39 PH7 PF39 -* GPIO_40 PH8 PF40 -* GPIO_41 PH9 PF41 -* GPIO_42 PH10 PF42 -* GPIO_43 PH11 PF43 -* GPIO_44 PH12 PF44 -* GPIO_45 PH13 PF45 -* GPIO_46 PH14 PF46 -* GPIO_47 PH15 PF47 -*/ - #include <linux/delay.h> #include <linux/module.h> #include <linux/err.h> @@ -119,62 +66,61 @@ enum { #define AWA_DUMMY_READ(...) do { } while (0) #endif +static struct gpio_port_t * const gpio_array[] = { #if defined(BF533_FAMILY) || defined(BF538_FAMILY) -static struct gpio_port_t *gpio_bankb[] = { (struct gpio_port_t *) FIO_FLAG_D, -}; -#endif - -#if defined(BF527_FAMILY) || defined(BF537_FAMILY) || defined(BF518_FAMILY) -static struct gpio_port_t *gpio_bankb[] = { +#elif defined(BF527_FAMILY) || defined(BF537_FAMILY) || defined(BF518_FAMILY) (struct gpio_port_t *) PORTFIO, (struct gpio_port_t *) PORTGIO, (struct gpio_port_t *) PORTHIO, +#elif defined(BF561_FAMILY) + (struct gpio_port_t *) FIO0_FLAG_D, + (struct gpio_port_t *) FIO1_FLAG_D, + (struct gpio_port_t *) FIO2_FLAG_D, +#elif defined(BF548_FAMILY) + (struct gpio_port_t *)PORTA_FER, + (struct gpio_port_t *)PORTB_FER, + (struct gpio_port_t *)PORTC_FER, + (struct gpio_port_t *)PORTD_FER, + (struct gpio_port_t *)PORTE_FER, + (struct gpio_port_t *)PORTF_FER, + (struct gpio_port_t *)PORTG_FER, + (struct gpio_port_t *)PORTH_FER, + (struct gpio_port_t *)PORTI_FER, + (struct gpio_port_t *)PORTJ_FER, +#else +# error no gpio arrays defined +#endif }; -static unsigned short *port_fer[] = { +#if defined(BF527_FAMILY) || defined(BF537_FAMILY) || defined(BF518_FAMILY) +static unsigned short * const port_fer[] = { (unsigned short *) PORTF_FER, (unsigned short *) PORTG_FER, (unsigned short *) PORTH_FER, }; -#endif -#if defined(BF527_FAMILY) || defined(BF518_FAMILY) -static unsigned short *port_mux[] = { +# if !defined(BF537_FAMILY) +static unsigned short * const port_mux[] = { (unsigned short *) PORTF_MUX, (unsigned short *) PORTG_MUX, (unsigned short *) PORTH_MUX, }; static const -u8 pmux_offset[][16] = - {{ 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 4, 6, 8, 8, 10, 10 }, /* PORTF */ - { 0, 0, 0, 0, 0, 2, 2, 4, 4, 6, 8, 10, 10, 10, 12, 12 }, /* PORTG */ - { 0, 0, 0, 0, 0, 0, 0, 0, 2, 4, 4, 4, 4, 4, 4, 4 }, /* PORTH */ - }; -#endif - -#ifdef BF561_FAMILY -static struct gpio_port_t *gpio_bankb[] = { - (struct gpio_port_t *) FIO0_FLAG_D, - (struct gpio_port_t *) FIO1_FLAG_D, - (struct gpio_port_t *) FIO2_FLAG_D, +u8 pmux_offset[][16] = { +# if defined(BF527_FAMILY) + { 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 4, 6, 8, 8, 10, 10 }, /* PORTF */ + { 0, 0, 0, 0, 0, 2, 2, 4, 4, 6, 8, 10, 10, 10, 12, 12 }, /* PORTG */ + { 0, 0, 0, 0, 0, 0, 0, 0, 2, 4, 4, 4, 4, 4, 4, 4 }, /* PORTH */ +# elif defined(BF518_FAMILY) + { 0, 2, 2, 2, 2, 2, 2, 4, 6, 6, 6, 8, 8, 8, 8, 10 }, /* PORTF */ + { 0, 0, 0, 2, 4, 6, 6, 6, 8, 10, 10, 12, 14, 14, 14, 14 }, /* PORTG */ + { 0, 0, 0, 0, 2, 2, 4, 6, 10, 10, 10, 10, 10, 10, 10, 10 }, /* PORTH */ +# endif }; -#endif +# endif -#ifdef BF548_FAMILY -static struct gpio_port_t *gpio_array[] = { - (struct gpio_port_t *)PORTA_FER, - (struct gpio_port_t *)PORTB_FER, - (struct gpio_port_t *)PORTC_FER, - (struct gpio_port_t *)PORTD_FER, - (struct gpio_port_t *)PORTE_FER, - (struct gpio_port_t *)PORTF_FER, - (struct gpio_port_t *)PORTG_FER, - (struct gpio_port_t *)PORTH_FER, - (struct gpio_port_t *)PORTI_FER, - (struct gpio_port_t *)PORTJ_FER, -}; #endif static unsigned short reserved_gpio_map[GPIO_BANK_NUM]; @@ -188,35 +134,9 @@ static struct str_ident { } str_ident[MAX_RESOURCES]; #if defined(CONFIG_PM) -#if defined(CONFIG_BF54x) -static struct gpio_port_s gpio_bank_saved[GPIO_BANK_NUM]; -#else -static unsigned short wakeup_map[GPIO_BANK_NUM]; -static unsigned char wakeup_flags_map[MAX_BLACKFIN_GPIOS]; static struct gpio_port_s gpio_bank_saved[GPIO_BANK_NUM]; - -#ifdef BF533_FAMILY -static unsigned int sic_iwr_irqs[] = {IRQ_PROG_INTB}; -#endif - -#ifdef BF537_FAMILY -static unsigned int sic_iwr_irqs[] = {IRQ_PROG_INTB, IRQ_PORTG_INTB, IRQ_MAC_TX}; -#endif - -#ifdef BF538_FAMILY -static unsigned int sic_iwr_irqs[] = {IRQ_PORTF_INTB}; #endif -#if defined(BF527_FAMILY) || defined(BF518_FAMILY) -static unsigned int sic_iwr_irqs[] = {IRQ_PORTF_INTB, IRQ_PORTG_INTB, IRQ_PORTH_INTB}; -#endif - -#ifdef BF561_FAMILY -static unsigned int sic_iwr_irqs[] = {IRQ_PROG0_INTB, IRQ_PROG1_INTB, IRQ_PROG2_INTB}; -#endif -#endif -#endif /* CONFIG_PM */ - inline int check_gpio(unsigned gpio) { #if defined(BF548_FAMILY) @@ -330,9 +250,10 @@ static struct { {.res = P_SPI0_SSEL3, .offset = 0}, }; -static void portmux_setup(unsigned short per, unsigned short function) +static void portmux_setup(unsigned short per) { u16 y, offset, muxreg; + u16 function = P_FUNCT2MUX(per); for (y = 0; y < ARRAY_SIZE(port_mux_lut); y++) { if (port_mux_lut[y].res == per) { @@ -353,30 +274,33 @@ static void portmux_setup(unsigned short per, unsigned short function) } } #elif defined(BF548_FAMILY) -inline void portmux_setup(unsigned short portno, unsigned short function) +inline void portmux_setup(unsigned short per) { u32 pmux; + u16 ident = P_IDENT(per); + u16 function = P_FUNCT2MUX(per); - pmux = gpio_array[gpio_bank(portno)]->port_mux; + pmux = gpio_array[gpio_bank(ident)]->port_mux; - pmux &= ~(0x3 << (2 * gpio_sub_n(portno))); - pmux |= (function & 0x3) << (2 * gpio_sub_n(portno)); + pmux &= ~(0x3 << (2 * gpio_sub_n(ident))); + pmux |= (function & 0x3) << (2 * gpio_sub_n(ident)); - gpio_array[gpio_bank(portno)]->port_mux = pmux; + gpio_array[gpio_bank(ident)]->port_mux = pmux; } -inline u16 get_portmux(unsigned short portno) +inline u16 get_portmux(unsigned short per) { u32 pmux; + u16 ident = P_IDENT(per); - pmux = gpio_array[gpio_bank(portno)]->port_mux; + pmux = gpio_array[gpio_bank(ident)]->port_mux; - return (pmux >> (2 * gpio_sub_n(portno)) & 0x3); + return (pmux >> (2 * gpio_sub_n(ident)) & 0x3); } #elif defined(BF527_FAMILY) || defined(BF518_FAMILY) -inline void portmux_setup(unsigned short portno, unsigned short function) +inline void portmux_setup(unsigned short per) { - u16 pmux, ident = P_IDENT(portno); + u16 pmux, ident = P_IDENT(per), function = P_FUNCT2MUX(per); u8 offset = pmux_offset[gpio_bank(ident)][gpio_sub_n(ident)]; pmux = *port_mux[gpio_bank(ident)]; @@ -424,90 +348,71 @@ void set_gpio_ ## name(unsigned gpio, unsigned short arg) \ unsigned long flags; \ local_irq_save_hw(flags); \ if (arg) \ - gpio_bankb[gpio_bank(gpio)]->name |= gpio_bit(gpio); \ + gpio_array[gpio_bank(gpio)]->name |= gpio_bit(gpio); \ else \ - gpio_bankb[gpio_bank(gpio)]->name &= ~gpio_bit(gpio); \ + gpio_array[gpio_bank(gpio)]->name &= ~gpio_bit(gpio); \ AWA_DUMMY_READ(name); \ local_irq_restore_hw(flags); \ } \ EXPORT_SYMBOL(set_gpio_ ## name); -SET_GPIO(dir) -SET_GPIO(inen) -SET_GPIO(polar) -SET_GPIO(edge) -SET_GPIO(both) +SET_GPIO(dir) /* set_gpio_dir() */ +SET_GPIO(inen) /* set_gpio_inen() */ +SET_GPIO(polar) /* set_gpio_polar() */ +SET_GPIO(edge) /* set_gpio_edge() */ +SET_GPIO(both) /* set_gpio_both() */ -#if ANOMALY_05000311 || ANOMALY_05000323 #define SET_GPIO_SC(name) \ void set_gpio_ ## name(unsigned gpio, unsigned short arg) \ { \ unsigned long flags; \ - local_irq_save_hw(flags); \ - if (arg) \ - gpio_bankb[gpio_bank(gpio)]->name ## _set = gpio_bit(gpio); \ - else \ - gpio_bankb[gpio_bank(gpio)]->name ## _clear = gpio_bit(gpio); \ - AWA_DUMMY_READ(name); \ - local_irq_restore_hw(flags); \ -} \ -EXPORT_SYMBOL(set_gpio_ ## name); -#else -#define SET_GPIO_SC(name) \ -void set_gpio_ ## name(unsigned gpio, unsigned short arg) \ -{ \ + if (ANOMALY_05000311 || ANOMALY_05000323) \ + local_irq_save_hw(flags); \ if (arg) \ - gpio_bankb[gpio_bank(gpio)]->name ## _set = gpio_bit(gpio); \ + gpio_array[gpio_bank(gpio)]->name ## _set = gpio_bit(gpio); \ else \ - gpio_bankb[gpio_bank(gpio)]->name ## _clear = gpio_bit(gpio); \ + gpio_array[gpio_bank(gpio)]->name ## _clear = gpio_bit(gpio); \ + if (ANOMALY_05000311 || ANOMALY_05000323) { \ + AWA_DUMMY_READ(name); \ + local_irq_restore_hw(flags); \ + } \ } \ EXPORT_SYMBOL(set_gpio_ ## name); -#endif SET_GPIO_SC(maska) SET_GPIO_SC(maskb) SET_GPIO_SC(data) -#if ANOMALY_05000311 || ANOMALY_05000323 void set_gpio_toggle(unsigned gpio) { unsigned long flags; - local_irq_save_hw(flags); - gpio_bankb[gpio_bank(gpio)]->toggle = gpio_bit(gpio); - AWA_DUMMY_READ(toggle); - local_irq_restore_hw(flags); -} -#else -void set_gpio_toggle(unsigned gpio) -{ - gpio_bankb[gpio_bank(gpio)]->toggle = gpio_bit(gpio); + if (ANOMALY_05000311 || ANOMALY_05000323) + local_irq_save_hw(flags); + gpio_array[gpio_bank(gpio)]->toggle = gpio_bit(gpio); + if (ANOMALY_05000311 || ANOMALY_05000323) { + AWA_DUMMY_READ(toggle); + local_irq_restore_hw(flags); + } } -#endif EXPORT_SYMBOL(set_gpio_toggle); /*Set current PORT date (16-bit word)*/ -#if ANOMALY_05000311 || ANOMALY_05000323 #define SET_GPIO_P(name) \ void set_gpiop_ ## name(unsigned gpio, unsigned short arg) \ { \ unsigned long flags; \ - local_irq_save_hw(flags); \ - gpio_bankb[gpio_bank(gpio)]->name = arg; \ - AWA_DUMMY_READ(name); \ - local_irq_restore_hw(flags); \ + if (ANOMALY_05000311 || ANOMALY_05000323) \ + local_irq_save_hw(flags); \ + gpio_array[gpio_bank(gpio)]->name = arg; \ + if (ANOMALY_05000311 || ANOMALY_05000323) { \ + AWA_DUMMY_READ(name); \ + local_irq_restore_hw(flags); \ + } \ } \ EXPORT_SYMBOL(set_gpiop_ ## name); -#else -#define SET_GPIO_P(name) \ -void set_gpiop_ ## name(unsigned gpio, unsigned short arg) \ -{ \ - gpio_bankb[gpio_bank(gpio)]->name = arg; \ -} \ -EXPORT_SYMBOL(set_gpiop_ ## name); -#endif SET_GPIO_P(data) SET_GPIO_P(dir) @@ -519,27 +424,21 @@ SET_GPIO_P(maska) SET_GPIO_P(maskb) /* Get a specific bit */ -#if ANOMALY_05000311 || ANOMALY_05000323 #define GET_GPIO(name) \ unsigned short get_gpio_ ## name(unsigned gpio) \ { \ unsigned long flags; \ unsigned short ret; \ - local_irq_save_hw(flags); \ - ret = 0x01 & (gpio_bankb[gpio_bank(gpio)]->name >> gpio_sub_n(gpio)); \ - AWA_DUMMY_READ(name); \ - local_irq_restore_hw(flags); \ + if (ANOMALY_05000311 || ANOMALY_05000323) \ + local_irq_save_hw(flags); \ + ret = 0x01 & (gpio_array[gpio_bank(gpio)]->name >> gpio_sub_n(gpio)); \ + if (ANOMALY_05000311 || ANOMALY_05000323) { \ + AWA_DUMMY_READ(name); \ + local_irq_restore_hw(flags); \ + } \ return ret; \ } \ EXPORT_SYMBOL(get_gpio_ ## name); -#else -#define GET_GPIO(name) \ -unsigned short get_gpio_ ## name(unsigned gpio) \ -{ \ - return (0x01 & (gpio_bankb[gpio_bank(gpio)]->name >> gpio_sub_n(gpio))); \ -} \ -EXPORT_SYMBOL(get_gpio_ ## name); -#endif GET_GPIO(data) GET_GPIO(dir) @@ -552,27 +451,21 @@ GET_GPIO(maskb) /*Get current PORT date (16-bit word)*/ -#if ANOMALY_05000311 || ANOMALY_05000323 #define GET_GPIO_P(name) \ unsigned short get_gpiop_ ## name(unsigned gpio) \ { \ unsigned long flags; \ unsigned short ret; \ - local_irq_save_hw(flags); \ - ret = (gpio_bankb[gpio_bank(gpio)]->name); \ - AWA_DUMMY_READ(name); \ - local_irq_restore_hw(flags); \ + if (ANOMALY_05000311 || ANOMALY_05000323) \ + local_irq_save_hw(flags); \ + ret = (gpio_array[gpio_bank(gpio)]->name); \ + if (ANOMALY_05000311 || ANOMALY_05000323) { \ + AWA_DUMMY_READ(name); \ + local_irq_restore_hw(flags); \ + } \ return ret; \ } \ EXPORT_SYMBOL(get_gpiop_ ## name); -#else -#define GET_GPIO_P(name) \ -unsigned short get_gpiop_ ## name(unsigned gpio) \ -{ \ - return (gpio_bankb[gpio_bank(gpio)]->name);\ -} \ -EXPORT_SYMBOL(get_gpiop_ ## name); -#endif GET_GPIO_P(data) GET_GPIO_P(dir) @@ -585,6 +478,26 @@ GET_GPIO_P(maskb) #ifdef CONFIG_PM + +static unsigned short wakeup_map[GPIO_BANK_NUM]; +static unsigned char wakeup_flags_map[MAX_BLACKFIN_GPIOS]; + +static const unsigned int sic_iwr_irqs[] = { +#if defined(BF533_FAMILY) + IRQ_PROG_INTB +#elif defined(BF537_FAMILY) + IRQ_PROG_INTB, IRQ_PORTG_INTB, IRQ_MAC_TX +#elif defined(BF538_FAMILY) + IRQ_PORTF_INTB +#elif defined(BF527_FAMILY) || defined(BF518_FAMILY) + IRQ_PORTF_INTB, IRQ_PORTG_INTB, IRQ_PORTH_INTB +#elif defined(BF561_FAMILY) + IRQ_PROG0_INTB, IRQ_PROG1_INTB, IRQ_PROG2_INTB +#else +# error no SIC_IWR defined +#endif +}; + /*********************************************************** * * FUNCTIONS: Blackfin PM Setup API @@ -669,18 +582,18 @@ u32 bfin_pm_standby_setup(void) mask = wakeup_map[gpio_bank(i)]; bank = gpio_bank(i); - gpio_bank_saved[bank].maskb = gpio_bankb[bank]->maskb; - gpio_bankb[bank]->maskb = 0; + gpio_bank_saved[bank].maskb = gpio_array[bank]->maskb; + gpio_array[bank]->maskb = 0; if (mask) { #if defined(BF527_FAMILY) || defined(BF537_FAMILY) || defined(BF518_FAMILY) gpio_bank_saved[bank].fer = *port_fer[bank]; #endif - gpio_bank_saved[bank].inen = gpio_bankb[bank]->inen; - gpio_bank_saved[bank].polar = gpio_bankb[bank]->polar; - gpio_bank_saved[bank].dir = gpio_bankb[bank]->dir; - gpio_bank_saved[bank].edge = gpio_bankb[bank]->edge; - gpio_bank_saved[bank].both = gpio_bankb[bank]->both; + gpio_bank_saved[bank].inen = gpio_array[bank]->inen; + gpio_bank_saved[bank].polar = gpio_array[bank]->polar; + gpio_bank_saved[bank].dir = gpio_array[bank]->dir; + gpio_bank_saved[bank].edge = gpio_array[bank]->edge; + gpio_bank_saved[bank].both = gpio_array[bank]->both; gpio_bank_saved[bank].reserved = reserved_gpio_map[bank]; @@ -700,7 +613,7 @@ u32 bfin_pm_standby_setup(void) } bfin_internal_set_wake(sic_iwr_irqs[bank], 1); - gpio_bankb[bank]->maskb_set = wakeup_map[gpio_bank(i)]; + gpio_array[bank]->maskb_set = wakeup_map[gpio_bank(i)]; } } @@ -721,18 +634,18 @@ void bfin_pm_standby_restore(void) #if defined(BF527_FAMILY) || defined(BF537_FAMILY) || defined(BF518_FAMILY) *port_fer[bank] = gpio_bank_saved[bank].fer; #endif - gpio_bankb[bank]->inen = gpio_bank_saved[bank].inen; - gpio_bankb[bank]->dir = gpio_bank_saved[bank].dir; - gpio_bankb[bank]->polar = gpio_bank_saved[bank].polar; - gpio_bankb[bank]->edge = gpio_bank_saved[bank].edge; - gpio_bankb[bank]->both = gpio_bank_saved[bank].both; + gpio_array[bank]->inen = gpio_bank_saved[bank].inen; + gpio_array[bank]->dir = gpio_bank_saved[bank].dir; + gpio_array[bank]->polar = gpio_bank_saved[bank].polar; + gpio_array[bank]->edge = gpio_bank_saved[bank].edge; + gpio_array[bank]->both = gpio_bank_saved[bank].both; reserved_gpio_map[bank] = gpio_bank_saved[bank].reserved; bfin_internal_set_wake(sic_iwr_irqs[bank], 0); } - gpio_bankb[bank]->maskb = gpio_bank_saved[bank].maskb; + gpio_array[bank]->maskb = gpio_bank_saved[bank].maskb; } AWA_DUMMY_READ(maskb); } @@ -745,21 +658,21 @@ void bfin_gpio_pm_hibernate_suspend(void) bank = gpio_bank(i); #if defined(BF527_FAMILY) || defined(BF537_FAMILY) || defined(BF518_FAMILY) - gpio_bank_saved[bank].fer = *port_fer[bank]; + gpio_bank_saved[bank].fer = *port_fer[bank]; #if defined(BF527_FAMILY) || defined(BF518_FAMILY) - gpio_bank_saved[bank].mux = *port_mux[bank]; + gpio_bank_saved[bank].mux = *port_mux[bank]; #else - if (bank == 0) - gpio_bank_saved[bank].mux = bfin_read_PORT_MUX(); + if (bank == 0) + gpio_bank_saved[bank].mux = bfin_read_PORT_MUX(); #endif #endif - gpio_bank_saved[bank].data = gpio_bankb[bank]->data; - gpio_bank_saved[bank].inen = gpio_bankb[bank]->inen; - gpio_bank_saved[bank].polar = gpio_bankb[bank]->polar; - gpio_bank_saved[bank].dir = gpio_bankb[bank]->dir; - gpio_bank_saved[bank].edge = gpio_bankb[bank]->edge; - gpio_bank_saved[bank].both = gpio_bankb[bank]->both; - gpio_bank_saved[bank].maska = gpio_bankb[bank]->maska; + gpio_bank_saved[bank].data = gpio_array[bank]->data; + gpio_bank_saved[bank].inen = gpio_array[bank]->inen; + gpio_bank_saved[bank].polar = gpio_array[bank]->polar; + gpio_bank_saved[bank].dir = gpio_array[bank]->dir; + gpio_bank_saved[bank].edge = gpio_array[bank]->edge; + gpio_bank_saved[bank].both = gpio_array[bank]->both; + gpio_bank_saved[bank].maska = gpio_array[bank]->maska; } AWA_DUMMY_READ(maska); @@ -770,27 +683,27 @@ void bfin_gpio_pm_hibernate_restore(void) int i, bank; for (i = 0; i < MAX_BLACKFIN_GPIOS; i += GPIO_BANKSIZE) { - bank = gpio_bank(i); + bank = gpio_bank(i); #if defined(BF527_FAMILY) || defined(BF537_FAMILY) || defined(BF518_FAMILY) #if defined(BF527_FAMILY) || defined(BF518_FAMILY) - *port_mux[bank] = gpio_bank_saved[bank].mux; + *port_mux[bank] = gpio_bank_saved[bank].mux; #else - if (bank == 0) - bfin_write_PORT_MUX(gpio_bank_saved[bank].mux); + if (bank == 0) + bfin_write_PORT_MUX(gpio_bank_saved[bank].mux); #endif - *port_fer[bank] = gpio_bank_saved[bank].fer; + *port_fer[bank] = gpio_bank_saved[bank].fer; #endif - gpio_bankb[bank]->inen = gpio_bank_saved[bank].inen; - gpio_bankb[bank]->dir = gpio_bank_saved[bank].dir; - gpio_bankb[bank]->polar = gpio_bank_saved[bank].polar; - gpio_bankb[bank]->edge = gpio_bank_saved[bank].edge; - gpio_bankb[bank]->both = gpio_bank_saved[bank].both; + gpio_array[bank]->inen = gpio_bank_saved[bank].inen; + gpio_array[bank]->dir = gpio_bank_saved[bank].dir; + gpio_array[bank]->polar = gpio_bank_saved[bank].polar; + gpio_array[bank]->edge = gpio_bank_saved[bank].edge; + gpio_array[bank]->both = gpio_bank_saved[bank].both; - gpio_bankb[bank]->data_set = gpio_bank_saved[bank].data - | gpio_bank_saved[bank].dir; + gpio_array[bank]->data_set = gpio_bank_saved[bank].data + | gpio_bank_saved[bank].dir; - gpio_bankb[bank]->maska = gpio_bank_saved[bank].maska; + gpio_array[bank]->maska = gpio_bank_saved[bank].maska; } AWA_DUMMY_READ(maska); } @@ -817,12 +730,12 @@ void bfin_gpio_pm_hibernate_suspend(void) for (i = 0; i < MAX_BLACKFIN_GPIOS; i += GPIO_BANKSIZE) { bank = gpio_bank(i); - gpio_bank_saved[bank].fer = gpio_array[bank]->port_fer; - gpio_bank_saved[bank].mux = gpio_array[bank]->port_mux; - gpio_bank_saved[bank].data = gpio_array[bank]->port_data; - gpio_bank_saved[bank].data = gpio_array[bank]->port_data; - gpio_bank_saved[bank].inen = gpio_array[bank]->port_inen; - gpio_bank_saved[bank].dir = gpio_array[bank]->port_dir_set; + gpio_bank_saved[bank].fer = gpio_array[bank]->port_fer; + gpio_bank_saved[bank].mux = gpio_array[bank]->port_mux; + gpio_bank_saved[bank].data = gpio_array[bank]->data; + gpio_bank_saved[bank].data = gpio_array[bank]->data; + gpio_bank_saved[bank].inen = gpio_array[bank]->inen; + gpio_bank_saved[bank].dir = gpio_array[bank]->dir_set; } } @@ -831,21 +744,21 @@ void bfin_gpio_pm_hibernate_restore(void) int i, bank; for (i = 0; i < MAX_BLACKFIN_GPIOS; i += GPIO_BANKSIZE) { - bank = gpio_bank(i); - - gpio_array[bank]->port_mux = gpio_bank_saved[bank].mux; - gpio_array[bank]->port_fer = gpio_bank_saved[bank].fer; - gpio_array[bank]->port_inen = gpio_bank_saved[bank].inen; - gpio_array[bank]->port_dir_set = gpio_bank_saved[bank].dir; - gpio_array[bank]->port_set = gpio_bank_saved[bank].data - | gpio_bank_saved[bank].dir; + bank = gpio_bank(i); + + gpio_array[bank]->port_mux = gpio_bank_saved[bank].mux; + gpio_array[bank]->port_fer = gpio_bank_saved[bank].fer; + gpio_array[bank]->inen = gpio_bank_saved[bank].inen; + gpio_array[bank]->dir_set = gpio_bank_saved[bank].dir; + gpio_array[bank]->data_set = gpio_bank_saved[bank].data + | gpio_bank_saved[bank].dir; } } #endif unsigned short get_gpio_dir(unsigned gpio) { - return (0x01 & (gpio_array[gpio_bank(gpio)]->port_dir_clear >> gpio_sub_n(gpio))); + return (0x01 & (gpio_array[gpio_bank(gpio)]->dir_clear >> gpio_sub_n(gpio))); } EXPORT_SYMBOL(get_gpio_dir); @@ -905,9 +818,7 @@ int peripheral_request(unsigned short per, const char *label) */ #ifdef BF548_FAMILY - u16 funct = get_portmux(ident); - - if (!((per & P_MAYSHARE) && (funct == P_FUNCT2MUX(per)))) { + if (!((per & P_MAYSHARE) && get_portmux(per) == P_FUNCT2MUX(per))) { #else if (!(per & P_MAYSHARE)) { #endif @@ -931,11 +842,7 @@ int peripheral_request(unsigned short per, const char *label) anyway: reserved_peri_map[gpio_bank(ident)] |= gpio_bit(ident); -#ifdef BF548_FAMILY - portmux_setup(ident, P_FUNCT2MUX(per)); -#else - portmux_setup(per, P_FUNCT2MUX(per)); -#endif + portmux_setup(per); port_setup(ident, PERIPHERAL_USAGE); local_irq_restore_hw(flags); @@ -977,9 +884,6 @@ void peripheral_free(unsigned short per) if (!(per & P_DEFINED)) return; - if (check_gpio(ident) < 0) - return; - local_irq_save_hw(flags); if (unlikely(!(reserved_peri_map[gpio_bank(ident)] & gpio_bit(ident)))) { @@ -1056,9 +960,15 @@ int bfin_gpio_request(unsigned gpio, const char *label) local_irq_restore_hw(flags); return -EBUSY; } - if (unlikely(reserved_gpio_irq_map[gpio_bank(gpio)] & gpio_bit(gpio))) + if (unlikely(reserved_gpio_irq_map[gpio_bank(gpio)] & gpio_bit(gpio))) { printk(KERN_NOTICE "bfin-gpio: GPIO %d is already reserved as gpio-irq!" " (Documentation/blackfin/bfin-gpio-notes.txt)\n", gpio); + } +#ifndef BF548_FAMILY + else { /* Reset POLAR setting when acquiring a gpio for the first time */ + set_gpio_polar(gpio, 0); + } +#endif reserved_gpio_map[gpio_bank(gpio)] |= gpio_bit(gpio); set_label(gpio, label); @@ -1078,6 +988,8 @@ void bfin_gpio_free(unsigned gpio) if (check_gpio(gpio) < 0) return; + might_sleep(); + local_irq_save_hw(flags); if (unlikely(!(reserved_gpio_map[gpio_bank(gpio)] & gpio_bit(gpio)))) { @@ -1158,8 +1070,16 @@ void bfin_gpio_irq_free(unsigned gpio) local_irq_restore_hw(flags); } - +static inline void __bfin_gpio_direction_input(unsigned gpio) +{ #ifdef BF548_FAMILY + gpio_array[gpio_bank(gpio)]->dir_clear = gpio_bit(gpio); +#else + gpio_array[gpio_bank(gpio)]->dir &= ~gpio_bit(gpio); +#endif + gpio_array[gpio_bank(gpio)]->inen |= gpio_bit(gpio); +} + int bfin_gpio_direction_input(unsigned gpio) { unsigned long flags; @@ -1170,125 +1090,85 @@ int bfin_gpio_direction_input(unsigned gpio) } local_irq_save_hw(flags); - gpio_array[gpio_bank(gpio)]->port_dir_clear = gpio_bit(gpio); - gpio_array[gpio_bank(gpio)]->port_inen |= gpio_bit(gpio); + __bfin_gpio_direction_input(gpio); + AWA_DUMMY_READ(inen); local_irq_restore_hw(flags); return 0; } EXPORT_SYMBOL(bfin_gpio_direction_input); -int bfin_gpio_direction_output(unsigned gpio, int value) +void bfin_gpio_irq_prepare(unsigned gpio) { +#ifdef BF548_FAMILY unsigned long flags; +#endif - if (!(reserved_gpio_map[gpio_bank(gpio)] & gpio_bit(gpio))) { - gpio_error(gpio); - return -EINVAL; - } + port_setup(gpio, GPIO_USAGE); +#ifdef BF548_FAMILY local_irq_save_hw(flags); - gpio_array[gpio_bank(gpio)]->port_inen &= ~gpio_bit(gpio); - gpio_set_value(gpio, value); - gpio_array[gpio_bank(gpio)]->port_dir_set = gpio_bit(gpio); + __bfin_gpio_direction_input(gpio); local_irq_restore_hw(flags); - - return 0; +#endif } -EXPORT_SYMBOL(bfin_gpio_direction_output); void bfin_gpio_set_value(unsigned gpio, int arg) { if (arg) - gpio_array[gpio_bank(gpio)]->port_set = gpio_bit(gpio); + gpio_array[gpio_bank(gpio)]->data_set = gpio_bit(gpio); else - gpio_array[gpio_bank(gpio)]->port_clear = gpio_bit(gpio); + gpio_array[gpio_bank(gpio)]->data_clear = gpio_bit(gpio); } EXPORT_SYMBOL(bfin_gpio_set_value); -int bfin_gpio_get_value(unsigned gpio) -{ - return (1 & (gpio_array[gpio_bank(gpio)]->port_data >> gpio_sub_n(gpio))); -} -EXPORT_SYMBOL(bfin_gpio_get_value); - -void bfin_gpio_irq_prepare(unsigned gpio) +int bfin_gpio_direction_output(unsigned gpio, int value) { unsigned long flags; - port_setup(gpio, GPIO_USAGE); + if (!(reserved_gpio_map[gpio_bank(gpio)] & gpio_bit(gpio))) { + gpio_error(gpio); + return -EINVAL; + } local_irq_save_hw(flags); - gpio_array[gpio_bank(gpio)]->port_dir_clear = gpio_bit(gpio); - gpio_array[gpio_bank(gpio)]->port_inen |= gpio_bit(gpio); - local_irq_restore_hw(flags); -} + gpio_array[gpio_bank(gpio)]->inen &= ~gpio_bit(gpio); + gpio_set_value(gpio, value); +#ifdef BF548_FAMILY + gpio_array[gpio_bank(gpio)]->dir_set = gpio_bit(gpio); #else + gpio_array[gpio_bank(gpio)]->dir |= gpio_bit(gpio); +#endif + + AWA_DUMMY_READ(dir); + local_irq_restore_hw(flags); + + return 0; +} +EXPORT_SYMBOL(bfin_gpio_direction_output); int bfin_gpio_get_value(unsigned gpio) { +#ifdef BF548_FAMILY + return (1 & (gpio_array[gpio_bank(gpio)]->data >> gpio_sub_n(gpio))); +#else unsigned long flags; - int ret; if (unlikely(get_gpio_edge(gpio))) { + int ret; local_irq_save_hw(flags); set_gpio_edge(gpio, 0); ret = get_gpio_data(gpio); set_gpio_edge(gpio, 1); local_irq_restore_hw(flags); - return ret; } else return get_gpio_data(gpio); +#endif } EXPORT_SYMBOL(bfin_gpio_get_value); - -int bfin_gpio_direction_input(unsigned gpio) -{ - unsigned long flags; - - if (!(reserved_gpio_map[gpio_bank(gpio)] & gpio_bit(gpio))) { - gpio_error(gpio); - return -EINVAL; - } - - local_irq_save_hw(flags); - gpio_bankb[gpio_bank(gpio)]->dir &= ~gpio_bit(gpio); - gpio_bankb[gpio_bank(gpio)]->inen |= gpio_bit(gpio); - AWA_DUMMY_READ(inen); - local_irq_restore_hw(flags); - - return 0; -} -EXPORT_SYMBOL(bfin_gpio_direction_input); - -int bfin_gpio_direction_output(unsigned gpio, int value) -{ - unsigned long flags; - - if (!(reserved_gpio_map[gpio_bank(gpio)] & gpio_bit(gpio))) { - gpio_error(gpio); - return -EINVAL; - } - - local_irq_save_hw(flags); - gpio_bankb[gpio_bank(gpio)]->inen &= ~gpio_bit(gpio); - - if (value) - gpio_bankb[gpio_bank(gpio)]->data_set = gpio_bit(gpio); - else - gpio_bankb[gpio_bank(gpio)]->data_clear = gpio_bit(gpio); - - gpio_bankb[gpio_bank(gpio)]->dir |= gpio_bit(gpio); - AWA_DUMMY_READ(dir); - local_irq_restore_hw(flags); - - return 0; -} -EXPORT_SYMBOL(bfin_gpio_direction_output); - /* If we are booting from SPI and our board lacks a strong enough pull up, * the core can reset and execute the bootrom faster than the resistor can * pull the signal logically high. To work around this (common) error in @@ -1299,23 +1179,15 @@ EXPORT_SYMBOL(bfin_gpio_direction_output); * lives here as we need to force all the GPIO states w/out going through * BUG() checks and such. */ -void bfin_gpio_reset_spi0_ssel1(void) +void bfin_reset_boot_spi_cs(unsigned short pin) { - u16 gpio = P_IDENT(P_SPI0_SSEL1); - + unsigned short gpio = P_IDENT(pin); port_setup(gpio, GPIO_USAGE); - gpio_bankb[gpio_bank(gpio)]->data_set = gpio_bit(gpio); + gpio_array[gpio_bank(gpio)]->data_set = gpio_bit(gpio); AWA_DUMMY_READ(data_set); udelay(1); } -void bfin_gpio_irq_prepare(unsigned gpio) -{ - port_setup(gpio, GPIO_USAGE); -} - -#endif /*BF548_FAMILY */ - #if defined(CONFIG_PROC_FS) static int gpio_proc_read(char *buf, char **start, off_t offset, int len, int *unused_i, void *unused_v) @@ -1369,11 +1241,7 @@ int bfin_gpiolib_get_value(struct gpio_chip *chip, unsigned gpio) void bfin_gpiolib_set_value(struct gpio_chip *chip, unsigned gpio, int value) { -#ifdef BF548_FAMILY return bfin_gpio_set_value(gpio, value); -#else - return set_gpio_data(gpio, value); -#endif } int bfin_gpiolib_gpio_request(struct gpio_chip *chip, unsigned gpio) diff --git a/arch/blackfin/kernel/cplb-mpu/cplbinit.c b/arch/blackfin/kernel/cplb-mpu/cplbinit.c index bdb958486e7..3e329a6ce04 100644 --- a/arch/blackfin/kernel/cplb-mpu/cplbinit.c +++ b/arch/blackfin/kernel/cplb-mpu/cplbinit.c @@ -63,10 +63,8 @@ void __init generate_cplb_tables_cpu(unsigned int cpu) dcplb_tbl[cpu][i_d].addr = 0; dcplb_tbl[cpu][i_d++].data = SDRAM_OOPS | PAGE_SIZE_1KB; -#if 0 icplb_tbl[cpu][i_i].addr = 0; - icplb_tbl[cpu][i_i++].data = i_cache | CPLB_USER_RD | PAGE_SIZE_4KB; -#endif + icplb_tbl[cpu][i_i++].data = i_cache | CPLB_USER_RD | PAGE_SIZE_1KB; /* Cover kernel memory with 4M pages. */ addr = 0; diff --git a/arch/blackfin/kernel/cplb-nompu/cplbmgr.c b/arch/blackfin/kernel/cplb-nompu/cplbmgr.c index 376249ab269..8cbb47c7b66 100644 --- a/arch/blackfin/kernel/cplb-nompu/cplbmgr.c +++ b/arch/blackfin/kernel/cplb-nompu/cplbmgr.c @@ -163,12 +163,14 @@ MGR_ATTR static int icplb_miss(int cpu) nr_icplb_supv_miss[cpu]++; base = 0; - for (idx = 0; idx < icplb_nr_bounds; idx++) { + idx = 0; + do { eaddr = icplb_bounds[idx].eaddr; if (addr < eaddr) break; base = eaddr; - } + } while (++idx < icplb_nr_bounds); + if (unlikely(idx == icplb_nr_bounds)) return CPLB_NO_ADDR_MATCH; @@ -208,12 +210,14 @@ MGR_ATTR static int dcplb_miss(int cpu) nr_dcplb_supv_miss[cpu]++; base = 0; - for (idx = 0; idx < dcplb_nr_bounds; idx++) { + idx = 0; + do { eaddr = dcplb_bounds[idx].eaddr; if (addr < eaddr) break; base = eaddr; - } + } while (++idx < dcplb_nr_bounds); + if (unlikely(idx == dcplb_nr_bounds)) return CPLB_NO_ADDR_MATCH; diff --git a/arch/blackfin/kernel/irqchip.c b/arch/blackfin/kernel/irqchip.c index 5780d6df154..23e9aa08071 100644 --- a/arch/blackfin/kernel/irqchip.c +++ b/arch/blackfin/kernel/irqchip.c @@ -35,6 +35,7 @@ #include <linux/interrupt.h> #include <linux/irq.h> #include <asm/trace.h> +#include <asm/pda.h> static atomic_t irq_err_count; static spinlock_t irq_controller_lock; @@ -96,8 +97,13 @@ int show_interrupts(struct seq_file *p, void *v) seq_putc(p, '\n'); skip: spin_unlock_irqrestore(&irq_desc[i].lock, flags); - } else if (i == NR_IRQS) + } else if (i == NR_IRQS) { + seq_printf(p, "NMI: "); + for_each_online_cpu(j) + seq_printf(p, "%10u ", cpu_pda[j].__nmi_count); + seq_printf(p, " CORE Non Maskable Interrupt\n"); seq_printf(p, "Err: %10u\n", atomic_read(&irq_err_count)); + } return 0; } diff --git a/arch/blackfin/kernel/reboot.c b/arch/blackfin/kernel/reboot.c index eeee8cb4336..53d08dee853 100644 --- a/arch/blackfin/kernel/reboot.c +++ b/arch/blackfin/kernel/reboot.c @@ -20,8 +20,8 @@ * reset while the Core B bit (on dual core parts) is cleared by * the core reset. */ -__attribute__((l1_text)) -static void _bfin_reset(void) +__attribute__ ((__l1_text__, __noreturn__)) +static void bfin_reset(void) { /* Wait for completion of "system" events such as cache line * line fills so that we avoid infinite stalls later on as @@ -30,7 +30,11 @@ static void _bfin_reset(void) */ __builtin_bfin_ssync(); - while (1) { + /* The bootrom checks to see how it was reset and will + * automatically perform a software reset for us when + * it starts executing after the core reset. + */ + if (ANOMALY_05000353 || ANOMALY_05000386) { /* Initiate System software reset. */ bfin_write_SWRST(0x7); @@ -50,6 +54,11 @@ static void _bfin_reset(void) /* Clear System software reset */ bfin_write_SWRST(0); + /* The BF526 ROM will crash during reset */ +#if defined(__ADSPBF522__) || defined(__ADSPBF524__) || defined(__ADSPBF526__) + bfin_read_SWRST(); +#endif + /* Wait for the SWRST write to complete. Cannot rely on SSYNC * though as the System state is all reset now. */ @@ -60,22 +69,11 @@ static void _bfin_reset(void) : "a" (15 * 1) : "LC1", "LB1", "LT1" ); + } + while (1) /* Issue core reset */ asm("raise 1"); - } -} - -static void bfin_reset(void) -{ - if (ANOMALY_05000353 || ANOMALY_05000386) - _bfin_reset(); - else - /* the bootrom checks to see how it was reset and will - * automatically perform a software reset for us when - * it starts executing boot - */ - asm("raise 1;"); } __attribute__((weak)) diff --git a/arch/blackfin/kernel/setup.c b/arch/blackfin/kernel/setup.c index b2a811347b6..e5c11623080 100644 --- a/arch/blackfin/kernel/setup.c +++ b/arch/blackfin/kernel/setup.c @@ -60,7 +60,7 @@ void __initdata *init_retx, *init_saved_retx, *init_saved_seqstat, #define BFIN_MEMMAP_MAX 128 /* number of entries in bfin_memmap */ #define BFIN_MEMMAP_RAM 1 #define BFIN_MEMMAP_RESERVED 2 -struct bfin_memmap { +static struct bfin_memmap { int nr_map; struct bfin_memmap_entry { unsigned long long addr; /* start of memory segment */ @@ -824,7 +824,15 @@ void __init setup_arch(char **cmdline_p) flash_probe(); #endif + printk(KERN_INFO "Boot Mode: %i\n", bfin_read_SYSCR() & 0xF); + + /* Newer parts mirror SWRST bits in SYSCR */ +#if defined(CONFIG_BF53x) || defined(CONFIG_BF561) || \ + defined(CONFIG_BF538) || defined(CONFIG_BF539) _bfin_swrst = bfin_read_SWRST(); +#else + _bfin_swrst = bfin_read_SYSCR(); +#endif #ifdef CONFIG_DEBUG_DOUBLEFAULT_PRINT bfin_write_SWRST(_bfin_swrst & ~DOUBLE_FAULT); @@ -853,7 +861,7 @@ void __init setup_arch(char **cmdline_p) else if (_bfin_swrst & RESET_SOFTWARE) printk(KERN_NOTICE "Reset caused by Software reset\n"); - printk(KERN_INFO "Blackfin support (C) 2004-2008 Analog Devices, Inc.\n"); + printk(KERN_INFO "Blackfin support (C) 2004-2009 Analog Devices, Inc.\n"); if (bfin_compiled_revid() == 0xffff) printk(KERN_INFO "Compiled for ADSP-%s Rev any\n", CPU); else if (bfin_compiled_revid() == -1) diff --git a/arch/blackfin/kernel/traps.c b/arch/blackfin/kernel/traps.c index 5b0667da8d0..ffe7fb53ecc 100644 --- a/arch/blackfin/kernel/traps.c +++ b/arch/blackfin/kernel/traps.c @@ -673,6 +673,14 @@ static void decode_instruction(unsigned short *address) verbose_printk("RTI"); else if (opcode == 0x0012) verbose_printk("RTX"); + else if (opcode == 0x0013) + verbose_printk("RTN"); + else if (opcode == 0x0014) + verbose_printk("RTE"); + else if (opcode == 0x0025) + verbose_printk("EMUEXCPT"); + else if (opcode == 0x0040 && opcode <= 0x0047) + verbose_printk("STI R%i", opcode & 7); else if (opcode >= 0x0050 && opcode <= 0x0057) verbose_printk("JUMP (P%i)", opcode & 7); else if (opcode >= 0x0060 && opcode <= 0x0067) @@ -681,6 +689,10 @@ static void decode_instruction(unsigned short *address) verbose_printk("CALL (PC+P%i)", opcode & 7); else if (opcode >= 0x0080 && opcode <= 0x0087) verbose_printk("JUMP (PC+P%i)", opcode & 7); + else if (opcode >= 0x0090 && opcode <= 0x009F) + verbose_printk("RAISE 0x%x", opcode & 0xF); + else if (opcode >= 0x00A0 && opcode <= 0x00AF) + verbose_printk("EXCPT 0x%x", opcode & 0xF); else if ((opcode >= 0x1000 && opcode <= 0x13FF) || (opcode >= 0x1800 && opcode <= 0x1BFF)) verbose_printk("IF !CC JUMP"); else if ((opcode >= 0x1400 && opcode <= 0x17ff) || (opcode >= 0x1c00 && opcode <= 0x1fff)) @@ -820,11 +832,8 @@ void show_stack(struct task_struct *task, unsigned long *stack) decode_address(buf, (unsigned int)stack); printk(KERN_NOTICE " SP: [0x%p] %s\n", stack, buf); - addr = (unsigned int *)((unsigned int)stack & ~0x3F); - /* First thing is to look for a frame pointer */ - for (addr = (unsigned int *)((unsigned int)stack & ~0xF), i = 0; - addr < endstack; addr++, i++) { + for (addr = (unsigned int *)((unsigned int)stack & ~0xF); addr < endstack; addr++) { if (*addr & 0x1) continue; ins_addr = (unsigned short *)*addr; @@ -834,7 +843,8 @@ void show_stack(struct task_struct *task, unsigned long *stack) if (fp) { /* Let's check to see if it is a frame pointer */ - while (fp >= (addr - 1) && fp < endstack && fp) + while (fp >= (addr - 1) && fp < endstack + && fp && ((unsigned int) fp & 0x3) == 0) fp = (unsigned int *)*fp; if (fp == 0 || fp == endstack) { fp = addr - 1; @@ -1052,8 +1062,9 @@ void show_regs(struct pt_regs *fp) char buf [150]; struct irqaction *action; unsigned int i; - unsigned long flags; + unsigned long flags = 0; unsigned int cpu = smp_processor_id(); + unsigned char in_atomic = (bfin_read_IPEND() & 0x10) || in_atomic(); verbose_printk(KERN_NOTICE "\n" KERN_NOTICE "SEQUENCER STATUS:\t\t%s\n", print_tainted()); verbose_printk(KERN_NOTICE " SEQSTAT: %08lx IPEND: %04lx SYSCFG: %04lx\n", @@ -1073,17 +1084,22 @@ void show_regs(struct pt_regs *fp) } verbose_printk(KERN_NOTICE " EXCAUSE : 0x%lx\n", fp->seqstat & SEQSTAT_EXCAUSE); - for (i = 6; i <= 15 ; i++) { + for (i = 2; i <= 15 ; i++) { if (fp->ipend & (1 << i)) { - decode_address(buf, bfin_read32(EVT0 + 4*i)); - verbose_printk(KERN_NOTICE " physical IVG%i asserted : %s\n", i, buf); + if (i != 4) { + decode_address(buf, bfin_read32(EVT0 + 4*i)); + verbose_printk(KERN_NOTICE " physical IVG%i asserted : %s\n", i, buf); + } else + verbose_printk(KERN_NOTICE " interrupts disabled\n"); } } /* if no interrupts are going off, don't print this out */ if (fp->ipend & ~0x3F) { for (i = 0; i < (NR_IRQS - 1); i++) { - spin_lock_irqsave(&irq_desc[i].lock, flags); + if (!in_atomic) + spin_lock_irqsave(&irq_desc[i].lock, flags); + action = irq_desc[i].action; if (!action) goto unlock; @@ -1096,7 +1112,8 @@ void show_regs(struct pt_regs *fp) } verbose_printk("\n"); unlock: - spin_unlock_irqrestore(&irq_desc[i].lock, flags); + if (!in_atomic) + spin_unlock_irqrestore(&irq_desc[i].lock, flags); } } |