Merge branch 'for-5.4' of git://git.kernel.org/pub/scm/linux/kernel/git/rzhang/linux
authorLinus Torvalds <torvalds@linux-foundation.org>
Fri, 27 Sep 2019 18:35:13 +0000 (11:35 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Fri, 27 Sep 2019 18:35:13 +0000 (11:35 -0700)
Pull thermal management updates from Zhang Rui:

 - Add Amit Kucheria as thermal subsystem Reviewer (Amit Kucheria)

 - Fix a use after free bug when unregistering thermal zone devices (Ido
   Schimmel)

 - Fix thermal core framework to use put_device() when device_register()
   fails (Yue Hu)

 - Enable intel_pch_thermal and MMIO RAPL support for Intel Icelake
   platform (Srinivas Pandruvada)

 - Add clock operations in qorip thermal driver, for some platforms with
   clock control like i.MX8MQ (Anson Huang)

 - A couple of trivial fixes and cleanups for thermal core and different
   soc thermal drivers (Amit Kucheria, Christophe JAILLET, Chuhong Yuan,
   Fuqian Huang, Kelsey Skunberg, Nathan Huckleberry, Rishi Gupta,
   Srinivas Kandagatla)

* 'for-5.4' of git://git.kernel.org/pub/scm/linux/kernel/git/rzhang/linux:
  MAINTAINERS: Add Amit Kucheria as reviewer for thermal
  thermal: Add some error messages
  thermal: Fix use-after-free when unregistering thermal zone device
  thermal/drivers/core: Use put_device() if device_register() fails
  thermal_hwmon: Sanitize thermal_zone type
  thermal: intel: Use dev_get_drvdata
  thermal: intel: int3403: replace printk(KERN_WARN...) with pr_warn(...)
  thermal: intel: int340x_thermal: Remove unnecessary acpi_has_method() uses
  thermal: int340x: processor_thermal: Add Ice Lake support
  drivers: thermal: qcom: tsens: Fix memory leak from qfprom read
  thermal: tegra: Fix a typo
  thermal: rcar_gen3_thermal: Replace devm_add_action() followed by failure action with devm_add_action_or_reset()
  thermal: armada: Fix -Wshift-negative-value
  dt-bindings: thermal: qoriq: Add optional clocks property
  thermal: qoriq: Use __maybe_unused instead of #if CONFIG_PM_SLEEP
  thermal: qoriq: Use devm_platform_ioremap_resource() instead of of_iomap()
  thermal: qoriq: Fix error path of calling qoriq_tmu_register_tmu_zone fail
  thermal: qoriq: Add clock operations
  drivers: thermal: processor_thermal_device: Export sysfs interface for TCC offset

16 files changed:
Documentation/devicetree/bindings/thermal/qoriq-thermal.txt
MAINTAINERS
drivers/thermal/armada_thermal.c
drivers/thermal/intel/int340x_thermal/acpi_thermal_rel.c
drivers/thermal/intel/int340x_thermal/int3403_thermal.c
drivers/thermal/intel/int340x_thermal/processor_thermal_device.c
drivers/thermal/intel/intel_pch_thermal.c
drivers/thermal/qcom/tsens-8960.c
drivers/thermal/qcom/tsens-v0_1.c
drivers/thermal/qcom/tsens-v1.c
drivers/thermal/qcom/tsens.h
drivers/thermal/qoriq_thermal.c
drivers/thermal/rcar_gen3_thermal.c
drivers/thermal/tegra/soctherm.c
drivers/thermal/thermal_core.c
drivers/thermal/thermal_hwmon.c

index 04cbb90a5d3ee51788cb63c5e668b39eea274795..28f2cbaf170250c86a2f33c199beaaaf3be6567a 100644 (file)
@@ -23,6 +23,7 @@ Required properties:
 Optional property:
 - little-endian : If present, the TMU registers are little endian. If absent,
        the default is big endian.
+- clocks : the clock for clocking the TMU silicon.
 
 Example:
 
index d9ebe514708ba18db53cd183186aa31bed587b22..ee3971d8d3354f829b197f7d7f31b2d1443ac66f 100644 (file)
@@ -16072,6 +16072,7 @@ THERMAL
 M:     Zhang Rui <rui.zhang@intel.com>
 M:     Eduardo Valentin <edubezval@gmail.com>
 R:     Daniel Lezcano <daniel.lezcano@linaro.org>
+R:     Amit Kucheria <amit.kucheria@verdurent.com>
 L:     linux-pm@vger.kernel.org
 T:     git git://git.kernel.org/pub/scm/linux/kernel/git/rzhang/linux.git
 T:     git git://git.kernel.org/pub/scm/linux/kernel/git/evalenti/linux-soc-thermal.git
index 8c07a393dc2e3f02f7d8efd907063e47117790c8..709a22f455e99b6a393fb34fc33666f801e5e348 100644 (file)
@@ -53,7 +53,6 @@
 #define CONTROL0_TSEN_MODE_EXTERNAL    0x2
 #define CONTROL0_TSEN_MODE_MASK                0x3
 
-#define CONTROL1_TSEN_AVG_SHIFT                0
 #define CONTROL1_TSEN_AVG_MASK         0x7
 #define CONTROL1_EXT_TSEN_SW_RESET     BIT(7)
 #define CONTROL1_EXT_TSEN_HW_RESETn    BIT(8)
@@ -267,8 +266,8 @@ static void armada_cp110_init(struct platform_device *pdev,
 
        /* Average the output value over 2^1 = 2 samples */
        regmap_read(priv->syscon, data->syscon_control1_off, &reg);
-       reg &= ~CONTROL1_TSEN_AVG_MASK << CONTROL1_TSEN_AVG_SHIFT;
-       reg |= 1 << CONTROL1_TSEN_AVG_SHIFT;
+       reg &= ~CONTROL1_TSEN_AVG_MASK;
+       reg |= 1;
        regmap_write(priv->syscon, data->syscon_control1_off, reg);
 }
 
index 9716bc3abaf91b6895f45cd153ead9c8afd638f3..7130e90773ed6e4c4f91caec9421136b34e4bc1c 100644 (file)
@@ -77,9 +77,6 @@ int acpi_parse_trt(acpi_handle handle, int *trt_count, struct trt **trtp,
        struct acpi_buffer element = { 0, NULL };
        struct acpi_buffer trt_format = { sizeof("RRNNNNNN"), "RRNNNNNN" };
 
-       if (!acpi_has_method(handle, "_TRT"))
-               return -ENODEV;
-
        status = acpi_evaluate_object(handle, "_TRT", NULL, &buffer);
        if (ACPI_FAILURE(status))
                return -ENODEV;
@@ -158,9 +155,6 @@ int acpi_parse_art(acpi_handle handle, int *art_count, struct art **artp,
        struct acpi_buffer art_format = {
                sizeof("RRNNNNNNNNNNN"), "RRNNNNNNNNNNN" };
 
-       if (!acpi_has_method(handle, "_ART"))
-               return -ENODEV;
-
        status = acpi_evaluate_object(handle, "_ART", NULL, &buffer);
        if (ACPI_FAILURE(status))
                return -ENODEV;
index f5749d4418aebd49aac8d741bbcf8f9e00754882..a7bbd8584ae25222343768a0bbfedd0f3f97d5f4 100644 (file)
@@ -181,7 +181,7 @@ static int int3403_cdev_add(struct int3403_priv *priv)
 
        p = buf.pointer;
        if (!p || (p->type != ACPI_TYPE_PACKAGE)) {
-               printk(KERN_WARNING "Invalid PPSS data\n");
+               pr_warn("Invalid PPSS data\n");
                kfree(buf.pointer);
                return -EFAULT;
        }
index d3446acf9bbde5a0bd4a45f369811f45d900c5ea..89a015387283b53cbd9ca89fd714c475d4e01611 100644 (file)
@@ -39,6 +39,9 @@
 /* GeminiLake thermal reporting device */
 #define PCI_DEVICE_ID_PROC_GLK_THERMAL 0x318C
 
+/* IceLake thermal reporting device */
+#define PCI_DEVICE_ID_PROC_ICL_THERMAL 0x8a03
+
 #define DRV_NAME "proc_thermal"
 
 struct power_config {
@@ -137,6 +140,72 @@ static const struct attribute_group power_limit_attribute_group = {
        .name = "power_limits"
 };
 
+static ssize_t tcc_offset_degree_celsius_show(struct device *dev,
+                              struct device_attribute *attr, char *buf)
+{
+       u64 val;
+       int err;
+
+       err = rdmsrl_safe(MSR_IA32_TEMPERATURE_TARGET, &val);
+       if (err)
+               return err;
+
+       val = (val >> 24) & 0xff;
+       return sprintf(buf, "%d\n", (int)val);
+}
+
+static int tcc_offset_update(int tcc)
+{
+       u64 val;
+       int err;
+
+       if (!tcc)
+               return -EINVAL;
+
+       err = rdmsrl_safe(MSR_IA32_TEMPERATURE_TARGET, &val);
+       if (err)
+               return err;
+
+       val &= ~GENMASK_ULL(31, 24);
+       val |= (tcc & 0xff) << 24;
+
+       err = wrmsrl_safe(MSR_IA32_TEMPERATURE_TARGET, val);
+       if (err)
+               return err;
+
+       return 0;
+}
+
+static int tcc_offset_save;
+
+static ssize_t tcc_offset_degree_celsius_store(struct device *dev,
+                               struct device_attribute *attr, const char *buf,
+                               size_t count)
+{
+       u64 val;
+       int tcc, err;
+
+       err = rdmsrl_safe(MSR_PLATFORM_INFO, &val);
+       if (err)
+               return err;
+
+       if (!(val & BIT(30)))
+               return -EACCES;
+
+       if (kstrtoint(buf, 0, &tcc))
+               return -EINVAL;
+
+       err = tcc_offset_update(tcc);
+       if (err)
+               return err;
+
+       tcc_offset_save = tcc;
+
+       return count;
+}
+
+static DEVICE_ATTR_RW(tcc_offset_degree_celsius);
+
 static int stored_tjmax; /* since it is fixed, we can have local storage */
 
 static int get_tjmax(void)
@@ -332,6 +401,7 @@ static void proc_thermal_remove(struct proc_thermal_device *proc_priv)
        acpi_remove_notify_handler(proc_priv->adev->handle,
                                   ACPI_DEVICE_NOTIFY, proc_thermal_notify);
        int340x_thermal_zone_remove(proc_priv->int340x_zone);
+       sysfs_remove_file(&proc_priv->dev->kobj, &dev_attr_tcc_offset_degree_celsius.attr);
        sysfs_remove_group(&proc_priv->dev->kobj,
                           &power_limit_attribute_group);
 }
@@ -355,8 +425,15 @@ static int int3401_add(struct platform_device *pdev)
 
        dev_info(&pdev->dev, "Creating sysfs group for PROC_THERMAL_PLATFORM_DEV\n");
 
-       return sysfs_create_group(&pdev->dev.kobj,
-                                        &power_limit_attribute_group);
+       ret = sysfs_create_file(&pdev->dev.kobj, &dev_attr_tcc_offset_degree_celsius.attr);
+       if (ret)
+               return ret;
+
+       ret = sysfs_create_group(&pdev->dev.kobj, &power_limit_attribute_group);
+       if (ret)
+               sysfs_remove_file(&pdev->dev.kobj, &dev_attr_tcc_offset_degree_celsius.attr);
+
+       return ret;
 }
 
 static int int3401_remove(struct platform_device *pdev)
@@ -588,8 +665,15 @@ static int  proc_thermal_pci_probe(struct pci_dev *pdev,
 
        dev_info(&pdev->dev, "Creating sysfs group for PROC_THERMAL_PCI\n");
 
-       return sysfs_create_group(&pdev->dev.kobj,
-                                        &power_limit_attribute_group);
+       ret = sysfs_create_file(&pdev->dev.kobj, &dev_attr_tcc_offset_degree_celsius.attr);
+       if (ret)
+               return ret;
+
+       ret = sysfs_create_group(&pdev->dev.kobj, &power_limit_attribute_group);
+       if (ret)
+               sysfs_remove_file(&pdev->dev.kobj, &dev_attr_tcc_offset_degree_celsius.attr);
+
+       return ret;
 }
 
 static void  proc_thermal_pci_remove(struct pci_dev *pdev)
@@ -615,6 +699,8 @@ static int proc_thermal_resume(struct device *dev)
        proc_dev = dev_get_drvdata(dev);
        proc_thermal_read_ppcc(proc_dev);
 
+       tcc_offset_update(tcc_offset_save);
+
        return 0;
 }
 #else
@@ -636,6 +722,8 @@ static const struct pci_device_id proc_thermal_pci_ids[] = {
        { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_PROC_CNL_THERMAL)},
        { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_PROC_CFL_THERMAL)},
        { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_PROC_GLK_THERMAL)},
