From a3793a0d86e2d65dda6beb86fa295be25b238159 Mon Sep 17 00:00:00 2001 From: Guennadi Liakhovetski Date: Tue, 22 Feb 2011 09:57:44 +0000 Subject: [PATCH 01/13] sh: switch ap325rxa to dynamically manage the platform camera Use soc_camera_platform helper functions to dynamically manage the camera device. Signed-off-by: Guennadi Liakhovetski Signed-off-by: Paul Mundt --- arch/sh/boards/mach-ap325rxa/setup.c | 34 ++++++++++++---------------- 1 file changed, 14 insertions(+), 20 deletions(-) diff --git a/arch/sh/boards/mach-ap325rxa/setup.c b/arch/sh/boards/mach-ap325rxa/setup.c index 618bd566cf53..969421f64a15 100644 --- a/arch/sh/boards/mach-ap325rxa/setup.c +++ b/arch/sh/boards/mach-ap325rxa/setup.c @@ -359,37 +359,31 @@ static struct soc_camera_link camera_link = { .priv = &camera_info, }; -static void dummy_release(struct device *dev) -{ -} +static struct platform_device *camera_device; -static struct platform_device camera_device = { - .name = "soc_camera_platform", - .dev = { - .platform_data = &camera_info, - .release = dummy_release, - }, -}; +static void ap325rxa_camera_release(struct device *dev) +{ + soc_camera_platform_release(&camera_device); +} static int ap325rxa_camera_add(struct soc_camera_link *icl, struct device *dev) { - if (icl != &camera_link || camera_probe() <= 0) - return -ENODEV; + int ret = soc_camera_platform_add(icl, dev, &camera_device, &camera_link, + ap325rxa_camera_release, 0); + if (ret < 0) + return ret; - camera_info.dev = dev; + ret = camera_probe(); + if (ret < 0) + soc_camera_platform_del(icl, camera_device, &camera_link); - return platform_device_register(&camera_device); + return ret; } static void ap325rxa_camera_del(struct soc_camera_link *icl) { - if (icl != &camera_link) - return; - - platform_device_unregister(&camera_device); - memset(&camera_device.dev.kobj, 0, - sizeof(camera_device.dev.kobj)); + soc_camera_platform_del(icl, camera_device, &camera_link); } #endif /* CONFIG_I2C */ From 52b96c2592e8fdb93231c9644b68112518916a57 Mon Sep 17 00:00:00 2001 From: Guennadi Liakhovetski Date: Fri, 15 Apr 2011 18:30:55 +0000 Subject: [PATCH 02/13] sh: add MMCIF runtime PM support on ecovec Signed-off-by: Guennadi Liakhovetski Cc: Simon Horman Cc: Magnus Damm Signed-off-by: Paul Mundt --- arch/sh/boards/mach-ecovec24/setup.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/arch/sh/boards/mach-ecovec24/setup.c b/arch/sh/boards/mach-ecovec24/setup.c index bb13d0e1b964..3a32741cc0ac 100644 --- a/arch/sh/boards/mach-ecovec24/setup.c +++ b/arch/sh/boards/mach-ecovec24/setup.c @@ -885,6 +885,9 @@ static struct platform_device sh_mmcif_device = { }, .num_resources = ARRAY_SIZE(sh_mmcif_resources), .resource = sh_mmcif_resources, + .archdata = { + .hwblk_id = HWBLK_MMC, + }, }; #endif From 0f0ebd980e0e8a2fd33ab3ef0d5b0cffbcddd8a1 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Tue, 24 May 2011 17:25:23 +0900 Subject: [PATCH 03/13] sh: arch/sh/kernel/process_32.c needs linux/prefetch.h. Trivial build fix for certain configurations that don't grab linux/prefetch.h via alternate means (specifically SH-2 and SH-3 parts). Signed-off-by: Paul Mundt --- arch/sh/kernel/process_32.c | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/sh/kernel/process_32.c b/arch/sh/kernel/process_32.c index 762a13984bbd..b473f0c06fbc 100644 --- a/arch/sh/kernel/process_32.c +++ b/arch/sh/kernel/process_32.c @@ -21,6 +21,7 @@ #include #include #include +#include #include #include #include From 4e2b1084b0fb79c963b73586815e1ef034dc2b57 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Tue, 24 May 2011 17:33:51 +0900 Subject: [PATCH 04/13] sh: Update shmin to reflect PIO dependency. shmin uses __set_io_port_base() for legacy I/O mapping that ethernet and other SuperI/O functions depend on. Ensure that PIO support is built in until the board is updated for MMIO properly. Signed-off-by: Paul Mundt --- arch/sh/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/sh/Kconfig b/arch/sh/Kconfig index b44e37753b9a..a164c9e3c73c 100644 --- a/arch/sh/Kconfig +++ b/arch/sh/Kconfig @@ -167,7 +167,7 @@ config ARCH_HAS_CPU_IDLE_WAIT config NO_IOPORT def_bool !PCI - depends on !SH_CAYMAN && !SH_SH4202_MICRODEV + depends on !SH_CAYMAN && !SH_SH4202_MICRODEV && !SH_SHMIN config IO_TRAPPED bool From 54525552c6ccfd867e819845da14be994e303218 Mon Sep 17 00:00:00 2001 From: Guennadi Liakhovetski Date: Tue, 24 May 2011 10:23:59 +0000 Subject: [PATCH 05/13] sh: mark DMA slave ID 0 as invalid This makes it possible to leave DMA slave IDs in the platform data at default 0 value without hitting DMA channel allocation error paths. Signed-off-by: Guennadi Liakhovetski Signed-off-by: Paul Mundt --- arch/sh/include/cpu-sh4/cpu/sh7722.h | 1 + arch/sh/include/cpu-sh4/cpu/sh7724.h | 1 + arch/sh/include/cpu-sh4/cpu/sh7757.h | 1 + 3 files changed, 3 insertions(+) diff --git a/arch/sh/include/cpu-sh4/cpu/sh7722.h b/arch/sh/include/cpu-sh4/cpu/sh7722.h index 7a5b8a331b4a..bd0622788d64 100644 --- a/arch/sh/include/cpu-sh4/cpu/sh7722.h +++ b/arch/sh/include/cpu-sh4/cpu/sh7722.h @@ -236,6 +236,7 @@ enum { }; enum { + SHDMA_SLAVE_INVALID, SHDMA_SLAVE_SCIF0_TX, SHDMA_SLAVE_SCIF0_RX, SHDMA_SLAVE_SCIF1_TX, diff --git a/arch/sh/include/cpu-sh4/cpu/sh7724.h b/arch/sh/include/cpu-sh4/cpu/sh7724.h index 7eb435999426..3daef8ecbc63 100644 --- a/arch/sh/include/cpu-sh4/cpu/sh7724.h +++ b/arch/sh/include/cpu-sh4/cpu/sh7724.h @@ -285,6 +285,7 @@ enum { }; enum { + SHDMA_SLAVE_INVALID, SHDMA_SLAVE_SCIF0_TX, SHDMA_SLAVE_SCIF0_RX, SHDMA_SLAVE_SCIF1_TX, diff --git a/arch/sh/include/cpu-sh4/cpu/sh7757.h b/arch/sh/include/cpu-sh4/cpu/sh7757.h index 05b8196c7753..41f9f8b9db73 100644 --- a/arch/sh/include/cpu-sh4/cpu/sh7757.h +++ b/arch/sh/include/cpu-sh4/cpu/sh7757.h @@ -252,6 +252,7 @@ enum { }; enum { + SHDMA_SLAVE_INVALID, SHDMA_SLAVE_SDHI_TX, SHDMA_SLAVE_SDHI_RX, SHDMA_SLAVE_MMCIF_TX, From 194cd8dfc9e4f29249b3bd45c5cb5c0a33a6438c Mon Sep 17 00:00:00 2001 From: Nobuhiro Iwamatsu Date: Tue, 31 May 2011 13:27:41 +0900 Subject: [PATCH 06/13] sh: asm/tlb.h needs linux/swap.h Commit 1e56a56410bb64bce62d44563e35a143fc2d515f introduced the mmu_gather rework for sh, but missed a linux/swap.h include: CC arch/sh/mm/tlb-urb.o In file included from arch/sh/mm/tlb-urb.c:14:0: arch/sh/include/asm/tlb.h: In function '__tlb_remove_page': arch/sh/include/asm/tlb.h:92:2: error: implicit declaration of function 'free_page_and_swap_cache' Signed-off-by: Nobuhiro Iwamatsu CC: Peter Zijlstra Signed-off-by: Paul Mundt --- arch/sh/include/asm/tlb.h | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/sh/include/asm/tlb.h b/arch/sh/include/asm/tlb.h index 6c308d8b9a50..ec88bfcdf7ce 100644 --- a/arch/sh/include/asm/tlb.h +++ b/arch/sh/include/asm/tlb.h @@ -9,6 +9,7 @@ #include #ifdef CONFIG_MMU +#include #include #include #include From 65d517eb7224d24ee4206416161390f30d69e622 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Tue, 31 May 2011 14:37:44 +0900 Subject: [PATCH 07/13] sh64: asm/pgtable.h needs asm/mmu.h Needed to satisfy the __in_29bit_mode() check. Signed-off-by: Paul Mundt --- arch/sh/include/asm/pgtable.h | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/sh/include/asm/pgtable.h b/arch/sh/include/asm/pgtable.h index db85916b9e95..9210e93a92c3 100644 --- a/arch/sh/include/asm/pgtable.h +++ b/arch/sh/include/asm/pgtable.h @@ -18,6 +18,7 @@ #include #endif #include +#include #ifndef __ASSEMBLY__ #include From 3f9b8520b06013939ad247ba08b69529b5f14be1 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Tue, 31 May 2011 14:38:29 +0900 Subject: [PATCH 08/13] sh64: Move from P1SEG to CAC_ADDR for consistent sync. sh64 doesn't define a P1SEGADDR, resulting in a build failure. The proper mapping can be attained for both sh32 and 64 via the CAC_ADDR macro, so switch to that instead. Signed-off-by: Paul Mundt --- arch/sh/mm/consistent.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/sh/mm/consistent.c b/arch/sh/mm/consistent.c index 40733a952402..f251b5f27652 100644 --- a/arch/sh/mm/consistent.c +++ b/arch/sh/mm/consistent.c @@ -82,7 +82,7 @@ void dma_cache_sync(struct device *dev, void *vaddr, size_t size, void *addr; addr = __in_29bit_mode() ? - (void *)P1SEGADDR((unsigned long)vaddr) : vaddr; + (void *)CAC_ADDR((unsigned long)vaddr) : vaddr; switch (direction) { case DMA_FROM_DEVICE: /* invalidate only */ From db7eba292e913390fa881272bfbc3da0a5380513 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Tue, 31 May 2011 14:39:49 +0900 Subject: [PATCH 09/13] sh: Fix up asm-generic/ptrace.h fallout. There was an ordering issue with regards to instruction_pointer() being used in profile_pc() prior to the asm-generic/ptrace.h include, which subsequently provided the instruction_pointer() definition. In the interest of simplicity we simply open-code the regs->pc deref for the profile_pc() definition instead. The FP functions were also broken due to a lack of a common regs->fp, so provide a common GET_FP() that is safe for both architectures in order to fix up the frame pointer helpers too. Signed-off-by: Paul Mundt --- arch/sh/include/asm/ptrace.h | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/arch/sh/include/asm/ptrace.h b/arch/sh/include/asm/ptrace.h index 40725b4a8018..88bd6be168a9 100644 --- a/arch/sh/include/asm/ptrace.h +++ b/arch/sh/include/asm/ptrace.h @@ -41,7 +41,9 @@ #define user_mode(regs) (((regs)->sr & 0x40000000)==0) #define kernel_stack_pointer(_regs) ((unsigned long)(_regs)->regs[15]) -#define GET_USP(regs) ((regs)->regs[15]) + +#define GET_FP(regs) ((regs)->regs[14]) +#define GET_USP(regs) ((regs)->regs[15]) extern void show_regs(struct pt_regs *); @@ -131,7 +133,7 @@ extern void ptrace_triggered(struct perf_event *bp, int nmi, static inline unsigned long profile_pc(struct pt_regs *regs) { - unsigned long pc = instruction_pointer(regs); + unsigned long pc = regs->pc; if (virt_addr_uncached(pc)) return CAC_ADDR(pc); From d4905ce38c73964b868037e49a5945e1cf47a7f2 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Tue, 31 May 2011 15:23:20 +0900 Subject: [PATCH 10/13] Revert "clocksource: sh_tmu: Runtime PM support" This reverts commit 1b842e91fea9447eff5eb687e28ad61c02f5033e. There is a fundamental ordering race between the early and late probe paths and the runtime PM tie-in that results in __pm_runtime_resume() attempting to take a lock that hasn't been initialized yet (which by proxy also suggests that pm_runtime_init() hasn't yet been run on the device either, making the entire thing unsafe) -- resulting in instant death on SMP or on UP with spinlock debugging enabled: sh_tmu.0: used for clock events sh_tmu.0: used for periodic clock events BUG: spinlock trylock failure on UP on CPU#0, swapper/0 lock: 804db198, .magic: 00000000, .owner: /-1, .owner_cpu: 0 ... Revert it for now until the ordering issues can be resolved, or we can get some more help from the runtime PM framework to make this possible. Signed-off-by: Paul Mundt --- drivers/clocksource/sh_tmu.c | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/drivers/clocksource/sh_tmu.c b/drivers/clocksource/sh_tmu.c index 17296288a205..808135768617 100644 --- a/drivers/clocksource/sh_tmu.c +++ b/drivers/clocksource/sh_tmu.c @@ -25,7 +25,6 @@ #include #include #include -#include #include #include #include @@ -110,12 +109,10 @@ static int sh_tmu_enable(struct sh_tmu_priv *p) { int ret; - /* wake up device and enable clock */ - pm_runtime_get_sync(&p->pdev->dev); + /* enable clock */ ret = clk_enable(p->clk); if (ret) { dev_err(&p->pdev->dev, "cannot enable clock\n"); - pm_runtime_put_sync(&p->pdev->dev); return ret; } @@ -144,9 +141,8 @@ static void sh_tmu_disable(struct sh_tmu_priv *p) /* disable interrupts in TMU block */ sh_tmu_write(p, TCR, 0x0000); - /* stop clock and mark device as idle */ + /* stop clock */ clk_disable(p->clk); - pm_runtime_put_sync(&p->pdev->dev); } static void sh_tmu_set_next(struct sh_tmu_priv *p, unsigned long delta, @@ -415,7 +411,6 @@ static int __devinit sh_tmu_probe(struct platform_device *pdev) if (p) { dev_info(&pdev->dev, "kept as earlytimer\n"); - pm_runtime_enable(&pdev->dev); return 0; } @@ -430,9 +425,6 @@ static int __devinit sh_tmu_probe(struct platform_device *pdev) kfree(p); platform_set_drvdata(pdev, NULL); } - - if (!is_early_platform_device(pdev)) - pm_runtime_enable(&pdev->dev); return ret; } From 9436b4abec28a22edd961ae375535d940625f1f2 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Tue, 31 May 2011 15:26:42 +0900 Subject: [PATCH 11/13] Revert "clocksource: sh_cmt: Runtime PM support" This reverts commit 01fa68b58492a5d6708a91c1f474b6a099a9509e. The same note as per the sh_tmu change applies here, too. Signed-off-by: Paul Mundt --- drivers/clocksource/sh_cmt.c | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/drivers/clocksource/sh_cmt.c b/drivers/clocksource/sh_cmt.c index 036e5865eb40..dc7c033ef587 100644 --- a/drivers/clocksource/sh_cmt.c +++ b/drivers/clocksource/sh_cmt.c @@ -24,7 +24,6 @@ #include #include #include -#include #include #include #include @@ -153,12 +152,10 @@ static int sh_cmt_enable(struct sh_cmt_priv *p, unsigned long *rate) { int ret; - /* wake up device and enable clock */ - pm_runtime_get_sync(&p->pdev->dev); + /* enable clock */ ret = clk_enable(p->clk); if (ret) { dev_err(&p->pdev->dev, "cannot enable clock\n"); - pm_runtime_put_sync(&p->pdev->dev); return ret; } @@ -190,9 +187,8 @@ static void sh_cmt_disable(struct sh_cmt_priv *p) /* disable interrupts in CMT block */ sh_cmt_write(p, CMCSR, 0); - /* stop clock and mark device as idle */ + /* stop clock */ clk_disable(p->clk); - pm_runtime_put_sync(&p->pdev->dev); } /* private flags */ @@ -664,7 +660,6 @@ static int __devinit sh_cmt_probe(struct platform_device *pdev) if (p) { dev_info(&pdev->dev, "kept as earlytimer\n"); - pm_runtime_enable(&pdev->dev); return 0; } @@ -679,9 +674,6 @@ static int __devinit sh_cmt_probe(struct platform_device *pdev) kfree(p); platform_set_drvdata(pdev, NULL); } - - if (!is_early_platform_device(pdev)) - pm_runtime_enable(&pdev->dev); return ret; } From 5c2de44417523385010b529599a2b30f290831a3 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Tue, 31 May 2011 15:53:03 +0900 Subject: [PATCH 12/13] dmaengine: shdma: Fix up fallout from runtime PM changes. The runtime PM changes introduce sh_dmae_rst() wrapping via the runtime_resume helper, depending on dev_get_drvdata() to fetch the platform data needed for the DMAOR initialization default at a time where drvdata hasn't yet been established by the probe path, resulting in general probe misery: Unable to handle kernel NULL pointer dereference at virtual address 000000c4 pc = 8025adee *pde = 00000000 Oops: 0000 [#1] Modules linked in: Pid : 1, Comm: swapper CPU : 0 Not tainted (3.0.0-rc1-00012-g9436b4a-dirty #1456) PC is at sh_dmae_rst+0x28/0x86 PR is at sh_dmae_rst+0x22/0x86 PC : 8025adee SP : 9e803d10 SR : 400080f1 TEA : 000000c4 R0 : 000000c4 R1 : 0000fff8 R2 : 00000000 R3 : 00000040 R4 : 000000f0 R5 : 00000000 R6 : 00000000 R7 : 804f184c R8 : 00000000 R9 : 804dd0e8 R10 : 80283204 R11 : ffffffda R12 : 000000a0 R13 : 804dd18c R14 : 9e803d10 MACH: 00000000 MACL: 00008f20 GBR : 00000000 PR : 8025ade8 Call trace: [<8025ae70>] sh_dmae_runtime_resume+0x24/0x34 [<80283238>] pm_generic_runtime_resume+0x34/0x3c [<80283370>] rpm_callback+0x4a/0x7e [<80283efc>] rpm_resume+0x240/0x384 [<80283f54>] rpm_resume+0x298/0x384 [<8028428c>] __pm_runtime_resume+0x44/0x7c [<8038a358>] __ioremap_caller+0x0/0xec [<80284296>] __pm_runtime_resume+0x4e/0x7c [<8038a358>] __ioremap_caller+0x0/0xec [<80666254>] sh_dmae_probe+0x180/0x6a0 [<802803ae>] platform_drv_probe+0x26/0x2e Fix up the ordering accordingly. Signed-off-by: Paul Mundt --- drivers/dma/shdma.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/drivers/dma/shdma.c b/drivers/dma/shdma.c index 636e40925b16..727e76ff13e1 100644 --- a/drivers/dma/shdma.c +++ b/drivers/dma/shdma.c @@ -1144,6 +1144,8 @@ static int __init sh_dmae_probe(struct platform_device *pdev) /* platform data */ shdev->pdata = pdata; + platform_set_drvdata(pdev, shdev); + pm_runtime_enable(&pdev->dev); pm_runtime_get_sync(&pdev->dev); @@ -1256,7 +1258,6 @@ static int __init sh_dmae_probe(struct platform_device *pdev) pm_runtime_put(&pdev->dev); - platform_set_drvdata(pdev, shdev); dma_async_device_register(&shdev->common); return err; @@ -1278,6 +1279,8 @@ rst_err: if (dmars) iounmap(shdev->dmars); + + platform_set_drvdata(pdev, NULL); emapdmars: iounmap(shdev->chan_reg); synchronize_rcu(); @@ -1316,6 +1319,8 @@ static int __exit sh_dmae_remove(struct platform_device *pdev) iounmap(shdev->dmars); iounmap(shdev->chan_reg); + platform_set_drvdata(pdev, NULL); + synchronize_rcu(); kfree(shdev); From a1b2cc50679c1d2eed44e2885f6178ce907498b7 Mon Sep 17 00:00:00 2001 From: Guennadi Liakhovetski Date: Tue, 31 May 2011 09:25:16 +0000 Subject: [PATCH 13/13] dmaengine: shdma: fix a regression: initialise DMA channels for memcpy A recent patch has introduced a regression, where repeating a memcpy DMA test with shdma module unloading between them skips the DMA channel configuration. Fix this regression by always configuring the channel during its allocation. Signed-off-by: Guennadi Liakhovetski Signed-off-by: Paul Mundt --- drivers/dma/shdma.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/dma/shdma.c b/drivers/dma/shdma.c index 727e76ff13e1..2a638f9f09a2 100644 --- a/drivers/dma/shdma.c +++ b/drivers/dma/shdma.c @@ -343,7 +343,7 @@ static int sh_dmae_alloc_chan_resources(struct dma_chan *chan) dmae_set_dmars(sh_chan, cfg->mid_rid); dmae_set_chcr(sh_chan, cfg->chcr); - } else if ((sh_dmae_readl(sh_chan, CHCR) & 0xf00) != 0x400) { + } else { dmae_init(sh_chan); }