2005-10-28 17:46:19 -07:00
/*
* c 2001 PPC 64 Team , IBM Corp
*
* This program is free software ; you can redistribute it and / or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation ; either version
* 2 of the License , or ( at your option ) any later version .
*
* / dev / nvram driver for PPC
*
*/
# include <linux/kernel.h>
# include <linux/init.h>
# include <linux/spinlock.h>
# include <asm/uaccess.h>
# include <asm/prom.h>
# include <asm/machdep.h>
2005-11-02 19:58:12 +11:00
# include <asm/rtas.h>
2005-10-28 17:46:19 -07:00
# include "chrp.h"
static unsigned int nvram_size ;
static unsigned char nvram_buf [ 4 ] ;
static DEFINE_SPINLOCK ( nvram_lock ) ;
static unsigned char chrp_nvram_read ( int addr )
{
2005-11-02 19:58:12 +11:00
unsigned int done ;
unsigned long flags ;
2005-10-28 17:46:19 -07:00
unsigned char ret ;
if ( addr > = nvram_size ) {
printk ( KERN_DEBUG " %s: read addr %d > nvram_size %u \n " ,
current - > comm , addr , nvram_size ) ;
return 0xff ;
}
spin_lock_irqsave ( & nvram_lock , flags ) ;
2005-11-02 15:04:26 +11:00
if ( ( rtas_call ( rtas_token ( " nvram-fetch " ) , 3 , 2 , & done , addr ,
__pa ( nvram_buf ) , 1 ) ! = 0 ) | | 1 ! = done )
2005-10-28 17:46:19 -07:00
ret = 0xff ;
else
ret = nvram_buf [ 0 ] ;
spin_unlock_irqrestore ( & nvram_lock , flags ) ;
return ret ;
}
static void chrp_nvram_write ( int addr , unsigned char val )
{
2005-11-02 19:58:12 +11:00
unsigned int done ;
unsigned long flags ;
2005-10-28 17:46:19 -07:00
if ( addr > = nvram_size ) {
printk ( KERN_DEBUG " %s: write addr %d > nvram_size %u \n " ,
current - > comm , addr , nvram_size ) ;
return ;
}
spin_lock_irqsave ( & nvram_lock , flags ) ;
nvram_buf [ 0 ] = val ;
2005-11-02 15:04:26 +11:00
if ( ( rtas_call ( rtas_token ( " nvram-store " ) , 3 , 2 , & done , addr ,
__pa ( nvram_buf ) , 1 ) ! = 0 ) | | 1 ! = done )
2005-10-28 17:46:19 -07:00
printk ( KERN_DEBUG " rtas IO error storing 0x%02x at %d " , val , addr ) ;
spin_unlock_irqrestore ( & nvram_lock , flags ) ;
}
void __init chrp_nvram_init ( void )
{
struct device_node * nvram ;
2006-07-12 15:40:05 +10:00
const unsigned int * nbytes_p ;
unsigned int proplen ;
2005-10-28 17:46:19 -07:00
nvram = of_find_node_by_type ( NULL , " nvram " ) ;
if ( nvram = = NULL )
return ;
2007-04-03 22:26:41 +10:00
nbytes_p = of_get_property ( nvram , " #bytes " , & proplen ) ;
2010-08-31 05:48:58 +00:00
if ( nbytes_p = = NULL | | proplen ! = sizeof ( unsigned int ) ) {
of_node_put ( nvram ) ;
2005-10-28 17:46:19 -07:00
return ;
2010-08-31 05:48:58 +00:00
}
2005-10-28 17:46:19 -07:00
nvram_size = * nbytes_p ;
printk ( KERN_INFO " CHRP nvram contains %u bytes \n " , nvram_size ) ;
of_node_put ( nvram ) ;
ppc_md . nvram_read_val = chrp_nvram_read ;
ppc_md . nvram_write_val = chrp_nvram_write ;
return ;
}