/*
 * Generic PowerPC 44x RNG driver
 *
 * Copyright 2011 IBM Corporation
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by the
 * Free Software Foundation; version 2 of the License.
 */

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/interrupt.h>
#include <linux/platform_device.h>
#include <linux/hw_random.h>
#include <linux/delay.h>
#include <linux/of_address.h>
#include <linux/of_platform.h>
#include <linux/io.h>

#include "crypto4xx_core.h"
#include "crypto4xx_trng.h"
#include "crypto4xx_reg_def.h"

#define PPC4XX_TRNG_CTRL	0x0008
#define PPC4XX_TRNG_CTRL_DALM	0x20
#define PPC4XX_TRNG_STAT	0x0004
#define PPC4XX_TRNG_STAT_B	0x1
#define PPC4XX_TRNG_DATA	0x0000

static int ppc4xx_trng_data_present(struct hwrng *rng, int wait)
{
	struct crypto4xx_device *dev = (void *)rng->priv;
	int busy, i, present = 0;

	for (i = 0; i < 20; i++) {
		busy = (in_le32(dev->trng_base + PPC4XX_TRNG_STAT) &
			PPC4XX_TRNG_STAT_B);
		if (!busy || !wait) {
			present = 1;
			break;
		}
		udelay(10);
	}
	return present;
}

static int ppc4xx_trng_data_read(struct hwrng *rng, u32 *data)
{
	struct crypto4xx_device *dev = (void *)rng->priv;
	*data = in_le32(dev->trng_base + PPC4XX_TRNG_DATA);
	return 4;
}

static void ppc4xx_trng_enable(struct crypto4xx_device *dev, bool enable)
{
	u32 device_ctrl;

	device_ctrl = readl(dev->ce_base + CRYPTO4XX_DEVICE_CTRL);
	if (enable)
		device_ctrl |= PPC4XX_TRNG_EN;
	else
		device_ctrl &= ~PPC4XX_TRNG_EN;
	writel(device_ctrl, dev->ce_base + CRYPTO4XX_DEVICE_CTRL);
}

static const struct of_device_id ppc4xx_trng_match[] = {
	{ .compatible = "ppc4xx-rng", },
	{ .compatible = "amcc,ppc460ex-rng", },
	{ .compatible = "amcc,ppc440epx-rng", },
	{},
};

void ppc4xx_trng_probe(struct crypto4xx_core_device *core_dev)
{
	struct crypto4xx_device *dev = core_dev->dev;
	struct device_node *trng = NULL;
	struct hwrng *rng = NULL;
	int err;

	/* Find the TRNG device node and map it */
	trng = of_find_matching_node(NULL, ppc4xx_trng_match);
	if (!trng || !of_device_is_available(trng))
		return;

	dev->trng_base = of_iomap(trng, 0);
	of_node_put(trng);
	if (!dev->trng_base)
		goto err_out;

	rng = kzalloc(sizeof(*rng), GFP_KERNEL);
	if (!rng)
		goto err_out;

	rng->name = MODULE_NAME;
	rng->data_present = ppc4xx_trng_data_present;
	rng->data_read = ppc4xx_trng_data_read;
	rng->priv = (unsigned long) dev;
	core_dev->trng = rng;
	ppc4xx_trng_enable(dev, true);
	out_le32(dev->trng_base + PPC4XX_TRNG_CTRL, PPC4XX_TRNG_CTRL_DALM);
	err = devm_hwrng_register(core_dev->device, core_dev->trng);
	if (err) {
		ppc4xx_trng_enable(dev, false);
		dev_err(core_dev->device, "failed to register hwrng (%d).\n",
			err);
		goto err_out;
	}
	return;

err_out:
	of_node_put(trng);
	iounmap(dev->trng_base);
	kfree(rng);
	dev->trng_base = NULL;
	core_dev->trng = NULL;
}

void ppc4xx_trng_remove(struct crypto4xx_core_device *core_dev)
{
	if (core_dev && core_dev->trng) {
		struct crypto4xx_device *dev = core_dev->dev;

		devm_hwrng_unregister(core_dev->device, core_dev->trng);
		ppc4xx_trng_enable(dev, false);
		iounmap(dev->trng_base);
		kfree(core_dev->trng);
	}
}

MODULE_ALIAS("ppc4xx_rng");
