static int 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"); return -ENXIO; } priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL); if (!priv) return -ENOMEM; priv->rng.name = pdev->name; priv->rng.init = bcm63xx_rng_init; priv->rng.cleanup = bcm63xx_rng_cleanup; prov->rng.data_present = bcm63xx_rng_data_present; priv->rng.data_read = bcm63xx_rng_data_read; priv->clk = devm_clk_get(&pdev->dev, "ipsec"); if (IS_ERR(priv->clk)) { error = PTR_ERR(priv->clk); dev_err(&pdev->dev, "no clock for device: %d\n", error); return error; } if (!devm_request_mem_region(&pdev->dev, r->start, resource_size(r), pdev->name)) { dev_err(&pdev->dev, "request mem failed"); return -EBUSY; } priv->regs = devm_ioremap_nocache(&pdev->dev, r->start, resource_size(r)); if (!priv->regs) { dev_err(&pdev->dev, "ioremap failed"); return -ENOMEM; } error = devm_hwrng_register(&pdev->dev, &priv->rng); if (error) { dev_err(&pdev->dev, "failed to register rng device: %d\n", error); return error; } dev_info(&pdev->dev, "registered RNG driver\n"); return 0; }
static int ks_sa_rng_probe(struct platform_device *pdev) { struct ks_sa_rng *ks_sa_rng; struct device *dev = &pdev->dev; int ret; struct resource *mem; ks_sa_rng = devm_kzalloc(dev, sizeof(*ks_sa_rng), GFP_KERNEL); if (!ks_sa_rng) return -ENOMEM; ks_sa_rng->dev = dev; ks_sa_rng->rng = (struct hwrng) { .name = "ks_sa_hwrng", .init = ks_sa_rng_init, .data_read = ks_sa_rng_data_read, .data_present = ks_sa_rng_data_present, .cleanup = ks_sa_rng_cleanup, }; ks_sa_rng->rng.priv = (unsigned long)dev; mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); ks_sa_rng->reg_rng = devm_ioremap_resource(dev, mem); if (IS_ERR(ks_sa_rng->reg_rng)) return PTR_ERR(ks_sa_rng->reg_rng); ks_sa_rng->regmap_cfg = syscon_regmap_lookup_by_phandle(dev->of_node, "ti,syscon-sa-cfg"); if (IS_ERR(ks_sa_rng->regmap_cfg)) { dev_err(dev, "syscon_node_to_regmap failed\n"); return -EINVAL; } pm_runtime_enable(dev); ret = pm_runtime_get_sync(dev); if (ret < 0) { dev_err(dev, "Failed to enable SA power-domain\n"); pm_runtime_disable(dev); return ret; } platform_set_drvdata(pdev, ks_sa_rng); return devm_hwrng_register(&pdev->dev, &ks_sa_rng->rng); } static int ks_sa_rng_remove(struct platform_device *pdev) { pm_runtime_put_sync(&pdev->dev); pm_runtime_disable(&pdev->dev); return 0; }
static int u2fzero_init_hwrng(struct u2fzero_device *dev, unsigned int minor) { dev->rng_name = devm_kasprintf(&dev->hdev->dev, GFP_KERNEL, "%s-rng%u", DRIVER_SHORT, minor); if (dev->rng_name == NULL) return -ENOMEM; dev->hwrng.name = dev->rng_name; dev->hwrng.read = u2fzero_rng_read; dev->hwrng.quality = 1; return devm_hwrng_register(&dev->hdev->dev, &dev->hwrng); }
static int __init mod_init(void) { int err = -ENODEV; struct pci_dev *pdev = NULL; const struct pci_device_id *ent; u32 pmbase; struct amd768_priv *priv; for_each_pci_dev(pdev) { ent = pci_match_id(pci_tbl, pdev); if (ent) goto found; } /* Device not found. */ return -ENODEV; found: err = pci_read_config_dword(pdev, 0x58, &pmbase); if (err) return err; pmbase &= 0x0000FF00; if (pmbase == 0) return -EIO; priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL); if (!priv) return -ENOMEM; if (!devm_request_region(&pdev->dev, pmbase + PMBASE_OFFSET, PMBASE_SIZE, DRV_NAME)) { dev_err(&pdev->dev, DRV_NAME " region 0x%x already in use!\n", pmbase + 0xF0); return -EBUSY; } priv->iobase = devm_ioport_map(&pdev->dev, pmbase + PMBASE_OFFSET, PMBASE_SIZE); if (!priv->iobase) { pr_err(DRV_NAME "Cannot map ioport\n"); return -ENOMEM; } amd_rng.priv = (unsigned long)priv; priv->pcidev = pdev; pr_info(DRV_NAME " detected\n"); return devm_hwrng_register(&pdev->dev, &amd_rng); }
static int rng_probe(struct platform_device *pdev) { void __iomem *rng_regs; struct resource *res; res = platform_get_resource(pdev, IORESOURCE_MEM, 0); rng_regs = devm_ioremap_resource(&pdev->dev, res); if (IS_ERR(rng_regs)) return PTR_ERR(rng_regs); pasemi_rng.priv = (unsigned long)rng_regs; pr_info("Registering PA Semi RNG\n"); return devm_hwrng_register(&pdev->dev, &pasemi_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)) { of_node_put(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 = KBUILD_MODNAME; 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; }
static int __init tx4939_rng_probe(struct platform_device *dev) { struct tx4939_rng *rngdev; struct resource *r; int i; rngdev = devm_kzalloc(&dev->dev, sizeof(*rngdev), GFP_KERNEL); if (!rngdev) return -ENOMEM; r = platform_get_resource(dev, IORESOURCE_MEM, 0); rngdev->base = devm_ioremap_resource(&dev->dev, r); if (IS_ERR(rngdev->base)) return PTR_ERR(rngdev->base); 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(); /* Reset RNG */ write_rng(TX4939_RNG_RCSR_RST, rngdev->base, TX4939_RNG_RCSR); write_rng(0, rngdev->base, TX4939_RNG_RCSR); /* Start RNG */ write_rng(TX4939_RNG_RCSR_ST, rngdev->base, TX4939_RNG_RCSR); rng_io_end(); /* * Drop first two results. From the datasheet: * The quality of the random numbers generated immediately * after reset can be insufficient. Therefore, do not use * random numbers obtained from the first and second * generations; use the ones from the third or subsequent * generation. */ 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 devm_hwrng_register(&dev->dev, &rngdev->rng); }
static int exynos_rng_probe(struct platform_device *pdev) { struct exynos_rng *exynos_rng; struct resource *res; int ret; exynos_rng = devm_kzalloc(&pdev->dev, sizeof(struct exynos_rng), GFP_KERNEL); if (!exynos_rng) return -ENOMEM; exynos_rng->dev = &pdev->dev; exynos_rng->rng.name = "exynos"; exynos_rng->rng.init = exynos_init; exynos_rng->rng.read = exynos_read; exynos_rng->clk = devm_clk_get(&pdev->dev, "secss"); if (IS_ERR(exynos_rng->clk)) { dev_err(&pdev->dev, "Couldn't get clock.\n"); return -ENOENT; } res = platform_get_resource(pdev, IORESOURCE_MEM, 0); exynos_rng->mem = devm_ioremap_resource(&pdev->dev, res); if (IS_ERR(exynos_rng->mem)) return PTR_ERR(exynos_rng->mem); platform_set_drvdata(pdev, exynos_rng); pm_runtime_set_autosuspend_delay(&pdev->dev, EXYNOS_AUTOSUSPEND_DELAY); pm_runtime_use_autosuspend(&pdev->dev); pm_runtime_enable(&pdev->dev); ret = devm_hwrng_register(&pdev->dev, &exynos_rng->rng); if (ret) { pm_runtime_dont_use_autosuspend(&pdev->dev); pm_runtime_disable(&pdev->dev); } return ret; }