data, sizeof(*data));
 }
 
+static void apmf_sbios_heartbeat_notify(struct work_struct *work)
+{
+       struct amd_pmf_dev *dev = container_of(work, struct amd_pmf_dev, heart_beat.work);
+       union acpi_object *info;
+
+       dev_dbg(dev->dev, "Sending heartbeat to SBIOS\n");
+       info = apmf_if_call(dev, APMF_FUNC_SBIOS_HEARTBEAT, NULL);
+       if (!info)
+               goto out;
+
+       schedule_delayed_work(&dev->heart_beat, msecs_to_jiffies(dev->hb_interval * 1000));
+
+out:
+       kfree(info);
+}
+
 static int apmf_if_verify_interface(struct amd_pmf_dev *pdev)
 {
        struct apmf_verify_interface output;
        if (err)
                return err;
 
-       dev_dbg(dev->dev, "system params mask:0x%x flags:0x%x cmd_code:0x%x\n",
+       dev_dbg(dev->dev, "system params mask:0x%x flags:0x%x cmd_code:0x%x heartbeat:%d\n",
                params.valid_mask,
                params.flags,
-               params.command_code);
+               params.command_code,
+               params.heartbeat_int);
        params.flags = params.flags & params.valid_mask;
+       dev->hb_interval = params.heartbeat_int;
 
        return 0;
 }
 
+void apmf_acpi_deinit(struct amd_pmf_dev *pmf_dev)
+{
+       if (pmf_dev->hb_interval)
+               cancel_delayed_work_sync(&pmf_dev->heart_beat);
+}
+
 int apmf_acpi_init(struct amd_pmf_dev *pmf_dev)
 {
        int ret;
                goto out;
        }
 
+       if (pmf_dev->hb_interval) {
+               /* send heartbeats only if the interval is not zero */
+               INIT_DELAYED_WORK(&pmf_dev->heart_beat, apmf_sbios_heartbeat_notify);
+               schedule_delayed_work(&pmf_dev->heart_beat, 0);
+       }
+
 out:
        return ret;
 }
 
 /* APMF Functions */
 #define APMF_FUNC_VERIFY_INTERFACE                     0
 #define APMF_FUNC_GET_SYS_PARAMS                       1
+#define APMF_FUNC_SBIOS_HEARTBEAT                      4
 #define APMF_FUNC_STATIC_SLIDER_GRANULAR       9
 
 /* Message Definitions */
        u32 valid_mask;
        u32 flags;
        u8 command_code;
+       u32 heartbeat_int;
 } __packed;
 
 enum amd_stt_skin_temp {
        enum platform_profile_option current_profile;
        struct platform_profile_handler pprof;
        struct dentry *dbgfs_dir;
+       int hb_interval; /* SBIOS heartbeat interval */
+       struct delayed_work heart_beat;
 };
 
 struct apmf_sps_prop_granular {
 
 /* Core Layer */
 int apmf_acpi_init(struct amd_pmf_dev *pmf_dev);
+void apmf_acpi_deinit(struct amd_pmf_dev *pmf_dev);
 int is_apmf_func_supported(struct amd_pmf_dev *pdev, unsigned long index);
 int amd_pmf_send_cmd(struct amd_pmf_dev *dev, u8 message, bool get, u32 arg, u32 *data);
 int amd_pmf_get_power_source(void);