Skip to content

Commit

Permalink
thermal/drivers/tegra-bpmp: Check if BPMP supports trip points
Browse files Browse the repository at this point in the history
Check if BPMP supports thermal trip points, and if not,
do not expose the .set_trips callback to the thermal core
framework. This can happen in virtualized environments
where asynchronous communication with VM BPMP drivers is not
available.

Signed-off-by: Mikko Perttunen <mperttunen@nvidia.com>
Acked-by: Thierry Reding <treding@nvidia.com>
Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
Link: https://lore.kernel.org/r/20221129153914.2699041-1-cyndis@kapsi.fi
  • Loading branch information
Mikko Perttunen authored and Daniel Lezcano committed Aug 22, 2023
1 parent 72684d9 commit 1ef5a9f
Showing 1 changed file with 51 additions and 1 deletion.
52 changes: 51 additions & 1 deletion drivers/thermal/tegra/tegra-bpmp-thermal.c
Original file line number Diff line number Diff line change
Expand Up @@ -167,19 +167,69 @@ static int tegra_bpmp_thermal_get_num_zones(struct tegra_bpmp *bpmp,
return 0;
}

static int tegra_bpmp_thermal_trips_supported(struct tegra_bpmp *bpmp, bool *supported)
{
struct mrq_thermal_host_to_bpmp_request req;
union mrq_thermal_bpmp_to_host_response reply;
struct tegra_bpmp_message msg;
int err;

memset(&req, 0, sizeof(req));
req.type = CMD_THERMAL_QUERY_ABI;
req.query_abi.type = CMD_THERMAL_SET_TRIP;

memset(&msg, 0, sizeof(msg));
msg.mrq = MRQ_THERMAL;
msg.tx.data = &req;
msg.tx.size = sizeof(req);
msg.rx.data = &reply;
msg.rx.size = sizeof(reply);

err = tegra_bpmp_transfer(bpmp, &msg);
if (err)
return err;

if (msg.rx.ret == 0) {
*supported = true;
return 0;
} else if (msg.rx.ret == -BPMP_ENODEV) {
*supported = false;
return 0;
} else {
return -EINVAL;
}
}

static const struct thermal_zone_device_ops tegra_bpmp_of_thermal_ops = {
.get_temp = tegra_bpmp_thermal_get_temp,
.set_trips = tegra_bpmp_thermal_set_trips,
};

static const struct thermal_zone_device_ops tegra_bpmp_of_thermal_ops_notrips = {
.get_temp = tegra_bpmp_thermal_get_temp,
};

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

err = tegra_bpmp_thermal_trips_supported(bpmp, &supported);
if (err) {
dev_err(&pdev->dev, "failed to determine if trip points are supported\n");
return err;
}

if (supported)
thermal_ops = &tegra_bpmp_of_thermal_ops;
else
thermal_ops = &tegra_bpmp_of_thermal_ops_notrips;

tegra = devm_kzalloc(&pdev->dev, sizeof(*tegra), GFP_KERNEL);
if (!tegra)
return -ENOMEM;
Expand Down Expand Up @@ -222,7 +272,7 @@ static int tegra_bpmp_thermal_probe(struct platform_device *pdev)
}

tzd = devm_thermal_of_zone_register(
&pdev->dev, i, zone, &tegra_bpmp_of_thermal_ops);
&pdev->dev, i, zone, thermal_ops);
if (IS_ERR(tzd)) {
if (PTR_ERR(tzd) == -EPROBE_DEFER)
return -EPROBE_DEFER;
Expand Down

0 comments on commit 1ef5a9f

Please sign in to comment.