diff options
Diffstat (limited to 'arch/sh/kernel')
-rw-r--r-- | arch/sh/kernel/cpu/clock.c | 4 | ||||
-rw-r--r-- | arch/sh/kernel/cpu/sh3/entry.S | 3 | ||||
-rw-r--r-- | arch/sh/kernel/cpu/sh4a/setup-sh7724.c | 15 | ||||
-rw-r--r-- | arch/sh/kernel/cpu/sh4a/setup-sh7785.c | 14 | ||||
-rw-r--r-- | arch/sh/kernel/dwarf.c | 28 | ||||
-rw-r--r-- | arch/sh/kernel/entry-common.S | 8 | ||||
-rw-r--r-- | arch/sh/kernel/idle.c | 2 | ||||
-rw-r--r-- | arch/sh/kernel/process_64.c | 2 | ||||
-rw-r--r-- | arch/sh/kernel/syscalls_32.S | 1 | ||||
-rw-r--r-- | arch/sh/kernel/syscalls_64.S | 1 |
10 files changed, 68 insertions, 10 deletions
diff --git a/arch/sh/kernel/cpu/clock.c b/arch/sh/kernel/cpu/clock.c index f3a46be..83da5de 100644 --- a/arch/sh/kernel/cpu/clock.c +++ b/arch/sh/kernel/cpu/clock.c @@ -598,7 +598,7 @@ static struct dentry *clk_debugfs_root; static int clk_debugfs_register_one(struct clk *c) { int err; - struct dentry *d, *child; + struct dentry *d, *child, *child_tmp; struct clk *pa = c->parent; char s[255]; char *p = s; @@ -630,7 +630,7 @@ static int clk_debugfs_register_one(struct clk *c) err_out: d = c->dentry; - list_for_each_entry(child, &d->d_subdirs, d_u.d_child) + list_for_each_entry_safe(child, child_tmp, &d->d_subdirs, d_u.d_child) debugfs_remove(child); debugfs_remove(c->dentry); return err; diff --git a/arch/sh/kernel/cpu/sh3/entry.S b/arch/sh/kernel/cpu/sh3/entry.S index 3f7e2a2..f6a389c 100644 --- a/arch/sh/kernel/cpu/sh3/entry.S +++ b/arch/sh/kernel/cpu/sh3/entry.S @@ -132,7 +132,6 @@ ENTRY(tlb_protection_violation_store) mov #1, r5 call_handle_tlbmiss: - setup_frame_reg mov.l 1f, r0 mov r5, r8 mov.l @r0, r6 @@ -365,6 +364,8 @@ handle_exception: mov.l @k2, k2 ! read out vector and keep in k2 handle_exception_special: + setup_frame_reg + ! Setup return address and jump to exception handler mov.l 7f, r9 ! fetch return address stc r2_bank, r0 ! k2 (vector) diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7724.c b/arch/sh/kernel/cpu/sh4a/setup-sh7724.c index a52f351..d32f96c 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-sh7724.c +++ b/arch/sh/kernel/cpu/sh4a/setup-sh7724.c @@ -23,9 +23,23 @@ #include <linux/notifier.h> #include <asm/suspend.h> #include <asm/clock.h> +#include <asm/dma-sh.h> #include <asm/mmzone.h> #include <cpu/sh7724.h> +/* DMA */ +static struct sh_dmae_pdata dma_platform_data = { + .mode = SHDMA_DMAOR1, +}; + +static struct platform_device dma_device = { + .name = "sh-dma-engine", + .id = -1, + .dev = { + .platform_data = &dma_platform_data, + }, +}; + /* Serial */ static struct plat_sci_port scif0_platform_data = { .mapbase = 0xffe00000, @@ -649,6 +663,7 @@ static struct platform_device *sh7724_devices[] __initdata = { &tmu3_device, &tmu4_device, &tmu5_device, + &dma_device, &rtc_device, &iic0_device, &iic1_device, diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7785.c b/arch/sh/kernel/cpu/sh4a/setup-sh7785.c index ef26ebd..f685b9b 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-sh7785.c +++ b/arch/sh/kernel/cpu/sh4a/setup-sh7785.c @@ -14,6 +14,7 @@ #include <linux/io.h> #include <linux/mm.h> #include <linux/sh_timer.h> +#include <asm/dma-sh.h> #include <asm/mmzone.h> static struct plat_sci_port scif0_platform_data = { @@ -294,6 +295,18 @@ static struct platform_device tmu5_device = { .num_resources = ARRAY_SIZE(tmu5_resources), }; +static struct sh_dmae_pdata dma_platform_data = { + .mode = (SHDMA_MIX_IRQ | SHDMA_DMAOR1), +}; + +static struct platform_device dma_device = { + .name = "sh-dma-engine", + .id = -1, + .dev = { + .platform_data = &dma_platform_data, + }, +}; + static struct platform_device *sh7785_devices[] __initdata = { &scif0_device, &scif1_device, @@ -307,6 +320,7 @@ static struct platform_device *sh7785_devices[] __initdata = { &tmu3_device, &tmu4_device, &tmu5_device, + &dma_device, }; static int __init sh7785_devices_setup(void) diff --git a/arch/sh/kernel/dwarf.c b/arch/sh/kernel/dwarf.c index 3576b70..e511680 100644 --- a/arch/sh/kernel/dwarf.c +++ b/arch/sh/kernel/dwarf.c @@ -540,6 +540,8 @@ void dwarf_free_frame(struct dwarf_frame *frame) mempool_free(frame, dwarf_frame_pool); } +extern void ret_from_irq(void); + /** * dwarf_unwind_stack - unwind the stack * @@ -678,6 +680,24 @@ struct dwarf_frame * dwarf_unwind_stack(unsigned long pc, addr = frame->cfa + reg->addr; frame->return_addr = __raw_readl(addr); + /* + * Ah, the joys of unwinding through interrupts. + * + * Interrupts are tricky - the DWARF info needs to be _really_ + * accurate and unfortunately I'm seeing a lot of bogus DWARF + * info. For example, I've seen interrupts occur in epilogues + * just after the frame pointer (r14) had been restored. The + * problem was that the DWARF info claimed that the CFA could be + * reached by using the value of the frame pointer before it was + * restored. + * + * So until the compiler can be trusted to produce reliable + * DWARF info when it really matters, let's stop unwinding once + * we've calculated the function that was interrupted. + */ + if (prev && prev->pc == (unsigned long)ret_from_irq) + frame->return_addr = 0; + return frame; bail: @@ -892,18 +912,18 @@ static struct unwinder dwarf_unwinder = { static void dwarf_unwinder_cleanup(void) { - struct dwarf_cie *cie; - struct dwarf_fde *fde; + struct dwarf_cie *cie, *cie_tmp; + struct dwarf_fde *fde, *fde_tmp; /* * Deallocate all the memory allocated for the DWARF unwinder. * Traverse all the FDE/CIE lists and remove and free all the * memory associated with those data structures. */ - list_for_each_entry(cie, &dwarf_cie_list, link) + list_for_each_entry_safe(cie, cie_tmp, &dwarf_cie_list, link) kfree(cie); - list_for_each_entry(fde, &dwarf_fde_list, link) + list_for_each_entry_safe(fde, fde_tmp, &dwarf_fde_list, link) kfree(fde); kmem_cache_destroy(dwarf_reg_cachep); diff --git a/arch/sh/kernel/entry-common.S b/arch/sh/kernel/entry-common.S index f0abd58..2b15ae6 100644 --- a/arch/sh/kernel/entry-common.S +++ b/arch/sh/kernel/entry-common.S @@ -70,8 +70,14 @@ ret_from_exception: CFI_STARTPROC simple CFI_DEF_CFA r14, 0 CFI_REL_OFFSET 17, 64 - CFI_REL_OFFSET 15, 0 + CFI_REL_OFFSET 15, 60 CFI_REL_OFFSET 14, 56 + CFI_REL_OFFSET 13, 52 + CFI_REL_OFFSET 12, 48 + CFI_REL_OFFSET 11, 44 + CFI_REL_OFFSET 10, 40 + CFI_REL_OFFSET 9, 36 + CFI_REL_OFFSET 8, 32 preempt_stop() ENTRY(ret_from_irq) ! diff --git a/arch/sh/kernel/idle.c b/arch/sh/kernel/idle.c index aaff003..6b3d706 100644 --- a/arch/sh/kernel/idle.c +++ b/arch/sh/kernel/idle.c @@ -62,6 +62,7 @@ void default_idle(void) clear_thread_flag(TIF_POLLING_NRFLAG); smp_mb__after_clear_bit(); + set_bl_bit(); if (!need_resched()) { local_irq_enable(); cpu_sleep(); @@ -69,6 +70,7 @@ void default_idle(void) local_irq_enable(); set_thread_flag(TIF_POLLING_NRFLAG); + clear_bl_bit(); } else poll_idle(); } diff --git a/arch/sh/kernel/process_64.c b/arch/sh/kernel/process_64.c index 31f80c6..ec79faf 100644 --- a/arch/sh/kernel/process_64.c +++ b/arch/sh/kernel/process_64.c @@ -368,7 +368,7 @@ void exit_thread(void) void flush_thread(void) { - /* Called by fs/exec.c (flush_old_exec) to remove traces of a + /* Called by fs/exec.c (setup_new_exec) to remove traces of a * previously running executable. */ #ifdef CONFIG_SH_FPU if (last_task_used_math == current) { diff --git a/arch/sh/kernel/syscalls_32.S b/arch/sh/kernel/syscalls_32.S index 4bd5a11..19fd11d 100644 --- a/arch/sh/kernel/syscalls_32.S +++ b/arch/sh/kernel/syscalls_32.S @@ -353,4 +353,3 @@ ENTRY(sys_call_table) .long sys_pwritev .long sys_rt_tgsigqueueinfo /* 335 */ .long sys_perf_event_open - .long sys_recvmmsg diff --git a/arch/sh/kernel/syscalls_64.S b/arch/sh/kernel/syscalls_64.S index 07d2aae..2048a20 100644 --- a/arch/sh/kernel/syscalls_64.S +++ b/arch/sh/kernel/syscalls_64.S @@ -392,3 +392,4 @@ sys_call_table: .long sys_rt_tgsigqueueinfo .long sys_perf_event_open .long sys_recvmmsg /* 365 */ + .long sys_accept4 |