#define I2C_HEADER_CONTINUE_XFER               (1<<15)
 #define I2C_HEADER_MASTER_ADDR_SHIFT           12
 #define I2C_HEADER_SLAVE_ADDR_SHIFT            1
+
+#define I2C_CONFIG_LOAD                                0x08C
+#define I2C_MSTR_CONFIG_LOAD                   (1 << 0)
+#define I2C_SLV_CONFIG_LOAD                    (1 << 1)
+#define I2C_TIMEOUT_CONFIG_LOAD                        (1 << 2)
+
 /*
  * msg_end_type: The bus control which need to be send at end of transfer.
  * @MSG_END_STOP: Send stop pulse at end of transfer.
  * @has_single_clk_source: The i2c controller has single clock source. Tegra30
  *             and earlier Socs has two clock sources i.e. div-clk and
  *             fast-clk.
+ * @has_config_load_reg: Has the config load register to load the new
+ *             configuration.
  * @clk_divisor_hs_mode: Clock divisor in HS mode.
  * @clk_divisor_std_fast_mode: Clock divisor in standard/fast mode. It is
  *             applicable if there is no fast clock source i.e. single clock
        bool has_continue_xfer_support;
        bool has_per_pkt_xfer_complete_irq;
        bool has_single_clk_source;
+       bool has_config_load_reg;
        int clk_divisor_hs_mode;
        int clk_divisor_std_fast_mode;
 };
        u32 val;
        int err = 0;
        u32 clk_divisor;
+       unsigned long timeout = jiffies + HZ;
 
        err = tegra_i2c_clock_enable(i2c_dev);
        if (err < 0) {
        if (tegra_i2c_flush_fifos(i2c_dev))
                err = -ETIMEDOUT;
 
+       if (i2c_dev->hw->has_config_load_reg) {
+               i2c_writel(i2c_dev, I2C_MSTR_CONFIG_LOAD, I2C_CONFIG_LOAD);
+               while (i2c_readl(i2c_dev, I2C_CONFIG_LOAD) != 0) {
+                       if (time_after(jiffies, timeout)) {
+                               dev_warn(i2c_dev->dev,
+                                       "timeout waiting for config load\n");
+                               return -ETIMEDOUT;
+                       }
+                       msleep(1);
+               }
+       }
+
        tegra_i2c_clock_disable(i2c_dev);
 
        if (i2c_dev->irq_disabled) {
        .has_single_clk_source = false,
        .clk_divisor_hs_mode = 3,
        .clk_divisor_std_fast_mode = 0,
+       .has_config_load_reg = false,
 };
 
 static const struct tegra_i2c_hw_feature tegra30_i2c_hw = {
        .has_single_clk_source = false,
        .clk_divisor_hs_mode = 3,
        .clk_divisor_std_fast_mode = 0,
+       .has_config_load_reg = false,
 };
 
 static const struct tegra_i2c_hw_feature tegra114_i2c_hw = {
        .has_single_clk_source = true,
        .clk_divisor_hs_mode = 1,
        .clk_divisor_std_fast_mode = 0x19,
+       .has_config_load_reg = false,
+};
+
+static const struct tegra_i2c_hw_feature tegra124_i2c_hw = {
+       .has_continue_xfer_support = true,
+       .has_per_pkt_xfer_complete_irq = true,
+       .has_single_clk_source = true,
+       .clk_divisor_hs_mode = 1,
+       .clk_divisor_std_fast_mode = 0x19,
+       .has_config_load_reg = true,
 };
 
 /* Match table for of_platform binding */
 static const struct of_device_id tegra_i2c_of_match[] = {
+       { .compatible = "nvidia,tegra124-i2c", .data = &tegra124_i2c_hw, },
        { .compatible = "nvidia,tegra114-i2c", .data = &tegra114_i2c_hw, },
        { .compatible = "nvidia,tegra30-i2c", .data = &tegra30_i2c_hw, },
        { .compatible = "nvidia,tegra20-i2c", .data = &tegra20_i2c_hw, },