/*
 * 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 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 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		= 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");
