2019-05-27 08:55:01 +02:00
// SPDX-License-Identifier: GPL-2.0-or-later
2005-10-28 17:46:19 -07:00
/*
* c 2001 PPC 64 Team , IBM Corp
*
* / dev / nvram driver for PPC
*/
# include <linux/kernel.h>
2018-07-13 21:27:48 -07:00
# include <linux/module.h>
2005-10-28 17:46:19 -07:00
# include <linux/init.h>
# include <linux/spinlock.h>
2016-12-24 11:46:01 -08:00
# include <linux/uaccess.h>
2005-10-28 17:46:19 -07:00
# 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 ) ;
2019-01-15 15:18:56 +11:00
static unsigned char chrp_nvram_read_val ( int addr )
2005-10-28 17:46:19 -07:00
{
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 ;
}
2019-01-15 15:18:56 +11:00
static void chrp_nvram_write_val ( int addr , unsigned char val )
2005-10-28 17:46:19 -07:00
{
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 ) ;
}
2019-01-15 15:18:56 +11:00
static ssize_t chrp_nvram_size ( void )
{
return nvram_size ;
}
2005-10-28 17:46:19 -07:00
void __init chrp_nvram_init ( void )
{
struct device_node * nvram ;
2013-10-30 14:47:07 +01:00
const __be32 * nbytes_p ;
2006-07-12 15:40:05 +10:00
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
2013-10-30 14:47:07 +01:00
nvram_size = be32_to_cpup ( nbytes_p ) ;
2005-10-28 17:46:19 -07:00
printk ( KERN_INFO " CHRP nvram contains %u bytes \n " , nvram_size ) ;
of_node_put ( nvram ) ;
2019-01-15 15:18:56 +11:00
ppc_md . nvram_read_val = chrp_nvram_read_val ;
ppc_md . nvram_write_val = chrp_nvram_write_val ;
ppc_md . nvram_size = chrp_nvram_size ;
2005-10-28 17:46:19 -07:00
return ;
}
2018-07-13 21:27:48 -07:00
MODULE_LICENSE ( " GPL v2 " ) ;