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