[v2] sh: Update dma-sh api
diff mbox

Message ID 49B5F10E.7080706@renesas.com
State Superseded
Headers show

Commit Message

Nobuhiro Iwamatsu March 10, 2009, 4:48 a.m. UTC
Add DMA support of new SH CPU and the change of definition.
And add Multi IRQ support for SH7763/64/80/85.

Signed-off-by: Nobuhiro Iwamatsu <iwamatsu.nobuhiro@renesas.com>
Signed-off-by: Yoshihiro Shimoda <shimoda.yoshihiro@renesas.com>
---
 V2: Remove Makefile

 arch/sh/drivers/dma/Kconfig              |    8 +-
 arch/sh/drivers/dma/dma-sh.c             |  172 ++++++++++++++++++++----------
 arch/sh/drivers/dma/dma-sh.h             |   75 -------------
 arch/sh/include/asm/dma-sh.h             |  117 ++++++++++++++++++++
 arch/sh/include/asm/dma.h                |    8 +-
 arch/sh/include/cpu-sh3/cpu/dma.h        |   17 +--
 arch/sh/include/cpu-sh4/cpu/dma-sh4a.h   |   94 ++++++++++++++++
 arch/sh/include/cpu-sh4/cpu/dma-sh7780.h |   39 -------
 arch/sh/include/cpu-sh4/cpu/dma.h        |   30 +++---
 9 files changed, 352 insertions(+), 208 deletions(-)
 delete mode 100644 arch/sh/drivers/dma/dma-sh.h
 create mode 100644 arch/sh/include/asm/dma-sh.h
 create mode 100644 arch/sh/include/cpu-sh4/cpu/dma-sh4a.h
 delete mode 100644 arch/sh/include/cpu-sh4/cpu/dma-sh7780.h

Comments

Paul Mundt March 10, 2009, 6:02 a.m. UTC | #1
On Tue, Mar 10, 2009 at 01:48:14PM +0900, Nobuhiro Iwamatsu wrote:
> diff --git a/arch/sh/include/asm/dma.h b/arch/sh/include/asm/dma.h
> index beca712..085e05a 100644
> --- a/arch/sh/include/asm/dma.h
> +++ b/arch/sh/include/asm/dma.h
> @@ -23,12 +23,8 @@
>  /* But... */
>  /* XXX: This is not applicable to SuperH, just needed for alloc_bootmem */
>  #define MAX_DMA_ADDRESS		(PAGE_OFFSET+0x10000000)
> -
> -#ifdef CONFIG_NR_DMA_CHANNELS
> -#  define MAX_DMA_CHANNELS	(CONFIG_NR_DMA_CHANNELS)
> -#else
> -#  define MAX_DMA_CHANNELS	(CONFIG_NR_ONCHIP_DMA_CHANNELS)
> -#endif
> +/* MAX DMA Channel */
> +#define MAX_DMA_CHANNELS	(CONFIG_NR_ONCHIP_DMA_CHANNELS)
> 
This breaks the Dreamcast, which contains multiple DMACs and needs more
than the on-chip channels managed by the DMA API. As the Dreamcast is the
primary user of this code, please make sure you do not break its use of
the API. It would also be good if someone can verify whether the G2 and
PVR2 DMA still work after this patch is applied.

On the other hand, I don't know how much we really want to be doing here
in the first place. All new development should be happening on the
dmaengine API instead, this code is mostly for keeping the existing users
limping along, and not much else. Matt Fleming was doing some work there,
it would be preferable to see that code updated and merged rather than
work spent on the old DMA API.
--
To unsubscribe from this list: send the line "unsubscribe linux-sh" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Nobuhiro Iwamatsu March 10, 2009, 7:22 a.m. UTC | #2
Paul Mundt wrote:
> On Tue, Mar 10, 2009 at 01:48:14PM +0900, Nobuhiro Iwamatsu wrote:
>> diff --git a/arch/sh/include/asm/dma.h b/arch/sh/include/asm/dma.h
>> index beca712..085e05a 100644
>> --- a/arch/sh/include/asm/dma.h
>> +++ b/arch/sh/include/asm/dma.h
>> @@ -23,12 +23,8 @@
>>  /* But... */
>>  /* XXX: This is not applicable to SuperH, just needed for alloc_bootmem */
>>  #define MAX_DMA_ADDRESS		(PAGE_OFFSET+0x10000000)
>> -
>> -#ifdef CONFIG_NR_DMA_CHANNELS
>> -#  define MAX_DMA_CHANNELS	(CONFIG_NR_DMA_CHANNELS)
>> -#else
>> -#  define MAX_DMA_CHANNELS	(CONFIG_NR_ONCHIP_DMA_CHANNELS)
>> -#endif
>> +/* MAX DMA Channel */
>> +#define MAX_DMA_CHANNELS	(CONFIG_NR_ONCHIP_DMA_CHANNELS)

Thank you for your comments.


>>
> This breaks the Dreamcast, which contains multiple DMACs and needs more
> than the on-chip channels managed by the DMA API. As the Dreamcast is the
> primary user of this code, please make sure you do not break its use of
> the API. It would also be good if someone can verify whether the G2 and
> PVR2 DMA still work after this patch is applied.

OK. I will fix this point.
> 
> On the other hand, I don't know how much we really want to be doing here
> in the first place. All new development should be happening on the
> dmaengine API instead, this code is mostly for keeping the existing users
> limping along, and not much else. Matt Fleming was doing some work there,
> it would be preferable to see that code updated and merged rather than
> work spent on the old DMA API.
> 

I see.
I have already been writing the driver of DMAengine, and I am testing.
To make old DMA-API coexist with dma engine in these patches, I wrote.

Best regards,
  Nobuhiro

--
To unsubscribe from this list: send the line "unsubscribe linux-sh" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Paul Mundt March 10, 2009, 7:23 a.m. UTC | #3
On Tue, Mar 10, 2009 at 04:22:37PM +0900, Nobuhiro Iwamatsu wrote:
> Paul Mundt wrote:
> >On Tue, Mar 10, 2009 at 01:48:14PM +0900, Nobuhiro Iwamatsu wrote:
> >>diff --git a/arch/sh/include/asm/dma.h b/arch/sh/include/asm/dma.h
> >>index beca712..085e05a 100644
> >>--- a/arch/sh/include/asm/dma.h
> >>+++ b/arch/sh/include/asm/dma.h
> >>@@ -23,12 +23,8 @@
> >> /* But... */
> >> /* XXX: This is not applicable to SuperH, just needed for alloc_bootmem 
> >> */
> >> #define MAX_DMA_ADDRESS		(PAGE_OFFSET+0x10000000)
> >>-
> >>-#ifdef CONFIG_NR_DMA_CHANNELS
> >>-#  define MAX_DMA_CHANNELS	(CONFIG_NR_DMA_CHANNELS)
> >>-#else
> >>-#  define MAX_DMA_CHANNELS	(CONFIG_NR_ONCHIP_DMA_CHANNELS)
> >>-#endif
> >>+/* MAX DMA Channel */
> >>+#define MAX_DMA_CHANNELS	(CONFIG_NR_ONCHIP_DMA_CHANNELS)
> 
> Thank you for your comments.
> 
> 
> >>
> >This breaks the Dreamcast, which contains multiple DMACs and needs more
> >than the on-chip channels managed by the DMA API. As the Dreamcast is the
> >primary user of this code, please make sure you do not break its use of
> >the API. It would also be good if someone can verify whether the G2 and
> >PVR2 DMA still work after this patch is applied.
> 
> OK. I will fix this point.
> >
> >On the other hand, I don't know how much we really want to be doing here
> >in the first place. All new development should be happening on the
> >dmaengine API instead, this code is mostly for keeping the existing users
> >limping along, and not much else. Matt Fleming was doing some work there,
> >it would be preferable to see that code updated and merged rather than
> >work spent on the old DMA API.
> >
> 
> I see.
> I have already been writing the driver of DMAengine, and I am testing.
> To make old DMA-API coexist with dma engine in these patches, I wrote.
> 
Ah, ok, I wasn't aware that that was what your intention was. In that
case, once the Dreamcast fallout is fixed, I'll merge these.
--
To unsubscribe from this list: send the line "unsubscribe linux-sh" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Adrian McMenamin March 13, 2009, 12:05 p.m. UTC | #4
2009/3/10 Paul Mundt <lethal@linux-sh.org>:
> On Tue, Mar 10, 2009 at 04:22:37PM +0900, Nobuhiro Iwamatsu wrote:
>> Paul Mundt wrote:
>> >On Tue, Mar 10, 2009 at 01:48:14PM +0900, Nobuhiro Iwamatsu wrote:

 ...