+       { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_PROC_ICL_THERMAL),
+               .driver_data = (kernel_ulong_t)&rapl_mmio_hsw, },
        { 0, },
 };
 
index 99f8b2540f1813558d7c96c3d758a418e1c72753..4f0bb8f502e16ea488b624640aa29844e934a29b 100644 (file)
@@ -371,16 +371,14 @@ static void intel_pch_thermal_remove(struct pci_dev *pdev)
 
 static int intel_pch_thermal_suspend(struct device *device)
 {
-       struct pci_dev *pdev = to_pci_dev(device);
-       struct pch_thermal_device *ptd = pci_get_drvdata(pdev);
+       struct pch_thermal_device *ptd = dev_get_drvdata(device);
 
        return ptd->ops->suspend(ptd);
 }
 
 static int intel_pch_thermal_resume(struct device *device)
 {
-       struct pci_dev *pdev = to_pci_dev(device);
-       struct pch_thermal_device *ptd = pci_get_drvdata(pdev);
+       struct pch_thermal_device *ptd = dev_get_drvdata(device);
 
        return ptd->ops->resume(ptd);
 }
index 8d9b721dadb6522122891f7fbff59ea8922fe488..e46a4e3f25c42d8dd33ddb83fb4070a97e1e29ec 100644 (file)
@@ -229,6 +229,8 @@ static int calibrate_8960(struct tsens_priv *priv)
        for (i = 0; i < num_read; i++, s++)
                s->offset = data[i];
 
