linux/arch/arm/mach-s3c24xx/pm.c
<<
>>
Prefs
   1/* linux/arch/arm/plat-s3c24xx/pm.c
   2 *
   3 * Copyright (c) 2004-2006 Simtec Electronics
   4 *      Ben Dooks <ben@simtec.co.uk>
   5 *
   6 * S3C24XX Power Manager (Suspend-To-RAM) support
   7 *
   8 * See Documentation/arm/Samsung-S3C24XX/Suspend.txt for more information
   9 *
  10 * This program is free software; you can redistribute it and/or modify
  11 * it under the terms of the GNU General Public License as published by
  12 * the Free Software Foundation; either version 2 of the License, or
  13 * (at your option) any later version.
  14 *
  15 * This program is distributed in the hope that it will be useful,
  16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  18 * GNU General Public License for more details.
  19 *
  20 * You should have received a copy of the GNU General Public License
  21 * along with this program; if not, write to the Free Software
  22 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  23 *
  24 * Parts based on arch/arm/mach-pxa/pm.c
  25 *
  26 * Thanks to Dimitry Andric for debugging
  27*/
  28
  29#include <linux/init.h>
  30#include <linux/suspend.h>
  31#include <linux/errno.h>
  32#include <linux/time.h>
  33#include <linux/gpio.h>
  34#include <linux/interrupt.h>
  35#include <linux/serial_core.h>
  36#include <linux/serial_s3c.h>
  37#include <linux/io.h>
  38
  39#include <mach/regs-clock.h>
  40#include <mach/regs-gpio.h>
  41#include <mach/regs-irq.h>
  42#include <mach/gpio-samsung.h>
  43
  44#include <asm/mach/time.h>
  45
  46#include <plat/gpio-cfg.h>
  47#include <plat/pm.h>
  48
  49#include "regs-mem.h"
  50
  51#define PFX "s3c24xx-pm: "
  52
  53#ifdef CONFIG_PM_SLEEP
  54static struct sleep_save core_save[] = {
  55        /* we restore the timings here, with the proviso that the board
  56         * brings the system up in an slower, or equal frequency setting
  57         * to the original system.
  58         *
  59         * if we cannot guarantee this, then things are going to go very
  60         * wrong here, as we modify the refresh and both pll settings.
  61         */
  62
  63        SAVE_ITEM(S3C2410_BWSCON),
  64        SAVE_ITEM(S3C2410_BANKCON0),
  65        SAVE_ITEM(S3C2410_BANKCON1),
  66        SAVE_ITEM(S3C2410_BANKCON2),
  67        SAVE_ITEM(S3C2410_BANKCON3),
  68        SAVE_ITEM(S3C2410_BANKCON4),
  69        SAVE_ITEM(S3C2410_BANKCON5),
  70};
  71#endif
  72
  73/* s3c_pm_check_resume_pin
  74 *
  75 * check to see if the pin is configured correctly for sleep mode, and
  76 * make any necessary adjustments if it is not
  77*/
  78
  79static void s3c_pm_check_resume_pin(unsigned int pin, unsigned int irqoffs)
  80{
  81        unsigned long irqstate;
  82        unsigned long pinstate;
  83        int irq = gpio_to_irq(pin);
  84
  85        if (irqoffs < 4)
  86                irqstate = s3c_irqwake_intmask & (1L<<irqoffs);
  87        else
  88                irqstate = s3c_irqwake_eintmask & (1L<<irqoffs);
  89
  90        pinstate = s3c_gpio_getcfg(pin);
  91
  92        if (!irqstate) {
  93                if (pinstate == S3C2410_GPIO_IRQ)
  94                        S3C_PMDBG("Leaving IRQ %d (pin %d) as is\n", irq, pin);
  95        } else {
  96                if (pinstate == S3C2410_GPIO_IRQ) {
  97                        S3C_PMDBG("Disabling IRQ %d (pin %d)\n", irq, pin);
  98                        s3c_gpio_cfgpin(pin, S3C2410_GPIO_INPUT);
  99                }
 100        }
 101}
 102
 103/* s3c_pm_configure_extint
 104 *
 105 * configure all external interrupt pins
 106*/
 107
 108void s3c_pm_configure_extint(void)
 109{
 110        int pin;
 111
 112        /* for each of the external interrupts (EINT0..EINT15) we
 113         * need to check whether it is an external interrupt source,
 114         * and then configure it as an input if it is not
 115        */
 116
 117        for (pin = S3C2410_GPF(0); pin <= S3C2410_GPF(7); pin++) {
 118                s3c_pm_check_resume_pin(pin, pin - S3C2410_GPF(0));
 119        }
 120
 121        for (pin = S3C2410_GPG(0); pin <= S3C2410_GPG(7); pin++) {
 122                s3c_pm_check_resume_pin(pin, (pin - S3C2410_GPG(0))+8);
 123        }
 124}
 125
 126#ifdef CONFIG_PM_SLEEP
 127void s3c_pm_restore_core(void)
 128{
 129        s3c_pm_do_restore_core(core_save, ARRAY_SIZE(core_save));
 130}
 131
 132void s3c_pm_save_core(void)
 133{
 134        s3c_pm_do_save(core_save, ARRAY_SIZE(core_save));
 135}
 136#endif
 137