>> I see.
>> I have already been writing the driver of DMAengine, and I am testing.
>> To make old DMA-API coexist with dma engine in these patches, I wrote.
>>
> Ah, ok, I wasn't aware that that was what your intention was. In that
> case, once the Dreamcast fallout is fixed, I'll merge these.


Just come across this. I am happy to test any new patch on the
Dreamcast once it's done. Just let me know and kick me if I don't
respond.
--
To unsubscribe from this list: send the line "unsubscribe linux-sh" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Paul Mundt March 13, 2009, 3:09 p.m. UTC | #5
On Fri, Mar 13, 2009 at 12:05:25PM +0000, Adrian McMenamin wrote:
> 2009/3/10 Paul Mundt <lethal@linux-sh.org>:
> > On Tue, Mar 10, 2009 at 04:22:37PM +0900, Nobuhiro Iwamatsu wrote:
> >> Paul Mundt wrote:
> >> >On Tue, Mar 10, 2009 at 01:48:14PM +0900, Nobuhiro Iwamatsu wrote:
> 
>  ...
> 
> >> I see.
> >> I have already been writing the driver of DMAengine, and I am testing.
> >> To make old DMA-API coexist with dma engine in these patches, I wrote.
> >>
> > Ah, ok, I wasn't aware that that was what your intention was. In that
> > case, once the Dreamcast fallout is fixed, I'll merge these.
> 
> 
> Just come across this. I am happy to test any new patch on the
> Dreamcast once it's done. Just let me know and kick me if I don't
> respond.

The updated version of this is merged now, so please see if there are any
regressions in the current git tree.
--
To unsubscribe from this list: send the line "unsubscribe linux-sh" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Adrian McMenamin March 14, 2009, 1:12 a.m. UTC | #6
On Sat, 2009-03-14 at 00:09 +0900, Paul Mundt wrote:
> On Fri, Mar 13, 2009 at 12:05:25PM +0000, Adrian McMenamin wrote:
> > 2009/3/10 Paul Mundt <lethal@linux-sh.org>:
> > > On Tue, Mar 10, 2009 at 04:22:37PM +0900, Nobuhiro Iwamatsu wrote:
> > >> Paul Mundt wrote:
> > >> >On Tue, Mar 10, 2009 at 01:48:14PM +0900, Nobuhiro Iwamatsu wrote:
> > 
> >  ...
> > 
> > >> I see.
> > >> I have already been writing the driver of DMAengine, and I am testing.
> > >> To make old DMA-API coexist with dma engine in these patches, I wrote.
> > >>
> > > Ah, ok, I wasn't aware that that was what your intention was. In that
> > > case, once the Dreamcast fallout is fixed, I'll merge these.
> > 
> > 
> > Just come across this. I am happy to test any new patch on the
> > Dreamcast once it's done. Just let me know and kick me if I don't
> > respond.
> 
> The updated version of this is merged now, so please see if there are any
> regressions in the current git tree.


Doesn't work I'm afraid:

