diff --git a/arch/arm/boards/at91sam9260ek/init.c b/arch/arm/boards/at91sam9260ek/init.c index 4bff35e..03abc0e 100644 --- a/arch/arm/boards/at91sam9260ek/init.c +++ b/arch/arm/boards/at91sam9260ek/init.c @@ -172,6 +172,7 @@ #if defined(CONFIG_MCI_ATMEL) static struct atmel_mci_platform_data __initdata ek_mci_data = { .bus_width = 4, + .slot_b = 1, }; static void ek_usb_add_device_mci(void) @@ -179,7 +180,7 @@ if (machine_is_at91sam9g20ek()) ek_mci_data.detect_pin = AT91_PIN_PC9; - at91_add_device_mci(1, &ek_mci_data); + at91_add_device_mci(0, &ek_mci_data); } #else static void ek_usb_add_device_mci(void) {} diff --git a/arch/arm/boards/dss11/init.c b/arch/arm/boards/dss11/init.c index 96c4eef..722c0f6 100644 --- a/arch/arm/boards/dss11/init.c +++ b/arch/arm/boards/dss11/init.c @@ -110,6 +110,7 @@ } static struct atmel_mci_platform_data dss11_mci_data = { + .slot_b = 1, .bus_width = 4, .host_caps = MMC_MODE_HS, }; @@ -131,7 +132,7 @@ dss11_add_device_nand(); dss11_phy_reset(); at91_add_device_eth(&macb_pdata); - at91_add_device_mci(1, &dss11_mci_data); + at91_add_device_mci(0, &dss11_mci_data); at91_add_device_usbh_ohci(&dss11_usbh_data); armlinux_set_bootparams((void *)(AT91_CHIPSELECT_1 + 0x100)); diff --git a/arch/arm/cpu/interrupts.c b/arch/arm/cpu/interrupts.c index 3d2077f..c4f9113 100644 --- a/arch/arm/cpu/interrupts.c +++ b/arch/arm/cpu/interrupts.c @@ -73,6 +73,11 @@ #endif } +void dump_stack(void) +{ + unwind_backtrace(NULL); +} + static void __noreturn do_exception(struct pt_regs *pt_regs) { show_regs(pt_regs); diff --git a/arch/arm/include/asm/barebox.h b/arch/arm/include/asm/barebox.h index c9372da..2b08d68 100644 --- a/arch/arm/include/asm/barebox.h +++ b/arch/arm/include/asm/barebox.h @@ -1,41 +1,8 @@ -/* - * (C) Copyright 2002 - * Sysgo Real-Time Solutions, GmbH - * Marius Groeger - * - * (C) Copyright 2002 - * Sysgo Real-Time Solutions, GmbH - * Alex Zuepke - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - * - ******************************************************************** - * NOTE: This header file defines an interface to barebox. Including - * this (unmodified) header file in another file is considered normal - * use of barebox, and does *not* fall under the heading of "derived - * work". - ******************************************************************** - */ - #ifndef _BAREBOX_H_ #define _BAREBOX_H_ 1 -//typedef struct bd_info {} bd_t; +#ifdef CONFIG_ARM_UNWIND +#define ARCH_HAS_STACK_DUMP +#endif #endif /* _BAREBOX_H_ */ diff --git a/arch/arm/lib/div0.c b/arch/arm/lib/div0.c index 99d6b85..6313c672 100644 --- a/arch/arm/lib/div0.c +++ b/arch/arm/lib/div0.c @@ -27,5 +27,5 @@ /* Replacement (=dummy) for GNU/Linux division-by zero handler */ void __div0 (void) { - hang(); + panic("division by zero\n"); } diff --git a/arch/arm/mach-at91/at91sam9260_devices.c b/arch/arm/mach-at91/at91sam9260_devices.c index c8871f8..3ddd0cf 100644 --- a/arch/arm/mach-at91/at91sam9260_devices.c +++ b/arch/arm/mach-at91/at91sam9260_devices.c @@ -356,18 +356,7 @@ at91_set_A_periph(AT91_PIN_PA8, 0); - if (mmc_id == 0) { - /* CMD */ - at91_set_A_periph(AT91_PIN_PA7, 1); - - /* DAT0, maybe DAT1..DAT3 */ - at91_set_A_periph(AT91_PIN_PA6, 1); - if (data->bus_width == 4) { - at91_set_A_periph(AT91_PIN_PA9, 1); - at91_set_A_periph(AT91_PIN_PA10, 1); - at91_set_A_periph(AT91_PIN_PA11, 1); - } - } else if (mmc_id == 1) { + if (data->slot_b) { /* CMD */ at91_set_B_periph(AT91_PIN_PA1, 1); @@ -378,6 +367,17 @@ at91_set_B_periph(AT91_PIN_PA4, 1); at91_set_B_periph(AT91_PIN_PA5, 1); } + } else { + /* CMD */ + at91_set_A_periph(AT91_PIN_PA7, 1); + + /* DAT0, maybe DAT1..DAT3 */ + at91_set_A_periph(AT91_PIN_PA6, 1); + if (data->bus_width == 4) { + at91_set_A_periph(AT91_PIN_PA9, 1); + at91_set_A_periph(AT91_PIN_PA10, 1); + at91_set_A_periph(AT91_PIN_PA11, 1); + } } dev = add_generic_device("atmel_mci", mmc_id, NULL, AT91SAM9260_BASE_MCI, SZ_16K, diff --git a/arch/arm/mach-at91/at91sam9263_devices.c b/arch/arm/mach-at91/at91sam9263_devices.c index 1811c12..fc7dc14 100644 --- a/arch/arm/mach-at91/at91sam9263_devices.c +++ b/arch/arm/mach-at91/at91sam9263_devices.c @@ -310,33 +310,58 @@ if (mmc_id == 0) { /* MCI0 */ start = AT91SAM9263_BASE_MCI0; + /* CLK */ at91_set_A_periph(AT91_PIN_PA12, 0); - /* CMD */ - at91_set_A_periph(AT91_PIN_PA1, 1); + if (data->slot_b) { + /* CMD */ + at91_set_A_periph(AT91_PIN_PA16, 1); - /* DAT0, maybe DAT1..DAT3 and maybe DAT4..DAT7 */ - at91_set_A_periph(AT91_PIN_PA0, 1); - if (data->bus_width == 4) { - at91_set_A_periph(AT91_PIN_PA3, 1); - at91_set_A_periph(AT91_PIN_PA4, 1); - at91_set_A_periph(AT91_PIN_PA5, 1); + /* DAT0, maybe DAT1..DAT3 */ + at91_set_A_periph(AT91_PIN_PA17, 1); + if (data->bus_width == 4) { + at91_set_A_periph(AT91_PIN_PA18, 1); + at91_set_A_periph(AT91_PIN_PA19, 1); + at91_set_A_periph(AT91_PIN_PA20, 1); + } + } else { + /* CMD */ + at91_set_A_periph(AT91_PIN_PA1, 1); + + /* DAT0, maybe DAT1..DAT3 */ + at91_set_A_periph(AT91_PIN_PA0, 1); + if (data->bus_width == 4) { + at91_set_A_periph(AT91_PIN_PA3, 1); + at91_set_A_periph(AT91_PIN_PA4, 1); + at91_set_A_periph(AT91_PIN_PA5, 1); + } } } else { /* MCI1 */ start = AT91SAM9263_BASE_MCI1; - /* CLK */ - at91_set_A_periph(AT91_PIN_PA6, 0); - /* CMD */ - at91_set_A_periph(AT91_PIN_PA7, 1); + if (data->slot_b) { + /* CMD */ + at91_set_A_periph(AT91_PIN_PA21, 1); - /* DAT0, maybe DAT1..DAT3 */ - at91_set_A_periph(AT91_PIN_PA8, 1); - if (data->bus_width == 4) { - at91_set_A_periph(AT91_PIN_PA9, 1); - at91_set_A_periph(AT91_PIN_PA10, 1); - at91_set_A_periph(AT91_PIN_PA11, 1); + /* DAT0, maybe DAT1..DAT3 */ + at91_set_A_periph(AT91_PIN_PA22, 1); + if (data->bus_width == 4) { + at91_set_A_periph(AT91_PIN_PA23, 1); + at91_set_A_periph(AT91_PIN_PA24, 1); + at91_set_A_periph(AT91_PIN_PA25, 1); + } + } else { + /* CMD */ + at91_set_A_periph(AT91_PIN_PA7, 1); + + /* DAT0, maybe DAT1..DAT3 */ + at91_set_A_periph(AT91_PIN_PA8, 1); + if (data->bus_width == 4) { + at91_set_A_periph(AT91_PIN_PA9, 1); + at91_set_A_periph(AT91_PIN_PA10, 1); + at91_set_A_periph(AT91_PIN_PA11, 1); + } } } diff --git a/arch/arm/mach-at91/at91sam9g45_devices.c b/arch/arm/mach-at91/at91sam9g45_devices.c index 9a24022..bb252bd 100644 --- a/arch/arm/mach-at91/at91sam9g45_devices.c +++ b/arch/arm/mach-at91/at91sam9g45_devices.c @@ -264,6 +264,7 @@ } } } else { /* MCI1 */ + data->slot_b = 1; start = AT91SAM9G45_BASE_MCI1; /* CLK */ at91_set_A_periph(AT91_PIN_PA31, 0); diff --git a/arch/arm/mach-at91/include/mach/board.h b/arch/arm/mach-at91/include/mach/board.h index 738af87..755ddc8 100644 --- a/arch/arm/mach-at91/include/mach/board.h +++ b/arch/arm/mach-at91/include/mach/board.h @@ -87,6 +87,7 @@ /* Multimedia Card Interface */ struct atmel_mci_platform_data { + unsigned slot_b; unsigned bus_width; unsigned host_caps; /* MCI_MODE_* from mci.h */ unsigned detect_pin; diff --git a/common/console.c b/common/console.c index 88c4010..abc0627 100644 --- a/common/console.c +++ b/common/console.c @@ -40,8 +40,9 @@ LIST_HEAD(console_list); EXPORT_SYMBOL(console_list); -#define CONSOLE_UNINITIALIZED 0 -#define CONSOLE_INIT_FULL 1 +#define CONSOLE_UNINITIALIZED 0 +#define CONSOLE_INITIALIZED_BUFFER 1 +#define CONSOLE_INIT_FULL 2 static int initialized = 0; @@ -109,17 +110,25 @@ return 0; } -static struct kfifo *console_input_buffer; -static struct kfifo *console_output_buffer; +#define CONSOLE_BUFFER_SIZE 1024 -static int getc_buffer_flush(void) +static char console_input_buffer[CONSOLE_BUFFER_SIZE]; +static char console_output_buffer[CONSOLE_BUFFER_SIZE]; + +static struct kfifo __console_input_fifo; +static struct kfifo __console_output_fifo; +static struct kfifo *console_input_fifo = &__console_input_fifo; +static struct kfifo *console_output_fifo = &__console_output_fifo; + +static void console_init_early(void) { - console_input_buffer = kfifo_alloc(1024); - console_output_buffer = kfifo_alloc(1024); - return 0; -} + kfifo_init(console_input_fifo, console_input_buffer, + CONSOLE_BUFFER_SIZE); + kfifo_init(console_output_fifo, console_output_buffer, + CONSOLE_BUFFER_SIZE); -postcore_initcall(getc_buffer_flush); + initialized = CONSOLE_INITIALIZED_BUFFER; +} int console_register(struct console_device *newcdev) { @@ -127,6 +136,9 @@ int first = 0; char ch; + if (initialized == CONSOLE_UNINITIALIZED) + console_init_early(); + dev->id = -1; strcpy(dev->name, "cs"); dev->type_data = newcdev; @@ -154,8 +166,7 @@ list_add_tail(&newcdev->list, &console_list); - - while (kfifo_getc(console_output_buffer, &ch) == 0) + while (kfifo_getc(console_output_fifo, &ch) == 0) console_putc(CONSOLE_STDOUT, ch); if (first) barebox_banner(); @@ -226,16 +237,16 @@ start = get_time_ns(); while (1) { if (tstc_raw()) { - kfifo_putc(console_input_buffer, getc_raw()); + kfifo_putc(console_input_fifo, getc_raw()); start = get_time_ns(); } if (is_timeout(start, 100 * USECOND) && - kfifo_len(console_input_buffer)) + kfifo_len(console_input_fifo)) break; } - kfifo_getc(console_input_buffer, &ch); + kfifo_getc(console_input_fifo, &ch); return ch; } EXPORT_SYMBOL(getc); @@ -252,7 +263,7 @@ int tstc(void) { - return kfifo_len(console_input_buffer) || tstc_raw(); + return kfifo_len(console_input_fifo) || tstc_raw(); } EXPORT_SYMBOL(tstc); @@ -263,7 +274,11 @@ switch (init) { case CONSOLE_UNINITIALIZED: - kfifo_putc(console_output_buffer, c); + console_init_early(); + /* fall through */ + + case CONSOLE_INITIALIZED_BUFFER: + kfifo_putc(console_output_fifo, c); return; case CONSOLE_INIT_FULL: diff --git a/common/startup.c b/common/startup.c index 180fdc3..abd1b77 100644 --- a/common/startup.c +++ b/common/startup.c @@ -121,16 +121,12 @@ for (initcall = __barebox_initcalls_start; initcall < __barebox_initcalls_end; initcall++) { - PUTS_LL("<<"); - PUTHEX_LL(*initcall); + debug("initcall-> %pS\n", *initcall); result = (*initcall)(); - PUTC_LL('>'); - if (result) - hang(); - PUTS_LL(">\n"); + debug("initcall<- %pS (%d)\n", *initcall, result); } - PUTS_LL("initcalls done\n"); + debug("initcalls done\n"); display_meminfo(); diff --git a/drivers/mci/atmel_mci.c b/drivers/mci/atmel_mci.c index 15668fc..3c37747 100644 --- a/drivers/mci/atmel_mci.c +++ b/drivers/mci/atmel_mci.c @@ -36,6 +36,7 @@ u32 datasize; struct mci_cmd *cmd; struct mci_data *data; + unsigned slot_b; }; #define to_mci_host(mci) container_of(mci, struct atmel_mci_host, mci) @@ -370,7 +371,7 @@ break; } atmel_mci_writel(host, AT91_MCI_SDCR, atmel_mci_readl(host, AT91_MCI_SDCR) - | host->hw_dev->id); + | host->slot_b); if (clock) { atmel_set_clk_rate(host, clock); @@ -459,6 +460,7 @@ host->mci.host_caps |= MMC_MODE_4BIT; if (pd->bus_width == 8) host->mci.host_caps |= MMC_MODE_8BIT; + host->slot_b = pd->slot_b; host->base = dev_request_mem_region(hw_dev, 0); host->hw_dev = hw_dev; diff --git a/drivers/usb/gadget/pxa27x_udc.c b/drivers/usb/gadget/pxa27x_udc.c index d0dbee9..5652555 100644 --- a/drivers/usb/gadget/pxa27x_udc.c +++ b/drivers/usb/gadget/pxa27x_udc.c @@ -1473,6 +1473,14 @@ } }; +static int pxa27x_udc_poller(struct poller_struct *poller) +{ + return usb_gadget_poll(); +} +static struct poller_struct poller = { + .func = pxa27x_udc_poller +}; + static int __init pxa_udc_probe(struct device_d *dev) { struct pxa_udc *udc = &memory; @@ -1496,6 +1504,8 @@ the_controller = udc; udc_init_data(udc); pxa_eps_setup(udc); + poller_register(&poller); + return 0; } @@ -1506,18 +1516,9 @@ .probe = pxa_udc_probe, }; -static int pxa27x_udc_poller(struct poller_struct *poller) -{ - return usb_gadget_poll(); -} -static struct poller_struct poller = { - .func = pxa27x_udc_poller -}; - static int __init pxa27x_udc_init(void) { register_driver(&udc_driver); - poller_register(&poller); return 0; } diff --git a/include/common.h b/include/common.h index a89b3bd..d227875 100644 --- a/include/common.h +++ b/include/common.h @@ -119,6 +119,15 @@ /* common/console.c */ int ctrlc (void); +#ifdef ARCH_HAS_STACK_DUMP +void dump_stack(void); +#else +static inline void dump_stack(void) +{ + printf("no stack data available\n"); +} +#endif + #define MEMAREA_SIZE_SPECIFIED 1 struct memarea_info { diff --git a/include/console.h b/include/console.h index c0817f6..47e8600 100644 --- a/include/console.h +++ b/include/console.h @@ -56,17 +56,4 @@ #define CFG_PBSIZE (CONFIG_CBSIZE+sizeof(CONFIG_PROMPT)+16) -void early_console_putc(void *base, char c); -void early_console_init(void *base, int baudrate); - -void early_console_start(const char *name, int baudrate); - -/* - * Resolve an early console name to a pointer pointing - * to the consoles base address, usually implemented in - * board setup file. - */ -void *get_early_console_base(const char *name); - #endif - diff --git a/include/kfifo.h b/include/kfifo.h index 3eb03cb..2987e0b 100644 --- a/include/kfifo.h +++ b/include/kfifo.h @@ -28,7 +28,7 @@ unsigned int out; /* data is extracted from off. (out % size) */ }; -struct kfifo *kfifo_init(unsigned char *buffer, unsigned int size); +void kfifo_init(struct kfifo *fifo, unsigned char *buffer, unsigned int size); struct kfifo *kfifo_alloc(unsigned int size); void kfifo_free(struct kfifo *fifo); diff --git a/lib/kfifo.c b/lib/kfifo.c index 27d44e9..a2f3727 100644 --- a/lib/kfifo.c +++ b/lib/kfifo.c @@ -34,19 +34,11 @@ * Do NOT pass the kfifo to kfifo_free() after use! Simply free the * &struct kfifo with free(). */ -struct kfifo *kfifo_init(unsigned char *buffer, unsigned int size) +void kfifo_init(struct kfifo *fifo, unsigned char *buffer, unsigned int size) { - struct kfifo *fifo; - - fifo = malloc(sizeof(struct kfifo)); - if (!fifo) - return NULL; - fifo->buffer = buffer; fifo->size = size; fifo->in = fifo->out = 0; - - return fifo; } /** @@ -60,18 +52,21 @@ struct kfifo *kfifo_alloc(unsigned int size) { unsigned char *buffer; - struct kfifo *ret; + struct kfifo *fifo; buffer = malloc(size); if (!buffer) return NULL; - ret = kfifo_init(buffer, size); - - if (!ret) + fifo = malloc(sizeof(struct kfifo)); + if (!fifo) { free(buffer); + return NULL; + } - return ret; + kfifo_init(fifo, buffer, size); + + return fifo; } /** diff --git a/lib/vsprintf.c b/lib/vsprintf.c index 4165f97..9763515 100644 --- a/lib/vsprintf.c +++ b/lib/vsprintf.c @@ -625,6 +625,8 @@ putchar('\n'); va_end(args); + dump_stack(); + led_trigger(LED_TRIGGER_PANIC, TRIGGER_ENABLE); #if defined (CONFIG_PANIC_HANG)