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;
}