[    0.000000] Linux version 2.6.29-rc7-00215-g600fa57 (adrian@bossclass) (gcc version 4.2.2) #1 PREEMPT Sat Mar 14 00:53:47 GMT 2009
[    0.000000] Boot params:
[    0.000000] ... MOUNT_ROOT_RDONLY - 91f0c75f
[    0.000000] ... RAMDISK_FLAGS     - e1ff3018
[    0.000000] ... ORIG_ROOT_DEV     - 89093610
[    0.000000] ... LOADER_TYPE       - 3612e108
[    0.000000] ... INITRD_START      - 46088904
[    0.000000] ... INITRD_SIZE       - 6002306c
[    0.000000] console [sercon0] enabled
[    0.000000] Booting machvec: Sega Dreamcast
[    0.000000] Node 0: start_pfn = 0xc000, low = 0xd000
[    0.000000] Zone PFN ranges:
[    0.000000]   Normal   0x0000c000 -> 0x0000d000
[    0.000000] Movable zone start PFN for each node
[    0.000000] early_node_map[1] active PFN ranges
[    0.000000]     0: 0x0000c000 -> 0x0000d000
[    0.000000] Built 1 zonelists in Zone order, mobility grouping on.  Total pages: 4064
[    0.000000] Kernel command line: root=/dev/nfs rw nfsroot=192.168.61.50:/home/adrian/debdist ip=dhcp earlyprintk=serial video=pvr2fb:640x480-32@60 console=ttySC1 panic=7
[    0.000000] PID hash table entries: 64 (order: 6, 256 bytes)
[    0.000000] Using tmu for system timer
[    0.004322] Console: colour dummy device 80x25
[    0.009399] Dentry cache hash table entries: 2048 (order: 1, 8192 bytes)
[    0.016935] Inode-cache hash table entries: 1024 (order: 0, 4096 bytes)
[    0.026888] Memory: 12400k/16384k available (2456k kernel code, 623k data, 124k init)
[    0.035501] PVR=040205c1 CVR=00000000 PRR=00000000
[    0.040841] I-cache : n_ways=1 n_sets=256 way_incr=8192
[    0.046567] I-cache : entry_mask=0x00001fe0 alias_mask=0x00001000 n_aliases=2
[    0.054406] D-cache : n_ways=1 n_sets=512 way_incr=16384
[    0.060231] D-cache : entry_mask=0x00003fe0 alias_mask=0x00003000 n_aliases=4
[    0.068538] SLUB: Genslabs=10, HWalign=32, Order=0-3, MinObjects=0, CPUs=1, Nodes=1
[    0.077089] Calibrating delay loop (skipped)... 199.50 BogoMIPS PRESET (lpj=399012)
[    0.086987] Mount-cache hash table entries: 512
[    0.097040] CPU: SH7750
[    0.128986] net_namespace: 296 bytes
[    0.134762] NET: Registered protocol family 16
[    0.266443] bio: create slab <bio-0> at 0
[    0.292390] DMA: Registering DMA API.
[    0.297156] DMAC Address Error0 request_irq fail
[    0.302362] Fault in unaligned fixup: 0000 [#1]
[    0.307267] Modules linked in:
[    0.310696] 
[    0.312257] Pid : 1, Comm:           swapper
[    0.316168] CPU : 0                  Not tainted  (2.6.29-rc7-00215-g600fa57 #1)
[    0.316197] 
[    0.325248] PC is at request_dma+0x2c/0xc0
[    0.329693] PR is at request_dma+0x1e/0xc0
[    0.334162] PC  : 8c1c40cc SP  : 8cc1ff00 SR  : 400001f1 TEA : 0000001a
[    0.341421] R0  : 00000000 R1  : 40000101 R2  : 8c2feb94 R3  : 8c2feb94
[    0.348673] R4  : 00000002 R5  : 8c2bed08 R6  : 8cc47c58 R7  : 00000000
[    0.355926] R8  : ffffffea R9  : 00000000 R10 : 8c2bed08 R11 : 00000000
[    0.363165] R12 : 8c315500 R13 : 8c323064 R14 : 8cc1ff00
[    0.368990] MACH: 00000000 MACL: 00000a80 GBR : 00000000 PR  : 8c1c40be
[    0.376220] 
[    0.376234] Call trace:
[    0.380641] [<8c315516>] pvr2_dma_init+0x16/0x40
[    0.385669] [<8c002060>] do_one_initcall+0x0/0x1a0
[    0.390912] [<8c00208c>] do_one_initcall+0x2c/0x1a0
[    0.396261] [<8c04d1ee>] register_irq_proc+0x6e/0xc0
[    0.401696] [<8c04d27a>] init_irq_proc+0x3a/0x80
[    0.406753] [<8c04d180>] register_irq_proc+0x0/0xc0
[    0.412094] [<8c04a040>] irq_to_desc+0x0/0x40
[    0.416863] [<8c304528>] kernel_init+0x68/0x120
[    0.421908] [<8c002060>] do_one_initcall+0x0/0x1a0
[    0.427122] [<8c003c88>] kernel_thread_helper+0x8/0x20
[    0.432760] [<8c3044c0>] kernel_init+0x0/0x120
[    0.437621] [<8c003c80>] kernel_thread_helper+0x0/0x20
[    0.443317] 
[    0.444873] Code:
[    0.446971]   8c1c40c6:  ldc       r0, sr
[    0.451456]   8c1c40c8:  mov       r1, r0
[    0.455911]   8c1c40ca:  and       #-16, r0
[    0.460557] ->8c1c40cc:  mov.l     @(48,r8), r9
[    0.465623]   8c1c40ce:  mov       #1, r1
[    0.470090]   8c1c40d0:  tst       r0, r0
[    0.474580]   8c1c40d2:  mov.l     r1, @(48,r8)
[    0.479644]   8c1c40d4:  bt        8c1c40e0
[    0.484259]   8c1c40d6:  and       #-16, r0
[    0.488887] 
[    0.490453] Process: swapper (pid: 1, stack limit = 8cc1e001)
[    0.496744] Stack: (0x8cc1ff00 to 0x8cc20000)
[    0.501503] ff00: 8c315516 8cc1ff18 8c321718 8c32148c 8c002060 8c321530 8c00208c 8cc1ff20 
[    0.510632] ff20: 00000001 00000000 8c32ba48 8cc1fef8 8cc47600 8cc46d20 8c04d1ee 8cc1ff48 
[    0.519864] ff40: 8c2ee0a4 8cc1ff4a 3431ff14 00000032 00000000 8c04d27a 8cc1ff6c 8c04d180 
[    0.529019] ff60: 8c04a040 8c304528 8cc1ff84 00000000 00000000 8c321718 8c32148c 8c002060 
[    0.538237] ff80: 8c321530 8c003c88 8cc1ff9c 00000000 00000000 00000000 00000000 00000000 
[    0.547379] ffa0: 00000000 00000000 00000000 00000000 00000000 00000000 8c3044c0 00000000 
[    0.556470] ffc0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 
[    0.565759] ffe0: 8cc1ffa4 8c003c80 00000000 40000000 00000000 00000000 00000000 00000000 
[    0.575044] ---[ end trace 4eaa2a86a8e2da22 ]---
[    0.580220] Kernel panic - not syncing: Attempted to kill init!
[    0.586833] Rebooting in 7 seconds..


0x8c1c40cc corresponds to arch/sh/include/asm/cmpxchg-irq.h:9

0x8c1c40be is arch/sh/drivers/dma/dma-api.c:198

--
To unsubscribe from this list: send the line "unsubscribe linux-sh" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Nobuhiro Iwamatsu March 16, 2009, 2:18 a.m. UTC | #7
Hi, Adrian.

Thank you for your test!.

2009/3/14 Adrian McMenamin <adrian@newgolddream.dyndns.info>:
> On Sat, 2009-03-14 at 00:09 +0900, Paul Mundt wrote:
>> On Fri, Mar 13, 2009 at 12:05:25PM +0000, Adrian McMenamin wrote:
>> > 2009/3/10 Paul Mundt <lethal@linux-sh.org>:
>> > > On Tue, Mar 10, 2009 at 04:22:37PM +0900, Nobuhiro Iwamatsu wrote:
>> > >> Paul Mundt wrote:
>> > >> >On Tue, Mar 10, 2009 at 01:48:14PM +0900, Nobuhiro Iwamatsu wrote:
>> >
>> >  ...
>> >
>> > >> I see.
>> > >> I have already been writing the driver of DMAengine, and I am testing.
>> > >> To make old DMA-API coexist with dma engine in these patches, I wrote.
>> > >>
>> > > Ah, ok, I wasn't aware that that was what your intention was. In that
>> > > case, once the Dreamcast fallout is fixed, I'll merge these.
>> >
>> >
>> > Just come across this. I am happy to test any new patch on the
>> > Dreamcast once it's done. Just let me know and kick me if I don't
>> > respond.
>>
>> The updated version of this is merged now, so please see if there are any
>> regressions in the current git tree.
>
>
> Doesn't work I'm afraid:
>
> [    0.000000] Linux version 2.6.29-rc7-00215-g600fa57 (adrian@bossclass) (gcc version 4.2.2) #1 PREEMPT Sat Mar 14 00:53:47 GMT 2009
> [    0.000000] Boot params:
> [    0.000000] ... MOUNT_ROOT_RDONLY - 91f0c75f
> [    0.000000] ... RAMDISK_FLAGS     - e1ff3018
> [    0.000000] ... ORIG_ROOT_DEV     - 89093610
> [    0.000000] ... LOADER_TYPE       - 3612e108
> [    0.000000] ... INITRD_START      - 46088904
> [    0.000000] ... INITRD_SIZE       - 6002306c
> [    0.000000] console [sercon0] enabled
> [    0.000000] Booting machvec: Sega Dreamcast
> [    0.000000] Node 0: start_pfn = 0xc000, low = 0xd000
> [    0.000000] Zone PFN ranges:
> [    0.000000]   Normal   0x0000c000 -> 0x0000d000
> [    0.000000] Movable zone start PFN for each node
> [    0.000000] early_node_map[1] active PFN ranges
> [    0.000000]     0: 0x0000c000 -> 0x0000d000
> [    0.000000] Built 1 zonelists in Zone order, mobility grouping on.  Total pages: 4064
> [    0.000000] Kernel command line: root=/dev/nfs rw nfsroot=192.168.61.50:/home/adrian/debdist ip=dhcp earlyprintk=serial video=pvr2fb:640x480-32@60 console=ttySC1 panic=7
> [    0.000000] PID hash table entries: 64 (order: 6, 256 bytes)
> [    0.000000] Using tmu for system timer
> [    0.004322] Console: colour dummy device 80x25
> [    0.009399] Dentry cache hash table entries: 2048 (order: 1, 8192 bytes)
> [    0.016935] Inode-cache hash table entries: 1024 (order: 0, 4096 bytes)
> [    0.026888] Memory: 12400k/16384k available (2456k kernel code, 623k data, 124k init)
> [    0.035501] PVR=040205c1 CVR=00000000 PRR=00000000
> [    0.040841] I-cache : n_ways=1 n_sets=256 way_incr=8192
> [    0.046567] I-cache : entry_mask=0x00001fe0 alias_mask=0x00001000 n_aliases=2
> [    0.054406] D-cache : n_ways=1 n_sets=512 way_incr=16384
> [    0.060231] D-cache : entry_mask=0x00003fe0 alias_mask=0x00003000 n_aliases=4
> [    0.068538] SLUB: Genslabs=10, HWalign=32, Order=0-3, MinObjects=0, CPUs=1, Nodes=1
> [    0.077089] Calibrating delay loop (skipped)... 199.50 BogoMIPS PRESET (lpj=399012)
> [    0.086987] Mount-cache hash table entries: 512
> [    0.097040] CPU: SH7750
> [    0.128986] net_namespace: 296 bytes
> [    0.134762] NET: Registered protocol family 16
> [    0.266443] bio: create slab <bio-0> at 0
> [    0.292390] DMA: Registering DMA API.
> [    0.297156] DMAC Address Error0 request_irq fail
> [    0.302362] Fault in unaligned fixup: 0000 [#1]
> [    0.307267] Modules linked in:
> [    0.310696]
> [    0.312257] Pid : 1, Comm:           swapper
> [    0.316168] CPU : 0                  Not tainted  (2.6.29-rc7-00215-g600fa57 #1)
> [    0.316197]
> [    0.325248] PC is at request_dma+0x2c/0xc0
> [    0.329693] PR is at request_dma+0x1e/0xc0
> [    0.334162] PC  : 8c1c40cc SP  : 8cc1ff00 SR  : 400001f1 TEA : 0000001a
> [    0.341421] R0  : 00000000 R1  : 40000101 R2  : 8c2feb94 R3  : 8c2feb94
> [    0.348673] R4  : 00000002 R5  : 8c2bed08 R6  : 8cc47c58 R7  : 00000000
> [    0.355926] R8  : ffffffea R9  : 00000000 R10 : 8c2bed08 R11 : 00000000
> [    0.363165] R12 : 8c315500 R13 : 8c323064 R14 : 8cc1ff00
> [    0.368990] MACH: 00000000 MACL: 00000a80 GBR : 00000000 PR  : 8c1c40be
> [    0.376220]
> [    0.376234] Call trace:
> [    0.380641] [<8c315516>] pvr2_dma_init+0x16/0x40
> [    0.385669] [<8c002060>] do_one_initcall+0x0/0x1a0
> [    0.390912] [<8c00208c>] do_one_initcall+0x2c/0x1a0
> [    0.396261] [<8c04d1ee>] register_irq_proc+0x6e/0xc0
> [    0.401696] [<8c04d27a>] init_irq_proc+0x3a/0x80
> [    0.406753] [<8c04d180>] register_irq_proc+0x0/0xc0
> [    0.412094] [<8c04a040>] irq_to_desc+0x0/0x40
> [    0.416863] [<8c304528>] kernel_init+0x68/0x120
> [    0.421908] [<8c002060>] do_one_initcall+0x0/0x1a0
> [    0.427122] [<8c003c88>] kernel_thread_helper+0x8/0x20
> [    0.432760] [<8c3044c0>] kernel_init+0x0/0x120
> [    0.437621] [<8c003c80>] kernel_thread_helper+0x0/0x20
> [    0.443317]
> [    0.444873] Code:
> [    0.446971]   8c1c40c6:  ldc       r0, sr
> [    0.451456]   8c1c40c8:  mov       r1, r0
> [    0.455911]   8c1c40ca:  and       #-16, r0
> [    0.460557] ->8c1c40cc:  mov.l     @(48,r8), r9
> [    0.465623]   8c1c40ce:  mov       #1, r1
> [    0.470090]   8c1c40d0:  tst       r0, r0
> [    0.474580]   8c1c40d2:  mov.l     r1, @(48,r8)
> [    0.479644]   8c1c40d4:  bt        8c1c40e0
> [    0.484259]   8c1c40d6:  and       #-16, r0
> [    0.488887]
> [    0.490453] Process: swapper (pid: 1, stack limit = 8cc1e001)
> [    0.496744] Stack: (0x8cc1ff00 to 0x8cc20000)
> [    0.501503] ff00: 8c315516 8cc1ff18 8c321718 8c32148c 8c002060 8c321530 8c00208c 8cc1ff20
> [    0.510632] ff20: 00000001 00000000 8c32ba48 8cc1fef8 8cc47600 8cc46d20 8c04d1ee 8cc1ff48
> [    0.519864] ff40: 8c2ee0a4 8cc1ff4a 3431ff14 00000032 00000000 8c04d27a 8cc1ff6c 8c04d180
> [    0.529019] ff60: 8c04a040 8c304528 8cc1ff84 00000000 00000000 8c321718 8c32148c 8c002060
> [    0.538237] ff80: 8c321530 8c003c88 8cc1ff9c 00000000 00000000 00000000 00000000 00000000
> [    0.547379] ffa0: 00000000 00000000 00000000 00000000 00000000 00000000 8c3044c0 00000000
> [    0.556470] ffc0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
> [    0.565759] ffe0: 8cc1ffa4 8c003c80 00000000 40000000 00000000 00000000 00000000 00000000
> [    0.575044] ---[ end trace 4eaa2a86a8e2da22 ]---
> [    0.580220] Kernel panic - not syncing: Attempted to kill init!
> [    0.586833] Rebooting in 7 seconds..
>
>
> 0x8c1c40cc corresponds to arch/sh/include/asm/cmpxchg-irq.h:9
>
> 0x8c1c40be is arch/sh/drivers/dma/dma-api.c:198
This is because DMA-api of sh775x does not support multi-irq.
I will send a patch to revise.

Best regards,
 Nobuhiro

Patch
diff mbox

diff --git a/arch/sh/drivers/dma/Kconfig b/arch/sh/drivers/dma/Kconfig
index 0193636..57d95fc 100644
--- a/arch/sh/drivers/dma/Kconfig
+++ b/arch/sh/drivers/dma/Kconfig
@@ -12,10 +12,10 @@  config SH_DMA
 config NR_ONCHIP_DMA_CHANNELS
 	int
 	depends on SH_DMA
-	default "6" if CPU_SUBTYPE_SH7720 || CPU_SUBTYPE_SH7721
-	default "8" if CPU_SUBTYPE_SH7750R || CPU_SUBTYPE_SH7751R
-	default "12" if CPU_SUBTYPE_SH7780
-	default "4"
+	default "4" if CPU_SUBTYPE_SH7750 || CPU_SUBTYPE_SH7751 || CPU_SUBTYPE_SH7750S
+	default "8" if CPU_SUBTYPE_SH7750R || CPU_SUBTYPE_SH7751R || CPU_SUBTYPE_SH7760
+	default "12" if CPU_SUBTYPE_SH7723 || CPU_SUBTYPE_SH7780 || CPU_SUBTYPE_SH7785
+	default "6"
 	help
 	  This allows you to specify the number of channels that the on-chip
 	  DMAC supports. This will be 4 for SH7750/SH7751 and 8 for the
diff --git a/arch/sh/drivers/dma/dma-sh.c b/arch/sh/drivers/dma/dma-sh.c
index 50887a5..ab7b18d 100644
--- a/arch/sh/drivers/dma/dma-sh.c
+++ b/arch/sh/drivers/dma/dma-sh.c
@@ -17,28 +17,23 @@ 
 #include <mach-dreamcast/mach/dma.h>
 #include <asm/dma.h>
 #include <asm/io.h>
-#include "dma-sh.h"
-
-static int dmte_irq_map[] = {
-	DMTE0_IRQ,
-	DMTE1_IRQ,
-	DMTE2_IRQ,
-	DMTE3_IRQ,
-#if defined(CONFIG_CPU_SUBTYPE_SH7720)  ||	\
-    defined(CONFIG_CPU_SUBTYPE_SH7721)  ||	\
-    defined(CONFIG_CPU_SUBTYPE_SH7751R) ||	\
-    defined(CONFIG_CPU_SUBTYPE_SH7760)  ||	\
-    defined(CONFIG_CPU_SUBTYPE_SH7709)  ||	\
-    defined(CONFIG_CPU_SUBTYPE_SH7780)
-	DMTE4_IRQ,
-	DMTE5_IRQ,
+#include <asm/dma-sh.h>
+
+#if defined(CONFIG_CPU_SUBTYPE_SH7763)	|| \
+		defined(CONFIG_CPU_SUBTYPE_SH7764)	|| \
+		defined(CONFIG_CPU_SUBTYPE_SH7780)	|| \
+		defined(CONFIG_CPU_SUBTYPE_SH7785)
+#define DMAC_IRQ_MULTI	1
 #endif
-#if defined(CONFIG_CPU_SUBTYPE_SH7751R) ||	\
-    defined(CONFIG_CPU_SUBTYPE_SH7760)  ||	\
-    defined(CONFIG_CPU_SUBTYPE_SH7780)
-	DMTE6_IRQ,
-	DMTE7_IRQ,
+
+#if defined(DMAE1_IRQ)
+#define NR_DMAE		2
+#else
+#define NR_DMAE		1
 #endif
+
+static const char *dmae_name[] = {
+	"DMAC Address Error0", "DMAC Address Error1"
 };

 static inline unsigned int get_dmte_irq(unsigned int chan)
@@ -46,7 +41,14 @@  static inline unsigned int get_dmte_irq(unsigned int chan)
 	unsigned int irq = 0;
 	if (chan < ARRAY_SIZE(dmte_irq_map))
 		irq = dmte_irq_map[chan];
+
+#if defined(DMAC_IRQ_MULTI)
+	if (irq > DMTE6_IRQ)
+		return DMTE6_IRQ;
+	return DMTE0_IRQ;
+#else
 	return irq;
+#endif
 }

 /*
@@ -59,7 +61,7 @@  static inline unsigned int get_dmte_irq(unsigned int chan)
  */
 static inline unsigned int calc_xmit_shift(struct dma_channel *chan)
 {
-	u32 chcr = ctrl_inl(CHCR[chan->chan]);
+	u32 chcr = ctrl_inl(dma_base_addr[chan->chan] + CHCR);

 	return ts_shift[(chcr & CHCR_TS_MASK)>>CHCR_TS_SHIFT];
 }
@@ -75,13 +77,13 @@  static irqreturn_t dma_tei(int irq, void *dev_id)
 	struct dma_channel *chan = dev_id;
 	u32 chcr;

-	chcr = ctrl_inl(CHCR[chan->chan]);
+	chcr = ctrl_inl(dma_base_addr[chan->chan] + CHCR);

 	if (!(chcr & CHCR_TE))
 		return IRQ_NONE;

 	chcr &= ~(CHCR_IE | CHCR_DE);
-	ctrl_outl(chcr, CHCR[chan->chan]);
+	ctrl_outl(chcr, (dma_base_addr[chan->chan] + CHCR));

 	wake_up(&chan->wait_queue);

@@ -94,7 +96,12 @@  static int sh_dmac_request_dma(struct dma_channel *chan)
 		return 0;

 	return request_irq(get_dmte_irq(chan->chan), dma_tei,
-			   IRQF_DISABLED, chan->dev_id, chan);
+#if defined(DMAC_IRQ_MULTI)
+				IRQF_SHARED,
+#else
+				IRQF_DISABLED,
+#endif
+				chan->dev_id, chan);
 }

 static void sh_dmac_free_dma(struct dma_channel *chan)
@@ -115,7 +122,7 @@  sh_dmac_configure_channel(struct dma_channel *chan, unsigned long chcr)
 		chan->flags &= ~DMA_TEI_CAPABLE;
 	}

-	ctrl_outl(chcr, CHCR[chan->chan]);
+	ctrl_outl(chcr, (dma_base_addr[chan->chan] + CHCR));

 	chan->flags |= DMA_CONFIGURED;
 	return 0;
@@ -126,13 +133,13 @@  static void sh_dmac_enable_dma(struct dma_channel *chan)
 	int irq;
 	u32 chcr;

-	chcr = ctrl_inl(CHCR[chan->chan]);
+	chcr = ctrl_inl(dma_base_addr[chan->chan] + CHCR);
 	chcr |= CHCR_DE;

 	if (chan->flags & DMA_TEI_CAPABLE)
 		chcr |= CHCR_IE;

-	ctrl_outl(chcr, CHCR[chan->chan]);
+	ctrl_outl(chcr, (dma_base_addr[chan->chan] + CHCR));

 	if (chan->flags & DMA_TEI_CAPABLE) {
 		irq = get_dmte_irq(chan->chan);
@@ -150,9 +157,9 @@  static void sh_dmac_disable_dma(struct dma_channel *chan)
 		disable_irq(irq);
 	}

-	chcr = ctrl_inl(CHCR[chan->chan]);
+	chcr = ctrl_inl(dma_base_addr[chan->chan] + CHCR);
 	chcr &= ~(CHCR_DE | CHCR_TE | CHCR_IE);
-	ctrl_outl(chcr, CHCR[chan->chan]);
+	ctrl_outl(chcr, (dma_base_addr[chan->chan] + CHCR));
 }

 static int sh_dmac_xfer_dma(struct dma_channel *chan)
