static int tegra_bpmp_thermal_probe()

in tegra/tegra-bpmp-thermal.c [154:225]


static int tegra_bpmp_thermal_probe(struct platform_device *pdev)
{
	struct tegra_bpmp *bpmp = dev_get_drvdata(pdev->dev.parent);
	struct tegra_bpmp_thermal *tegra;
	struct thermal_zone_device *tzd;
	unsigned int i, max_num_zones;
	int err;

	tegra = devm_kzalloc(&pdev->dev, sizeof(*tegra), GFP_KERNEL);
	if (!tegra)
		return -ENOMEM;

	tegra->dev = &pdev->dev;
	tegra->bpmp = bpmp;

	err = tegra_bpmp_thermal_get_num_zones(bpmp, &max_num_zones);
	if (err) {
		dev_err(&pdev->dev, "failed to get the number of zones: %d\n",
			err);
		return err;
	}

	tegra->zones = devm_kcalloc(&pdev->dev, max_num_zones,
				    sizeof(*tegra->zones), GFP_KERNEL);
	if (!tegra->zones)
		return -ENOMEM;

	for (i = 0; i < max_num_zones; ++i) {
		struct tegra_bpmp_thermal_zone *zone;
		int temp;

		zone = devm_kzalloc(&pdev->dev, sizeof(*zone), GFP_KERNEL);
		if (!zone)
			return -ENOMEM;

		zone->idx = i;
		zone->tegra = tegra;

		err = tegra_bpmp_thermal_get_temp(zone, &temp);
		if (err < 0) {
			devm_kfree(&pdev->dev, zone);
			continue;
		}

		tzd = devm_thermal_zone_of_sensor_register(
			&pdev->dev, i, zone, &tegra_bpmp_of_thermal_ops);
		if (IS_ERR(tzd)) {
			if (PTR_ERR(tzd) == -EPROBE_DEFER)
				return -EPROBE_DEFER;
			devm_kfree(&pdev->dev, zone);
			continue;
		}

		zone->tzd = tzd;
		INIT_WORK(&zone->tz_device_update_work,
			  tz_device_update_work_fn);

		tegra->zones[tegra->num_zones++] = zone;
	}

	err = tegra_bpmp_request_mrq(bpmp, MRQ_THERMAL, bpmp_mrq_thermal,
				     tegra);
	if (err) {
		dev_err(&pdev->dev, "failed to register mrq handler: %d\n",
			err);
		return err;
	}

	platform_set_drvdata(pdev, tegra);

	return 0;
}