static int __init mod_init(void)
{
	int err;
	int found = 0;
	int i;
	gxio_mica_pka_trng_context_t* rng;

	if (num_hw_trngs > HV_PKA_NUM_SHIMS)
		return -EINVAL;

	if (num_hw_trngs == 0)
		return -ENODEV;

	rng = kzalloc(sizeof(*rng), GFP_KERNEL);
	if (!rng)
		return -ENOMEM;

	for (i = 0; i < HV_PKA_NUM_SHIMS; i++) {
		if (gxio_mica_pka_trng_init(rng, i) == 0)
		{
			found = 1;
			break;
		}
	}
	
	if (!found) {
		printk(KERN_NOTICE "Tilera RNG not detected\n");
		return -ENODEV;
	}

	tile_rng.priv = (unsigned long)rng;

	err = hwrng_register(&tile_rng);
	if (err) {
		printk(KERN_ERR "RNG registering failed (%d)\n", err);
		return err;
	}

	return 0;
}
예제 #2
0
static int __init mod_init(void)
{
	int err = -ENODEV;
	struct pci_dev *pdev = NULL;
	const struct pci_device_id *ent;
	void __iomem *mem;
	unsigned long rng_base;

	for_each_pci_dev(pdev) {
		ent = pci_match_id(pci_tbl, pdev);
		if (ent)
			goto found;
	}
	/* Device not found. */
	goto out;

found:
	rng_base = pci_resource_start(pdev, 0);
	if (rng_base == 0)
		goto out;
	err = -ENOMEM;
	mem = ioremap(rng_base, 0x58);
	if (!mem)
		goto out;
	geode_rng.priv = (unsigned long)mem;

	printk(KERN_INFO "AMD Geode RNG detected\n");
	err = hwrng_register(&geode_rng);
	if (err) {
		printk(KERN_ERR PFX "RNG registering failed (%d)\n",
		       err);
		goto err_unmap;
	}
out:
	return err;

err_unmap:
	iounmap(mem);
	goto out;
}
예제 #3
0
static int __init stm32_rng_init(void)
{
	volatile struct stm32_rng_regs *rng_regs = (void *) STM32_RNG_BASE;
	int err;

	/* Enable RNG clock. */
	STM32_RCC->ahb2enr |= STM32_RCC_AHB2ENR_RNG;

	/* Enable RNG. */
	rng_regs->cr |= STM32_RNG_CR_EN;

	stm32_rng_ops.priv = (unsigned long) rng_regs;

	err = hwrng_register(&stm32_rng_ops);

	if (err)
		printk(KERN_ERR PFX "RNG registering failed (%d)\n", err);

	printk(KERN_INFO "STM32 Hardware RNG initialized\n");

	return err;
}
예제 #4
0
파일: virtio-rng.c 프로젝트: Anjali05/linux
static int virtrng_restore(struct virtio_device *vdev)
{
	int err;

	err = probe_common(vdev);
	if (!err) {
		struct virtrng_info *vi = vdev->priv;

		/*
		 * Set hwrng_removed to ensure that virtio_read()
		 * does not block waiting for data before the
		 * registration is complete.
		 */
		vi->hwrng_removed = true;
		err = hwrng_register(&vi->hwrng);
		if (!err) {
			vi->hwrng_register_done = true;
			vi->hwrng_removed = false;
		}
	}

	return err;
}
예제 #5
0
static int omap3_rom_rng_probe(struct platform_device *pdev)
{
	pr_info("initializing\n");

	omap3_rom_rng_call = pdev->dev.platform_data;
	if (!omap3_rom_rng_call) {
		pr_err("omap3_rom_rng_call is NULL\n");
		return -EINVAL;
	}

	setup_timer(&idle_timer, omap3_rom_rng_idle, 0);
	rng_clk = devm_clk_get(&pdev->dev, "ick");
	if (IS_ERR(rng_clk)) {
		pr_err("unable to get RNG clock\n");
		return PTR_ERR(rng_clk);
	}

	/* Leave the RNG in reset state. */
	clk_prepare_enable(rng_clk);
	omap3_rom_rng_idle(0);

	return hwrng_register(&omap3_rom_rng_ops);
}
static int __init tx4939_rng_probe(struct platform_device *dev)
{
	struct tx4939_rng *rngdev;
	struct resource *r;
	int i;

	r = platform_get_resource(dev, IORESOURCE_MEM, 0);
	if (!r)
		return -EBUSY;
	rngdev = devm_kzalloc(&dev->dev, sizeof(*rngdev), GFP_KERNEL);
	if (!rngdev)
		return -ENOMEM;
	rngdev->base = devm_request_and_ioremap(&dev->dev, r);
	if (!rngdev->base)
		return -EBUSY;

	rngdev->rng.name = dev_name(&dev->dev);
	rngdev->rng.data_present = tx4939_rng_data_present;
	rngdev->rng.data_read = tx4939_rng_data_read;

	rng_io_start();
	
	write_rng(TX4939_RNG_RCSR_RST, rngdev->base, TX4939_RNG_RCSR);
	write_rng(0, rngdev->base, TX4939_RNG_RCSR);
	
	write_rng(TX4939_RNG_RCSR_ST, rngdev->base, TX4939_RNG_RCSR);
	rng_io_end();
	for (i = 0; i < 2; i++) {
		rngdev->data_avail = 0;
		if (!tx4939_rng_data_present(&rngdev->rng, 1))
			return -EIO;
	}

	platform_set_drvdata(dev, rngdev);
	return hwrng_register(&rngdev->rng);
}
예제 #7
0
static int nmk_rng_probe(struct amba_device *dev, const struct amba_id *id)
{
	void __iomem *base;
	int ret;

	rng_clk = clk_get(&dev->dev, NULL);
	if (IS_ERR(rng_clk)) {
		dev_err(&dev->dev, "could not get rng clock\n");
		ret = PTR_ERR(rng_clk);
		return ret;
	}

	clk_prepare_enable(rng_clk);

	ret = amba_request_regions(dev, dev->dev.init_name);
	if (ret)
		goto out_clk;
	ret = -ENOMEM;
	base = ioremap(dev->res.start, resource_size(&dev->res));
	if (!base)
		goto out_release;
	nmk_rng.priv = (unsigned long)base;
	ret = hwrng_register(&nmk_rng);
	if (ret)
		goto out_unmap;
	return 0;

out_unmap:
	iounmap(base);
out_release:
	amba_release_regions(dev);
out_clk:
	clk_disable(rng_clk);
	clk_put(rng_clk);
	return ret;
}
static int __init mod_init(void)
{
	int err = -ENODEV;
	struct pci_dev *pdev = NULL;
	const struct pci_device_id *ent;
	u32 pmbase;

	for_each_pci_dev(pdev) {
		ent = pci_match_id(pci_tbl, pdev);
		if (ent)
			goto found;
	}
	/* Device not found. */
	goto out;

found:
	err = pci_read_config_dword(pdev, 0x58, &pmbase);
	if (err)
		goto out;
	err = -EIO;
	pmbase &= 0x0000FF00;
	if (pmbase == 0)
		goto out;
	amd_rng.priv = (unsigned long)pmbase;
	amd_pdev = pdev;

	printk(KERN_INFO "AMD768 RNG detected\n");
	err = hwrng_register(&amd_rng);
	if (err) {
		printk(KERN_ERR PFX "RNG registering failed (%d)\n",
		       err);
		goto out;
	}
out:
	return err;
}
예제 #9
0
static int xgene_rng_probe(struct platform_device *pdev)
{
	struct resource *res;
	struct xgene_rng_dev *ctx;
	int rc = 0;

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

	ctx->dev = &pdev->dev;
	platform_set_drvdata(pdev, ctx);

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

	ctx->irq = platform_get_irq(pdev, 0);
	if (ctx->irq < 0) {
		dev_err(&pdev->dev, "No IRQ resource\n");
		return ctx->irq;
	}

	dev_dbg(&pdev->dev, "APM X-Gene RNG BASE %p ALARM IRQ %d",
		ctx->csr_base, ctx->irq);

	rc = devm_request_irq(&pdev->dev, ctx->irq, xgene_rng_irq_handler, 0,
				dev_name(&pdev->dev), ctx);
	if (rc) {
		dev_err(&pdev->dev, "Could not request RNG alarm IRQ\n");
		return rc;
	}

	/* Enable IP clock */
	ctx->clk = devm_clk_get(&pdev->dev, NULL);
	if (IS_ERR(ctx->clk)) {
		dev_warn(&pdev->dev, "Couldn't get the clock for RNG\n");
	} else {
		rc = clk_prepare_enable(ctx->clk);
		if (rc) {
			dev_warn(&pdev->dev,
				 "clock prepare enable failed for RNG");
			return rc;
		}
	}

	xgene_rng_func.priv = (unsigned long) ctx;

	rc = hwrng_register(&xgene_rng_func);
	if (rc) {
		dev_err(&pdev->dev, "RNG registering failed error %d\n", rc);
		if (!IS_ERR(ctx->clk))
			clk_disable_unprepare(ctx->clk);
		return rc;
	}

	rc = device_init_wakeup(&pdev->dev, 1);
	if (rc) {
		dev_err(&pdev->dev, "RNG device_init_wakeup failed error %d\n",
			rc);
		if (!IS_ERR(ctx->clk))
			clk_disable_unprepare(ctx->clk);
		hwrng_unregister(&xgene_rng_func);
		return rc;
	}

	return 0;
}
예제 #10
0
static int __devinit msm_rng_probe(struct platform_device *pdev)
{
	struct resource *res;
	struct msm_rng_device *msm_rng_dev = NULL;
	void __iomem *base = NULL;
	int error = 0;

	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	if (res == NULL) {
		dev_err(&pdev->dev, "invalid address\n");
		error = -EFAULT;
		goto err_exit;
	}

	msm_rng_dev = kzalloc(sizeof(msm_rng_dev), GFP_KERNEL);
	if (!msm_rng_dev) {
		dev_err(&pdev->dev, "cannot allocate memory\n");
		error = -ENOMEM;
		goto err_exit;
	}

	base = ioremap(res->start, resource_size(res));
	if (!base) {
		dev_err(&pdev->dev, "ioremap failed\n");
		error = -ENOMEM;
		goto err_iomap;
	}
	msm_rng_dev->base = base;

	/* create a handle for clock control */
	msm_rng_dev->prng_clk = clk_get(&pdev->dev, "core_clk");
	if (IS_ERR(msm_rng_dev->prng_clk)) {
		dev_err(&pdev->dev, "failed to register clock source\n");
		error = -EPERM;
		goto err_clk_get;
	}

	/* save away pdev and register driver data */
	msm_rng_dev->pdev = pdev;
	platform_set_drvdata(pdev, msm_rng_dev);

	/* Enable rng h/w */
	error = msm_rng_enable_hw(msm_rng_dev);

	if (error)
		goto rollback_clk;

	/* register with hwrng framework */
	msm_rng.priv = (unsigned long) msm_rng_dev;
	error = hwrng_register(&msm_rng);
	if (error) {
		dev_err(&pdev->dev, "failed to register hwrng\n");
		error = -EPERM;
		goto rollback_clk;
	}

	return 0;

rollback_clk:
	clk_put(msm_rng_dev->prng_clk);
err_clk_get:
	iounmap(msm_rng_dev->base);
err_iomap:
	kfree(msm_rng_dev);
err_exit:
	return error;
}
예제 #11
0
파일: tpm-rng.c 프로젝트: 0-T-0/ps4-linux
static int __init rng_init(void)
{
	return hwrng_register(&tpm_rng);
}
예제 #12
0
static int __devinit omap4_rng_probe(struct platform_device *pdev)
{
	struct resource *res;
	int ret;
	u32 reg;

	/*
	 * 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;

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

	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(&omap4_rng_ops);
	if (ret)
		goto err_register;

	reg = trng_read(REV);
	dev_info(&pdev->dev, "OMAP4 Random Number Generator ver. %u.%02u\n",
		 ((reg & RNG_REG_REV_X_MAJOR_MASK) >> 4),
		 (reg & RNG_REG_REV_Y_MINOR_MASK));

	rng_dev = pdev;

	/* start TRNG if not running yet */
	if (!(trng_read(CONTROL) & RNG_REG_CONTROL_ENABLE_TRNG)) {
		trng_write(0x00220021, CONFIG);
		trng_write(0x00210400, CONTROL);
	}

	return 0;

err_register:
	iounmap(rng_base);
	rng_base = NULL;
err_ioremap:
	release_mem_region(res->start, resource_size(res));
err_region:
	clk_disable(rng_fck);
	clk_put(rng_fck);
	return ret;
}
예제 #13
0
static int timeriomem_rng_probe(struct platform_device *pdev)
{
	struct timeriomem_rng_data *pdata = pdev->dev.platform_data;
	struct timeriomem_rng_private *priv;
	struct resource *res;
	int err = 0;
	int period;

	if (!pdev->dev.of_node && !pdata) {
		dev_err(&pdev->dev, "timeriomem_rng_data is missing\n");
		return -EINVAL;
	}

	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	if (!res)
		return -ENXIO;

	if (res->start % 4 != 0 || resource_size(res) != 4) {
		dev_err(&pdev->dev,
			"address must be four bytes wide and aligned\n");
		return -EINVAL;
	}

	/* Allocate memory for the device structure (and zero it) */
	priv = devm_kzalloc(&pdev->dev,
			sizeof(struct timeriomem_rng_private), GFP_KERNEL);
	if (!priv)
		return -ENOMEM;

	platform_set_drvdata(pdev, priv);

	if (pdev->dev.of_node) {
		int i;

		if (!of_property_read_u32(pdev->dev.of_node,
						"period", &i))
			period = i;
		else {
			dev_err(&pdev->dev, "missing period\n");
			return -EINVAL;
		}

		if (!of_property_read_u32(pdev->dev.of_node,
						"quality", &i))
			priv->rng_ops.quality = i;
		else
			priv->rng_ops.quality = 0;
	} else {
		period = pdata->period;
		priv->rng_ops.quality = pdata->quality;
	}

	priv->period = ns_to_ktime(period * NSEC_PER_USEC);
	init_completion(&priv->completion);
	hrtimer_init(&priv->timer, CLOCK_MONOTONIC, HRTIMER_MODE_ABS);
	priv->timer.function = timeriomem_rng_trigger;

	priv->rng_ops.name = dev_name(&pdev->dev);
	priv->rng_ops.read = timeriomem_rng_read;

	priv->io_base = devm_ioremap_resource(&pdev->dev, res);
	if (IS_ERR(priv->io_base)) {
		return PTR_ERR(priv->io_base);
	}

	/* Assume random data is already available. */
	priv->present = 1;
	complete(&priv->completion);

	err = hwrng_register(&priv->rng_ops);
	if (err) {
		dev_err(&pdev->dev, "problem registering\n");
		return err;
	}

	dev_info(&pdev->dev, "32bits from 0x%p @ %dus\n",
			priv->io_base, period);

	return 0;
}
static int msm_rng_probe(struct platform_device *pdev)
{
	struct resource *res;
	struct msm_rng_device *msm_rng_dev = NULL;
	void __iomem *base = NULL;
	int error = 0;
	int ret = 0;
	struct device *dev;

	struct msm_bus_scale_pdata *qrng_platform_support = NULL;

	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	if (res == NULL) {
		dev_err(&pdev->dev, "invalid address\n");
		error = -EFAULT;
		goto err_exit;
	}

	msm_rng_dev = kzalloc(sizeof(msm_rng_dev), GFP_KERNEL);
	if (!msm_rng_dev) {
		dev_err(&pdev->dev, "cannot allocate memory\n");
		error = -ENOMEM;
		goto err_exit;
	}

	base = ioremap(res->start, resource_size(res));
	if (!base) {
		dev_err(&pdev->dev, "ioremap failed\n");
		error = -ENOMEM;
		goto err_iomap;
	}
	msm_rng_dev->base = base;

	/* create a handle for clock control */
	if ((pdev->dev.of_node) && (of_property_read_bool(pdev->dev.of_node,
					"qcom,msm-rng-iface-clk")))
		msm_rng_dev->prng_clk = clk_get(&pdev->dev,
							"iface_clk");
	else
		msm_rng_dev->prng_clk = clk_get(&pdev->dev, "core_clk");
	if (IS_ERR(msm_rng_dev->prng_clk)) {
		dev_err(&pdev->dev, "failed to register clock source\n");
		error = -EPERM;
		goto err_clk_get;
	}

	/* save away pdev and register driver data */
	msm_rng_dev->pdev = pdev;
	platform_set_drvdata(pdev, msm_rng_dev);

	if (pdev->dev.of_node) {
		/* Register bus client */
		qrng_platform_support = msm_bus_cl_get_pdata(pdev);
		msm_rng_dev->qrng_perf_client = msm_bus_scale_register_client(
						qrng_platform_support);
		msm_rng_device_info.qrng_perf_client =
					msm_rng_dev->qrng_perf_client;
		if (!msm_rng_dev->qrng_perf_client)
			pr_err("Unable to register bus client\n");
	}

	/* Enable rng h/w */
	error = msm_rng_enable_hw(msm_rng_dev);

	if (error)
		goto rollback_clk;

	/* register with hwrng framework */
	msm_rng.priv = (unsigned long) msm_rng_dev;
	error = hwrng_register(&msm_rng);
	if (error) {
		dev_err(&pdev->dev, "failed to register hwrng\n");
		error = -EPERM;
		goto rollback_clk;
	}
	ret = register_chrdev(QRNG_IOC_MAGIC, DRIVER_NAME, &msm_rng_fops);

	msm_rng_class = class_create(THIS_MODULE, "msm-rng");
	if (IS_ERR(msm_rng_class)) {
		pr_err("class_create failed\n");
		return PTR_ERR(msm_rng_class);
	}

	dev = device_create(msm_rng_class, NULL, MKDEV(QRNG_IOC_MAGIC, 0),
				NULL, "msm-rng");
	if (IS_ERR(dev)) {
		pr_err("Device create failed\n");
		error = PTR_ERR(dev);
		goto unregister_chrdev;
	}
	cdev_init(&msm_rng_cdev, &msm_rng_fops);

	return ret;

unregister_chrdev:
	unregister_chrdev(QRNG_IOC_MAGIC, DRIVER_NAME);
rollback_clk:
	clk_put(msm_rng_dev->prng_clk);
err_clk_get:
	iounmap(msm_rng_dev->base);
err_iomap:
	kfree(msm_rng_dev);
err_exit:
	return error;
}
예제 #15
0
static int __devinit 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;
}
예제 #16
0
static int __init mod_init(void)
{
	int err = -ENODEV;
	int i;
	struct pci_dev *dev = NULL;
	void __iomem *mem = mem;
	u8 hw_status;
	struct intel_rng_hw *intel_rng_hw;

	for (i = 0; !dev && pci_tbl[i].vendor; ++i)
		dev = pci_get_device(pci_tbl[i].vendor, pci_tbl[i].device,
				     NULL);

	if (!dev)
		goto out; /* Device not found. */

	if (no_fwh_detect < 0) {
		pci_dev_put(dev);
		goto fwh_done;
	}

	intel_rng_hw = kmalloc(sizeof(*intel_rng_hw), GFP_KERNEL);
	if (!intel_rng_hw) {
		pci_dev_put(dev);
		goto out;
	}

	err = intel_init_hw_struct(intel_rng_hw, dev);
	if (err) {
		pci_dev_put(dev);
		kfree(intel_rng_hw);
		if (err == -ENODEV)
			goto fwh_done;
		goto out;
	}

	/*
	 * Since the BIOS code/data is going to disappear from its normal
	 * location with the Read ID command, all activity on the system
	 * must be stopped until the state is back to normal.
	 *
	 * Use stop_machine because IPIs can be blocked by disabling
	 * interrupts.
	 */
	err = stop_machine(intel_rng_hw_init, intel_rng_hw, NULL);
	pci_dev_put(dev);
	iounmap(intel_rng_hw->mem);
	kfree(intel_rng_hw);
	if (err)
		goto out;

fwh_done:
	err = -ENOMEM;
	mem = ioremap(INTEL_RNG_ADDR, INTEL_RNG_ADDR_LEN);
	if (!mem)
		goto out;
	intel_rng.priv = (unsigned long)mem;

	/* Check for Random Number Generator */
	err = -ENODEV;
	hw_status = hwstatus_get(mem);
	if ((hw_status & INTEL_RNG_PRESENT) == 0) {
		iounmap(mem);
		goto out;
	}

	printk(KERN_INFO "Intel 82802 RNG detected\n");
	err = hwrng_register(&intel_rng);
	if (err) {
		printk(KERN_ERR PFX "RNG registering failed (%d)\n",
		       err);
		iounmap(mem);
	}
out:
	return err;

}
예제 #17
0
static int __init mod_init(void)
{
	int err = -ENODEV;
	int i;
	struct pci_dev *dev = NULL;
	void __iomem *mem = mem;
	u8 hw_status;
	struct intel_rng_hw *intel_rng_hw;

	for (i = 0; !dev && pci_tbl[i].vendor; ++i)
		dev = pci_get_device(pci_tbl[i].vendor, pci_tbl[i].device,
				     NULL);

	if (!dev)
		goto out; 

	if (no_fwh_detect < 0) {
		pci_dev_put(dev);
		goto fwh_done;
	}

	intel_rng_hw = kmalloc(sizeof(*intel_rng_hw), GFP_KERNEL);
	if (!intel_rng_hw) {
		pci_dev_put(dev);
		goto out;
	}

	err = intel_init_hw_struct(intel_rng_hw, dev);
	if (err) {
		pci_dev_put(dev);
		kfree(intel_rng_hw);
		if (err == -ENODEV)
			goto fwh_done;
		goto out;
	}

	
	err = stop_machine(intel_rng_hw_init, intel_rng_hw, NULL);
	pci_dev_put(dev);
	iounmap(intel_rng_hw->mem);
	kfree(intel_rng_hw);
	if (err)
		goto out;

fwh_done:
	err = -ENOMEM;
	mem = ioremap(INTEL_RNG_ADDR, INTEL_RNG_ADDR_LEN);
	if (!mem)
		goto out;
	intel_rng.priv = (unsigned long)mem;

	
	err = -ENODEV;
	hw_status = hwstatus_get(mem);
	if ((hw_status & INTEL_RNG_PRESENT) == 0) {
		iounmap(mem);
		goto out;
	}

	printk(KERN_INFO "Intel 82802 RNG detected\n");
	err = hwrng_register(&intel_rng);
	if (err) {
		printk(KERN_ERR PFX "RNG registering failed (%d)\n",
		       err);
		iounmap(mem);
	}
out:
	return err;

}
예제 #18
0
static int __init mxc_rnga_probe(struct platform_device *pdev)
{
	int err = -ENODEV;
	struct clk *clk;
	struct resource *res, *mem;
	void __iomem *rng_base = NULL;

	if (rng_dev)
		return -EBUSY;

	clk = clk_get(&pdev->dev, "rng");
	if (IS_ERR(clk)) {
		dev_err(&pdev->dev, "Could not get rng_clk!\n");
		err = PTR_ERR(clk);
		goto out;
	}

	clk_enable(clk);

	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	if (!res) {
		err = -ENOENT;
		goto err_region;
	}

	mem = request_mem_region(res->start, resource_size(res), pdev->name);
	if (mem == NULL) {
		err = -EBUSY;
		goto err_region;
	}

	rng_base = ioremap(res->start, resource_size(res));
	if (!rng_base) {
		err = -ENOMEM;
		goto err_ioremap;
	}

	mxc_rnga.priv = (unsigned long)rng_base;

	err = hwrng_register(&mxc_rnga);
	if (err) {
		dev_err(&pdev->dev, "MXC RNGA registering failed (%d)\n", err);
		goto err_register;
	}

	rng_dev = pdev;

	dev_info(&pdev->dev, "MXC RNGA Registered.\n");

	return 0;

err_register:
	iounmap(rng_base);
	rng_base = NULL;

err_ioremap:
	release_mem_region(res->start, resource_size(res));

err_region:
	clk_disable(clk);
	clk_put(clk);

out:
	return err;
}
예제 #19
0
static int __devinit 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
	 */
	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)
		return -ENOENT;

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

	dev_set_drvdata(&pdev->dev, mem);
	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_resource(mem);