@@ -183,12 +190,13 @@  static int sh_dmac_xfer_dma(struct dma_channel *chan)
 	 */
 	if (chan->sar || (mach_is_dreamcast() &&
 			  chan->chan == PVR2_CASCADE_CHAN))
-		ctrl_outl(chan->sar, SAR[chan->chan]);
+		ctrl_outl(chan->sar, (dma_base_addr[chan->chan]+SAR));
 	if (chan->dar || (mach_is_dreamcast() &&
 			  chan->chan == PVR2_CASCADE_CHAN))
-		ctrl_outl(chan->dar, DAR[chan->chan]);
+		ctrl_outl(chan->dar, (dma_base_addr[chan->chan] + DAR));

-	ctrl_outl(chan->count >> calc_xmit_shift(chan), DMATCR[chan->chan]);
+	ctrl_outl(chan->count >> calc_xmit_shift(chan),
+		(dma_base_addr[chan->chan] + TCR));

 	sh_dmac_enable_dma(chan);

@@ -197,36 +205,26 @@  static int sh_dmac_xfer_dma(struct dma_channel *chan)

 static int sh_dmac_get_dma_residue(struct dma_channel *chan)
 {
-	if (!(ctrl_inl(CHCR[chan->chan]) & CHCR_DE))
+	if (!(ctrl_inl(dma_base_addr[chan->chan] + CHCR) & CHCR_DE))
 		return 0;

-	return ctrl_inl(DMATCR[chan->chan]) << calc_xmit_shift(chan);
+	return ctrl_inl(dma_base_addr[chan->chan] + TCR)
+		 << calc_xmit_shift(chan);
 }