+       kfree(data);
+
        return 0;
 }
 
index 6f26fadf4c27918606e7b93f1be557c98b89ec7d..055647bcee67d33387414276bd8be385e582f20f 100644 (file)
@@ -145,8 +145,10 @@ static int calibrate_8916(struct tsens_priv *priv)
                return PTR_ERR(qfprom_cdata);
 
        qfprom_csel = (u32 *)qfprom_read(priv->dev, "calib_sel");
-       if (IS_ERR(qfprom_csel))
+       if (IS_ERR(qfprom_csel)) {
+               kfree(qfprom_cdata);
                return PTR_ERR(qfprom_csel);
+       }
 
        mode = (qfprom_csel[0] & MSM8916_CAL_SEL_MASK) >> MSM8916_CAL_SEL_SHIFT;
        dev_dbg(priv->dev, "calibration mode is %d\n", mode);
@@ -181,6 +183,8 @@ static int calibrate_8916(struct tsens_priv *priv)
        }
 
        compute_intercept_slope(priv, p1, p2, mode);
+       kfree(qfprom_cdata);
+       kfree(qfprom_csel);
 
        return 0;
 }
@@ -198,8 +202,10 @@ static int calibrate_8974(struct tsens_priv *priv)
                return PTR_ERR(calib);
 
        bkp = (u32 *)qfprom_read(priv->dev, "calib_backup");
