linux/arch/arm/mach-mvebu/kirkwood-pm.c
<<
>>
Prefs
   1/*
   2 * Power Management driver for Marvell Kirkwood SoCs
   3 *
   4 * Copyright (C) 2013 Ezequiel Garcia <ezequiel@free-electrons.com>
   5 * Copyright (C) 2010 Simon Guinot <sguinot@lacie.com>
   6 *
   7 * This program is free software; you can redistribute it and/or modify
   8 * it under the terms of the GNU General Public License,
   9 * version 2 of the License.
  10 *
  11 * This program is distributed in the hope that it will be useful,
  12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14 * GNU General Public License for more details.
  15 */
  16
  17#include <linux/kernel.h>
  18#include <linux/suspend.h>
  19#include <linux/io.h>
  20#include "kirkwood.h"
  21#include "kirkwood-pm.h"
  22
  23static void __iomem *ddr_operation_base;
  24static void __iomem *memory_pm_ctrl;
  25
  26static void kirkwood_low_power(void)
  27{
  28        u32 mem_pm_ctrl;
  29
  30        mem_pm_ctrl = readl(memory_pm_ctrl);
  31
  32        /* Set peripherals to low-power mode */
  33        writel_relaxed(~0, memory_pm_ctrl);
  34
  35        /* Set DDR in self-refresh */
  36        writel_relaxed(0x7, ddr_operation_base);
  37
  38        /*
  39         * Set CPU in wait-for-interrupt state.
  40         * This disables the CPU core clocks,
  41         * the array clocks, and also the L2 controller.
  42         */
  43        cpu_do_idle();
  44
  45        writel_relaxed(mem_pm_ctrl, memory_pm_ctrl);
  46}
  47
  48static int kirkwood_suspend_enter(suspend_state_t state)
  49{
  50        switch (state) {
  51        case PM_SUSPEND_STANDBY:
  52                kirkwood_low_power();
  53                break;
  54        default:
  55                return -EINVAL;
  56        }
  57        return 0;
  58}
  59
  60static int kirkwood_pm_valid_standby(suspend_state_t state)
  61{
  62        return state == PM_SUSPEND_STANDBY;
  63}
  64
  65static const struct platform_suspend_ops kirkwood_suspend_ops = {
  66        .enter = kirkwood_suspend_enter,
  67        .valid = kirkwood_pm_valid_standby,
  68};
  69
  70void __init kirkwood_pm_init(void)
  71{
  72        ddr_operation_base = ioremap(DDR_OPERATION_BASE, 4);
  73        memory_pm_ctrl = ioremap(MEMORY_PM_CTRL_PHYS, 4);
  74
  75        suspend_set_ops(&kirkwood_suspend_ops);
  76}
  77