-#if defined(CONFIG_CPU_SUBTYPE_SH7720) || \
-    defined(CONFIG_CPU_SUBTYPE_SH7721) || \
-    defined(CONFIG_CPU_SUBTYPE_SH7780) || \
-    defined(CONFIG_CPU_SUBTYPE_SH7709)
-#define dmaor_read_reg()	ctrl_inw(DMAOR)
-#define dmaor_write_reg(data)	ctrl_outw(data, DMAOR)
-#else
-#define dmaor_read_reg()	ctrl_inl(DMAOR)
-#define dmaor_write_reg(data)	ctrl_outl(data, DMAOR)
-#endif
-
-static inline int dmaor_reset(void)
+static inline int dmaor_reset(int no)
 {
-	unsigned long dmaor = dmaor_read_reg();
+	unsigned long dmaor = dmaor_read_reg(no);

 	/* Try to clear the error flags first, incase they are set */
 	dmaor &= ~(DMAOR_NMIF | DMAOR_AE);
-	dmaor_write_reg(dmaor);
+	dmaor_write_reg(no, dmaor);

 	dmaor |= DMAOR_INIT;
-	dmaor_write_reg(dmaor);
+	dmaor_write_reg(no, dmaor);

 	/* See if we got an error again */
-	if ((dmaor_read_reg() & (DMAOR_AE | DMAOR_NMIF))) {
+	if ((dmaor_read_reg(no) & (DMAOR_AE | DMAOR_NMIF))) {
 		printk(KERN_ERR "dma-sh: Can't initialize DMAOR.\n");
 		return -EINVAL;
 	}
@@ -237,10 +235,33 @@  static inline int dmaor_reset(void)
 #if defined(CONFIG_CPU_SH4)
 static irqreturn_t dma_err(int irq, void *dummy)
 {
-	dmaor_reset();
+#if defined(DMAC_IRQ_MULTI)
+	int cnt = 0;
+	switch (irq) {
+#if defined(DMTE6_IRQ) && defined(DMAE1_IRQ)
+	case DMTE6_IRQ:
+		cnt++;
+#endif
+	case DMTE0_IRQ:
+		if (dmaor_read_reg(cnt) & (DMAOR_NMIF | DMAOR_AE)) {
+			disable_irq(irq);
+			/* DMA multi and error IRQ */
+			return IRQ_HANDLED;
+		}
+	default:
+		return IRQ_NONE;
+	}
+#else
+	dmaor_reset(0);
+#if defined(CONFIG_CPU_SUBTYPE_SH7723)	|| \
+		defined(CONFIG_CPU_SUBTYPE_SH7780)	|| \
+		defined(CONFIG_CPU_SUBTYPE_SH7785)
+	dmaor_reset(1);
+#endif
 	disable_irq(irq);

 	return IRQ_HANDLED;
+#endif
 }
 #endif

@@ -259,24 +280,57 @@  static struct dma_info sh_dmac_info = {
 	.flags		= DMAC_CHANNELS_TEI_CAPABLE,
 };

+static unsigned int get_dma_error_irq(int n)
+{
+#if defined(DMAC_IRQ_MULTI)
+	return (n == 0) ? get_dmte_irq(0) : get_dmte_irq(6);
+#else
+	return (n == 0) ? DMAE0_IRQ :
+#if defined(DMAE1_IRQ)
+				DMAE1_IRQ;
+#else
+				-1;
+#endif
+#endif
+}
+
 static int __init sh_dmac_init(void)
 {
 	struct dma_info *info = &sh_dmac_info;
 	int i;

 #ifdef CONFIG_CPU_SH4
-	i = request_irq(DMAE_IRQ, dma_err, IRQF_DISABLED, "DMAC Address Error", 0);
-	if (unlikely(i < 0))
-		return i;
+	int n;
+
+	for (n = 0; n < NR_DMAE; n++) {
+		i = request_irq(get_dma_error_irq(n), dma_err,
+#if defined(DMAC_IRQ_MULTI)
+				IRQF_SHARED,
+#else
+				IRQF_DISABLED,
 #endif
+				dmae_name[n], (void *)dmae_name[n]);
+		if (unlikely(i < 0)) {
+			printk(KERN_ERR "%s request_irq fail\n", dmae_name[n]);
+			return i;
+		}
+	}
+#endif /* CONFIG_CPU_SH4 */

 	/*
 	 * Initialize DMAOR, and clean up any error flags that may have
 	 * been set.
 	 */
-	i = dmaor_reset();
+	i = dmaor_reset(0);
+	if (unlikely(i != 0))
+		return i;
+#if defined(CONFIG_CPU_SUBTYPE_SH7723)	|| \
+		defined(CONFIG_CPU_SUBTYPE_SH7780)	|| \
+		defined(CONFIG_CPU_SUBTYPE_SH7785)
+	i = dmaor_reset(1);
 	if (unlikely(i != 0))
 		return i;
+#endif

 	return register_dmac(info);
 }
@@ -284,8 +338,12 @@  static int __init sh_dmac_init(void)
 static void __exit sh_dmac_exit(void)
 {
 #ifdef CONFIG_CPU_SH4
-	free_irq(DMAE_IRQ, 0);
-#endif
+	int n;
+
+	for (n = 0; n < NR_DMAE; n++) {
+		free_irq(get_dma_error_irq(n), (void *)dmae_name[n]);
+	}
+#endif /* CONFIG_CPU_SH4 */
 	unregister_dmac(&sh_dmac_info);
 }

diff --git a/arch/sh/drivers/dma/dma-sh.h b/arch/sh/drivers/dma/dma-sh.h
deleted file mode 100644
index 05fecd5..0000000
--- a/arch/sh/drivers/dma/dma-sh.h
+++ /dev/null
@@ -1,75 +0,0 @@ 
-/*
- * arch/sh/drivers/dma/dma-sh.h
- *
- * Copyright (C) 2000  Takashi YOSHII
- * Copyright (C) 2003  Paul Mundt
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- */
-#ifndef __DMA_SH_H
-#define __DMA_SH_H
-
-#include <cpu/dma.h>
-
-/* Definitions for the SuperH DMAC */
-#define REQ_L	0x00000000
-#define REQ_E	0x00080000
-#define RACK_H	0x00000000
-#define RACK_L	0x00040000
-#define ACK_R	0x00000000
-#define ACK_W	0x00020000
-#define ACK_H	0x00000000
-#define ACK_L	0x00010000
-#define DM_INC	0x00004000
-#define DM_DEC	0x00008000
-#define SM_INC	0x00001000
-#define SM_DEC	0x00002000
-#define RS_IN	0x00000200
-#define RS_OUT	0x00000300
-#define TS_BLK	0x00000040
-#define TM_BUR	0x00000020
-#define CHCR_DE 0x00000001
-#define CHCR_TE 0x00000002
-#define CHCR_IE 0x00000004
-
-/* DMAOR definitions */
-#define DMAOR_AE	0x00000004
-#define DMAOR_NMIF	0x00000002
-#define DMAOR_DME	0x00000001
-
-/*
- * Define the default configuration for dual address memory-memory transfer.
- * The 0x400 value represents auto-request, external->external.
- */
-#define RS_DUAL	(DM_INC | SM_INC | 0x400 | TS_32)
-
-#define MAX_DMAC_CHANNELS	(CONFIG_NR_ONCHIP_DMA_CHANNELS)
-
-/*
- * Subtypes that have fewer channels than this simply need to change
- * CONFIG_NR_ONCHIP_DMA_CHANNELS. Likewise, subtypes with a larger number
- * of channels should expand on this.
- *
- * For most subtypes we can easily figure these values out with some
- * basic calculation, unfortunately on other subtypes these are more
- * scattered, so we just leave it unrolled for simplicity.
- */
-#define SAR	((unsigned long[]){SH_DMAC_BASE + 0x00, SH_DMAC_BASE + 0x10, \
-				   SH_DMAC_BASE + 0x20, SH_DMAC_BASE + 0x30, \
-				   SH_DMAC_BASE + 0x50, SH_DMAC_BASE + 0x60})
-#define DAR	((unsigned long[]){SH_DMAC_BASE + 0x04, SH_DMAC_BASE + 0x14, \
-				   SH_DMAC_BASE + 0x24, SH_DMAC_BASE + 0x34, \
-				   SH_DMAC_BASE + 0x54, SH_DMAC_BASE + 0x64})
-#define DMATCR	((unsigned long[]){SH_DMAC_BASE + 0x08, SH_DMAC_BASE + 0x18, \
-				   SH_DMAC_BASE + 0x28, SH_DMAC_BASE + 0x38, \
-				   SH_DMAC_BASE + 0x58, SH_DMAC_BASE + 0x68})
-#define CHCR	((unsigned long[]){SH_DMAC_BASE + 0x0c, SH_DMAC_BASE + 0x1c, \
-				   SH_DMAC_BASE + 0x2c, SH_DMAC_BASE + 0x3c, \
-				   SH_DMAC_BASE + 0x5c, SH_DMAC_BASE + 0x6c})
-
-#define DMAOR	(SH_DMAC_BASE + 0x40)
-
-#endif /* __DMA_SH_H */
-
diff --git a/arch/sh/include/asm/dma-sh.h b/arch/sh/include/asm/dma-sh.h
new file mode 100644
index 0000000..e873eca
--- /dev/null
+++ b/arch/sh/include/asm/dma-sh.h
@@ -0,0 +1,117 @@ 
+/*
+ * arch/sh/include/asm/dma-sh.h
+ *
+ * Copyright (C) 2000  Takashi YOSHII
+ * Copyright (C) 2003  Paul Mundt
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ */
+#ifndef __DMA_SH_H
+#define __DMA_SH_H
+
+#include <cpu/dma.h>
+
+/* DMAOR contorl: The DMAOR access size is different by CPU.*/
+#if defined(CONFIG_CPU_SUBTYPE_SH7723)	|| \
+    defined(CONFIG_CPU_SUBTYPE_SH7780)	|| \
+    defined(CONFIG_CPU_SUBTYPE_SH7785)
+#define dmaor_read_reg(n) \
+    (n ? ctrl_inw(SH_DMAC_BASE1 + DMAOR) \
+	: ctrl_inw(SH_DMAC_BASE0 + DMAOR))
+#define dmaor_write_reg(n, data) \
+    (n ? ctrl_outw(data, SH_DMAC_BASE1 + DMAOR) \
+    : ctrl_outw(data, SH_DMAC_BASE0 + DMAOR))
+#else /* Other CPU */
+#define dmaor_read_reg(n) ctrl_inw(SH_DMAC_BASE0 + DMAOR)
+#define dmaor_write_reg(n, data) ctrl_outw(data, SH_DMAC_BASE0 + DMAOR)
+#endif
+
+static int dmte_irq_map[] __maybe_unused = {
+#if (CONFIG_NR_ONCHIP_DMA_CHANNELS >= 4)
+    DMTE0_IRQ,
+    DMTE0_IRQ + 1,
+    DMTE0_IRQ + 2,
+    DMTE0_IRQ + 3,
+#endif
+#if (CONFIG_NR_ONCHIP_DMA_CHANNELS >= 6)
+    DMTE4_IRQ,
+    DMTE4_IRQ + 1,
+#endif
+#if (CONFIG_NR_ONCHIP_DMA_CHANNELS >= 8)
+    DMTE6_IRQ,
+    DMTE6_IRQ + 1,
+#endif
+#if (CONFIG_NR_ONCHIP_DMA_CHANNELS >= 12)
+    DMTE8_IRQ,
+    DMTE9_IRQ,
+    DMTE10_IRQ,
+    DMTE11_IRQ,
+#endif
+};
+
+/* Definitions for the SuperH DMAC */
+#define REQ_L	0x00000000
+#define REQ_E	0x00080000
+#define RACK_H	0x00000000
+#define RACK_L	0x00040000
+#define ACK_R	0x00000000
+#define ACK_W	0x00020000
+#define ACK_H	0x00000000
+#define ACK_L	0x00010000
+#define DM_INC	0x00004000
+#define DM_DEC	0x00008000
+#define SM_INC	0x00001000
+#define SM_DEC	0x00002000
+#define RS_IN	0x00000200
+#define RS_OUT	0x00000300
+#define TS_BLK	0x00000040
+#define TM_BUR	0x00000020
+#define CHCR_DE 0x00000001
+#define CHCR_TE 0x00000002
+#define CHCR_IE 0x00000004
+
+/* DMAOR definitions */
+#define DMAOR_AE	0x00000004
+#define DMAOR_NMIF	0x00000002
+#define DMAOR_DME	0x00000001
+
+/*
+ * Define the default configuration for dual address memory-memory transfer.
+ * The 0x400 value represents auto-request, external->external.
+ */
+#define RS_DUAL	(DM_INC | SM_INC | 0x400 | TS_32)
+
+/* DMA base address */
+static u32 dma_base_addr[] __maybe_unused = {
+#if (CONFIG_NR_ONCHIP_DMA_CHANNELS >= 4)
+	SH_DMAC_BASE0 + 0x00,	/* channel 0 */
+	SH_DMAC_BASE0 + 0x10,
+	SH_DMAC_BASE0 + 0x20,
+	SH_DMAC_BASE0 + 0x30,
+#endif
+#if (CONFIG_NR_ONCHIP_DMA_CHANNELS >= 6)
+	SH_DMAC_BASE0 + 0x50,
+	SH_DMAC_BASE0 + 0x60,
+#endif
+#if (CONFIG_NR_ONCHIP_DMA_CHANNELS >= 8)
+	SH_DMAC_BASE1 + 0x00,
+	SH_DMAC_BASE1 + 0x10,
+#endif
+#if (CONFIG_NR_ONCHIP_DMA_CHANNELS >= 12)
+	SH_DMAC_BASE1 + 0x20,
+	SH_DMAC_BASE1 + 0x30,
+	SH_DMAC_BASE1 + 0x50,
+	SH_DMAC_BASE1 + 0x60, /* channel 11 */
+#endif
+};
+
+/* DMA register */
+#define SAR     0x00
+#define DAR     0x04
+#define TCR     0x08
+#define CHCR    0x0C
+#define DMAOR	0x40
+
+#endif /* __DMA_SH_H */
diff --git a/arch/sh/include/asm/dma.h b/arch/sh/include/asm/dma.h
index beca712..085e05a 100644
--- a/arch/sh/include/asm/dma.h
+++ b/arch/sh/include/asm/dma.h
@@ -23,12 +23,8 @@ 
 /* But... */
 /* XXX: This is not applicable to SuperH, just needed for alloc_bootmem */
 #define MAX_DMA_ADDRESS		(PAGE_OFFSET+0x10000000)
