2019-05-29 16:57:47 -07:00
// SPDX-License-Identifier: GPL-2.0-only
2012-04-12 05:08:53 +00:00
/*
* Copyright ( C ) 2010 Michael Neuling IBM Corporation
*
* Driver for the pseries hardware RNG for POWER7 + and above
*/
2013-09-25 19:24:17 +10:00
# define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
# include <linux/kernel.h>
2012-04-12 05:08:53 +00:00
# include <linux/module.h>
# include <linux/hw_random.h>
# include <asm/vio.h>
2014-10-31 07:50:11 +01:00
static int pseries_rng_read ( struct hwrng * rng , void * data , size_t max , bool wait )
2012-04-12 05:08:53 +00:00
{
2014-10-31 07:50:11 +01:00
u64 buffer [ PLPAR_HCALL_BUFSIZE ] ;
2013-09-25 19:24:17 +10:00
int rc ;
2014-10-31 07:50:11 +01:00
rc = plpar_hcall ( H_RANDOM , ( unsigned long * ) buffer ) ;
2013-09-25 19:24:17 +10:00
if ( rc ! = H_SUCCESS ) {
pr_err_ratelimited ( " H_RANDOM call failed %d \n " , rc ) ;
return - EIO ;
2012-04-12 05:08:53 +00:00
}
2016-11-18 23:00:10 +05:30
memcpy ( data , buffer , 8 ) ;
2013-09-25 19:24:17 +10:00
/* The hypervisor interface returns 64 bits */
2016-11-18 23:00:10 +05:30
return 8 ;
2012-04-12 05:08:53 +00:00
}
2021-05-20 13:13:46 +01:00
/*
2012-04-12 05:08:53 +00:00
* pseries_rng_get_desired_dma - Return desired DMA allocate for CMO operations
*
* This is a required function for a driver to operate in a CMO environment
* but this device does not make use of DMA allocations , return 0.
*
* Return value :
* Number of bytes of IO data the driver will need to perform well - > 0
*/
static unsigned long pseries_rng_get_desired_dma ( struct vio_dev * vdev )
{
return 0 ;
} ;
static struct hwrng pseries_rng = {
2013-09-25 19:24:16 +10:00
. name = KBUILD_MODNAME ,
2014-10-31 07:50:11 +01:00
. read = pseries_rng_read ,
2012-04-12 05:08:53 +00:00
} ;
2015-03-09 10:36:38 -07:00
static int pseries_rng_probe ( struct vio_dev * dev ,
2012-04-12 05:08:53 +00:00
const struct vio_device_id * id )
{
return hwrng_register ( & pseries_rng ) ;
}
2021-02-25 23:18:34 +01:00
static void pseries_rng_remove ( struct vio_dev * dev )
2012-04-12 05:08:53 +00:00
{
hwrng_unregister ( & pseries_rng ) ;
}
2017-08-17 23:06:23 +05:30
static const struct vio_device_id pseries_rng_driver_ids [ ] = {
2012-04-12 05:08:53 +00:00
{ " ibm,random-v1 " , " ibm,random " } ,
{ " " , " " }
} ;
MODULE_DEVICE_TABLE ( vio , pseries_rng_driver_ids ) ;
static struct vio_driver pseries_rng_driver = {
2013-09-25 19:24:16 +10:00
. name = KBUILD_MODNAME ,
2012-04-12 05:08:53 +00:00
. probe = pseries_rng_probe ,
. remove = pseries_rng_remove ,
. get_desired_dma = pseries_rng_get_desired_dma ,
. id_table = pseries_rng_driver_ids
} ;
static int __init rng_init ( void )
{
2014-09-15 20:31:20 +05:30
pr_info ( " Registering IBM pSeries RNG driver \n " ) ;
2012-04-12 05:08:53 +00:00
return vio_register_driver ( & pseries_rng_driver ) ;
}
module_init ( rng_init ) ;
static void __exit rng_exit ( void )
{
vio_unregister_driver ( & pseries_rng_driver ) ;
}
module_exit ( rng_exit ) ;
MODULE_LICENSE ( " GPL " ) ;
MODULE_AUTHOR ( " Michael Neuling <mikey@neuling.org> " ) ;
MODULE_DESCRIPTION ( " H/W RNG driver for IBM pSeries processors " ) ;