diff --git a/[refs] b/[refs] index 73bfc5252fac..340601ae365c 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 4fbca5320eb102d2e15bdeffe79e125c11cf925e +refs/heads/master: 4cff33f94fefcce1b3c01a9d1da6bb85fe3cbdfa diff --git a/trunk/arch/arm/kernel/asm-offsets.c b/trunk/arch/arm/kernel/asm-offsets.c index 396efba9bacd..45fdf4a51a2a 100644 --- a/trunk/arch/arm/kernel/asm-offsets.c +++ b/trunk/arch/arm/kernel/asm-offsets.c @@ -99,8 +99,6 @@ int main(void) DEFINE(MACHINFO_NAME, offsetof(struct machine_desc, name)); DEFINE(MACHINFO_PHYSIO, offsetof(struct machine_desc, phys_io)); DEFINE(MACHINFO_PGOFFIO, offsetof(struct machine_desc, io_pg_offst)); - BLANK(); - DEFINE(PROC_INFO_SZ, sizeof(struct proc_info_list)); DEFINE(PROCINFO_INITFUNC, offsetof(struct proc_info_list, __cpu_flush)); DEFINE(PROCINFO_MMUFLAGS, offsetof(struct proc_info_list, __cpu_mmu_flags)); return 0; diff --git a/trunk/arch/arm/kernel/dma-isa.c b/trunk/arch/arm/kernel/dma-isa.c index 0a3e9ad297d8..03532769a97f 100644 --- a/trunk/arch/arm/kernel/dma-isa.c +++ b/trunk/arch/arm/kernel/dma-isa.c @@ -143,23 +143,12 @@ static struct dma_ops isa_dma_ops = { .residue = isa_get_dma_residue, }; -static struct resource dma_resources[] = { { - .name = "dma1", - .start = 0x0000, - .end = 0x000f -}, { - .name = "dma low page", - .start = 0x0080, - .end = 0x008f -}, { - .name = "dma2", - .start = 0x00c0, - .end = 0x00df -}, { - .name = "dma high page", - .start = 0x0480, - .end = 0x048f -} }; +static struct resource dma_resources[] = { + { "dma1", 0x0000, 0x000f }, + { "dma low page", 0x0080, 0x008f }, + { "dma2", 0x00c0, 0x00df }, + { "dma high page", 0x0480, 0x048f } +}; void __init isa_init_dma(dma_t *dma) { diff --git a/trunk/arch/arm/kernel/process.c b/trunk/arch/arm/kernel/process.c index 7df6e1aaa323..1a1539e3a946 100644 --- a/trunk/arch/arm/kernel/process.c +++ b/trunk/arch/arm/kernel/process.c @@ -311,7 +311,7 @@ void free_thread_info(struct thread_info *thread) struct thread_info_list *th = &get_cpu_var(thread_info_list); if (th->nr < EXTRA_TASK_STRUCT) { unsigned long *p = (unsigned long *)thread; - p[0] = (unsigned long)th->head; + p[0] = th->head; th->head = p; th->nr += 1; put_cpu_var(thread_info_list); diff --git a/trunk/arch/arm/lib/backtrace.S b/trunk/arch/arm/lib/backtrace.S index 16153c86c3f8..3bdc8c6949c5 100644 --- a/trunk/arch/arm/lib/backtrace.S +++ b/trunk/arch/arm/lib/backtrace.S @@ -122,7 +122,7 @@ ENTRY(c_backtrace) #define reg r5 #define stack r6 -.Ldumpstm: stmfd sp!, {instr, reg, stack, r7, r8, lr} +.Ldumpstm: stmfd sp!, {instr, reg, stack, r7, lr} mov stack, r0 mov instr, r1 mov reg, #9 @@ -145,7 +145,7 @@ ENTRY(c_backtrace) adrne r0, .Lcr blne printk mov r0, stack - LOADREGS(fd, sp!, {instr, reg, stack, r7, r8, pc}) + LOADREGS(fd, sp!, {instr, reg, stack, r7, pc}) .Lfp: .asciz " r%d = %08X%c" .Lcr: .asciz "\n" diff --git a/trunk/arch/arm/lib/div64.S b/trunk/arch/arm/lib/div64.S index 58eef6607629..ec9a1cd6176f 100644 --- a/trunk/arch/arm/lib/div64.S +++ b/trunk/arch/arm/lib/div64.S @@ -189,12 +189,12 @@ ENTRY(__do_div64) moveq pc, lr @ Division by 0: - str lr, [sp, #-8]! + str lr, [sp, #-4]! bl __div0 @ as wrong as it could be... mov yl, #0 mov yh, #0 mov xh, #0 - ldr pc, [sp], #8 + ldr pc, [sp], #4 diff --git a/trunk/arch/arm/mach-realview/realview_eb.c b/trunk/arch/arm/mach-realview/realview_eb.c index 693fb1e396e0..d4a586e38d5b 100644 --- a/trunk/arch/arm/mach-realview/realview_eb.c +++ b/trunk/arch/arm/mach-realview/realview_eb.c @@ -137,11 +137,8 @@ static struct amba_device *amba_devs[] __initdata = { static void __init gic_init_irq(void) { #ifdef CONFIG_REALVIEW_MPCORE - unsigned int pldctrl; writel(0x0000a05f, __io_address(REALVIEW_SYS_LOCK)); - pldctrl = readl(__io_address(REALVIEW_SYS_BASE) + 0xd8); - pldctrl |= 0x00800000; /* New irq mode */ - writel(pldctrl, __io_address(REALVIEW_SYS_BASE) + 0xd8); + writel(0x008003c0, __io_address(REALVIEW_SYS_BASE) + 0xd8); writel(0x00000000, __io_address(REALVIEW_SYS_LOCK)); #endif gic_dist_init(__io_address(REALVIEW_GIC_DIST_BASE)); diff --git a/trunk/arch/arm/mm/ioremap.c b/trunk/arch/arm/mm/ioremap.c index c1f7180c7bed..25e0ca3e598c 100644 --- a/trunk/arch/arm/mm/ioremap.c +++ b/trunk/arch/arm/mm/ioremap.c @@ -141,7 +141,7 @@ __ioremap_pfn(unsigned long pfn, unsigned long offset, size_t size, return NULL; addr = (unsigned long)area->addr; if (remap_area_pages(addr, pfn, size, flags)) { - vunmap((void *)addr); + vfree((void *)addr); return NULL; } return (void __iomem *) (offset + (char *)addr); @@ -173,7 +173,7 @@ EXPORT_SYMBOL(__ioremap); void __iounmap(void __iomem *addr) { - vunmap((void *)(PAGE_MASK & (unsigned long)addr)); + vfree((void *) (PAGE_MASK & (unsigned long) addr)); } EXPORT_SYMBOL(__iounmap); diff --git a/trunk/drivers/serial/serial_core.c b/trunk/drivers/serial/serial_core.c index 17839e753e4c..aeb8153ccf24 100644 --- a/trunk/drivers/serial/serial_core.c +++ b/trunk/drivers/serial/serial_core.c @@ -1907,12 +1907,9 @@ uart_set_options(struct uart_port *port, struct console *co, static void uart_change_pm(struct uart_state *state, int pm_state) { struct uart_port *port = state->port; - - if (state->pm_state != pm_state) { - if (port->ops->pm) - port->ops->pm(port, pm_state, state->pm_state); - state->pm_state = pm_state; - } + if (port->ops->pm) + port->ops->pm(port, pm_state, state->pm_state); + state->pm_state = pm_state; } int uart_suspend_port(struct uart_driver *drv, struct uart_port *port) diff --git a/trunk/drivers/spi/spi_bitbang.c b/trunk/drivers/spi/spi_bitbang.c index f037e5593269..0525c99118c3 100644 --- a/trunk/drivers/spi/spi_bitbang.c +++ b/trunk/drivers/spi/spi_bitbang.c @@ -138,6 +138,43 @@ static unsigned bitbang_txrx_32( return t->len - count; } +static int +bitbang_transfer_setup(struct spi_device *spi, struct spi_transfer *t) +{ + struct spi_bitbang_cs *cs = spi->controller_state; + u8 bits_per_word; + u32 hz; + + if (t) { + bits_per_word = t->bits_per_word; + hz = t->speed_hz; + } else { + bits_per_word = 0; + hz = 0; + } + + /* spi_transfer level calls that work per-word */ + if (!bits_per_word) + bits_per_word = spi->bits_per_word; + if (bits_per_word <= 8) + cs->txrx_bufs = bitbang_txrx_8; + else if (bits_per_word <= 16) + cs->txrx_bufs = bitbang_txrx_16; + else if (bits_per_word <= 32) + cs->txrx_bufs = bitbang_txrx_32; + else + return -EINVAL; + + /* nsecs = (clock period)/2 */ + if (!hz) + hz = spi->max_speed_hz; + cs->nsecs = (1000000000/2) / hz; + if (cs->nsecs > MAX_UDELAY_MS * 1000) + return -EINVAL; + + return 0; +} + /** * spi_bitbang_setup - default setup for per-word I/O loops */ @@ -145,6 +182,7 @@ int spi_bitbang_setup(struct spi_device *spi) { struct spi_bitbang_cs *cs = spi->controller_state; struct spi_bitbang *bitbang; + int retval; if (!spi->max_speed_hz) return -EINVAL; @@ -160,25 +198,14 @@ int spi_bitbang_setup(struct spi_device *spi) if (!spi->bits_per_word) spi->bits_per_word = 8; - /* spi_transfer level calls that work per-word */ - if (spi->bits_per_word <= 8) - cs->txrx_bufs = bitbang_txrx_8; - else if (spi->bits_per_word <= 16) - cs->txrx_bufs = bitbang_txrx_16; - else if (spi->bits_per_word <= 32) - cs->txrx_bufs = bitbang_txrx_32; - else - return -EINVAL; - /* per-word shift register access, in hardware or bitbanging */ cs->txrx_word = bitbang->txrx_word[spi->mode & (SPI_CPOL|SPI_CPHA)]; if (!cs->txrx_word) return -EINVAL; - /* nsecs = (clock period)/2 */ - cs->nsecs = (1000000000/2) / (spi->max_speed_hz); - if (cs->nsecs > MAX_UDELAY_MS * 1000) - return -EINVAL; + retval = bitbang_transfer_setup(spi, NULL); + if (retval < 0) + return retval; dev_dbg(&spi->dev, "%s, mode %d, %u bits/w, %u nsec\n", __FUNCTION__, spi->mode & (SPI_CPOL | SPI_CPHA), @@ -246,6 +273,8 @@ static void bitbang_work(void *_bitbang) unsigned tmp; unsigned cs_change; int status; + int (*setup_transfer)(struct spi_device *, + struct spi_transfer *); m = container_of(bitbang->queue.next, struct spi_message, queue); @@ -262,6 +291,7 @@ static void bitbang_work(void *_bitbang) tmp = 0; cs_change = 1; status = 0; + setup_transfer = NULL; list_for_each_entry (t, &m->transfers, transfer_list) { if (bitbang->shutdown) { @@ -269,6 +299,20 @@ static void bitbang_work(void *_bitbang) break; } + /* override or restore speed and wordsize */ + if (t->speed_hz || t->bits_per_word) { + setup_transfer = bitbang->setup_transfer; + if (!setup_transfer) { + status = -ENOPROTOOPT; + break; + } + } + if (setup_transfer) { + status = setup_transfer(spi, t); + if (status < 0) + break; + } + /* set up default clock polarity, and activate chip; * this implicitly updates clock and spi modes as * previously recorded for this device via setup(). @@ -325,6 +369,10 @@ static void bitbang_work(void *_bitbang) m->status = status; m->complete(m->context); + /* restore speed and wordsize */ + if (setup_transfer) + setup_transfer(spi, NULL); + /* normally deactivate chipselect ... unless no error and * cs_change has hinted that the next message will probably * be for this chip too. @@ -406,6 +454,7 @@ int spi_bitbang_start(struct spi_bitbang *bitbang) bitbang->use_dma = 0; bitbang->txrx_bufs = spi_bitbang_bufs; if (!bitbang->master->setup) { + bitbang->setup_transfer = bitbang_transfer_setup; bitbang->master->setup = spi_bitbang_setup; bitbang->master->cleanup = spi_bitbang_cleanup; } diff --git a/trunk/include/asm-arm/procinfo.h b/trunk/include/asm-arm/procinfo.h index 842526055225..a9c75b2c314f 100644 --- a/trunk/include/asm-arm/procinfo.h +++ b/trunk/include/asm-arm/procinfo.h @@ -45,6 +45,8 @@ extern unsigned int elf_hwcap; #endif /* __ASSEMBLY__ */ +#define PROC_INFO_SZ 48 + #define HWCAP_SWP 1 #define HWCAP_HALF 2 #define HWCAP_THUMB 4 diff --git a/trunk/include/linux/spi/spi.h b/trunk/include/linux/spi/spi.h index b05f1463a267..caa4665e3fa2 100644 --- a/trunk/include/linux/spi/spi.h +++ b/trunk/include/linux/spi/spi.h @@ -31,6 +31,7 @@ extern struct bus_type spi_bus_type; * @master: SPI controller used with the device. * @max_speed_hz: Maximum clock rate to be used with this chip * (on this board); may be changed by the device's driver. + * The spi_transfer.speed_hz can override this for each transfer. * @chip-select: Chipselect, distinguishing chips handled by "master". * @mode: The spi mode defines how data is clocked out and in. * This may be changed by the device's driver. @@ -38,6 +39,7 @@ extern struct bus_type spi_bus_type; * like eight or 12 bits are common. In-memory wordsizes are * powers of two bytes (e.g. 20 bit samples use 32 bits). * This may be changed by the device's driver. + * The spi_transfer.bits_per_word can override this for each transfer. * @irq: Negative, or the number passed to request_irq() to receive * interrupts from this device. * @controller_state: Controller's runtime state @@ -268,6 +270,10 @@ extern struct spi_master *spi_busnum_to_master(u16 busnum); * @tx_dma: DMA address of tx_buf, if spi_message.is_dma_mapped * @rx_dma: DMA address of rx_buf, if spi_message.is_dma_mapped * @len: size of rx and tx buffers (in bytes) + * @speed_hz: Select a speed other then the device default for this + * transfer. If 0 the default (from spi_device) is used. + * @bits_per_word: select a bits_per_word other then the device default + * for this transfer. If 0 the default (from spi_device) is used. * @cs_change: affects chipselect after this transfer completes * @delay_usecs: microseconds to delay after this transfer before * (optionally) changing the chipselect status, then starting @@ -322,7 +328,9 @@ struct spi_transfer { dma_addr_t rx_dma; unsigned cs_change:1; + u8 bits_per_word; u16 delay_usecs; + u32 speed_hz; struct list_head transfer_list; }; diff --git a/trunk/include/linux/spi/spi_bitbang.h b/trunk/include/linux/spi/spi_bitbang.h index c961fe9bf3eb..c954557b757c 100644 --- a/trunk/include/linux/spi/spi_bitbang.h +++ b/trunk/include/linux/spi/spi_bitbang.h @@ -30,6 +30,12 @@ struct spi_bitbang { struct spi_master *master; + /* setup_transfer() changes clock and/or wordsize to match settings + * for this transfer; zeroes restore defaults from spi_device. + */ + int (*setup_transfer)(struct spi_device *spi, + struct spi_transfer *t); + void (*chipselect)(struct spi_device *spi, int is_on); #define BITBANG_CS_ACTIVE 1 /* normally nCS, active low */ #define BITBANG_CS_INACTIVE 0