#define STM32F7_AUTOSUSPEND_DELAY              (HZ / 100)
 
+/**
+ * struct stm32f7_i2c_regs - i2c f7 registers backup
+ * @cr1: Control register 1
+ * @cr2: Control register 2
+ * @oar1: Own address 1 register
+ * @oar2: Own address 2 register
+ * @pecr: PEC register
+ * @tmgr: Timing register
+ */
+struct stm32f7_i2c_regs {
+       u32 cr1;
+       u32 cr2;
+       u32 oar1;
+       u32 oar2;
+       u32 pecr;
+       u32 tmgr;
+};
+
 /**
  * struct stm32f7_i2c_spec - private i2c specification timing
  * @rate: I2C bus speed (Hz)
  * @timing: I2C computed timings
  * @slave: list of slave devices registered on the I2C bus
  * @slave_running: slave device currently used
+ * @backup_regs: backup of i2c controller registers (for suspend/resume)
  * @slave_dir: transfer direction for the current slave device
  * @master_mode: boolean to know in which mode the I2C is running (master or
  * slave)
        struct stm32f7_i2c_timings timing;
        struct i2c_client *slave[STM32F7_I2C_MAX_SLAVE];
        struct i2c_client *slave_running;
+       struct stm32f7_i2c_regs backup_regs;
        u32 slave_dir;
        bool master_mode;
        struct stm32_i2c_dma *dma;
        return 0;
 }
 
-#ifdef CONFIG_PM
-static int stm32f7_i2c_runtime_suspend(struct device *dev)
+static int __maybe_unused stm32f7_i2c_runtime_suspend(struct device *dev)
 {
        struct stm32f7_i2c_dev *i2c_dev = dev_get_drvdata(dev);
 
        return 0;
 }
 
-static int stm32f7_i2c_runtime_resume(struct device *dev)
+static int __maybe_unused stm32f7_i2c_runtime_resume(struct device *dev)
 {
        struct stm32f7_i2c_dev *i2c_dev = dev_get_drvdata(dev);
        int ret;
 
        return 0;
 }
-#endif
+
+static int __maybe_unused
+stm32f7_i2c_regs_backup(struct stm32f7_i2c_dev *i2c_dev)
+{
+       int ret;
+       struct stm32f7_i2c_regs *backup_regs = &i2c_dev->backup_regs;
+
+       ret = pm_runtime_get_sync(i2c_dev->dev);
+       if (ret < 0)
+               return ret;
+
+       backup_regs->cr1 = readl_relaxed(i2c_dev->base + STM32F7_I2C_CR1);
+       backup_regs->cr2 = readl_relaxed(i2c_dev->base + STM32F7_I2C_CR2);
+       backup_regs->oar1 = readl_relaxed(i2c_dev->base + STM32F7_I2C_OAR1);
+       backup_regs->oar2 = readl_relaxed(i2c_dev->base + STM32F7_I2C_OAR2);
+       backup_regs->pecr = readl_relaxed(i2c_dev->base + STM32F7_I2C_PECR);
+       backup_regs->tmgr = readl_relaxed(i2c_dev->base + STM32F7_I2C_TIMINGR);
+
+       pm_runtime_put_sync(i2c_dev->dev);
+
+       return ret;
+}
+
+static int __maybe_unused
+stm32f7_i2c_regs_restore(struct stm32f7_i2c_dev *i2c_dev)
+{
+       u32 cr1;
+       int ret;
+       struct stm32f7_i2c_regs *backup_regs = &i2c_dev->backup_regs;
+
+       ret = pm_runtime_get_sync(i2c_dev->dev);
+       if (ret < 0)
+               return ret;
+
+       cr1 = readl_relaxed(i2c_dev->base + STM32F7_I2C_CR1);
+       if (cr1 & STM32F7_I2C_CR1_PE)
+               stm32f7_i2c_clr_bits(i2c_dev->base + STM32F7_I2C_CR1,
+                                    STM32F7_I2C_CR1_PE);
+
+       writel_relaxed(backup_regs->tmgr, i2c_dev->base + STM32F7_I2C_TIMINGR);
+       writel_relaxed(backup_regs->cr1 & ~STM32F7_I2C_CR1_PE,
+                      i2c_dev->base + STM32F7_I2C_CR1);
+       if (backup_regs->cr1 & STM32F7_I2C_CR1_PE)
+               stm32f7_i2c_set_bits(i2c_dev->base + STM32F7_I2C_CR1,
+                                    STM32F7_I2C_CR1_PE);
+       writel_relaxed(backup_regs->cr2, i2c_dev->base + STM32F7_I2C_CR2);
+       writel_relaxed(backup_regs->oar1, i2c_dev->base + STM32F7_I2C_OAR1);
+       writel_relaxed(backup_regs->oar2, i2c_dev->base + STM32F7_I2C_OAR2);
+       writel_relaxed(backup_regs->pecr, i2c_dev->base + STM32F7_I2C_PECR);
+
+       pm_runtime_put_sync(i2c_dev->dev);
+
+       return ret;
+}
+
+static int __maybe_unused stm32f7_i2c_suspend(struct device *dev)
+{
+       struct stm32f7_i2c_dev *i2c_dev = dev_get_drvdata(dev);
+       int ret;
+
+       i2c_mark_adapter_suspended(&i2c_dev->adap);
+       ret = stm32f7_i2c_regs_backup(i2c_dev);
+       if (ret < 0) {
+               i2c_mark_adapter_resumed(&i2c_dev->adap);
+               return ret;
+       }
+
+       pinctrl_pm_select_sleep_state(dev);
+       pm_runtime_force_suspend(dev);
+
+       return 0;
+}
+
+static int __maybe_unused stm32f7_i2c_resume(struct device *dev)
+{
+       struct stm32f7_i2c_dev *i2c_dev = dev_get_drvdata(dev);
+       int ret;
+
+       ret = pm_runtime_force_resume(dev);
+       if (ret < 0)
+               return ret;
+       pinctrl_pm_select_default_state(dev);
+
+       ret = stm32f7_i2c_regs_restore(i2c_dev);
+       if (ret < 0)
+               return ret;
+       i2c_mark_adapter_resumed(&i2c_dev->adap);
+
+       return 0;
+}
 
 static const struct dev_pm_ops stm32f7_i2c_pm_ops = {
        SET_RUNTIME_PM_OPS(stm32f7_i2c_runtime_suspend,
                           stm32f7_i2c_runtime_resume, NULL)
+       SET_SYSTEM_SLEEP_PM_OPS(stm32f7_i2c_suspend, stm32f7_i2c_resume)
 };
 
 static const struct of_device_id stm32f7_i2c_match[] = {