/*
 * Broadcom BCM63xx Random Number Generator support
 *
 * Copyright (C) 2011, Florian Fainelli <florian@openwrt.org>
 * Copyright (C) 2009, Broadcom Corporation
 *
 */
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/io.h>
#include <linux/err.h>
#include <linux/clk.h>
#include <linux/platform_device.h>
#include <linux/hw_random.h>

#include <bcm63xx_io.h>
#include <bcm63xx_regs.h>

struct bcm63xx_rng_priv {
	struct clk *clk;
	void __iomem *regs;
};

#define to_rng_priv(rng)	((struct bcm63xx_rng_priv *)rng->priv)

static int bcm63xx_rng_init(struct hwrng *rng)
{
	struct bcm63xx_rng_priv *priv = to_rng_priv(rng);
	u32 val;

	val = bcm_readl(priv->regs + RNG_CTRL);
	val |= RNG_EN;
	bcm_writel(val, priv->regs + RNG_CTRL);

	return 0;
}

static void bcm63xx_rng_cleanup(struct hwrng *rng)
{
	struct bcm63xx_rng_priv *priv = to_rng_priv(rng);
	u32 val;

	val = bcm_readl(priv->regs + RNG_CTRL);
	val &= ~RNG_EN;
	bcm_writel(val, priv->regs + RNG_CTRL);
}

static int bcm63xx_rng_data_present(struct hwrng *rng, int wait)
{
	struct bcm63xx_rng_priv *priv = to_rng_priv(rng);

	return bcm_readl(priv->regs + RNG_STAT) & RNG_AVAIL_MASK;
}

static int bcm63xx_rng_data_read(struct hwrng *rng, u32 *data)
{
	struct bcm63xx_rng_priv *priv = to_rng_priv(rng);

	*data = bcm_readl(priv->regs + RNG_DATA);

	return 4;
}

static int __devinit bcm63xx_rng_probe(struct platform_device *pdev)
{
	struct resource *r;
	struct clk *clk;
	int ret;
	struct bcm63xx_rng_priv *priv;
	struct hwrng *rng;

	r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	if (!r) {
		dev_err(&pdev->dev, "no iomem resource\n");
		ret = -ENXIO;
		goto out;
	}

	priv = kzalloc(sizeof(*priv), GFP_KERNEL);
	if (!priv) {
		dev_err(&pdev->dev, "no memory for private structure\n");
		ret = -ENOMEM;
		goto out;
	}

	rng = kzalloc(sizeof(*rng), GFP_KERNEL);
	if (!rng) {
		dev_err(&pdev->dev, "no memory for rng structure\n");
		ret = -ENOMEM;
		goto out_free_priv;
	}

	platform_set_drvdata(pdev, rng);
	rng->priv = (unsigned long)priv;
	rng->name = pdev->name;
	rng->init = bcm63xx_rng_init;
	rng->cleanup = bcm63xx_rng_cleanup;
	rng->data_present = bcm63xx_rng_data_present;
	rng->data_read = bcm63xx_rng_data_read;

	clk = clk_get(&pdev->dev, "ipsec");
	if (IS_ERR(clk)) {
		dev_err(&pdev->dev, "no clock for device\n");
		ret = PTR_ERR(clk);
		goto out_free_rng;
	}

	priv->clk = clk;

	if (!devm_request_mem_region(&pdev->dev, r->start,
					resource_size(r), pdev->name)) {
		dev_err(&pdev->dev, "request mem failed");
		ret = -ENOMEM;
		goto out_free_rng;
	}

	priv->regs = devm_ioremap_nocache(&pdev->dev, r->start,
					resource_size(r));
	if (!priv->regs) {
		dev_err(&pdev->dev, "ioremap failed");
		ret = -ENOMEM;
		goto out_free_rng;
	}

	clk_enable(clk);

	ret = hwrng_register(rng);
	if (ret) {
		dev_err(&pdev->dev, "failed to register rng device\n");
		goto out_clk_disable;
	}

	dev_info(&pdev->dev, "registered RNG driver\n");

	return 0;

out_clk_disable:
	clk_disable(clk);
out_free_rng:
	platform_set_drvdata(pdev, NULL);
	kfree(rng);
out_free_priv:
	kfree(priv);
out:
	return ret;
}

static int __devexit bcm63xx_rng_remove(struct platform_device *pdev)
{
	struct hwrng *rng = platform_get_drvdata(pdev);
	struct bcm63xx_rng_priv *priv = to_rng_priv(rng);

	hwrng_unregister(rng);
	clk_disable(priv->clk);
	kfree(priv);
	kfree(rng);
	platform_set_drvdata(pdev, NULL);

	return 0;
}

static struct platform_driver bcm63xx_rng_driver = {
	.probe		= bcm63xx_rng_probe,
	.remove		= __devexit_p(bcm63xx_rng_remove),
	.driver		= {
		.name	= "bcm63xx-rng",
		.owner	= THIS_MODULE,
	},
};

module_platform_driver(bcm63xx_rng_driver);

MODULE_AUTHOR("Florian Fainelli <florian@openwrt.org>");
MODULE_DESCRIPTION("Broadcom BCM63xx RNG driver");
MODULE_LICENSE("GPL");
