18c2ecf20Sopenharmony_ci/*
28c2ecf20Sopenharmony_ci * drivers/char/hw_random/ixp4xx-rng.c
38c2ecf20Sopenharmony_ci *
48c2ecf20Sopenharmony_ci * RNG driver for Intel IXP4xx family of NPUs
58c2ecf20Sopenharmony_ci *
68c2ecf20Sopenharmony_ci * Author: Deepak Saxena <dsaxena@plexity.net>
78c2ecf20Sopenharmony_ci *
88c2ecf20Sopenharmony_ci * Copyright 2005 (c) MontaVista Software, Inc.
98c2ecf20Sopenharmony_ci *
108c2ecf20Sopenharmony_ci * Fixes by Michael Buesch
118c2ecf20Sopenharmony_ci *
128c2ecf20Sopenharmony_ci * This file is licensed under  the terms of the GNU General Public
138c2ecf20Sopenharmony_ci * License version 2. This program is licensed "as is" without any
148c2ecf20Sopenharmony_ci * warranty of any kind, whether express or implied.
158c2ecf20Sopenharmony_ci */
168c2ecf20Sopenharmony_ci
178c2ecf20Sopenharmony_ci#include <linux/kernel.h>
188c2ecf20Sopenharmony_ci#include <linux/types.h>
198c2ecf20Sopenharmony_ci#include <linux/module.h>
208c2ecf20Sopenharmony_ci#include <linux/moduleparam.h>
218c2ecf20Sopenharmony_ci#include <linux/init.h>
228c2ecf20Sopenharmony_ci#include <linux/bitops.h>
238c2ecf20Sopenharmony_ci#include <linux/hw_random.h>
248c2ecf20Sopenharmony_ci
258c2ecf20Sopenharmony_ci#include <asm/io.h>
268c2ecf20Sopenharmony_ci#include <mach/hardware.h>
278c2ecf20Sopenharmony_ci
288c2ecf20Sopenharmony_ci
298c2ecf20Sopenharmony_cistatic int ixp4xx_rng_data_read(struct hwrng *rng, u32 *buffer)
308c2ecf20Sopenharmony_ci{
318c2ecf20Sopenharmony_ci	void __iomem * rng_base = (void __iomem *)rng->priv;
328c2ecf20Sopenharmony_ci
338c2ecf20Sopenharmony_ci	*buffer = __raw_readl(rng_base);
348c2ecf20Sopenharmony_ci
358c2ecf20Sopenharmony_ci	return 4;
368c2ecf20Sopenharmony_ci}
378c2ecf20Sopenharmony_ci
388c2ecf20Sopenharmony_cistatic struct hwrng ixp4xx_rng_ops = {
398c2ecf20Sopenharmony_ci	.name		= "ixp4xx",
408c2ecf20Sopenharmony_ci	.data_read	= ixp4xx_rng_data_read,
418c2ecf20Sopenharmony_ci};
428c2ecf20Sopenharmony_ci
438c2ecf20Sopenharmony_cistatic int __init ixp4xx_rng_init(void)
448c2ecf20Sopenharmony_ci{
458c2ecf20Sopenharmony_ci	void __iomem * rng_base;
468c2ecf20Sopenharmony_ci	int err;
478c2ecf20Sopenharmony_ci
488c2ecf20Sopenharmony_ci	if (!cpu_is_ixp46x()) /* includes IXP455 */
498c2ecf20Sopenharmony_ci		return -ENOSYS;
508c2ecf20Sopenharmony_ci
518c2ecf20Sopenharmony_ci	rng_base = ioremap(0x70002100, 4);
528c2ecf20Sopenharmony_ci	if (!rng_base)
538c2ecf20Sopenharmony_ci		return -ENOMEM;
548c2ecf20Sopenharmony_ci	ixp4xx_rng_ops.priv = (unsigned long)rng_base;
558c2ecf20Sopenharmony_ci	err = hwrng_register(&ixp4xx_rng_ops);
568c2ecf20Sopenharmony_ci	if (err)
578c2ecf20Sopenharmony_ci		iounmap(rng_base);
588c2ecf20Sopenharmony_ci
598c2ecf20Sopenharmony_ci	return err;
608c2ecf20Sopenharmony_ci}
618c2ecf20Sopenharmony_ci
628c2ecf20Sopenharmony_cistatic void __exit ixp4xx_rng_exit(void)
638c2ecf20Sopenharmony_ci{
648c2ecf20Sopenharmony_ci	void __iomem * rng_base = (void __iomem *)ixp4xx_rng_ops.priv;
658c2ecf20Sopenharmony_ci
668c2ecf20Sopenharmony_ci	hwrng_unregister(&ixp4xx_rng_ops);
678c2ecf20Sopenharmony_ci	iounmap(rng_base);
688c2ecf20Sopenharmony_ci}
698c2ecf20Sopenharmony_ci
708c2ecf20Sopenharmony_cimodule_init(ixp4xx_rng_init);
718c2ecf20Sopenharmony_cimodule_exit(ixp4xx_rng_exit);
728c2ecf20Sopenharmony_ci
738c2ecf20Sopenharmony_ciMODULE_AUTHOR("Deepak Saxena <dsaxena@plexity.net>");
748c2ecf20Sopenharmony_ciMODULE_DESCRIPTION("H/W Pseudo-Random Number Generator (RNG) driver for IXP45x/46x");
758c2ecf20Sopenharmony_ciMODULE_LICENSE("GPL");
76