-       if (IS_ERR(bkp))
+       if (IS_ERR(bkp)) {
+               kfree(calib);
                return PTR_ERR(bkp);
+       }
 
        calib_redun_sel =  bkp[1] & BKP_REDUN_SEL;
        calib_redun_sel >>= BKP_REDUN_SHIFT;
@@ -313,6 +319,8 @@ static int calibrate_8974(struct tsens_priv *priv)
        }
 
        compute_intercept_slope(priv, p1, p2, mode);
+       kfree(calib);
+       kfree(bkp);
 
        return 0;
 }
index 10b595d4f619982b1b5ef6b23e4cf26b302cbae5..870f502f2cb6c6184ecb8bb61aed7fe58b95cacf 100644 (file)
@@ -138,6 +138,7 @@ static int calibrate_v1(struct tsens_priv *priv)
        }
 
        compute_intercept_slope(priv, p1, p2, mode);
+       kfree(qfprom_cdata);
 
        return 0;
 }
index 2fd94997245bfd6f8aed5d3a4adced8a8a02b24b..b89083b61c383596e3c5c25642fd5d5256c97c72 100644 (file)
@@ -17,6 +17,7 @@
 
 #include <linux/thermal.h>
 #include <linux/regmap.h>
+#include <linux/slab.h>
 
 struct tsens_priv;
 
