static int turris_mox_rwtm_probe()

in turris-mox-rwtm.c [471:556]


static int turris_mox_rwtm_probe(struct platform_device *pdev)
{
	struct mox_rwtm *rwtm;
	struct device *dev = &pdev->dev;
	int ret;

	rwtm = devm_kzalloc(dev, sizeof(*rwtm), GFP_KERNEL);
	if (!rwtm)
		return -ENOMEM;

	rwtm->dev = dev;
	rwtm->buf = dmam_alloc_coherent(dev, PAGE_SIZE, &rwtm->buf_phys,
					GFP_KERNEL);
	if (!rwtm->buf)
		return -ENOMEM;

	ret = mox_kobj_create(rwtm);
	if (ret < 0) {
		dev_err(dev, "Cannot create turris-mox-rwtm kobject!\n");
		return ret;
	}

	ret = sysfs_create_files(rwtm_to_kobj(rwtm), mox_rwtm_attrs);
	if (ret < 0) {
		dev_err(dev, "Cannot create sysfs files!\n");
		goto put_kobj;
	}

	platform_set_drvdata(pdev, rwtm);

	mutex_init(&rwtm->busy);

	rwtm->mbox_client.dev = dev;
	rwtm->mbox_client.rx_callback = mox_rwtm_rx_callback;

	rwtm->mbox = mbox_request_channel(&rwtm->mbox_client, 0);
	if (IS_ERR(rwtm->mbox)) {
		ret = PTR_ERR(rwtm->mbox);
		if (ret != -EPROBE_DEFER)
			dev_err(dev, "Cannot request mailbox channel: %i\n",
				ret);
		goto remove_files;
	}

	init_completion(&rwtm->cmd_done);

	ret = mox_get_board_info(rwtm);
	if (ret < 0)
		dev_warn(dev, "Cannot read board information: %i\n", ret);

	ret = check_get_random_support(rwtm);
	if (ret < 0) {
		dev_notice(dev,
			   "Firmware does not support the GET_RANDOM command\n");
		goto free_channel;
	}

	rwtm->hwrng.name = DRIVER_NAME "_hwrng";
	rwtm->hwrng.read = mox_hwrng_read;
	rwtm->hwrng.priv = (unsigned long) rwtm;
	rwtm->hwrng.quality = 1024;

	ret = devm_hwrng_register(dev, &rwtm->hwrng);
	if (ret < 0) {
		dev_err(dev, "Cannot register HWRNG: %i\n", ret);
		goto free_channel;
	}

	ret = rwtm_register_debugfs(rwtm);
	if (ret < 0) {
		dev_err(dev, "Failed creating debugfs entries: %i\n", ret);
		goto free_channel;
	}

	dev_info(dev, "HWRNG successfully registered\n");

	return 0;

free_channel:
	mbox_free_channel(rwtm->mbox);
remove_files:
	sysfs_remove_files(rwtm_to_kobj(rwtm), mox_rwtm_attrs);
put_kobj:
	kobject_put(rwtm_to_kobj(rwtm));
	return ret;
}