err_region:
	if (cpu_is_omap24xx()) {
		clk_disable(rng_ick);
		clk_put(rng_ick);
	}
	return ret;
}
예제 #20
0
파일: chaoskey.c 프로젝트: Chong-Li/cse522
static int chaoskey_probe(struct usb_interface *interface,
			  const struct usb_device_id *id)
{
	struct usb_device *udev = interface_to_usbdev(interface);
	struct usb_host_interface *altsetting = interface->cur_altsetting;
	int i;
	int in_ep = -1;
	struct chaoskey *dev;
	int result;
	int size;

	usb_dbg(interface, "probe %s-%s", udev->product, udev->serial);

	/* Find the first bulk IN endpoint and its packet size */
	for (i = 0; i < altsetting->desc.bNumEndpoints; i++) {
		if (usb_endpoint_is_bulk_in(&altsetting->endpoint[i].desc)) {
			in_ep = usb_endpoint_num(&altsetting->endpoint[i].desc);
			size = usb_endpoint_maxp(&altsetting->endpoint[i].desc);
			break;
		}
	}

	/* Validate endpoint and size */
	if (in_ep == -1) {
		usb_dbg(interface, "no IN endpoint found");
		return -ENODEV;
	}
	if (size <= 0) {
		usb_dbg(interface, "invalid size (%d)", size);
		return -ENODEV;
	}

	if (size > CHAOSKEY_BUF_LEN) {
		usb_dbg(interface, "size reduced from %d to %d\n",
			size, CHAOSKEY_BUF_LEN);
		size = CHAOSKEY_BUF_LEN;
	}

	/* Looks good, allocate and initialize */

	dev = kzalloc(sizeof(struct chaoskey), GFP_KERNEL);

	if (dev == NULL)
		return -ENOMEM;

	dev->buf = kmalloc(size, GFP_KERNEL);

	if (dev->buf == NULL) {
		kfree(dev);
		return -ENOMEM;
	}

	/* Construct a name using the product and serial values. Each
	 * device needs a unique name for the hwrng code
	 */

	if (udev->product && udev->serial) {
		dev->name = kmalloc(strlen(udev->product) + 1 +
				    strlen(udev->serial) + 1, GFP_KERNEL);
		if (dev->name == NULL) {
			kfree(dev->buf);
			kfree(dev);
			return -ENOMEM;
		}

		strcpy(dev->name, udev->product);
		strcat(dev->name, "-");
		strcat(dev->name, udev->serial);
	}

	dev->interface = interface;

	dev->in_ep = in_ep;

	dev->size = size;
	dev->present = 1;

	init_waitqueue_head(&dev->wait_q);

	mutex_init(&dev->lock);
	mutex_init(&dev->rng_lock);

	usb_set_intfdata(interface, dev);

	result = usb_register_dev(interface, &chaoskey_class);
	if (result) {
		usb_err(interface, "Unable to allocate minor number.");
		usb_set_intfdata(interface, NULL);
		chaoskey_free(dev);
		return result;
	}

	dev->hwrng.name = dev->name ? dev->name : chaoskey_driver.name;
	dev->hwrng.read = chaoskey_rng_read;

	/* Set the 'quality' metric.  Quality is measured in units of
	 * 1/1024's of a bit ("mills"). This should be set to 1024,
	 * but there is a bug in the hwrng core which masks it with
	 * 1023.
	 *
	 * The patch that has been merged to the crypto development
	 * tree for that bug limits the value to 1024 at most, so by
	 * setting this to 1024 + 1023, we get 1023 before the fix is
	 * merged and 1024 afterwards. We'll patch this driver once
	 * both bits of code are in the same tree.
	 */
	dev->hwrng.quality = 1024 + 1023;

	dev->hwrng_registered = (hwrng_register(&dev->hwrng) == 0);
	if (!dev->hwrng_registered)
		usb_err(interface, "Unable to register with hwrng");

	usb_enable_autosuspend(udev);

	usb_dbg(interface, "chaoskey probe success, size %d", dev->size);
	return 0;
}
예제 #21
0
static int __init pseries_rng_probe(struct vio_dev *dev,
		const struct vio_device_id *id)
{
	return hwrng_register(&pseries_rng);
}
예제 #22
0
파일: chaoskey.c 프로젝트: mkrufky/linux
static int chaoskey_probe(struct usb_interface *interface,
			  const struct usb_device_id *id)
{
	struct usb_device *udev = interface_to_usbdev(interface);
	struct usb_host_interface *altsetting = interface->cur_altsetting;
	struct usb_endpoint_descriptor *epd;
	int in_ep;
	struct chaoskey *dev;
	int result = -ENOMEM;
	int size;
	int res;

	usb_dbg(interface, "probe %s-%s", udev->product, udev->serial);

	/* Find the first bulk IN endpoint and its packet size */
	res = usb_find_bulk_in_endpoint(altsetting, &epd);
	if (res) {
		usb_dbg(interface, "no IN endpoint found");
		return res;
	}

	in_ep = usb_endpoint_num(epd);
	size = usb_endpoint_maxp(epd);

	/* Validate endpoint and size */
	if (size <= 0) {
		usb_dbg(interface, "invalid size (%d)", size);
		return -ENODEV;
	}

	if (size > CHAOSKEY_BUF_LEN) {
		usb_dbg(interface, "size reduced from %d to %d\n",
			size, CHAOSKEY_BUF_LEN);
		size = CHAOSKEY_BUF_LEN;
	}

	/* Looks good, allocate and initialize */

	dev = kzalloc(sizeof(struct chaoskey), GFP_KERNEL);

	if (dev == NULL)
		goto out;

	dev->buf = kmalloc(size, GFP_KERNEL);

	if (dev->buf == NULL)
		goto out;

	dev->urb = usb_alloc_urb(0, GFP_KERNEL);

	if (!dev->urb)
		goto out;

	usb_fill_bulk_urb(dev->urb,
		udev,
		usb_rcvbulkpipe(udev, in_ep),
		dev->buf,
		size,
		chaos_read_callback,
		dev);

	/* Construct a name using the product and serial values. Each
	 * device needs a unique name for the hwrng code
	 */

	if (udev->product && udev->serial) {
		dev->name = kmalloc(strlen(udev->product) + 1 +
				    strlen(udev->serial) + 1, GFP_KERNEL);
		if (dev->name == NULL)
			goto out;

		strcpy(dev->name, udev->product);
		strcat(dev->name, "-");
		strcat(dev->name, udev->serial);
	}

	dev->interface = interface;

	dev->in_ep = in_ep;

	if (le16_to_cpu(udev->descriptor.idVendor) != ALEA_VENDOR_ID)
		dev->reads_started = 1;

	dev->size = size;
	dev->present = 1;

	init_waitqueue_head(&dev->wait_q);

	mutex_init(&dev->lock);
	mutex_init(&dev->rng_lock);

	usb_set_intfdata(interface, dev);

	result = usb_register_dev(interface, &chaoskey_class);
	if (result) {
		usb_err(interface, "Unable to allocate minor number.");
		goto out;
	}

	dev->hwrng.name = dev->name ? dev->name : chaoskey_driver.name;
	dev->hwrng.read = chaoskey_rng_read;
	dev->hwrng.quality = 1024;

	dev->hwrng_registered = (hwrng_register(&dev->hwrng) == 0);
	if (!dev->hwrng_registered)
		usb_err(interface, "Unable to register with hwrng");

	usb_enable_autosuspend(udev);

	usb_dbg(interface, "chaoskey probe success, size %d", dev->size);
	return 0;

out:
	usb_set_intfdata(interface, NULL);
	chaoskey_free(dev);
	return result;
}
예제 #23
0
static int timeriomem_rng_probe(struct platform_device *pdev)
{
	struct timeriomem_rng_data *pdata = pdev->dev.platform_data;
	struct timeriomem_rng_private_data *priv;
	struct resource *res;
	int err = 0;
	int period;

	if (!pdev->dev.of_node && !pdata) {
		dev_err(&pdev->dev, "timeriomem_rng_data is missing\n");
		return -EINVAL;
	}

	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	if (!res)
		return -ENXIO;

	if (res->start % 4 != 0 || resource_size(res) != 4) {
		dev_err(&pdev->dev,
			"address must be four bytes wide and aligned\n");
		return -EINVAL;
	}

	/* Allocate memory for the device structure (and zero it) */
	priv = kzalloc(sizeof(struct timeriomem_rng_private_data), GFP_KERNEL);
	if (!priv) {
		dev_err(&pdev->dev, "failed to allocate device structure.\n");
		return -ENOMEM;
	}

	platform_set_drvdata(pdev, priv);

	if (pdev->dev.of_node) {
		int i;

		if (!of_property_read_u32(pdev->dev.of_node,
						"period", &i))
			period = i;
		else {
			dev_err(&pdev->dev, "missing period\n");
			err = -EINVAL;
			goto out_free;
		}
	} else
		period = pdata->period;

	priv->period = usecs_to_jiffies(period);
	if (priv->period < 1) {
		dev_err(&pdev->dev, "period is less than one jiffy\n");
		err = -EINVAL;
		goto out_free;
	}

	priv->expires	= jiffies;
	priv->present	= 1;

	init_completion(&priv->completion);
	complete(&priv->completion);

	setup_timer(&priv->timer, timeriomem_rng_trigger, (unsigned long)priv);

	priv->timeriomem_rng_ops.name		= dev_name(&pdev->dev);
	priv->timeriomem_rng_ops.data_present	= timeriomem_rng_data_present;
	priv->timeriomem_rng_ops.data_read	= timeriomem_rng_data_read;
	priv->timeriomem_rng_ops.priv		= (unsigned long)priv;

	if (!request_mem_region(res->start, resource_size(res),
				dev_name(&pdev->dev))) {
		dev_err(&pdev->dev, "request_mem_region failed\n");
		err = -EBUSY;
		goto out_timer;
	}

	priv->io_base = ioremap(res->start, resource_size(res));
	if (priv->io_base == NULL) {
		dev_err(&pdev->dev, "ioremap failed\n");
		err = -EIO;
		goto out_release_io;
	}

	err = hwrng_register(&priv->timeriomem_rng_ops);
	if (err) {
		dev_err(&pdev->dev, "problem registering\n");
		goto out;
	}

	dev_info(&pdev->dev, "32bits from 0x%p @ %dus\n",
			priv->io_base, period);

	return 0;

out:
	iounmap(priv->io_base);
out_release_io:
	release_mem_region(res->start, resource_size(res));
out_timer:
	del_timer_sync(&priv->timer);
out_free:
	platform_set_drvdata(pdev, NULL);
	kfree(priv);
	return err;
}
예제 #24
0
static int probe_common(struct virtio_device *vdev)
{
	int err, index;
	struct virtrng_info *vi = NULL;

	vi = kzalloc(sizeof(struct virtrng_info), GFP_KERNEL);
	if (!vi)
		return -ENOMEM;

	vi->index = index = ida_simple_get(&rng_index_ida, 0, 0, GFP_KERNEL);
	if (index < 0) {
		kfree(vi);
		return index;
	}
	sprintf(vi->name, "virtio_rng.%d", index);
	init_completion(&vi->have_data);

	vi->hwrng = (struct hwrng) {
		.read = virtio_read,
		.cleanup = virtio_cleanup,
		.priv = (unsigned long)vi,
		.name = vi->name,
	};
	vdev->priv = vi;

	/* We expect a single virtqueue. */
	vi->vq = virtio_find_single_vq(vdev, random_recv_done, "input");
	if (IS_ERR(vi->vq)) {
		err = PTR_ERR(vi->vq);
		vi->vq = NULL;
		kfree(vi);
		ida_simple_remove(&rng_index_ida, index);
		return err;
	}

	err = hwrng_register(&vi->hwrng);
	if (err) {
		vdev->config->del_vqs(vdev);
		vi->vq = NULL;
		kfree(vi);
		ida_simple_remove(&rng_index_ida, index);
		return err;
	}

	probe_done = true;
	return 0;
}

static void remove_common(struct virtio_device *vdev)
{
	struct virtrng_info *vi = vdev->priv;
	vdev->config->reset(vdev);
	vi->busy = false;
	hwrng_unregister(&vi->hwrng);
	vdev->config->del_vqs(vdev);
	ida_simple_remove(&rng_index_ida, vi->index);
	kfree(vi);
}

static int virtrng_probe(struct virtio_device *vdev)
{
	return probe_common(vdev);
}

static void virtrng_remove(struct virtio_device *vdev)
{
	remove_common(vdev);
}