linux/drivers/cpuidle/cpuidle-kirkwood.c
<<
>>
Prefs
   1/*
   2 * arch/arm/mach-kirkwood/cpuidle.c
   3 *
   4 * CPU idle Marvell Kirkwood SoCs
   5 *
   6 * This file is licensed under the terms of the GNU General Public
   7 * License version 2.  This program is licensed "as is" without any
   8 * warranty of any kind, whether express or implied.
   9 *
  10 * The cpu idle uses wait-for-interrupt and DDR self refresh in order
  11 * to implement two idle states -
  12 * #1 wait-for-interrupt
  13 * #2 wait-for-interrupt and DDR self refresh
  14 */
  15
  16#include <linux/kernel.h>
  17#include <linux/module.h>
  18#include <linux/init.h>
  19#include <linux/platform_device.h>
  20#include <linux/cpuidle.h>
  21#include <linux/io.h>
  22#include <linux/export.h>
  23#include <asm/proc-fns.h>
  24#include <asm/cpuidle.h>
  25
  26#define KIRKWOOD_MAX_STATES     2
  27
  28static void __iomem *ddr_operation_base;
  29
  30/* Actual code that puts the SoC in different idle states */
  31static int kirkwood_enter_idle(struct cpuidle_device *dev,
  32                               struct cpuidle_driver *drv,
  33                               int index)
  34{
  35        writel(0x7, ddr_operation_base);
  36        cpu_do_idle();
  37
  38        return index;
  39}
  40
  41static struct cpuidle_driver kirkwood_idle_driver = {
  42        .name                   = "kirkwood_idle",
  43        .owner                  = THIS_MODULE,
  44        .en_core_tk_irqen       = 1,
  45        .states[0]              = ARM_CPUIDLE_WFI_STATE,
  46        .states[1]              = {
  47                .enter                  = kirkwood_enter_idle,
  48                .exit_latency           = 10,
  49                .target_residency       = 100000,
  50                .flags                  = CPUIDLE_FLAG_TIME_VALID,
  51                .name                   = "DDR SR",
  52                .desc                   = "WFI and DDR Self Refresh",
  53        },
  54        .state_count = KIRKWOOD_MAX_STATES,
  55};
  56static struct cpuidle_device *device;
  57
  58static DEFINE_PER_CPU(struct cpuidle_device, kirkwood_cpuidle_device);
  59
  60/* Initialize CPU idle by registering the idle states */
  61static int kirkwood_cpuidle_probe(struct platform_device *pdev)
  62{
  63        struct resource *res;
  64
  65        res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
  66        if (res == NULL)
  67                return -EINVAL;
  68
  69        ddr_operation_base = devm_request_and_ioremap(&pdev->dev, res);
  70        if (!ddr_operation_base)
  71                return -EADDRNOTAVAIL;
  72
  73        device = &per_cpu(kirkwood_cpuidle_device, smp_processor_id());
  74        device->state_count = KIRKWOOD_MAX_STATES;
  75
  76        cpuidle_register_driver(&kirkwood_idle_driver);
  77        if (cpuidle_register_device(device)) {
  78                pr_err("kirkwood_init_cpuidle: Failed registering\n");
  79                return -EIO;
  80        }
  81        return 0;
  82}
  83
  84int kirkwood_cpuidle_remove(struct platform_device *pdev)
  85{
  86        cpuidle_unregister_device(device);
  87        cpuidle_unregister_driver(&kirkwood_idle_driver);
  88
  89        return 0;
  90}
  91
  92static struct platform_driver kirkwood_cpuidle_driver = {
  93        .probe = kirkwood_cpuidle_probe,
  94        .remove = kirkwood_cpuidle_remove,
  95        .driver = {
  96                   .name = "kirkwood_cpuidle",
  97                   .owner = THIS_MODULE,
  98                   },
  99};
 100
 101module_platform_driver(kirkwood_cpuidle_driver);
 102
 103MODULE_AUTHOR("Andrew Lunn <andrew@lunn.ch>");
 104MODULE_DESCRIPTION("Kirkwood cpu idle driver");
 105MODULE_LICENSE("GPL v2");
 106MODULE_ALIAS("platform:kirkwood-cpuidle");
 107
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.