enable ? "en" : "dis");
 }
 
+static unsigned long i2c_dw_clk_rate(struct dw_i2c_dev *dev)
+{
+       /*
+        * Clock is not necessary if we got LCNT/HCNT values directly from
+        * the platform code.
+        */
+       if (WARN_ON_ONCE(!dev->get_clk_rate_khz))
+               return 0;
+       return dev->get_clk_rate_khz(dev);
+}
+
 /**
  * i2c_dw_init() - initialize the designware i2c master hardware
  * @dev: device private data
  */
 int i2c_dw_init(struct dw_i2c_dev *dev)
 {
-       u32 input_clock_khz;
        u32 hcnt, lcnt;
        u32 reg;
        u32 sda_falling_time, scl_falling_time;
                }
        }
 
-       input_clock_khz = dev->get_clk_rate_khz(dev);
-
        reg = dw_readl(dev, DW_IC_COMP_TYPE);
        if (reg == ___constant_swab32(DW_IC_COMP_TYPE_VALUE)) {
                /* Configure register endianess access */
                hcnt = dev->ss_hcnt;
                lcnt = dev->ss_lcnt;
        } else {
-               hcnt = i2c_dw_scl_hcnt(input_clock_khz,
+               hcnt = i2c_dw_scl_hcnt(i2c_dw_clk_rate(dev),
                                        4000,   /* tHD;STA = tHIGH = 4.0 us */
                                        sda_falling_time,
                                        0,      /* 0: DW default, 1: Ideal */
                                        0);     /* No offset */
-               lcnt = i2c_dw_scl_lcnt(input_clock_khz,
+               lcnt = i2c_dw_scl_lcnt(i2c_dw_clk_rate(dev),
                                        4700,   /* tLOW = 4.7 us */
                                        scl_falling_time,
                                        0);     /* No offset */
                hcnt = dev->fs_hcnt;
                lcnt = dev->fs_lcnt;
        } else {
-               hcnt = i2c_dw_scl_hcnt(input_clock_khz,
+               hcnt = i2c_dw_scl_hcnt(i2c_dw_clk_rate(dev),
                                        600,    /* tHD;STA = tHIGH = 0.6 us */
                                        sda_falling_time,
                                        0,      /* 0: DW default, 1: Ideal */
                                        0);     /* No offset */
-               lcnt = i2c_dw_scl_lcnt(input_clock_khz,
+               lcnt = i2c_dw_scl_lcnt(i2c_dw_clk_rate(dev),
                                        1300,   /* tLOW = 1.3 us */
                                        scl_falling_time,
                                        0);     /* No offset */
 
 }
 #endif
 
+static int i2c_dw_plat_prepare_clk(struct dw_i2c_dev *i_dev, bool prepare)
+{
+       if (IS_ERR(i_dev->clk))
+               return PTR_ERR(i_dev->clk);
+
+       if (prepare)
+               return clk_prepare_enable(i_dev->clk);
+
+       clk_disable_unprepare(i_dev->clk);
+       return 0;
+}
+
 static int dw_i2c_plat_probe(struct platform_device *pdev)
 {
        struct dw_i2c_dev *dev;
                        DW_IC_CON_RESTART_EN | DW_IC_CON_SPEED_FAST;
 
        dev->clk = devm_clk_get(&pdev->dev, NULL);
-       dev->get_clk_rate_khz = i2c_dw_get_clk_rate_khz;
-       if (IS_ERR(dev->clk))
-               return PTR_ERR(dev->clk);
-       clk_prepare_enable(dev->clk);
+       if (!i2c_dw_plat_prepare_clk(dev, true)) {
+               dev->get_clk_rate_khz = i2c_dw_get_clk_rate_khz;
 
-       if (!dev->sda_hold_time && ht) {
-               u32 ic_clk = dev->get_clk_rate_khz(dev);
-
-               dev->sda_hold_time = div_u64((u64)ic_clk * ht + 500000,
-                                            1000000);
+               if (!dev->sda_hold_time && ht)
+                       dev->sda_hold_time = div_u64(
+                               (u64)dev->get_clk_rate_khz(dev) * ht + 500000,
+                               1000000);
        }
 
        if (!dev->tx_fifo_depth) {
        struct dw_i2c_dev *i_dev = platform_get_drvdata(pdev);
 
        i2c_dw_disable(i_dev);
-       clk_disable_unprepare(i_dev->clk);
+       i2c_dw_plat_prepare_clk(i_dev, false);
 
        return 0;
 }
        struct platform_device *pdev = to_platform_device(dev);
        struct dw_i2c_dev *i_dev = platform_get_drvdata(pdev);
 
-       clk_prepare_enable(i_dev->clk);
+       i2c_dw_plat_prepare_clk(i_dev, true);
 
        if (!i_dev->pm_runtime_disabled)
                i2c_dw_init(i_dev);