linux/arch/arm/mach-s3c24xx/irq-pm.c
<<
>>
Prefs
   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 <plat/cpu.h>
  17#include <plat/pm.h>
  18#include <plat/map-base.h>
  19#include <plat/map-s3c.h>
  20
  21#include <mach/regs-irq.h>
  22#include <mach/regs-gpio.h>
  23#include <mach/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
 116