-
-#ifdef CONFIG_NR_DMA_CHANNELS
-#  define MAX_DMA_CHANNELS	(CONFIG_NR_DMA_CHANNELS)
-#else
-#  define MAX_DMA_CHANNELS	(CONFIG_NR_ONCHIP_DMA_CHANNELS)
-#endif
+/* MAX DMA Channel */
+#define MAX_DMA_CHANNELS	(CONFIG_NR_ONCHIP_DMA_CHANNELS)

 /*
  * Read and write modes can mean drastically different things depending on the
diff --git a/arch/sh/include/cpu-sh3/cpu/dma.h b/arch/sh/include/cpu-sh3/cpu/dma.h
index 6813c32..0ea15f3 100644
--- a/arch/sh/include/cpu-sh3/cpu/dma.h
+++ b/arch/sh/include/cpu-sh3/cpu/dma.h
@@ -1,22 +1,17 @@ 
 #ifndef __ASM_CPU_SH3_DMA_H
 #define __ASM_CPU_SH3_DMA_H

-
 #if defined(CONFIG_CPU_SUBTYPE_SH7720) || \
-    defined(CONFIG_CPU_SUBTYPE_SH7721)
-#define SH_DMAC_BASE	0xa4010020
-#else
-#define SH_DMAC_BASE	0xa4000020
+    defined(CONFIG_CPU_SUBTYPE_SH7721) || \
+    defined(CONFIG_CPU_SUBTYPE_SH7710) || \
+    defined(CONFIG_CPU_SUBTYPE_SH7712)
+#define SH_DMAC_BASE0	0xa4010020
+#else /* SH7705/06/07/09 */
+#define SH_DMAC_BASE0	0xa4000020
 #endif

