static int exynos_bus_probe()

in exynos-bus.c [389:466]


static int exynos_bus_probe(struct platform_device *pdev)
{
	struct device *dev = &pdev->dev;
	struct device_node *np = dev->of_node, *node;
	struct devfreq_dev_profile *profile;
	struct exynos_bus *bus;
	int ret, max_state;
	unsigned long min_freq, max_freq;
	bool passive = false;

	if (!np) {
		dev_err(dev, "failed to find devicetree node\n");
		return -EINVAL;
	}

	bus = devm_kzalloc(&pdev->dev, sizeof(*bus), GFP_KERNEL);
	if (!bus)
		return -ENOMEM;
	mutex_init(&bus->lock);
	bus->dev = &pdev->dev;
	platform_set_drvdata(pdev, bus);

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

	node = of_parse_phandle(dev->of_node, "devfreq", 0);
	if (node) {
		of_node_put(node);
		passive = true;
	} else {
		ret = exynos_bus_parent_parse_of(np, bus);
		if (ret < 0)
			return ret;
	}

	/* Parse the device-tree to get the resource information */
	ret = exynos_bus_parse_of(np, bus);
	if (ret < 0)
		goto err_reg;

	if (passive)
		ret = exynos_bus_profile_init_passive(bus, profile);
	else
		ret = exynos_bus_profile_init(bus, profile);

	if (ret < 0)
		goto err;

	/* Create child platform device for the interconnect provider */
	if (of_get_property(dev->of_node, "#interconnect-cells", NULL)) {
		bus->icc_pdev = platform_device_register_data(
						dev, "exynos-generic-icc",
						PLATFORM_DEVID_AUTO, NULL, 0);

		if (IS_ERR(bus->icc_pdev)) {
			ret = PTR_ERR(bus->icc_pdev);
			goto err;
		}
	}

	max_state = bus->devfreq->profile->max_state;
	min_freq = (bus->devfreq->profile->freq_table[0] / 1000);
	max_freq = (bus->devfreq->profile->freq_table[max_state - 1] / 1000);
	pr_info("exynos-bus: new bus device registered: %s (%6ld KHz ~ %6ld KHz)\n",
			dev_name(dev), min_freq, max_freq);

	return 0;

err:
	dev_pm_opp_of_remove_table(dev);
	clk_disable_unprepare(bus->clk);
err_reg:
	dev_pm_opp_put_regulators(bus->opp_table);
	bus->opp_table = NULL;

	return ret;
}