1/* 2 * drivers/net/ubi32-eth.c 3 * Ubicom32 hardware random number generator driver. 4 * 5 * (C) Copyright 2009, Ubicom, Inc. 6 * 7 * This file is part of the Ubicom32 Linux Kernel Port. 8 * 9 * The Ubicom32 Linux Kernel Port is free software: you can redistribute 10 * it and/or modify it under the terms of the GNU General Public License 11 * as published by the Free Software Foundation, either version 2 of the 12 * License, or (at your option) any later version. 13 * 14 * The Ubicom32 Linux Kernel Port is distributed in the hope that it 15 * will be useful, but WITHOUT ANY WARRANTY; without even the implied 16 * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See 17 * the GNU General Public License for more details. 18 * 19 * You should have received a copy of the GNU General Public License 20 * along with the Ubicom32 Linux Kernel Port. If not, 21 * see <http://www.gnu.org/licenses/>. 22 * 23 * Ubicom32 implementation derived from (with many thanks): 24 * arch/m68knommu 25 * arch/blackfin 26 * arch/parisc 27 */ 28 29#include <linux/kernel.h> 30#include <linux/module.h> 31#include <linux/hw_random.h> 32#include <linux/delay.h> 33#include <asm/io.h> 34#include <asm/ip5000.h> 35 36#define MODULE_NAME "ubicom32_rng" 37 38static int ubicom32_rng_data_present(struct hwrng *rng, int wait) 39{ 40 int data, i; 41 42 for (i = 0; i < 20; i++) { 43 data = *(int *)(TIMER_BASE + TIMER_TRN); 44 if (data || !wait) 45 break; 46 udelay(10); 47 } 48 return data; 49} 50 51static int ubicom32_rng_data_read(struct hwrng *rng, u32 *data) 52{ 53 *data = *(int *)(TIMER_BASE + TIMER_TRN); 54 return 4; 55} 56 57static int ubicom32_rng_init(struct hwrng *rng) 58{ 59 printk(KERN_INFO "ubicom32 rng init\n"); 60 *(int *)(TIMER_BASE + TIMER_TRN_CFG) = TIMER_TRN_CFG_ENABLE_OSC; 61 return 0; 62} 63 64static void ubicom32_rng_cleanup(struct hwrng *rng) 65{ 66 printk(KERN_INFO "ubicom32 rng cleanup\n"); 67 *(int *)(TIMER_BASE + TIMER_TRN_CFG) = 0; 68} 69 70static struct hwrng ubicom32_rng = { 71 .name = MODULE_NAME, 72 .init = ubicom32_rng_init, 73 .cleanup = ubicom32_rng_cleanup, 74 .data_present = ubicom32_rng_data_present, 75 .data_read = ubicom32_rng_data_read, 76 .priv = 0, 77}; 78 79static int __init mod_init(void) 80{ 81 int err; 82 83 printk(KERN_INFO "ubicom32 rng started\n"); 84 err = hwrng_register(&ubicom32_rng); 85 if (err) { 86 printk(KERN_ERR "ubicom32 rng register failed (%d)\n", 87 err); 88 } 89 90 return err; 91} 92 93static void __exit mod_exit(void) 94{ 95 printk(KERN_INFO "ubicom32 rng stopped\n"); 96 hwrng_unregister(&ubicom32_rng); 97} 98 99module_init(mod_init); 100module_exit(mod_exit); 101 102MODULE_LICENSE("GPL"); 103MODULE_AUTHOR("Ubicom, Inc."); 104MODULE_DESCRIPTION("H/W rng driver for ubicom32 processor"); 105MODULE_VERSION("1:1.0.a"); 106