/*
 * omap-rng.c - RNG driver for TI OMAP CPU family
 *
 * Author: Deepak Saxena <dsaxena@plexity.net>
 *
 * Copyright 2005 (c) MontaVista Software, Inc.
 *
 * Mostly based on original driver:
 *
 * Copyright (C) 2005 Nokia Corporation
 * Author: Juha Yrjölä <juha.yrjola@nokia.com>
 *
 * This file is licensed under  the terms of the GNU General Public
 * License version 2. This program is licensed "as is" without any
 * warranty of any kind, whether express or implied.
 */

#include <linux/module.h>
#include <linux/init.h>
#include <linux/random.h>
#include <linux/err.h>
#include <linux/platform_device.h>
#include <linux/hw_random.h>
#include <linux/delay.h>
#include <linux/slab.h>
#include <linux/pm_runtime.h>

#include <asm/io.h>

#define RNG_OUT_REG		0x00		/* Output register */
#define RNG_STAT_REG		0x04		/* Status register
							[0] = STAT_BUSY */
#define RNG_ALARM_REG		0x24		/* Alarm register
							[7:0] = ALARM_COUNTER */
#define RNG_CONFIG_REG		0x28		/* Configuration register
							[11:6] = RESET_COUNT
							[5:3]  = RING2_DELAY
							[2:0]  = RING1_DELAY */
#define RNG_REV_REG		0x3c		/* Revision register
							[7:0] = REV_NB */
#define RNG_MASK_REG		0x40		/* Mask and reset register
							[2] = IT_EN
							[1] = SOFTRESET
							[0] = AUTOIDLE */
#define RNG_SYSSTATUS		0x44		/* System status
							[0] = RESETDONE */

/**
 * struct omap_rng_private_data - RNG IP block-specific data
 * @base: virtual address of the beginning of the RNG IP block registers
 * @mem_res: struct resource * for the IP block registers physical memory
 */
struct omap_rng_private_data {
	void __iomem *base;
	struct resource *mem_res;
};

static inline u32 omap_rng_read_reg(struct omap_rng_private_data *priv, int reg)
{
	return __raw_readl(priv->base + reg);
}

static inline void omap_rng_write_reg(struct omap_rng_private_data *priv,
				      int reg, u32 val)
{
	__raw_writel(val, priv->base + reg);
}

static int omap_rng_data_present(struct hwrng *rng, int wait)
{
	struct omap_rng_private_data *priv;
	int data, i;

	priv = (struct omap_rng_private_data *)rng->priv;

	for (i = 0; i < 20; i++) {
		data = omap_rng_read_reg(priv, RNG_STAT_REG) ? 0 : 1;
		if (data || !wait)
			break;
		/* RNG produces data fast enough (2+ MBit/sec, even
		 * during "rngtest" loads, that these delays don't
		 * seem to trigger.  We *could* use the RNG IRQ, but
		 * that'd be higher overhead ... so why bother?
		 */
		udelay(10);
	}
	return data;
}

static int omap_rng_data_read(struct hwrng *rng, u32 *data)
{
	struct omap_rng_private_data *priv;

	priv = (struct omap_rng_private_data *)rng->priv;

	*data = omap_rng_read_reg(priv, RNG_OUT_REG);

	return sizeof(u32);
}

static struct hwrng omap_rng_ops = {
	.name		= "omap",
	.data_present	= omap_rng_data_present,
	.data_read	= omap_rng_data_read,
};

static int omap_rng_probe(struct platform_device *pdev)
{
	struct omap_rng_private_data *priv;
	int ret;

	priv = kzalloc(sizeof(struct omap_rng_private_data), GFP_KERNEL);
	if (!priv) {
		dev_err(&pdev->dev, "could not allocate memory\n");
		return -ENOMEM;
	};

	omap_rng_ops.priv = (unsigned long)priv;
	dev_set_drvdata(&pdev->dev, priv);

	priv->mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	if (!priv->mem_res) {
		ret = -ENOENT;
		goto err_ioremap;
	}

	priv->base = devm_ioremap_resource(&pdev->dev, priv->mem_res);
	if (IS_ERR(priv->base)) {
		ret = PTR_ERR(priv->base);
		goto err_ioremap;
	}
	dev_set_drvdata(&pdev->dev, priv);

	pm_runtime_enable(&pdev->dev);
	pm_runtime_get_sync(&pdev->dev);

	ret = hwrng_register(&omap_rng_ops);
	if (ret)
		goto err_register;

	dev_info(&pdev->dev, "OMAP Random Number Generator ver. %02x\n",
		 omap_rng_read_reg(priv, RNG_REV_REG));

	omap_rng_write_reg(priv, RNG_MASK_REG, 0x1);

	return 0;

err_register:
	priv->base = NULL;
	pm_runtime_disable(&pdev->dev);
err_ioremap:
	kfree(priv);

	return ret;
}

static int __exit omap_rng_remove(struct platform_device *pdev)
{
	struct omap_rng_private_data *priv = dev_get_drvdata(&pdev->dev);

	hwrng_unregister(&omap_rng_ops);

	omap_rng_write_reg(priv, RNG_MASK_REG, 0x0);

	pm_runtime_put_sync(&pdev->dev);
	pm_runtime_disable(&pdev->dev);

	release_mem_region(priv->mem_res->start, resource_size(priv->mem_res));

	kfree(priv);

	return 0;
}

#ifdef CONFIG_PM_SLEEP

static int omap_rng_suspend(struct device *dev)
{
	struct omap_rng_private_data *priv = dev_get_drvdata(dev);

	omap_rng_write_reg(priv, RNG_MASK_REG, 0x0);
	pm_runtime_put_sync(dev);

	return 0;
}

static int omap_rng_resume(struct device *dev)
{
	struct omap_rng_private_data *priv = dev_get_drvdata(dev);

	pm_runtime_get_sync(dev);
	omap_rng_write_reg(priv, RNG_MASK_REG, 0x1);

	return 0;
}

static SIMPLE_DEV_PM_OPS(omap_rng_pm, omap_rng_suspend, omap_rng_resume);
#define	OMAP_RNG_PM	(&omap_rng_pm)

#else

#define	OMAP_RNG_PM	NULL

#endif

/* work with hotplug and coldplug */
MODULE_ALIAS("platform:omap_rng");

static struct platform_driver omap_rng_driver = {
	.driver = {
		.name		= "omap_rng",
		.owner		= THIS_MODULE,
		.pm		= OMAP_RNG_PM,
	},
	.probe		= omap_rng_probe,
	.remove		= __exit_p(omap_rng_remove),
};

static int __init omap_rng_init(void)
{
	return platform_driver_register(&omap_rng_driver);
}

static void __exit omap_rng_exit(void)
{
	platform_driver_unregister(&omap_rng_driver);
}

module_init(omap_rng_init);
module_exit(omap_rng_exit);

MODULE_AUTHOR("Deepak Saxena (and others)");
MODULE_LICENSE("GPL");
