diff options
Diffstat (limited to 'drivers')
| -rw-r--r-- | drivers/thermal/tegra/tegra-bpmp-thermal.c | 52 | 
1 files changed, 51 insertions, 1 deletions
| diff --git a/drivers/thermal/tegra/tegra-bpmp-thermal.c b/drivers/thermal/tegra/tegra-bpmp-thermal.c index a2879d624945..4ffc3bb3bf35 100644 --- a/drivers/thermal/tegra/tegra-bpmp-thermal.c +++ b/drivers/thermal/tegra/tegra-bpmp-thermal.c @@ -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; @@ -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; | 
