diff options
author | Pierre Ossman <drzeus@drzeus.cx> | 2005-09-03 18:56:54 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@evo.osdl.org> | 2005-09-05 03:06:14 -0400 |
commit | 795312e763569ce4df67e7a0ca726a9901358fa2 (patch) | |
tree | c04db2abe5b75fd8c5e40e4365aa9d267bc66b7d /arch/i386/kernel/i8237.c | |
parent | 2a23b5d1e119fd10e25b8e93464c8d549f5a5c5d (diff) |
[PATCH] ISA DMA suspend for i386
Reset the ISA DMA controller into a known state after a suspend. Primary
concern was reenabling the cascading DMA channel (4).
Signed-off-by: Pierre Ossman <drzeus@drzeus.cx>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'arch/i386/kernel/i8237.c')
-rw-r--r-- | arch/i386/kernel/i8237.c | 67 |
1 files changed, 67 insertions, 0 deletions
diff --git a/arch/i386/kernel/i8237.c b/arch/i386/kernel/i8237.c new file mode 100644 index 000000000000..c36d1c006c2f --- /dev/null +++ b/arch/i386/kernel/i8237.c | |||
@@ -0,0 +1,67 @@ | |||
1 | /* | ||
2 | * i8237.c: 8237A DMA controller suspend functions. | ||
3 | * | ||
4 | * Written by Pierre Ossman, 2005. | ||
5 | */ | ||
6 | |||
7 | #include <linux/init.h> | ||
8 | #include <linux/sysdev.h> | ||
9 | |||
10 | #include <asm/dma.h> | ||
11 | |||
12 | /* | ||
13 | * This module just handles suspend/resume issues with the | ||
14 | * 8237A DMA controller (used for ISA and LPC). | ||
15 | * Allocation is handled in kernel/dma.c and normal usage is | ||
16 | * in asm/dma.h. | ||
17 | */ | ||
18 | |||
19 | static int i8237A_resume(struct sys_device *dev) | ||
20 | { | ||
21 | unsigned long flags; | ||
22 | int i; | ||
23 | |||
24 | flags = claim_dma_lock(); | ||
25 | |||
26 | dma_outb(DMA1_RESET_REG, 0); | ||
27 | dma_outb(DMA2_RESET_REG, 0); | ||
28 | |||
29 | for (i = 0;i < 8;i++) { | ||
30 | set_dma_addr(i, 0x000000); | ||
31 | /* DMA count is a bit weird so this is not 0 */ | ||
32 | set_dma_count(i, 1); | ||
33 | } | ||
34 | |||
35 | /* Enable cascade DMA or channel 0-3 won't work */ | ||
36 | enable_dma(4); | ||
37 | |||
38 | release_dma_lock(flags); | ||
39 | |||
40 | return 0; | ||
41 | } | ||
42 | |||
43 | static int i8237A_suspend(struct sys_device *dev, pm_message_t state) | ||
44 | { | ||
45 | return 0; | ||
46 | } | ||
47 | |||
48 | static struct sysdev_class i8237_sysdev_class = { | ||
49 | set_kset_name("i8237"), | ||
50 | .suspend = i8237A_suspend, | ||
51 | .resume = i8237A_resume, | ||
52 | }; | ||
53 | |||
54 | static struct sys_device device_i8237A = { | ||
55 | .id = 0, | ||
56 | .cls = &i8237_sysdev_class, | ||
57 | }; | ||
58 | |||
59 | static int __init i8237A_init_sysfs(void) | ||
60 | { | ||
61 | int error = sysdev_class_register(&i8237_sysdev_class); | ||
62 | if (!error) | ||
63 | error = sysdev_register(&device_i8237A); | ||
64 | return error; | ||
65 | } | ||
66 | |||
67 | device_initcall(i8237A_init_sysfs); | ||