diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2011-01-31 17:30:31 -0500 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2011-01-31 17:30:31 -0500 |
| commit | 7921127e297ea203b794c4a1c3ef3eb0ee52acbf (patch) | |
| tree | b7497bc5cf17f8c833d1d535e2f235dace25f069 | |
| parent | 35a8524ffe84667e805b9249316e729e050c83b2 (diff) | |
| parent | e98ff0f55a0232b578c9aa7f1c245868277ac7bc (diff) | |
Merge branch 'fixes' of master.kernel.org:/home/rmk/linux-2.6-arm
* 'fixes' of master.kernel.org:/home/rmk/linux-2.6-arm:
ARM: smp_on_up: allow non-ARM SMP processors
ARM: io: ensure inb/outb() et.al. are properly ordered on ARMv6+
ARM: initrd: disable initrd if passed address overlaps reserved region
ARM: footbridge: fix debug macros
ARM: mmci: round down the bytes transferred on error
ARM: mmci: complete the transaction on error
ARM: 6642/1: mmci: calculate remaining bytes at error correctly
| -rw-r--r-- | arch/arm/include/asm/io.h | 33 | ||||
| -rw-r--r-- | arch/arm/kernel/head.S | 22 | ||||
| -rw-r--r-- | arch/arm/mach-footbridge/include/mach/debug-macro.S | 4 | ||||
| -rw-r--r-- | arch/arm/mm/init.c | 6 | ||||
| -rw-r--r-- | drivers/mmc/host/mmci.c | 11 |
5 files changed, 41 insertions, 35 deletions
diff --git a/arch/arm/include/asm/io.h b/arch/arm/include/asm/io.h index 20e0f7c9e03e..d66605dea55a 100644 --- a/arch/arm/include/asm/io.h +++ b/arch/arm/include/asm/io.h | |||
| @@ -95,6 +95,15 @@ static inline void __iomem *__typesafe_io(unsigned long addr) | |||
| 95 | return (void __iomem *)addr; | 95 | return (void __iomem *)addr; |
| 96 | } | 96 | } |
| 97 | 97 | ||
| 98 | /* IO barriers */ | ||
| 99 | #ifdef CONFIG_ARM_DMA_MEM_BUFFERABLE | ||
| 100 | #define __iormb() rmb() | ||
| 101 | #define __iowmb() wmb() | ||
| 102 | #else | ||
| 103 | #define __iormb() do { } while (0) | ||
| 104 | #define __iowmb() do { } while (0) | ||
| 105 | #endif | ||
| 106 | |||
| 98 | /* | 107 | /* |
| 99 | * Now, pick up the machine-defined IO definitions | 108 | * Now, pick up the machine-defined IO definitions |
| 100 | */ | 109 | */ |
| @@ -125,17 +134,17 @@ static inline void __iomem *__typesafe_io(unsigned long addr) | |||
| 125 | * The {in,out}[bwl] macros are for emulating x86-style PCI/ISA IO space. | 134 | * The {in,out}[bwl] macros are for emulating x86-style PCI/ISA IO space. |
| 126 | */ | 135 | */ |
| 127 | #ifdef __io | 136 | #ifdef __io |
| 128 | #define outb(v,p) __raw_writeb(v,__io(p)) | 137 | #define outb(v,p) ({ __iowmb(); __raw_writeb(v,__io(p)); }) |
| 129 | #define outw(v,p) __raw_writew((__force __u16) \ | 138 | #define outw(v,p) ({ __iowmb(); __raw_writew((__force __u16) \ |
| 130 | cpu_to_le16(v),__io(p)) | 139 | cpu_to_le16(v),__io(p)); }) |
| 131 | #define outl(v,p) __raw_writel((__force __u32) \ | 140 | #define outl(v,p) ({ __iowmb(); __raw_writel((__force __u32) \ |
| 132 | cpu_to_le32(v),__io(p)) | 141 | cpu_to_le32(v),__io(p)); }) |
| 133 | 142 | ||
| 134 | #define inb(p) ({ __u8 __v = __raw_readb(__io(p)); __v; }) | 143 | #define inb(p) ({ __u8 __v = __raw_readb(__io(p)); __iormb(); __v; }) |
| 135 | #define inw(p) ({ __u16 __v = le16_to_cpu((__force __le16) \ | 144 | #define inw(p) ({ __u16 __v = le16_to_cpu((__force __le16) \ |
| 136 | __raw_readw(__io(p))); __v; }) | 145 | __raw_readw(__io(p))); __iormb(); __v; }) |
| 137 | #define inl(p) ({ __u32 __v = le32_to_cpu((__force __le32) \ | 146 | #define inl(p) ({ __u32 __v = le32_to_cpu((__force __le32) \ |
| 138 | __raw_readl(__io(p))); __v; }) | 147 | __raw_readl(__io(p))); __iormb(); __v; }) |
| 139 | 148 | ||
| 140 | #define outsb(p,d,l) __raw_writesb(__io(p),d,l) | 149 | #define outsb(p,d,l) __raw_writesb(__io(p),d,l) |
| 141 | #define outsw(p,d,l) __raw_writesw(__io(p),d,l) | 150 | #define outsw(p,d,l) __raw_writesw(__io(p),d,l) |
| @@ -192,14 +201,6 @@ extern void _memset_io(volatile void __iomem *, int, size_t); | |||
| 192 | #define writel_relaxed(v,c) ((void)__raw_writel((__force u32) \ | 201 | #define writel_relaxed(v,c) ((void)__raw_writel((__force u32) \ |
| 193 | cpu_to_le32(v),__mem_pci(c))) | 202 | cpu_to_le32(v),__mem_pci(c))) |
| 194 | 203 | ||
| 195 | #ifdef CONFIG_ARM_DMA_MEM_BUFFERABLE | ||
| 196 | #define __iormb() rmb() | ||
| 197 | #define __iowmb() wmb() | ||
| 198 | #else | ||
| 199 | #define __iormb() do { } while (0) | ||
| 200 | #define __iowmb() do { } while (0) | ||
| 201 | #endif | ||
| 202 | |||
| 203 | #define readb(c) ({ u8 __v = readb_relaxed(c); __iormb(); __v; }) | 204 | #define readb(c) ({ u8 __v = readb_relaxed(c); __iormb(); __v; }) |
| 204 | #define readw(c) ({ u16 __v = readw_relaxed(c); __iormb(); __v; }) | 205 | #define readw(c) ({ u16 __v = readw_relaxed(c); __iormb(); __v; }) |
| 205 | #define readl(c) ({ u32 __v = readl_relaxed(c); __iormb(); __v; }) | 206 | #define readl(c) ({ u32 __v = readl_relaxed(c); __iormb(); __v; }) |
diff --git a/arch/arm/kernel/head.S b/arch/arm/kernel/head.S index f17d9a09e8fb..c0225da3fb21 100644 --- a/arch/arm/kernel/head.S +++ b/arch/arm/kernel/head.S | |||
| @@ -392,24 +392,22 @@ ENDPROC(__turn_mmu_on) | |||
| 392 | 392 | ||
| 393 | #ifdef CONFIG_SMP_ON_UP | 393 | #ifdef CONFIG_SMP_ON_UP |
| 394 | __fixup_smp: | 394 | __fixup_smp: |
| 395 | mov r4, #0x00070000 | 395 | and r3, r9, #0x000f0000 @ architecture version |
| 396 | orr r3, r4, #0xff000000 @ mask 0xff070000 | 396 | teq r3, #0x000f0000 @ CPU ID supported? |
| 397 | orr r4, r4, #0x41000000 @ val 0x41070000 | ||
| 398 | and r0, r9, r3 | ||
| 399 | teq r0, r4 @ ARM CPU and ARMv6/v7? | ||
| 400 | bne __fixup_smp_on_up @ no, assume UP | 397 | bne __fixup_smp_on_up @ no, assume UP |
| 401 | 398 | ||
| 402 | orr r3, r3, #0x0000ff00 | 399 | bic r3, r9, #0x00ff0000 |
| 403 | orr r3, r3, #0x000000f0 @ mask 0xff07fff0 | 400 | bic r3, r3, #0x0000000f @ mask 0xff00fff0 |
| 401 | mov r4, #0x41000000 | ||
| 404 | orr r4, r4, #0x0000b000 | 402 | orr r4, r4, #0x0000b000 |
| 405 | orr r4, r4, #0x00000020 @ val 0x4107b020 | 403 | orr r4, r4, #0x00000020 @ val 0x4100b020 |
| 406 | and r0, r9, r3 | 404 | teq r3, r4 @ ARM 11MPCore? |
| 407 | teq r0, r4 @ ARM 11MPCore? | ||
| 408 | moveq pc, lr @ yes, assume SMP | 405 | moveq pc, lr @ yes, assume SMP |
| 409 | 406 | ||
| 410 | mrc p15, 0, r0, c0, c0, 5 @ read MPIDR | 407 | mrc p15, 0, r0, c0, c0, 5 @ read MPIDR |
| 411 | tst r0, #1 << 31 | 408 | and r0, r0, #0xc0000000 @ multiprocessing extensions and |
| 412 | movne pc, lr @ bit 31 => SMP | 409 | teq r0, #0x80000000 @ not part of a uniprocessor system? |
| 410 | moveq pc, lr @ yes, assume SMP | ||
| 413 | 411 | ||
| 414 | __fixup_smp_on_up: | 412 | __fixup_smp_on_up: |
| 415 | adr r0, 1f | 413 | adr r0, 1f |
diff --git a/arch/arm/mach-footbridge/include/mach/debug-macro.S b/arch/arm/mach-footbridge/include/mach/debug-macro.S index 3c9e0c40c679..30b971d65815 100644 --- a/arch/arm/mach-footbridge/include/mach/debug-macro.S +++ b/arch/arm/mach-footbridge/include/mach/debug-macro.S | |||
| @@ -17,8 +17,8 @@ | |||
| 17 | /* For NetWinder debugging */ | 17 | /* For NetWinder debugging */ |
| 18 | .macro addruart, rp, rv | 18 | .macro addruart, rp, rv |
| 19 | mov \rp, #0x000003f8 | 19 | mov \rp, #0x000003f8 |
| 20 | orr \rv, \rp, #0x7c000000 @ physical | 20 | orr \rv, \rp, #0xff000000 @ virtual |
| 21 | orr \rp, \rp, #0xff000000 @ virtual | 21 | orr \rp, \rp, #0x7c000000 @ physical |
| 22 | .endm | 22 | .endm |
| 23 | 23 | ||
| 24 | #define UART_SHIFT 0 | 24 | #define UART_SHIFT 0 |
diff --git a/arch/arm/mm/init.c b/arch/arm/mm/init.c index 5164069ced42..cddd684364da 100644 --- a/arch/arm/mm/init.c +++ b/arch/arm/mm/init.c | |||
| @@ -297,6 +297,12 @@ void __init arm_memblock_init(struct meminfo *mi, struct machine_desc *mdesc) | |||
| 297 | memblock_reserve(__pa(_stext), _end - _stext); | 297 | memblock_reserve(__pa(_stext), _end - _stext); |
| 298 | #endif | 298 | #endif |
| 299 | #ifdef CONFIG_BLK_DEV_INITRD | 299 | #ifdef CONFIG_BLK_DEV_INITRD |
| 300 | if (phys_initrd_size && | ||
| 301 | memblock_is_region_reserved(phys_initrd_start, phys_initrd_size)) { | ||
| 302 | pr_err("INITRD: 0x%08lx+0x%08lx overlaps in-use memory region - disabling initrd\n", | ||
| 303 | phys_initrd_start, phys_initrd_size); | ||
| 304 | phys_initrd_start = phys_initrd_size = 0; | ||
| 305 | } | ||
| 300 | if (phys_initrd_size) { | 306 | if (phys_initrd_size) { |
| 301 | memblock_reserve(phys_initrd_start, phys_initrd_size); | 307 | memblock_reserve(phys_initrd_start, phys_initrd_size); |
| 302 | 308 | ||
diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c index 4b8dcd5b2a01..2d6de3e03e2d 100644 --- a/drivers/mmc/host/mmci.c +++ b/drivers/mmc/host/mmci.c | |||
| @@ -14,6 +14,7 @@ | |||
| 14 | #include <linux/ioport.h> | 14 | #include <linux/ioport.h> |
| 15 | #include <linux/device.h> | 15 | #include <linux/device.h> |
| 16 | #include <linux/interrupt.h> | 16 | #include <linux/interrupt.h> |
| 17 | #include <linux/kernel.h> | ||
| 17 | #include <linux/delay.h> | 18 | #include <linux/delay.h> |
| 18 | #include <linux/err.h> | 19 | #include <linux/err.h> |
| 19 | #include <linux/highmem.h> | 20 | #include <linux/highmem.h> |
| @@ -283,19 +284,19 @@ mmci_data_irq(struct mmci_host *host, struct mmc_data *data, | |||
| 283 | u32 remain, success; | 284 | u32 remain, success; |
| 284 | 285 | ||
| 285 | /* Calculate how far we are into the transfer */ | 286 | /* Calculate how far we are into the transfer */ |
| 286 | remain = readl(host->base + MMCIDATACNT) << 2; | 287 | remain = readl(host->base + MMCIDATACNT); |
| 287 | success = data->blksz * data->blocks - remain; | 288 | success = data->blksz * data->blocks - remain; |
| 288 | 289 | ||
| 289 | dev_dbg(mmc_dev(host->mmc), "MCI ERROR IRQ (status %08x)\n", status); | 290 | dev_dbg(mmc_dev(host->mmc), "MCI ERROR IRQ (status %08x)\n", status); |
| 290 | if (status & MCI_DATACRCFAIL) { | 291 | if (status & MCI_DATACRCFAIL) { |
| 291 | /* Last block was not successful */ | 292 | /* Last block was not successful */ |
| 292 | host->data_xfered = ((success / data->blksz) - 1 * data->blksz); | 293 | host->data_xfered = round_down(success - 1, data->blksz); |
| 293 | data->error = -EILSEQ; | 294 | data->error = -EILSEQ; |
| 294 | } else if (status & MCI_DATATIMEOUT) { | 295 | } else if (status & MCI_DATATIMEOUT) { |
| 295 | host->data_xfered = success; | 296 | host->data_xfered = round_down(success, data->blksz); |
| 296 | data->error = -ETIMEDOUT; | 297 | data->error = -ETIMEDOUT; |
| 297 | } else if (status & (MCI_TXUNDERRUN|MCI_RXOVERRUN)) { | 298 | } else if (status & (MCI_TXUNDERRUN|MCI_RXOVERRUN)) { |
| 298 | host->data_xfered = success; | 299 | host->data_xfered = round_down(success, data->blksz); |
| 299 | data->error = -EIO; | 300 | data->error = -EIO; |
| 300 | } | 301 | } |
| 301 | 302 | ||
| @@ -319,7 +320,7 @@ mmci_data_irq(struct mmci_host *host, struct mmc_data *data, | |||
| 319 | if (status & MCI_DATABLOCKEND) | 320 | if (status & MCI_DATABLOCKEND) |
| 320 | dev_err(mmc_dev(host->mmc), "stray MCI_DATABLOCKEND interrupt\n"); | 321 | dev_err(mmc_dev(host->mmc), "stray MCI_DATABLOCKEND interrupt\n"); |
| 321 | 322 | ||
| 322 | if (status & MCI_DATAEND) { | 323 | if (status & MCI_DATAEND || data->error) { |
| 323 | mmci_stop_data(host); | 324 | mmci_stop_data(host); |
| 324 | 325 | ||
| 325 | if (!data->error) | 326 | if (!data->error) |
