flush_workqueue(tpacpi_wq);
 }
 
+static void fan_suspend(pm_message_t state)
+{
+       if (!fan_control_allowed)
+               return;
+
+       /* Store fan status in cache */
+       fan_get_status_safe(NULL);
+       if (tp_features.fan_ctrl_status_undef)
+               fan_control_desired_level = TP_EC_FAN_AUTO;
+}
+
+static void fan_resume(void)
+{
+       u8 saved_fan_level;
+       u8 current_level = 7;
+       bool do_set = false;
+
+       /* DSDT *always* updates status on resume */
+       tp_features.fan_ctrl_status_undef = 0;
+
+       saved_fan_level = fan_control_desired_level;
+       if (!fan_control_allowed ||
+           (fan_get_status_safe(¤t_level) < 0))
+               return;
+
+       switch (fan_control_access_mode) {
+       case TPACPI_FAN_WR_ACPI_SFAN:
+               do_set = (saved_fan_level > current_level);
+               break;
+       case TPACPI_FAN_WR_ACPI_FANS:
+       case TPACPI_FAN_WR_TPEC:
+               do_set = ((saved_fan_level & TP_EC_FAN_FULLSPEED) ||
+                         (saved_fan_level == 7 &&
+                          !(current_level & TP_EC_FAN_FULLSPEED)));
+               break;
+       default:
+               return;
+       }
+       if (do_set) {
+               printk(TPACPI_NOTICE
+                       "restoring fan level to 0x%02x\n",
+                       saved_fan_level);
+               fan_set_level_safe(saved_fan_level);
+       }
+}
+
 static int fan_read(char *p)
 {
        int len = 0;
        .read = fan_read,
        .write = fan_write,
        .exit = fan_exit,
+       .suspend = fan_suspend,
+       .resume = fan_resume,
 };
 
 /****************************************************************************