static int apple_dart_probe()

in apple-dart.c [845:929]


static int apple_dart_probe(struct platform_device *pdev)
{
	int ret;
	u32 dart_params[2];
	struct resource *res;
	struct apple_dart *dart;
	struct device *dev = &pdev->dev;

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

	dart->dev = dev;
	spin_lock_init(&dart->lock);

	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	if (resource_size(res) < 0x4000) {
		dev_err(dev, "MMIO region too small (%pr)\n", res);
		return -EINVAL;
	}

	dart->regs = devm_ioremap_resource(dev, res);
	if (IS_ERR(dart->regs))
		return PTR_ERR(dart->regs);

	dart->irq = platform_get_irq(pdev, 0);
	if (dart->irq < 0)
		return -ENODEV;

	ret = devm_clk_bulk_get_all(dev, &dart->clks);
	if (ret < 0)
		return ret;
	dart->num_clks = ret;

	ret = clk_bulk_prepare_enable(dart->num_clks, dart->clks);
	if (ret)
		return ret;

	ret = apple_dart_hw_reset(dart);
	if (ret)
		goto err_clk_disable;

	dart_params[0] = readl(dart->regs + DART_PARAMS1);
	dart_params[1] = readl(dart->regs + DART_PARAMS2);
	dart->pgsize = 1 << FIELD_GET(DART_PARAMS_PAGE_SHIFT, dart_params[0]);
	dart->supports_bypass = dart_params[1] & DART_PARAMS_BYPASS_SUPPORT;
	dart->force_bypass = dart->pgsize > PAGE_SIZE;

	ret = request_irq(dart->irq, apple_dart_irq, IRQF_SHARED,
			  "apple-dart fault handler", dart);
	if (ret)
		goto err_clk_disable;

	platform_set_drvdata(pdev, dart);

	ret = apple_dart_set_bus_ops(&apple_dart_iommu_ops);
	if (ret)
		goto err_free_irq;

	ret = iommu_device_sysfs_add(&dart->iommu, dev, NULL, "apple-dart.%s",
				     dev_name(&pdev->dev));
	if (ret)
		goto err_remove_bus_ops;

	ret = iommu_device_register(&dart->iommu, &apple_dart_iommu_ops, dev);
	if (ret)
		goto err_sysfs_remove;

	dev_info(
		&pdev->dev,
		"DART [pagesize %x, bypass support: %d, bypass forced: %d] initialized\n",
		dart->pgsize, dart->supports_bypass, dart->force_bypass);
	return 0;

err_sysfs_remove:
	iommu_device_sysfs_remove(&dart->iommu);
err_remove_bus_ops:
	apple_dart_set_bus_ops(NULL);
err_free_irq:
	free_irq(dart->irq, dart);
err_clk_disable:
	clk_bulk_disable_unprepare(dart->num_clks, dart->clks);

	return ret;
}