static int sun50i_iommu_probe()

in sun50i-iommu.c [904:986]


static int sun50i_iommu_probe(struct platform_device *pdev)
{
	struct sun50i_iommu *iommu;
	int ret, irq;

	iommu = devm_kzalloc(&pdev->dev, sizeof(*iommu), GFP_KERNEL);
	if (!iommu)
		return -ENOMEM;
	spin_lock_init(&iommu->iommu_lock);
	platform_set_drvdata(pdev, iommu);
	iommu->dev = &pdev->dev;

	iommu->pt_pool = kmem_cache_create(dev_name(&pdev->dev),
					   PT_SIZE, PT_SIZE,
					   SLAB_HWCACHE_ALIGN,
					   NULL);
	if (!iommu->pt_pool)
		return -ENOMEM;

	iommu->group = iommu_group_alloc();
	if (IS_ERR(iommu->group)) {
		ret = PTR_ERR(iommu->group);
		goto err_free_cache;
	}

	iommu->base = devm_platform_ioremap_resource(pdev, 0);
	if (IS_ERR(iommu->base)) {
		ret = PTR_ERR(iommu->base);
		goto err_free_group;
	}

	irq = platform_get_irq(pdev, 0);
	if (irq < 0) {
		ret = irq;
		goto err_free_group;
	}

	iommu->clk = devm_clk_get(&pdev->dev, NULL);
	if (IS_ERR(iommu->clk)) {
		dev_err(&pdev->dev, "Couldn't get our clock.\n");
		ret = PTR_ERR(iommu->clk);
		goto err_free_group;
	}

	iommu->reset = devm_reset_control_get(&pdev->dev, NULL);
	if (IS_ERR(iommu->reset)) {
		dev_err(&pdev->dev, "Couldn't get our reset line.\n");
		ret = PTR_ERR(iommu->reset);
		goto err_free_group;
	}

	ret = iommu_device_sysfs_add(&iommu->iommu, &pdev->dev,
				     NULL, dev_name(&pdev->dev));
	if (ret)
		goto err_free_group;

	ret = iommu_device_register(&iommu->iommu, &sun50i_iommu_ops, &pdev->dev);
	if (ret)
		goto err_remove_sysfs;

	ret = devm_request_irq(&pdev->dev, irq, sun50i_iommu_irq, 0,
			       dev_name(&pdev->dev), iommu);
	if (ret < 0)
		goto err_unregister;

	bus_set_iommu(&platform_bus_type, &sun50i_iommu_ops);

	return 0;

err_unregister:
	iommu_device_unregister(&iommu->iommu);

err_remove_sysfs:
	iommu_device_sysfs_remove(&iommu->iommu);

err_free_group:
	iommu_group_put(iommu->group);

err_free_cache:
	kmem_cache_destroy(iommu->pt_pool);

	return ret;
}