blob: 4d5e28312d910568c9ec627780844c7fa1228562 [file] [log] [blame]
Krzysztof Kozlowski84b21702017-12-25 20:54:32 +01001// 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
Ben Dooks65fa22b2008-12-12 00:24:10 +00008
9#include <linux/init.h>
10#include <linux/module.h>
11#include <linux/interrupt.h>
Lennert Buytenhek57436c2d2011-01-03 19:15:54 +090012#include <linux/irq.h>
Heiko Stuebnerd8fdec12013-01-29 10:25:22 -080013#include <linux/syscore_ops.h>
Heiko Stuebnerdc1a3532013-02-12 14:23:01 -080014#include <linux/io.h>
Ben Dooks65fa22b2008-12-12 00:24:10 +000015
Arnd Bergmannc6ff1322019-09-02 18:37:30 +020016#include "cpu.h"
17#include "pm.h"
18#include <mach/map-base.h>
19#include "map-s3c.h"
Heiko Stuebnerdc1a3532013-02-12 14:23:01 -080020
Arnd Bergmannc6ff1322019-09-02 18:37:30 +020021#include "regs-irq.h"
22#include "regs-gpio.h"
23#include "pm-core.h"
Ben Dooks65fa22b2008-12-12 00:24:10 +000024
Lennert Buytenhek57436c2d2011-01-03 19:15:54 +090025#include <asm/irq.h>
26
Lennert Buytenhek57436c2d2011-01-03 19:15:54 +090027int s3c_irq_wake(struct irq_data *data, unsigned int state)
Ben Dooks65fa22b2008-12-12 00:24:10 +000028{
Heiko Stuebnerb4a343e2013-01-29 10:25:22 -080029 unsigned long irqbit = 1 << data->hwirq;
Ben Dooks65fa22b2008-12-12 00:24:10 +000030
31 if (!(s3c_irqwake_intallow & irqbit))
32 return -ENOENT;
33
Heiko Stuebnerb4a343e2013-01-29 10:25:22 -080034 pr_info("wake %s for hwirq %lu\n",
35 state ? "enabled" : "disabled", data->hwirq);
Ben Dooks65fa22b2008-12-12 00:24:10 +000036
37 if (!state)
38 s3c_irqwake_intmask |= irqbit;
39 else
40 s3c_irqwake_intmask &= ~irqbit;
41
42 return 0;
43}
44
Ben Dooks65fa22b2008-12-12 00:24:10 +000045static 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
Heiko Stuebnerd8fdec12013-01-29 10:25:22 -080059static int s3c24xx_irq_suspend(void)
Ben Dooks65fa22b2008-12-12 00:24:10 +000060{
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
Heiko Stuebnerd8fdec12013-01-29 10:25:22 -080075static void s3c24xx_irq_resume(void)
Ben Dooks65fa22b2008-12-12 00:24:10 +000076{
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);
Ben Dooks65fa22b2008-12-12 00:24:10 +000087}
Heiko Stuebnerd8fdec12013-01-29 10:25:22 -080088
89struct syscore_ops s3c24xx_irq_syscore_ops = {
90 .suspend = s3c24xx_irq_suspend,
91 .resume = s3c24xx_irq_resume,
92};
Heiko Stuebneref602eb2013-01-29 10:25:22 -080093
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