예제 #1
0
파일: omap-rng.c 프로젝트: neocanable/linux
static int omap_rng_data_read(struct hwrng *rng, u32 *data)
{
    struct omap_rng_private_data *priv;

    priv = (struct omap_rng_private_data *)rng->priv;

    *data = omap_rng_read_reg(priv, RNG_OUT_REG);

    return sizeof(u32);
}
static int omap_rng_data_present(struct hwrng *rng, int wait)
{
	int data, i;

	for (i = 0; i < 20; i++) {
		data = omap_rng_read_reg(RNG_STAT_REG) ? 0 : 1;
		if (data || !wait)
			break;
		udelay(10);
	}
	return data;
}
예제 #3
0
static int __devinit omap_rng_probe(struct platform_device *pdev)
{
	struct resource *res;
	int ret;

	/*
	 * A bit ugly, and it will never actually happen but there can
	 * be only one RNG and this catches any bork
	 */
	if (rng_dev)
		return -EBUSY;

	if (cpu_is_omap24xx()) {
		rng_ick = clk_get(&pdev->dev, "ick");
		if (IS_ERR(rng_ick)) {
			dev_err(&pdev->dev, "Could not get rng_ick\n");
			ret = PTR_ERR(rng_ick);
			return ret;
		} else
			clk_enable(rng_ick);
	}

	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);

	rng_base = devm_request_and_ioremap(&pdev->dev, res);
	if (!rng_base) {
		ret = -ENOMEM;
		goto err_ioremap;
	}
	dev_set_drvdata(&pdev->dev, res);

	ret = hwrng_register(&omap_rng_ops);
	if (ret)
		goto err_register;

	dev_info(&pdev->dev, "OMAP Random Number Generator ver. %02x\n",
		omap_rng_read_reg(RNG_REV_REG));
	omap_rng_write_reg(RNG_MASK_REG, 0x1);

	rng_dev = pdev;

	return 0;

err_register:
	rng_base = NULL;
err_ioremap:
	if (cpu_is_omap24xx()) {
		clk_disable(rng_ick);
		clk_put(rng_ick);
	}
	return ret;
}
예제 #4
0
static int __init omap_rng_probe(struct platform_device *pdev)
{
	struct resource *res, *mem;
	int ret;

	/*
	 * A bit ugly, and it will never actually happen but there can
	 * be only one RNG and this catches any bork
	 */
	BUG_ON(rng_dev);

	if (cpu_is_omap24xx()) {
		rng_ick = clk_get(NULL, "rng_ick");
		if (IS_ERR(rng_ick)) {
			dev_err(&pdev->dev, "Could not get rng_ick\n");
			ret = PTR_ERR(rng_ick);
			return ret;
		} else
			clk_enable(rng_ick);
	}

	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);

	if (!res)
		return -ENOENT;

	mem = request_mem_region(res->start, res->end - res->start + 1,
				 pdev->name);
	if (mem == NULL)
		return -EBUSY;

	dev_set_drvdata(&pdev->dev, mem);
	rng_base = (u32 __iomem *)io_p2v(res->start);

	ret = hwrng_register(&omap_rng_ops);
	if (ret) {
		release_resource(mem);
		rng_base = NULL;
		return ret;
	}

	dev_info(&pdev->dev, "OMAP Random Number Generator ver. %02x\n",
		omap_rng_read_reg(RNG_REV_REG));
	omap_rng_write_reg(RNG_MASK_REG, 0x1);

	rng_dev = pdev;

	return 0;
}
예제 #5
0
파일: omap-rng.c 프로젝트: neocanable/linux
static int __devinit omap_rng_probe(struct platform_device *pdev)
{
    struct omap_rng_private_data *priv;
    int ret;

    priv = kzalloc(sizeof(struct omap_rng_private_data), GFP_KERNEL);
    if (!priv) {
        dev_err(&pdev->dev, "could not allocate memory\n");
        return -ENOMEM;
    };

    omap_rng_ops.priv = (unsigned long)priv;
    dev_set_drvdata(&pdev->dev, priv);

    priv->mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
    if (!priv->mem_res) {
        ret = -ENOENT;
        goto err_ioremap;
    }

    priv->base = devm_request_and_ioremap(&pdev->dev, priv->mem_res);
    if (!priv->base) {
        ret = -ENOMEM;
        goto err_ioremap;
    }
    dev_set_drvdata(&pdev->dev, priv);

    pm_runtime_enable(&pdev->dev);
    pm_runtime_get_sync(&pdev->dev);

    ret = hwrng_register(&omap_rng_ops);
    if (ret)
        goto err_register;

    dev_info(&pdev->dev, "OMAP Random Number Generator ver. %02x\n",
             omap_rng_read_reg(priv, RNG_REV_REG));

    omap_rng_write_reg(priv, RNG_MASK_REG, 0x1);

    return 0;

err_register:
    priv->base = NULL;
    pm_runtime_disable(&pdev->dev);
err_ioremap:
    kfree(priv);

    return ret;
}
예제 #6
0
static int omap_rng_data_present(struct hwrng *rng, int wait)
{
	int data, i;

	for (i = 0; i < 20; i++) {
		data = omap_rng_read_reg(RNG_STAT_REG) ? 0 : 1;
		if (data || !wait)
			break;
		/* RNG produces data fast enough (2+ MBit/sec, even
		 * during "rngtest" loads, that these delays don't
		 * seem to trigger.  We *could* use the RNG IRQ, but
		 * that'd be higher overhead ... so why bother?
		 */
		udelay(10);
	}
	return data;
}
예제 #7
0
static int omap_rng_data_read(struct hwrng *rng, u32 *data)
{
	*data = omap_rng_read_reg(RNG_OUT_REG);

	return 4;
}
예제 #8
0
/* REVISIT: Does the status bit really work on 16xx? */
static int omap_rng_data_present(struct hwrng *rng)
{
	return omap_rng_read_reg(RNG_STAT_REG) ? 0 : 1;
}
static int __devinit omap_rng_probe(struct platform_device *pdev)
{
	struct resource *res;
	int ret;

	if (rng_dev)
		return -EBUSY;

	if (cpu_is_omap24xx()) {
		rng_ick = clk_get(&pdev->dev, "ick");
		if (IS_ERR(rng_ick)) {
			dev_err(&pdev->dev, "Could not get rng_ick\n");
			ret = PTR_ERR(rng_ick);
			return ret;
		} else
			clk_enable(rng_ick);
	}

	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);

	if (!res) {
		ret = -ENOENT;
		goto err_region;
	}

	if (!request_mem_region(res->start, resource_size(res), pdev->name)) {
		ret = -EBUSY;
		goto err_region;
	}

	dev_set_drvdata(&pdev->dev, res);
	rng_base = ioremap(res->start, resource_size(res));
	if (!rng_base) {
		ret = -ENOMEM;
		goto err_ioremap;
	}

	ret = hwrng_register(&omap_rng_ops);
	if (ret)
		goto err_register;

	dev_info(&pdev->dev, "OMAP Random Number Generator ver. %02x\n",
		omap_rng_read_reg(RNG_REV_REG));
	omap_rng_write_reg(RNG_MASK_REG, 0x1);

	rng_dev = pdev;

	return 0;

err_register:
	iounmap(rng_base);
	rng_base = NULL;
err_ioremap:
	release_mem_region(res->start, resource_size(res));
err_region:
	if (cpu_is_omap24xx()) {
		clk_disable(rng_ick);
		clk_put(rng_ick);
	}
	return ret;
}