static DEFINE_PER_CPU(struct hfi_cpu_info, hfi_cpu_info) = { .index = -1 };
 
 static int max_hfi_instances;
+static int hfi_clients_nr;
 static struct hfi_instance *hfi_instances;
 
 static struct hfi_features hfi_features;
 enable:
        cpumask_set_cpu(cpu, hfi_instance->cpus);
 
-       /* Enable this HFI instance if this is its first online CPU. */
-       if (cpumask_weight(hfi_instance->cpus) == 1) {
+       /*
+        * Enable this HFI instance if this is its first online CPU and
+        * there are user-space clients of thermal events.
+        */
+       if (cpumask_weight(hfi_instance->cpus) == 1 && hfi_clients_nr > 0) {
                hfi_set_hw_table(hfi_instance);
                hfi_enable();
        }
        return 0;
 }
 
-static void hfi_do_enable(void)
+/*
+ * If concurrency is not prevented by other means, the HFI enable/disable
+ * routines must be called under hfi_instance_lock."
+ */
+static void hfi_enable_instance(void *ptr)
+{
+       hfi_set_hw_table(ptr);
+       hfi_enable();
+}
+
+static void hfi_disable_instance(void *ptr)
+{
+       hfi_disable();
+}
+
+static void hfi_syscore_resume(void)
 {
        /* This code runs only on the boot CPU. */
        struct hfi_cpu_info *info = &per_cpu(hfi_cpu_info, 0);
        struct hfi_instance *hfi_instance = info->hfi_instance;
 
        /* No locking needed. There is no concurrency with CPU online. */
-       hfi_set_hw_table(hfi_instance);
-       hfi_enable();
+       if (hfi_clients_nr > 0)
+               hfi_enable_instance(hfi_instance);
 }
 
-static int hfi_do_disable(void)
+static int hfi_syscore_suspend(void)
 {
        /* No locking needed. There is no concurrency with CPU offline. */
        hfi_disable();
 }
 
 static struct syscore_ops hfi_pm_ops = {
-       .resume = hfi_do_enable,
-       .suspend = hfi_do_disable,
+       .resume = hfi_syscore_resume,
+       .suspend = hfi_syscore_suspend,
+};
+
+static int hfi_thermal_notify(struct notifier_block *nb, unsigned long state,
+                             void *_notify)
+{
+       struct thermal_genl_notify *notify = _notify;
+       struct hfi_instance *hfi_instance;
+       smp_call_func_t func = NULL;
+       unsigned int cpu;
+       int i;
+
+       if (notify->mcgrp != THERMAL_GENL_EVENT_GROUP)
+               return NOTIFY_DONE;
+
+       if (state != THERMAL_NOTIFY_BIND && state != THERMAL_NOTIFY_UNBIND)
+               return NOTIFY_DONE;
+
+       mutex_lock(&hfi_instance_lock);
+
+       switch (state) {
+       case THERMAL_NOTIFY_BIND:
+               if (++hfi_clients_nr == 1)
+                       func = hfi_enable_instance;
+               break;
+       case THERMAL_NOTIFY_UNBIND:
+               if (--hfi_clients_nr == 0)
+                       func = hfi_disable_instance;
+               break;
+       }
+
+       if (!func)
+               goto out;
+
+       for (i = 0; i < max_hfi_instances; i++) {
+               hfi_instance = &hfi_instances[i];
+               if (cpumask_empty(hfi_instance->cpus))
+                       continue;
+
+               cpu = cpumask_any(hfi_instance->cpus);
+               smp_call_function_single(cpu, func, hfi_instance, true);
+       }
+
+out:
+       mutex_unlock(&hfi_instance_lock);
+
+       return NOTIFY_OK;
+}
+
+static struct notifier_block hfi_thermal_nb = {
+       .notifier_call = hfi_thermal_notify,
 };
 
 void __init intel_hfi_init(void)
        if (!hfi_updates_wq)
                goto err_nomem;
 
+       /*
+        * Both thermal core and Intel HFI can not be build as modules.
+        * As kernel build-in drivers they are initialized before user-space
+        * starts, hence we can not miss BIND/UNBIND events when applications
+        * add/remove thermal multicast group to/from a netlink socket.
+        */
+       if (thermal_genl_register_notifier(&hfi_thermal_nb))
+               goto err_nl_notif;
+
        register_syscore_ops(&hfi_pm_ops);
 
        return;
 
+err_nl_notif:
+       destroy_workqueue(hfi_updates_wq);
+
 err_nomem:
        for (j = 0; j < i; ++j) {
                hfi_instance = &hfi_instances[j];