linux/arch/arm/mach-s3c24xx/irq-pm.c
<<
>>
Prefs
   1/* linux/arch/arm/plat-s3c24xx/irq-om.c
   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 * This program is free software; you can redistribute it and/or modify
  10 * it under the terms of the GNU General Public License version 2 as
  11 * published by the Free Software Foundation.
  12 */
  13
  14#include <linux/init.h>
  15#include <linux/module.h>
  16#include <linux/interrupt.h>
  17#include <linux/irq.h>
  18#include <linux/syscore_ops.h>
  19#include <linux/io.h>
  20
  21#include <plat/cpu.h>
  22#include <plat/pm.h>
  23#include <plat/map-base.h>
  24#include <plat/map-s3c.h>
  25
  26#include <mach/regs-irq.h>
  27#include <mach/regs-gpio.h>
  28#include <mach/pm-core.h>
  29
  30#include <asm/irq.h>
  31
  32int s3c_irq_wake(struct irq_data *data, unsigned int state)
  33{
  34        unsigned long irqbit = 1 << data->hwirq;
  35
  36        if (!(s3c_irqwake_intallow & irqbit))
  37                return -ENOENT;
  38
  39        pr_info("wake %s for hwirq %lu\n",
  40                state ? "enabled" : "disabled", data->hwirq);
  41
  42        if (!state)
  43                s3c_irqwake_intmask |= irqbit;
  44        else
  45                s3c_irqwake_intmask &= ~irqbit;
  46
  47        return 0;
  48}
  49
  50static struct sleep_save irq_save[] = {
  51        SAVE_ITEM(S3C2410_INTMSK),
  52        SAVE_ITEM(S3C2410_INTSUBMSK),
  53};
  54
  55/* the extint values move between the s3c2410/s3c2440 and the s3c2412
  56 * so we use an array to hold them, and to calculate the address of
  57 * the register at run-time
  58*/
  59
  60static unsigned long save_extint[3];
  61static unsigned long save_eintflt[4];
  62static unsigned long save_eintmask;
  63
  64static int s3c24xx_irq_suspend(void)
  65{
  66        unsigned int i;
  67
  68        for (i = 0; i < ARRAY_SIZE(save_extint); i++)
  69                save_extint[i] = __raw_readl(S3C24XX_EXTINT0 + (i*4));
  70
  71        for (i = 0; i < ARRAY_SIZE(save_eintflt); i++)
  72                save_eintflt[i] = __raw_readl(S3C24XX_EINFLT0 + (i*4));
  73
  74        s3c_pm_do_save(irq_save, ARRAY_SIZE(irq_save));
  75        save_eintmask = __raw_readl(S3C24XX_EINTMASK);
  76
  77        return 0;
  78}
  79
  80static void s3c24xx_irq_resume(void)
  81{
  82        unsigned int i;
  83
  84        for (i = 0; i < ARRAY_SIZE(save_extint); i++)
  85                __raw_writel(save_extint[i], S3C24XX_EXTINT0 + (i*4));
  86
  87        for (i = 0; i < ARRAY_SIZE(save_eintflt); i++)
  88                __raw_writel(save_eintflt[i], S3C24XX_EINFLT0 + (i*4));
  89
  90        s3c_pm_do_restore(irq_save, ARRAY_SIZE(irq_save));
  91        __raw_writel(save_eintmask, S3C24XX_EINTMASK);
  92}
  93
  94struct syscore_ops s3c24xx_irq_syscore_ops = {
  95        .suspend        = s3c24xx_irq_suspend,
  96        .resume         = s3c24xx_irq_resume,
  97};
  98
  99#ifdef CONFIG_CPU_S3C2416
 100static struct sleep_save s3c2416_irq_save[] = {
 101        SAVE_ITEM(S3C2416_INTMSK2),
 102};
 103
 104static int s3c2416_irq_suspend(void)
 105{
 106        s3c_pm_do_save(s3c2416_irq_save, ARRAY_SIZE(s3c2416_irq_save));
 107
 108        return 0;
 109}
 110
 111static void s3c2416_irq_resume(void)
 112{
 113        s3c_pm_do_restore(s3c2416_irq_save, ARRAY_SIZE(s3c2416_irq_save));
 114}
 115
 116struct syscore_ops s3c2416_irq_syscore_ops = {
 117        .suspend        = s3c2416_irq_suspend,
 118        .resume         = s3c2416_irq_resume,
 119};
 120#endif
 121