/*
 * Copyright (c) 2011-2013, The Linux Foundation. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
 * only version 2 as published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 */
#include <linux/clk.h>
#include <linux/err.h>
#include <linux/hw_random.h>
#include <linux/io.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/platform_device.h>

/* Device specific register offsets */
#define PRNG_DATA_OUT		0x0000
#define PRNG_STATUS		0x0004
#define PRNG_LFSR_CFG		0x0100
#define PRNG_CONFIG		0x0104

/* Device specific register masks and config values */
#define PRNG_LFSR_CFG_MASK	0x0000ffff
#define PRNG_LFSR_CFG_CLOCKS	0x0000dddd
#define PRNG_CONFIG_HW_ENABLE	BIT(1)
#define PRNG_STATUS_DATA_AVAIL	BIT(0)

#define MAX_HW_FIFO_DEPTH	16
#define MAX_HW_FIFO_SIZE	(MAX_HW_FIFO_DEPTH * 4)
#define WORD_SZ			4

struct msm_rng {
	void __iomem *base;
	struct clk *clk;
	struct hwrng hwrng;
};

#define to_msm_rng(p)	container_of(p, struct msm_rng, hwrng)

static int msm_rng_enable(struct hwrng *hwrng, int enable)
{
	struct msm_rng *rng = to_msm_rng(hwrng);
	u32 val;
	int ret;

	ret = clk_prepare_enable(rng->clk);
	if (ret)
		return ret;

	if (enable) {
		/* Enable PRNG only if it is not already enabled */
		val = readl_relaxed(rng->base + PRNG_CONFIG);
		if (val & PRNG_CONFIG_HW_ENABLE)
			goto already_enabled;

		val = readl_relaxed(rng->base + PRNG_LFSR_CFG);
		val &= ~PRNG_LFSR_CFG_MASK;
		val |= PRNG_LFSR_CFG_CLOCKS;
		writel(val, rng->base + PRNG_LFSR_CFG);

		val = readl_relaxed(rng->base + PRNG_CONFIG);
		val |= PRNG_CONFIG_HW_ENABLE;
		writel(val, rng->base + PRNG_CONFIG);
	} else {
		val = readl_relaxed(rng->base + PRNG_CONFIG);
		val &= ~PRNG_CONFIG_HW_ENABLE;
		writel(val, rng->base + PRNG_CONFIG);
	}

already_enabled:
	clk_disable_unprepare(rng->clk);
	return 0;
}

static int msm_rng_read(struct hwrng *hwrng, void *data, size_t max, bool wait)
{
	struct msm_rng *rng = to_msm_rng(hwrng);
	size_t currsize = 0;
	u32 *retdata = data;
	size_t maxsize;
	int ret;
	u32 val;

	/* calculate max size bytes to transfer back to caller */
	maxsize = min_t(size_t, MAX_HW_FIFO_SIZE, max);

	/* no room for word data */
	if (maxsize < WORD_SZ)
		return 0;

	ret = clk_prepare_enable(rng->clk);
	if (ret)
		return ret;

	/* read random data from hardware */
	do {
		val = readl_relaxed(rng->base + PRNG_STATUS);
		if (!(val & PRNG_STATUS_DATA_AVAIL))
			break;

		val = readl_relaxed(rng->base + PRNG_DATA_OUT);
		if (!val)
			break;

		*retdata++ = val;
		currsize += WORD_SZ;

		/* make sure we stay on 32bit boundary */
		if ((maxsize - currsize) < WORD_SZ)
			break;
	} while (currsize < maxsize);

	clk_disable_unprepare(rng->clk);

	return currsize;
}

static int msm_rng_init(struct hwrng *hwrng)
{
	return msm_rng_enable(hwrng, 1);
}

static void msm_rng_cleanup(struct hwrng *hwrng)
{
	msm_rng_enable(hwrng, 0);
}

static int msm_rng_probe(struct platform_device *pdev)
{
	struct resource *res;
	struct msm_rng *rng;
	int ret;

	rng = devm_kzalloc(&pdev->dev, sizeof(*rng), GFP_KERNEL);
	if (!rng)
		return -ENOMEM;

	platform_set_drvdata(pdev, rng);

	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	rng->base = devm_ioremap_resource(&pdev->dev, res);
	if (IS_ERR(rng->base))
		return PTR_ERR(rng->base);

	rng->clk = devm_clk_get(&pdev->dev, "core");
	if (IS_ERR(rng->clk))
		return PTR_ERR(rng->clk);

	rng->hwrng.name = KBUILD_MODNAME,
	rng->hwrng.init = msm_rng_init,
	rng->hwrng.cleanup = msm_rng_cleanup,
	rng->hwrng.read = msm_rng_read,

	ret = devm_hwrng_register(&pdev->dev, &rng->hwrng);
	if (ret) {
		dev_err(&pdev->dev, "failed to register hwrng\n");
		return ret;
	}

	return 0;
}

static const struct of_device_id msm_rng_of_match[] = {
	{ .compatible = "qcom,prng", },
	{}
};
MODULE_DEVICE_TABLE(of, msm_rng_of_match);

static struct platform_driver msm_rng_driver = {
	.probe = msm_rng_probe,
	.driver = {
		.name = KBUILD_MODNAME,
		.of_match_table = of_match_ptr(msm_rng_of_match),
	}
};
module_platform_driver(msm_rng_driver);

MODULE_ALIAS("platform:" KBUILD_MODNAME);
MODULE_AUTHOR("The Linux Foundation");
MODULE_DESCRIPTION("Qualcomm MSM random number generator driver");
MODULE_LICENSE("GPL v2");
