aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sh
diff options
context:
space:
mode:
authorIngo Molnar <mingo@elte.hu>2009-10-15 02:07:26 -0400
committerIngo Molnar <mingo@elte.hu>2009-10-15 02:07:30 -0400
commita0738a688d1105cbf8d71868a1e020c6cdf42d4c (patch)
tree2cad553a9def773ce79b8fc793f89c0634187109 /arch/sh
parent89ccf465abe6b20d804a63ae20307970c441369d (diff)
parenta3ccf63ee643ef243cbf8918da8b3f9238f10029 (diff)
Merge branch 'linus' into x86/urgent
Merge reason: pull in latest, to be able to revert a patch there. Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'arch/sh')
-rw-r--r--arch/sh/boards/board-magicpanelr2.c2
-rw-r--r--arch/sh/boards/mach-dreamcast/setup.c2
-rw-r--r--arch/sh/boards/mach-ecovec24/setup.c63
-rw-r--r--arch/sh/kernel/cpu/sh3/entry.S2
-rw-r--r--arch/sh/kernel/entry-common.S2
-rw-r--r--arch/sh/kernel/ftrace.c37
-rw-r--r--arch/sh/kernel/io_generic.c3
-rw-r--r--arch/sh/kernel/machvec.c3
-rw-r--r--arch/sh/kernel/setup.c2
-rw-r--r--arch/sh/kernel/sh_ksyms_32.c1
-rw-r--r--arch/sh/kernel/signal_32.c9
-rw-r--r--arch/sh/kernel/smp.c2
-rw-r--r--arch/sh/kernel/traps_32.c11
-rw-r--r--arch/sh/mm/cache-sh4.c2
-rw-r--r--arch/sh/mm/cache-sh7705.c4
-rw-r--r--arch/sh/mm/cache.c2
-rw-r--r--arch/sh/mm/ioremap_32.c2
-rw-r--r--arch/sh/mm/pmb.c37
18 files changed, 147 insertions, 39 deletions
diff --git a/arch/sh/boards/board-magicpanelr2.c b/arch/sh/boards/board-magicpanelr2.c
index 0a37c8bfc959..99ffc5f1c0dd 100644
--- a/arch/sh/boards/board-magicpanelr2.c
+++ b/arch/sh/boards/board-magicpanelr2.c
@@ -205,8 +205,6 @@ static void __init setup_port_multiplexing(void)
205 205
206static void __init mpr2_setup(char **cmdline_p) 206static void __init mpr2_setup(char **cmdline_p)
207{ 207{
208 __set_io_port_base(0xa0000000);
209
210 /* set Pin Select Register A: 208 /* set Pin Select Register A:
211 * /PCC_CD1, /PCC_CD2, PCC_BVD1, PCC_BVD2, 209 * /PCC_CD1, /PCC_CD2, PCC_BVD1, PCC_BVD2,
212 * /IOIS16, IRQ4, IRQ5, USB1d_SUSPEND 210 * /IOIS16, IRQ4, IRQ5, USB1d_SUSPEND
diff --git a/arch/sh/boards/mach-dreamcast/setup.c b/arch/sh/boards/mach-dreamcast/setup.c
index ebe99227d4e6..a4b7402d6176 100644
--- a/arch/sh/boards/mach-dreamcast/setup.c
+++ b/arch/sh/boards/mach-dreamcast/setup.c
@@ -42,8 +42,6 @@ static void __init dreamcast_setup(char **cmdline_p)
42 /* Acknowledge any previous events */ 42 /* Acknowledge any previous events */
43 /* XXX */ 43 /* XXX */
44 44
45 __set_io_port_base(0xa0000000);
46
47 /* Assign all virtual IRQs to the System ASIC int. handler */ 45 /* Assign all virtual IRQs to the System ASIC int. handler */
48 for (i = HW_EVENT_IRQ_BASE; i < HW_EVENT_IRQ_MAX; i++) 46 for (i = HW_EVENT_IRQ_BASE; i < HW_EVENT_IRQ_MAX; i++)
49 set_irq_chip_and_handler(i, &systemasic_int, 47 set_irq_chip_and_handler(i, &systemasic_int,
diff --git a/arch/sh/boards/mach-ecovec24/setup.c b/arch/sh/boards/mach-ecovec24/setup.c
index 5f9881e16e2f..3b1ceb46fa54 100644
--- a/arch/sh/boards/mach-ecovec24/setup.c
+++ b/arch/sh/boards/mach-ecovec24/setup.c
@@ -18,6 +18,7 @@
18#include <linux/delay.h> 18#include <linux/delay.h>
19#include <linux/usb/r8a66597.h> 19#include <linux/usb/r8a66597.h>
20#include <linux/i2c.h> 20#include <linux/i2c.h>
21#include <linux/i2c/tsc2007.h>
21#include <linux/input.h> 22#include <linux/input.h>
22#include <video/sh_mobile_lcdc.h> 23#include <video/sh_mobile_lcdc.h>
23#include <media/sh_mobile_ceu.h> 24#include <media/sh_mobile_ceu.h>
@@ -38,6 +39,20 @@
38 * 0x1800_0000 MFI 16bit 39 * 0x1800_0000 MFI 16bit
39 */ 40 */
40 41
42/* SWITCH
43 *------------------------------
44 * DS2[1] = FlashROM write protect ON : write protect
45 * OFF : No write protect
46 * DS2[2] = RMII / TS, SCIF ON : RMII
47 * OFF : TS, SCIF3
48 * DS2[3] = Camera / Video ON : Camera
49 * OFF : NTSC/PAL (IN)
50 * DS2[5] = NTSC_OUT Clock ON : On board OSC
51 * OFF : SH7724 DV_CLK
52 * DS2[6-7] = MMC / SD ON-OFF : SD
53 * OFF-ON : MMC
54 */
55
41/* Heartbeat */ 56/* Heartbeat */
42static unsigned char led_pos[] = { 0, 1, 2, 3 }; 57static unsigned char led_pos[] = { 0, 1, 2, 3 };
43static struct heartbeat_data heartbeat_data = { 58static struct heartbeat_data heartbeat_data = {
@@ -70,7 +85,7 @@ static struct mtd_partition nor_flash_partitions[] = {
70 .name = "boot loader", 85 .name = "boot loader",
71 .offset = 0, 86 .offset = 0,
72 .size = (5 * 1024 * 1024), 87 .size = (5 * 1024 * 1024),
73 .mask_flags = MTD_CAP_ROM, 88 .mask_flags = MTD_WRITEABLE, /* force read-only */
74 }, { 89 }, {
75 .name = "free-area", 90 .name = "free-area",
76 .offset = MTDPART_OFS_APPEND, 91 .offset = MTDPART_OFS_APPEND,
@@ -376,6 +391,43 @@ static struct platform_device keysc_device = {
376 }, 391 },
377}; 392};
378 393
394/* TouchScreen */
395#define IRQ0 32
396static int ts_get_pendown_state(void)
397{
398 int val = 0;
399 gpio_free(GPIO_FN_INTC_IRQ0);
400 gpio_request(GPIO_PTZ0, NULL);
401 gpio_direction_input(GPIO_PTZ0);
402
403 val = gpio_get_value(GPIO_PTZ0);
404
405 gpio_free(GPIO_PTZ0);
406 gpio_request(GPIO_FN_INTC_IRQ0, NULL);
407
408 return val ? 0 : 1;
409}
410
411static int ts_init(void)
412{
413 gpio_request(GPIO_FN_INTC_IRQ0, NULL);
414 return 0;
415}
416
417struct tsc2007_platform_data tsc2007_info = {
418 .model = 2007,
419 .x_plate_ohms = 180,
420 .get_pendown_state = ts_get_pendown_state,
421 .init_platform_hw = ts_init,
422};
423
424static struct i2c_board_info ts_i2c_clients = {
425 I2C_BOARD_INFO("tsc2007", 0x48),
426 .type = "tsc2007",
427 .platform_data = &tsc2007_info,
428 .irq = IRQ0,
429};
430
379static struct platform_device *ecovec_devices[] __initdata = { 431static struct platform_device *ecovec_devices[] __initdata = {
380 &heartbeat_device, 432 &heartbeat_device,
381 &nor_flash_device, 433 &nor_flash_device,
@@ -460,6 +512,11 @@ static void __init sh_eth_init(void)
460#define IODRIVEA 0xA405018A 512#define IODRIVEA 0xA405018A
461static int __init arch_setup(void) 513static int __init arch_setup(void)
462{ 514{
515 /* enable STATUS0, STATUS2 and PDSTATUS */
516 gpio_request(GPIO_FN_STATUS0, NULL);
517 gpio_request(GPIO_FN_STATUS2, NULL);
518 gpio_request(GPIO_FN_PDSTATUS, NULL);
519
463 /* enable SCIFA0 */ 520 /* enable SCIFA0 */
464 gpio_request(GPIO_FN_SCIF0_TXD, NULL); 521 gpio_request(GPIO_FN_SCIF0_TXD, NULL);
465 gpio_request(GPIO_FN_SCIF0_RXD, NULL); 522 gpio_request(GPIO_FN_SCIF0_RXD, NULL);
@@ -590,6 +647,10 @@ static int __init arch_setup(void)
590 */ 647 */
591 gpio_request(GPIO_PTF4, NULL); 648 gpio_request(GPIO_PTF4, NULL);
592 gpio_direction_output(GPIO_PTF4, 1); 649 gpio_direction_output(GPIO_PTF4, 1);
650
651 /* enable TouchScreen */
652 i2c_register_board_info(0, &ts_i2c_clients, 1);
653 set_irq_type(IRQ0, IRQ_TYPE_LEVEL_LOW);
593 } 654 }
594 655
595 /* enable CEU0 */ 656 /* enable CEU0 */
diff --git a/arch/sh/kernel/cpu/sh3/entry.S b/arch/sh/kernel/cpu/sh3/entry.S
index 0151933e5253..bb407ef0b91e 100644
--- a/arch/sh/kernel/cpu/sh3/entry.S
+++ b/arch/sh/kernel/cpu/sh3/entry.S
@@ -152,8 +152,6 @@ call_do_page_fault:
152 mov.l 1f, r0 152 mov.l 1f, r0
153 mov.l @r0, r6 153 mov.l @r0, r6
154 154
155 sti
156
157 mov.l 3f, r0 155 mov.l 3f, r0
158 mov.l 4f, r1 156 mov.l 4f, r1
159 mov r15, r4 157 mov r15, r4
diff --git a/arch/sh/kernel/entry-common.S b/arch/sh/kernel/entry-common.S
index 68d9223b145e..3eb84931d2aa 100644
--- a/arch/sh/kernel/entry-common.S
+++ b/arch/sh/kernel/entry-common.S
@@ -121,7 +121,7 @@ noresched:
121ENTRY(resume_userspace) 121ENTRY(resume_userspace)
122 ! r8: current_thread_info 122 ! r8: current_thread_info
123 cli 123 cli
124 TRACE_IRQS_OfF 124 TRACE_IRQS_OFF
125 mov.l @(TI_FLAGS,r8), r0 ! current_thread_info->flags 125 mov.l @(TI_FLAGS,r8), r0 ! current_thread_info->flags
126 tst #(_TIF_WORK_MASK & 0xff), r0 126 tst #(_TIF_WORK_MASK & 0xff), r0
127 bt/s __restore_all 127 bt/s __restore_all
diff --git a/arch/sh/kernel/ftrace.c b/arch/sh/kernel/ftrace.c
index a3dcc6d5d253..2c48e267256e 100644
--- a/arch/sh/kernel/ftrace.c
+++ b/arch/sh/kernel/ftrace.c
@@ -291,31 +291,48 @@ struct syscall_metadata *syscall_nr_to_meta(int nr)
291 return syscalls_metadata[nr]; 291 return syscalls_metadata[nr];
292} 292}
293 293
294void arch_init_ftrace_syscalls(void) 294int syscall_name_to_nr(char *name)
295{
296 int i;
297
298 if (!syscalls_metadata)
299 return -1;
300 for (i = 0; i < NR_syscalls; i++)
301 if (syscalls_metadata[i])
302 if (!strcmp(syscalls_metadata[i]->name, name))
303 return i;
304 return -1;
305}
306
307void set_syscall_enter_id(int num, int id)
308{
309 syscalls_metadata[num]->enter_id = id;
310}
311
312void set_syscall_exit_id(int num, int id)
313{
314 syscalls_metadata[num]->exit_id = id;
315}
316
317static int __init arch_init_ftrace_syscalls(void)
295{ 318{
296 int i; 319 int i;
297 struct syscall_metadata *meta; 320 struct syscall_metadata *meta;
298 unsigned long **psys_syscall_table = &sys_call_table; 321 unsigned long **psys_syscall_table = &sys_call_table;
299 static atomic_t refs;
300
301 if (atomic_inc_return(&refs) != 1)
302 goto end;
303 322
304 syscalls_metadata = kzalloc(sizeof(*syscalls_metadata) * 323 syscalls_metadata = kzalloc(sizeof(*syscalls_metadata) *
305 FTRACE_SYSCALL_MAX, GFP_KERNEL); 324 FTRACE_SYSCALL_MAX, GFP_KERNEL);
306 if (!syscalls_metadata) { 325 if (!syscalls_metadata) {
307 WARN_ON(1); 326 WARN_ON(1);
308 return; 327 return -ENOMEM;
309 } 328 }
310 329
311 for (i = 0; i < FTRACE_SYSCALL_MAX; i++) { 330 for (i = 0; i < FTRACE_SYSCALL_MAX; i++) {
312 meta = find_syscall_meta(psys_syscall_table[i]); 331 meta = find_syscall_meta(psys_syscall_table[i]);
313 syscalls_metadata[i] = meta; 332 syscalls_metadata[i] = meta;
314 } 333 }
315 return;
316 334
317 /* Paranoid: avoid overflow */ 335 return 0;
318end:
319 atomic_dec(&refs);
320} 336}
337arch_initcall(arch_init_ftrace_syscalls);
321#endif /* CONFIG_FTRACE_SYSCALLS */ 338#endif /* CONFIG_FTRACE_SYSCALLS */
diff --git a/arch/sh/kernel/io_generic.c b/arch/sh/kernel/io_generic.c
index 4ff507239286..b8fa6524760a 100644
--- a/arch/sh/kernel/io_generic.c
+++ b/arch/sh/kernel/io_generic.c
@@ -147,6 +147,9 @@ void generic_outsl(unsigned long port, const void *src, unsigned long count)
147 147
148void __iomem *generic_ioport_map(unsigned long addr, unsigned int size) 148void __iomem *generic_ioport_map(unsigned long addr, unsigned int size)
149{ 149{
150 if (PXSEG(addr) >= P1SEG)
151 return (void __iomem *)addr;
152
150 return (void __iomem *)(addr + generic_io_base); 153 return (void __iomem *)(addr + generic_io_base);
151} 154}
152 155
diff --git a/arch/sh/kernel/machvec.c b/arch/sh/kernel/machvec.c
index 548f6607fd0f..cbce639b108a 100644
--- a/arch/sh/kernel/machvec.c
+++ b/arch/sh/kernel/machvec.c
@@ -14,6 +14,7 @@
14#include <linux/string.h> 14#include <linux/string.h>
15#include <asm/machvec.h> 15#include <asm/machvec.h>
16#include <asm/sections.h> 16#include <asm/sections.h>
17#include <asm/addrspace.h>
17#include <asm/setup.h> 18#include <asm/setup.h>
18#include <asm/io.h> 19#include <asm/io.h>
19#include <asm/irq.h> 20#include <asm/irq.h>
@@ -133,4 +134,6 @@ void __init sh_mv_setup(void)
133 134
134 if (!sh_mv.mv_nr_irqs) 135 if (!sh_mv.mv_nr_irqs)
135 sh_mv.mv_nr_irqs = NR_IRQS; 136 sh_mv.mv_nr_irqs = NR_IRQS;
137
138 __set_io_port_base(P2SEG);
136} 139}
diff --git a/arch/sh/kernel/setup.c b/arch/sh/kernel/setup.c
index f9d44f8e0df6..99b4fb553bf1 100644
--- a/arch/sh/kernel/setup.c
+++ b/arch/sh/kernel/setup.c
@@ -549,6 +549,8 @@ static int show_cpuinfo(struct seq_file *m, void *v)
549 549
550 if (cpu == 0) 550 if (cpu == 0)
551 seq_printf(m, "machine\t\t: %s\n", get_system_type()); 551 seq_printf(m, "machine\t\t: %s\n", get_system_type());
552 else
553 seq_printf(m, "\n");
552 554
553 seq_printf(m, "processor\t: %d\n", cpu); 555 seq_printf(m, "processor\t: %d\n", cpu);
554 seq_printf(m, "cpu family\t: %s\n", init_utsname()->machine); 556 seq_printf(m, "cpu family\t: %s\n", init_utsname()->machine);
diff --git a/arch/sh/kernel/sh_ksyms_32.c b/arch/sh/kernel/sh_ksyms_32.c
index 8dbe26b17c44..86c270428357 100644
--- a/arch/sh/kernel/sh_ksyms_32.c
+++ b/arch/sh/kernel/sh_ksyms_32.c
@@ -84,6 +84,7 @@ DECLARE_EXPORT(__movstrSI60);
84DECLARE_EXPORT(__movstr_i4_even); 84DECLARE_EXPORT(__movstr_i4_even);
85DECLARE_EXPORT(__movstr_i4_odd); 85DECLARE_EXPORT(__movstr_i4_odd);
86DECLARE_EXPORT(__movstrSI12_i4); 86DECLARE_EXPORT(__movstrSI12_i4);
87DECLARE_EXPORT(__movmem);
87DECLARE_EXPORT(__movmem_i4_even); 88DECLARE_EXPORT(__movmem_i4_even);
88DECLARE_EXPORT(__movmem_i4_odd); 89DECLARE_EXPORT(__movmem_i4_odd);
89DECLARE_EXPORT(__movmemSI12_i4); 90DECLARE_EXPORT(__movmemSI12_i4);
diff --git a/arch/sh/kernel/signal_32.c b/arch/sh/kernel/signal_32.c
index 6729703547a1..3db37425210d 100644
--- a/arch/sh/kernel/signal_32.c
+++ b/arch/sh/kernel/signal_32.c
@@ -145,7 +145,7 @@ static inline int restore_sigcontext_fpu(struct sigcontext __user *sc)
145{ 145{
146 struct task_struct *tsk = current; 146 struct task_struct *tsk = current;
147 147
148 if (!(current_cpu_data.flags & CPU_HAS_FPU)) 148 if (!(boot_cpu_data.flags & CPU_HAS_FPU))
149 return 0; 149 return 0;
150 150
151 set_used_math(); 151 set_used_math();
@@ -158,7 +158,7 @@ static inline int save_sigcontext_fpu(struct sigcontext __user *sc,
158{ 158{
159 struct task_struct *tsk = current; 159 struct task_struct *tsk = current;
160 160
161 if (!(current_cpu_data.flags & CPU_HAS_FPU)) 161 if (!(boot_cpu_data.flags & CPU_HAS_FPU))
162 return 0; 162 return 0;
163 163
164 if (!used_math()) { 164 if (!used_math()) {
@@ -199,7 +199,7 @@ restore_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc, int *r0_p
199#undef COPY 199#undef COPY
200 200
201#ifdef CONFIG_SH_FPU 201#ifdef CONFIG_SH_FPU
202 if (current_cpu_data.flags & CPU_HAS_FPU) { 202 if (boot_cpu_data.flags & CPU_HAS_FPU) {
203 int owned_fp; 203 int owned_fp;
204 struct task_struct *tsk = current; 204 struct task_struct *tsk = current;
205 205
@@ -472,6 +472,7 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
472 err |= __put_user(OR_R0_R0, &frame->retcode[6]); 472 err |= __put_user(OR_R0_R0, &frame->retcode[6]);
473 err |= __put_user((__NR_rt_sigreturn), &frame->retcode[7]); 473 err |= __put_user((__NR_rt_sigreturn), &frame->retcode[7]);
474 regs->pr = (unsigned long) frame->retcode; 474 regs->pr = (unsigned long) frame->retcode;
475 flush_icache_range(regs->pr, regs->pr + sizeof(frame->retcode));
475 } 476 }
476 477
477 if (err) 478 if (err)
@@ -497,8 +498,6 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
497 pr_debug("SIG deliver (%s:%d): sp=%p pc=%08lx pr=%08lx\n", 498 pr_debug("SIG deliver (%s:%d): sp=%p pc=%08lx pr=%08lx\n",
498 current->comm, task_pid_nr(current), frame, regs->pc, regs->pr); 499 current->comm, task_pid_nr(current), frame, regs->pc, regs->pr);
499 500
500 flush_icache_range(regs->pr, regs->pr + sizeof(frame->retcode));
501
502 return 0; 501 return 0;
503 502
504give_sigsegv: 503give_sigsegv:
diff --git a/arch/sh/kernel/smp.c b/arch/sh/kernel/smp.c
index 442d8d47a41e..160db1003cfb 100644
--- a/arch/sh/kernel/smp.c
+++ b/arch/sh/kernel/smp.c
@@ -35,6 +35,8 @@ static inline void __init smp_store_cpu_info(unsigned int cpu)
35{ 35{
36 struct sh_cpuinfo *c = cpu_data + cpu; 36 struct sh_cpuinfo *c = cpu_data + cpu;
37 37
38 memcpy(c, &boot_cpu_data, sizeof(struct sh_cpuinfo));
39
38 c->loops_per_jiffy = loops_per_jiffy; 40 c->loops_per_jiffy = loops_per_jiffy;
39} 41}
40 42
diff --git a/arch/sh/kernel/traps_32.c b/arch/sh/kernel/traps_32.c
index 69bb1652eccd..7a2ee3a6b8e7 100644
--- a/arch/sh/kernel/traps_32.c
+++ b/arch/sh/kernel/traps_32.c
@@ -25,6 +25,7 @@
25#include <linux/kexec.h> 25#include <linux/kexec.h>
26#include <linux/limits.h> 26#include <linux/limits.h>
27#include <linux/proc_fs.h> 27#include <linux/proc_fs.h>
28#include <linux/sysfs.h>
28#include <asm/system.h> 29#include <asm/system.h>
29#include <asm/uaccess.h> 30#include <asm/uaccess.h>
30#include <asm/fpu.h> 31#include <asm/fpu.h>
@@ -54,8 +55,8 @@ static unsigned long se_multi;
54/* bitfield: 1: warn 2: fixup 4: signal -> combinations 2|4 && 1|2|4 are not 55/* bitfield: 1: warn 2: fixup 4: signal -> combinations 2|4 && 1|2|4 are not
55 valid! */ 56 valid! */
56static int se_usermode = 3; 57static int se_usermode = 3;
57/* 0: no warning 1: print a warning message */ 58/* 0: no warning 1: print a warning message, disabled by default */
58static int se_kernmode_warn = 1; 59static int se_kernmode_warn;
59 60
60#ifdef CONFIG_PROC_FS 61#ifdef CONFIG_PROC_FS
61static const char *se_usermode_action[] = { 62static const char *se_usermode_action[] = {
@@ -159,12 +160,12 @@ void die(const char * str, struct pt_regs * regs, long err)
159 160
160 oops_enter(); 161 oops_enter();
161 162
162 console_verbose();
163 spin_lock_irq(&die_lock); 163 spin_lock_irq(&die_lock);
164 console_verbose();
164 bust_spinlocks(1); 165 bust_spinlocks(1);
165 166
166 printk("%s: %04lx [#%d]\n", str, err & 0xffff, ++die_counter); 167 printk("%s: %04lx [#%d]\n", str, err & 0xffff, ++die_counter);
167 168 sysfs_printk_last_file();
168 print_modules(); 169 print_modules();
169 show_regs(regs); 170 show_regs(regs);
170 171
@@ -180,6 +181,7 @@ void die(const char * str, struct pt_regs * regs, long err)
180 bust_spinlocks(0); 181 bust_spinlocks(0);
181 add_taint(TAINT_DIE); 182 add_taint(TAINT_DIE);
182 spin_unlock_irq(&die_lock); 183 spin_unlock_irq(&die_lock);
184 oops_exit();
183 185
184 if (kexec_should_crash(current)) 186 if (kexec_should_crash(current))
185 crash_kexec(regs); 187 crash_kexec(regs);
@@ -190,7 +192,6 @@ void die(const char * str, struct pt_regs * regs, long err)
190 if (panic_on_oops) 192 if (panic_on_oops)
191 panic("Fatal exception"); 193 panic("Fatal exception");
192 194
193 oops_exit();
194 do_exit(SIGSEGV); 195 do_exit(SIGSEGV);
195} 196}
196 197
diff --git a/arch/sh/mm/cache-sh4.c b/arch/sh/mm/cache-sh4.c
index b2453bbef4cd..a98c7d8984fa 100644
--- a/arch/sh/mm/cache-sh4.c
+++ b/arch/sh/mm/cache-sh4.c
@@ -43,7 +43,7 @@ static void (*__flush_dcache_segment_fn)(unsigned long, unsigned long) =
43 * Called from kernel/module.c:sys_init_module and routine for a.out format, 43 * Called from kernel/module.c:sys_init_module and routine for a.out format,
44 * signal handler code and kprobes code 44 * signal handler code and kprobes code
45 */ 45 */
46static void sh4_flush_icache_range(void *args) 46static void __uses_jump_to_uncached sh4_flush_icache_range(void *args)
47{ 47{
48 struct flusher_data *data = args; 48 struct flusher_data *data = args;
49 unsigned long start, end; 49 unsigned long start, end;
diff --git a/arch/sh/mm/cache-sh7705.c b/arch/sh/mm/cache-sh7705.c
index 2cadee2037ac..2601935eb589 100644
--- a/arch/sh/mm/cache-sh7705.c
+++ b/arch/sh/mm/cache-sh7705.c
@@ -78,7 +78,7 @@ static void sh7705_flush_icache_range(void *args)
78/* 78/*
79 * Writeback&Invalidate the D-cache of the page 79 * Writeback&Invalidate the D-cache of the page
80 */ 80 */
81static void __flush_dcache_page(unsigned long phys) 81static void __uses_jump_to_uncached __flush_dcache_page(unsigned long phys)
82{ 82{
83 unsigned long ways, waysize, addrstart; 83 unsigned long ways, waysize, addrstart;
84 unsigned long flags; 84 unsigned long flags;
@@ -144,7 +144,7 @@ static void sh7705_flush_dcache_page(void *arg)
144 __flush_dcache_page(PHYSADDR(page_address(page))); 144 __flush_dcache_page(PHYSADDR(page_address(page)));
145} 145}
146 146
147static void sh7705_flush_cache_all(void *args) 147static void __uses_jump_to_uncached sh7705_flush_cache_all(void *args)
148{ 148{
149 unsigned long flags; 149 unsigned long flags;
150 150
diff --git a/arch/sh/mm/cache.c b/arch/sh/mm/cache.c
index 35c37b7f717a..5e1091be9dc4 100644
--- a/arch/sh/mm/cache.c
+++ b/arch/sh/mm/cache.c
@@ -128,7 +128,7 @@ void __update_cache(struct vm_area_struct *vma,
128 return; 128 return;
129 129
130 page = pfn_to_page(pfn); 130 page = pfn_to_page(pfn);
131 if (pfn_valid(pfn) && page_mapping(page)) { 131 if (pfn_valid(pfn)) {
132 int dirty = test_and_clear_bit(PG_dcache_dirty, &page->flags); 132 int dirty = test_and_clear_bit(PG_dcache_dirty, &page->flags);
133 if (dirty) { 133 if (dirty) {
134 unsigned long addr = (unsigned long)page_address(page); 134 unsigned long addr = (unsigned long)page_address(page);
diff --git a/arch/sh/mm/ioremap_32.c b/arch/sh/mm/ioremap_32.c
index c3250614e3ae..a86eaa9d75a5 100644
--- a/arch/sh/mm/ioremap_32.c
+++ b/arch/sh/mm/ioremap_32.c
@@ -83,7 +83,7 @@ void __iomem *__ioremap(unsigned long phys_addr, unsigned long size,
83 * 83 *
84 * PMB entries are all pre-faulted. 84 * PMB entries are all pre-faulted.
85 */ 85 */
86 if (unlikely(size >= 0x1000000)) { 86 if (unlikely(phys_addr >= P1SEG)) {
87 unsigned long mapped = pmb_remap(addr, phys_addr, size, flags); 87 unsigned long mapped = pmb_remap(addr, phys_addr, size, flags);
88 88
89 if (likely(mapped)) { 89 if (likely(mapped)) {
diff --git a/arch/sh/mm/pmb.c b/arch/sh/mm/pmb.c
index b1a714a92b14..aade31102112 100644
--- a/arch/sh/mm/pmb.c
+++ b/arch/sh/mm/pmb.c
@@ -33,6 +33,8 @@
33 33
34#define NR_PMB_ENTRIES 16 34#define NR_PMB_ENTRIES 16
35 35
36static void __pmb_unmap(struct pmb_entry *);
37
36static struct kmem_cache *pmb_cache; 38static struct kmem_cache *pmb_cache;
37static unsigned long pmb_map; 39static unsigned long pmb_map;
38 40
@@ -218,9 +220,10 @@ static struct {
218long pmb_remap(unsigned long vaddr, unsigned long phys, 220long pmb_remap(unsigned long vaddr, unsigned long phys,
219 unsigned long size, unsigned long flags) 221 unsigned long size, unsigned long flags)
220{ 222{
221 struct pmb_entry *pmbp; 223 struct pmb_entry *pmbp, *pmbe;
222 unsigned long wanted; 224 unsigned long wanted;
223 int pmb_flags, i; 225 int pmb_flags, i;
226 long err;
224 227
225 /* Convert typical pgprot value to the PMB equivalent */ 228 /* Convert typical pgprot value to the PMB equivalent */
226 if (flags & _PAGE_CACHABLE) { 229 if (flags & _PAGE_CACHABLE) {
@@ -236,20 +239,22 @@ long pmb_remap(unsigned long vaddr, unsigned long phys,
236 239
237again: 240again:
238 for (i = 0; i < ARRAY_SIZE(pmb_sizes); i++) { 241 for (i = 0; i < ARRAY_SIZE(pmb_sizes); i++) {
239 struct pmb_entry *pmbe;
240 int ret; 242 int ret;
241 243
242 if (size < pmb_sizes[i].size) 244 if (size < pmb_sizes[i].size)
243 continue; 245 continue;
244 246
245 pmbe = pmb_alloc(vaddr, phys, pmb_flags | pmb_sizes[i].flag); 247 pmbe = pmb_alloc(vaddr, phys, pmb_flags | pmb_sizes[i].flag);
246 if (IS_ERR(pmbe)) 248 if (IS_ERR(pmbe)) {
247 return PTR_ERR(pmbe); 249 err = PTR_ERR(pmbe);
250 goto out;
251 }
248 252
249 ret = set_pmb_entry(pmbe); 253 ret = set_pmb_entry(pmbe);
250 if (ret != 0) { 254 if (ret != 0) {
251 pmb_free(pmbe); 255 pmb_free(pmbe);
252 return -EBUSY; 256 err = -EBUSY;
257 goto out;
253 } 258 }
254 259
255 phys += pmb_sizes[i].size; 260 phys += pmb_sizes[i].size;
@@ -264,12 +269,25 @@ again:
264 pmbp->link = pmbe; 269 pmbp->link = pmbe;
265 270
266 pmbp = pmbe; 271 pmbp = pmbe;
272
273 /*
274 * Instead of trying smaller sizes on every iteration
275 * (even if we succeed in allocating space), try using
276 * pmb_sizes[i].size again.
277 */
278 i--;
267 } 279 }
268 280
269 if (size >= 0x1000000) 281 if (size >= 0x1000000)
270 goto again; 282 goto again;
271 283
272 return wanted - size; 284 return wanted - size;
285
286out:
287 if (pmbp)
288 __pmb_unmap(pmbp);
289
290 return err;
273} 291}
274 292
275void pmb_unmap(unsigned long addr) 293void pmb_unmap(unsigned long addr)
@@ -283,12 +301,19 @@ void pmb_unmap(unsigned long addr)
283 if (unlikely(!pmbe)) 301 if (unlikely(!pmbe))
284 return; 302 return;
285 303
304 __pmb_unmap(pmbe);
305}
306
307static void __pmb_unmap(struct pmb_entry *pmbe)
308{
286 WARN_ON(!test_bit(pmbe->entry, &pmb_map)); 309 WARN_ON(!test_bit(pmbe->entry, &pmb_map));
287 310
288 do { 311 do {
289 struct pmb_entry *pmblink = pmbe; 312 struct pmb_entry *pmblink = pmbe;
290 313
291 clear_pmb_entry(pmbe); 314 if (pmbe->entry != PMB_NO_ENTRY)
315 clear_pmb_entry(pmbe);
316
292 pmbe = pmblink->link; 317 pmbe = pmblink->link;
293 318
294 pmb_free(pmblink); 319 pmb_free(pmblink);