/* param1: ptr, param2: count, param3: flag */
static u32 (*omap3_rom_rng_call)(u32, u32, u32);
+struct omap_rom_rng {
+ struct clk *clk;
+ struct device *dev;
+ struct hwrng ops;
+};
+
static struct delayed_work idle_work;
static int rng_idle;
static struct clk *rng_clk;
return 4;
}
-static struct hwrng omap3_rom_rng_ops = {
- .name = "omap3-rom",
- .quality = 900,
-};
-
static int omap3_rom_rng_probe(struct platform_device *pdev)
{
+ struct omap_rom_rng *ddata;
int ret = 0;
- omap3_rom_rng_ops.read = of_device_get_match_data(&pdev->dev);
- if (!omap3_rom_rng_ops.read) {
+ ddata = devm_kzalloc(&pdev->dev, sizeof(*ddata), GFP_KERNEL);
+ if (!ddata)
+ return -ENOMEM;
+
+ ddata->dev = &pdev->dev;
+ ddata->ops.priv = (unsigned long)ddata;
+ ddata->ops.name = "omap3-rom";
+ ddata->ops.read = of_device_get_match_data(&pdev->dev);
+ ddata->ops.quality = 900;
+ if (!ddata->ops.read) {
dev_err(&pdev->dev, "missing rom code handler\n");
return -ENODEV;
}
+ dev_set_drvdata(ddata->dev, ddata);
omap3_rom_rng_call = pdev->dev.platform_data;
if (!omap3_rom_rng_call) {
- pr_err("omap3_rom_rng_call is NULL\n");
+ dev_err(ddata->dev, "rom_rng_call is NULL\n");
return -EINVAL;
}
INIT_DELAYED_WORK(&idle_work, omap3_rom_rng_idle);
- 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);
+ ddata->clk = devm_clk_get(ddata->dev, "ick");
+ if (IS_ERR(ddata->clk)) {
+ dev_err(ddata->dev, "unable to get RNG clock\n");
+ return PTR_ERR(ddata->clk);
}
+ rng_clk = ddata->clk;
/* Leave the RNG in reset state. */
- ret = clk_prepare_enable(rng_clk);
+ ret = clk_prepare_enable(ddata->clk);
if (ret)
return ret;
omap3_rom_rng_idle(0);
- return hwrng_register(&omap3_rom_rng_ops);
+ return hwrng_register(&ddata->ops);
}
static int omap3_rom_rng_remove(struct platform_device *pdev)
{
+ struct omap_rom_rng *ddata;
+
+ ddata = dev_get_drvdata(&pdev->dev);
cancel_delayed_work_sync(&idle_work);
- hwrng_unregister(&omap3_rom_rng_ops);
+ hwrng_unregister(&ddata->ops);
if (!rng_idle)
clk_disable_unprepare(rng_clk);
return 0;