-#if defined(CONFIG_CPU_SUBTYPE_SH7720) || defined(CONFIG_CPU_SUBTYPE_SH7709)
 #define DMTE0_IRQ	48
-#define DMTE1_IRQ	49
-#define DMTE2_IRQ	50
-#define DMTE3_IRQ	51
 #define DMTE4_IRQ	76
-#define DMTE5_IRQ	77
-#endif

 /* Definitions for the SuperH DMAC */
 #define TM_BURST	0x00000020
diff --git a/arch/sh/include/cpu-sh4/cpu/dma-sh4a.h b/arch/sh/include/cpu-sh4/cpu/dma-sh4a.h
new file mode 100644
index 0000000..0ed5178
--- /dev/null
+++ b/arch/sh/include/cpu-sh4/cpu/dma-sh4a.h
@@ -0,0 +1,94 @@ 
+#ifndef __ASM_SH_CPU_SH4_DMA_SH7780_H
+#define __ASM_SH_CPU_SH4_DMA_SH7780_H
+
+#if defined(CONFIG_CPU_SUBTYPE_SH7343) || \
+	defined(CONFIG_CPU_SUBTYPE_SH7722) || \
+	defined(CONFIG_CPU_SUBTYPE_SH7730)
+#define DMTE0_IRQ	48
+#define DMTE4_IRQ	76
+#define DMAE0_IRQ	78	/* DMA Error IRQ*/
+#define SH_DMAC_BASE0	0xFE008020
+#define SH_DMARS_BASE	0xFE009000
+#elif defined(CONFIG_CPU_SUBTYPE_SH7763) || \
+	defined(CONFIG_CPU_SUBTYPE_SH7764)
+#define DMTE0_IRQ	34
+#define DMTE4_IRQ	44
+#define DMAE0_IRQ	38
+#define SH_DMAC_BASE0	0xFF608020
+#define SH_DMARS_BASE	0xFF609000
+#elif defined(CONFIG_CPU_SUBTYPE_SH7723)
+#define DMTE0_IRQ	48	/* DMAC0A*/
+#define DMTE4_IRQ	40	/* DMAC0B */
+#define DMTE6_IRQ	42
+#define DMTE8_IRQ	76	/* DMAC1A */
+#define DMTE9_IRQ	77
+#define DMTE10_IRQ	72	/* DMAC1B */
+#define DMTE11_IRQ	73
+#define DMAE0_IRQ	78	/* DMA Error IRQ*/
+#define DMAE1_IRQ	74	/* DMA Error IRQ*/
+#define SH_DMAC_BASE0	0xFE008020
+#define SH_DMAC_BASE1	0xFDC08020
+#define SH_DMARS_BASE	0xFDC09000
+#elif defined(CONFIG_CPU_SUBTYPE_SH7780)
+#define DMTE0_IRQ	34
+#define DMTE4_IRQ	44
+#define DMTE6_IRQ	46
+#define DMTE8_IRQ	92
+#define DMTE9_IRQ	93
+#define DMTE10_IRQ	94
+#define DMTE11_IRQ	95
+#define DMAE0_IRQ	38	/* DMA Error IRQ */
+#define SH_DMAC_BASE0	0xFC808020
+#define SH_DMAC_BASE1	0xFC818020
+#define SH_DMARS_BASE	0xFC809000
+#else /* SH7785 */
+#define DMTE0_IRQ	33
+#define DMTE4_IRQ	37
+#define DMTE6_IRQ	52
+#define DMTE8_IRQ	54
+#define DMTE9_IRQ	55
+#define DMTE10_IRQ	56
+#define DMTE11_IRQ	57
+#define DMAE0_IRQ	39	/* DMA Error IRQ0 */
+#define DMAE1_IRQ	58	/* DMA Error IRQ1 */
+#define SH_DMAC_BASE0	0xFC808020
+#define SH_DMAC_BASE1	0xFCC08020
+#define SH_DMARS_BASE	0xFC809000
+#endif
+
+#define REQ_HE	0x000000C0
+#define REQ_H	0x00000080
+#define REQ_LE	0x00000040
+#define TM_BURST 0x0000020
+#define TS_8	0x00000000
+#define TS_16	0x00000008
+#define TS_32	0x00000010
+#define TS_16BLK	0x00000018
+#define TS_32BLK	0x00100000
+
+/*
+ * The SuperH DMAC supports a number of transmit sizes, we list them here,
+ * with their respective values as they appear in the CHCR registers.
+ *
+ * Defaults to a 64-bit transfer size.
+ */
+enum {
+	XMIT_SZ_8BIT,
+	XMIT_SZ_16BIT,
+	XMIT_SZ_32BIT,
+	XMIT_SZ_128BIT,
+	XMIT_SZ_256BIT,
+};
+
+/*
+ * The DMA count is defined as the number of bytes to transfer.
+ */
+static unsigned int ts_shift[] __maybe_unused = {
+	[XMIT_SZ_8BIT]		= 0,
+	[XMIT_SZ_16BIT]		= 1,
+	[XMIT_SZ_32BIT]		= 2,
+	[XMIT_SZ_128BIT]	= 4,
+	[XMIT_SZ_256BIT]	= 5,
+};
+
+#endif /* __ASM_SH_CPU_SH4_DMA_SH7780_H */
diff --git a/arch/sh/include/cpu-sh4/cpu/dma-sh7780.h b/arch/sh/include/cpu-sh4/cpu/dma-sh7780.h
deleted file mode 100644
index 71b426a..0000000
--- a/arch/sh/include/cpu-sh4/cpu/dma-sh7780.h
+++ /dev/null
@@ -1,39 +0,0 @@ 
-#ifndef __ASM_SH_CPU_SH4_DMA_SH7780_H
-#define __ASM_SH_CPU_SH4_DMA_SH7780_H
-
-#define REQ_HE	0x000000C0
-#define REQ_H	0x00000080
-#define REQ_LE	0x00000040
-#define TM_BURST 0x0000020
-#define TS_8	0x00000000
-#define TS_16	0x00000008
-#define TS_32	0x00000010
-#define TS_16BLK	0x00000018
-#define TS_32BLK	0x00100000
-
-/*
- * The SuperH DMAC supports a number of transmit sizes, we list them here,
- * with their respective values as they appear in the CHCR registers.
- *
- * Defaults to a 64-bit transfer size.
- */
-enum {
-	XMIT_SZ_8BIT,
-	XMIT_SZ_16BIT,
-	XMIT_SZ_32BIT,
-	XMIT_SZ_128BIT,
-	XMIT_SZ_256BIT,
-};
-
-/*
- * The DMA count is defined as the number of bytes to transfer.
- */
-static unsigned int ts_shift[] __maybe_unused = {
-	[XMIT_SZ_8BIT]		= 0,
-	[XMIT_SZ_16BIT]		= 1,
-	[XMIT_SZ_32BIT]		= 2,
-	[XMIT_SZ_128BIT]	= 4,
-	[XMIT_SZ_256BIT]	= 5,
-};
-
-#endif /* __ASM_SH_CPU_SH4_DMA_SH7780_H */
diff --git a/arch/sh/include/cpu-sh4/cpu/dma.h b/arch/sh/include/cpu-sh4/cpu/dma.h
index 235b7cd..bcb3024 100644
--- a/arch/sh/include/cpu-sh4/cpu/dma.h
+++ b/arch/sh/include/cpu-sh4/cpu/dma.h
@@ -1,31 +1,29 @@ 
 #ifndef __ASM_CPU_SH4_DMA_H
 #define __ASM_CPU_SH4_DMA_H

