17c7f8f7fSAlexander Shiyan /* 27c7f8f7fSAlexander Shiyan * CLPS711X CPU idle driver 37c7f8f7fSAlexander Shiyan * 47c7f8f7fSAlexander Shiyan * Copyright (C) 2014 Alexander Shiyan <shc_work@mail.ru> 57c7f8f7fSAlexander Shiyan * 67c7f8f7fSAlexander Shiyan * This program is free software; you can redistribute it and/or modify 77c7f8f7fSAlexander Shiyan * it under the terms of the GNU General Public License as published by 87c7f8f7fSAlexander Shiyan * the Free Software Foundation; either version 2 of the License, or 97c7f8f7fSAlexander Shiyan * (at your option) any later version. 107c7f8f7fSAlexander Shiyan */ 117c7f8f7fSAlexander Shiyan 127c7f8f7fSAlexander Shiyan #include <linux/cpuidle.h> 137c7f8f7fSAlexander Shiyan #include <linux/err.h> 147c7f8f7fSAlexander Shiyan #include <linux/io.h> 15*94e8057bSPaul Gortmaker #include <linux/init.h> 167c7f8f7fSAlexander Shiyan #include <linux/platform_device.h> 177c7f8f7fSAlexander Shiyan 187c7f8f7fSAlexander Shiyan #define CLPS711X_CPUIDLE_NAME "clps711x-cpuidle" 197c7f8f7fSAlexander Shiyan 207c7f8f7fSAlexander Shiyan static void __iomem *clps711x_halt; 217c7f8f7fSAlexander Shiyan 227c7f8f7fSAlexander Shiyan static int clps711x_cpuidle_halt(struct cpuidle_device *dev, 237c7f8f7fSAlexander Shiyan struct cpuidle_driver *drv, int index) 247c7f8f7fSAlexander Shiyan { 257c7f8f7fSAlexander Shiyan writel(0xaa, clps711x_halt); 267c7f8f7fSAlexander Shiyan 277c7f8f7fSAlexander Shiyan return index; 287c7f8f7fSAlexander Shiyan } 297c7f8f7fSAlexander Shiyan 307c7f8f7fSAlexander Shiyan static struct cpuidle_driver clps711x_idle_driver = { 317c7f8f7fSAlexander Shiyan .name = CLPS711X_CPUIDLE_NAME, 327c7f8f7fSAlexander Shiyan .owner = THIS_MODULE, 337c7f8f7fSAlexander Shiyan .states[0] = { 347c7f8f7fSAlexander Shiyan .name = "HALT", 357c7f8f7fSAlexander Shiyan .desc = "CLPS711X HALT", 367c7f8f7fSAlexander Shiyan .enter = clps711x_cpuidle_halt, 377c7f8f7fSAlexander Shiyan .exit_latency = 1, 387c7f8f7fSAlexander Shiyan }, 397c7f8f7fSAlexander Shiyan .state_count = 1, 407c7f8f7fSAlexander Shiyan }; 417c7f8f7fSAlexander Shiyan 427c7f8f7fSAlexander Shiyan static int __init clps711x_cpuidle_probe(struct platform_device *pdev) 437c7f8f7fSAlexander Shiyan { 447c7f8f7fSAlexander Shiyan struct resource *res; 457c7f8f7fSAlexander Shiyan 467c7f8f7fSAlexander Shiyan res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 477c7f8f7fSAlexander Shiyan clps711x_halt = devm_ioremap_resource(&pdev->dev, res); 487c7f8f7fSAlexander Shiyan if (IS_ERR(clps711x_halt)) 497c7f8f7fSAlexander Shiyan return PTR_ERR(clps711x_halt); 507c7f8f7fSAlexander Shiyan 517c7f8f7fSAlexander Shiyan return cpuidle_register(&clps711x_idle_driver, NULL); 527c7f8f7fSAlexander Shiyan } 537c7f8f7fSAlexander Shiyan 547c7f8f7fSAlexander Shiyan static struct platform_driver clps711x_cpuidle_driver = { 557c7f8f7fSAlexander Shiyan .driver = { 567c7f8f7fSAlexander Shiyan .name = CLPS711X_CPUIDLE_NAME, 577c7f8f7fSAlexander Shiyan }, 587c7f8f7fSAlexander Shiyan }; 59*94e8057bSPaul Gortmaker builtin_platform_driver_probe(clps711x_cpuidle_driver, clps711x_cpuidle_probe); 60