irq-pm-s3c24xx.c (2562B)
1// SPDX-License-Identifier: GPL-2.0 2// 3// Copyright (c) 2003-2004 Simtec Electronics 4// Ben Dooks <ben@simtec.co.uk> 5// http://armlinux.simtec.co.uk/ 6// 7// S3C24XX - IRQ PM code 8 9#include <linux/init.h> 10#include <linux/module.h> 11#include <linux/interrupt.h> 12#include <linux/irq.h> 13#include <linux/syscore_ops.h> 14#include <linux/io.h> 15 16#include "cpu.h" 17#include "pm.h" 18#include "map-base.h" 19#include "map-s3c.h" 20 21#include "regs-irq.h" 22#include "regs-gpio.h" 23#include "pm-core.h" 24 25#include <asm/irq.h> 26 27int s3c_irq_wake(struct irq_data *data, unsigned int state) 28{ 29 unsigned long irqbit = 1 << data->hwirq; 30 31 if (!(s3c_irqwake_intallow & irqbit)) 32 return -ENOENT; 33 34 pr_info("wake %s for hwirq %lu\n", 35 state ? "enabled" : "disabled", data->hwirq); 36 37 if (!state) 38 s3c_irqwake_intmask |= irqbit; 39 else 40 s3c_irqwake_intmask &= ~irqbit; 41 42 return 0; 43} 44 45static struct sleep_save irq_save[] = { 46 SAVE_ITEM(S3C2410_INTMSK), 47 SAVE_ITEM(S3C2410_INTSUBMSK), 48}; 49 50/* the extint values move between the s3c2410/s3c2440 and the s3c2412 51 * so we use an array to hold them, and to calculate the address of 52 * the register at run-time 53*/ 54 55static unsigned long save_extint[3]; 56static unsigned long save_eintflt[4]; 57static unsigned long save_eintmask; 58 59static int s3c24xx_irq_suspend(void) 60{ 61 unsigned int i; 62 63 for (i = 0; i < ARRAY_SIZE(save_extint); i++) 64 save_extint[i] = __raw_readl(S3C24XX_EXTINT0 + (i*4)); 65 66 for (i = 0; i < ARRAY_SIZE(save_eintflt); i++) 67 save_eintflt[i] = __raw_readl(S3C24XX_EINFLT0 + (i*4)); 68 69 s3c_pm_do_save(irq_save, ARRAY_SIZE(irq_save)); 70 save_eintmask = __raw_readl(S3C24XX_EINTMASK); 71 72 return 0; 73} 74 75static void s3c24xx_irq_resume(void) 76{ 77 unsigned int i; 78 79 for (i = 0; i < ARRAY_SIZE(save_extint); i++) 80 __raw_writel(save_extint[i], S3C24XX_EXTINT0 + (i*4)); 81 82 for (i = 0; i < ARRAY_SIZE(save_eintflt); i++) 83 __raw_writel(save_eintflt[i], S3C24XX_EINFLT0 + (i*4)); 84 85 s3c_pm_do_restore(irq_save, ARRAY_SIZE(irq_save)); 86 __raw_writel(save_eintmask, S3C24XX_EINTMASK); 87} 88 89struct syscore_ops s3c24xx_irq_syscore_ops = { 90 .suspend = s3c24xx_irq_suspend, 91 .resume = s3c24xx_irq_resume, 92}; 93 94#ifdef CONFIG_CPU_S3C2416 95static struct sleep_save s3c2416_irq_save[] = { 96 SAVE_ITEM(S3C2416_INTMSK2), 97}; 98 99static int s3c2416_irq_suspend(void) 100{ 101 s3c_pm_do_save(s3c2416_irq_save, ARRAY_SIZE(s3c2416_irq_save)); 102 103 return 0; 104} 105 106static void s3c2416_irq_resume(void) 107{ 108 s3c_pm_do_restore(s3c2416_irq_save, ARRAY_SIZE(s3c2416_irq_save)); 109} 110 111struct syscore_ops s3c2416_irq_syscore_ops = { 112 .suspend = s3c2416_irq_suspend, 113 .resume = s3c2416_irq_resume, 114}; 115#endif