diff options
author | Ralf Baechle <ralf@linux-mips.org> | 2014-05-28 13:00:14 -0400 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 2014-05-29 09:08:23 -0400 |
commit | 2e2d663d2dd64ffe9855be0b35aa221c9b8139f2 (patch) | |
tree | 508667aa6fbab564e7875d3953671265d0176e69 /arch/mips/mm | |
parent | 5ec79bf919ddb53fd98893b7217897c839aa19cc (diff) | |
parent | 322014531e1fac4674b8eef67e4f80aca1e9f003 (diff) |
Merge branch 'wip-mips-pm' of https://github.com/paulburton/linux into mips-for-linux-next
Diffstat (limited to 'arch/mips/mm')
-rw-r--r-- | arch/mips/mm/c-r4k.c | 24 | ||||
-rw-r--r-- | arch/mips/mm/init.c | 14 | ||||
-rw-r--r-- | arch/mips/mm/tlb-r4k.c | 34 | ||||
-rw-r--r-- | arch/mips/mm/uasm-micromips.c | 2 | ||||
-rw-r--r-- | arch/mips/mm/uasm-mips.c | 4 | ||||
-rw-r--r-- | arch/mips/mm/uasm.c | 31 |
6 files changed, 100 insertions, 9 deletions
diff --git a/arch/mips/mm/c-r4k.c b/arch/mips/mm/c-r4k.c index 5c2128283ba6..587a14874f98 100644 --- a/arch/mips/mm/c-r4k.c +++ b/arch/mips/mm/c-r4k.c | |||
@@ -7,6 +7,7 @@ | |||
7 | * Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002 Ralf Baechle (ralf@gnu.org) | 7 | * Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002 Ralf Baechle (ralf@gnu.org) |
8 | * Copyright (C) 1999, 2000 Silicon Graphics, Inc. | 8 | * Copyright (C) 1999, 2000 Silicon Graphics, Inc. |
9 | */ | 9 | */ |
10 | #include <linux/cpu_pm.h> | ||
10 | #include <linux/hardirq.h> | 11 | #include <linux/hardirq.h> |
11 | #include <linux/init.h> | 12 | #include <linux/init.h> |
12 | #include <linux/highmem.h> | 13 | #include <linux/highmem.h> |
@@ -1643,3 +1644,26 @@ void r4k_cache_init(void) | |||
1643 | coherency_setup(); | 1644 | coherency_setup(); |
1644 | board_cache_error_setup = r4k_cache_error_setup; | 1645 | board_cache_error_setup = r4k_cache_error_setup; |
1645 | } | 1646 | } |
1647 | |||
1648 | static int r4k_cache_pm_notifier(struct notifier_block *self, unsigned long cmd, | ||
1649 | void *v) | ||
1650 | { | ||
1651 | switch (cmd) { | ||
1652 | case CPU_PM_ENTER_FAILED: | ||
1653 | case CPU_PM_EXIT: | ||
1654 | coherency_setup(); | ||
1655 | break; | ||
1656 | } | ||
1657 | |||
1658 | return NOTIFY_OK; | ||
1659 | } | ||
1660 | |||
1661 | static struct notifier_block r4k_cache_pm_notifier_block = { | ||
1662 | .notifier_call = r4k_cache_pm_notifier, | ||
1663 | }; | ||
1664 | |||
1665 | int __init r4k_cache_init_pm(void) | ||
1666 | { | ||
1667 | return cpu_pm_register_notifier(&r4k_cache_pm_notifier_block); | ||
1668 | } | ||
1669 | arch_initcall(r4k_cache_init_pm); | ||
diff --git a/arch/mips/mm/init.c b/arch/mips/mm/init.c index 609a0cd749ff..6e4413330e36 100644 --- a/arch/mips/mm/init.c +++ b/arch/mips/mm/init.c | |||
@@ -79,7 +79,7 @@ void setup_zero_pages(void) | |||
79 | zero_page_mask = ((PAGE_SIZE << order) - 1) & PAGE_MASK; | 79 | zero_page_mask = ((PAGE_SIZE << order) - 1) & PAGE_MASK; |
80 | } | 80 | } |
81 | 81 | ||
82 | void *kmap_coherent(struct page *page, unsigned long addr) | 82 | static void *__kmap_pgprot(struct page *page, unsigned long addr, pgprot_t prot) |
83 | { | 83 | { |
84 | enum fixed_addresses idx; | 84 | enum fixed_addresses idx; |
85 | unsigned long vaddr, flags, entrylo; | 85 | unsigned long vaddr, flags, entrylo; |
@@ -93,7 +93,7 @@ void *kmap_coherent(struct page *page, unsigned long addr) | |||
93 | idx = (addr >> PAGE_SHIFT) & (FIX_N_COLOURS - 1); | 93 | idx = (addr >> PAGE_SHIFT) & (FIX_N_COLOURS - 1); |
94 | idx += in_interrupt() ? FIX_N_COLOURS : 0; | 94 | idx += in_interrupt() ? FIX_N_COLOURS : 0; |
95 | vaddr = __fix_to_virt(FIX_CMAP_END - idx); | 95 | vaddr = __fix_to_virt(FIX_CMAP_END - idx); |
96 | pte = mk_pte(page, PAGE_KERNEL); | 96 | pte = mk_pte(page, prot); |
97 | #if defined(CONFIG_64BIT_PHYS_ADDR) && defined(CONFIG_CPU_MIPS32) | 97 | #if defined(CONFIG_64BIT_PHYS_ADDR) && defined(CONFIG_CPU_MIPS32) |
98 | entrylo = pte.pte_high; | 98 | entrylo = pte.pte_high; |
99 | #else | 99 | #else |
@@ -117,6 +117,16 @@ void *kmap_coherent(struct page *page, unsigned long addr) | |||
117 | return (void*) vaddr; | 117 | return (void*) vaddr; |
118 | } | 118 | } |
119 | 119 | ||
120 | void *kmap_coherent(struct page *page, unsigned long addr) | ||
121 | { | ||
122 | return __kmap_pgprot(page, addr, PAGE_KERNEL); | ||
123 | } | ||
124 | |||
125 | void *kmap_noncoherent(struct page *page, unsigned long addr) | ||
126 | { | ||
127 | return __kmap_pgprot(page, addr, PAGE_KERNEL_NC); | ||
128 | } | ||
129 | |||
120 | void kunmap_coherent(void) | 130 | void kunmap_coherent(void) |
121 | { | 131 | { |
122 | unsigned int wired; | 132 | unsigned int wired; |
diff --git a/arch/mips/mm/tlb-r4k.c b/arch/mips/mm/tlb-r4k.c index 403fa804e4f4..3914e27456f2 100644 --- a/arch/mips/mm/tlb-r4k.c +++ b/arch/mips/mm/tlb-r4k.c | |||
@@ -8,6 +8,7 @@ | |||
8 | * Carsten Langgaard, carstenl@mips.com | 8 | * Carsten Langgaard, carstenl@mips.com |
9 | * Copyright (C) 2002 MIPS Technologies, Inc. All rights reserved. | 9 | * Copyright (C) 2002 MIPS Technologies, Inc. All rights reserved. |
10 | */ | 10 | */ |
11 | #include <linux/cpu_pm.h> | ||
11 | #include <linux/init.h> | 12 | #include <linux/init.h> |
12 | #include <linux/sched.h> | 13 | #include <linux/sched.h> |
13 | #include <linux/smp.h> | 14 | #include <linux/smp.h> |
@@ -399,7 +400,10 @@ static int __init set_ntlb(char *str) | |||
399 | 400 | ||
400 | __setup("ntlb=", set_ntlb); | 401 | __setup("ntlb=", set_ntlb); |
401 | 402 | ||
402 | void tlb_init(void) | 403 | /* |
404 | * Configure TLB (for init or after a CPU has been powered off). | ||
405 | */ | ||
406 | static void r4k_tlb_configure(void) | ||
403 | { | 407 | { |
404 | /* | 408 | /* |
405 | * You should never change this register: | 409 | * You should never change this register: |
@@ -431,6 +435,11 @@ void tlb_init(void) | |||
431 | local_flush_tlb_all(); | 435 | local_flush_tlb_all(); |
432 | 436 | ||
433 | /* Did I tell you that ARC SUCKS? */ | 437 | /* Did I tell you that ARC SUCKS? */ |
438 | } | ||
439 | |||
440 | void tlb_init(void) | ||
441 | { | ||
442 | r4k_tlb_configure(); | ||
434 | 443 | ||
435 | if (ntlb) { | 444 | if (ntlb) { |
436 | if (ntlb > 1 && ntlb <= current_cpu_data.tlbsize) { | 445 | if (ntlb > 1 && ntlb <= current_cpu_data.tlbsize) { |
@@ -444,3 +453,26 @@ void tlb_init(void) | |||
444 | 453 | ||
445 | build_tlb_refill_handler(); | 454 | build_tlb_refill_handler(); |
446 | } | 455 | } |
456 | |||
457 | static int r4k_tlb_pm_notifier(struct notifier_block *self, unsigned long cmd, | ||
458 | void *v) | ||
459 | { | ||
460 | switch (cmd) { | ||
461 | case CPU_PM_ENTER_FAILED: | ||
462 | case CPU_PM_EXIT: | ||
463 | r4k_tlb_configure(); | ||
464 | break; | ||
465 | } | ||
466 | |||
467 | return NOTIFY_OK; | ||
468 | } | ||
469 | |||
470 | static struct notifier_block r4k_tlb_pm_notifier_block = { | ||
471 | .notifier_call = r4k_tlb_pm_notifier, | ||
472 | }; | ||
473 | |||
474 | static int __init r4k_tlb_init_pm(void) | ||
475 | { | ||
476 | return cpu_pm_register_notifier(&r4k_tlb_pm_notifier_block); | ||
477 | } | ||
478 | arch_initcall(r4k_tlb_init_pm); | ||
diff --git a/arch/mips/mm/uasm-micromips.c b/arch/mips/mm/uasm-micromips.c index b8d580ca02e5..bcbcf4ae69b7 100644 --- a/arch/mips/mm/uasm-micromips.c +++ b/arch/mips/mm/uasm-micromips.c | |||
@@ -99,10 +99,12 @@ static struct insn insn_table_MM[] = { | |||
99 | { insn_rotr, M(mm_pool32a_op, 0, 0, 0, 0, mm_rotr_op), RT | RS | RD }, | 99 | { insn_rotr, M(mm_pool32a_op, 0, 0, 0, 0, mm_rotr_op), RT | RS | RD }, |
100 | { insn_subu, M(mm_pool32a_op, 0, 0, 0, 0, mm_subu32_op), RT | RS | RD }, | 100 | { insn_subu, M(mm_pool32a_op, 0, 0, 0, 0, mm_subu32_op), RT | RS | RD }, |
101 | { insn_sw, M(mm_sw32_op, 0, 0, 0, 0, 0), RT | RS | SIMM }, | 101 | { insn_sw, M(mm_sw32_op, 0, 0, 0, 0, 0), RT | RS | SIMM }, |
102 | { insn_sync, M(mm_pool32a_op, 0, 0, 0, mm_sync_op, mm_pool32axf_op), RS }, | ||
102 | { insn_tlbp, M(mm_pool32a_op, 0, 0, 0, mm_tlbp_op, mm_pool32axf_op), 0 }, | 103 | { insn_tlbp, M(mm_pool32a_op, 0, 0, 0, mm_tlbp_op, mm_pool32axf_op), 0 }, |
103 | { insn_tlbr, M(mm_pool32a_op, 0, 0, 0, mm_tlbr_op, mm_pool32axf_op), 0 }, | 104 | { insn_tlbr, M(mm_pool32a_op, 0, 0, 0, mm_tlbr_op, mm_pool32axf_op), 0 }, |
104 | { insn_tlbwi, M(mm_pool32a_op, 0, 0, 0, mm_tlbwi_op, mm_pool32axf_op), 0 }, | 105 | { insn_tlbwi, M(mm_pool32a_op, 0, 0, 0, mm_tlbwi_op, mm_pool32axf_op), 0 }, |
105 | { insn_tlbwr, M(mm_pool32a_op, 0, 0, 0, mm_tlbwr_op, mm_pool32axf_op), 0 }, | 106 | { insn_tlbwr, M(mm_pool32a_op, 0, 0, 0, mm_tlbwr_op, mm_pool32axf_op), 0 }, |
107 | { insn_wait, M(mm_pool32a_op, 0, 0, 0, mm_wait_op, mm_pool32axf_op), SCIMM }, | ||
106 | { insn_xor, M(mm_pool32a_op, 0, 0, 0, 0, mm_xor32_op), RT | RS | RD }, | 108 | { insn_xor, M(mm_pool32a_op, 0, 0, 0, 0, mm_xor32_op), RT | RS | RD }, |
107 | { insn_xori, M(mm_xori32_op, 0, 0, 0, 0, 0), RT | RS | UIMM }, | 109 | { insn_xori, M(mm_xori32_op, 0, 0, 0, 0, 0), RT | RS | UIMM }, |
108 | { insn_dins, 0, 0 }, | 110 | { insn_dins, 0, 0 }, |
diff --git a/arch/mips/mm/uasm-mips.c b/arch/mips/mm/uasm-mips.c index 3abd609518c9..4a2fc82fcd4f 100644 --- a/arch/mips/mm/uasm-mips.c +++ b/arch/mips/mm/uasm-mips.c | |||
@@ -82,6 +82,7 @@ static struct insn insn_table[] = { | |||
82 | { insn_ins, M(spec3_op, 0, 0, 0, 0, ins_op), RS | RT | RD | RE }, | 82 | { insn_ins, M(spec3_op, 0, 0, 0, 0, ins_op), RS | RT | RD | RE }, |
83 | { insn_j, M(j_op, 0, 0, 0, 0, 0), JIMM }, | 83 | { insn_j, M(j_op, 0, 0, 0, 0, 0), JIMM }, |
84 | { insn_jal, M(jal_op, 0, 0, 0, 0, 0), JIMM }, | 84 | { insn_jal, M(jal_op, 0, 0, 0, 0, 0), JIMM }, |
85 | { insn_jalr, M(spec_op, 0, 0, 0, 0, jalr_op), RS | RD }, | ||
85 | { insn_j, M(j_op, 0, 0, 0, 0, 0), JIMM }, | 86 | { insn_j, M(j_op, 0, 0, 0, 0, 0), JIMM }, |
86 | { insn_jr, M(spec_op, 0, 0, 0, 0, jr_op), RS }, | 87 | { insn_jr, M(spec_op, 0, 0, 0, 0, jr_op), RS }, |
87 | { insn_ld, M(ld_op, 0, 0, 0, 0, 0), RS | RT | SIMM }, | 88 | { insn_ld, M(ld_op, 0, 0, 0, 0, 0), RS | RT | SIMM }, |
@@ -106,13 +107,16 @@ static struct insn insn_table[] = { | |||
106 | { insn_srl, M(spec_op, 0, 0, 0, 0, srl_op), RT | RD | RE }, | 107 | { insn_srl, M(spec_op, 0, 0, 0, 0, srl_op), RT | RD | RE }, |
107 | { insn_subu, M(spec_op, 0, 0, 0, 0, subu_op), RS | RT | RD }, | 108 | { insn_subu, M(spec_op, 0, 0, 0, 0, subu_op), RS | RT | RD }, |
108 | { insn_sw, M(sw_op, 0, 0, 0, 0, 0), RS | RT | SIMM }, | 109 | { insn_sw, M(sw_op, 0, 0, 0, 0, 0), RS | RT | SIMM }, |
110 | { insn_sync, M(spec_op, 0, 0, 0, 0, sync_op), RE }, | ||
109 | { insn_syscall, M(spec_op, 0, 0, 0, 0, syscall_op), SCIMM}, | 111 | { insn_syscall, M(spec_op, 0, 0, 0, 0, syscall_op), SCIMM}, |
110 | { insn_tlbp, M(cop0_op, cop_op, 0, 0, 0, tlbp_op), 0 }, | 112 | { insn_tlbp, M(cop0_op, cop_op, 0, 0, 0, tlbp_op), 0 }, |
111 | { insn_tlbr, M(cop0_op, cop_op, 0, 0, 0, tlbr_op), 0 }, | 113 | { insn_tlbr, M(cop0_op, cop_op, 0, 0, 0, tlbr_op), 0 }, |
112 | { insn_tlbwi, M(cop0_op, cop_op, 0, 0, 0, tlbwi_op), 0 }, | 114 | { insn_tlbwi, M(cop0_op, cop_op, 0, 0, 0, tlbwi_op), 0 }, |
113 | { insn_tlbwr, M(cop0_op, cop_op, 0, 0, 0, tlbwr_op), 0 }, | 115 | { insn_tlbwr, M(cop0_op, cop_op, 0, 0, 0, tlbwr_op), 0 }, |
116 | { insn_wait, M(cop0_op, cop_op, 0, 0, 0, wait_op), SCIMM }, | ||
114 | { insn_xori, M(xori_op, 0, 0, 0, 0, 0), RS | RT | UIMM }, | 117 | { insn_xori, M(xori_op, 0, 0, 0, 0, 0), RS | RT | UIMM }, |
115 | { insn_xor, M(spec_op, 0, 0, 0, 0, xor_op), RS | RT | RD }, | 118 | { insn_xor, M(spec_op, 0, 0, 0, 0, xor_op), RS | RT | RD }, |
119 | { insn_yield, M(spec3_op, 0, 0, 0, 0, yield_op), RS | RD }, | ||
116 | { insn_invalid, 0, 0 } | 120 | { insn_invalid, 0, 0 } |
117 | }; | 121 | }; |
118 | 122 | ||
diff --git a/arch/mips/mm/uasm.c b/arch/mips/mm/uasm.c index b9d14b6c7f58..55a1fdfb76ef 100644 --- a/arch/mips/mm/uasm.c +++ b/arch/mips/mm/uasm.c | |||
@@ -49,12 +49,12 @@ enum opcode { | |||
49 | insn_bne, insn_cache, insn_daddiu, insn_daddu, insn_dins, insn_dinsm, | 49 | insn_bne, insn_cache, insn_daddiu, insn_daddu, insn_dins, insn_dinsm, |
50 | insn_dmfc0, insn_dmtc0, insn_drotr, insn_drotr32, insn_dsll, | 50 | insn_dmfc0, insn_dmtc0, insn_drotr, insn_drotr32, insn_dsll, |
51 | insn_dsll32, insn_dsra, insn_dsrl, insn_dsrl32, insn_dsubu, insn_eret, | 51 | insn_dsll32, insn_dsra, insn_dsrl, insn_dsrl32, insn_dsubu, insn_eret, |
52 | insn_ext, insn_ins, insn_j, insn_jal, insn_jr, insn_ld, insn_ldx, | 52 | insn_ext, insn_ins, insn_j, insn_jal, insn_jalr, insn_jr, insn_ld, |
53 | insn_ll, insn_lld, insn_lui, insn_lw, insn_lwx, insn_mfc0, insn_mtc0, | 53 | insn_ldx, insn_ll, insn_lld, insn_lui, insn_lw, insn_lwx, insn_mfc0, |
54 | insn_or, insn_ori, insn_pref, insn_rfe, insn_rotr, insn_sc, insn_scd, | 54 | insn_mtc0, insn_or, insn_ori, insn_pref, insn_rfe, insn_rotr, insn_sc, |
55 | insn_sd, insn_sll, insn_sra, insn_srl, insn_subu, insn_sw, | 55 | insn_scd, insn_sd, insn_sll, insn_sra, insn_srl, insn_subu, insn_sw, |
56 | insn_syscall, insn_tlbp, insn_tlbr, insn_tlbwi, insn_tlbwr, insn_xor, | 56 | insn_sync, insn_syscall, insn_tlbp, insn_tlbr, insn_tlbwi, insn_tlbwr, |
57 | insn_xori, | 57 | insn_wait, insn_xor, insn_xori, insn_yield, |
58 | }; | 58 | }; |
59 | 59 | ||
60 | struct insn { | 60 | struct insn { |
@@ -200,6 +200,13 @@ Ip_u1u2(op) \ | |||
200 | } \ | 200 | } \ |
201 | UASM_EXPORT_SYMBOL(uasm_i##op); | 201 | UASM_EXPORT_SYMBOL(uasm_i##op); |
202 | 202 | ||
203 | #define I_u2u1(op) \ | ||
204 | Ip_u1u2(op) \ | ||
205 | { \ | ||
206 | build_insn(buf, insn##op, b, a); \ | ||
207 | } \ | ||
208 | UASM_EXPORT_SYMBOL(uasm_i##op); | ||
209 | |||
203 | #define I_u1s2(op) \ | 210 | #define I_u1s2(op) \ |
204 | Ip_u1s2(op) \ | 211 | Ip_u1s2(op) \ |
205 | { \ | 212 | { \ |
@@ -250,6 +257,7 @@ I_u2u1msbdu3(_ext) | |||
250 | I_u2u1msbu3(_ins) | 257 | I_u2u1msbu3(_ins) |
251 | I_u1(_j) | 258 | I_u1(_j) |
252 | I_u1(_jal) | 259 | I_u1(_jal) |
260 | I_u2u1(_jalr) | ||
253 | I_u1(_jr) | 261 | I_u1(_jr) |
254 | I_u2s3u1(_ld) | 262 | I_u2s3u1(_ld) |
255 | I_u2s3u1(_ll) | 263 | I_u2s3u1(_ll) |
@@ -270,12 +278,15 @@ I_u2u1u3(_srl) | |||
270 | I_u2u1u3(_rotr) | 278 | I_u2u1u3(_rotr) |
271 | I_u3u1u2(_subu) | 279 | I_u3u1u2(_subu) |
272 | I_u2s3u1(_sw) | 280 | I_u2s3u1(_sw) |
281 | I_u1(_sync) | ||
273 | I_0(_tlbp) | 282 | I_0(_tlbp) |
274 | I_0(_tlbr) | 283 | I_0(_tlbr) |
275 | I_0(_tlbwi) | 284 | I_0(_tlbwi) |
276 | I_0(_tlbwr) | 285 | I_0(_tlbwr) |
286 | I_u1(_wait); | ||
277 | I_u3u1u2(_xor) | 287 | I_u3u1u2(_xor) |
278 | I_u2u1u3(_xori) | 288 | I_u2u1u3(_xori) |
289 | I_u2u1(_yield) | ||
279 | I_u2u1msbu3(_dins); | 290 | I_u2u1msbu3(_dins); |
280 | I_u2u1msb32u3(_dinsm); | 291 | I_u2u1msb32u3(_dinsm); |
281 | I_u1(_syscall); | 292 | I_u1(_syscall); |
@@ -469,6 +480,14 @@ void ISAFUNC(uasm_il_b)(u32 **p, struct uasm_reloc **r, int lid) | |||
469 | } | 480 | } |
470 | UASM_EXPORT_SYMBOL(ISAFUNC(uasm_il_b)); | 481 | UASM_EXPORT_SYMBOL(ISAFUNC(uasm_il_b)); |
471 | 482 | ||
483 | void ISAFUNC(uasm_il_beq)(u32 **p, struct uasm_reloc **r, unsigned int r1, | ||
484 | unsigned int r2, int lid) | ||
485 | { | ||
486 | uasm_r_mips_pc16(r, *p, lid); | ||
487 | ISAFUNC(uasm_i_beq)(p, r1, r2, 0); | ||
488 | } | ||
489 | UASM_EXPORT_SYMBOL(ISAFUNC(uasm_il_beq)); | ||
490 | |||
472 | void ISAFUNC(uasm_il_beqz)(u32 **p, struct uasm_reloc **r, unsigned int reg, | 491 | void ISAFUNC(uasm_il_beqz)(u32 **p, struct uasm_reloc **r, unsigned int reg, |
473 | int lid) | 492 | int lid) |
474 | { | 493 | { |