diff options
author | Manuel Lauss <manuel.lauss@googlemail.com> | 2010-04-14 14:33:44 -0400 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 2010-05-21 16:31:15 -0400 |
commit | 96d660c482e03b2d7b6c0245b95a7cce537606c8 (patch) | |
tree | c414bcdc389770516cc53308540171e510e0dcc0 /arch/mips | |
parent | 0f0d85bcc332ec8f0957378ea5fa3e553f80ae4b (diff) |
MIPS: Alchemy: add sysdev for DBDMA PM.
Add a sysdev for DBDMA PM.
Signed-off-by: Manuel Lauss <manuel.lauss@gmail.com>
To: Linux-MIPS <linux-mips@linux-mips.org>
Patchwork: http://patchwork.linux-mips.org/patch/1119/
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
Diffstat (limited to 'arch/mips')
-rw-r--r-- | arch/mips/alchemy/common/dbdma.c | 101 | ||||
-rw-r--r-- | arch/mips/alchemy/common/power.c | 11 | ||||
-rw-r--r-- | arch/mips/include/asm/mach-au1x00/au1xxx_dbdma.h | 4 |
3 files changed, 72 insertions, 44 deletions
diff --git a/arch/mips/alchemy/common/dbdma.c b/arch/mips/alchemy/common/dbdma.c index 99ae84ce5af3..ca0506a8585a 100644 --- a/arch/mips/alchemy/common/dbdma.c +++ b/arch/mips/alchemy/common/dbdma.c | |||
@@ -36,6 +36,7 @@ | |||
36 | #include <linux/spinlock.h> | 36 | #include <linux/spinlock.h> |
37 | #include <linux/interrupt.h> | 37 | #include <linux/interrupt.h> |
38 | #include <linux/module.h> | 38 | #include <linux/module.h> |
39 | #include <linux/sysdev.h> | ||
39 | #include <asm/mach-au1x00/au1000.h> | 40 | #include <asm/mach-au1x00/au1000.h> |
40 | #include <asm/mach-au1x00/au1xxx_dbdma.h> | 41 | #include <asm/mach-au1x00/au1xxx_dbdma.h> |
41 | 42 | ||
@@ -174,10 +175,6 @@ static dbdev_tab_t dbdev_tab[] = { | |||
174 | 175 | ||
175 | #define DBDEV_TAB_SIZE ARRAY_SIZE(dbdev_tab) | 176 | #define DBDEV_TAB_SIZE ARRAY_SIZE(dbdev_tab) |
176 | 177 | ||
177 | #ifdef CONFIG_PM | ||
178 | static u32 au1xxx_dbdma_pm_regs[NUM_DBDMA_CHANS + 1][6]; | ||
179 | #endif | ||
180 | |||
181 | 178 | ||
182 | static chan_tab_t *chan_tab_ptr[NUM_DBDMA_CHANS]; | 179 | static chan_tab_t *chan_tab_ptr[NUM_DBDMA_CHANS]; |
183 | 180 | ||
@@ -960,29 +957,37 @@ u32 au1xxx_dbdma_put_dscr(u32 chanid, au1x_ddma_desc_t *dscr) | |||
960 | return nbytes; | 957 | return nbytes; |
961 | } | 958 | } |
962 | 959 | ||
963 | #ifdef CONFIG_PM | 960 | |
964 | void au1xxx_dbdma_suspend(void) | 961 | struct alchemy_dbdma_sysdev { |
962 | struct sys_device sysdev; | ||
963 | u32 pm_regs[NUM_DBDMA_CHANS + 1][6]; | ||
964 | }; | ||
965 | |||
966 | static int alchemy_dbdma_suspend(struct sys_device *dev, | ||
967 | pm_message_t state) | ||
965 | { | 968 | { |
969 | struct alchemy_dbdma_sysdev *sdev = | ||
970 | container_of(dev, struct alchemy_dbdma_sysdev, sysdev); | ||
966 | int i; | 971 | int i; |
967 | u32 addr; | 972 | u32 addr; |
968 | 973 | ||
969 | addr = DDMA_GLOBAL_BASE; | 974 | addr = DDMA_GLOBAL_BASE; |
970 | au1xxx_dbdma_pm_regs[0][0] = au_readl(addr + 0x00); | 975 | sdev->pm_regs[0][0] = au_readl(addr + 0x00); |
971 | au1xxx_dbdma_pm_regs[0][1] = au_readl(addr + 0x04); | 976 | sdev->pm_regs[0][1] = au_readl(addr + 0x04); |
972 | au1xxx_dbdma_pm_regs[0][2] = au_readl(addr + 0x08); | 977 | sdev->pm_regs[0][2] = au_readl(addr + 0x08); |
973 | au1xxx_dbdma_pm_regs[0][3] = au_readl(addr + 0x0c); | 978 | sdev->pm_regs[0][3] = au_readl(addr + 0x0c); |
974 | 979 | ||
975 | /* save channel configurations */ | 980 | /* save channel configurations */ |
976 | for (i = 1, addr = DDMA_CHANNEL_BASE; i <= NUM_DBDMA_CHANS; i++) { | 981 | for (i = 1, addr = DDMA_CHANNEL_BASE; i <= NUM_DBDMA_CHANS; i++) { |
977 | au1xxx_dbdma_pm_regs[i][0] = au_readl(addr + 0x00); | 982 | sdev->pm_regs[i][0] = au_readl(addr + 0x00); |
978 | au1xxx_dbdma_pm_regs[i][1] = au_readl(addr + 0x04); | 983 | sdev->pm_regs[i][1] = au_readl(addr + 0x04); |
979 | au1xxx_dbdma_pm_regs[i][2] = au_readl(addr + 0x08); | 984 | sdev->pm_regs[i][2] = au_readl(addr + 0x08); |
980 | au1xxx_dbdma_pm_regs[i][3] = au_readl(addr + 0x0c); | 985 | sdev->pm_regs[i][3] = au_readl(addr + 0x0c); |
981 | au1xxx_dbdma_pm_regs[i][4] = au_readl(addr + 0x10); | 986 | sdev->pm_regs[i][4] = au_readl(addr + 0x10); |
982 | au1xxx_dbdma_pm_regs[i][5] = au_readl(addr + 0x14); | 987 | sdev->pm_regs[i][5] = au_readl(addr + 0x14); |
983 | 988 | ||
984 | /* halt channel */ | 989 | /* halt channel */ |
985 | au_writel(au1xxx_dbdma_pm_regs[i][0] & ~1, addr + 0x00); | 990 | au_writel(sdev->pm_regs[i][0] & ~1, addr + 0x00); |
986 | au_sync(); | 991 | au_sync(); |
987 | while (!(au_readl(addr + 0x14) & 1)) | 992 | while (!(au_readl(addr + 0x14) & 1)) |
988 | au_sync(); | 993 | au_sync(); |
@@ -992,32 +997,65 @@ void au1xxx_dbdma_suspend(void) | |||
992 | /* disable channel interrupts */ | 997 | /* disable channel interrupts */ |
993 | au_writel(0, DDMA_GLOBAL_BASE + 0x0c); | 998 | au_writel(0, DDMA_GLOBAL_BASE + 0x0c); |
994 | au_sync(); | 999 | au_sync(); |
1000 | |||
1001 | return 0; | ||
995 | } | 1002 | } |
996 | 1003 | ||
997 | void au1xxx_dbdma_resume(void) | 1004 | static int alchemy_dbdma_resume(struct sys_device *dev) |
998 | { | 1005 | { |
1006 | struct alchemy_dbdma_sysdev *sdev = | ||
1007 | container_of(dev, struct alchemy_dbdma_sysdev, sysdev); | ||
999 | int i; | 1008 | int i; |
1000 | u32 addr; | 1009 | u32 addr; |
1001 | 1010 | ||
1002 | addr = DDMA_GLOBAL_BASE; | 1011 | addr = DDMA_GLOBAL_BASE; |
1003 | au_writel(au1xxx_dbdma_pm_regs[0][0], addr + 0x00); | 1012 | au_writel(sdev->pm_regs[0][0], addr + 0x00); |
1004 | au_writel(au1xxx_dbdma_pm_regs[0][1], addr + 0x04); | 1013 | au_writel(sdev->pm_regs[0][1], addr + 0x04); |
1005 | au_writel(au1xxx_dbdma_pm_regs[0][2], addr + 0x08); | 1014 | au_writel(sdev->pm_regs[0][2], addr + 0x08); |
1006 | au_writel(au1xxx_dbdma_pm_regs[0][3], addr + 0x0c); | 1015 | au_writel(sdev->pm_regs[0][3], addr + 0x0c); |
1007 | 1016 | ||
1008 | /* restore channel configurations */ | 1017 | /* restore channel configurations */ |
1009 | for (i = 1, addr = DDMA_CHANNEL_BASE; i <= NUM_DBDMA_CHANS; i++) { | 1018 | for (i = 1, addr = DDMA_CHANNEL_BASE; i <= NUM_DBDMA_CHANS; i++) { |
1010 | au_writel(au1xxx_dbdma_pm_regs[i][0], addr + 0x00); | 1019 | au_writel(sdev->pm_regs[i][0], addr + 0x00); |
1011 | au_writel(au1xxx_dbdma_pm_regs[i][1], addr + 0x04); | 1020 | au_writel(sdev->pm_regs[i][1], addr + 0x04); |
1012 | au_writel(au1xxx_dbdma_pm_regs[i][2], addr + 0x08); | 1021 | au_writel(sdev->pm_regs[i][2], addr + 0x08); |
1013 | au_writel(au1xxx_dbdma_pm_regs[i][3], addr + 0x0c); | 1022 | au_writel(sdev->pm_regs[i][3], addr + 0x0c); |
1014 | au_writel(au1xxx_dbdma_pm_regs[i][4], addr + 0x10); | 1023 | au_writel(sdev->pm_regs[i][4], addr + 0x10); |
1015 | au_writel(au1xxx_dbdma_pm_regs[i][5], addr + 0x14); | 1024 | au_writel(sdev->pm_regs[i][5], addr + 0x14); |
1016 | au_sync(); | 1025 | au_sync(); |
1017 | addr += 0x100; /* next channel base */ | 1026 | addr += 0x100; /* next channel base */ |
1018 | } | 1027 | } |
1028 | |||
1029 | return 0; | ||
1030 | } | ||
1031 | |||
1032 | static struct sysdev_class alchemy_dbdma_sysdev_class = { | ||
1033 | .name = "dbdma", | ||
1034 | .suspend = alchemy_dbdma_suspend, | ||
1035 | .resume = alchemy_dbdma_resume, | ||
1036 | }; | ||
1037 | |||
1038 | static int __init alchemy_dbdma_sysdev_init(void) | ||
1039 | { | ||
1040 | struct alchemy_dbdma_sysdev *sdev; | ||
1041 | int ret; | ||
1042 | |||
1043 | ret = sysdev_class_register(&alchemy_dbdma_sysdev_class); | ||
1044 | if (ret) | ||
1045 | return ret; | ||
1046 | |||
1047 | sdev = kzalloc(sizeof(struct alchemy_dbdma_sysdev), GFP_KERNEL); | ||
1048 | if (!sdev) | ||
1049 | return -ENOMEM; | ||
1050 | |||
1051 | sdev->sysdev.id = -1; | ||
1052 | sdev->sysdev.cls = &alchemy_dbdma_sysdev_class; | ||
1053 | ret = sysdev_register(&sdev->sysdev); | ||
1054 | if (ret) | ||
1055 | kfree(sdev); | ||
1056 | |||
1057 | return ret; | ||
1019 | } | 1058 | } |
1020 | #endif /* CONFIG_PM */ | ||
1021 | 1059 | ||
1022 | static int __init au1xxx_dbdma_init(void) | 1060 | static int __init au1xxx_dbdma_init(void) |
1023 | { | 1061 | { |
@@ -1046,6 +1084,11 @@ static int __init au1xxx_dbdma_init(void) | |||
1046 | else { | 1084 | else { |
1047 | dbdma_initialized = 1; | 1085 | dbdma_initialized = 1; |
1048 | printk(KERN_INFO "Alchemy DBDMA initialized\n"); | 1086 | printk(KERN_INFO "Alchemy DBDMA initialized\n"); |
1087 | ret = alchemy_dbdma_sysdev_init(); | ||
1088 | if (ret) { | ||
1089 | printk(KERN_ERR "DBDMA PM init failed\n"); | ||
1090 | ret = 0; | ||
1091 | } | ||
1049 | } | 1092 | } |
1050 | 1093 | ||
1051 | return ret; | 1094 | return ret; |
diff --git a/arch/mips/alchemy/common/power.c b/arch/mips/alchemy/common/power.c index 11e5ec748414..14eb8c492da2 100644 --- a/arch/mips/alchemy/common/power.c +++ b/arch/mips/alchemy/common/power.c | |||
@@ -36,9 +36,6 @@ | |||
36 | 36 | ||
37 | #include <asm/uaccess.h> | 37 | #include <asm/uaccess.h> |
38 | #include <asm/mach-au1x00/au1000.h> | 38 | #include <asm/mach-au1x00/au1000.h> |
39 | #if defined(CONFIG_SOC_AU1550) || defined(CONFIG_SOC_AU1200) | ||
40 | #include <asm/mach-au1x00/au1xxx_dbdma.h> | ||
41 | #endif | ||
42 | 39 | ||
43 | #ifdef CONFIG_PM | 40 | #ifdef CONFIG_PM |
44 | 41 | ||
@@ -129,10 +126,6 @@ static void save_core_regs(void) | |||
129 | sleep_static_memctlr[3][0] = au_readl(MEM_STCFG3); | 126 | sleep_static_memctlr[3][0] = au_readl(MEM_STCFG3); |
130 | sleep_static_memctlr[3][1] = au_readl(MEM_STTIME3); | 127 | sleep_static_memctlr[3][1] = au_readl(MEM_STTIME3); |
131 | sleep_static_memctlr[3][2] = au_readl(MEM_STADDR3); | 128 | sleep_static_memctlr[3][2] = au_readl(MEM_STADDR3); |
132 | |||
133 | #if defined(CONFIG_SOC_AU1550) || defined(CONFIG_SOC_AU1200) | ||
134 | au1xxx_dbdma_suspend(); | ||
135 | #endif | ||
136 | } | 129 | } |
137 | 130 | ||
138 | static void restore_core_regs(void) | 131 | static void restore_core_regs(void) |
@@ -196,10 +189,6 @@ static void restore_core_regs(void) | |||
196 | au_writel(sleep_uart0_linectl, UART0_ADDR + UART_LCR); au_sync(); | 189 | au_writel(sleep_uart0_linectl, UART0_ADDR + UART_LCR); au_sync(); |
197 | au_writel(sleep_uart0_clkdiv, UART0_ADDR + UART_CLK); au_sync(); | 190 | au_writel(sleep_uart0_clkdiv, UART0_ADDR + UART_CLK); au_sync(); |
198 | } | 191 | } |
199 | |||
200 | #if defined(CONFIG_SOC_AU1550) || defined(CONFIG_SOC_AU1200) | ||
201 | au1xxx_dbdma_resume(); | ||
202 | #endif | ||
203 | } | 192 | } |
204 | 193 | ||
205 | void au_sleep(void) | 194 | void au_sleep(void) |
diff --git a/arch/mips/include/asm/mach-au1x00/au1xxx_dbdma.h b/arch/mips/include/asm/mach-au1x00/au1xxx_dbdma.h index 8c6b1105ce0b..c8a553a36ba4 100644 --- a/arch/mips/include/asm/mach-au1x00/au1xxx_dbdma.h +++ b/arch/mips/include/asm/mach-au1x00/au1xxx_dbdma.h | |||
@@ -358,10 +358,6 @@ u32 au1xxx_dbdma_put_dscr(u32 chanid, au1x_ddma_desc_t *dscr); | |||
358 | u32 au1xxx_ddma_add_device(dbdev_tab_t *dev); | 358 | u32 au1xxx_ddma_add_device(dbdev_tab_t *dev); |
359 | extern void au1xxx_ddma_del_device(u32 devid); | 359 | extern void au1xxx_ddma_del_device(u32 devid); |
360 | void *au1xxx_ddma_get_nextptr_virt(au1x_ddma_desc_t *dp); | 360 | void *au1xxx_ddma_get_nextptr_virt(au1x_ddma_desc_t *dp); |
361 | #ifdef CONFIG_PM | ||
362 | void au1xxx_dbdma_suspend(void); | ||
363 | void au1xxx_dbdma_resume(void); | ||
364 | #endif | ||
365 | 361 | ||
366 | /* | 362 | /* |
367 | * Flags for the put_source/put_dest functions. | 363 | * Flags for the put_source/put_dest functions. |