const struct scmi_sensor_info **info[hwmon_max];
 };
 
+struct scmi_thermal_sensor {
+       const struct scmi_protocol_handle *ph;
+       const struct scmi_sensor_info *info;
+};
+
 static inline u64 __pow10(u8 x)
 {
        u64 r = 1;
        return 0;
 }
 
-static int scmi_hwmon_read(struct device *dev, enum hwmon_sensor_types type,
-                          u32 attr, int channel, long *val)
+static int scmi_hwmon_read_scaled_value(const struct scmi_protocol_handle *ph,
+                                       const struct scmi_sensor_info *sensor,
+                                       long *val)
 {
        int ret;
        u64 value;
-       const struct scmi_sensor_info *sensor;
-       struct scmi_sensors *scmi_sensors = dev_get_drvdata(dev);
 
-       sensor = *(scmi_sensors->info[type] + channel);
-       ret = sensor_ops->reading_get(scmi_sensors->ph, sensor->id, &value);
+       ret = sensor_ops->reading_get(ph, sensor->id, &value);
        if (ret)
                return ret;
 
        return ret;
 }
 
+static int scmi_hwmon_read(struct device *dev, enum hwmon_sensor_types type,
+                          u32 attr, int channel, long *val)
+{
+       const struct scmi_sensor_info *sensor;
+       struct scmi_sensors *scmi_sensors = dev_get_drvdata(dev);
+
+       sensor = *(scmi_sensors->info[type] + channel);
+
+       return scmi_hwmon_read_scaled_value(scmi_sensors->ph, sensor, val);
+}
+
 static int
 scmi_hwmon_read_string(struct device *dev, enum hwmon_sensor_types type,
                       u32 attr, int channel, const char **str)
        .info = NULL,
 };
 
+static int scmi_hwmon_thermal_get_temp(struct thermal_zone_device *tz,
+                                      int *temp)
+{
+       int ret;
+       long value;
+       struct scmi_thermal_sensor *th_sensor = tz->devdata;
+
+       ret = scmi_hwmon_read_scaled_value(th_sensor->ph, th_sensor->info,
+                                          &value);
+       if (!ret)
+               *temp = value;
+
+       return ret;
+}
+
+static const struct thermal_zone_device_ops scmi_hwmon_thermal_ops = {
+       .get_temp = scmi_hwmon_thermal_get_temp,
+};
+
 static int scmi_hwmon_add_chan_info(struct hwmon_channel_info *scmi_hwmon_chan,
                                    struct device *dev, int num,
                                    enum hwmon_sensor_types type, u32 config)
 };
 
 static u32 hwmon_attributes[hwmon_max] = {
-       [hwmon_chip] = HWMON_C_REGISTER_TZ,
        [hwmon_temp] = HWMON_T_INPUT | HWMON_T_LABEL,
        [hwmon_in] = HWMON_I_INPUT | HWMON_I_LABEL,
        [hwmon_curr] = HWMON_C_INPUT | HWMON_C_LABEL,
        [hwmon_energy] = HWMON_E_INPUT | HWMON_E_LABEL,
 };
 
+static int scmi_thermal_sensor_register(struct device *dev,
+                                       const struct scmi_protocol_handle *ph,
+                                       const struct scmi_sensor_info *sensor)
+{
+       struct scmi_thermal_sensor *th_sensor;
+       struct thermal_zone_device *tzd;
+
+       th_sensor = devm_kzalloc(dev, sizeof(*th_sensor), GFP_KERNEL);
+       if (!th_sensor)
+               return -ENOMEM;
+
+       th_sensor->ph = ph;
+       th_sensor->info = sensor;
+
+       /*
+        * Try to register a temperature sensor with the Thermal Framework:
+        * skip sensors not defined as part of any thermal zone (-ENODEV) but
+        * report any other errors related to misconfigured zones/sensors.
+        */
+       tzd = devm_thermal_of_zone_register(dev, th_sensor->info->id, th_sensor,
+                                           &scmi_hwmon_thermal_ops);
+       if (IS_ERR(tzd)) {
+               devm_kfree(dev, th_sensor);
+
+               if (PTR_ERR(tzd) != -ENODEV)
+                       return PTR_ERR(tzd);
+
+               dev_dbg(dev, "Sensor '%s' not attached to any thermal zone.\n",
+                       sensor->name);
+       } else {
+               dev_dbg(dev, "Sensor '%s' attached to thermal zone ID:%d\n",
+                       sensor->name, tzd->id);
+       }
+
+       return 0;
+}
+
 static int scmi_hwmon_probe(struct scmi_device *sdev)
 {
        int i, idx;
        enum hwmon_sensor_types type;
        struct scmi_sensors *scmi_sensors;
        const struct scmi_sensor_info *sensor;
-       int nr_count[hwmon_max] = {0}, nr_types = 0;
+       int nr_count[hwmon_max] = {0}, nr_types = 0, nr_count_temp = 0;
        const struct hwmon_chip_info *chip_info;
        struct device *hwdev, *dev = &sdev->dev;
        struct hwmon_channel_info *scmi_hwmon_chan;
                }
        }
 
-       if (nr_count[hwmon_temp]) {
-               nr_count[hwmon_chip]++;
-               nr_types++;
-       }
+       if (nr_count[hwmon_temp])
+               nr_count_temp = nr_count[hwmon_temp];
 
        scmi_hwmon_chan = devm_kcalloc(dev, nr_types, sizeof(*scmi_hwmon_chan),
                                       GFP_KERNEL);
        hwdev = devm_hwmon_device_register_with_info(dev, "scmi_sensors",
                                                     scmi_sensors, chip_info,
                                                     NULL);
+       if (IS_ERR(hwdev))
+               return PTR_ERR(hwdev);
 
-       return PTR_ERR_OR_ZERO(hwdev);
+       for (i = 0; i < nr_count_temp; i++) {
+               int ret;
+
+               sensor = *(scmi_sensors->info[hwmon_temp] + i);
+               if (!sensor)
+                       continue;
+
+               /*
+                * Warn on any misconfiguration related to thermal zones but
+                * bail out of probing only on memory errors.
+                */
+               ret = scmi_thermal_sensor_register(dev, ph, sensor);
+               if (ret) {
+                       if (ret == -ENOMEM)
+                               return ret;
+                       dev_warn(dev,
+                                "Thermal zone misconfigured for %s. err=%d\n",
+                                sensor->name, ret);
+               }
+       }
+
+       return 0;
 }
 
 static const struct scmi_device_id scmi_id_table[] = {