/*
 * Copyright (C) 2016 HiSilicon Co., Ltd.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
 */

#include <linux/err.h>
#include <linux/kernel.h>
#include <linux/hw_random.h>
#include <linux/io.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/platform_device.h>
#include <linux/random.h>

#define RNG_SEED	0x0
#define RNG_CTRL	0x4
  #define RNG_SEED_SEL	BIT(2)
  #define RNG_RING_EN	BIT(1)
  #define RNG_EN	BIT(0)
#define RNG_RAN_NUM	0x10
#define RNG_PHY_SEED	0x14

#define to_hisi_rng(p)	container_of(p, struct hisi_rng, rng)

static int seed_sel;
module_param(seed_sel, int, S_IRUGO);
MODULE_PARM_DESC(seed_sel, "Auto reload seed. 0, use LFSR(default); 1, use ring oscillator.");

struct hisi_rng {
	void __iomem *base;
	struct hwrng rng;
};

static int hisi_rng_init(struct hwrng *rng)
{
	struct hisi_rng *hrng = to_hisi_rng(rng);
	int val = RNG_EN;
	u32 seed;

	/* get a random number as initial seed */
	get_random_bytes(&seed, sizeof(seed));

	writel_relaxed(seed, hrng->base + RNG_SEED);

	/**
	 * The seed is reload periodically, there are two choice
	 * of seeds, default seed using the value from LFSR, or
	 * will use seed generated by ring oscillator.
	 */
	if (seed_sel == 1)
		val |= RNG_RING_EN | RNG_SEED_SEL;

	writel_relaxed(val, hrng->base + RNG_CTRL);
	return 0;
}

static void hisi_rng_cleanup(struct hwrng *rng)
{
	struct hisi_rng *hrng = to_hisi_rng(rng);

	writel_relaxed(0, hrng->base + RNG_CTRL);
}

static int hisi_rng_read(struct hwrng *rng, void *buf, size_t max, bool wait)
{
	struct hisi_rng *hrng = to_hisi_rng(rng);
	u32 *data = buf;

	*data = readl_relaxed(hrng->base + RNG_RAN_NUM);
	return 4;
}

static int hisi_rng_probe(struct platform_device *pdev)
{
	struct hisi_rng *rng;
	struct resource *res;
	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->rng.name = pdev->name;
	rng->rng.init = hisi_rng_init;
	rng->rng.cleanup = hisi_rng_cleanup;
	rng->rng.read = hisi_rng_read;

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

	return 0;
}

static const struct of_device_id hisi_rng_dt_ids[] = {
	{ .compatible = "hisilicon,hip04-rng" },
	{ .compatible = "hisilicon,hip05-rng" },
	{ }
};
MODULE_DEVICE_TABLE(of, hisi_rng_dt_ids);

static struct platform_driver hisi_rng_driver = {
	.probe		= hisi_rng_probe,
	.driver		= {
		.name	= "hisi-rng",
		.of_match_table = of_match_ptr(hisi_rng_dt_ids),
	},
};

module_platform_driver(hisi_rng_driver);

MODULE_LICENSE("GPL");
MODULE_AUTHOR("Kefeng Wang <wangkefeng.wang@huawei>");
MODULE_DESCRIPTION("Hisilicon random number generator driver");
