Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

pasemi: hardware rng driver

Driver for the on-chip hardware random number generator on PA Semi
PA6T-1682M.

Signed-off-by: Egor Martovetsky <egor@pasemi.com>
Signed-off-by: Olof Johansson <olof@lixom.net>
Signed-off-by: Michael Buesch <mb@bu3sch.de>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Kumar Gala <galak@gate.crashing.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>

authored by

Olof Johansson and committed by
Linus Torvalds
b8cb3448 4d355632

+171
+14
drivers/char/hw_random/Kconfig
··· 91 91 module will be called omap-rng. 92 92 93 93 If unsure, say Y. 94 + 95 + config HW_RANDOM_PASEMI 96 + tristate "PA Semi HW Random Number Generator support" 97 + depends on HW_RANDOM && PPC_PASEMI 98 + default HW_RANDOM 99 + ---help--- 100 + This driver provides kernel-side support for the Random Number 101 + Generator hardware found on PA6T-1682M processor. 102 + 103 + To compile this driver as a module, choose M here: the 104 + module will be called pasemi-rng. 105 + 106 + If unsure, say Y. 107 +
+1
drivers/char/hw_random/Makefile
··· 10 10 obj-$(CONFIG_HW_RANDOM_VIA) += via-rng.o 11 11 obj-$(CONFIG_HW_RANDOM_IXP4XX) += ixp4xx-rng.o 12 12 obj-$(CONFIG_HW_RANDOM_OMAP) += omap-rng.o 13 + obj-$(CONFIG_HW_RANDOM_PASEMI) += pasemi-rng.o
+156
drivers/char/hw_random/pasemi-rng.c
··· 1 + /* 2 + * Copyright (C) 2006-2007 PA Semi, Inc 3 + * 4 + * Maintained by: Olof Johansson <olof@lixom.net> 5 + * 6 + * Driver for the PWRficient onchip rng 7 + * 8 + * This program is free software; you can redistribute it and/or modify 9 + * it under the terms of the GNU General Public License version 2 as 10 + * published by the Free Software Foundation. 11 + * 12 + * This program is distributed in the hope that it will be useful, 13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 + * GNU General Public License for more details. 16 + * 17 + * You should have received a copy of the GNU General Public License 18 + * along with this program; if not, write to the Free Software 19 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20 + */ 21 + 22 + #include <linux/module.h> 23 + #include <linux/kernel.h> 24 + #include <linux/platform_device.h> 25 + #include <linux/hw_random.h> 26 + #include <asm/of_platform.h> 27 + #include <asm/io.h> 28 + 29 + #define SDCRNG_CTL_REG 0x00 30 + #define SDCRNG_CTL_FVLD_M 0x0000f000 31 + #define SDCRNG_CTL_FVLD_S 12 32 + #define SDCRNG_CTL_KSZ 0x00000800 33 + #define SDCRNG_CTL_RSRC_CRG 0x00000010 34 + #define SDCRNG_CTL_RSRC_RRG 0x00000000 35 + #define SDCRNG_CTL_CE 0x00000004 36 + #define SDCRNG_CTL_RE 0x00000002 37 + #define SDCRNG_CTL_DR 0x00000001 38 + #define SDCRNG_CTL_SELECT_RRG_RNG (SDCRNG_CTL_RE | SDCRNG_CTL_RSRC_RRG) 39 + #define SDCRNG_CTL_SELECT_CRG_RNG (SDCRNG_CTL_CE | SDCRNG_CTL_RSRC_CRG) 40 + #define SDCRNG_VAL_REG 0x20 41 + 42 + #define MODULE_NAME "pasemi_rng" 43 + 44 + static int pasemi_rng_data_present(struct hwrng *rng) 45 + { 46 + void __iomem *rng_regs = (void __iomem *)rng->priv; 47 + 48 + return (in_le32(rng_regs + SDCRNG_CTL_REG) 49 + & SDCRNG_CTL_FVLD_M) ? 1 : 0; 50 + } 51 + 52 + static int pasemi_rng_data_read(struct hwrng *rng, u32 *data) 53 + { 54 + void __iomem *rng_regs = (void __iomem *)rng->priv; 55 + *data = in_le32(rng_regs + SDCRNG_VAL_REG); 56 + return 4; 57 + } 58 + 59 + static int pasemi_rng_init(struct hwrng *rng) 60 + { 61 + void __iomem *rng_regs = (void __iomem *)rng->priv; 62 + u32 ctl; 63 + 64 + ctl = SDCRNG_CTL_DR | SDCRNG_CTL_SELECT_RRG_RNG | SDCRNG_CTL_KSZ; 65 + out_le32(rng_regs + SDCRNG_CTL_REG, ctl); 66 + out_le32(rng_regs + SDCRNG_CTL_REG, ctl & ~SDCRNG_CTL_DR); 67 + 68 + return 0; 69 + } 70 + 71 + static void pasemi_rng_cleanup(struct hwrng *rng) 72 + { 73 + void __iomem *rng_regs = (void __iomem *)rng->priv; 74 + u32 ctl; 75 + 76 + ctl = SDCRNG_CTL_RE | SDCRNG_CTL_CE; 77 + out_le32(rng_regs + SDCRNG_CTL_REG, 78 + in_le32(rng_regs + SDCRNG_CTL_REG) & ~ctl); 79 + } 80 + 81 + static struct hwrng pasemi_rng = { 82 + .name = MODULE_NAME, 83 + .init = pasemi_rng_init, 84 + .cleanup = pasemi_rng_cleanup, 85 + .data_present = pasemi_rng_data_present, 86 + .data_read = pasemi_rng_data_read, 87 + }; 88 + 89 + static int __devinit rng_probe(struct of_device *ofdev, 90 + const struct of_device_id *match) 91 + { 92 + void __iomem *rng_regs; 93 + struct device_node *rng_np = ofdev->node; 94 + struct resource res; 95 + int err = 0; 96 + 97 + err = of_address_to_resource(rng_np, 0, &res); 98 + if (err) 99 + return -ENODEV; 100 + 101 + rng_regs = ioremap(res.start, 0x100); 102 + 103 + if (!rng_regs) 104 + return -ENOMEM; 105 + 106 + pasemi_rng.priv = (unsigned long)rng_regs; 107 + 108 + printk(KERN_INFO "Registering PA Semi RNG\n"); 109 + 110 + err = hwrng_register(&pasemi_rng); 111 + 112 + if (err) 113 + iounmap(rng_regs); 114 + 115 + return err; 116 + } 117 + 118 + static int __devexit rng_remove(struct of_device *dev) 119 + { 120 + void __iomem *rng_regs = (void __iomem *)pasemi_rng.priv; 121 + 122 + hwrng_unregister(&pasemi_rng); 123 + iounmap(rng_regs); 124 + 125 + return 0; 126 + } 127 + 128 + static struct of_device_id rng_match[] = { 129 + { 130 + .compatible = "1682m-rng", 131 + }, 132 + {}, 133 + }; 134 + 135 + static struct of_platform_driver rng_driver = { 136 + .name = "pasemi-rng", 137 + .match_table = rng_match, 138 + .probe = rng_probe, 139 + .remove = rng_remove, 140 + }; 141 + 142 + static int __init rng_init(void) 143 + { 144 + return of_register_platform_driver(&rng_driver); 145 + } 146 + module_init(rng_init); 147 + 148 + static void __exit rng_exit(void) 149 + { 150 + of_unregister_platform_driver(&rng_driver); 151 + } 152 + module_exit(rng_exit); 153 + 154 + MODULE_LICENSE("GPL"); 155 + MODULE_AUTHOR("Egor Martovetsky <egor@pasemi.com>"); 156 + MODULE_DESCRIPTION("H/W RNG driver for PA Semi processor");