index 7b364933bfb18b2d863f7f869fbe78199ee2ca81..39542c670301144406470b4cc407edd51f576278 100644 (file)
@@ -2,6 +2,7 @@
 //
 // Copyright 2016 Freescale Semiconductor, Inc.
 
+#include <linux/clk.h>
 #include <linux/module.h>
 #include <linux/platform_device.h>
 #include <linux/err.h>
@@ -72,6 +73,7 @@ struct qoriq_sensor {
 
 struct qoriq_tmu_data {
        struct qoriq_tmu_regs __iomem *regs;
+       struct clk *clk;
        bool little_endian;
        struct qoriq_sensor     *sensor[SITES_MAX];
 };
@@ -202,32 +204,39 @@ static int qoriq_tmu_probe(struct platform_device *pdev)
 
        data->little_endian = of_property_read_bool(np, "little-endian");
 
-       data->regs = of_iomap(np, 0);
-       if (!data->regs) {
+       data->regs = devm_platform_ioremap_resource(pdev, 0);
+       if (IS_ERR(data->regs)) {
                dev_err(&pdev->dev, "Failed to get memory region\n");
-               ret = -ENODEV;
-               goto err_iomap;
+               return PTR_ERR(data->regs);
+       }
+
+       data->clk = devm_clk_get_optional(&pdev->dev, NULL);
+       if (IS_ERR(data->clk))
+               return PTR_ERR(data->clk);
+
+       ret = clk_prepare_enable(data->clk);
+       if (ret) {
+               dev_err(&pdev->dev, "Failed to enable clock\n");
+               return ret;
        }
 
        qoriq_tmu_init_device(data);    /* TMU initialization */
 
        ret = qoriq_tmu_calibration(pdev);      /* TMU calibration */
        if (ret < 0)
-               goto err_tmu;
+               goto err;
 
        ret = qoriq_tmu_register_tmu_zone(pdev);
        if (ret < 0) {
                dev_err(&pdev->dev, "Failed to register sensors\n");
                ret = -ENODEV;
-               goto err_iomap;
+               goto err;
        }
 
        return 0;
 
-err_tmu:
-       iounmap(data->regs);
-
-err_iomap:
+err:
+       clk_disable_unprepare(data->clk);
        platform_set_drvdata(pdev, NULL);
 
        return ret;
@@ -240,14 +249,14 @@ static int qoriq_tmu_remove(struct platform_device *pdev)
        /* Disable monitoring */
        tmu_write(data, TMR_DISABLE, &data->regs->tmr);
 
-       iounmap(data->regs);
+       clk_disable_unprepare(data->clk);
+
        platform_set_drvdata(pdev, NULL);
 
        return 0;
 }
 
-#ifdef CONFIG_PM_SLEEP
-static int qoriq_tmu_suspend(struct device *dev)
+static int __maybe_unused qoriq_tmu_suspend(struct device *dev)
 {
        u32 tmr;
        struct qoriq_tmu_data *data = dev_get_drvdata(dev);
@@ -257,14 +266,21 @@ static int qoriq_tmu_suspend(struct device *dev)
        tmr &= ~TMR_ME;
        tmu_write(data, tmr, &data->regs->tmr);
 
+       clk_disable_unprepare(data->clk);
+
        return 0;
 }
 
-static int qoriq_tmu_resume(struct device *dev)
+static int __maybe_unused qoriq_tmu_resume(struct device *dev)
 {
        u32 tmr;
+       int ret;
        struct qoriq_tmu_data *data = dev_get_drvdata(dev);
 
+       ret = clk_prepare_enable(data->clk);
+       if (ret)
+               return ret;
+
        /* Enable monitoring */
        tmr = tmu_read(data, &data->regs->tmr);
        tmr |= TMR_ME;
@@ -272,7 +288,6 @@ static int qoriq_tmu_resume(struct device *dev)
 
        return 0;
 }
-#endif
 
 static SIMPLE_DEV_PM_OPS(qoriq_tmu_pm_ops,
                         qoriq_tmu_suspend, qoriq_tmu_resume);
index a56463308694e937028bed12111579a72c243c49..755d2b5bd2c2b552eb16effcfd2f7fe27777d66f 100644 (file)
@@ -443,9 +443,8 @@ static int rcar_gen3_thermal_probe(struct platform_device *pdev)
                if (ret)
                        goto error_unregister;
 
-               ret = devm_add_action(dev, rcar_gen3_hwmon_action, zone);
+               ret = devm_add_action_or_reset(dev, rcar_gen3_hwmon_action, zone);
                if (ret) {
-                       rcar_gen3_hwmon_action(zone);
                        goto error_unregister;
                }
 
index 43941eb734eb097492ede7daa1357653fab52216..5acaad3a594f36232e3b0c41f060f87d230cc9a2 100644 (file)
 /* get dividend from the depth */
 #define THROT_DEPTH_DIVIDEND(depth)    ((256 * (100 - (depth)) / 100) - 1)
 
-/* gk20a nv_therm interface N:3 Mapping. Levels defined in tegra124-sochterm.h
+/* gk20a nv_therm interface N:3 Mapping. Levels defined in tegra124-soctherm.h
  * level       vector
  * NONE                3'b000
  * LOW         3'b001
index 6bab66e84eb58c6fc86d1528bf5ffdfa4a1dfc4b..d4481cc8958fec35b5e6ca6fc1b4c677b8ca86a1 100644 (file)
@@ -304,7 +304,7 @@ static void thermal_zone_device_set_polling(struct thermal_zone_device *tz,
                                 &tz->poll_queue,
                                 msecs_to_jiffies(delay));
        else
-               cancel_delayed_work(&tz->poll_queue);
+               cancel_delayed_work_sync(&tz->poll_queue);
 }
 
 static void monitor_thermal_zone(struct thermal_zone_device *tz)
@@ -985,7 +985,7 @@ __thermal_cooling_device_register(struct device_node *np,
        result = device_register(&cdev->device);
        if (result) {
                ida_simple_remove(&thermal_cdev_ida, cdev->id);
-               kfree(cdev);
+               put_device(&cdev->device);
                return ERR_PTR(result);
        }
 
@@ -1240,21 +1240,31 @@ thermal_zone_device_register(const char *type, int trips, int mask,
        struct thermal_zone_device *tz;
        enum thermal_trip_type trip_type;
        int trip_temp;
+       int id;
        int result;
        int count;
        struct thermal_governor *governor;
 
-       if (!type || strlen(type) == 0)
+       if (!type || strlen(type) == 0) {
+               pr_err("Error: No thermal zone type defined\n");
                return ERR_PTR(-EINVAL);
+       }
 
-       if (type && strlen(type) >= THERMAL_NAME_LENGTH)
+       if (type && strlen(type) >= THERMAL_NAME_LENGTH) {
+               pr_err("Error: Thermal zone name (%s) too long, should be under %d chars\n",
+                      type, THERMAL_NAME_LENGTH);
                return ERR_PTR(-EINVAL);
+       }
 
-       if (trips > THERMAL_MAX_TRIPS || trips < 0 || mask >> trips)
+       if (trips > THERMAL_MAX_TRIPS || trips < 0 || mask >> trips) {
+               pr_err("Error: Incorrect number of thermal trips\n");
                return ERR_PTR(-EINVAL);
+       }
 
-       if (!ops)
+       if (!ops) {
+               pr_err("Error: Thermal zone device ops not defined\n");
                return ERR_PTR(-EINVAL);
+       }
 
        if (trips > 0 && (!ops->get_trip_type || !ops->get_trip_temp))
                return ERR_PTR(-EINVAL);
@@ -1266,11 +1276,13 @@ thermal_zone_device_register(const char *type, int trips, int mask,
        INIT_LIST_HEAD(&tz->thermal_instances);
        ida_init(&tz->ida);
        mutex_init(&tz->lock);
-       result = ida_simple_get(&thermal_tz_ida, 0, 0, GFP_KERNEL);
-       if (result < 0)
+       id = ida_simple_get(&thermal_tz_ida, 0, 0, GFP_KERNEL);
+       if (id < 0) {
+               result = id;
                goto free_tz;
+       }
 
-       tz->id = result;
+       tz->id = id;
        strlcpy(tz->type, type, sizeof(tz->type));
        tz->ops = ops;
        tz->tzp = tzp;
@@ -1292,7 +1304,7 @@ thermal_zone_device_register(const char *type, int trips, int mask,
        dev_set_name(&tz->device, "thermal_zone%d", tz->id);
        result = device_register(&tz->device);
        if (result)
-               goto remove_device_groups;
+               goto release_device;
 
        for (count = 0; count < trips; count++) {
                if (tz->ops->get_trip_type(tz, count, &trip_type))
@@ -1343,14 +1355,12 @@ thermal_zone_device_register(const char *type, int trips, int mask,
        return tz;
 
 unregister:
-       ida_simple_remove(&thermal_tz_ida, tz->id);
-       device_unregister(&tz->device);
-       return ERR_PTR(result);
-
-remove_device_groups:
-       thermal_zone_destroy_device_groups(tz);
+       device_del(&tz->device);
+release_device:
+       put_device(&tz->device);
+       tz = NULL;
 remove_id:
-       ida_simple_remove(&thermal_tz_ida, tz->id);
+       ida_simple_remove(&thermal_tz_ida, id);
 free_tz:
        kfree(tz);
        return ERR_PTR(result);
index 40c69a533b240787c2dfa7a9328aecb05ed24bbf..dd5d8ee3792870fccbff4c5ab0b7fb251d007612 100644 (file)
@@ -87,13 +87,17 @@ static struct thermal_hwmon_device *
 thermal_hwmon_lookup_by_type(const struct thermal_zone_device *tz)
 {
        struct thermal_hwmon_device *hwmon;
+       char type[THERMAL_NAME_LENGTH];
 
        mutex_lock(&thermal_hwmon_list_lock);
-       list_for_each_entry(hwmon, &thermal_hwmon_list, node)
-               if (!strcmp(hwmon->type, tz->type)) {
+       list_for_each_entry(hwmon, &thermal_hwmon_list, node) {
+               strcpy(type, tz->type);
+               strreplace(type, '-', '_');
+               if (!strcmp(hwmon->type, type)) {
                        mutex_unlock(&thermal_hwmon_list_lock);
                        return hwmon;
                }
+       }
        mutex_unlock(&thermal_hwmon_list_lock);
 
        return NULL;