aboutsummaryrefslogtreecommitdiffstats
path: root/arch/mips/mm
diff options
context:
space:
mode:
authorDmitry Torokhov <dtor@insightbb.com>2007-05-01 00:24:54 -0400
committerDmitry Torokhov <dtor@insightbb.com>2007-05-01 00:24:54 -0400
commitbc95f3669f5e6f63cf0b84fe4922c3c6dd4aa775 (patch)
tree427fcf2a7287c16d4b5aa6cbf494d59579a6a8b1 /arch/mips/mm
parentInput: cobalt_btns - convert to use polldev library (diff)
parentlibata: honour host controllers that want just one host (diff)
downloadlinux-dev-bc95f3669f5e6f63cf0b84fe4922c3c6dd4aa775.tar.xz
linux-dev-bc95f3669f5e6f63cf0b84fe4922c3c6dd4aa775.zip
Merge master.kernel.org:/pub/scm/linux/kernel/git/torvalds/linux-2.6
Conflicts: drivers/usb/input/Makefile drivers/usb/input/gtco.c
Diffstat (limited to 'arch/mips/mm')
-rw-r--r--arch/mips/mm/Makefile2
-rw-r--r--arch/mips/mm/c-r3k.c2
-rw-r--r--arch/mips/mm/c-tx39.c18
-rw-r--r--arch/mips/mm/cache.c16
-rw-r--r--arch/mips/mm/cerr-sb1.c133
-rw-r--r--arch/mips/mm/dma-default.c23
-rw-r--r--arch/mips/mm/fault.c6
-rw-r--r--arch/mips/mm/init.c35
-rw-r--r--arch/mips/mm/ioremap.c96
-rw-r--r--arch/mips/mm/pg-sb1.c3
-rw-r--r--arch/mips/mm/pgtable-32.c1
-rw-r--r--arch/mips/mm/pgtable-64.c1
12 files changed, 213 insertions, 123 deletions
diff --git a/arch/mips/mm/Makefile b/arch/mips/mm/Makefile
index de5727385bc6..293697b15603 100644
--- a/arch/mips/mm/Makefile
+++ b/arch/mips/mm/Makefile
@@ -31,5 +31,3 @@ obj-$(CONFIG_IP22_CPU_SCACHE) += sc-ip22.o
obj-$(CONFIG_R5000_CPU_SCACHE) += sc-r5k.o
obj-$(CONFIG_RM7000_CPU_SCACHE) += sc-rm7k.o
obj-$(CONFIG_MIPS_CPU_SCACHE) += sc-mips.o
-
-EXTRA_AFLAGS := $(CFLAGS)
diff --git a/arch/mips/mm/c-r3k.c b/arch/mips/mm/c-r3k.c
index d1af42c2a52e..59868a1edf66 100644
--- a/arch/mips/mm/c-r3k.c
+++ b/arch/mips/mm/c-r3k.c
@@ -260,7 +260,7 @@ static void r3k_flush_cache_page(struct vm_area_struct *vma, unsigned long page,
{
}
-static void local_r3k_flush_data_cache_page(unsigned long addr)
+static void local_r3k_flush_data_cache_page(void *addr)
{
}
diff --git a/arch/mips/mm/c-tx39.c b/arch/mips/mm/c-tx39.c
index f32ebde30ccf..560a6de96556 100644
--- a/arch/mips/mm/c-tx39.c
+++ b/arch/mips/mm/c-tx39.c
@@ -128,7 +128,6 @@ static inline void tx39_flush_cache_all(void)
return;
tx39_blast_dcache();
- tx39_blast_icache();
}
static inline void tx39___flush_cache_all(void)
@@ -142,24 +141,19 @@ static void tx39_flush_cache_mm(struct mm_struct *mm)
if (!cpu_has_dc_aliases)
return;
- if (cpu_context(smp_processor_id(), mm) != 0) {
- tx39_flush_cache_all();
- }
+ if (cpu_context(smp_processor_id(), mm) != 0)
+ tx39_blast_dcache();
}
static void tx39_flush_cache_range(struct vm_area_struct *vma,
unsigned long start, unsigned long end)
{
- int exec;
-
+ if (!cpu_has_dc_aliases)
+ return;
if (!(cpu_context(smp_processor_id(), vma->vm_mm)))
return;
- exec = vma->vm_flags & VM_EXEC;
- if (cpu_has_dc_aliases || exec)
- tx39_blast_dcache();
- if (exec)
- tx39_blast_icache();
+ tx39_blast_dcache();
}
static void tx39_flush_cache_page(struct vm_area_struct *vma, unsigned long page, unsigned long pfn)
@@ -218,7 +212,7 @@ static void tx39_flush_cache_page(struct vm_area_struct *vma, unsigned long page
static void local_tx39_flush_data_cache_page(void * addr)
{
- tx39_blast_dcache_page(addr);
+ tx39_blast_dcache_page((unsigned long)addr);
}
static void tx39_flush_data_cache_page(unsigned long addr)
diff --git a/arch/mips/mm/cache.c b/arch/mips/mm/cache.c
index 31819c58bffa..abf99b1eba13 100644
--- a/arch/mips/mm/cache.c
+++ b/arch/mips/mm/cache.c
@@ -3,7 +3,8 @@
* License. See the file "COPYING" in the main directory of this archive
* for more details.
*
- * Copyright (C) 1994 - 2003 by Ralf Baechle
+ * Copyright (C) 1994 - 2003, 07 by Ralf Baechle (ralf@linux-mips.org)
+ * Copyright (C) 2007 MIPS Technologies, Inc.
*/
#include <linux/init.h>
#include <linux/kernel.h>
@@ -88,6 +89,19 @@ void __flush_dcache_page(struct page *page)
EXPORT_SYMBOL(__flush_dcache_page);
+void __flush_anon_page(struct page *page, unsigned long vmaddr)
+{
+ if (pages_do_alias((unsigned long)page_address(page), vmaddr)) {
+ void *kaddr;
+
+ kaddr = kmap_coherent(page, vmaddr);
+ flush_data_cache_page((unsigned long)kaddr);
+ kunmap_coherent();
+ }
+}
+
+EXPORT_SYMBOL(__flush_anon_page);
+
void __update_cache(struct vm_area_struct *vma, unsigned long address,
pte_t pte)
{
diff --git a/arch/mips/mm/cerr-sb1.c b/arch/mips/mm/cerr-sb1.c
index e19fbb9ee47f..4c72e650f9b6 100644
--- a/arch/mips/mm/cerr-sb1.c
+++ b/arch/mips/mm/cerr-sb1.c
@@ -77,66 +77,66 @@ static uint32_t extract_dc(unsigned short addr, int data);
static inline void breakout_errctl(unsigned int val)
{
if (val & CP0_ERRCTL_RECOVERABLE)
- prom_printf(" recoverable");
+ printk(" recoverable");
if (val & CP0_ERRCTL_DCACHE)
- prom_printf(" dcache");
+ printk(" dcache");
if (val & CP0_ERRCTL_ICACHE)
- prom_printf(" icache");
+ printk(" icache");
if (val & CP0_ERRCTL_MULTIBUS)
- prom_printf(" multiple-buserr");
- prom_printf("\n");
+ printk(" multiple-buserr");
+ printk("\n");
}
static inline void breakout_cerri(unsigned int val)
{
if (val & CP0_CERRI_TAG_PARITY)
- prom_printf(" tag-parity");
+ printk(" tag-parity");
if (val & CP0_CERRI_DATA_PARITY)
- prom_printf(" data-parity");
+ printk(" data-parity");
if (val & CP0_CERRI_EXTERNAL)
- prom_printf(" external");
- prom_printf("\n");
+ printk(" external");
+ printk("\n");
}
static inline void breakout_cerrd(unsigned int val)
{
switch (val & CP0_CERRD_CAUSES) {
case CP0_CERRD_LOAD:
- prom_printf(" load,");
+ printk(" load,");
break;
case CP0_CERRD_STORE:
- prom_printf(" store,");
+ printk(" store,");
break;
case CP0_CERRD_FILLWB:
- prom_printf(" fill/wb,");
+ printk(" fill/wb,");
break;
case CP0_CERRD_COHERENCY:
- prom_printf(" coherency,");
+ printk(" coherency,");
break;
case CP0_CERRD_DUPTAG:
- prom_printf(" duptags,");
+ printk(" duptags,");
break;
default:
- prom_printf(" NO CAUSE,");
+ printk(" NO CAUSE,");
break;
}
if (!(val & CP0_CERRD_TYPES))
- prom_printf(" NO TYPE");
+ printk(" NO TYPE");
else {
if (val & CP0_CERRD_MULTIPLE)
- prom_printf(" multi-err");
+ printk(" multi-err");
if (val & CP0_CERRD_TAG_STATE)
- prom_printf(" tag-state");
+ printk(" tag-state");
if (val & CP0_CERRD_TAG_ADDRESS)
- prom_printf(" tag-address");
+ printk(" tag-address");
if (val & CP0_CERRD_DATA_SBE)
- prom_printf(" data-SBE");
+ printk(" data-SBE");
if (val & CP0_CERRD_DATA_DBE)
- prom_printf(" data-DBE");
+ printk(" data-DBE");
if (val & CP0_CERRD_EXTERNAL)
- prom_printf(" external");
+ printk(" external");
}
- prom_printf("\n");
+ printk("\n");
}
#ifndef CONFIG_SIBYTE_BUS_WATCHER
@@ -157,18 +157,18 @@ static void check_bus_watcher(void)
l2_tag = in64(IO_SPACE_BASE | A_L2_ECC_TAG);
#endif
memio_err = csr_in32(IOADDR(A_BUS_MEM_IO_ERRORS));
- prom_printf("Bus watcher error counters: %08x %08x\n", l2_err, memio_err);
- prom_printf("\nLast recorded signature:\n");
- prom_printf("Request %02x from %d, answered by %d with Dcode %d\n",
+ printk("Bus watcher error counters: %08x %08x\n", l2_err, memio_err);
+ printk("\nLast recorded signature:\n");
+ printk("Request %02x from %d, answered by %d with Dcode %d\n",
(unsigned int)(G_SCD_BERR_TID(status) & 0x3f),
(int)(G_SCD_BERR_TID(status) >> 6),
(int)G_SCD_BERR_RID(status),
(int)G_SCD_BERR_DCODE(status));
#ifdef DUMP_L2_ECC_TAG_ON_ERROR
- prom_printf("Last L2 tag w/ bad ECC: %016llx\n", l2_tag);
+ printk("Last L2 tag w/ bad ECC: %016llx\n", l2_tag);
#endif
} else {
- prom_printf("Bus watcher indicates no error\n");
+ printk("Bus watcher indicates no error\n");
}
}
#else
@@ -177,8 +177,8 @@ extern void check_bus_watcher(void);
asmlinkage void sb1_cache_error(void)
{
- uint64_t cerr_dpa;
uint32_t errctl, cerr_i, cerr_d, dpalo, dpahi, eepc, res;
+ unsigned long long cerr_dpa;
#ifdef CONFIG_SIBYTE_BW_TRACE
/* Freeze the trace buffer now */
@@ -187,11 +187,11 @@ asmlinkage void sb1_cache_error(void)
#else
csr_out32(M_SCD_TRACE_CFG_FREEZE, IO_SPACE_BASE | A_SCD_TRACE_CFG);
#endif
- prom_printf("Trace buffer frozen\n");
+ printk("Trace buffer frozen\n");
#endif
- prom_printf("Cache error exception on CPU %x:\n",
- (read_c0_prid() >> 25) & 0x7);
+ printk("Cache error exception on CPU %x:\n",
+ (read_c0_prid() >> 25) & 0x7);
__asm__ __volatile__ (
" .set push\n\t"
@@ -209,43 +209,43 @@ asmlinkage void sb1_cache_error(void)
"=r" (dpahi), "=r" (dpalo), "=r" (eepc));
cerr_dpa = (((uint64_t)dpahi) << 32) | dpalo;
- prom_printf(" c0_errorepc == %08x\n", eepc);
- prom_printf(" c0_errctl == %08x", errctl);
+ printk(" c0_errorepc == %08x\n", eepc);
+ printk(" c0_errctl == %08x", errctl);
breakout_errctl(errctl);
if (errctl & CP0_ERRCTL_ICACHE) {
- prom_printf(" c0_cerr_i == %08x", cerr_i);
+ printk(" c0_cerr_i == %08x", cerr_i);
breakout_cerri(cerr_i);
if (CP0_CERRI_IDX_VALID(cerr_i)) {
/* Check index of EPC, allowing for delay slot */
if (((eepc & SB1_CACHE_INDEX_MASK) != (cerr_i & SB1_CACHE_INDEX_MASK)) &&
((eepc & SB1_CACHE_INDEX_MASK) != ((cerr_i & SB1_CACHE_INDEX_MASK) - 4)))
- prom_printf(" cerr_i idx doesn't match eepc\n");
+ printk(" cerr_i idx doesn't match eepc\n");
else {
res = extract_ic(cerr_i & SB1_CACHE_INDEX_MASK,
(cerr_i & CP0_CERRI_DATA) != 0);
if (!(res & cerr_i))
- prom_printf("...didn't see indicated icache problem\n");
+ printk("...didn't see indicated icache problem\n");
}
}
}
if (errctl & CP0_ERRCTL_DCACHE) {
- prom_printf(" c0_cerr_d == %08x", cerr_d);
+ printk(" c0_cerr_d == %08x", cerr_d);
breakout_cerrd(cerr_d);
if (CP0_CERRD_DPA_VALID(cerr_d)) {
- prom_printf(" c0_cerr_dpa == %010llx\n", cerr_dpa);
+ printk(" c0_cerr_dpa == %010llx\n", cerr_dpa);
if (!CP0_CERRD_IDX_VALID(cerr_d)) {
res = extract_dc(cerr_dpa & SB1_CACHE_INDEX_MASK,
(cerr_d & CP0_CERRD_DATA) != 0);
if (!(res & cerr_d))
- prom_printf("...didn't see indicated dcache problem\n");
+ printk("...didn't see indicated dcache problem\n");
} else {
if ((cerr_dpa & SB1_CACHE_INDEX_MASK) != (cerr_d & SB1_CACHE_INDEX_MASK))
- prom_printf(" cerr_d idx doesn't match cerr_dpa\n");
+ printk(" cerr_d idx doesn't match cerr_dpa\n");
else {
res = extract_dc(cerr_d & SB1_CACHE_INDEX_MASK,
(cerr_d & CP0_CERRD_DATA) != 0);
if (!(res & cerr_d))
- prom_printf("...didn't see indicated problem\n");
+ printk("...didn't see indicated problem\n");
}
}
}
@@ -329,12 +329,13 @@ static uint32_t extract_ic(unsigned short addr, int data)
{
unsigned short way;
int valid;
- uint64_t taglo, va, tlo_tmp;
uint32_t taghi, taglolo, taglohi;
+ unsigned long long taglo, va;
+ uint64_t tlo_tmp;
uint8_t lru;
int res = 0;
- prom_printf("Icache index 0x%04x ", addr);
+ printk("Icache index 0x%04x ", addr);
for (way = 0; way < 4; way++) {
/* Index-load-tag-I */
__asm__ __volatile__ (
@@ -354,7 +355,7 @@ static uint32_t extract_ic(unsigned short addr, int data)
taglo = ((unsigned long long)taglohi << 32) | taglolo;
if (way == 0) {
lru = (taghi >> 14) & 0xff;
- prom_printf("[Bank %d Set 0x%02x] LRU > %d %d %d %d > MRU\n",
+ printk("[Bank %d Set 0x%02x] LRU > %d %d %d %d > MRU\n",
((addr >> 5) & 0x3), /* bank */
((addr >> 7) & 0x3f), /* index */
(lru & 0x3),
@@ -369,19 +370,19 @@ static uint32_t extract_ic(unsigned short addr, int data)
if (valid) {
tlo_tmp = taglo & 0xfff3ff;
if (((taglo >> 10) & 1) ^ range_parity(tlo_tmp, 23, 0)) {
- prom_printf(" ** bad parity in VTag0/G/ASID\n");
+ printk(" ** bad parity in VTag0/G/ASID\n");
res |= CP0_CERRI_TAG_PARITY;
}
if (((taglo >> 11) & 1) ^ range_parity(taglo, 63, 24)) {
- prom_printf(" ** bad parity in R/VTag1\n");
+ printk(" ** bad parity in R/VTag1\n");
res |= CP0_CERRI_TAG_PARITY;
}
}
if (valid ^ ((taghi >> 27) & 1)) {
- prom_printf(" ** bad parity for valid bit\n");
+ printk(" ** bad parity for valid bit\n");
res |= CP0_CERRI_TAG_PARITY;
}
- prom_printf(" %d [VA %016llx] [Vld? %d] raw tags: %08X-%016llX\n",
+ printk(" %d [VA %016llx] [Vld? %d] raw tags: %08X-%016llX\n",
way, va, valid, taghi, taglo);
if (data) {
@@ -407,21 +408,21 @@ static uint32_t extract_ic(unsigned short addr, int data)
: "r" ((way << 13) | addr | (offset << 3)));
predecode = (datahi >> 8) & 0xff;
if (((datahi >> 16) & 1) != (uint32_t)range_parity(predecode, 7, 0)) {
- prom_printf(" ** bad parity in predecode\n");
+ printk(" ** bad parity in predecode\n");
res |= CP0_CERRI_DATA_PARITY;
}
/* XXXKW should/could check predecode bits themselves */
if (((datahi >> 4) & 0xf) ^ inst_parity(insta)) {
- prom_printf(" ** bad parity in instruction a\n");
+ printk(" ** bad parity in instruction a\n");
res |= CP0_CERRI_DATA_PARITY;
}
if ((datahi & 0xf) ^ inst_parity(instb)) {
- prom_printf(" ** bad parity in instruction b\n");
+ printk(" ** bad parity in instruction b\n");
res |= CP0_CERRI_DATA_PARITY;
}
- prom_printf(" %05X-%08X%08X", datahi, insta, instb);
+ printk(" %05X-%08X%08X", datahi, insta, instb);
}
- prom_printf("\n");
+ printk("\n");
}
}
return res;
@@ -484,12 +485,12 @@ static uint32_t extract_dc(unsigned short addr, int data)
{
int valid, way;
unsigned char state;
- uint64_t taglo, pa;
uint32_t taghi, taglolo, taglohi;
+ unsigned long long taglo, pa;
uint8_t ecc, lru;
int res = 0;
- prom_printf("Dcache index 0x%04x ", addr);
+ printk("Dcache index 0x%04x ", addr);
for (way = 0; way < 4; way++) {
__asm__ __volatile__ (
" .set push\n\t"
@@ -509,7 +510,7 @@ static uint32_t extract_dc(unsigned short addr, int data)
pa = (taglo & 0xFFFFFFE000ULL) | addr;
if (way == 0) {
lru = (taghi >> 14) & 0xff;
- prom_printf("[Bank %d Set 0x%02x] LRU > %d %d %d %d > MRU\n",
+ printk("[Bank %d Set 0x%02x] LRU > %d %d %d %d > MRU\n",
((addr >> 11) & 0x2) | ((addr >> 5) & 1), /* bank */
((addr >> 6) & 0x3f), /* index */
(lru & 0x3),
@@ -519,15 +520,15 @@ static uint32_t extract_dc(unsigned short addr, int data)
}
state = (taghi >> 25) & 0x1f;
valid = DC_TAG_VALID(state);
- prom_printf(" %d [PA %010llx] [state %s (%02x)] raw tags: %08X-%016llX\n",
+ printk(" %d [PA %010llx] [state %s (%02x)] raw tags: %08X-%016llX\n",
way, pa, dc_state_str(state), state, taghi, taglo);
if (valid) {
if (((taglo >> 11) & 1) ^ range_parity(taglo, 39, 26)) {
- prom_printf(" ** bad parity in PTag1\n");
+ printk(" ** bad parity in PTag1\n");
res |= CP0_CERRD_TAG_ADDRESS;
}
if (((taglo >> 10) & 1) ^ range_parity(taglo, 25, 13)) {
- prom_printf(" ** bad parity in PTag0\n");
+ printk(" ** bad parity in PTag0\n");
res |= CP0_CERRD_TAG_ADDRESS;
}
} else {
@@ -535,8 +536,8 @@ static uint32_t extract_dc(unsigned short addr, int data)
}
if (data) {
- uint64_t datalo;
uint32_t datalohi, datalolo, datahi;
+ unsigned long long datalo;
int offset;
char bad_ecc = 0;
@@ -567,13 +568,13 @@ static uint32_t extract_dc(unsigned short addr, int data)
}
res |= (bits == 1) ? CP0_CERRD_DATA_SBE : CP0_CERRD_DATA_DBE;
}
- prom_printf(" %02X-%016llX", datahi, datalo);
+ printk(" %02X-%016llX", datahi, datalo);
}
- prom_printf("\n");
+ printk("\n");
if (bad_ecc)
- prom_printf(" dwords w/ bad ECC: %d %d %d %d\n",
- !!(bad_ecc & 8), !!(bad_ecc & 4),
- !!(bad_ecc & 2), !!(bad_ecc & 1));
+ printk(" dwords w/ bad ECC: %d %d %d %d\n",
+ !!(bad_ecc & 8), !!(bad_ecc & 4),
+ !!(bad_ecc & 2), !!(bad_ecc & 1));
}
}
return res;
diff --git a/arch/mips/mm/dma-default.c b/arch/mips/mm/dma-default.c
index 4a32e939698f..f0eb29917d9a 100644
--- a/arch/mips/mm/dma-default.c
+++ b/arch/mips/mm/dma-default.c
@@ -19,6 +19,13 @@
#include <dma-coherence.h>
+static inline unsigned long dma_addr_to_virt(dma_addr_t dma_addr)
+{
+ unsigned long addr = plat_dma_addr_to_phys(dma_addr);
+
+ return (unsigned long)phys_to_virt(addr);
+}
+
/*
* Warning on the terminology - Linux calls an uncached area coherent;
* MIPS terminology calls memory areas with hardware maintained coherency
@@ -140,7 +147,7 @@ void dma_unmap_single(struct device *dev, dma_addr_t dma_addr, size_t size,
enum dma_data_direction direction)
{
if (cpu_is_noncoherent_r10000(dev))
- __dma_sync(plat_dma_addr_to_phys(dma_addr) + PAGE_OFFSET, size,
+ __dma_sync(dma_addr_to_virt(dma_addr), size,
direction);
plat_unmap_dma_mem(dma_addr);
@@ -234,7 +241,7 @@ void dma_sync_single_for_cpu(struct device *dev, dma_addr_t dma_handle,
if (cpu_is_noncoherent_r10000(dev)) {
unsigned long addr;
- addr = PAGE_OFFSET + plat_dma_addr_to_phys(dma_handle);
+ addr = dma_addr_to_virt(dma_handle);
__dma_sync(addr, size, direction);
}
}
@@ -246,10 +253,10 @@ void dma_sync_single_for_device(struct device *dev, dma_addr_t dma_handle,
{
BUG_ON(direction == DMA_NONE);
- if (cpu_is_noncoherent_r10000(dev)) {
+ if (!plat_device_is_coherent(dev)) {
unsigned long addr;
- addr = plat_dma_addr_to_phys(dma_handle);
+ addr = dma_addr_to_virt(dma_handle);
__dma_sync(addr, size, direction);
}
}
@@ -264,7 +271,7 @@ void dma_sync_single_range_for_cpu(struct device *dev, dma_addr_t dma_handle,
if (cpu_is_noncoherent_r10000(dev)) {
unsigned long addr;
- addr = PAGE_OFFSET + plat_dma_addr_to_phys(dma_handle);
+ addr = dma_addr_to_virt(dma_handle);
__dma_sync(addr + offset, size, direction);
}
}
@@ -276,10 +283,10 @@ void dma_sync_single_range_for_device(struct device *dev, dma_addr_t dma_handle,
{
BUG_ON(direction == DMA_NONE);
- if (cpu_is_noncoherent_r10000(dev)) {
+ if (!plat_device_is_coherent(dev)) {
unsigned long addr;
- addr = PAGE_OFFSET + plat_dma_addr_to_phys(dma_handle);
+ addr = dma_addr_to_virt(dma_handle);
__dma_sync(addr + offset, size, direction);
}
}
@@ -295,7 +302,7 @@ void dma_sync_sg_for_cpu(struct device *dev, struct scatterlist *sg, int nelems,
/* Make sure that gcc doesn't leave the empty loop body. */
for (i = 0; i < nelems; i++, sg++) {
- if (!plat_device_is_coherent(dev))
+ if (cpu_is_noncoherent_r10000(dev))
__dma_sync((unsigned long)page_address(sg->page),
sg->length, direction);
plat_unmap_dma_mem(sg->dma_address);
diff --git a/arch/mips/mm/fault.c b/arch/mips/mm/fault.c
index 6f90e7ef66ac..f9c595dceba9 100644
--- a/arch/mips/mm/fault.c
+++ b/arch/mips/mm/fault.c
@@ -42,7 +42,7 @@ asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long write,
siginfo_t info;
#if 0
- printk("Cpu%d[%s:%d:%0*lx:%ld:%0*lx]\n", smp_processor_id(),
+ printk("Cpu%d[%s:%d:%0*lx:%ld:%0*lx]\n", raw_smp_processor_id(),
current->comm, current->pid, field, address, write,
field, regs->cp0_epc);
#endif
@@ -165,7 +165,7 @@ no_context:
printk(KERN_ALERT "CPU %d Unable to handle kernel paging request at "
"virtual address %0*lx, epc == %0*lx, ra == %0*lx\n",
- smp_processor_id(), field, address, field, regs->cp0_epc,
+ raw_smp_processor_id(), field, address, field, regs->cp0_epc,
field, regs->regs[31]);
die("Oops", regs);
@@ -228,7 +228,7 @@ vmalloc_fault:
pmd_t *pmd, *pmd_k;
pte_t *pte_k;
- pgd = (pgd_t *) pgd_current[smp_processor_id()] + offset;
+ pgd = (pgd_t *) pgd_current[raw_smp_processor_id()] + offset;
pgd_k = init_mm.pgd + offset;
if (!pgd_present(*pgd_k))
diff --git a/arch/mips/mm/init.c b/arch/mips/mm/init.c
index 125a4a85ec05..2d1c2c024822 100644
--- a/arch/mips/mm/init.c
+++ b/arch/mips/mm/init.c
@@ -61,8 +61,6 @@
DEFINE_PER_CPU(struct mmu_gather, mmu_gathers);
-unsigned long highstart_pfn, highend_pfn;
-
/*
* We have up to 8 empty zeroed pages so we can map one of the right colour
* when needed. This is necessary only on R4000 / R4400 SC and MC versions
@@ -125,7 +123,7 @@ static void __init kmap_coherent_init(void)
static inline void kmap_coherent_init(void) {}
#endif
-static inline void *kmap_coherent(struct page *page, unsigned long addr)
+void *kmap_coherent(struct page *page, unsigned long addr)
{
enum fixed_addresses idx;
unsigned long vaddr, flags, entrylo;
@@ -179,7 +177,7 @@ static inline void *kmap_coherent(struct page *page, unsigned long addr)
#define UNIQUE_ENTRYHI(idx) (CKSEG0 + ((idx) << (PAGE_SHIFT + 1)))
-static inline void kunmap_coherent(struct page *page)
+void kunmap_coherent(void)
{
#ifndef CONFIG_MIPS_MT_SMTC
unsigned int wired;
@@ -212,7 +210,7 @@ void copy_user_highpage(struct page *to, struct page *from,
if (cpu_has_dc_aliases) {
vfrom = kmap_coherent(from, vaddr);
copy_page(vto, vfrom);
- kunmap_coherent(from);
+ kunmap_coherent();
} else {
vfrom = kmap_atomic(from, KM_USER0);
copy_page(vto, vfrom);
@@ -235,7 +233,7 @@ void copy_to_user_page(struct vm_area_struct *vma,
if (cpu_has_dc_aliases) {
void *vto = kmap_coherent(page, vaddr) + (vaddr & ~PAGE_MASK);
memcpy(vto, src, len);
- kunmap_coherent(page);
+ kunmap_coherent();
} else
memcpy(dst, src, len);
if ((vma->vm_flags & VM_EXEC) && !cpu_has_ic_fills_f_dc)
@@ -252,7 +250,7 @@ void copy_from_user_page(struct vm_area_struct *vma,
void *vfrom =
kmap_coherent(page, vaddr) + (vaddr & ~PAGE_MASK);
memcpy(dst, vfrom, len);
- kunmap_coherent(page);
+ kunmap_coherent();
} else
memcpy(dst, src, len);
}
@@ -261,6 +259,8 @@ EXPORT_SYMBOL(copy_from_user_page);
#ifdef CONFIG_HIGHMEM
+unsigned long highstart_pfn, highend_pfn;
+
pte_t *kmap_pte;
pgprot_t kmap_prot;
@@ -314,8 +314,6 @@ void __init fixrange_init(unsigned long start, unsigned long end,
}
#ifndef CONFIG_NEED_MULTIPLE_NODES
-extern void pagetable_init(void);
-
static int __init page_is_ram(unsigned long pagenr)
{
int i;
@@ -353,18 +351,15 @@ void __init paging_init(void)
#endif
kmap_coherent_init();
-#ifdef CONFIG_ISA
- if (max_low_pfn >= MAX_DMA_PFN)
- if (min_low_pfn >= MAX_DMA_PFN) {
- zones_size[ZONE_DMA] = 0;
- zones_size[ZONE_NORMAL] = max_low_pfn - min_low_pfn;
- } else {
- zones_size[ZONE_DMA] = MAX_DMA_PFN - min_low_pfn;
- zones_size[ZONE_NORMAL] = max_low_pfn - MAX_DMA_PFN;
- }
+#ifdef CONFIG_ZONE_DMA
+ if (min_low_pfn < MAX_DMA_PFN && MAX_DMA_PFN <= max_low_pfn) {
+ zones_size[ZONE_DMA] = MAX_DMA_PFN - min_low_pfn;
+ zones_size[ZONE_NORMAL] = max_low_pfn - MAX_DMA_PFN;
+ } else if (max_low_pfn < MAX_DMA_PFN)
+ zones_size[ZONE_DMA] = max_low_pfn - min_low_pfn;
else
#endif
- zones_size[ZONE_DMA] = max_low_pfn - min_low_pfn;
+ zones_size[ZONE_NORMAL] = max_low_pfn - min_low_pfn;
#ifdef CONFIG_HIGHMEM
zones_size[ZONE_HIGHMEM] = highend_pfn - highstart_pfn;
@@ -379,7 +374,7 @@ void __init paging_init(void)
#ifdef CONFIG_FLATMEM
free_area_init(zones_size);
#else
- pfn = 0;
+ pfn = min_low_pfn;
for (i = 0; i < MAX_NR_ZONES; i++)
for (j = 0; j < zones_size[i]; j++, pfn++)
if (!page_is_ram(pfn))
diff --git a/arch/mips/mm/ioremap.c b/arch/mips/mm/ioremap.c
index fc2c96f0a1fd..cea7d0ea36e4 100644
--- a/arch/mips/mm/ioremap.c
+++ b/arch/mips/mm/ioremap.c
@@ -6,13 +6,98 @@
* (C) Copyright 1995 1996 Linus Torvalds
* (C) Copyright 2001, 2002 Ralf Baechle
*/
-#include <linux/mm.h>
#include <linux/module.h>
#include <asm/addrspace.h>
#include <asm/byteorder.h>
#include <linux/vmalloc.h>
-#include <linux/io.h>
+#include <asm/cacheflush.h>
+#include <asm/io.h>
+#include <asm/tlbflush.h>
+
+static inline void remap_area_pte(pte_t * pte, unsigned long address,
+ phys_t size, phys_t phys_addr, unsigned long flags)
+{
+ phys_t end;
+ unsigned long pfn;
+ pgprot_t pgprot = __pgprot(_PAGE_GLOBAL | _PAGE_PRESENT | __READABLE
+ | __WRITEABLE | flags);
+
+ address &= ~PMD_MASK;
+ end = address + size;
+ if (end > PMD_SIZE)
+ end = PMD_SIZE;
+ if (address >= end)
+ BUG();
+ pfn = phys_addr >> PAGE_SHIFT;
+ do {
+ if (!pte_none(*pte)) {
+ printk("remap_area_pte: page already exists\n");
+ BUG();
+ }
+ set_pte(pte, pfn_pte(pfn, pgprot));
+ address += PAGE_SIZE;
+ pfn++;
+ pte++;
+ } while (address && (address < end));
+}
+
+static inline int remap_area_pmd(pmd_t * pmd, unsigned long address,
+ phys_t size, phys_t phys_addr, unsigned long flags)
+{
+ phys_t end;
+
+ address &= ~PGDIR_MASK;
+ end = address + size;
+ if (end > PGDIR_SIZE)
+ end = PGDIR_SIZE;
+ phys_addr -= address;
+ if (address >= end)
+ BUG();
+ do {
+ pte_t * pte = pte_alloc_kernel(pmd, address);
+ if (!pte)
+ return -ENOMEM;
+ remap_area_pte(pte, address, end - address, address + phys_addr, flags);
+ address = (address + PMD_SIZE) & PMD_MASK;
+ pmd++;
+ } while (address && (address < end));
+ return 0;
+}
+
+static int remap_area_pages(unsigned long address, phys_t phys_addr,
+ phys_t size, unsigned long flags)
+{
+ int error;
+ pgd_t * dir;
+ unsigned long end = address + size;
+
+ phys_addr -= address;
+ dir = pgd_offset(&init_mm, address);
+ flush_cache_all();
+ if (address >= end)
+ BUG();
+ do {
+ pud_t *pud;
+ pmd_t *pmd;
+
+ error = -ENOMEM;
+ pud = pud_alloc(&init_mm, dir, address);
+ if (!pud)
+ break;
+ pmd = pmd_alloc(&init_mm, pud, address);
+ if (!pmd)
+ break;
+ if (remap_area_pmd(pmd, address, end - address,
+ phys_addr + address, flags))
+ break;
+ error = 0;
+ address = (address + PGDIR_SIZE) & PGDIR_MASK;
+ dir++;
+ } while (address && (address < end));
+ flush_tlb_all();
+ return error;
+}
/*
* Generic mapping function (not visible outside):
@@ -36,7 +121,6 @@ void __iomem * __ioremap(phys_t phys_addr, phys_t size, unsigned long flags)
unsigned long offset;
phys_t last_addr;
void * addr;
- pgprot_t pgprot;
phys_addr = fixup_bigphys_addr(phys_addr, size);
@@ -68,9 +152,6 @@ void __iomem * __ioremap(phys_t phys_addr, phys_t size, unsigned long flags)
return NULL;
}
- pgprot = __pgprot(_PAGE_GLOBAL | _PAGE_PRESENT | __READABLE
- | __WRITEABLE | flags);
-
/*
* Mappings have to be page-aligned
*/
@@ -85,8 +166,7 @@ void __iomem * __ioremap(phys_t phys_addr, phys_t size, unsigned long flags)
if (!area)
return NULL;
addr = area->addr;
- if (ioremap_page_range((unsigned long)addr, (unsigned long)addr + size,
- phys_addr, pgprot)) {
+ if (remap_area_pages((unsigned long) addr, phys_addr, size, flags)) {
vunmap(addr);
return NULL;
}
diff --git a/arch/mips/mm/pg-sb1.c b/arch/mips/mm/pg-sb1.c
index fc3c7878fb45..adb37d0a30ea 100644
--- a/arch/mips/mm/pg-sb1.c
+++ b/arch/mips/mm/pg-sb1.c
@@ -218,8 +218,7 @@ void sb1_dma_init(void)
for (i = 0; i < DM_NUM_CHANNELS; i++) {
const u64 base_val = CPHYSADDR(&page_descr[i]) |
V_DM_DSCR_BASE_RINGSZ(1);
- volatile void *base_reg =
- IOADDR(A_DM_REGISTER(i, R_DM_DSCR_BASE));
+ void *base_reg = IOADDR(A_DM_REGISTER(i, R_DM_DSCR_BASE));
__raw_writeq(base_val, base_reg);
__raw_writeq(base_val | M_DM_DSCR_BASE_RESET, base_reg);
diff --git a/arch/mips/mm/pgtable-32.c b/arch/mips/mm/pgtable-32.c
index 4a61e624b0ec..575e4019227b 100644
--- a/arch/mips/mm/pgtable-32.c
+++ b/arch/mips/mm/pgtable-32.c
@@ -11,6 +11,7 @@
#include <linux/highmem.h>
#include <asm/fixmap.h>
#include <asm/pgtable.h>
+#include <asm/pgalloc.h>
void pgd_init(unsigned long page)
{
diff --git a/arch/mips/mm/pgtable-64.c b/arch/mips/mm/pgtable-64.c
index c46eb651bf09..e4b565aeb008 100644
--- a/arch/mips/mm/pgtable-64.c
+++ b/arch/mips/mm/pgtable-64.c
@@ -10,6 +10,7 @@
#include <linux/mm.h>
#include <asm/fixmap.h>
#include <asm/pgtable.h>
+#include <asm/pgalloc.h>
void pgd_init(unsigned long page)
{