2007-07-12 05:18:04 +04:00
/* power.c: Power management driver.
2005-04-17 02:20:36 +04:00
*
2008-08-30 12:18:56 +04:00
* Copyright ( C ) 1999 , 2007 , 2008 David S . Miller ( davem @ davemloft . net )
2005-04-17 02:20:36 +04:00
*/
# include <linux/kernel.h>
2011-07-22 21:18:16 +04:00
# include <linux/export.h>
2005-04-17 02:20:36 +04:00
# include <linux/init.h>
# include <linux/interrupt.h>
2007-07-19 00:12:45 +04:00
# include <linux/reboot.h>
2008-08-08 02:33:36 +04:00
# include <linux/of_device.h>
2005-04-17 02:20:36 +04:00
2006-06-30 02:22:46 +04:00
# include <asm/prom.h>
# include <asm/io.h>
2005-04-17 02:20:36 +04:00
static void __iomem * power_reg ;
2007-07-12 05:18:04 +04:00
static irqreturn_t power_handler ( int irq , void * dev_id )
{
2007-07-19 00:12:45 +04:00
orderly_poweroff ( true ) ;
2005-04-17 02:20:36 +04:00
/* FIXME: Check registers for status... */
return IRQ_HANDLED ;
}
2012-12-22 02:03:26 +04:00
static int has_button_interrupt ( unsigned int irq , struct device_node * dp )
2005-04-17 02:20:36 +04:00
{
2007-07-12 05:18:04 +04:00
if ( irq = = 0xffffffff )
2005-04-17 02:20:36 +04:00
return 0 ;
2006-06-23 06:12:03 +04:00
if ( ! of_find_property ( dp , " button " , NULL ) )
2005-04-17 02:20:36 +04:00
return 0 ;
return 1 ;
}
2012-12-22 02:03:26 +04:00
static int power_probe ( struct platform_device * op )
2005-04-17 02:20:36 +04:00
{
2006-06-30 02:22:46 +04:00
struct resource * res = & op - > resource [ 0 ] ;
2010-06-18 21:09:58 +04:00
unsigned int irq = op - > archdata . irqs [ 0 ] ;
2006-06-23 12:44:10 +04:00
2006-06-30 02:22:46 +04:00
power_reg = of_ioremap ( res , 0 , 0x4 , " power " ) ;
2009-01-07 00:19:28 +03:00
printk ( KERN_INFO " %s: Control reg at %llx \n " ,
2010-04-14 03:12:29 +04:00
op - > dev . of_node - > name , res - > start ) ;
2006-06-23 12:44:10 +04:00
2010-04-14 03:12:29 +04:00
if ( has_button_interrupt ( irq , op - > dev . of_node ) ) {
2005-10-07 07:43:54 +04:00
if ( request_irq ( irq ,
2006-06-30 01:39:11 +04:00
power_handler , 0 , " power " , NULL ) < 0 )
2007-07-12 05:18:04 +04:00
printk ( KERN_ERR " power: Cannot setup IRQ handler. \n " ) ;
2005-04-17 02:20:36 +04:00
}
2006-06-30 02:22:46 +04:00
return 0 ;
2005-04-17 02:20:36 +04:00
}
2006-06-23 12:44:10 +04:00
2011-03-31 04:37:56 +04:00
static const struct of_device_id power_match [ ] = {
2006-06-23 12:44:10 +04:00
{
. name = " power " ,
} ,
{ } ,
} ;
2011-02-23 06:01:33 +03:00
static struct platform_driver power_driver = {
2006-06-30 02:22:46 +04:00
. probe = power_probe ,
2010-04-14 03:13:02 +04:00
. driver = {
. name = " power " ,
. owner = THIS_MODULE ,
. of_match_table = power_match ,
2007-10-11 10:27:34 +04:00
} ,
2006-06-23 12:44:10 +04:00
} ;
2008-08-30 12:18:56 +04:00
static int __init power_init ( void )
2006-06-23 12:44:10 +04:00
{
2011-02-23 06:01:33 +03:00
return platform_driver_register ( & power_driver ) ;
2006-06-23 12:44:10 +04:00
}
2008-08-30 12:18:56 +04:00
device_initcall ( power_init ) ;