2019-06-04 11:11:33 +03:00
// SPDX-License-Identifier: GPL-2.0-only
hwrng: timeriomem - New driver
Some hardware platforms, the TS-7800[1] is one for example, can
supply the kernel with an entropy source, albeit a slow one for
TS-7800 users, by just reading a particular IO address. This
source must not be read above a certain rate otherwise the quality
suffers.
The driver is then hooked into by calling
platform_device_(register|add|del) passing a structure similar to:
------
static struct timeriomem_rng_data ts78xx_ts_rng_data = {
.address = (u32 *__iomem) TS_RNG,
.period = 1000000, /* one second */
};
static struct platform_device ts78xx_ts_rng_device = {
.name = "timeriomem_rng",
.id = -1,
.dev = {
.platform_data = &ts78xx_ts_rng_data,
},
.num_resources = 0,
};
------
[1] http://www.embeddedarm.com/products/board-detail.php?product=TS-7800
Signed-off-by: Alexander Clouter <alex@digriz.org.uk>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2009-02-22 07:03:56 +03:00
/*
* drivers / char / hw_random / timeriomem - rng . c
*
* Copyright ( C ) 2009 Alexander Clouter < alex @ digriz . org . uk >
*
* Derived from drivers / char / hw_random / omap - rng . c
* Copyright 2005 ( c ) MontaVista Software , Inc .
* Author : Deepak Saxena < dsaxena @ plexity . net >
*
* Overview :
* This driver is useful for platforms that have an IO range that provides
* periodic random data from a single IO memory address . All the platform
* has to do is provide the address and ' wait time ' that new data becomes
* available .
*
* TODO : add support for reading sizes other than 32 bits and masking
*/
2017-04-06 02:20:58 +03:00
# include <linux/completion.h>
2017-04-06 02:21:00 +03:00
# include <linux/delay.h>
# include <linux/hrtimer.h>
hwrng: timeriomem - New driver
Some hardware platforms, the TS-7800[1] is one for example, can
supply the kernel with an entropy source, albeit a slow one for
TS-7800 users, by just reading a particular IO address. This
source must not be read above a certain rate otherwise the quality
suffers.
The driver is then hooked into by calling
platform_device_(register|add|del) passing a structure similar to:
------
static struct timeriomem_rng_data ts78xx_ts_rng_data = {
.address = (u32 *__iomem) TS_RNG,
.period = 1000000, /* one second */
};
static struct platform_device ts78xx_ts_rng_device = {
.name = "timeriomem_rng",
.id = -1,
.dev = {
.platform_data = &ts78xx_ts_rng_data,
},
.num_resources = 0,
};
------
[1] http://www.embeddedarm.com/products/board-detail.php?product=TS-7800
Signed-off-by: Alexander Clouter <alex@digriz.org.uk>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2009-02-22 07:03:56 +03:00
# include <linux/hw_random.h>
# include <linux/io.h>
2017-04-06 02:21:00 +03:00
# include <linux/ktime.h>
2017-04-06 02:20:58 +03:00
# include <linux/module.h>
# include <linux/of.h>
# include <linux/platform_device.h>
2013-03-31 20:34:50 +04:00
# include <linux/slab.h>
2017-04-06 02:21:00 +03:00
# include <linux/time.h>
hwrng: timeriomem - New driver
Some hardware platforms, the TS-7800[1] is one for example, can
supply the kernel with an entropy source, albeit a slow one for
TS-7800 users, by just reading a particular IO address. This
source must not be read above a certain rate otherwise the quality
suffers.
The driver is then hooked into by calling
platform_device_(register|add|del) passing a structure similar to:
------
static struct timeriomem_rng_data ts78xx_ts_rng_data = {
.address = (u32 *__iomem) TS_RNG,
.period = 1000000, /* one second */
};
static struct platform_device ts78xx_ts_rng_device = {
.name = "timeriomem_rng",
.id = -1,
.dev = {
.platform_data = &ts78xx_ts_rng_data,
},
.num_resources = 0,
};
------
[1] http://www.embeddedarm.com/products/board-detail.php?product=TS-7800
Signed-off-by: Alexander Clouter <alex@digriz.org.uk>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2009-02-22 07:03:56 +03:00
# include <linux/timeriomem-rng.h>
2017-04-06 02:20:59 +03:00
struct timeriomem_rng_private {
2013-03-31 20:34:50 +04:00
void __iomem * io_base ;
2017-04-06 02:21:00 +03:00
ktime_t period ;
2013-03-31 20:34:50 +04:00
unsigned int present : 1 ;
hwrng: timeriomem - New driver
Some hardware platforms, the TS-7800[1] is one for example, can
supply the kernel with an entropy source, albeit a slow one for
TS-7800 users, by just reading a particular IO address. This
source must not be read above a certain rate otherwise the quality
suffers.
The driver is then hooked into by calling
platform_device_(register|add|del) passing a structure similar to:
------
static struct timeriomem_rng_data ts78xx_ts_rng_data = {
.address = (u32 *__iomem) TS_RNG,
.period = 1000000, /* one second */
};
static struct platform_device ts78xx_ts_rng_device = {
.name = "timeriomem_rng",
.id = -1,
.dev = {
.platform_data = &ts78xx_ts_rng_data,
},
.num_resources = 0,
};
------
[1] http://www.embeddedarm.com/products/board-detail.php?product=TS-7800
Signed-off-by: Alexander Clouter <alex@digriz.org.uk>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2009-02-22 07:03:56 +03:00
2017-04-06 02:21:00 +03:00
struct hrtimer timer ;
2013-03-31 20:34:50 +04:00
struct completion completion ;
2017-04-06 02:20:59 +03:00
struct hwrng rng_ops ;
2013-03-31 20:34:50 +04:00
} ;
2017-04-06 02:20:58 +03:00
static int timeriomem_rng_read ( struct hwrng * hwrng , void * data ,
size_t max , bool wait )
hwrng: timeriomem - New driver
Some hardware platforms, the TS-7800[1] is one for example, can
supply the kernel with an entropy source, albeit a slow one for
TS-7800 users, by just reading a particular IO address. This
source must not be read above a certain rate otherwise the quality
suffers.
The driver is then hooked into by calling
platform_device_(register|add|del) passing a structure similar to:
------
static struct timeriomem_rng_data ts78xx_ts_rng_data = {
.address = (u32 *__iomem) TS_RNG,
.period = 1000000, /* one second */
};
static struct platform_device ts78xx_ts_rng_device = {
.name = "timeriomem_rng",
.id = -1,
.dev = {
.platform_data = &ts78xx_ts_rng_data,
},
.num_resources = 0,
};
------
[1] http://www.embeddedarm.com/products/board-detail.php?product=TS-7800
Signed-off-by: Alexander Clouter <alex@digriz.org.uk>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2009-02-22 07:03:56 +03:00
{
2017-04-06 02:20:59 +03:00
struct timeriomem_rng_private * priv =
container_of ( hwrng , struct timeriomem_rng_private , rng_ops ) ;
2017-04-06 02:21:00 +03:00
int retval = 0 ;
int period_us = ktime_to_us ( priv - > period ) ;
hwrng: timeriomem - New driver
Some hardware platforms, the TS-7800[1] is one for example, can
supply the kernel with an entropy source, albeit a slow one for
TS-7800 users, by just reading a particular IO address. This
source must not be read above a certain rate otherwise the quality
suffers.
The driver is then hooked into by calling
platform_device_(register|add|del) passing a structure similar to:
------
static struct timeriomem_rng_data ts78xx_ts_rng_data = {
.address = (u32 *__iomem) TS_RNG,
.period = 1000000, /* one second */
};
static struct platform_device ts78xx_ts_rng_device = {
.name = "timeriomem_rng",
.id = -1,
.dev = {
.platform_data = &ts78xx_ts_rng_data,
},
.num_resources = 0,
};
------
[1] http://www.embeddedarm.com/products/board-detail.php?product=TS-7800
Signed-off-by: Alexander Clouter <alex@digriz.org.uk>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2009-02-22 07:03:56 +03:00
2017-04-06 02:20:58 +03:00
/*
* There may not have been enough time for new data to be generated
* since the last request . If the caller doesn ' t want to wait , let them
* bail out . Otherwise , wait for the completion . If the new data has
* already been generated , the completion should already be available .
*/
if ( ! wait & & ! priv - > present )
return 0 ;
hwrng: timeriomem - New driver
Some hardware platforms, the TS-7800[1] is one for example, can
supply the kernel with an entropy source, albeit a slow one for
TS-7800 users, by just reading a particular IO address. This
source must not be read above a certain rate otherwise the quality
suffers.
The driver is then hooked into by calling
platform_device_(register|add|del) passing a structure similar to:
------
static struct timeriomem_rng_data ts78xx_ts_rng_data = {
.address = (u32 *__iomem) TS_RNG,
.period = 1000000, /* one second */
};
static struct platform_device ts78xx_ts_rng_device = {
.name = "timeriomem_rng",
.id = -1,
.dev = {
.platform_data = &ts78xx_ts_rng_data,
},
.num_resources = 0,
};
------
[1] http://www.embeddedarm.com/products/board-detail.php?product=TS-7800
Signed-off-by: Alexander Clouter <alex@digriz.org.uk>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2009-02-22 07:03:56 +03:00
2017-04-06 02:20:58 +03:00
wait_for_completion ( & priv - > completion ) ;
hwrng: timeriomem - New driver
Some hardware platforms, the TS-7800[1] is one for example, can
supply the kernel with an entropy source, albeit a slow one for
TS-7800 users, by just reading a particular IO address. This
source must not be read above a certain rate otherwise the quality
suffers.
The driver is then hooked into by calling
platform_device_(register|add|del) passing a structure similar to:
------
static struct timeriomem_rng_data ts78xx_ts_rng_data = {
.address = (u32 *__iomem) TS_RNG,
.period = 1000000, /* one second */
};
static struct platform_device ts78xx_ts_rng_device = {
.name = "timeriomem_rng",
.id = -1,
.dev = {
.platform_data = &ts78xx_ts_rng_data,
},
.num_resources = 0,
};
------
[1] http://www.embeddedarm.com/products/board-detail.php?product=TS-7800
Signed-off-by: Alexander Clouter <alex@digriz.org.uk>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2009-02-22 07:03:56 +03:00
2017-04-06 02:21:00 +03:00
do {
/*
* After the first read , all additional reads will need to wait
* for the RNG to generate new data . Since the period can have
* a wide range of values ( 1u s to 1 s have been observed ) , allow
* for 1 % tolerance in the sleep time rather than a fixed value .
*/
if ( retval > 0 )
usleep_range ( period_us ,
2021-02-01 18:14:59 +03:00
period_us + max ( 1 , period_us / 100 ) ) ;
2017-04-06 02:21:00 +03:00
* ( u32 * ) data = readl ( priv - > io_base ) ;
retval + = sizeof ( u32 ) ;
data + = sizeof ( u32 ) ;
max - = sizeof ( u32 ) ;
} while ( wait & & max > sizeof ( u32 ) ) ;
hwrng: timeriomem - New driver
Some hardware platforms, the TS-7800[1] is one for example, can
supply the kernel with an entropy source, albeit a slow one for
TS-7800 users, by just reading a particular IO address. This
source must not be read above a certain rate otherwise the quality
suffers.
The driver is then hooked into by calling
platform_device_(register|add|del) passing a structure similar to:
------
static struct timeriomem_rng_data ts78xx_ts_rng_data = {
.address = (u32 *__iomem) TS_RNG,
.period = 1000000, /* one second */
};
static struct platform_device ts78xx_ts_rng_device = {
.name = "timeriomem_rng",
.id = -1,
.dev = {
.platform_data = &ts78xx_ts_rng_data,
},
.num_resources = 0,
};
------
[1] http://www.embeddedarm.com/products/board-detail.php?product=TS-7800
Signed-off-by: Alexander Clouter <alex@digriz.org.uk>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2009-02-22 07:03:56 +03:00
2017-04-06 02:20:58 +03:00
/*
* Block any new callers until the RNG has had time to generate new
* data .
*/
2013-03-31 20:34:50 +04:00
priv - > present = 0 ;
2013-11-15 02:32:02 +04:00
reinit_completion ( & priv - > completion ) ;
2017-04-06 02:21:00 +03:00
hrtimer_forward_now ( & priv - > timer , priv - > period ) ;
hrtimer_restart ( & priv - > timer ) ;
hwrng: timeriomem - New driver
Some hardware platforms, the TS-7800[1] is one for example, can
supply the kernel with an entropy source, albeit a slow one for
TS-7800 users, by just reading a particular IO address. This
source must not be read above a certain rate otherwise the quality
suffers.
The driver is then hooked into by calling
platform_device_(register|add|del) passing a structure similar to:
------
static struct timeriomem_rng_data ts78xx_ts_rng_data = {
.address = (u32 *__iomem) TS_RNG,
.period = 1000000, /* one second */
};
static struct platform_device ts78xx_ts_rng_device = {
.name = "timeriomem_rng",
.id = -1,
.dev = {
.platform_data = &ts78xx_ts_rng_data,
},
.num_resources = 0,
};
------
[1] http://www.embeddedarm.com/products/board-detail.php?product=TS-7800
Signed-off-by: Alexander Clouter <alex@digriz.org.uk>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2009-02-22 07:03:56 +03:00
2017-04-06 02:21:00 +03:00
return retval ;
hwrng: timeriomem - New driver
Some hardware platforms, the TS-7800[1] is one for example, can
supply the kernel with an entropy source, albeit a slow one for
TS-7800 users, by just reading a particular IO address. This
source must not be read above a certain rate otherwise the quality
suffers.
The driver is then hooked into by calling
platform_device_(register|add|del) passing a structure similar to:
------
static struct timeriomem_rng_data ts78xx_ts_rng_data = {
.address = (u32 *__iomem) TS_RNG,
.period = 1000000, /* one second */
};
static struct platform_device ts78xx_ts_rng_device = {
.name = "timeriomem_rng",
.id = -1,
.dev = {
.platform_data = &ts78xx_ts_rng_data,
},
.num_resources = 0,
};
------
[1] http://www.embeddedarm.com/products/board-detail.php?product=TS-7800
Signed-off-by: Alexander Clouter <alex@digriz.org.uk>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2009-02-22 07:03:56 +03:00
}
2017-04-06 02:21:00 +03:00
static enum hrtimer_restart timeriomem_rng_trigger ( struct hrtimer * timer )
hwrng: timeriomem - New driver
Some hardware platforms, the TS-7800[1] is one for example, can
supply the kernel with an entropy source, albeit a slow one for
TS-7800 users, by just reading a particular IO address. This
source must not be read above a certain rate otherwise the quality
suffers.
The driver is then hooked into by calling
platform_device_(register|add|del) passing a structure similar to:
------
static struct timeriomem_rng_data ts78xx_ts_rng_data = {
.address = (u32 *__iomem) TS_RNG,
.period = 1000000, /* one second */
};
static struct platform_device ts78xx_ts_rng_device = {
.name = "timeriomem_rng",
.id = -1,
.dev = {
.platform_data = &ts78xx_ts_rng_data,
},
.num_resources = 0,
};
------
[1] http://www.embeddedarm.com/products/board-detail.php?product=TS-7800
Signed-off-by: Alexander Clouter <alex@digriz.org.uk>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2009-02-22 07:03:56 +03:00
{
2017-04-06 02:20:59 +03:00
struct timeriomem_rng_private * priv
2017-04-06 02:21:00 +03:00
= container_of ( timer , struct timeriomem_rng_private , timer ) ;
hwrng: timeriomem - New driver
Some hardware platforms, the TS-7800[1] is one for example, can
supply the kernel with an entropy source, albeit a slow one for
TS-7800 users, by just reading a particular IO address. This
source must not be read above a certain rate otherwise the quality
suffers.
The driver is then hooked into by calling
platform_device_(register|add|del) passing a structure similar to:
------
static struct timeriomem_rng_data ts78xx_ts_rng_data = {
.address = (u32 *__iomem) TS_RNG,
.period = 1000000, /* one second */
};
static struct platform_device ts78xx_ts_rng_device = {
.name = "timeriomem_rng",
.id = -1,
.dev = {
.platform_data = &ts78xx_ts_rng_data,
},
.num_resources = 0,
};
------
[1] http://www.embeddedarm.com/products/board-detail.php?product=TS-7800
Signed-off-by: Alexander Clouter <alex@digriz.org.uk>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2009-02-22 07:03:56 +03:00
2013-03-31 20:34:50 +04:00
priv - > present = 1 ;
complete ( & priv - > completion ) ;
2017-04-06 02:21:00 +03:00
return HRTIMER_NORESTART ;
2013-03-31 20:34:50 +04:00
}
hwrng: timeriomem - New driver
Some hardware platforms, the TS-7800[1] is one for example, can
supply the kernel with an entropy source, albeit a slow one for
TS-7800 users, by just reading a particular IO address. This
source must not be read above a certain rate otherwise the quality
suffers.
The driver is then hooked into by calling
platform_device_(register|add|del) passing a structure similar to:
------
static struct timeriomem_rng_data ts78xx_ts_rng_data = {
.address = (u32 *__iomem) TS_RNG,
.period = 1000000, /* one second */
};
static struct platform_device ts78xx_ts_rng_device = {
.name = "timeriomem_rng",
.id = -1,
.dev = {
.platform_data = &ts78xx_ts_rng_data,
},
.num_resources = 0,
};
------
[1] http://www.embeddedarm.com/products/board-detail.php?product=TS-7800
Signed-off-by: Alexander Clouter <alex@digriz.org.uk>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2009-02-22 07:03:56 +03:00
2012-12-22 03:12:08 +04:00
static int timeriomem_rng_probe ( struct platform_device * pdev )
hwrng: timeriomem - New driver
Some hardware platforms, the TS-7800[1] is one for example, can
supply the kernel with an entropy source, albeit a slow one for
TS-7800 users, by just reading a particular IO address. This
source must not be read above a certain rate otherwise the quality
suffers.
The driver is then hooked into by calling
platform_device_(register|add|del) passing a structure similar to:
------
static struct timeriomem_rng_data ts78xx_ts_rng_data = {
.address = (u32 *__iomem) TS_RNG,
.period = 1000000, /* one second */
};
static struct platform_device ts78xx_ts_rng_device = {
.name = "timeriomem_rng",
.id = -1,
.dev = {
.platform_data = &ts78xx_ts_rng_data,
},
.num_resources = 0,
};
------
[1] http://www.embeddedarm.com/products/board-detail.php?product=TS-7800
Signed-off-by: Alexander Clouter <alex@digriz.org.uk>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2009-02-22 07:03:56 +03:00
{
2013-03-31 20:34:50 +04:00
struct timeriomem_rng_data * pdata = pdev - > dev . platform_data ;
2017-04-06 02:20:59 +03:00
struct timeriomem_rng_private * priv ;
2009-06-03 13:28:03 +04:00
struct resource * res ;
2013-03-31 20:34:50 +04:00
int err = 0 ;
int period ;
hwrng: timeriomem - New driver
Some hardware platforms, the TS-7800[1] is one for example, can
supply the kernel with an entropy source, albeit a slow one for
TS-7800 users, by just reading a particular IO address. This
source must not be read above a certain rate otherwise the quality
suffers.
The driver is then hooked into by calling
platform_device_(register|add|del) passing a structure similar to:
------
static struct timeriomem_rng_data ts78xx_ts_rng_data = {
.address = (u32 *__iomem) TS_RNG,
.period = 1000000, /* one second */
};
static struct platform_device ts78xx_ts_rng_device = {
.name = "timeriomem_rng",
.id = -1,
.dev = {
.platform_data = &ts78xx_ts_rng_data,
},
.num_resources = 0,
};
------
[1] http://www.embeddedarm.com/products/board-detail.php?product=TS-7800
Signed-off-by: Alexander Clouter <alex@digriz.org.uk>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2009-02-22 07:03:56 +03:00
2013-03-31 20:34:51 +04:00
if ( ! pdev - > dev . of_node & & ! pdata ) {
2013-03-31 20:34:50 +04:00
dev_err ( & pdev - > dev , " timeriomem_rng_data is missing \n " ) ;
return - EINVAL ;
}
2009-03-27 07:59:54 +03:00
2013-03-31 20:34:50 +04:00
res = platform_get_resource ( pdev , IORESOURCE_MEM , 0 ) ;
2009-03-27 07:59:54 +03:00
if ( ! res )
2013-03-31 20:34:50 +04:00
return - ENXIO ;
2009-03-27 07:59:54 +03:00
2019-08-31 14:55:55 +03:00
if ( res - > start % 4 ! = 0 | | resource_size ( res ) < 4 ) {
2013-03-31 20:34:50 +04:00
dev_err ( & pdev - > dev ,
2019-08-31 14:55:55 +03:00
" address must be at least four bytes wide and 32-bit aligned \n " ) ;
2013-03-31 20:34:50 +04:00
return - EINVAL ;
}
hwrng: timeriomem - New driver
Some hardware platforms, the TS-7800[1] is one for example, can
supply the kernel with an entropy source, albeit a slow one for
TS-7800 users, by just reading a particular IO address. This
source must not be read above a certain rate otherwise the quality
suffers.
The driver is then hooked into by calling
platform_device_(register|add|del) passing a structure similar to:
------
static struct timeriomem_rng_data ts78xx_ts_rng_data = {
.address = (u32 *__iomem) TS_RNG,
.period = 1000000, /* one second */
};
static struct platform_device ts78xx_ts_rng_device = {
.name = "timeriomem_rng",
.id = -1,
.dev = {
.platform_data = &ts78xx_ts_rng_data,
},
.num_resources = 0,
};
------
[1] http://www.embeddedarm.com/products/board-detail.php?product=TS-7800
Signed-off-by: Alexander Clouter <alex@digriz.org.uk>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2009-02-22 07:03:56 +03:00
2013-03-31 20:34:50 +04:00
/* Allocate memory for the device structure (and zero it) */
2014-02-27 09:07:52 +04:00
priv = devm_kzalloc ( & pdev - > dev ,
2017-04-06 02:20:59 +03:00
sizeof ( struct timeriomem_rng_private ) , GFP_KERNEL ) ;
2014-04-29 12:16:42 +04:00
if ( ! priv )
2013-03-31 20:34:50 +04:00
return - ENOMEM ;
platform_set_drvdata ( pdev , priv ) ;
2009-03-27 07:59:54 +03:00
2013-03-31 20:34:51 +04:00
if ( pdev - > dev . of_node ) {
int i ;
if ( ! of_property_read_u32 ( pdev - > dev . of_node ,
" period " , & i ) )
period = i ;
else {
dev_err ( & pdev - > dev , " missing period \n " ) ;
2014-02-27 09:07:52 +04:00
return - EINVAL ;
2013-03-31 20:34:51 +04:00
}
2017-05-23 00:12:24 +03:00
if ( ! of_property_read_u32 ( pdev - > dev . of_node ,
" quality " , & i ) )
priv - > rng_ops . quality = i ;
2014-02-27 09:07:52 +04:00
} else {
2013-03-31 20:34:51 +04:00
period = pdata - > period ;
2017-05-23 00:12:24 +03:00
priv - > rng_ops . quality = pdata - > quality ;
2014-02-27 09:07:52 +04:00
}
hwrng: timeriomem - New driver
Some hardware platforms, the TS-7800[1] is one for example, can
supply the kernel with an entropy source, albeit a slow one for
TS-7800 users, by just reading a particular IO address. This
source must not be read above a certain rate otherwise the quality
suffers.
The driver is then hooked into by calling
platform_device_(register|add|del) passing a structure similar to:
------
static struct timeriomem_rng_data ts78xx_ts_rng_data = {
.address = (u32 *__iomem) TS_RNG,
.period = 1000000, /* one second */
};
static struct platform_device ts78xx_ts_rng_device = {
.name = "timeriomem_rng",
.id = -1,
.dev = {
.platform_data = &ts78xx_ts_rng_data,
},
.num_resources = 0,
};
------
[1] http://www.embeddedarm.com/products/board-detail.php?product=TS-7800
Signed-off-by: Alexander Clouter <alex@digriz.org.uk>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2009-02-22 07:03:56 +03:00
2017-04-06 02:21:00 +03:00
priv - > period = ns_to_ktime ( period * NSEC_PER_USEC ) ;
2013-03-31 20:34:50 +04:00
init_completion ( & priv - > completion ) ;
2017-04-06 02:21:00 +03:00
hrtimer_init ( & priv - > timer , CLOCK_MONOTONIC , HRTIMER_MODE_ABS ) ;
priv - > timer . function = timeriomem_rng_trigger ;
2013-03-31 20:34:50 +04:00
2017-04-06 02:20:59 +03:00
priv - > rng_ops . name = dev_name ( & pdev - > dev ) ;
priv - > rng_ops . read = timeriomem_rng_read ;
2013-03-31 20:34:50 +04:00
2014-02-27 09:07:52 +04:00
priv - > io_base = devm_ioremap_resource ( & pdev - > dev , res ) ;
if ( IS_ERR ( priv - > io_base ) ) {
2017-04-06 02:21:00 +03:00
return PTR_ERR ( priv - > io_base ) ;
2013-03-31 20:34:50 +04:00
}
2017-04-06 02:21:00 +03:00
/* Assume random data is already available. */
priv - > present = 1 ;
complete ( & priv - > completion ) ;
2021-02-07 05:39:05 +03:00
err = devm_hwrng_register ( & pdev - > dev , & priv - > rng_ops ) ;
2013-03-31 20:34:50 +04:00
if ( err ) {
dev_err ( & pdev - > dev , " problem registering \n " ) ;
2017-04-06 02:21:00 +03:00
return err ;
2013-03-31 20:34:50 +04:00
}
hwrng: timeriomem - New driver
Some hardware platforms, the TS-7800[1] is one for example, can
supply the kernel with an entropy source, albeit a slow one for
TS-7800 users, by just reading a particular IO address. This
source must not be read above a certain rate otherwise the quality
suffers.
The driver is then hooked into by calling
platform_device_(register|add|del) passing a structure similar to:
------
static struct timeriomem_rng_data ts78xx_ts_rng_data = {
.address = (u32 *__iomem) TS_RNG,
.period = 1000000, /* one second */
};
static struct platform_device ts78xx_ts_rng_device = {
.name = "timeriomem_rng",
.id = -1,
.dev = {
.platform_data = &ts78xx_ts_rng_data,
},
.num_resources = 0,
};
------
[1] http://www.embeddedarm.com/products/board-detail.php?product=TS-7800
Signed-off-by: Alexander Clouter <alex@digriz.org.uk>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2009-02-22 07:03:56 +03:00
dev_info ( & pdev - > dev , " 32bits from 0x%p @ %dus \n " ,
2013-03-31 20:34:50 +04:00
priv - > io_base , period ) ;
hwrng: timeriomem - New driver
Some hardware platforms, the TS-7800[1] is one for example, can
supply the kernel with an entropy source, albeit a slow one for
TS-7800 users, by just reading a particular IO address. This
source must not be read above a certain rate otherwise the quality
suffers.
The driver is then hooked into by calling
platform_device_(register|add|del) passing a structure similar to:
------
static struct timeriomem_rng_data ts78xx_ts_rng_data = {
.address = (u32 *__iomem) TS_RNG,
.period = 1000000, /* one second */
};
static struct platform_device ts78xx_ts_rng_device = {
.name = "timeriomem_rng",
.id = -1,
.dev = {
.platform_data = &ts78xx_ts_rng_data,
},
.num_resources = 0,
};
------
[1] http://www.embeddedarm.com/products/board-detail.php?product=TS-7800
Signed-off-by: Alexander Clouter <alex@digriz.org.uk>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2009-02-22 07:03:56 +03:00
return 0 ;
}
2012-11-19 22:26:26 +04:00
static int timeriomem_rng_remove ( struct platform_device * pdev )
hwrng: timeriomem - New driver
Some hardware platforms, the TS-7800[1] is one for example, can
supply the kernel with an entropy source, albeit a slow one for
TS-7800 users, by just reading a particular IO address. This
source must not be read above a certain rate otherwise the quality
suffers.
The driver is then hooked into by calling
platform_device_(register|add|del) passing a structure similar to:
------
static struct timeriomem_rng_data ts78xx_ts_rng_data = {
.address = (u32 *__iomem) TS_RNG,
.period = 1000000, /* one second */
};
static struct platform_device ts78xx_ts_rng_device = {
.name = "timeriomem_rng",
.id = -1,
.dev = {
.platform_data = &ts78xx_ts_rng_data,
},
.num_resources = 0,
};
------
[1] http://www.embeddedarm.com/products/board-detail.php?product=TS-7800
Signed-off-by: Alexander Clouter <alex@digriz.org.uk>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2009-02-22 07:03:56 +03:00
{
2017-04-06 02:20:59 +03:00
struct timeriomem_rng_private * priv = platform_get_drvdata ( pdev ) ;
2013-03-31 20:34:50 +04:00
2017-04-06 02:21:00 +03:00
hrtimer_cancel ( & priv - > timer ) ;
2009-03-27 07:59:54 +03:00
hwrng: timeriomem - New driver
Some hardware platforms, the TS-7800[1] is one for example, can
supply the kernel with an entropy source, albeit a slow one for
TS-7800 users, by just reading a particular IO address. This
source must not be read above a certain rate otherwise the quality
suffers.
The driver is then hooked into by calling
platform_device_(register|add|del) passing a structure similar to:
------
static struct timeriomem_rng_data ts78xx_ts_rng_data = {
.address = (u32 *__iomem) TS_RNG,
.period = 1000000, /* one second */
};
static struct platform_device ts78xx_ts_rng_device = {
.name = "timeriomem_rng",
.id = -1,
.dev = {
.platform_data = &ts78xx_ts_rng_data,
},
.num_resources = 0,
};
------
[1] http://www.embeddedarm.com/products/board-detail.php?product=TS-7800
Signed-off-by: Alexander Clouter <alex@digriz.org.uk>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2009-02-22 07:03:56 +03:00
return 0 ;
}
2013-03-31 20:34:51 +04:00
static const struct of_device_id timeriomem_rng_match [ ] = {
{ . compatible = " timeriomem_rng " } ,
{ } ,
} ;
MODULE_DEVICE_TABLE ( of , timeriomem_rng_match ) ;
hwrng: timeriomem - New driver
Some hardware platforms, the TS-7800[1] is one for example, can
supply the kernel with an entropy source, albeit a slow one for
TS-7800 users, by just reading a particular IO address. This
source must not be read above a certain rate otherwise the quality
suffers.
The driver is then hooked into by calling
platform_device_(register|add|del) passing a structure similar to:
------
static struct timeriomem_rng_data ts78xx_ts_rng_data = {
.address = (u32 *__iomem) TS_RNG,
.period = 1000000, /* one second */
};
static struct platform_device ts78xx_ts_rng_device = {
.name = "timeriomem_rng",
.id = -1,
.dev = {
.platform_data = &ts78xx_ts_rng_data,
},
.num_resources = 0,
};
------
[1] http://www.embeddedarm.com/products/board-detail.php?product=TS-7800
Signed-off-by: Alexander Clouter <alex@digriz.org.uk>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2009-02-22 07:03:56 +03:00
static struct platform_driver timeriomem_rng_driver = {
. driver = {
. name = " timeriomem_rng " ,
2013-03-31 20:34:51 +04:00
. of_match_table = timeriomem_rng_match ,
hwrng: timeriomem - New driver
Some hardware platforms, the TS-7800[1] is one for example, can
supply the kernel with an entropy source, albeit a slow one for
TS-7800 users, by just reading a particular IO address. This
source must not be read above a certain rate otherwise the quality
suffers.
The driver is then hooked into by calling
platform_device_(register|add|del) passing a structure similar to:
------
static struct timeriomem_rng_data ts78xx_ts_rng_data = {
.address = (u32 *__iomem) TS_RNG,
.period = 1000000, /* one second */
};
static struct platform_device ts78xx_ts_rng_device = {
.name = "timeriomem_rng",
.id = -1,
.dev = {
.platform_data = &ts78xx_ts_rng_data,
},
.num_resources = 0,
};
------
[1] http://www.embeddedarm.com/products/board-detail.php?product=TS-7800
Signed-off-by: Alexander Clouter <alex@digriz.org.uk>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2009-02-22 07:03:56 +03:00
} ,
. probe = timeriomem_rng_probe ,
2012-12-22 03:12:08 +04:00
. remove = timeriomem_rng_remove ,
hwrng: timeriomem - New driver
Some hardware platforms, the TS-7800[1] is one for example, can
supply the kernel with an entropy source, albeit a slow one for
TS-7800 users, by just reading a particular IO address. This
source must not be read above a certain rate otherwise the quality
suffers.
The driver is then hooked into by calling
platform_device_(register|add|del) passing a structure similar to:
------
static struct timeriomem_rng_data ts78xx_ts_rng_data = {
.address = (u32 *__iomem) TS_RNG,
.period = 1000000, /* one second */
};
static struct platform_device ts78xx_ts_rng_device = {
.name = "timeriomem_rng",
.id = -1,
.dev = {
.platform_data = &ts78xx_ts_rng_data,
},
.num_resources = 0,
};
------
[1] http://www.embeddedarm.com/products/board-detail.php?product=TS-7800
Signed-off-by: Alexander Clouter <alex@digriz.org.uk>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2009-02-22 07:03:56 +03:00
} ;
2011-11-26 17:11:06 +04:00
module_platform_driver ( timeriomem_rng_driver ) ;
hwrng: timeriomem - New driver
Some hardware platforms, the TS-7800[1] is one for example, can
supply the kernel with an entropy source, albeit a slow one for
TS-7800 users, by just reading a particular IO address. This
source must not be read above a certain rate otherwise the quality
suffers.
The driver is then hooked into by calling
platform_device_(register|add|del) passing a structure similar to:
------
static struct timeriomem_rng_data ts78xx_ts_rng_data = {
.address = (u32 *__iomem) TS_RNG,
.period = 1000000, /* one second */
};
static struct platform_device ts78xx_ts_rng_device = {
.name = "timeriomem_rng",
.id = -1,
.dev = {
.platform_data = &ts78xx_ts_rng_data,
},
.num_resources = 0,
};
------
[1] http://www.embeddedarm.com/products/board-detail.php?product=TS-7800
Signed-off-by: Alexander Clouter <alex@digriz.org.uk>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2009-02-22 07:03:56 +03:00
MODULE_LICENSE ( " GPL " ) ;
MODULE_AUTHOR ( " Alexander Clouter <alex@digriz.org.uk> " ) ;
MODULE_DESCRIPTION ( " Timer IOMEM H/W RNG driver " ) ;