MIPS: Alchemy: sysdem for DBDMA PM
RFC PATCH 1/1 MIPS: Alchemy: sysdem for DBDMA PM
Add a sysdev for DBDMA PM.
Signed-off-by Manuel Lauss <[email protected]>
---
Tested on DB1200 (STR while playing audio and SD card activity works fine).
Will probably throw rejects in power.c, hence the RFC.
arch/mips/alchemy/common/dbdma.c | 101 +++++++++++++++------ arch/mips/alchemy/common/power.c | 11 --- arch/mips/include/asm/mach-au1x00/au1xxx_dbdma.h | 4 - 3 files changed, 72 insertions(+), 44 deletions(-)
arch/mips/alchemy/common/dbdma.c +72 -29
@@ -36,6 +36,7 @@#include <linux/spinlock.h> #include <linux/interrupt.h> #include <linux/module.h> +#include <linux/sysdev.h> #include <asm/mach-au1x00/au1000.h> #include <asm/mach-au1x00/au1xxx_dbdma.h>
@@ -174,10 +175,6 @@ static dbdev_tab_t dbdev_tab[] = {#define DBDEV_TAB_SIZE ARRAY_SIZE(dbdev_tab) -#ifdef CONFIG_PM -static u32 au1xxx_dbdma_pm_regs[NUM_DBDMA_CHANS +1 ][6 ]; -#endif -static chan_tab_t *chan_tab_ptr[NUM_DBDMA_CHANS ];
@@ -960,29 +957,37 @@ u32 au1xxx_dbdma_put_dscr(u32 chanid, au1x_ddma_desc_t *dscr)return nbytes; } -#ifdef CONFIG_PM -void au1xxx_dbdma_suspend (void ) + +struct alchemy_dbdma_sysdev { +struct sys_device sysdev; +u32 pm_regs[NUM_DBDMA_CHANS +1 ][6 ]; +}; + +static int alchemy_dbdma_suspend (struct sys_device *dev, +pm_message_t state) { +struct alchemy_dbdma_sysdev *sdev = + container_of(dev, struct alchemy_dbdma_sysdev, sysdev);int i;u32 addr; addr =DDMA_GLOBAL_BASE ; - au1xxx_dbdma_pm_regs[0 ][0 ] =au_readl (addr +0x00 ); - au1xxx_dbdma_pm_regs[0 ][1 ] =au_readl (addr +0x04 ); - au1xxx_dbdma_pm_regs[0 ][2 ] =au_readl (addr +0x08 ); - au1xxx_dbdma_pm_regs[0 ][3 ] =au_readl (addr +0x0c ); + sdev->pm_regs[0 ][0 ] =au_readl (addr +0x00 ); + sdev->pm_regs[0 ][1 ] =au_readl (addr +0x04 ); + sdev->pm_regs[0 ][2 ] =au_readl (addr +0x08 ); + sdev->pm_regs[0 ][3 ] =au_readl (addr +0x0c );/* save channel configurations */ for (i =1 , addr =DDMA_CHANNEL_BASE ; i <=NUM_DBDMA_CHANS ; i++) { - au1xxx_dbdma_pm_regs[i][0 ] =au_readl (addr +0x00 ); - au1xxx_dbdma_pm_regs[i][1 ] =au_readl (addr +0x04 ); - au1xxx_dbdma_pm_regs[i][2 ] =au_readl (addr +0x08 ); - au1xxx_dbdma_pm_regs[i][3 ] =au_readl (addr +0x0c ); - au1xxx_dbdma_pm_regs[i][4 ] =au_readl (addr +0x10 ); - au1xxx_dbdma_pm_regs[i][5 ] =au_readl (addr +0x14 ); + sdev->pm_regs[i][0 ] =au_readl (addr +0x00 ); + sdev->pm_regs[i][1 ] =au_readl (addr +0x04 ); + sdev->pm_regs[i][2 ] =au_readl (addr +0x08 ); + sdev->pm_regs[i][3 ] =au_readl (addr +0x0c ); + sdev->pm_regs[i][4 ] =au_readl (addr +0x10 ); + sdev->pm_regs[i][5 ] =au_readl (addr +0x14 );/* halt channel */ -au_writel (au1xxx_dbdma_pm_regs[i][0 ] & ~1 , addr +0x00 ); +au_writel (sdev->pm_regs[i][0 ] & ~1 , addr +0x00 );au_sync ();while (!(au_readl (addr +0x14 ) &1 ))au_sync ();
@@ -992,32 +997,65 @@ void au1xxx_dbdma_suspend(void)/* disable channel interrupts */ au_writel (0 ,DDMA_GLOBAL_BASE +0x0c );au_sync (); + +return 0 ; } -void au1xxx_dbdma_resume (void ) +static int alchemy_dbdma_resume (struct sys_device *dev) { +struct alchemy_dbdma_sysdev *sdev = + container_of(dev, struct alchemy_dbdma_sysdev, sysdev);int i;u32 addr; addr =DDMA_GLOBAL_BASE ; -au_writel (au1xxx_dbdma_pm_regs[0 ][0 ], addr +0x00 ); -au_writel (au1xxx_dbdma_pm_regs[0 ][1 ], addr +0x04 ); -au_writel (au1xxx_dbdma_pm_regs[0 ][2 ], addr +0x08 ); -au_writel (au1xxx_dbdma_pm_regs[0 ][3 ], addr +0x0c ); +au_writel (sdev->pm_regs[0 ][0 ], addr +0x00 ); +au_writel (sdev->pm_regs[0 ][1 ], addr +0x04 ); +au_writel (sdev->pm_regs[0 ][2 ], addr +0x08 ); +au_writel (sdev->pm_regs[0 ][3 ], addr +0x0c );/* restore channel configurations */ for (i =1 , addr =DDMA_CHANNEL_BASE ; i <=NUM_DBDMA_CHANS ; i++) { -au_writel (au1xxx_dbdma_pm_regs[i][0 ], addr +0x00 ); -au_writel (au1xxx_dbdma_pm_regs[i][1 ], addr +0x04 ); -au_writel (au1xxx_dbdma_pm_regs[i][2 ], addr +0x08 ); -au_writel (au1xxx_dbdma_pm_regs[i][3 ], addr +0x0c ); -au_writel (au1xxx_dbdma_pm_regs[i][4 ], addr +0x10 ); -au_writel (au1xxx_dbdma_pm_regs[i][5 ], addr +0x14 ); +au_writel (sdev->pm_regs[i][0 ], addr +0x00 ); +au_writel (sdev->pm_regs[i][1 ], addr +0x04 ); +au_writel (sdev->pm_regs[i][2 ], addr +0x08 ); +au_writel (sdev->pm_regs[i][3 ], addr +0x0c ); +au_writel (sdev->pm_regs[i][4 ], addr +0x10 ); +au_writel (sdev->pm_regs[i][5 ], addr +0x14 );au_sync (); addr +=0x100 ;/* next channel base */ } + +return 0 ; +} + +static struct sysdev_class alchemy_dbdma_sysdev_class = { + .name ="dbdma" , + .suspend = alchemy_dbdma_suspend, + .resume = alchemy_dbdma_resume, +}; + +static int __init alchemy_dbdma_sysdev_init (void ) +{ +struct alchemy_dbdma_sysdev *sdev; +int ret; + + ret =sysdev_class_register (&alchemy_dbdma_sysdev_class); +if (ret) +return ret; + + sdev =kzalloc (sizeof (struct alchemy_dbdma_sysdev ),GFP_KERNEL ); +if (!sdev) +return -ENOMEM ; + + sdev->sysdev.id =-1 ; + sdev->sysdev.cls = &alchemy_dbdma_sysdev_class; + ret =sysdev_register (&sdev->sysdev); +if (ret) +kfree (sdev); + +return ret; } -#endif /* CONFIG_PM */ static int __init au1xxx_dbdma_init (void ) {
@@ -1046,6 +1084,11 @@ static int __init au1xxx_dbdma_init(void)else { dbdma_initialized =1 ;printk (KERN_INFO "Alchemy DBDMA initialized\n" ); + ret =alchemy_dbdma_sysdev_init (); +if (ret) { +printk (KERN_ERR "DBDMA PM init failed\n" ); + ret =0 ; + } }return ret;
arch/mips/alchemy/common/power.c +0 -11
@@ -36,9 +36,6 @@#include <asm/uaccess.h> #include <asm/mach-au1x00/au1000.h> -#if defined(CONFIG_SOC_AU1550 ) || defined(CONFIG_SOC_AU1200 ) -#include <asm/mach-au1x00/au1xxx_dbdma.h> -#endif #ifdef CONFIG_PM
@@ -108,10 +105,6 @@ static void save_core_regs(void) sleep_static_memctlr[3 ][0 ] =au_readl (MEM_STCFG3 ); sleep_static_memctlr[3 ][1 ] =au_readl (MEM_STTIME3 ); sleep_static_memctlr[3 ][2 ] =au_readl (MEM_STADDR3 ); - -#if defined(CONFIG_SOC_AU1550 ) || defined(CONFIG_SOC_AU1200 ) -au1xxx_dbdma_suspend (); -#endif }static void restore_core_regs (void )
@@ -161,10 +154,6 @@ static void restore_core_regs(void)au_writel (sleep_static_memctlr[3 ][0 ],MEM_STCFG3 );au_writel (sleep_static_memctlr[3 ][1 ],MEM_STTIME3 );au_writel (sleep_static_memctlr[3 ][2 ],MEM_STADDR3 ); - -#if defined(CONFIG_SOC_AU1550 ) || defined(CONFIG_SOC_AU1200 ) -au1xxx_dbdma_resume (); -#endif }void au_sleep (void )
arch/mips/include/asm/mach-au1x00/au1xxx_dbdma.h +0 -4
@@ -358,10 +358,6 @@ u32 au1xxx_dbdma_put_dscr(u32 chanid, au1x_ddma_desc_t *dscr);u32 au1xxx_ddma_add_device (dbdev_tab_t *dev);extern void au1xxx_ddma_del_device (u32 devid);void *au1xxx_ddma_get_nextptr_virt (au1x_ddma_desc_t *dp); -#ifdef CONFIG_PM -void au1xxx_dbdma_suspend (void ); -void au1xxx_dbdma_resume (void ); -#endif /* * Flags for the put_source/put_dest functions.
Signature · 1 line
1.7.0.4