-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
This patch adds support for the hardware random number generator on the
TS-7800 board.
I'm not sure the struct resource is the right approach to pass the RNG
address from board init to the driver itself.
The omap-rng does that too, but it passes a physical address and does an
ioremap. That's not required for the TS RNG because the memory is
already remapped.
The omap1/perseus2 board also has an FPGA and exports the address
information through a platform header file. I'm not sure if that's right
either.
Signed-off-by: Kristof Provost <>
- - ---
diff --git a/arch/arm/mach-orion5x/ts78xx-setup.c
b/arch/arm/mach-orion5x/ts78xx-setup.c
index 38a06b4..ef9b4f2 100644
- - --- a/arch/arm/mach-orion5x/ts78xx-setup.c
+++ b/arch/arm/mach-orion5x/ts78xx-setup.c
@@ -40,6 +40,8 @@
#define TS78XX_FPGA_REGS_RTC_CTRL (TS78XX_FPGA_REGS_VIRT_BASE | 0x808)
#define TS78XX_FPGA_REGS_RTC_DATA (TS78XX_FPGA_REGS_VIRT_BASE | 0x80c)
+#define TS78XX_FPGA_REGS_RNG_DATA (TS78XX_FPGA_REGS_VIRT_BASE | 0x44)
+
/*
* 512kB NOR flash Device
*/
@@ -183,6 +185,21 @@ static struct mv_sata_platform_data ts78xx_sata_data = {
};
/*****************************************************************************
+ * RNG
+ ****************************************************************************/
+static struct resource ts78xx_rng_resource = {
+ .flags = IORESOURCE_MEM,
+ .start = TS78XX_FPGA_REGS_RNG_DATA,
+ .end = TS78XX_FPGA_REGS_RNG_DATA
+};
+
+static struct platform_device ts78xx_rng_device = {
+ .name = "ts78xx-rng",
+ .num_resources = 1,
+ .resource = &ts78xx_rng_resource,
+};
+
+/*****************************************************************************
* print some information regarding the board
****************************************************************************/
static void __init ts78xx_print_board_id(void)
@@ -261,6 +278,7 @@ static void __init ts78xx_init(void)
orion5x_setup_dev_boot_win(TS78XX_NOR_BOOT_BASE,
TS78XX_NOR_BOOT_SIZE);
platform_device_register(&ts78xx_nor_boot_flash);
+ platform_device_register(&ts78xx_rng_device);
if (!ts78xx_rtc_init())
printk(KERN_INFO "TS-78xx RTC not detected or enabled\n");
diff --git a/drivers/char/hw_random/Kconfig b/drivers/char/hw_random/Kconfig
index 8822eca..3964679 100644
- - --- a/drivers/char/hw_random/Kconfig
+++ b/drivers/char/hw_random/Kconfig
@@ -134,3 +134,16 @@ config HW_RANDOM_VIRTIO
To compile this driver as a module, choose M here: the
module will be called virtio-rng. If unsure, say N.
+
+config HW_RANDOM_TS78XX
+ tristate "EmbeddedARM TS-7800 Random Number Generator support"
+ depends on HW_RANDOM && MACH_TS78XX
+ default HW_RANDOM
+ ---help---
+ This driver provides kernel-side support for the Random Number
+ Generator hardware found on the EmbeddedARM TS-7800 board.
+
+ To compile this driver as a module, choose M here: the
+ module will be called pasemi-rng.
+
+ If unsure, say Y.
diff --git a/drivers/char/hw_random/Makefile b/drivers/char/hw_random/Makefile
index b6effb7..3369a63 100644
- - --- a/drivers/char/hw_random/Makefile
+++ b/drivers/char/hw_random/Makefile
@@ -14,3 +14,4 @@ obj-$(CONFIG_HW_RANDOM_IXP4XX) += ixp4xx-rng.o
obj-$(CONFIG_HW_RANDOM_OMAP) += omap-rng.o
obj-$(CONFIG_HW_RANDOM_PASEMI) += pasemi-rng.o
obj-$(CONFIG_HW_RANDOM_VIRTIO) += virtio-rng.o
+obj-$(CONFIG_HW_RANDOM_TS78XX) += ts78xx-rng.o
diff --git a/drivers/char/hw_random/ts78xx-rng.c
b/drivers/char/hw_random/ts78xx-rng.c
new file mode 100644
index 0000000..f7f56b5
- - --- /dev/null
+++ b/drivers/char/hw_random/ts78xx-rng.c
@@ -0,0 +1,94 @@
+#include <linux/module.h>
+#include <linux/hw_random.h>
+#include <linux/platform_device.h>
+#include <linux/ioport.h>
+#include <linux/jiffies.h>
+#include <linux/sched.h>
+#include <linux/io.h>
+
+static unsigned long ts78xx_rng_next_read_jiffies;
+static struct resource *ts78xx_rng_resource;
+
+static int ts78xx_rng_data_present(struct hwrng *rng, int wait)
+{
+ if (time_before(jiffies, ts78xx_rng_next_read_jiffies)) {
+ if (!wait)
+ return 0;
+
+ unsigned long timeout = (long)ts78xx_rng_next_read_jiffies -
(long)jiffies;
+ schedule_timeout_interruptible(timeout);
+ }
+
+ return 1;
+}
+
+static int ts78xx_rng_data_read(struct hwrng *rng, u32 *data)
+{
+ *data = readl(ts78xx_rng_resource->start);
+
+ ts78xx_rng_next_read_jiffies = jiffies + HZ + 2;
+
+ return 4;
+}
+
+static struct hwrng ts78xx_rng = {
+ .name = "ts78xx",
+ .data_present = ts78xx_rng_data_present,
+ .data_read = ts78xx_rng_data_read,
+};
+
+static int __devinit ts78xx_rng_probe(struct platform_device *pdev)
+{
+ int err;
+
+ ts78xx_rng_resource = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!ts78xx_rng_resource)
+ return -ENOENT;
+
+ ts78xx_rng_next_read_jiffies = jiffies;
+
+ err = hwrng_register(&ts78xx_rng);
+ if (err) {
+ printk(KERN_ERR "TS-78XX RNG registration failed(%d)\n", err);
+ return err;
+ }
+
+ dev_info(&pdev->dev, "TS-78XX Random Number Generator\n");
+
+ return 0;
+}
+
+static int __devexit ts78xx_rng_remove(struct platform_device *pdev)
+{
+ printk(KERN_INFO "TS-8XX RNG exit\n");
+ hwrng_unregister(&ts78xx_rng);
+
+ return 0;
+}
+
+static struct platform_driver ts78xx_rng_driver = {
+ .probe = ts78xx_rng_probe,
+ .remove = __devexit_p(ts78xx_rng_remove),
+ .driver = {
+ .name = "ts78xx-rng",
+ .owner = THIS_MODULE,
+ },
+};
+
+static int __init mod_init(void)
+{
+ return platform_driver_register(&ts78xx_rng_driver);
+}
+
+static void __exit mod_exit(void)
+{
+ platform_driver_unregister(&ts78xx_rng_driver);
+}
+
+module_init(mod_init);
+module_exit(mod_exit);
+
+MODULE_AUTHOR("Kristof Provost <>");
+MODULE_DESCRIPTION("H/W RNG driver for TS-7800 (Orion5x SoC board)");
+MODULE_LICENSE("GPL");
+
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.9 (GNU/Linux)
iEYEARECAAYFAknCxOEACgkQUEZ9DhGwDuiThwCfWLF4gIlgyufn3nPy48pYI8Gi
8uQAnjqjsUBz8ebKREw464VXCsAppHMM
=Gi11
-----END PGP SIGNATURE-----
------------------------------------
Yahoo! Groups Links
<*> To visit your group on the web, go to:
http://groups.yahoo.com/group/ts-7000/
<*> Your email settings:
Individual Email | Traditional
<*> To change settings online go to:
http://groups.yahoo.com/group/ts-7000/join
(Yahoo! ID required)
<*> To change settings via email:
<*> To unsubscribe from this group, send an email to:
<*> Your use of Yahoo! Groups is subject to:
http://docs.yahoo.com/info/terms/
|