linux/arch/arm/mach-s3c/pm-s3c24xx.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0+
   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.rst for more information
   9//
  10// Parts based on arch/arm/mach-pxa/pm.c
  11//
  12// Thanks to Dimitry Andric for debugging
  13
  14#include <linux/init.h>
  15#include <linux/suspend.h>
  16#include <linux/errno.h>
  17#include <linux/time.h>
  18#include <linux/gpio.h>
  19#include <linux/interrupt.h>
  20#include <linux/serial_core.h>
  21#include <linux/serial_s3c.h>
  22#include <linux/io.h>
  23
  24#include "regs-clock.h"
  25#include "regs-gpio.h"
  26#include "regs-irq.h"
  27#include "gpio-samsung.h"
  28
  29#include <asm/mach/time.h>
  30
  31#include "gpio-cfg.h"
  32#include "pm.h"
  33
  34#include "regs-mem-s3c24xx.h"
  35
  36#define PFX "s3c24xx-pm: "
  37
  38#ifdef CONFIG_PM_SLEEP
  39static struct sleep_save core_save[] = {
  40        /* we restore the timings here, with the proviso that the board
  41         * brings the system up in an slower, or equal frequency setting
  42         * to the original system.
  43         *
  44         * if we cannot guarantee this, then things are going to go very
  45         * wrong here, as we modify the refresh and both pll settings.
  46         */
  47
  48        SAVE_ITEM(S3C2410_BWSCON),
  49        SAVE_ITEM(S3C2410_BANKCON0),
  50        SAVE_ITEM(S3C2410_BANKCON1),
  51        SAVE_ITEM(S3C2410_BANKCON2),
  52        SAVE_ITEM(S3C2410_BANKCON3),
  53        SAVE_ITEM(S3C2410_BANKCON4),
  54        SAVE_ITEM(S3C2410_BANKCON5),
  55};
  56#endif
  57
  58/* s3c_pm_check_resume_pin
  59 *
  60 * check to see if the pin is configured correctly for sleep mode, and
  61 * make any necessary adjustments if it is not
  62*/
  63
  64static void s3c_pm_check_resume_pin(unsigned int pin, unsigned int irqoffs)
  65{
  66        unsigned long irqstate;
  67        unsigned long pinstate;
  68        int irq = gpio_to_irq(pin);
  69
  70        if (irqoffs < 4)
  71                irqstate = s3c_irqwake_intmask & (1L<<irqoffs);
  72        else
  73                irqstate = s3c_irqwake_eintmask & (1L<<irqoffs);
  74
  75        pinstate = s3c_gpio_getcfg(pin);
  76
  77        if (!irqstate) {
  78                if (pinstate == S3C2410_GPIO_IRQ)
  79                        S3C_PMDBG("Leaving IRQ %d (pin %d) as is\n", irq, pin);
  80        } else {
  81                if (pinstate == S3C2410_GPIO_IRQ) {
  82                        S3C_PMDBG("Disabling IRQ %d (pin %d)\n", irq, pin);
  83                        s3c_gpio_cfgpin(pin, S3C2410_GPIO_INPUT);
  84                }
  85        }
  86}
  87
  88/* s3c_pm_configure_extint
  89 *
  90 * configure all external interrupt pins
  91*/
  92
  93void s3c_pm_configure_extint(void)
  94{
  95        int pin;
  96
  97        /* for each of the external interrupts (EINT0..EINT15) we
  98         * need to check whether it is an external interrupt source,
  99         * and then configure it as an input if it is not
 100        */
 101
 102        for (pin = S3C2410_GPF(0); pin <= S3C2410_GPF(7); pin++) {
 103                s3c_pm_check_resume_pin(pin, pin - S3C2410_GPF(0));
 104        }
 105
 106        for (pin = S3C2410_GPG(0); pin <= S3C2410_GPG(7); pin++) {
 107                s3c_pm_check_resume_pin(pin, (pin - S3C2410_GPG(0))+8);
 108        }
 109}
 110
 111#ifdef CONFIG_PM_SLEEP
 112void s3c_pm_restore_core(void)
 113{
 114        s3c_pm_do_restore_core(core_save, ARRAY_SIZE(core_save));
 115}
 116
 117void s3c_pm_save_core(void)
 118{
 119        s3c_pm_do_save(core_save, ARRAY_SIZE(core_save));
 120}
 121#endif
 122