2009-03-27 14:25:24 +01:00
/*
* Copyright ( C ) 2007 - 2009 Michal Simek < monstr @ monstr . eu >
* Copyright ( C ) 2007 - 2009 PetaLogix
* Copyright ( C ) 2006 Atmark Techno , Inc .
*
* This file is subject to the terms and conditions of the GNU General Public
* License . See the file " COPYING " in the main directory of this archive
* for more details .
*/
# include <linux/sched.h>
# include <linux/io.h>
# include <asm/setup.h>
# include <asm/page.h>
# include <asm/prom.h>
static unsigned int base_addr ;
void heartbeat ( void )
{
static unsigned int cnt , period , dist ;
if ( base_addr ) {
if ( cnt = = 0 | | cnt = = dist )
out_be32 ( base_addr , 1 ) ;
else if ( cnt = = 7 | | cnt = = dist + 7 )
out_be32 ( base_addr , 0 ) ;
if ( + + cnt > period ) {
cnt = 0 ;
/*
* The hyperbolic function below modifies the heartbeat
* period length in dependency of the current ( 5 min )
* load . It goes through the points f ( 0 ) = 126 , f ( 1 ) = 86 ,
* f ( 5 ) = 51 , f ( inf ) - > 30.
*/
period = ( ( 672 < < FSHIFT ) / ( 5 * avenrun [ 0 ] +
( 7 < < FSHIFT ) ) ) + 30 ;
dist = period / 4 ;
}
}
}
void setup_heartbeat ( void )
{
struct device_node * gpio = NULL ;
2009-06-05 11:36:31 -06:00
int * prop ;
2009-03-27 14:25:24 +01:00
int j ;
2010-09-13 21:23:49 -07:00
const char * const gpio_list [ ] = {
" xlnx,xps-gpio-1.00.a " ,
NULL
} ;
2009-03-27 14:25:24 +01:00
for ( j = 0 ; gpio_list [ j ] ! = NULL ; j + + ) {
gpio = of_find_compatible_node ( NULL , NULL , gpio_list [ j ] ) ;
if ( gpio )
break ;
}
2009-06-05 11:36:31 -06:00
if ( gpio ) {
2010-09-28 16:04:14 +10:00
base_addr = be32_to_cpup ( of_get_property ( gpio , " reg " , NULL ) ) ;
2009-06-05 11:36:31 -06:00
base_addr = ( unsigned long ) ioremap ( base_addr , PAGE_SIZE ) ;
printk ( KERN_NOTICE " Heartbeat GPIO at 0x%x \n " , base_addr ) ;
2009-03-27 14:25:24 +01:00
2009-06-05 11:36:31 -06:00
/* GPIO is configured as output */
prop = ( int * ) of_get_property ( gpio , " xlnx,is-bidir " , NULL ) ;
if ( prop )
out_be32 ( base_addr + 4 , 0 ) ;
}
2009-03-27 14:25:24 +01:00
}