/*
 * RNG driver for TX4939 Random Number Generators (RNG)
 *
 * Copyright (C) 2009 Atsushi Nemoto <anemo@mba.ocn.ne.jp>
 *
 * This file is subject to the terms and conditions of the GNU General Public
 * License.  See the file "COPYING" in the main directory of this archive
 * for more details.
 */
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/delay.h>
#include <linux/io.h>
#include <linux/platform_device.h>
#include <linux/hw_random.h>

#define TX4939_RNG_RCSR		0x00000000
#define TX4939_RNG_ROR(n)	(0x00000018 + (n) * 8)

#define TX4939_RNG_RCSR_INTE	0x00000008
#define TX4939_RNG_RCSR_RST	0x00000004
#define TX4939_RNG_RCSR_FIN	0x00000002
#define TX4939_RNG_RCSR_ST	0x00000001

struct tx4939_rng {
	struct hwrng rng;
	void __iomem *base;
	u64 databuf[3];
	unsigned int data_avail;
};

static void rng_io_start(void)
{
#ifndef CONFIG_64BIT
	/*
	 * readq is reading a 64-bit register using a 64-bit load.  On
	 * a 32-bit kernel however interrupts or any other processor
	 * exception would clobber the upper 32-bit of the processor
	 * register so interrupts need to be disabled.
	 */
	local_irq_disable();
#endif
}

static void rng_io_end(void)
{
#ifndef CONFIG_64BIT
	local_irq_enable();
#endif
}

static u64 read_rng(void __iomem *base, unsigned int offset)
{
	return ____raw_readq(base + offset);
}

static void write_rng(u64 val, void __iomem *base, unsigned int offset)
{
	return ____raw_writeq(val, base + offset);
}

static int tx4939_rng_data_present(struct hwrng *rng, int wait)
{
	struct tx4939_rng *rngdev = container_of(rng, struct tx4939_rng, rng);
	int i;

	if (rngdev->data_avail)
		return rngdev->data_avail;
	for (i = 0; i < 20; i++) {
		rng_io_start();
		if (!(read_rng(rngdev->base, TX4939_RNG_RCSR)
		      & TX4939_RNG_RCSR_ST)) {
			rngdev->databuf[0] =
				read_rng(rngdev->base, TX4939_RNG_ROR(0));
			rngdev->databuf[1] =
				read_rng(rngdev->base, TX4939_RNG_ROR(1));
			rngdev->databuf[2] =
				read_rng(rngdev->base, TX4939_RNG_ROR(2));
			rngdev->data_avail =
				sizeof(rngdev->databuf) / sizeof(u32);
			/* Start RNG */
			write_rng(TX4939_RNG_RCSR_ST,
				  rngdev->base, TX4939_RNG_RCSR);
			wait = 0;
		}
		rng_io_end();
		if (!wait)
			break;
		/* 90 bus clock cycles by default for generation */
		ndelay(90 * 5);
	}
	return rngdev->data_avail;
}

static int tx4939_rng_data_read(struct hwrng *rng, u32 *buffer)
{
	struct tx4939_rng *rngdev = container_of(rng, struct tx4939_rng, rng);

	rngdev->data_avail--;
	*buffer = *((u32 *)&rngdev->databuf + rngdev->data_avail);
	return sizeof(u32);
}

static int __init tx4939_rng_probe(struct platform_device *dev)
{
	struct tx4939_rng *rngdev;
	struct resource *r;
	int i;

	r = platform_get_resource(dev, IORESOURCE_MEM, 0);
	if (!r)
		return -EBUSY;
	rngdev = devm_kzalloc(&dev->dev, sizeof(*rngdev), GFP_KERNEL);
	if (!rngdev)
		return -ENOMEM;
	if (!devm_request_mem_region(&dev->dev, r->start, resource_size(r),
				     dev_name(&dev->dev)))
		return -EBUSY;
	rngdev->base = devm_ioremap(&dev->dev, r->start, resource_size(r));
	if (!rngdev->base)
		return -EBUSY;

	rngdev->rng.name = dev_name(&dev->dev);
	rngdev->rng.data_present = tx4939_rng_data_present;
	rngdev->rng.data_read = tx4939_rng_data_read;

	rng_io_start();
	/* Reset RNG */
	write_rng(TX4939_RNG_RCSR_RST, rngdev->base, TX4939_RNG_RCSR);
	write_rng(0, rngdev->base, TX4939_RNG_RCSR);
	/* Start RNG */
	write_rng(TX4939_RNG_RCSR_ST, rngdev->base, TX4939_RNG_RCSR);
	rng_io_end();
	/*
	 * Drop first two results.  From the datasheet:
	 * The quality of the random numbers generated immediately
	 * after reset can be insufficient.  Therefore, do not use
	 * random numbers obtained from the first and second
	 * generations; use the ones from the third or subsequent
	 * generation.
	 */
	for (i = 0; i < 2; i++) {
		rngdev->data_avail = 0;
		if (!tx4939_rng_data_present(&rngdev->rng, 1))
			return -EIO;
	}

	platform_set_drvdata(dev, rngdev);
	return hwrng_register(&rngdev->rng);
}

static int __exit tx4939_rng_remove(struct platform_device *dev)
{
	struct tx4939_rng *rngdev = platform_get_drvdata(dev);

	hwrng_unregister(&rngdev->rng);
	platform_set_drvdata(dev, NULL);
	return 0;
}

static struct platform_driver tx4939_rng_driver = {
	.driver		= {
		.name	= "tx4939-rng",
		.owner	= THIS_MODULE,
	},
	.remove = tx4939_rng_remove,
};

static int __init tx4939rng_init(void)
{
	return platform_driver_probe(&tx4939_rng_driver, tx4939_rng_probe);
}

static void __exit tx4939rng_exit(void)
{
	platform_driver_unregister(&tx4939_rng_driver);
}

module_init(tx4939rng_init);
module_exit(tx4939rng_exit);

MODULE_DESCRIPTION("H/W Random Number Generator (RNG) driver for TX4939");
MODULE_LICENSE("GPL");
