]> bbs.cooldavid.org Git - net-next-2.6.git/blobdiff - drivers/platform/x86/intel_ips.c
NULL pointer might be used in ips_monitor()
[net-next-2.6.git] / drivers / platform / x86 / intel_ips.c
index afe82e50dfea1b03bf53820cf9f9d2edb76e6355..bfa9c726054abe991715c0cce9e86bcdfd80e879 100644 (file)
 #define THM_TC2                0xac
 #define THM_DTV                0xb0
 #define THM_ITV                0xd8
-#define   ITV_ME_SEQNO_MASK 0x000f0000 /* ME should update every ~200ms */
+#define   ITV_ME_SEQNO_MASK 0x00ff0000 /* ME should update every ~200ms */
 #define   ITV_ME_SEQNO_SHIFT (16)
 #define   ITV_MCH_TEMP_MASK 0x0000ff00
 #define   ITV_MCH_TEMP_SHIFT (8)
@@ -940,7 +940,6 @@ static int ips_monitor(void *data)
                kfree(mch_samples);
                kfree(cpu_samples);
                kfree(mchp_samples);
-               kthread_stop(ips->adjust);
                return -ENOMEM;
        }
 
@@ -948,7 +947,7 @@ static int ips_monitor(void *data)
                ITV_ME_SEQNO_SHIFT;
        seqno_timestamp = get_jiffies_64();
 
-       old_cpu_power = thm_readl(THM_CEC) / 65535;
+       old_cpu_power = thm_readl(THM_CEC);
        schedule_timeout_interruptible(msecs_to_jiffies(IPS_SAMPLE_PERIOD));
 
        /* Collect an initial average */
@@ -1342,8 +1341,10 @@ static struct ips_mcp_limits *ips_detect_cpu(struct ips_driver *ips)
                limits = &ips_lv_limits;
        else if (strstr(boot_cpu_data.x86_model_id, "CPU       U"))
                limits = &ips_ulv_limits;
-       else
+       else {
                dev_info(&ips->dev->dev, "No CPUID match found.\n");
+               goto out;
+       }
 
        rdmsrl(TURBO_POWER_CURRENT_LIMIT, turbo_power);
        tdp = turbo_power & TURBO_TDP_MASK;
@@ -1388,7 +1389,7 @@ static bool ips_get_i915_syms(struct ips_driver *ips)
        return true;
 
 out_put_busy:
-       symbol_put(i915_gpu_turbo_disable);
+       symbol_put(i915_gpu_busy);
 out_put_lower:
        symbol_put(i915_gpu_lower);
 out_put_raise:
@@ -1432,6 +1433,12 @@ static int ips_probe(struct pci_dev *dev, const struct pci_device_id *id)
 
        spin_lock_init(&ips->turbo_status_lock);
 
+       ret = pci_enable_device(dev);
+       if (ret) {
+               dev_err(&dev->dev, "can't enable PCI device, aborting\n");
+               goto error_free;
+       }
+
        if (!pci_resource_start(dev, 0)) {
                dev_err(&dev->dev, "TBAR not assigned, aborting\n");
                ret = -ENXIO;
@@ -1444,11 +1451,6 @@ static int ips_probe(struct pci_dev *dev, const struct pci_device_id *id)
                goto error_free;
        }
 
-       ret = pci_enable_device(dev);
-       if (ret) {
-               dev_err(&dev->dev, "can't enable PCI device, aborting\n");
-               goto error_free;
-       }
 
        ips->regmap = ioremap(pci_resource_start(dev, 0),
                              pci_resource_len(dev, 0));
@@ -1532,19 +1534,24 @@ static int ips_probe(struct pci_dev *dev, const struct pci_device_id *id)
        ips_enable_cpu_turbo(ips);
        ips->cpu_turbo_enabled = true;
 
-       /* Set up the work queue and monitor/adjust threads */
-       ips->monitor = kthread_run(ips_monitor, ips, "ips-monitor");
-       if (IS_ERR(ips->monitor)) {
+       /* Create thermal adjust thread */
+       ips->adjust = kthread_create(ips_adjust, ips, "ips-adjust");
+       if (IS_ERR(ips->adjust)) {
                dev_err(&dev->dev,
-                       "failed to create thermal monitor thread, aborting\n");
+                       "failed to create thermal adjust thread, aborting\n");
                ret = -ENOMEM;
                goto error_free_irq;
+
        }
 
-       ips->adjust = kthread_create(ips_adjust, ips, "ips-adjust");
-       if (IS_ERR(ips->adjust)) {
+       /*
+        * Set up the work queue and monitor thread. The monitor thread
+        * will wake up ips_adjust thread.
+        */
+       ips->monitor = kthread_run(ips_monitor, ips, "ips-monitor");
+       if (IS_ERR(ips->monitor)) {
                dev_err(&dev->dev,
-                       "failed to create thermal adjust thread, aborting\n");
+                       "failed to create thermal monitor thread, aborting\n");
                ret = -ENOMEM;
                goto error_thread_cleanup;
        }
@@ -1563,7 +1570,7 @@ static int ips_probe(struct pci_dev *dev, const struct pci_device_id *id)
        return ret;
 
 error_thread_cleanup:
-       kthread_stop(ips->monitor);
+       kthread_stop(ips->adjust);
 error_free_irq:
        free_irq(ips->dev->irq, ips);
 error_unmap: