Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

Manuel Lauss and committed by
Ralf Baechle
96d660c4 0f0d85bc

+72 -44
+72 -29
arch/mips/alchemy/common/dbdma.c
··· 36 36 #include <linux/spinlock.h> 37 37 #include <linux/interrupt.h> 38 38 #include <linux/module.h> 39 + #include <linux/sysdev.h> 39 40 #include <asm/mach-au1x00/au1000.h> 40 41 #include <asm/mach-au1x00/au1xxx_dbdma.h> 41 42 ··· 174 173 }; 175 174 176 175 #define DBDEV_TAB_SIZE ARRAY_SIZE(dbdev_tab) 177 - 178 - #ifdef CONFIG_PM 179 - static u32 au1xxx_dbdma_pm_regs[NUM_DBDMA_CHANS + 1][6]; 180 - #endif 181 176 182 177 183 178 static chan_tab_t *chan_tab_ptr[NUM_DBDMA_CHANS]; ··· 957 960 return nbytes; 958 961 } 959 962 960 - #ifdef CONFIG_PM 961 - void au1xxx_dbdma_suspend(void) 963 + 964 + struct alchemy_dbdma_sysdev { 965 + struct sys_device sysdev; 966 + u32 pm_regs[NUM_DBDMA_CHANS + 1][6]; 967 + }; 968 + 969 + static int alchemy_dbdma_suspend(struct sys_device *dev, 970 + pm_message_t state) 962 971 { 972 + struct alchemy_dbdma_sysdev *sdev = 973 + container_of(dev, struct alchemy_dbdma_sysdev, sysdev); 963 974 int i; 964 975 u32 addr; 965 976 966 977 addr = DDMA_GLOBAL_BASE; 967 - au1xxx_dbdma_pm_regs[0][0] = au_readl(addr + 0x00); 968 - au1xxx_dbdma_pm_regs[0][1] = au_readl(addr + 0x04); 969 - au1xxx_dbdma_pm_regs[0][2] = au_readl(addr + 0x08); 970 - au1xxx_dbdma_pm_regs[0][3] = au_readl(addr + 0x0c); 978 + sdev->pm_regs[0][0] = au_readl(addr + 0x00); 979 + sdev->pm_regs[0][1] = au_readl(addr + 0x04); 980 + sdev->pm_regs[0][2] = au_readl(addr + 0x08); 981 + sdev->pm_regs[0][3] = au_readl(addr + 0x0c); 971 982 972 983 /* save channel configurations */ 973 984 for (i = 1, addr = DDMA_CHANNEL_BASE; i <= NUM_DBDMA_CHANS; i++) { 974 - au1xxx_dbdma_pm_regs[i][0] = au_readl(addr + 0x00); 975 - au1xxx_dbdma_pm_regs[i][1] = au_readl(addr + 0x04); 976 - au1xxx_dbdma_pm_regs[i][2] = au_readl(addr + 0x08); 977 - au1xxx_dbdma_pm_regs[i][3] = au_readl(addr + 0x0c); 978 - au1xxx_dbdma_pm_regs[i][4] = au_readl(addr + 0x10); 979 - au1xxx_dbdma_pm_regs[i][5] = au_readl(addr + 0x14); 985 + sdev->pm_regs[i][0] = au_readl(addr + 0x00); 986 + sdev->pm_regs[i][1] = au_readl(addr + 0x04); 987 + sdev->pm_regs[i][2] = au_readl(addr + 0x08); 988 + sdev->pm_regs[i][3] = au_readl(addr + 0x0c); 989 + sdev->pm_regs[i][4] = au_readl(addr + 0x10); 990 + sdev->pm_regs[i][5] = au_readl(addr + 0x14); 980 991 981 992 /* halt channel */ 982 - au_writel(au1xxx_dbdma_pm_regs[i][0] & ~1, addr + 0x00); 993 + au_writel(sdev->pm_regs[i][0] & ~1, addr + 0x00); 983 994 au_sync(); 984 995 while (!(au_readl(addr + 0x14) & 1)) 985 996 au_sync(); ··· 997 992 /* disable channel interrupts */ 998 993 au_writel(0, DDMA_GLOBAL_BASE + 0x0c); 999 994 au_sync(); 995 + 996 + return 0; 1000 997 } 1001 998 1002 - void au1xxx_dbdma_resume(void) 999 + static int alchemy_dbdma_resume(struct sys_device *dev) 1003 1000 { 1001 + struct alchemy_dbdma_sysdev *sdev = 1002 + container_of(dev, struct alchemy_dbdma_sysdev, sysdev); 1004 1003 int i; 1005 1004 u32 addr; 1006 1005 1007 1006 addr = DDMA_GLOBAL_BASE; 1008 - au_writel(au1xxx_dbdma_pm_regs[0][0], addr + 0x00); 1009 - au_writel(au1xxx_dbdma_pm_regs[0][1], addr + 0x04); 1010 - au_writel(au1xxx_dbdma_pm_regs[0][2], addr + 0x08); 1011 - au_writel(au1xxx_dbdma_pm_regs[0][3], addr + 0x0c); 1007 + au_writel(sdev->pm_regs[0][0], addr + 0x00); 1008 + au_writel(sdev->pm_regs[0][1], addr + 0x04); 1009 + au_writel(sdev->pm_regs[0][2], addr + 0x08); 1010 + au_writel(sdev->pm_regs[0][3], addr + 0x0c); 1012 1011 1013 1012 /* restore channel configurations */ 1014 1013 for (i = 1, addr = DDMA_CHANNEL_BASE; i <= NUM_DBDMA_CHANS; i++) { 1015 - au_writel(au1xxx_dbdma_pm_regs[i][0], addr + 0x00); 1016 - au_writel(au1xxx_dbdma_pm_regs[i][1], addr + 0x04); 1017 - au_writel(au1xxx_dbdma_pm_regs[i][2], addr + 0x08); 1018 - au_writel(au1xxx_dbdma_pm_regs[i][3], addr + 0x0c); 1019 - au_writel(au1xxx_dbdma_pm_regs[i][4], addr + 0x10); 1020 - au_writel(au1xxx_dbdma_pm_regs[i][5], addr + 0x14); 1014 + au_writel(sdev->pm_regs[i][0], addr + 0x00); 1015 + au_writel(sdev->pm_regs[i][1], addr + 0x04); 1016 + au_writel(sdev->pm_regs[i][2], addr + 0x08); 1017 + au_writel(sdev->pm_regs[i][3], addr + 0x0c); 1018 + au_writel(sdev->pm_regs[i][4], addr + 0x10); 1019 + au_writel(sdev->pm_regs[i][5], addr + 0x14); 1021 1020 au_sync(); 1022 1021 addr += 0x100; /* next channel base */ 1023 1022 } 1023 + 1024 + return 0; 1024 1025 } 1025 - #endif /* CONFIG_PM */ 1026 + 1027 + static struct sysdev_class alchemy_dbdma_sysdev_class = { 1028 + .name = "dbdma", 1029 + .suspend = alchemy_dbdma_suspend, 1030 + .resume = alchemy_dbdma_resume, 1031 + }; 1032 + 1033 + static int __init alchemy_dbdma_sysdev_init(void) 1034 + { 1035 + struct alchemy_dbdma_sysdev *sdev; 1036 + int ret; 1037 + 1038 + ret = sysdev_class_register(&alchemy_dbdma_sysdev_class); 1039 + if (ret) 1040 + return ret; 1041 + 1042 + sdev = kzalloc(sizeof(struct alchemy_dbdma_sysdev), GFP_KERNEL); 1043 + if (!sdev) 1044 + return -ENOMEM; 1045 + 1046 + sdev->sysdev.id = -1; 1047 + sdev->sysdev.cls = &alchemy_dbdma_sysdev_class; 1048 + ret = sysdev_register(&sdev->sysdev); 1049 + if (ret) 1050 + kfree(sdev); 1051 + 1052 + return ret; 1053 + } 1026 1054 1027 1055 static int __init au1xxx_dbdma_init(void) 1028 1056 { ··· 1084 1046 else { 1085 1047 dbdma_initialized = 1; 1086 1048 printk(KERN_INFO "Alchemy DBDMA initialized\n"); 1049 + ret = alchemy_dbdma_sysdev_init(); 1050 + if (ret) { 1051 + printk(KERN_ERR "DBDMA PM init failed\n"); 1052 + ret = 0; 1053 + } 1087 1054 } 1088 1055 1089 1056 return ret;
-11
arch/mips/alchemy/common/power.c
··· 36 36 37 37 #include <asm/uaccess.h> 38 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 40 #ifdef CONFIG_PM 44 41 ··· 126 129 sleep_static_memctlr[3][0] = au_readl(MEM_STCFG3); 127 130 sleep_static_memctlr[3][1] = au_readl(MEM_STTIME3); 128 131 sleep_static_memctlr[3][2] = au_readl(MEM_STADDR3); 129 - 130 - #if defined(CONFIG_SOC_AU1550) || defined(CONFIG_SOC_AU1200) 131 - au1xxx_dbdma_suspend(); 132 - #endif 133 132 } 134 133 135 134 static void restore_core_regs(void) ··· 189 196 au_writel(sleep_uart0_linectl, UART0_ADDR + UART_LCR); au_sync(); 190 197 au_writel(sleep_uart0_clkdiv, UART0_ADDR + UART_CLK); au_sync(); 191 198 } 192 - 193 - #if defined(CONFIG_SOC_AU1550) || defined(CONFIG_SOC_AU1200) 194 - au1xxx_dbdma_resume(); 195 - #endif 196 199 } 197 200 198 201 void au_sleep(void)
-4
arch/mips/include/asm/mach-au1x00/au1xxx_dbdma.h
··· 358 358 u32 au1xxx_ddma_add_device(dbdev_tab_t *dev); 359 359 extern void au1xxx_ddma_del_device(u32 devid); 360 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 363 * Flags for the put_source/put_dest functions.