brintos

brintos / linux-shallow public Read only

0
0
Text · 3.5 KiB · 563dba6 Raw
145 lines · c
1/*2 * Marvell Armada 370, 38x and XP SoC cpuidle driver3 *4 * Copyright (C) 2014 Marvell5 *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 Public10 * License version 2.  This program is licensed "as is" without any11 * 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	0x1000025 26static int (*mvebu_v7_cpu_suspend)(int);27 28static __cpuidle 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	ct_cpuidle_enter();40	ret = mvebu_v7_cpu_suspend(deepidle);41	ct_cpuidle_exit();42 43	cpu_pm_exit();44 45	if (ret)46		return ret;47 48	return index;49}50 51static struct cpuidle_driver armadaxp_idle_driver = {52	.name			= "armada_xp_idle",53	.states[0]		= ARM_CPUIDLE_WFI_STATE,54	.states[1]		= {55		.enter			= mvebu_v7_enter_idle,56		.exit_latency		= 100,57		.power_usage		= 50,58		.target_residency	= 1000,59		.flags			= CPUIDLE_FLAG_RCU_IDLE,60		.name			= "MV CPU IDLE",61		.desc			= "CPU power down",62	},63	.states[2]		= {64		.enter			= mvebu_v7_enter_idle,65		.exit_latency		= 1000,66		.power_usage		= 5,67		.target_residency	= 10000,68		.flags			= MVEBU_V7_FLAG_DEEP_IDLE | CPUIDLE_FLAG_RCU_IDLE,69		.name			= "MV CPU DEEP IDLE",70		.desc			= "CPU and L2 Fabric power down",71	},72	.state_count = 3,73};74 75static struct cpuidle_driver armada370_idle_driver = {76	.name			= "armada_370_idle",77	.states[0]		= ARM_CPUIDLE_WFI_STATE,78	.states[1]		= {79		.enter			= mvebu_v7_enter_idle,80		.exit_latency		= 100,81		.power_usage		= 5,82		.target_residency	= 1000,83		.flags			= MVEBU_V7_FLAG_DEEP_IDLE | CPUIDLE_FLAG_RCU_IDLE,84		.name			= "Deep Idle",85		.desc			= "CPU and L2 Fabric power down",86	},87	.state_count = 2,88};89 90static struct cpuidle_driver armada38x_idle_driver = {91	.name			= "armada_38x_idle",92	.states[0]		= ARM_CPUIDLE_WFI_STATE,93	.states[1]		= {94		.enter			= mvebu_v7_enter_idle,95		.exit_latency		= 10,96		.power_usage		= 5,97		.target_residency	= 100,98		.flags			= CPUIDLE_FLAG_RCU_IDLE,99		.name			= "Idle",100		.desc			= "CPU and SCU power down",101	},102	.state_count = 2,103};104 105static int mvebu_v7_cpuidle_probe(struct platform_device *pdev)106{107	const struct platform_device_id *id = pdev->id_entry;108 109	if (!id)110		return -EINVAL;111 112	mvebu_v7_cpu_suspend = pdev->dev.platform_data;113 114	return cpuidle_register((struct cpuidle_driver *)id->driver_data, NULL);115}116 117static const struct platform_device_id mvebu_cpuidle_ids[] = {118	{119		.name = "cpuidle-armada-xp",120		.driver_data = (unsigned long)&armadaxp_idle_driver,121	}, {122		.name = "cpuidle-armada-370",123		.driver_data = (unsigned long)&armada370_idle_driver,124	}, {125		.name = "cpuidle-armada-38x",126		.driver_data = (unsigned long)&armada38x_idle_driver,127	},128	{}129};130 131static struct platform_driver mvebu_cpuidle_driver = {132	.probe = mvebu_v7_cpuidle_probe,133	.driver = {134		.name = "cpuidle-mbevu",135		.suppress_bind_attrs = true,136	},137	.id_table = mvebu_cpuidle_ids,138};139 140builtin_platform_driver(mvebu_cpuidle_driver);141 142MODULE_AUTHOR("Gregory CLEMENT <gregory.clement@free-electrons.com>");143MODULE_DESCRIPTION("Marvell EBU v7 cpuidle driver");144MODULE_LICENSE("GPL");145