diff --git a/hw/i2c/Makefile.objs b/hw/i2c/Makefile.objs
index a081b8e..7ad3d04 100644
--- a/hw/i2c/Makefile.objs
+++ b/hw/i2c/Makefile.objs
@@ -1,4 +1,4 @@
-common-obj-y += core.o smbus.o smbus_eeprom.o
+common-obj-y += core.o smbus.o smbus_eeprom.o smbus_alert.o
 common-obj-$(CONFIG_DDC) += i2c-ddc.o
 common-obj-$(CONFIG_VERSATILE_I2C) += versatile_i2c.o
 common-obj-$(CONFIG_ACPI_X86) += smbus_ich9.o
diff --git a/hw/i2c/smbus_alert.c b/hw/i2c/smbus_alert.c
new file mode 100644
index 0000000..5be83e7
--- /dev/null
+++ b/hw/i2c/smbus_alert.c
@@ -0,0 +1,130 @@
+/*
+ * QEMU SMBus alert
+ *
+ * Copyright (c) 2015,2016 Corey Minyard, MontaVista Software, LLC
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+#include "qemu/osdep.h"
+#include "hw/hw.h"
+#include "hw/i2c/smbus_alert.h"
+#include "qapi/error.h"
+#include "qemu/error-report.h"
+
+static void smbus_alert(SMBusAlertDevice *sad, SMBusAlertEntry *alert)
+{
+    if (alert->enqueued) {
+        return;
+    }
+
+    alert->enqueued = true;
+    QSIMPLEQ_INSERT_TAIL(&sad->alert_queue, alert, link);
+    qemu_irq_raise(*sad->irq);
+}
+
+static uint8_t alert_receive_byte(SMBusDevice *dev)
+{
+    SMBusAlertDevice *sad = (SMBusAlertDevice *) dev;
+    SMBusAlertEntry *alert = QSIMPLEQ_FIRST(&sad->alert_queue);
+
+    if (!alert) {
+        return -1;
+    }
+
+    alert->enqueued = false;
+    QSIMPLEQ_REMOVE_HEAD(&sad->alert_queue, link);
+
+    if (QSIMPLEQ_EMPTY(&sad->alert_queue)) {
+            qemu_irq_lower(*sad->irq);
+    }
+
+    return alert->val;
+}
+
+static int smbus_alert_event(SMBusDevice *dev, enum i2c_event event)
+{
+    SMBusAlertDevice *sad = (SMBusAlertDevice *) dev;
+
+    if (event == I2C_START_RECV && QSIMPLEQ_EMPTY(&sad->alert_queue)) {
+        return -1;
+    }
+
+    return 0;
+}
+
+static void smbus_alert_realize(DeviceState *dev, Error **errp)
+{
+    SMBusAlertDevice *sad = SMBUS_ALERT_DEVICE(dev);
+    IRQInterfaceClass *iic;
+
+    if (!sad->irqdev) {
+        error_setg(errp, "SMBus alert device created without irqid");
+        return;
+    }
+
+    iic = IRQ_INTERFACE_GET_CLASS(sad->irqdev);
+
+    sad->irq = iic->get_irq(sad->irqdev);
+}
+
+static void irq_check(Object *obj, const char *name,
+                      Object *val, Error **errp)
+{
+    /* Always succeed. */
+}
+
+static void smbus_alert_init(Object *obj)
+{
+    SMBusAlertDevice *sad = SMBUS_ALERT_DEVICE(obj);
+
+    QSIMPLEQ_INIT(&sad->alert_queue);
+
+    object_property_add_link(obj, "irqid", TYPE_IRQ_INTERFACE,
+                             (Object **) &sad->irqdev, irq_check,
+                             OBJ_PROP_LINK_UNREF_ON_RELEASE,
+                             &error_abort);
+}
+
+static void smbus_alert_class_init(ObjectClass *oc, void *data)
+{
+    DeviceClass *dc = DEVICE_CLASS(oc);
+    SMBusDeviceClass *sc = SMBUS_DEVICE_CLASS(oc);
+    SMBusAlertDeviceClass *sadc = SMBUS_ALERT_DEVICE_CLASS(oc);
+
+    dc->realize = smbus_alert_realize;
+    sc->receive_byte = alert_receive_byte;
+    sc->event = smbus_alert_event;
+    sadc->alert = smbus_alert;
+}
+
+static const TypeInfo smbus_alert_info = {
+    .name          = TYPE_SMBUS_ALERT_DEVICE,
+    .parent        = TYPE_SMBUS_DEVICE,
+    .instance_size = sizeof(SMBusAlertDevice),
+    .instance_init = smbus_alert_init,
+    .class_init    = smbus_alert_class_init,
+    .class_size    = sizeof(SMBusAlertDeviceClass),
+};
+
+static void smbus_alert_register_types(void)
+{
+    type_register_static(&smbus_alert_info);
+}
+
+type_init(smbus_alert_register_types)
diff --git a/include/hw/i2c/smbus.h b/include/hw/i2c/smbus.h
index fc995eb..b6e149a 100644
--- a/include/hw/i2c/smbus.h
+++ b/include/hw/i2c/smbus.h
@@ -26,6 +26,7 @@
  */
 
 #include "hw/i2c/i2c.h"
+#include "qemu/queue.h"
 
 #define TYPE_SMBUS_DEVICE "smbus-device"
 #define SMBUS_DEVICE(obj) \
diff --git a/include/hw/i2c/smbus_alert.h b/include/hw/i2c/smbus_alert.h
new file mode 100644
index 0000000..0b01be7
--- /dev/null
+++ b/include/hw/i2c/smbus_alert.h
@@ -0,0 +1,65 @@
+/*
+ * QEMU SMBus alert
+ *
+ * Copyright (c) 2015,2016 Corey Minyard, MontaVista Software, LLC
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "hw/irqif.h"
+#include "qemu/queue.h"
+#include "hw/i2c/smbus.h"
+
+#ifndef HW_I2C_SMBUS_ALERT
+#define HW_I2C_SMBUS_ALERT
+
+typedef struct SMBusAlertEntry {
+    uint8_t val;
+
+    /* Internal use */
+    bool enqueued;
+    QSIMPLEQ_ENTRY(SMBusAlertEntry) link;
+} SMBusAlertEntry;
+
+typedef struct SMBusAlertDevice {
+    SMBusDevice parent;
+
+    IRQInterface *irqdev;
+    qemu_irq *irq;
+
+    QSIMPLEQ_HEAD(, SMBusAlertEntry) alert_queue;
+} SMBusAlertDevice;
+
+typedef struct SMBusAlertDeviceClass {
+    SMBusDeviceClass parent;
+
+    void (*alert)(SMBusAlertDevice *sad, SMBusAlertEntry *alert);
+} SMBusAlertDeviceClass;
+
+#define TYPE_SMBUS_ALERT_DEVICE "smbus-alert"
+#define SMBUS_ALERT_DEVICE(obj) OBJECT_CHECK(SMBusAlertDevice, (obj),    \
+                                             TYPE_SMBUS_ALERT_DEVICE)
+#define SMBUS_ALERT_DEVICE_CLASS(obj) OBJECT_CLASS_CHECK(SMBusAlertDeviceClass,\
+                                             (obj),            \
+                                             TYPE_SMBUS_ALERT_DEVICE)
+#define SMBUS_ALERT_DEVICE_GET_CLASS(obj) \
+                OBJECT_GET_CLASS(SMBusAlertDeviceClass,  (obj),            \
+                                 TYPE_SMBUS_ALERT_DEVICE)
+
+#endif /* HW_I2C_SMBUS_ALERT */