-#define DMAOR_INIT	( 0x8000 | DMAOR_DME )
-
 /* SH7751/7760/7780 DMA IRQ sources */
-#define DMTE0_IRQ	34
-#define DMTE1_IRQ	35
-#define DMTE2_IRQ	36
-#define DMTE3_IRQ	37
-#define DMTE4_IRQ	44
-#define DMTE5_IRQ	45
-#define DMTE6_IRQ	46
-#define DMTE7_IRQ	47
-#define DMAE_IRQ	38

 #ifdef CONFIG_CPU_SH4A
-#define SH_DMAC_BASE	0xfc808020

+#define DMAOR_INIT	(DMAOR_DME)
 #define CHCR_TS_MASK	0x18
 #define CHCR_TS_SHIFT	3

-#include <cpu/dma-sh7780.h>
-#else
-#define SH_DMAC_BASE	0xffa00000
+#include <cpu/dma-sh4a.h>
+#else /* CONFIG_CPU_SH4A */
+/*
+ * SH7750/SH7751/SH7760
+ */
+#define DMTE0_IRQ	34
+#define DMTE4_IRQ	44
+#define DMTE6_IRQ	46
+#define DMAE0_IRQ	38

+#define DMAOR_INIT	(0x8000|DMAOR_DME)
+#define SH_DMAC_BASE0	0xffa00000
+#define SH_DMAC_BASE1	0xffa00070
 /* Definitions for the SuperH DMAC */
-#define TM_BURST	0x0000080
+#define TM_BURST	0x00000080
 #define TS_8		0x00000010
 #define TS_16		0x00000020
 #define TS_32		0x00000030