#define QUIRK_S3C2440          (1 << 0)
 #define QUIRK_HDMIPHY          (1 << 1)
 #define QUIRK_NO_GPIO          (1 << 2)
+#define QUIRK_POLL             (1 << 3)
 
 /* Max time to wait for bus to become idle after a xfer (in us) */
 #define S3C2410_IDLE_TIMEOUT   5000
 };
 MODULE_DEVICE_TABLE(platform, s3c24xx_driver_ids);
 
+static int i2c_s3c_irq_nextbyte(struct s3c24xx_i2c *i2c, unsigned long iicstat);
+
 #ifdef CONFIG_OF
 static const struct of_device_id s3c24xx_i2c_match[] = {
        { .compatible = "samsung,s3c2410-i2c", .data = (void *)0 },
          .data = (void *)(QUIRK_S3C2440 | QUIRK_HDMIPHY | QUIRK_NO_GPIO) },
        { .compatible = "samsung,exynos5440-i2c",
          .data = (void *)(QUIRK_S3C2440 | QUIRK_NO_GPIO) },
+       { .compatible = "samsung,exynos5-sata-phy-i2c",
+         .data = (void *)(QUIRK_S3C2440 | QUIRK_POLL | QUIRK_NO_GPIO) },
        {},
 };
 MODULE_DEVICE_TABLE(of, s3c24xx_i2c_match);
        if (ret)
                i2c->msg_idx = ret;
 
-       wake_up(&i2c->wait);
+       if (!(i2c->quirks & QUIRK_POLL))
+               wake_up(&i2c->wait);
 }
 
 static inline void s3c24xx_i2c_disable_ack(struct s3c24xx_i2c *i2c)
        writel(tmp | S3C2410_IICCON_IRQEN, i2c->regs + S3C2410_IICCON);
 }
 
+static bool is_ack(struct s3c24xx_i2c *i2c)
+{
+       int tries;
+
+       for (tries = 50; tries; --tries) {
+               if (readl(i2c->regs + S3C2410_IICCON)
+                       & S3C2410_IICCON_IRQPEND) {
+                       if (!(readl(i2c->regs + S3C2410_IICSTAT)
+                               & S3C2410_IICSTAT_LASTBIT))
+                               return true;
+               }
+               usleep_range(1000, 2000);
+       }
+       dev_err(i2c->dev, "ack was not recieved\n");
+       return false;
+}
 
 /* s3c24xx_i2c_message_start
  *
 
        stat |= S3C2410_IICSTAT_START;
        writel(stat, i2c->regs + S3C2410_IICSTAT);
+
+       if (i2c->quirks & QUIRK_POLL) {
+               while ((i2c->msg_num != 0) && is_ack(i2c)) {
+                       i2c_s3c_irq_nextbyte(i2c, stat);
+                       stat = readl(i2c->regs + S3C2410_IICSTAT);
+
+                       if (stat & S3C2410_IICSTAT_ARBITR)
+                               dev_err(i2c->dev, "deal with arbitration loss\n");
+               }
+       }
 }
 
 static inline void s3c24xx_i2c_stop(struct s3c24xx_i2c *i2c, int ret)
        s3c24xx_i2c_enable_irq(i2c);
        s3c24xx_i2c_message_start(i2c, msgs);
 
+       if (i2c->quirks & QUIRK_POLL) {
+               ret = i2c->msg_idx;
+
+               if (ret != num)
+                       dev_dbg(i2c->dev, "incomplete xfer (%d)\n", ret);
+
+               goto out;
+       }
+
        timeout = wait_event_timeout(i2c->wait, i2c->msg_num == 0, HZ * 5);
 
        ret = i2c->msg_idx;
        if (div1 == 512)
                iiccon |= S3C2410_IICCON_TXDIV_512;
 
+       if (i2c->quirks & QUIRK_POLL)
+               iiccon |= S3C2410_IICCON_SCALE(2);
+
        writel(iiccon, i2c->regs + S3C2410_IICCON);
 
        if (i2c->quirks & QUIRK_S3C2440) {
         * ensure no current IRQs pending
         */
 
-       i2c->irq = ret = platform_get_irq(pdev, 0);
-       if (ret <= 0) {
-               dev_err(&pdev->dev, "cannot find IRQ\n");
-               return ret;
-       }
+       if (!(i2c->quirks & QUIRK_POLL)) {
+               i2c->irq = ret = platform_get_irq(pdev, 0);
+               if (ret <= 0) {
+                       dev_err(&pdev->dev, "cannot find IRQ\n");
+                       return ret;
+               }
 
        ret = devm_request_irq(&pdev->dev, i2c->irq, s3c24xx_i2c_irq, 0,
-                              dev_name(&pdev->dev), i2c);
+                               dev_name(&pdev->dev), i2c);
 
-       if (ret != 0) {
-               dev_err(&pdev->dev, "cannot claim IRQ %d\n", i2c->irq);
-               return ret;
+               if (ret != 0) {
+                       dev_err(&pdev->dev, "cannot claim IRQ %d\n", i2c->irq);
+                       return ret;
+               }
        }
 
        ret = s3c24xx_i2c_register_cpufreq(i2c);