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; }
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; }
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; }
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; }
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); }
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; }
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; }
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; }
static int __init rng_init(void) { return hwrng_register(&tpm_rng); }
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; }
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; }
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; }
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; }
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; }
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; }
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; }
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; }
static int __init pseries_rng_probe(struct vio_dev *dev, const struct vio_device_id *id) { return hwrng_register(&pseries_rng); }
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; }
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; }
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); }