aboutsummaryrefslogtreecommitdiffstats
path: root/arch/mips/alchemy
diff options
context:
space:
mode:
authorManuel Lauss <manuel.lauss@googlemail.com>2010-04-14 14:33:44 -0400
committerRalf Baechle <ralf@linux-mips.org>2010-05-21 16:31:15 -0400
commit96d660c482e03b2d7b6c0245b95a7cce537606c8 (patch)
treec414bcdc389770516cc53308540171e510e0dcc0 /arch/mips/alchemy
parent0f0d85bcc332ec8f0957378ea5fa3e553f80ae4b (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/alchemy')
-rw-r--r--arch/mips/alchemy/common/dbdma.c101
-rw-r--r--arch/mips/alchemy/common/power.c11
2 files changed, 72 insertions, 40 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
178static u32 au1xxx_dbdma_pm_regs[NUM_DBDMA_CHANS + 1][6];
179#endif
180
181 178
182static chan_tab_t *chan_tab_ptr[NUM_DBDMA_CHANS]; 179static 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
964void au1xxx_dbdma_suspend(void) 961struct alchemy_dbdma_sysdev {
962 struct sys_device sysdev;
963 u32 pm_regs[NUM_DBDMA_CHANS + 1][6];
964};
965
966static 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
997void au1xxx_dbdma_resume(void) 1004static 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
1032static struct sysdev_class alchemy_dbdma_sysdev_class = {
1033 .name = "dbdma",
1034 .suspend = alchemy_dbdma_suspend,
1035 .resume = alchemy_dbdma_resume,
1036};
1037
1038static 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
1022static int __init au1xxx_dbdma_init(void) 1060static 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
138static void restore_core_regs(void) 131static 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
205void au_sleep(void) 194void au_sleep(void)