0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012 #include <linux/serial_core.h>
0013 #include <linux/serial_s3c.h>
0014 #include <linux/io.h>
0015
0016 #include <asm/mach/map.h>
0017
0018 #include <linux/soc/samsung/s3c-pm.h>
0019
0020 static struct pm_uart_save uart_save;
0021
0022 extern void printascii(const char *);
0023
0024 void s3c_pm_dbg(const char *fmt, ...)
0025 {
0026 va_list va;
0027 char buff[256];
0028
0029 va_start(va, fmt);
0030 vsnprintf(buff, sizeof(buff), fmt, va);
0031 va_end(va);
0032
0033 printascii(buff);
0034 }
0035
0036 static inline void __iomem *s3c_pm_uart_base(void)
0037 {
0038 unsigned long paddr;
0039 unsigned long vaddr;
0040
0041 debug_ll_addr(&paddr, &vaddr);
0042
0043 return (void __iomem *)vaddr;
0044 }
0045
0046 void s3c_pm_save_uarts(bool is_s3c2410)
0047 {
0048 void __iomem *regs = s3c_pm_uart_base();
0049 struct pm_uart_save *save = &uart_save;
0050
0051 save->ulcon = __raw_readl(regs + S3C2410_ULCON);
0052 save->ucon = __raw_readl(regs + S3C2410_UCON);
0053 save->ufcon = __raw_readl(regs + S3C2410_UFCON);
0054 save->umcon = __raw_readl(regs + S3C2410_UMCON);
0055 save->ubrdiv = __raw_readl(regs + S3C2410_UBRDIV);
0056
0057 if (!is_s3c2410)
0058 save->udivslot = __raw_readl(regs + S3C2443_DIVSLOT);
0059
0060 S3C_PMDBG("UART[%p]: ULCON=%04x, UCON=%04x, UFCON=%04x, UBRDIV=%04x\n",
0061 regs, save->ulcon, save->ucon, save->ufcon, save->ubrdiv);
0062 }
0063
0064 void s3c_pm_restore_uarts(bool is_s3c2410)
0065 {
0066 void __iomem *regs = s3c_pm_uart_base();
0067 struct pm_uart_save *save = &uart_save;
0068
0069 s3c_pm_arch_update_uart(regs, save);
0070
0071 __raw_writel(save->ulcon, regs + S3C2410_ULCON);
0072 __raw_writel(save->ucon, regs + S3C2410_UCON);
0073 __raw_writel(save->ufcon, regs + S3C2410_UFCON);
0074 __raw_writel(save->umcon, regs + S3C2410_UMCON);
0075 __raw_writel(save->ubrdiv, regs + S3C2410_UBRDIV);
0076
0077 if (!is_s3c2410)
0078 __raw_writel(save->udivslot, regs + S3C2443_DIVSLOT);
0079 }