| From 47c332deb8e89f6c59b0bb2615945c6e7fad1a60 Mon Sep 17 00:00:00 2001 |
| From: Linus Walleij <linus.walleij@linaro.org> |
| Date: Tue, 5 Dec 2017 09:36:14 +0100 |
| Subject: hwmon: Deal with errors from the thermal subsystem |
| |
| From: Linus Walleij <linus.walleij@linaro.org> |
| |
| commit 47c332deb8e89f6c59b0bb2615945c6e7fad1a60 upstream. |
| |
| If the thermal subsystem returne -EPROBE_DEFER or any other error |
| when hwmon calls devm_thermal_zone_of_sensor_register(), this is |
| silently ignored. |
| |
| I ran into this with an incorrectly defined thermal zone, making |
| it non-existing and thus this call failed with -EPROBE_DEFER |
| assuming it would appear later. The sensor was still added |
| which is incorrect: sensors must strictly be added after the |
| thermal zones, so deferred probe must be respected. |
| |
| Fixes: d560168b5d0f ("hwmon: (core) New hwmon registration API") |
| Signed-off-by: Linus Walleij <linus.walleij@linaro.org> |
| Signed-off-by: Guenter Roeck <linux@roeck-us.net> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| |
| --- |
| drivers/hwmon/hwmon.c | 21 +++++++++++++++++---- |
| 1 file changed, 17 insertions(+), 4 deletions(-) |
| |
| --- a/drivers/hwmon/hwmon.c |
| +++ b/drivers/hwmon/hwmon.c |
| @@ -143,6 +143,7 @@ static int hwmon_thermal_add_sensor(stru |
| struct hwmon_device *hwdev, int index) |
| { |
| struct hwmon_thermal_data *tdata; |
| + struct thermal_zone_device *tzd; |
| |
| tdata = devm_kzalloc(dev, sizeof(*tdata), GFP_KERNEL); |
| if (!tdata) |
| @@ -151,8 +152,14 @@ static int hwmon_thermal_add_sensor(stru |
| tdata->hwdev = hwdev; |
| tdata->index = index; |
| |
| - devm_thermal_zone_of_sensor_register(&hwdev->dev, index, tdata, |
| - &hwmon_thermal_ops); |
| + tzd = devm_thermal_zone_of_sensor_register(&hwdev->dev, index, tdata, |
| + &hwmon_thermal_ops); |
| + /* |
| + * If CONFIG_THERMAL_OF is disabled, this returns -ENODEV, |
| + * so ignore that error but forward any other error. |
| + */ |
| + if (IS_ERR(tzd) && (PTR_ERR(tzd) != -ENODEV)) |
| + return PTR_ERR(tzd); |
| |
| return 0; |
| } |
| @@ -586,14 +593,20 @@ __hwmon_device_register(struct device *d |
| if (!chip->ops->is_visible(drvdata, hwmon_temp, |
| hwmon_temp_input, j)) |
| continue; |
| - if (info[i]->config[j] & HWMON_T_INPUT) |
| - hwmon_thermal_add_sensor(dev, hwdev, j); |
| + if (info[i]->config[j] & HWMON_T_INPUT) { |
| + err = hwmon_thermal_add_sensor(dev, |
| + hwdev, j); |
| + if (err) |
| + goto free_device; |
| + } |
| } |
| } |
| } |
| |
| return hdev; |
| |
| +free_device: |
| + device_unregister(hdev); |
| free_hwmon: |
| kfree(hwdev); |
| ida_remove: |