#define REG_MTXFIFO    0x00
 #define REG_MRXFIFO    0x04
 #define REG_SMSTA      0x14
+#define REG_IMASK      0x18
 #define REG_CTL                0x1c
 #define REG_REV                0x28
 
                val |= CTL_EN;
 
        reg_write(smbus, REG_CTL, val);
+       reinit_completion(&smbus->irq_completion);
 }
 
 static void pasemi_smb_clear(struct pasemi_smbus *smbus)
 
 static int pasemi_smb_waitready(struct pasemi_smbus *smbus)
 {
-       int timeout = 10;
+       int timeout = 100;
        unsigned int status;
 
-       status = reg_read(smbus, REG_SMSTA);
-
-       while (!(status & SMSTA_XEN) && timeout--) {
-               msleep(1);
+       if (smbus->use_irq) {
+               reinit_completion(&smbus->irq_completion);
+               reg_write(smbus, REG_IMASK, SMSTA_XEN | SMSTA_MTN);
+               wait_for_completion_timeout(&smbus->irq_completion, msecs_to_jiffies(100));
+               reg_write(smbus, REG_IMASK, 0);
                status = reg_read(smbus, REG_SMSTA);
+       } else {
+               status = reg_read(smbus, REG_SMSTA);
+               while (!(status & SMSTA_XEN) && timeout--) {
+                       msleep(1);
+                       status = reg_read(smbus, REG_SMSTA);
+               }
        }
 
        /* Got NACK? */
 
        /* set up the sysfs linkage to our parent device */
        smbus->adapter.dev.parent = smbus->dev;
+       smbus->use_irq = 0;
+       init_completion(&smbus->irq_completion);
 
        if (smbus->hw_rev != PASEMI_HW_REV_PCI)
                smbus->hw_rev = reg_read(smbus, REG_REV);
 
+       reg_write(smbus, REG_IMASK, 0);
+
        pasemi_reset(smbus);
 
        error = devm_i2c_add_adapter(smbus->dev, &smbus->adapter);
 
        return 0;
 }
+
+irqreturn_t pasemi_irq_handler(int irq, void *dev_id)
+{
+       struct pasemi_smbus *smbus = dev_id;
+
+       reg_write(smbus, REG_IMASK, 0);
+       complete(&smbus->irq_completion);
+       return IRQ_HANDLED;
+}
 
 #include <linux/i2c-smbus.h>
 #include <linux/io.h>
 #include <linux/kernel.h>
+#include <linux/completion.h>
 
 #define PASEMI_HW_REV_PCI -1
 
        void __iomem            *ioaddr;
        unsigned int             clk_div;
        int                      hw_rev;
+       int                      use_irq;
+       struct completion        irq_completion;
 };
 
 int pasemi_i2c_common_probe(struct pasemi_smbus *smbus);
+
+irqreturn_t pasemi_irq_handler(int irq, void *dev_id);
 
        struct pasemi_smbus *smbus;
        u32 frequency;
        int error;
+       int irq_num;
 
        data = devm_kzalloc(dev, sizeof(struct pasemi_platform_i2c_data),
                            GFP_KERNEL);
        if (error)
                goto out_clk_disable;
 
+       irq_num = platform_get_irq(pdev, 0);
+       error = devm_request_irq(smbus->dev, irq_num, pasemi_irq_handler, 0, "pasemi_apple_i2c", (void *)smbus);
+
+       if (!error)
+               smbus->use_irq = 1;
        platform_set_drvdata(pdev, data);
 
        return 0;