root/drivers/cpuidle/cpuidle-mvebu-v7.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. mvebu_v7_enter_idle
  2. mvebu_v7_cpuidle_probe

   1 /*
   2  * Marvell Armada 370, 38x and XP SoC cpuidle driver
   3  *
   4  * Copyright (C) 2014 Marvell
   5  *
   6  * Nadav Haklai <nadavh@marvell.com>
   7  * Gregory CLEMENT <gregory.clement@free-electrons.com>
   8  *
   9  * This file is licensed under the terms of the GNU General Public
  10  * License version 2.  This program is licensed "as is" without any
  11  * warranty of any kind, whether express or implied.
  12  *
  13  * Maintainer: Gregory CLEMENT <gregory.clement@free-electrons.com>
  14  */
  15 
  16 #include <linux/cpu_pm.h>
  17 #include <linux/cpuidle.h>
  18 #include <linux/module.h>
  19 #include <linux/of.h>
  20 #include <linux/suspend.h>
  21 #include <linux/platform_device.h>
  22 #include <asm/cpuidle.h>
  23 
  24 #define MVEBU_V7_FLAG_DEEP_IDLE 0x10000
  25 
  26 static int (*mvebu_v7_cpu_suspend)(int);
  27 
  28 static int mvebu_v7_enter_idle(struct cpuidle_device *dev,
  29                                 struct cpuidle_driver *drv,
  30                                 int index)
  31 {
  32         int ret;
  33         bool deepidle = false;
  34         cpu_pm_enter();
  35 
  36         if (drv->states[index].flags & MVEBU_V7_FLAG_DEEP_IDLE)
  37                 deepidle = true;
  38 
  39         ret = mvebu_v7_cpu_suspend(deepidle);
  40         cpu_pm_exit();
  41 
  42         if (ret)
  43                 return ret;
  44 
  45         return index;
  46 }
  47 
  48 static struct cpuidle_driver armadaxp_idle_driver = {
  49         .name                   = "armada_xp_idle",
  50         .states[0]              = ARM_CPUIDLE_WFI_STATE,
  51         .states[1]              = {
  52                 .enter                  = mvebu_v7_enter_idle,
  53                 .exit_latency           = 100,
  54                 .power_usage            = 50,
  55                 .target_residency       = 1000,
  56                 .name                   = "MV CPU IDLE",
  57                 .desc                   = "CPU power down",
  58         },
  59         .states[2]              = {
  60                 .enter                  = mvebu_v7_enter_idle,
  61                 .exit_latency           = 1000,
  62                 .power_usage            = 5,
  63                 .target_residency       = 10000,
  64                 .flags                  = MVEBU_V7_FLAG_DEEP_IDLE,
  65                 .name                   = "MV CPU DEEP IDLE",
  66                 .desc                   = "CPU and L2 Fabric power down",
  67         },
  68         .state_count = 3,
  69 };
  70 
  71 static struct cpuidle_driver armada370_idle_driver = {
  72         .name                   = "armada_370_idle",
  73         .states[0]              = ARM_CPUIDLE_WFI_STATE,
  74         .states[1]              = {
  75                 .enter                  = mvebu_v7_enter_idle,
  76                 .exit_latency           = 100,
  77                 .power_usage            = 5,
  78                 .target_residency       = 1000,
  79                 .flags                  = MVEBU_V7_FLAG_DEEP_IDLE,
  80                 .name                   = "Deep Idle",
  81                 .desc                   = "CPU and L2 Fabric power down",
  82         },
  83         .state_count = 2,
  84 };
  85 
  86 static struct cpuidle_driver armada38x_idle_driver = {
  87         .name                   = "armada_38x_idle",
  88         .states[0]              = ARM_CPUIDLE_WFI_STATE,
  89         .states[1]              = {
  90                 .enter                  = mvebu_v7_enter_idle,
  91                 .exit_latency           = 10,
  92                 .power_usage            = 5,
  93                 .target_residency       = 100,
  94                 .name                   = "Idle",
  95                 .desc                   = "CPU and SCU power down",
  96         },
  97         .state_count = 2,
  98 };
  99 
 100 static int mvebu_v7_cpuidle_probe(struct platform_device *pdev)
 101 {
 102         const struct platform_device_id *id = pdev->id_entry;
 103 
 104         if (!id)
 105                 return -EINVAL;
 106 
 107         mvebu_v7_cpu_suspend = pdev->dev.platform_data;
 108 
 109         return cpuidle_register((struct cpuidle_driver *)id->driver_data, NULL);
 110 }
 111 
 112 static const struct platform_device_id mvebu_cpuidle_ids[] = {
 113         {
 114                 .name = "cpuidle-armada-xp",
 115                 .driver_data = (unsigned long)&armadaxp_idle_driver,
 116         }, {
 117                 .name = "cpuidle-armada-370",
 118                 .driver_data = (unsigned long)&armada370_idle_driver,
 119         }, {
 120                 .name = "cpuidle-armada-38x",
 121                 .driver_data = (unsigned long)&armada38x_idle_driver,
 122         },
 123         {}
 124 };
 125 
 126 static struct platform_driver mvebu_cpuidle_driver = {
 127         .probe = mvebu_v7_cpuidle_probe,
 128         .driver = {
 129                 .name = "cpuidle-mbevu",
 130                 .suppress_bind_attrs = true,
 131         },
 132         .id_table = mvebu_cpuidle_ids,
 133 };
 134 
 135 builtin_platform_driver(mvebu_cpuidle_driver);
 136 
 137 MODULE_AUTHOR("Gregory CLEMENT <gregory.clement@free-electrons.com>");
 138 MODULE_DESCRIPTION("Marvell EBU v7 cpuidle driver");
 139 MODULE_LICENSE("GPL");

/* [<][>][^][v][top][bottom][index][help] */