* is some wrong values returned by cpuid for number of thresholds.
 */
 #define MAX_NUMBER_OF_TRIPS    2
-/* Limit number of package temp zones */
-#define MAX_PKG_TEMP_ZONE_IDS  256
 
 struct pkg_device {
-       struct list_head                list;
-       u16                             phys_proc_id;
-       u16                             cpu;
+       int                             cpu;
        bool                            work_scheduled;
        u32                             tj_max;
        u32                             msr_pkg_therm_low;
        .no_hwmon       = true,
 };
 
-/* List maintaining number of package instances */
-static LIST_HEAD(phy_dev_list);
+/* Keep track of how many package pointers we allocated in init() */
+static int max_packages __read_mostly;
+/* Array of package pointers */
+static struct pkg_device **packages;
 /* Serializes interrupt notification, work and hotplug */
 static DEFINE_SPINLOCK(pkg_temp_lock);
 /* Protects zone operation in the work function against hotplug removal */
  */
 static struct pkg_device *pkg_temp_thermal_get_dev(unsigned int cpu)
 {
-       u16 phys_proc_id = topology_physical_package_id(cpu);
-       struct pkg_device *pkgdev;
+       int pkgid = topology_logical_package_id(cpu);
 
-       list_for_each_entry(pkgdev, &phy_dev_list, list) {
-               if (pkgdev->phys_proc_id == phys_proc_id)
-                       return pkgdev;
-       }
+       if (pkgid >= 0 && pkgid < max_packages)
+               return packages[pkgid];
        return NULL;
 }
 
 
 static int pkg_temp_thermal_device_add(unsigned int cpu)
 {
+       int pkgid = topology_logical_package_id(cpu);
        u32 tj_max, eax, ebx, ecx, edx;
        struct pkg_device *pkgdev;
        int thres_count, err;
 
+       if (pkgid >= max_packages)
+               return -ENOMEM;
+
        cpuid(6, &eax, &ebx, &ecx, &edx);
        thres_count = ebx & 0x07;
        if (!thres_count)
                return -ENODEV;
 
-       if (topology_physical_package_id(cpu) > MAX_PKG_TEMP_ZONE_IDS)
-               return -ENODEV;
-
        thres_count = clamp_val(thres_count, 0, MAX_NUMBER_OF_TRIPS);
 
        err = get_tj_max(cpu, &tj_max);
                return -ENOMEM;
 
        INIT_DELAYED_WORK(&pkgdev->work, pkg_temp_thermal_threshold_work_fn);
-       pkgdev->phys_proc_id = topology_physical_package_id(cpu);
        pkgdev->cpu = cpu;
        pkgdev->tj_max = tj_max;
        pkgdev->tzone = thermal_zone_device_register("x86_pkg_temp",
 
        cpumask_set_cpu(cpu, &pkgdev->cpumask);
        spin_lock_irq(&pkg_temp_lock);
-       list_add_tail(&pkgdev->list, &phy_dev_list);
+       packages[pkgid] = pkgdev;
        spin_unlock_irq(&pkg_temp_lock);
        return 0;
 }
 
        /*
         * If this is the last CPU in the package remove the package
-        * reference from the list and restore the interrupt MSR. When we
+        * reference from the array and restore the interrupt MSR. When we
         * drop the lock neither the interrupt notify function nor the
         * worker will see the package anymore.
         */
        if (lastcpu) {
-               list_del(&pkgdev->list);
+               packages[topology_logical_package_id(cpu)] = NULL;
                /*
                 * After this point nothing touches the MSR anymore. We
                 * must drop the lock to make the cross cpu call. This goes
        if (!x86_match_cpu(pkg_temp_thermal_ids))
                return -ENODEV;
 
+       max_packages = topology_max_packages();
+       packages = kzalloc(max_packages * sizeof(struct pkg_device *), GFP_KERNEL);
+       if (!packages)
+               return -ENOMEM;
+
        cpu_notifier_register_begin();
        for_each_online_cpu(i)
                if (get_core_online(i))
        for_each_online_cpu(i)
                put_core_offline(i);
        cpu_notifier_register_done();
+       kfree(packages);
        return -ENODEV;
 }
 module_init(pkg_temp_thermal_init)
        cpu_notifier_register_done();
 
        debugfs_remove_recursive(debugfs);
+       kfree(packages);
 }
 module_exit(pkg_temp_thermal_exit)