// SPDX-License-Identifier: GPL-2.0
/*
 * Driver for STMicroelectronics STM32F7 I2C controller
 *
 * This I2C controller is described in the STM32F75xxx and STM32F74xxx Soc
 * reference manual.
 * Please see below a link to the documentation:
 * http://www.st.com/resource/en/reference_manual/dm00124865.pdf
 *
 * Copyright (C) M'boumba Cedric Madianga 2017
 * Copyright (C) STMicroelectronics 2017
 * Author: M'boumba Cedric Madianga <cedric.madianga@gmail.com>
 *
 * This driver is based on i2c-stm32f4.c
 *
 */
#include <linux/clk.h>
#include <linux/delay.h>
#include <linux/err.h>
#include <linux/i2c.h>
#include <linux/i2c-smbus.h>
#include <linux/interrupt.h>
#include <linux/io.h>
#include <linux/iopoll.h>
#include <linux/mfd/syscon.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_address.h>
#include <linux/of_platform.h>
#include <linux/platform_device.h>
#include <linux/pinctrl/consumer.h>
#include <linux/pm_runtime.h>
#include <linux/pm_wakeirq.h>
#include <linux/regmap.h>
#include <linux/reset.h>
#include <linux/slab.h>

#include "i2c-stm32.h"

/* STM32F7 I2C registers */
#define STM32F7_I2C_CR1				0x00
#define STM32F7_I2C_CR2				0x04
#define STM32F7_I2C_OAR1			0x08
#define STM32F7_I2C_OAR2			0x0C
#define STM32F7_I2C_PECR			0x20
#define STM32F7_I2C_TIMINGR			0x10
#define STM32F7_I2C_ISR				0x18
#define STM32F7_I2C_ICR				0x1C
#define STM32F7_I2C_RXDR			0x24
#define STM32F7_I2C_TXDR			0x28

/* STM32F7 I2C control 1 */
#define STM32_I2C_CR1_FMP			BIT(24)
#define STM32F7_I2C_CR1_PECEN			BIT(23)
#define STM32F7_I2C_CR1_ALERTEN			BIT(22)
#define STM32F7_I2C_CR1_SMBHEN			BIT(20)
#define STM32F7_I2C_CR1_WUPEN			BIT(18)
#define STM32F7_I2C_CR1_SBC			BIT(16)
#define STM32F7_I2C_CR1_RXDMAEN			BIT(15)
#define STM32F7_I2C_CR1_TXDMAEN			BIT(14)
#define STM32F7_I2C_CR1_ANFOFF			BIT(12)
#define STM32F7_I2C_CR1_DNF_MASK		GENMASK(11, 8)
#define STM32F7_I2C_CR1_DNF(n)			(((n) & 0xf) << 8)
#define STM32F7_I2C_CR1_ERRIE			BIT(7)
#define STM32F7_I2C_CR1_TCIE			BIT(6)
#define STM32F7_I2C_CR1_STOPIE			BIT(5)
#define STM32F7_I2C_CR1_NACKIE			BIT(4)
#define STM32F7_I2C_CR1_ADDRIE			BIT(3)
#define STM32F7_I2C_CR1_RXIE			BIT(2)
#define STM32F7_I2C_CR1_TXIE			BIT(1)
#define STM32F7_I2C_CR1_PE			BIT(0)
#define STM32F7_I2C_ALL_IRQ_MASK		(STM32F7_I2C_CR1_ERRIE \
						| STM32F7_I2C_CR1_TCIE \
						| STM32F7_I2C_CR1_STOPIE \
						| STM32F7_I2C_CR1_NACKIE \
						| STM32F7_I2C_CR1_RXIE \
						| STM32F7_I2C_CR1_TXIE)
#define STM32F7_I2C_XFER_IRQ_MASK		(STM32F7_I2C_CR1_TCIE \
						| STM32F7_I2C_CR1_STOPIE \
						| STM32F7_I2C_CR1_NACKIE \
						| STM32F7_I2C_CR1_RXIE \
						| STM32F7_I2C_CR1_TXIE)

/* STM32F7 I2C control 2 */
#define STM32F7_I2C_CR2_PECBYTE			BIT(26)
#define STM32F7_I2C_CR2_RELOAD			BIT(24)
#define STM32F7_I2C_CR2_NBYTES_MASK		GENMASK(23, 16)
#define STM32F7_I2C_CR2_NBYTES(n)		(((n) & 0xff) << 16)
#define STM32F7_I2C_CR2_NACK			BIT(15)
#define STM32F7_I2C_CR2_STOP			BIT(14)
#define STM32F7_I2C_CR2_START			BIT(13)
#define STM32F7_I2C_CR2_HEAD10R			BIT(12)
#define STM32F7_I2C_CR2_ADD10			BIT(11)
#define STM32F7_I2C_CR2_RD_WRN			BIT(10)
#define STM32F7_I2C_CR2_SADD10_MASK		GENMASK(9, 0)
#define STM32F7_I2C_CR2_SADD10(n)		(((n) & \
						STM32F7_I2C_CR2_SADD10_MASK))
#define STM32F7_I2C_CR2_SADD7_MASK		GENMASK(7, 1)
#define STM32F7_I2C_CR2_SADD7(n)		(((n) & 0x7f) << 1)

/* STM32F7 I2C Own Address 1 */
#define STM32F7_I2C_OAR1_OA1EN			BIT(15)
#define STM32F7_I2C_OAR1_OA1MODE		BIT(10)
#define STM32F7_I2C_OAR1_OA1_10_MASK		GENMASK(9, 0)
#define STM32F7_I2C_OAR1_OA1_10(n)		(((n) & \
						STM32F7_I2C_OAR1_OA1_10_MASK))
#define STM32F7_I2C_OAR1_OA1_7_MASK		GENMASK(7, 1)
#define STM32F7_I2C_OAR1_OA1_7(n)		(((n) & 0x7f) << 1)
#define STM32F7_I2C_OAR1_MASK			(STM32F7_I2C_OAR1_OA1_7_MASK \
						| STM32F7_I2C_OAR1_OA1_10_MASK \
						| STM32F7_I2C_OAR1_OA1EN \
						| STM32F7_I2C_OAR1_OA1MODE)

/* STM32F7 I2C Own Address 2 */
#define STM32F7_I2C_OAR2_OA2EN			BIT(15)
#define STM32F7_I2C_OAR2_OA2MSK_MASK		GENMASK(10, 8)
#define STM32F7_I2C_OAR2_OA2MSK(n)		(((n) & 0x7) << 8)
#define STM32F7_I2C_OAR2_OA2_7_MASK		GENMASK(7, 1)
#define STM32F7_I2C_OAR2_OA2_7(n)		(((n) & 0x7f) << 1)
#define STM32F7_I2C_OAR2_MASK			(STM32F7_I2C_OAR2_OA2MSK_MASK \
						| STM32F7_I2C_OAR2_OA2_7_MASK \
						| STM32F7_I2C_OAR2_OA2EN)

/* STM32F7 I2C Interrupt Status */
#define STM32F7_I2C_ISR_ADDCODE_MASK		GENMASK(23, 17)
#define STM32F7_I2C_ISR_ADDCODE_GET(n) \
				(((n) & STM32F7_I2C_ISR_ADDCODE_MASK) >> 17)
#define STM32F7_I2C_ISR_DIR			BIT(16)
#define STM32F7_I2C_ISR_BUSY			BIT(15)
#define STM32F7_I2C_ISR_ALERT			BIT(13)
#define STM32F7_I2C_ISR_PECERR			BIT(11)
#define STM32F7_I2C_ISR_ARLO			BIT(9)
#define STM32F7_I2C_ISR_BERR			BIT(8)
#define STM32F7_I2C_ISR_TCR			BIT(7)
#define STM32F7_I2C_ISR_TC			BIT(6)
#define STM32F7_I2C_ISR_STOPF			BIT(5)
#define STM32F7_I2C_ISR_NACKF			BIT(4)
#define STM32F7_I2C_ISR_ADDR			BIT(3)
#define STM32F7_I2C_ISR_RXNE			BIT(2)
#define STM32F7_I2C_ISR_TXIS			BIT(1)
#define STM32F7_I2C_ISR_TXE			BIT(0)

/* STM32F7 I2C Interrupt Clear */
#define STM32F7_I2C_ICR_ALERTCF			BIT(13)
#define STM32F7_I2C_ICR_PECCF			BIT(11)
#define STM32F7_I2C_ICR_ARLOCF			BIT(9)
#define STM32F7_I2C_ICR_BERRCF			BIT(8)
#define STM32F7_I2C_ICR_STOPCF			BIT(5)
#define STM32F7_I2C_ICR_NACKCF			BIT(4)
#define STM32F7_I2C_ICR_ADDRCF			BIT(3)

/* STM32F7 I2C Timing */
#define STM32F7_I2C_TIMINGR_PRESC(n)		(((n) & 0xf) << 28)
#define STM32F7_I2C_TIMINGR_SCLDEL(n)		(((n) & 0xf) << 20)
#define STM32F7_I2C_TIMINGR_SDADEL(n)		(((n) & 0xf) << 16)
#define STM32F7_I2C_TIMINGR_SCLH(n)		(((n) & 0xff) << 8)
#define STM32F7_I2C_TIMINGR_SCLL(n)		((n) & 0xff)

#define STM32F7_I2C_MAX_LEN			0xff
#define STM32F7_I2C_DMA_LEN_MIN			0x16
enum {
	STM32F7_SLAVE_HOSTNOTIFY,
	STM32F7_SLAVE_7_10_BITS_ADDR,
	STM32F7_SLAVE_7_BITS_ADDR,
	STM32F7_I2C_MAX_SLAVE
};

#define STM32F7_I2C_DNF_DEFAULT			0
#define STM32F7_I2C_DNF_MAX			15

#define STM32F7_I2C_ANALOG_FILTER_DELAY_MIN	50	/* ns */
#define STM32F7_I2C_ANALOG_FILTER_DELAY_MAX	260	/* ns */

#define STM32F7_I2C_RISE_TIME_DEFAULT		25	/* ns */
#define STM32F7_I2C_FALL_TIME_DEFAULT		10	/* ns */

#define STM32F7_PRESC_MAX			BIT(4)
#define STM32F7_SCLDEL_MAX			BIT(4)
#define STM32F7_SDADEL_MAX			BIT(4)
#define STM32F7_SCLH_MAX			BIT(8)
#define STM32F7_SCLL_MAX			BIT(8)

#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
 * @tmgr: Timing register
 */
struct stm32f7_i2c_regs {
	u32 cr1;
	u32 cr2;
	u32 oar1;
	u32 oar2;
	u32 tmgr;
};

/**
 * struct stm32f7_i2c_spec - private i2c specification timing
 * @rate: I2C bus speed (Hz)
 * @fall_max: Max fall time of both SDA and SCL signals (ns)
 * @rise_max: Max rise time of both SDA and SCL signals (ns)
 * @hddat_min: Min data hold time (ns)
 * @vddat_max: Max data valid time (ns)
 * @sudat_min: Min data setup time (ns)
 * @l_min: Min low period of the SCL clock (ns)
 * @h_min: Min high period of the SCL clock (ns)
 */
struct stm32f7_i2c_spec {
	u32 rate;
	u32 fall_max;
	u32 rise_max;
	u32 hddat_min;
	u32 vddat_max;
	u32 sudat_min;
	u32 l_min;
	u32 h_min;
};

/**
 * struct stm32f7_i2c_setup - private I2C timing setup parameters
 * @speed_freq: I2C speed frequency  (Hz)
 * @clock_src: I2C clock source frequency (Hz)
 * @rise_time: Rise time (ns)
 * @fall_time: Fall time (ns)
 * @fmp_clr_offset: Fast Mode Plus clear register offset from set register
 * @single_it_line: Only a single IT line is used for both events/errors
 * @fmp_cr1_bit: Fast Mode Plus control is done via a bit in CR1
 */
struct stm32f7_i2c_setup {
	u32 speed_freq;
	u32 clock_src;
	u32 rise_time;
	u32 fall_time;
	u32 fmp_clr_offset;
	bool single_it_line;
	bool fmp_cr1_bit;
};

/**
 * struct stm32f7_i2c_timings - private I2C output parameters
 * @node: List entry
 * @presc: Prescaler value
 * @scldel: Data setup time
 * @sdadel: Data hold time
 * @sclh: SCL high period (master mode)
 * @scll: SCL low period (master mode)
 */
struct stm32f7_i2c_timings {
	struct list_head node;
	u8 presc;
	u8 scldel;
	u8 sdadel;
	u8 sclh;
	u8 scll;
};

/**
 * struct stm32f7_i2c_msg - client specific data
 * @addr: 8-bit or 10-bit slave addr, including r/w bit
 * @count: number of bytes to be transferred
 * @buf: data buffer
 * @result: result of the transfer
 * @stop: last I2C msg to be sent, i.e. STOP to be generated
 * @smbus: boolean to know if the I2C IP is used in SMBus mode
 * @size: type of SMBus protocol
 * @read_write: direction of SMBus protocol
 * SMBus block read and SMBus block write - block read process call protocols
 * @smbus_buf: buffer to be used for SMBus protocol transfer. It will
 * contain a maximum of 32 bytes of data + byte command + byte count + PEC
 * This buffer has to be 32-bit aligned to be compliant with memory address
 * register in DMA mode.
 */
struct stm32f7_i2c_msg {
	u16 addr;
	u32 count;
	u8 *buf;
	int result;
	bool stop;
	bool smbus;
	int size;
	char read_write;
	u8 smbus_buf[I2C_SMBUS_BLOCK_MAX + 3] __aligned(4);
};

/**
 * struct stm32f7_i2c_alert - SMBus alert specific data
 * @setup: platform data for the smbus_alert i2c client
 * @ara: I2C slave device used to respond to the SMBus Alert with Alert
 * Response Address
 */
struct stm32f7_i2c_alert {
	struct i2c_smbus_alert_setup setup;
	struct i2c_client *ara;
};

/**
 * struct stm32f7_i2c_dev - private data of the controller
 * @adap: I2C adapter for this controller
 * @dev: device for this controller
 * @base: virtual memory area
 * @complete: completion of I2C message
 * @clk: hw i2c clock
 * @bus_rate: I2C clock frequency of the controller
 * @msg: Pointer to data to be written
 * @msg_num: number of I2C messages to be executed
 * @msg_id: message identifiant
 * @f7_msg: customized i2c msg for driver usage
 * @setup: I2C timing input setup
 * @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)
 * @dma: dma data
 * @use_dma: boolean to know if dma is used in the current transfer
 * @regmap: holds SYSCFG phandle for Fast Mode Plus bits
 * @fmp_sreg: register address for setting Fast Mode Plus bits
 * @fmp_creg: register address for clearing Fast Mode Plus bits
 * @fmp_mask: mask for Fast Mode Plus bits in set register
 * @wakeup_src: boolean to know if the device is a wakeup source
 * @smbus_mode: states that the controller is configured in SMBus mode
 * @host_notify_client: SMBus host-notify client
 * @analog_filter: boolean to indicate enabling of the analog filter
 * @dnf_dt: value of digital filter requested via dt
 * @dnf: value of digital filter to apply
 * @alert: SMBus alert specific data
 * @atomic: boolean indicating that current transfer is atomic
 */
struct stm32f7_i2c_dev {
	struct i2c_adapter adap;
	struct device *dev;
	void __iomem *base;
	struct completion complete;
	struct clk *clk;
	unsigned int bus_rate;
	struct i2c_msg *msg;
	unsigned int msg_num;
	unsigned int msg_id;
	struct stm32f7_i2c_msg f7_msg;
	struct stm32f7_i2c_setup setup;
	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;
	bool use_dma;
	struct regmap *regmap;
	u32 fmp_sreg;
	u32 fmp_creg;
	u32 fmp_mask;
	bool wakeup_src;
	bool smbus_mode;
	struct i2c_client *host_notify_client;
	bool analog_filter;
	u32 dnf_dt;
	u32 dnf;
	struct stm32f7_i2c_alert *alert;
	bool atomic;
};

/*
 * All these values are coming from I2C Specification, Version 6.0, 4th of
 * April 2014.
 *
 * Table10. Characteristics of the SDA and SCL bus lines for Standard, Fast,
 * and Fast-mode Plus I2C-bus devices
 */
static struct stm32f7_i2c_spec stm32f7_i2c_specs[] = {
	{
		.rate = I2C_MAX_STANDARD_MODE_FREQ,
		.fall_max = 300,
		.rise_max = 1000,
		.hddat_min = 0,
		.vddat_max = 3450,
		.sudat_min = 250,
		.l_min = 4700,
		.h_min = 4000,
	},
	{
		.rate = I2C_MAX_FAST_MODE_FREQ,
		.fall_max = 300,
		.rise_max = 300,
		.hddat_min = 0,
		.vddat_max = 900,
		.sudat_min = 100,
		.l_min = 1300,
		.h_min = 600,
	},
	{
		.rate = I2C_MAX_FAST_MODE_PLUS_FREQ,
		.fall_max = 100,
		.rise_max = 120,
		.hddat_min = 0,
		.vddat_max = 450,
		.sudat_min = 50,
		.l_min = 500,
		.h_min = 260,
	},
};

static const struct stm32f7_i2c_setup stm32f7_setup = {
	.rise_time = STM32F7_I2C_RISE_TIME_DEFAULT,
	.fall_time = STM32F7_I2C_FALL_TIME_DEFAULT,
};

static const struct stm32f7_i2c_setup stm32mp15_setup = {
	.rise_time = STM32F7_I2C_RISE_TIME_DEFAULT,
	.fall_time = STM32F7_I2C_FALL_TIME_DEFAULT,
	.fmp_clr_offset = 0x40,
};

static const struct stm32f7_i2c_setup stm32mp13_setup = {
	.rise_time = STM32F7_I2C_RISE_TIME_DEFAULT,
	.fall_time = STM32F7_I2C_FALL_TIME_DEFAULT,
	.fmp_clr_offset = 0x4,
};

static const struct stm32f7_i2c_setup stm32mp25_setup = {
	.rise_time = STM32F7_I2C_RISE_TIME_DEFAULT,
	.fall_time = STM32F7_I2C_FALL_TIME_DEFAULT,
	.single_it_line = true,
	.fmp_cr1_bit = true,
};

static inline void stm32f7_i2c_set_bits(void __iomem *reg, u32 mask)
{
	writel_relaxed(readl_relaxed(reg) | mask, reg);
}

static inline void stm32f7_i2c_clr_bits(void __iomem *reg, u32 mask)
{
	writel_relaxed(readl_relaxed(reg) & ~mask, reg);
}

static void stm32f7_i2c_disable_irq(struct stm32f7_i2c_dev *i2c_dev, u32 mask)
{
	stm32f7_i2c_clr_bits(i2c_dev->base + STM32F7_I2C_CR1, mask);
}

static struct stm32f7_i2c_spec *stm32f7_get_specs(u32 rate)
{
	int i;

	for (i = 0; i < ARRAY_SIZE(stm32f7_i2c_specs); i++)
		if (rate <= stm32f7_i2c_specs[i].rate)
			return &stm32f7_i2c_specs[i];

	return ERR_PTR(-EINVAL);
}

#define	RATE_MIN(rate)	((rate) * 8 / 10)
static int stm32f7_i2c_compute_timing(struct stm32f7_i2c_dev *i2c_dev,
				      struct stm32f7_i2c_setup *setup,
				      struct stm32f7_i2c_timings *output)
{
	struct stm32f7_i2c_spec *specs;
	u32 p_prev = STM32F7_PRESC_MAX;
	u32 i2cclk = DIV_ROUND_CLOSEST(NSEC_PER_SEC,
				       setup->clock_src);
	u32 i2cbus = DIV_ROUND_CLOSEST(NSEC_PER_SEC,
				       setup->speed_freq);
	u32 clk_error_prev = i2cbus;
	u32 tsync;
	u32 af_delay_min, af_delay_max;
	u32 dnf_delay;
	u32 clk_min, clk_max;
	int sdadel_min, sdadel_max;
	int scldel_min;
	struct stm32f7_i2c_timings *v, *_v, *s;
	struct list_head solutions;
	u16 p, l, a, h;
	int ret = 0;

	specs = stm32f7_get_specs(setup->speed_freq);
	if (specs == ERR_PTR(-EINVAL)) {
		dev_err(i2c_dev->dev, "speed out of bound {%d}\n",
			setup->speed_freq);
		return -EINVAL;
	}

	if ((setup->rise_time > specs->rise_max) ||
	    (setup->fall_time > specs->fall_max)) {
		dev_err(i2c_dev->dev,
			"timings out of bound Rise{%d>%d}/Fall{%d>%d}\n",
			setup->rise_time, specs->rise_max,
			setup->fall_time, specs->fall_max);
		return -EINVAL;
	}

	i2c_dev->dnf = DIV_ROUND_CLOSEST(i2c_dev->dnf_dt, i2cclk);
	if (i2c_dev->dnf > STM32F7_I2C_DNF_MAX) {
		dev_err(i2c_dev->dev,
			"DNF out of bound %d/%d\n",
			i2c_dev->dnf * i2cclk, STM32F7_I2C_DNF_MAX * i2cclk);
		return -EINVAL;
	}

	/*  Analog and Digital Filters */
	af_delay_min =
		(i2c_dev->analog_filter ?
		 STM32F7_I2C_ANALOG_FILTER_DELAY_MIN : 0);
	af_delay_max =
		(i2c_dev->analog_filter ?
		 STM32F7_I2C_ANALOG_FILTER_DELAY_MAX : 0);
	dnf_delay = i2c_dev->dnf * i2cclk;

	sdadel_min = specs->hddat_min + setup->fall_time -
		af_delay_min - (i2c_dev->dnf + 3) * i2cclk;

	sdadel_max = specs->vddat_max - setup->rise_time -
		af_delay_max - (i2c_dev->dnf + 4) * i2cclk;

	scldel_min = setup->rise_time + specs->sudat_min;

	if (sdadel_min < 0)
		sdadel_min = 0;
	if (sdadel_max < 0)
		sdadel_max = 0;

	dev_dbg(i2c_dev->dev, "SDADEL(min/max): %i/%i, SCLDEL(Min): %i\n",
		sdadel_min, sdadel_max, scldel_min);

	INIT_LIST_HEAD(&solutions);
	/* Compute possible values for PRESC, SCLDEL and SDADEL */
	for (p = 0; p < STM32F7_PRESC_MAX; p++) {
		for (l = 0; l < STM32F7_SCLDEL_MAX; l++) {
			u32 scldel = (l + 1) * (p + 1) * i2cclk;

			if (scldel < scldel_min)
				continue;

			for (a = 0; a < STM32F7_SDADEL_MAX; a++) {
				u32 sdadel = (a * (p + 1) + 1) * i2cclk;

				if (((sdadel >= sdadel_min) &&
				     (sdadel <= sdadel_max)) &&
				    (p != p_prev)) {
					v = kmalloc(sizeof(*v), GFP_KERNEL);
					if (!v) {
						ret = -ENOMEM;
						goto exit;
					}

					v->presc = p;
					v->scldel = l;
					v->sdadel = a;
					p_prev = p;

					list_add_tail(&v->node,
						      &solutions);
					break;
				}
			}

			if (p_prev == p)
				break;
		}
	}

	if (list_empty(&solutions)) {
		dev_err(i2c_dev->dev, "no Prescaler solution\n");
		ret = -EPERM;
		goto exit;
	}

	tsync = af_delay_min + dnf_delay + (2 * i2cclk);
	s = NULL;
	clk_max = NSEC_PER_SEC / RATE_MIN(setup->speed_freq);
	clk_min = NSEC_PER_SEC / setup->speed_freq;

	/*
	 * Among Prescaler possibilities discovered above figures out SCL Low
	 * and High Period. Provided:
	 * - SCL Low Period has to be higher than SCL Clock Low Period
	 *   defined by I2C Specification. I2C Clock has to be lower than
	 *   (SCL Low Period - Analog/Digital filters) / 4.
	 * - SCL High Period has to be lower than SCL Clock High Period
	 *   defined by I2C Specification
	 * - I2C Clock has to be lower than SCL High Period
	 */
	list_for_each_entry(v, &solutions, node) {
		u32 prescaler = (v->presc + 1) * i2cclk;

		for (l = 0; l < STM32F7_SCLL_MAX; l++) {
			u32 tscl_l = (l + 1) * prescaler + tsync;

			if ((tscl_l < specs->l_min) ||
			    (i2cclk >=
			     ((tscl_l - af_delay_min - dnf_delay) / 4))) {
				continue;
			}

			for (h = 0; h < STM32F7_SCLH_MAX; h++) {
				u32 tscl_h = (h + 1) * prescaler + tsync;
				u32 tscl = tscl_l + tscl_h +
					setup->rise_time + setup->fall_time;

				if ((tscl >= clk_min) && (tscl <= clk_max) &&
				    (tscl_h >= specs->h_min) &&
				    (i2cclk < tscl_h)) {
					int clk_error = tscl - i2cbus;

					if (clk_error < 0)
						clk_error = -clk_error;

					if (clk_error < clk_error_prev) {
						clk_error_prev = clk_error;
						v->scll = l;
						v->sclh = h;
						s = v;
					}
				}
			}
		}
	}

	if (!s) {
		dev_err(i2c_dev->dev, "no solution at all\n");
		ret = -EPERM;
		goto exit;
	}

	output->presc = s->presc;
	output->scldel = s->scldel;
	output->sdadel = s->sdadel;
	output->scll = s->scll;
	output->sclh = s->sclh;

	dev_dbg(i2c_dev->dev,
		"Presc: %i, scldel: %i, sdadel: %i, scll: %i, sclh: %i\n",
		output->presc,
		output->scldel, output->sdadel,
		output->scll, output->sclh);

exit:
	/* Release list and memory */
	list_for_each_entry_safe(v, _v, &solutions, node) {
		list_del(&v->node);
		kfree(v);
	}

	return ret;
}

static u32 stm32f7_get_lower_rate(u32 rate)
{
	int i = ARRAY_SIZE(stm32f7_i2c_specs);

	while (--i)
		if (stm32f7_i2c_specs[i].rate < rate)
			break;

	return stm32f7_i2c_specs[i].rate;
}

static int stm32f7_i2c_setup_timing(struct stm32f7_i2c_dev *i2c_dev,
				    struct stm32f7_i2c_setup *setup)
{
	struct i2c_timings timings, *t = &timings;
	int ret = 0;

	t->bus_freq_hz = I2C_MAX_STANDARD_MODE_FREQ;
	t->scl_rise_ns = i2c_dev->setup.rise_time;
	t->scl_fall_ns = i2c_dev->setup.fall_time;

	i2c_parse_fw_timings(i2c_dev->dev, t, false);

	if (t->bus_freq_hz > I2C_MAX_FAST_MODE_PLUS_FREQ) {
		dev_err(i2c_dev->dev, "Invalid bus speed (%i>%i)\n",
			t->bus_freq_hz, I2C_MAX_FAST_MODE_PLUS_FREQ);
		return -EINVAL;
	}

	setup->speed_freq = t->bus_freq_hz;
	i2c_dev->setup.rise_time = t->scl_rise_ns;
	i2c_dev->setup.fall_time = t->scl_fall_ns;
	i2c_dev->dnf_dt = t->digital_filter_width_ns;
	setup->clock_src = clk_get_rate(i2c_dev->clk);

	if (!setup->clock_src) {
		dev_err(i2c_dev->dev, "clock rate is 0\n");
		return -EINVAL;
	}

	if (!of_property_read_bool(i2c_dev->dev->of_node, "i2c-digital-filter"))
		i2c_dev->dnf_dt = STM32F7_I2C_DNF_DEFAULT;

	do {
		ret = stm32f7_i2c_compute_timing(i2c_dev, setup,
						 &i2c_dev->timing);
		if (ret) {
			dev_err(i2c_dev->dev,
				"failed to compute I2C timings.\n");
			if (setup->speed_freq <= I2C_MAX_STANDARD_MODE_FREQ)
				break;
			setup->speed_freq =
				stm32f7_get_lower_rate(setup->speed_freq);
			dev_warn(i2c_dev->dev,
				 "downgrade I2C Speed Freq to (%i)\n",
				 setup->speed_freq);
		}
	} while (ret);

	if (ret) {
		dev_err(i2c_dev->dev, "Impossible to compute I2C timings.\n");
		return ret;
	}

	i2c_dev->analog_filter = of_property_read_bool(i2c_dev->dev->of_node,
						       "i2c-analog-filter");

	dev_dbg(i2c_dev->dev, "I2C Speed(%i), Clk Source(%i)\n",
		setup->speed_freq, setup->clock_src);
	dev_dbg(i2c_dev->dev, "I2C Rise(%i) and Fall(%i) Time\n",
		setup->rise_time, setup->fall_time);
	dev_dbg(i2c_dev->dev, "I2C Analog Filter(%s), DNF(%i)\n",
		(i2c_dev->analog_filter ? "On" : "Off"), i2c_dev->dnf);

	i2c_dev->bus_rate = setup->speed_freq;

	return 0;
}

static void stm32f7_i2c_disable_dma_req(struct stm32f7_i2c_dev *i2c_dev)
{
	void __iomem *base = i2c_dev->base;
	u32 mask = STM32F7_I2C_CR1_RXDMAEN | STM32F7_I2C_CR1_TXDMAEN;

	stm32f7_i2c_clr_bits(base + STM32F7_I2C_CR1, mask);
}

static void stm32f7_i2c_dma_callback(void *arg)
{
	struct stm32f7_i2c_dev *i2c_dev = (struct stm32f7_i2c_dev *)arg;
	struct stm32_i2c_dma *dma = i2c_dev->dma;
	struct device *dev = dma->chan_using->device->dev;

	stm32f7_i2c_disable_dma_req(i2c_dev);
	dma_unmap_single(dev, dma->dma_buf, dma->dma_len, dma->dma_data_dir);
	complete(&dma->dma_complete);
}

static void stm32f7_i2c_hw_config(struct stm32f7_i2c_dev *i2c_dev)
{
	struct stm32f7_i2c_timings *t = &i2c_dev->timing;
	u32 timing = 0;

	/* Timing settings */
	timing |= STM32F7_I2C_TIMINGR_PRESC(t->presc);
	timing |= STM32F7_I2C_TIMINGR_SCLDEL(t->scldel);
	timing |= STM32F7_I2C_TIMINGR_SDADEL(t->sdadel);
	timing |= STM32F7_I2C_TIMINGR_SCLH(t->sclh);
	timing |= STM32F7_I2C_TIMINGR_SCLL(t->scll);
	writel_relaxed(timing, i2c_dev->base + STM32F7_I2C_TIMINGR);

	/* Configure the Analog Filter */
	if (i2c_dev->analog_filter)
		stm32f7_i2c_clr_bits(i2c_dev->base + STM32F7_I2C_CR1,
				     STM32F7_I2C_CR1_ANFOFF);
	else
		stm32f7_i2c_set_bits(i2c_dev->base + STM32F7_I2C_CR1,
				     STM32F7_I2C_CR1_ANFOFF);

	/* Program the Digital Filter */
	stm32f7_i2c_clr_bits(i2c_dev->base + STM32F7_I2C_CR1,
			     STM32F7_I2C_CR1_DNF_MASK);
	stm32f7_i2c_set_bits(i2c_dev->base + STM32F7_I2C_CR1,
			     STM32F7_I2C_CR1_DNF(i2c_dev->dnf));

	stm32f7_i2c_set_bits(i2c_dev->base + STM32F7_I2C_CR1,
			     STM32F7_I2C_CR1_PE);
}

static void stm32f7_i2c_write_tx_data(struct stm32f7_i2c_dev *i2c_dev)
{
	struct stm32f7_i2c_msg *f7_msg = &i2c_dev->f7_msg;
	void __iomem *base = i2c_dev->base;

	if (f7_msg->count) {
		writeb_relaxed(*f7_msg->buf++, base + STM32F7_I2C_TXDR);
		f7_msg->count--;
	}
}

static void stm32f7_i2c_read_rx_data(struct stm32f7_i2c_dev *i2c_dev)
{
	struct stm32f7_i2c_msg *f7_msg = &i2c_dev->f7_msg;
	void __iomem *base = i2c_dev->base;

	if (f7_msg->count) {
		*f7_msg->buf++ = readb_relaxed(base + STM32F7_I2C_RXDR);
		f7_msg->count--;
	} else {
		/* Flush RX buffer has no data is expected */
		readb_relaxed(base + STM32F7_I2C_RXDR);
	}
}

static void stm32f7_i2c_reload(struct stm32f7_i2c_dev *i2c_dev)
{
	struct stm32f7_i2c_msg *f7_msg = &i2c_dev->f7_msg;
	u32 cr2;

	if (i2c_dev->use_dma)
		f7_msg->count -= STM32F7_I2C_MAX_LEN;

	cr2 = readl_relaxed(i2c_dev->base + STM32F7_I2C_CR2);

	cr2 &= ~STM32F7_I2C_CR2_NBYTES_MASK;
	if (f7_msg->count > STM32F7_I2C_MAX_LEN) {
		cr2 |= STM32F7_I2C_CR2_NBYTES(STM32F7_I2C_MAX_LEN);
	} else {
		cr2 &= ~STM32F7_I2C_CR2_RELOAD;
		cr2 |= STM32F7_I2C_CR2_NBYTES(f7_msg->count);
	}

	writel_relaxed(cr2, i2c_dev->base + STM32F7_I2C_CR2);
}

static void stm32f7_i2c_smbus_reload(struct stm32f7_i2c_dev *i2c_dev)
{
	struct stm32f7_i2c_msg *f7_msg = &i2c_dev->f7_msg;
	u32 cr2;
	u8 *val;

	/*
	 * For I2C_SMBUS_BLOCK_DATA && I2C_SMBUS_BLOCK_PROC_CALL, the first
	 * data received inform us how many data will follow.
	 */
	stm32f7_i2c_read_rx_data(i2c_dev);

	/*
	 * Update NBYTES with the value read to continue the transfer
	 */
	val = f7_msg->buf - sizeof(u8);
	f7_msg->count = *val;
	cr2 = readl_relaxed(i2c_dev->base + STM32F7_I2C_CR2);
	cr2 &= ~(STM32F7_I2C_CR2_NBYTES_MASK | STM32F7_I2C_CR2_RELOAD);
	cr2 |= STM32F7_I2C_CR2_NBYTES(f7_msg->count);
	writel_relaxed(cr2, i2c_dev->base + STM32F7_I2C_CR2);
}

static void stm32f7_i2c_release_bus(struct i2c_adapter *i2c_adap)
{
	struct stm32f7_i2c_dev *i2c_dev = i2c_get_adapdata(i2c_adap);

	stm32f7_i2c_clr_bits(i2c_dev->base + STM32F7_I2C_CR1,
			     STM32F7_I2C_CR1_PE);

	stm32f7_i2c_hw_config(i2c_dev);
}

static int stm32f7_i2c_wait_free_bus(struct stm32f7_i2c_dev *i2c_dev)
{
	u32 status;
	int ret;

	ret = readl_relaxed_poll_timeout(i2c_dev->base + STM32F7_I2C_ISR,
					 status,
					 !(status & STM32F7_I2C_ISR_BUSY),
					 10, 1000);
	if (!ret)
		return 0;

	stm32f7_i2c_release_bus(&i2c_dev->adap);

	return -EBUSY;
}

static void stm32f7_i2c_xfer_msg(struct stm32f7_i2c_dev *i2c_dev,
				 struct i2c_msg *msg)
{
	struct stm32f7_i2c_msg *f7_msg = &i2c_dev->f7_msg;
	void __iomem *base = i2c_dev->base;
	u32 cr1, cr2;
	int ret;

	f7_msg->addr = msg->addr;
	f7_msg->buf = msg->buf;
	f7_msg->count = msg->len;
	f7_msg->result = 0;
	f7_msg->stop = (i2c_dev->msg_id >= i2c_dev->msg_num - 1);

	reinit_completion(&i2c_dev->complete);

	cr1 = readl_relaxed(base + STM32F7_I2C_CR1);
	cr2 = readl_relaxed(base + STM32F7_I2C_CR2);

	/* Set transfer direction */
	cr2 &= ~STM32F7_I2C_CR2_RD_WRN;
	if (msg->flags & I2C_M_RD)
		cr2 |= STM32F7_I2C_CR2_RD_WRN;

	/* Set slave address */
	cr2 &= ~(STM32F7_I2C_CR2_HEAD10R | STM32F7_I2C_CR2_ADD10);
	if (msg->flags & I2C_M_TEN) {
		cr2 &= ~STM32F7_I2C_CR2_SADD10_MASK;
		cr2 |= STM32F7_I2C_CR2_SADD10(f7_msg->addr);
		cr2 |= STM32F7_I2C_CR2_ADD10;
	} else {
		cr2 &= ~STM32F7_I2C_CR2_SADD7_MASK;
		cr2 |= STM32F7_I2C_CR2_SADD7(f7_msg->addr);
	}

	/* Set nb bytes to transfer and reload if needed */
	cr2 &= ~(STM32F7_I2C_CR2_NBYTES_MASK | STM32F7_I2C_CR2_RELOAD);
	if (f7_msg->count > STM32F7_I2C_MAX_LEN) {
		cr2 |= STM32F7_I2C_CR2_NBYTES(STM32F7_I2C_MAX_LEN);
		cr2 |= STM32F7_I2C_CR2_RELOAD;
	} else {
		cr2 |= STM32F7_I2C_CR2_NBYTES(f7_msg->count);
	}

	/* Enable NACK, STOP, error and transfer complete interrupts */
	cr1 |= STM32F7_I2C_CR1_ERRIE | STM32F7_I2C_CR1_TCIE |
		STM32F7_I2C_CR1_STOPIE | STM32F7_I2C_CR1_NACKIE;

	/* Clear DMA req and TX/RX interrupt */
	cr1 &= ~(STM32F7_I2C_CR1_RXIE | STM32F7_I2C_CR1_TXIE |
			STM32F7_I2C_CR1_RXDMAEN | STM32F7_I2C_CR1_TXDMAEN);

	/* Configure DMA or enable RX/TX interrupt */
	i2c_dev->use_dma = false;
	if (i2c_dev->dma && f7_msg->count >= STM32F7_I2C_DMA_LEN_MIN
	    && !i2c_dev->atomic) {
		ret = stm32_i2c_prep_dma_xfer(i2c_dev->dev, i2c_dev->dma,
					      msg->flags & I2C_M_RD,
					      f7_msg->count, f7_msg->buf,
					      stm32f7_i2c_dma_callback,
					      i2c_dev);
		if (!ret)
			i2c_dev->use_dma = true;
		else
			dev_warn(i2c_dev->dev, "can't use DMA\n");
	}

	if (!i2c_dev->use_dma) {
		if (msg->flags & I2C_M_RD)
			cr1 |= STM32F7_I2C_CR1_RXIE;
		else
			cr1 |= STM32F7_I2C_CR1_TXIE;
	} else {
		if (msg->flags & I2C_M_RD)
			cr1 |= STM32F7_I2C_CR1_RXDMAEN;
		else
			cr1 |= STM32F7_I2C_CR1_TXDMAEN;
	}

	if (i2c_dev->atomic)
		cr1 &= ~STM32F7_I2C_ALL_IRQ_MASK; /* Disable all interrupts */

	/* Configure Start/Repeated Start */
	cr2 |= STM32F7_I2C_CR2_START;

	i2c_dev->master_mode = true;

	/* Write configurations registers */
	writel_relaxed(cr1, base + STM32F7_I2C_CR1);
	writel_relaxed(cr2, base + STM32F7_I2C_CR2);
}

static int stm32f7_i2c_smbus_xfer_msg(struct stm32f7_i2c_dev *i2c_dev,
				      unsigned short flags, u8 command,
				      union i2c_smbus_data *data)
{
	struct stm32f7_i2c_msg *f7_msg = &i2c_dev->f7_msg;
	struct device *dev = i2c_dev->dev;
	void __iomem *base = i2c_dev->base;
	u32 cr1, cr2;
	int i, ret;

	f7_msg->result = 0;
	reinit_completion(&i2c_dev->complete);

	cr2 = readl_relaxed(base + STM32F7_I2C_CR2);
	cr1 = readl_relaxed(base + STM32F7_I2C_CR1);

	/* Set transfer direction */
	cr2 &= ~STM32F7_I2C_CR2_RD_WRN;
	if (f7_msg->read_write)
		cr2 |= STM32F7_I2C_CR2_RD_WRN;

	/* Set slave address */
	cr2 &= ~(STM32F7_I2C_CR2_ADD10 | STM32F7_I2C_CR2_SADD7_MASK);
	cr2 |= STM32F7_I2C_CR2_SADD7(f7_msg->addr);

	f7_msg->smbus_buf[0] = command;
	switch (f7_msg->size) {
	case I2C_SMBUS_QUICK:
		f7_msg->stop = true;
		f7_msg->count = 0;
		break;
	case I2C_SMBUS_BYTE:
		f7_msg->stop = true;
		f7_msg->count = 1;
		break;
	case I2C_SMBUS_BYTE_DATA:
		if (f7_msg->read_write) {
			f7_msg->stop = false;
			f7_msg->count = 1;
			cr2 &= ~STM32F7_I2C_CR2_RD_WRN;
		} else {
			f7_msg->stop = true;
			f7_msg->count = 2;
			f7_msg->smbus_buf[1] = data->byte;
		}
		break;
	case I2C_SMBUS_WORD_DATA:
		if (f7_msg->read_write) {
			f7_msg->stop = false;
			f7_msg->count = 1;
			cr2 &= ~STM32F7_I2C_CR2_RD_WRN;
		} else {
			f7_msg->stop = true;
			f7_msg->count = 3;
			f7_msg->smbus_buf[1] = data->word & 0xff;
			f7_msg->smbus_buf[2] = data->word >> 8;
		}
		break;
	case I2C_SMBUS_BLOCK_DATA:
		if (f7_msg->read_write) {
			f7_msg->stop = false;
			f7_msg->count = 1;
			cr2 &= ~STM32F7_I2C_CR2_RD_WRN;
		} else {
			f7_msg->stop = true;
			if (data->block[0] > I2C_SMBUS_BLOCK_MAX ||
			    !data->block[0]) {
				dev_err(dev, "Invalid block write size %d\n",
					data->block[0]);
				return -EINVAL;
			}
			f7_msg->count = data->block[0] + 2;
			for (i = 1; i < f7_msg->count; i++)
				f7_msg->smbus_buf[i] = data->block[i - 1];
		}
		break;
	case I2C_SMBUS_PROC_CALL:
		f7_msg->stop = false;
		f7_msg->count = 3;
		f7_msg->smbus_buf[1] = data->word & 0xff;
		f7_msg->smbus_buf[2] = data->word >> 8;
		cr2 &= ~STM32F7_I2C_CR2_RD_WRN;
		f7_msg->read_write = I2C_SMBUS_READ;
		break;
	case I2C_SMBUS_BLOCK_PROC_CALL:
		f7_msg->stop = false;
		if (data->block[0] > I2C_SMBUS_BLOCK_MAX - 1) {
			dev_err(dev, "Invalid block write size %d\n",
				data->block[0]);
			return -EINVAL;
		}
		f7_msg->count = data->block[0] + 2;
		for (i = 1; i < f7_msg->count; i++)
			f7_msg->smbus_buf[i] = data->block[i - 1];
		cr2 &= ~STM32F7_I2C_CR2_RD_WRN;
		f7_msg->read_write = I2C_SMBUS_READ;
		break;
	case I2C_SMBUS_I2C_BLOCK_DATA:
		/* Rely on emulated i2c transfer (through master_xfer) */
		return -EOPNOTSUPP;
	default:
		dev_err(dev, "Unsupported smbus protocol %d\n", f7_msg->size);
		return -EOPNOTSUPP;
	}

	f7_msg->buf = f7_msg->smbus_buf;

	/* Configure PEC */
	if ((flags & I2C_CLIENT_PEC) && f7_msg->size != I2C_SMBUS_QUICK) {
		cr1 |= STM32F7_I2C_CR1_PECEN;
		if (!f7_msg->read_write) {
			cr2 |= STM32F7_I2C_CR2_PECBYTE;
			f7_msg->count++;
		}
	} else {
		cr1 &= ~STM32F7_I2C_CR1_PECEN;
		cr2 &= ~STM32F7_I2C_CR2_PECBYTE;
	}

	/* Set number of bytes to be transferred */
	cr2 &= ~(STM32F7_I2C_CR2_NBYTES_MASK | STM32F7_I2C_CR2_RELOAD);
	cr2 |= STM32F7_I2C_CR2_NBYTES(f7_msg->count);

	/* Enable NACK, STOP, error and transfer complete interrupts */
	cr1 |= STM32F7_I2C_CR1_ERRIE | STM32F7_I2C_CR1_TCIE |
		STM32F7_I2C_CR1_STOPIE | STM32F7_I2C_CR1_NACKIE;

	/* Clear DMA req and TX/RX interrupt */
	cr1 &= ~(STM32F7_I2C_CR1_RXIE | STM32F7_I2C_CR1_TXIE |
			STM32F7_I2C_CR1_RXDMAEN | STM32F7_I2C_CR1_TXDMAEN);

	/* Configure DMA or enable RX/TX interrupt */
	i2c_dev->use_dma = false;
	if (i2c_dev->dma && f7_msg->count >= STM32F7_I2C_DMA_LEN_MIN) {
		ret = stm32_i2c_prep_dma_xfer(i2c_dev->dev, i2c_dev->dma,
					      cr2 & STM32F7_I2C_CR2_RD_WRN,
					      f7_msg->count, f7_msg->buf,
					      stm32f7_i2c_dma_callback,
					      i2c_dev);
		if (!ret)
			i2c_dev->use_dma = true;
		else
			dev_warn(i2c_dev->dev, "can't use DMA\n");
	}

	if (!i2c_dev->use_dma) {
		if (cr2 & STM32F7_I2C_CR2_RD_WRN)
			cr1 |= STM32F7_I2C_CR1_RXIE;
		else
			cr1 |= STM32F7_I2C_CR1_TXIE;
	} else {
		if (cr2 & STM32F7_I2C_CR2_RD_WRN)
			cr1 |= STM32F7_I2C_CR1_RXDMAEN;
		else
			cr1 |= STM32F7_I2C_CR1_TXDMAEN;
	}

	/* Set Start bit */
	cr2 |= STM32F7_I2C_CR2_START;

	i2c_dev->master_mode = true;

	/* Write configurations registers */
	writel_relaxed(cr1, base + STM32F7_I2C_CR1);
	writel_relaxed(cr2, base + STM32F7_I2C_CR2);

	return 0;
}

static void stm32f7_i2c_smbus_rep_start(struct stm32f7_i2c_dev *i2c_dev)
{
	struct stm32f7_i2c_msg *f7_msg = &i2c_dev->f7_msg;
	void __iomem *base = i2c_dev->base;
	u32 cr1, cr2;
	int ret;

	cr2 = readl_relaxed(base + STM32F7_I2C_CR2);
	cr1 = readl_relaxed(base + STM32F7_I2C_CR1);

	/* Set transfer direction */
	cr2 |= STM32F7_I2C_CR2_RD_WRN;

	switch (f7_msg->size) {
	case I2C_SMBUS_BYTE_DATA:
		f7_msg->count = 1;
		break;
	case I2C_SMBUS_WORD_DATA:
	case I2C_SMBUS_PROC_CALL:
		f7_msg->count = 2;
		break;
	case I2C_SMBUS_BLOCK_DATA:
	case I2C_SMBUS_BLOCK_PROC_CALL:
		f7_msg->count = 1;
		cr2 |= STM32F7_I2C_CR2_RELOAD;
		break;
	}

	f7_msg->buf = f7_msg->smbus_buf;
	f7_msg->stop = true;

	/* Add one byte for PEC if needed */
	if (cr1 & STM32F7_I2C_CR1_PECEN) {
		cr2 |= STM32F7_I2C_CR2_PECBYTE;
		f7_msg->count++;
	}

	/* Set number of bytes to be transferred */
	cr2 &= ~(STM32F7_I2C_CR2_NBYTES_MASK);
	cr2 |= STM32F7_I2C_CR2_NBYTES(f7_msg->count);

	/*
	 * Configure RX/TX interrupt:
	 */
	cr1 &= ~(STM32F7_I2C_CR1_RXIE | STM32F7_I2C_CR1_TXIE);
	cr1 |= STM32F7_I2C_CR1_RXIE;

	/*
	 * Configure DMA or enable RX/TX interrupt:
	 * For I2C_SMBUS_BLOCK_DATA and I2C_SMBUS_BLOCK_PROC_CALL we don't use
	 * dma as we don't know in advance how many data will be received
	 */
	cr1 &= ~(STM32F7_I2C_CR1_RXIE | STM32F7_I2C_CR1_TXIE |
		 STM32F7_I2C_CR1_RXDMAEN | STM32F7_I2C_CR1_TXDMAEN);

	i2c_dev->use_dma = false;
	if (i2c_dev->dma && f7_msg->count >= STM32F7_I2C_DMA_LEN_MIN &&
	    f7_msg->size != I2C_SMBUS_BLOCK_DATA &&
	    f7_msg->size != I2C_SMBUS_BLOCK_PROC_CALL) {
		ret = stm32_i2c_prep_dma_xfer(i2c_dev->dev, i2c_dev->dma,
					      cr2 & STM32F7_I2C_CR2_RD_WRN,
					      f7_msg->count, f7_msg->buf,
					      stm32f7_i2c_dma_callback,
					      i2c_dev);

		if (!ret)
			i2c_dev->use_dma = true;
		else
			dev_warn(i2c_dev->dev, "can't use DMA\n");
	}

	if (!i2c_dev->use_dma)
		cr1 |= STM32F7_I2C_CR1_RXIE;
	else
		cr1 |= STM32F7_I2C_CR1_RXDMAEN;

	/* Configure Repeated Start */
	cr2 |= STM32F7_I2C_CR2_START;

	/* Write configurations registers */
	writel_relaxed(cr1, base + STM32F7_I2C_CR1);
	writel_relaxed(cr2, base + STM32F7_I2C_CR2);
}

static int stm32f7_i2c_smbus_check_pec(struct stm32f7_i2c_dev *i2c_dev)
{
	struct stm32f7_i2c_msg *f7_msg = &i2c_dev->f7_msg;
	u8 count, internal_pec, received_pec;

	internal_pec = readl_relaxed(i2c_dev->base + STM32F7_I2C_PECR);

	switch (f7_msg->size) {
	case I2C_SMBUS_BYTE:
	case I2C_SMBUS_BYTE_DATA:
		received_pec = f7_msg->smbus_buf[1];
		break;
	case I2C_SMBUS_WORD_DATA:
	case I2C_SMBUS_PROC_CALL:
		received_pec = f7_msg->smbus_buf[2];
		break;
	case I2C_SMBUS_BLOCK_DATA:
	case I2C_SMBUS_BLOCK_PROC_CALL:
		count = f7_msg->smbus_buf[0];
		received_pec = f7_msg->smbus_buf[count];
		break;
	default:
		dev_err(i2c_dev->dev, "Unsupported smbus protocol for PEC\n");
		return -EINVAL;
	}

	if (internal_pec != received_pec) {
		dev_err(i2c_dev->dev, "Bad PEC 0x%02x vs. 0x%02x\n",
			internal_pec, received_pec);
		return -EBADMSG;
	}

	return 0;
}

static bool stm32f7_i2c_is_addr_match(struct i2c_client *slave, u32 addcode)
{
	u32 addr;

	if (!slave)
		return false;

	if (slave->flags & I2C_CLIENT_TEN) {
		/*
		 * For 10-bit addr, addcode = 11110XY with
		 * X = Bit 9 of slave address
		 * Y = Bit 8 of slave address
		 */
		addr = slave->addr >> 8;
		addr |= 0x78;
		if (addr == addcode)
			return true;
	} else {
		addr = slave->addr & 0x7f;
		if (addr == addcode)
			return true;
	}

	return false;
}

static void stm32f7_i2c_slave_start(struct stm32f7_i2c_dev *i2c_dev)
{
	struct i2c_client *slave = i2c_dev->slave_running;
	void __iomem *base = i2c_dev->base;
	u32 mask;
	u8 value = 0;

	if (i2c_dev->slave_dir) {
		/* Notify i2c slave that new read transfer is starting */
		i2c_slave_event(slave, I2C_SLAVE_READ_REQUESTED, &value);

		/*
		 * Disable slave TX config in case of I2C combined message
		 * (I2C Write followed by I2C Read)
		 */
		mask = STM32F7_I2C_CR2_RELOAD;
		stm32f7_i2c_clr_bits(base + STM32F7_I2C_CR2, mask);
		mask = STM32F7_I2C_CR1_SBC | STM32F7_I2C_CR1_RXIE |
		       STM32F7_I2C_CR1_TCIE;
		stm32f7_i2c_clr_bits(base + STM32F7_I2C_CR1, mask);

		/* Enable TX empty, STOP, NACK interrupts */
		mask =  STM32F7_I2C_CR1_STOPIE | STM32F7_I2C_CR1_NACKIE |
			STM32F7_I2C_CR1_TXIE;
		stm32f7_i2c_set_bits(base + STM32F7_I2C_CR1, mask);

		/* Write 1st data byte */
		writel_relaxed(value, base + STM32F7_I2C_TXDR);
	} else {
		/* Notify i2c slave that new write transfer is starting */
		i2c_slave_event(slave, I2C_SLAVE_WRITE_REQUESTED, &value);

		/* Set reload mode to be able to ACK/NACK each received byte */
		mask = STM32F7_I2C_CR2_RELOAD;
		stm32f7_i2c_set_bits(base + STM32F7_I2C_CR2, mask);

		/*
		 * Set STOP, NACK, RX empty and transfer complete interrupts.*
		 * Set Slave Byte Control to be able to ACK/NACK each data
		 * byte received
		 */
		mask =  STM32F7_I2C_CR1_STOPIE | STM32F7_I2C_CR1_NACKIE |
			STM32F7_I2C_CR1_SBC | STM32F7_I2C_CR1_RXIE |
			STM32F7_I2C_CR1_TCIE;
		stm32f7_i2c_set_bits(base + STM32F7_I2C_CR1, mask);
	}
}

static void stm32f7_i2c_slave_addr(struct stm32f7_i2c_dev *i2c_dev)
{
	void __iomem *base = i2c_dev->base;
	u32 isr, addcode, dir, mask;
	int i;

	isr = readl_relaxed(i2c_dev->base + STM32F7_I2C_ISR);
	addcode = STM32F7_I2C_ISR_ADDCODE_GET(isr);
	dir = isr & STM32F7_I2C_ISR_DIR;

	for (i = 0; i < STM32F7_I2C_MAX_SLAVE; i++) {
		if (stm32f7_i2c_is_addr_match(i2c_dev->slave[i], addcode)) {
			i2c_dev->slave_running = i2c_dev->slave[i];
			i2c_dev->slave_dir = dir;

			/* Start I2C slave processing */
			stm32f7_i2c_slave_start(i2c_dev);

			/* Clear ADDR flag */
			mask = STM32F7_I2C_ICR_ADDRCF;
			writel_relaxed(mask, base + STM32F7_I2C_ICR);
			break;
		}
	}
}

static int stm32f7_i2c_get_slave_id(struct stm32f7_i2c_dev *i2c_dev,
				    struct i2c_client *slave, int *id)
{
	int i;

	for (i = 0; i < STM32F7_I2C_MAX_SLAVE; i++) {
		if (i2c_dev->slave[i] == slave) {
			*id = i;
			return 0;
		}
	}

	dev_err(i2c_dev->dev, "Slave 0x%x not registered\n", slave->addr);

	return -ENODEV;
}

static int stm32f7_i2c_get_free_slave_id(struct stm32f7_i2c_dev *i2c_dev,
					 struct i2c_client *slave, int *id)
{
	struct device *dev = i2c_dev->dev;
	int i;

	/*
	 * slave[STM32F7_SLAVE_HOSTNOTIFY] support only SMBus Host address (0x8)
	 * slave[STM32F7_SLAVE_7_10_BITS_ADDR] supports 7-bit and 10-bit slave address
	 * slave[STM32F7_SLAVE_7_BITS_ADDR] supports 7-bit slave address only
	 */
	if (i2c_dev->smbus_mode && (slave->addr == 0x08)) {
		if (i2c_dev->slave[STM32F7_SLAVE_HOSTNOTIFY])
			goto fail;
		*id = STM32F7_SLAVE_HOSTNOTIFY;
		return 0;
	}

	for (i = STM32F7_I2C_MAX_SLAVE - 1; i > STM32F7_SLAVE_HOSTNOTIFY; i--) {
		if ((i == STM32F7_SLAVE_7_BITS_ADDR) &&
		    (slave->flags & I2C_CLIENT_TEN))
			continue;
		if (!i2c_dev->slave[i]) {
			*id = i;
			return 0;
		}
	}

fail:
	dev_err(dev, "Slave 0x%x could not be registered\n", slave->addr);

	return -EINVAL;
}

static bool stm32f7_i2c_is_slave_registered(struct stm32f7_i2c_dev *i2c_dev)
{
	int i;

	for (i = 0; i < STM32F7_I2C_MAX_SLAVE; i++) {
		if (i2c_dev->slave[i])
			return true;
	}

	return false;
}

static bool stm32f7_i2c_is_slave_busy(struct stm32f7_i2c_dev *i2c_dev)
{
	int i, busy;

	busy = 0;
	for (i = 0; i < STM32F7_I2C_MAX_SLAVE; i++) {
		if (i2c_dev->slave[i])
			busy++;
	}

	return i == busy;
}

static irqreturn_t stm32f7_i2c_slave_isr_event(struct stm32f7_i2c_dev *i2c_dev, u32 status)
{
	void __iomem *base = i2c_dev->base;
	u32 cr2, mask;
	u8 val;
	int ret;

	/* Slave transmitter mode */
	if (status & STM32F7_I2C_ISR_TXIS) {
		i2c_slave_event(i2c_dev->slave_running,
				I2C_SLAVE_READ_PROCESSED,
				&val);

		/* Write data byte */
		writel_relaxed(val, base + STM32F7_I2C_TXDR);
	}

	/* Transfer Complete Reload for Slave receiver mode */
	if (status & STM32F7_I2C_ISR_TCR || status & STM32F7_I2C_ISR_RXNE) {
		/*
		 * Read data byte then set NBYTES to receive next byte or NACK
		 * the current received byte
		 */
		val = readb_relaxed(i2c_dev->base + STM32F7_I2C_RXDR);
		ret = i2c_slave_event(i2c_dev->slave_running,
				      I2C_SLAVE_WRITE_RECEIVED,
				      &val);
		if (!ret) {
			cr2 = readl_relaxed(i2c_dev->base + STM32F7_I2C_CR2);
			cr2 |= STM32F7_I2C_CR2_NBYTES(1);
			writel_relaxed(cr2, i2c_dev->base + STM32F7_I2C_CR2);
		} else {
			mask = STM32F7_I2C_CR2_NACK;
			stm32f7_i2c_set_bits(base + STM32F7_I2C_CR2, mask);
		}
	}

	/* NACK received */
	if (status & STM32F7_I2C_ISR_NACKF) {
		dev_dbg(i2c_dev->dev, "<%s>: Receive NACK\n", __func__);
		writel_relaxed(STM32F7_I2C_ICR_NACKCF, base + STM32F7_I2C_ICR);
	}

	/* STOP received */
	if (status & STM32F7_I2C_ISR_STOPF) {
		/* Disable interrupts */
		stm32f7_i2c_disable_irq(i2c_dev, STM32F7_I2C_XFER_IRQ_MASK);

		if (i2c_dev->slave_dir) {
			/*
			 * Flush TX buffer in order to not used the byte in
			 * TXDR for the next transfer
			 */
			mask = STM32F7_I2C_ISR_TXE;
			stm32f7_i2c_set_bits(base + STM32F7_I2C_ISR, mask);
		}

		/* Clear STOP flag */
		writel_relaxed(STM32F7_I2C_ICR_STOPCF, base + STM32F7_I2C_ICR);

		/* Notify i2c slave that a STOP flag has been detected */
		i2c_slave_event(i2c_dev->slave_running, I2C_SLAVE_STOP, &val);

		i2c_dev->slave_running = NULL;
	}

	/* Address match received */
	if (status & STM32F7_I2C_ISR_ADDR)
		stm32f7_i2c_slave_addr(i2c_dev);

	return IRQ_HANDLED;
}

static irqreturn_t stm32f7_i2c_handle_isr_errs(struct stm32f7_i2c_dev *i2c_dev, u32 status)
{
	struct stm32f7_i2c_msg *f7_msg = &i2c_dev->f7_msg;
	u16 addr = f7_msg->addr;
	void __iomem *base = i2c_dev->base;
	struct device *dev = i2c_dev->dev;
	struct stm32_i2c_dma *dma = i2c_dev->dma;

	/* Bus error */
	if (status & STM32F7_I2C_ISR_BERR) {
		dev_err(dev, "Bus error accessing addr 0x%x\n", addr);
		writel_relaxed(STM32F7_I2C_ICR_BERRCF, base + STM32F7_I2C_ICR);
		stm32f7_i2c_release_bus(&i2c_dev->adap);
		f7_msg->result = -EIO;
	}

	/* Arbitration loss */
	if (status & STM32F7_I2C_ISR_ARLO) {
		dev_dbg(dev, "Arbitration loss accessing addr 0x%x\n", addr);
		writel_relaxed(STM32F7_I2C_ICR_ARLOCF, base + STM32F7_I2C_ICR);
		f7_msg->result = -EAGAIN;
	}

	if (status & STM32F7_I2C_ISR_PECERR) {
		dev_err(dev, "PEC error in reception accessing addr 0x%x\n", addr);
		writel_relaxed(STM32F7_I2C_ICR_PECCF, base + STM32F7_I2C_ICR);
		f7_msg->result = -EINVAL;
	}

	if (status & STM32F7_I2C_ISR_ALERT) {
		dev_dbg(dev, "SMBus alert received\n");
		writel_relaxed(STM32F7_I2C_ICR_ALERTCF, base + STM32F7_I2C_ICR);
		i2c_handle_smbus_alert(i2c_dev->alert->ara);
		return IRQ_HANDLED;
	}

	if (!i2c_dev->slave_running) {
		u32 mask;
		/* Disable interrupts */
		if (stm32f7_i2c_is_slave_registered(i2c_dev))
			mask = STM32F7_I2C_XFER_IRQ_MASK;
		else
			mask = STM32F7_I2C_ALL_IRQ_MASK;
		stm32f7_i2c_disable_irq(i2c_dev, mask);
	}

	/* Disable dma */
	if (i2c_dev->use_dma) {
		stm32f7_i2c_disable_dma_req(i2c_dev);
		dmaengine_terminate_async(dma->chan_using);
	}

	i2c_dev->master_mode = false;
	complete(&i2c_dev->complete);

	return IRQ_HANDLED;
}

#define STM32F7_ERR_EVENTS (STM32F7_I2C_ISR_BERR | STM32F7_I2C_ISR_ARLO |\
			    STM32F7_I2C_ISR_PECERR | STM32F7_I2C_ISR_ALERT)
static irqreturn_t stm32f7_i2c_isr_event(int irq, void *data)
{
	struct stm32f7_i2c_dev *i2c_dev = data;
	u32 status;

	status = readl_relaxed(i2c_dev->base + STM32F7_I2C_ISR);

	/*
	 * Check if the interrupt is for a slave device or related
	 * to errors flags (in case of single it line mode)
	 */
	if (!i2c_dev->master_mode ||
	    (i2c_dev->setup.single_it_line && (status & STM32F7_ERR_EVENTS)))
		return IRQ_WAKE_THREAD;

	/* Tx empty */
	if (status & STM32F7_I2C_ISR_TXIS)
		stm32f7_i2c_write_tx_data(i2c_dev);

	/* RX not empty */
	if (status & STM32F7_I2C_ISR_RXNE)
		stm32f7_i2c_read_rx_data(i2c_dev);

	/* Wake up the thread if other flags are raised */
	if (status &
	    (STM32F7_I2C_ISR_NACKF | STM32F7_I2C_ISR_STOPF |
	     STM32F7_I2C_ISR_TC | STM32F7_I2C_ISR_TCR))
		return IRQ_WAKE_THREAD;

	return IRQ_HANDLED;
}

static irqreturn_t stm32f7_i2c_isr_event_thread(int irq, void *data)
{
	struct stm32f7_i2c_dev *i2c_dev = data;
	struct stm32f7_i2c_msg *f7_msg = &i2c_dev->f7_msg;
	struct stm32_i2c_dma *dma = i2c_dev->dma;
	void __iomem *base = i2c_dev->base;
	u32 status, mask;
	int ret;

	status = readl_relaxed(i2c_dev->base + STM32F7_I2C_ISR);

	if (!i2c_dev->master_mode)
		return stm32f7_i2c_slave_isr_event(i2c_dev, status);

	/* Handle errors in case of this handler is used for events/errors */
	if (i2c_dev->setup.single_it_line && (status & STM32F7_ERR_EVENTS))
		return stm32f7_i2c_handle_isr_errs(i2c_dev, status);

	/* NACK received */
	if (status & STM32F7_I2C_ISR_NACKF) {
		dev_dbg(i2c_dev->dev, "<%s>: Receive NACK (addr %x)\n",
			__func__, f7_msg->addr);
		writel_relaxed(STM32F7_I2C_ICR_NACKCF, base + STM32F7_I2C_ICR);
		if (i2c_dev->use_dma) {
			stm32f7_i2c_disable_dma_req(i2c_dev);
			dmaengine_terminate_async(dma->chan_using);
		}
		f7_msg->result = -ENXIO;
	}

	if (status & STM32F7_I2C_ISR_TCR) {
		if (f7_msg->smbus)
			stm32f7_i2c_smbus_reload(i2c_dev);
		else
			stm32f7_i2c_reload(i2c_dev);
	}

	/* Transfer complete */
	if (status & STM32F7_I2C_ISR_TC) {
		/* Wait for dma transfer completion before sending next message */
		if (i2c_dev->use_dma && !f7_msg->result) {
			ret = wait_for_completion_timeout(&i2c_dev->dma->dma_complete, HZ);
			if (!ret) {
				dev_dbg(i2c_dev->dev, "<%s>: Timed out\n", __func__);
				stm32f7_i2c_disable_dma_req(i2c_dev);
				dmaengine_terminate_async(dma->chan_using);
				f7_msg->result = -ETIMEDOUT;
			}
		}
		if (f7_msg->stop) {
			mask = STM32F7_I2C_CR2_STOP;
			stm32f7_i2c_set_bits(base + STM32F7_I2C_CR2, mask);
		} else if (f7_msg->smbus) {
			stm32f7_i2c_smbus_rep_start(i2c_dev);
		} else {
			i2c_dev->msg_id++;
			i2c_dev->msg++;
			stm32f7_i2c_xfer_msg(i2c_dev, i2c_dev->msg);
		}
	}

	/* STOP detection flag */
	if (status & STM32F7_I2C_ISR_STOPF) {
		/* Disable interrupts */
		if (stm32f7_i2c_is_slave_registered(i2c_dev))
			mask = STM32F7_I2C_XFER_IRQ_MASK;
		else
			mask = STM32F7_I2C_ALL_IRQ_MASK;
		stm32f7_i2c_disable_irq(i2c_dev, mask);

		/* Clear STOP flag */
		writel_relaxed(STM32F7_I2C_ICR_STOPCF, base + STM32F7_I2C_ICR);

		i2c_dev->master_mode = false;
		complete(&i2c_dev->complete);
	}

	return IRQ_HANDLED;
}

static irqreturn_t stm32f7_i2c_isr_error_thread(int irq, void *data)
{
	struct stm32f7_i2c_dev *i2c_dev = data;
	u32 status;

	status = readl_relaxed(i2c_dev->base + STM32F7_I2C_ISR);

	return stm32f7_i2c_handle_isr_errs(i2c_dev, status);
}

static int stm32f7_i2c_wait_polling(struct stm32f7_i2c_dev *i2c_dev)
{
	ktime_t timeout = ktime_add_ms(ktime_get(), i2c_dev->adap.timeout);

	while (ktime_compare(ktime_get(), timeout) < 0) {
		udelay(5);
		stm32f7_i2c_isr_event(0, i2c_dev);

		if (completion_done(&i2c_dev->complete))
			return 1;
	}

	return 0;
}

static int stm32f7_i2c_xfer_core(struct i2c_adapter *i2c_adap,
			    struct i2c_msg msgs[], int num)
{
	struct stm32f7_i2c_dev *i2c_dev = i2c_get_adapdata(i2c_adap);
	struct stm32f7_i2c_msg *f7_msg = &i2c_dev->f7_msg;
	struct stm32_i2c_dma *dma = i2c_dev->dma;
	unsigned long time_left;
	int ret;

	i2c_dev->msg = msgs;
	i2c_dev->msg_num = num;
	i2c_dev->msg_id = 0;
	f7_msg->smbus = false;

	ret = pm_runtime_resume_and_get(i2c_dev->dev);
	if (ret < 0)
		return ret;

	ret = stm32f7_i2c_wait_free_bus(i2c_dev);
	if (ret)
		goto pm_free;

	stm32f7_i2c_xfer_msg(i2c_dev, msgs);

	if (!i2c_dev->atomic)
		time_left = wait_for_completion_timeout(&i2c_dev->complete,
							i2c_dev->adap.timeout);
	else
		time_left = stm32f7_i2c_wait_polling(i2c_dev);

	ret = f7_msg->result;
	if (ret) {
		if (i2c_dev->use_dma)
			dmaengine_synchronize(dma->chan_using);

		/*
		 * It is possible that some unsent data have already been
		 * written into TXDR. To avoid sending old data in a
		 * further transfer, flush TXDR in case of any error
		 */
		writel_relaxed(STM32F7_I2C_ISR_TXE,
			       i2c_dev->base + STM32F7_I2C_ISR);
		goto pm_free;
	}

	if (!time_left) {
		dev_dbg(i2c_dev->dev, "Access to slave 0x%x timed out\n",
			i2c_dev->msg->addr);
		if (i2c_dev->use_dma)
			dmaengine_terminate_sync(dma->chan_using);
		stm32f7_i2c_wait_free_bus(i2c_dev);
		ret = -ETIMEDOUT;
	}

pm_free:
	pm_runtime_mark_last_busy(i2c_dev->dev);
	pm_runtime_put_autosuspend(i2c_dev->dev);

	return (ret < 0) ? ret : num;
}

static int stm32f7_i2c_xfer(struct i2c_adapter *i2c_adap,
			    struct i2c_msg msgs[], int num)
{
	struct stm32f7_i2c_dev *i2c_dev = i2c_get_adapdata(i2c_adap);

	i2c_dev->atomic = false;
	return stm32f7_i2c_xfer_core(i2c_adap, msgs, num);
}

static int stm32f7_i2c_xfer_atomic(struct i2c_adapter *i2c_adap,
			    struct i2c_msg msgs[], int num)
{
	struct stm32f7_i2c_dev *i2c_dev = i2c_get_adapdata(i2c_adap);

	i2c_dev->atomic = true;
	return stm32f7_i2c_xfer_core(i2c_adap, msgs, num);
}

static int stm32f7_i2c_smbus_xfer(struct i2c_adapter *adapter, u16 addr,
				  unsigned short flags, char read_write,
				  u8 command, int size,
				  union i2c_smbus_data *data)
{
	struct stm32f7_i2c_dev *i2c_dev = i2c_get_adapdata(adapter);
	struct stm32f7_i2c_msg *f7_msg = &i2c_dev->f7_msg;
	struct stm32_i2c_dma *dma = i2c_dev->dma;
	struct device *dev = i2c_dev->dev;
	unsigned long time_left;
	int i, ret;

	f7_msg->addr = addr;
	f7_msg->size = size;
	f7_msg->read_write = read_write;
	f7_msg->smbus = true;

	ret = pm_runtime_resume_and_get(dev);
	if (ret < 0)
		return ret;

	ret = stm32f7_i2c_wait_free_bus(i2c_dev);
	if (ret)
		goto pm_free;

	ret = stm32f7_i2c_smbus_xfer_msg(i2c_dev, flags, command, data);
	if (ret)
		goto pm_free;

	time_left = wait_for_completion_timeout(&i2c_dev->complete,
						i2c_dev->adap.timeout);
	ret = f7_msg->result;
	if (ret) {
		if (i2c_dev->use_dma)
			dmaengine_synchronize(dma->chan_using);

		/*
		 * It is possible that some unsent data have already been
		 * written into TXDR. To avoid sending old data in a
		 * further transfer, flush TXDR in case of any error
		 */
		writel_relaxed(STM32F7_I2C_ISR_TXE,
			       i2c_dev->base + STM32F7_I2C_ISR);
		goto pm_free;
	}

	if (!time_left) {
		dev_dbg(dev, "Access to slave 0x%x timed out\n", f7_msg->addr);
		if (i2c_dev->use_dma)
			dmaengine_terminate_sync(dma->chan_using);
		stm32f7_i2c_wait_free_bus(i2c_dev);
		ret = -ETIMEDOUT;
		goto pm_free;
	}

	/* Check PEC */
	if ((flags & I2C_CLIENT_PEC) && size != I2C_SMBUS_QUICK && read_write) {
		ret = stm32f7_i2c_smbus_check_pec(i2c_dev);
		if (ret)
			goto pm_free;
	}

	if (read_write && size != I2C_SMBUS_QUICK) {
		switch (size) {
		case I2C_SMBUS_BYTE:
		case I2C_SMBUS_BYTE_DATA:
			data->byte = f7_msg->smbus_buf[0];
		break;
		case I2C_SMBUS_WORD_DATA:
		case I2C_SMBUS_PROC_CALL:
			data->word = f7_msg->smbus_buf[0] |
				(f7_msg->smbus_buf[1] << 8);
		break;
		case I2C_SMBUS_BLOCK_DATA:
		case I2C_SMBUS_BLOCK_PROC_CALL:
		for (i = 0; i <= f7_msg->smbus_buf[0]; i++)
			data->block[i] = f7_msg->smbus_buf[i];
		break;
		default:
			dev_err(dev, "Unsupported smbus transaction\n");
			ret = -EINVAL;
		}
	}

pm_free:
	pm_runtime_mark_last_busy(dev);
	pm_runtime_put_autosuspend(dev);
	return ret;
}

static void stm32f7_i2c_enable_wakeup(struct stm32f7_i2c_dev *i2c_dev,
				      bool enable)
{
	void __iomem *base = i2c_dev->base;
	u32 mask = STM32F7_I2C_CR1_WUPEN;

	if (!i2c_dev->wakeup_src)
		return;

	if (enable) {
		device_set_wakeup_enable(i2c_dev->dev, true);
		stm32f7_i2c_set_bits(base + STM32F7_I2C_CR1, mask);
	} else {
		device_set_wakeup_enable(i2c_dev->dev, false);
		stm32f7_i2c_clr_bits(base + STM32F7_I2C_CR1, mask);
	}
}

static int stm32f7_i2c_reg_slave(struct i2c_client *slave)
{
	struct stm32f7_i2c_dev *i2c_dev = i2c_get_adapdata(slave->adapter);
	void __iomem *base = i2c_dev->base;
	struct device *dev = i2c_dev->dev;
	u32 oar1, oar2, mask;
	int id, ret;

	if (slave->flags & I2C_CLIENT_PEC) {
		dev_err(dev, "SMBus PEC not supported in slave mode\n");
		return -EINVAL;
	}

	if (stm32f7_i2c_is_slave_busy(i2c_dev)) {
		dev_err(dev, "Too much slave registered\n");
		return -EBUSY;
	}

	ret = stm32f7_i2c_get_free_slave_id(i2c_dev, slave, &id);
	if (ret)
		return ret;

	ret = pm_runtime_resume_and_get(dev);
	if (ret < 0)
		return ret;

	if (!stm32f7_i2c_is_slave_registered(i2c_dev))
		stm32f7_i2c_enable_wakeup(i2c_dev, true);

	switch (id) {
	case 0:
		/* Slave SMBus Host */
		i2c_dev->slave[id] = slave;
		break;

	case 1:
		/* Configure Own Address 1 */
		oar1 = readl_relaxed(i2c_dev->base + STM32F7_I2C_OAR1);
		oar1 &= ~STM32F7_I2C_OAR1_MASK;
		if (slave->flags & I2C_CLIENT_TEN) {
			oar1 |= STM32F7_I2C_OAR1_OA1_10(slave->addr);
			oar1 |= STM32F7_I2C_OAR1_OA1MODE;
		} else {
			oar1 |= STM32F7_I2C_OAR1_OA1_7(slave->addr);
		}
		oar1 |= STM32F7_I2C_OAR1_OA1EN;
		i2c_dev->slave[id] = slave;
		writel_relaxed(oar1, i2c_dev->base + STM32F7_I2C_OAR1);
		break;

	case 2:
		/* Configure Own Address 2 */
		oar2 = readl_relaxed(i2c_dev->base + STM32F7_I2C_OAR2);
		oar2 &= ~STM32F7_I2C_OAR2_MASK;
		if (slave->flags & I2C_CLIENT_TEN) {
			ret = -EOPNOTSUPP;
			goto pm_free;
		}

		oar2 |= STM32F7_I2C_OAR2_OA2_7(slave->addr);
		oar2 |= STM32F7_I2C_OAR2_OA2EN;
		i2c_dev->slave[id] = slave;
		writel_relaxed(oar2, i2c_dev->base + STM32F7_I2C_OAR2);
		break;

	default:
		dev_err(dev, "I2C slave id not supported\n");
		ret = -ENODEV;
		goto pm_free;
	}

	/* Enable ACK */
	stm32f7_i2c_clr_bits(base + STM32F7_I2C_CR2, STM32F7_I2C_CR2_NACK);

	/* Enable Address match interrupt, error interrupt and enable I2C  */
	mask = STM32F7_I2C_CR1_ADDRIE | STM32F7_I2C_CR1_ERRIE |
		STM32F7_I2C_CR1_PE;
	stm32f7_i2c_set_bits(base + STM32F7_I2C_CR1, mask);

	ret = 0;
pm_free:
	if (!stm32f7_i2c_is_slave_registered(i2c_dev))
		stm32f7_i2c_enable_wakeup(i2c_dev, false);

	pm_runtime_mark_last_busy(dev);
	pm_runtime_put_autosuspend(dev);

	return ret;
}

static int stm32f7_i2c_unreg_slave(struct i2c_client *slave)
{
	struct stm32f7_i2c_dev *i2c_dev = i2c_get_adapdata(slave->adapter);
	void __iomem *base = i2c_dev->base;
	u32 mask;
	int id, ret;

	ret = stm32f7_i2c_get_slave_id(i2c_dev, slave, &id);
	if (ret)
		return ret;

	WARN_ON(!i2c_dev->slave[id]);

	ret = pm_runtime_resume_and_get(i2c_dev->dev);
	if (ret < 0)
		return ret;

	if (id == 1) {
		mask = STM32F7_I2C_OAR1_OA1EN;
		stm32f7_i2c_clr_bits(base + STM32F7_I2C_OAR1, mask);
	} else if (id == 2) {
		mask = STM32F7_I2C_OAR2_OA2EN;
		stm32f7_i2c_clr_bits(base + STM32F7_I2C_OAR2, mask);
	}

	i2c_dev->slave[id] = NULL;

	if (!stm32f7_i2c_is_slave_registered(i2c_dev)) {
		stm32f7_i2c_disable_irq(i2c_dev, STM32F7_I2C_ALL_IRQ_MASK);
		stm32f7_i2c_enable_wakeup(i2c_dev, false);
	}

	pm_runtime_mark_last_busy(i2c_dev->dev);
	pm_runtime_put_autosuspend(i2c_dev->dev);

	return 0;
}

static int stm32f7_i2c_write_fm_plus_bits(struct stm32f7_i2c_dev *i2c_dev,
					  bool enable)
{
	int ret = 0;

	if (i2c_dev->bus_rate <= I2C_MAX_FAST_MODE_FREQ ||
	    (!i2c_dev->setup.fmp_cr1_bit && IS_ERR_OR_NULL(i2c_dev->regmap)))
		/* Optional */
		return 0;

	if (i2c_dev->setup.fmp_cr1_bit) {
		if (enable)
			stm32f7_i2c_set_bits(i2c_dev->base + STM32F7_I2C_CR1, STM32_I2C_CR1_FMP);
		else
			stm32f7_i2c_clr_bits(i2c_dev->base + STM32F7_I2C_CR1, STM32_I2C_CR1_FMP);
	} else {
		if (i2c_dev->fmp_sreg == i2c_dev->fmp_creg)
			ret = regmap_update_bits(i2c_dev->regmap, i2c_dev->fmp_sreg,
						 i2c_dev->fmp_mask, enable ? i2c_dev->fmp_mask : 0);
		else
			ret = regmap_write(i2c_dev->regmap,
					   enable ? i2c_dev->fmp_sreg : i2c_dev->fmp_creg,
					   i2c_dev->fmp_mask);
	}

	return ret;
}

static int stm32f7_i2c_setup_fm_plus_bits(struct platform_device *pdev,
					  struct stm32f7_i2c_dev *i2c_dev)
{
	struct device_node *np = pdev->dev.of_node;
	int ret;

	i2c_dev->regmap = syscon_regmap_lookup_by_phandle(np, "st,syscfg-fmp");
	if (IS_ERR(i2c_dev->regmap))
		/* Optional */
		return 0;

	ret = of_property_read_u32_index(np, "st,syscfg-fmp", 1,
					 &i2c_dev->fmp_sreg);
	if (ret)
		return ret;

	i2c_dev->fmp_creg = i2c_dev->fmp_sreg +
			       i2c_dev->setup.fmp_clr_offset;

	return of_property_read_u32_index(np, "st,syscfg-fmp", 2,
					  &i2c_dev->fmp_mask);
}

static int stm32f7_i2c_enable_smbus_host(struct stm32f7_i2c_dev *i2c_dev)
{
	struct i2c_adapter *adap = &i2c_dev->adap;
	void __iomem *base = i2c_dev->base;
	struct i2c_client *client;

	client = i2c_new_slave_host_notify_device(adap);
	if (IS_ERR(client))
		return PTR_ERR(client);

	i2c_dev->host_notify_client = client;

	/* Enable SMBus Host address */
	stm32f7_i2c_set_bits(base + STM32F7_I2C_CR1, STM32F7_I2C_CR1_SMBHEN);

	return 0;
}

static void stm32f7_i2c_disable_smbus_host(struct stm32f7_i2c_dev *i2c_dev)
{
	void __iomem *base = i2c_dev->base;

	if (i2c_dev->host_notify_client) {
		/* Disable SMBus Host address */
		stm32f7_i2c_clr_bits(base + STM32F7_I2C_CR1,
				     STM32F7_I2C_CR1_SMBHEN);
		i2c_free_slave_host_notify_device(i2c_dev->host_notify_client);
	}
}

static int stm32f7_i2c_enable_smbus_alert(struct stm32f7_i2c_dev *i2c_dev)
{
	struct stm32f7_i2c_alert *alert;
	struct i2c_adapter *adap = &i2c_dev->adap;
	struct device *dev = i2c_dev->dev;
	void __iomem *base = i2c_dev->base;

	alert = devm_kzalloc(dev, sizeof(*alert), GFP_KERNEL);
	if (!alert)
		return -ENOMEM;

	alert->ara = i2c_new_smbus_alert_device(adap, &alert->setup);
	if (IS_ERR(alert->ara))
		return PTR_ERR(alert->ara);

	i2c_dev->alert = alert;

	/* Enable SMBus Alert */
	stm32f7_i2c_set_bits(base + STM32F7_I2C_CR1, STM32F7_I2C_CR1_ALERTEN);

	return 0;
}

static void stm32f7_i2c_disable_smbus_alert(struct stm32f7_i2c_dev *i2c_dev)
{
	struct stm32f7_i2c_alert *alert = i2c_dev->alert;
	void __iomem *base = i2c_dev->base;

	if (alert) {
		/* Disable SMBus Alert */
		stm32f7_i2c_clr_bits(base + STM32F7_I2C_CR1,
				     STM32F7_I2C_CR1_ALERTEN);
		i2c_unregister_device(alert->ara);
	}
}

static u32 stm32f7_i2c_func(struct i2c_adapter *adap)
{
	struct stm32f7_i2c_dev *i2c_dev = i2c_get_adapdata(adap);

	u32 func = I2C_FUNC_I2C | I2C_FUNC_10BIT_ADDR | I2C_FUNC_SLAVE |
		   I2C_FUNC_SMBUS_QUICK | I2C_FUNC_SMBUS_BYTE |
		   I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA |
		   I2C_FUNC_SMBUS_BLOCK_DATA | I2C_FUNC_SMBUS_BLOCK_PROC_CALL |
		   I2C_FUNC_SMBUS_PROC_CALL | I2C_FUNC_SMBUS_PEC |
		   I2C_FUNC_SMBUS_I2C_BLOCK;

	if (i2c_dev->smbus_mode)
		func |= I2C_FUNC_SMBUS_HOST_NOTIFY;

	return func;
}

static const struct i2c_algorithm stm32f7_i2c_algo = {
	.master_xfer = stm32f7_i2c_xfer,
	.master_xfer_atomic = stm32f7_i2c_xfer_atomic,
	.smbus_xfer = stm32f7_i2c_smbus_xfer,
	.functionality = stm32f7_i2c_func,
	.reg_slave = stm32f7_i2c_reg_slave,
	.unreg_slave = stm32f7_i2c_unreg_slave,
};

static int stm32f7_i2c_probe(struct platform_device *pdev)
{
	struct stm32f7_i2c_dev *i2c_dev;
	const struct stm32f7_i2c_setup *setup;
	struct resource *res;
	struct i2c_adapter *adap;
	struct reset_control *rst;
	dma_addr_t phy_addr;
	int irq_error, irq_event, ret;

	i2c_dev = devm_kzalloc(&pdev->dev, sizeof(*i2c_dev), GFP_KERNEL);
	if (!i2c_dev)
		return -ENOMEM;

	setup = of_device_get_match_data(&pdev->dev);
	if (!setup) {
		dev_err(&pdev->dev, "Can't get device data\n");
		return -ENODEV;
	}
	i2c_dev->setup = *setup;

	i2c_dev->base = devm_platform_get_and_ioremap_resource(pdev, 0, &res);
	if (IS_ERR(i2c_dev->base))
		return PTR_ERR(i2c_dev->base);
	phy_addr = (dma_addr_t)res->start;

	irq_event = platform_get_irq(pdev, 0);
	if (irq_event < 0)
		return irq_event;

	i2c_dev->wakeup_src = of_property_read_bool(pdev->dev.of_node,
						    "wakeup-source");

	i2c_dev->clk = devm_clk_get_enabled(&pdev->dev, NULL);
	if (IS_ERR(i2c_dev->clk))
		return dev_err_probe(&pdev->dev, PTR_ERR(i2c_dev->clk),
				     "Failed to enable controller clock\n");

	rst = devm_reset_control_get(&pdev->dev, NULL);
	if (IS_ERR(rst))
		return dev_err_probe(&pdev->dev, PTR_ERR(rst),
				     "Error: Missing reset ctrl\n");

	reset_control_assert(rst);
	udelay(2);
	reset_control_deassert(rst);

	i2c_dev->dev = &pdev->dev;

	ret = devm_request_threaded_irq(&pdev->dev, irq_event,
					stm32f7_i2c_isr_event,
					stm32f7_i2c_isr_event_thread,
					IRQF_ONESHOT,
					pdev->name, i2c_dev);
	if (ret)
		return dev_err_probe(&pdev->dev, ret, "Failed to request irq event\n");

	if (!i2c_dev->setup.single_it_line) {
		irq_error = platform_get_irq(pdev, 1);
		if (irq_error < 0)
			return irq_error;

		ret = devm_request_threaded_irq(&pdev->dev, irq_error,
						NULL,
						stm32f7_i2c_isr_error_thread,
						IRQF_ONESHOT,
						pdev->name, i2c_dev);
		if (ret)
			return dev_err_probe(&pdev->dev, ret, "Failed to request irq error\n");
	}

	ret = stm32f7_i2c_setup_timing(i2c_dev, &i2c_dev->setup);
	if (ret)
		return ret;

	/* Setup Fast mode plus if necessary */
	if (i2c_dev->bus_rate > I2C_MAX_FAST_MODE_FREQ) {
		if (!i2c_dev->setup.fmp_cr1_bit) {
			ret = stm32f7_i2c_setup_fm_plus_bits(pdev, i2c_dev);
			if (ret)
				return ret;
		}

		ret = stm32f7_i2c_write_fm_plus_bits(i2c_dev, true);
		if (ret)
			return ret;
	}

	adap = &i2c_dev->adap;
	i2c_set_adapdata(adap, i2c_dev);
	snprintf(adap->name, sizeof(adap->name), "STM32F7 I2C(%pa)",
		 &res->start);
	adap->owner = THIS_MODULE;
	adap->timeout = 2 * HZ;
	adap->retries = 3;
	adap->algo = &stm32f7_i2c_algo;
	adap->dev.parent = &pdev->dev;
	adap->dev.of_node = pdev->dev.of_node;

	init_completion(&i2c_dev->complete);

	/* Init DMA config if supported */
	i2c_dev->dma = stm32_i2c_dma_request(i2c_dev->dev, phy_addr,
					     STM32F7_I2C_TXDR,
					     STM32F7_I2C_RXDR);
	if (IS_ERR(i2c_dev->dma)) {
		ret = PTR_ERR(i2c_dev->dma);
		/* DMA support is optional, only report other errors */
		if (ret != -ENODEV)
			goto fmp_clear;
		dev_dbg(i2c_dev->dev, "No DMA option: fallback using interrupts\n");
		i2c_dev->dma = NULL;
	}

	if (i2c_dev->wakeup_src) {
		device_set_wakeup_capable(i2c_dev->dev, true);

		ret = dev_pm_set_wake_irq(i2c_dev->dev, irq_event);
		if (ret) {
			dev_err(i2c_dev->dev, "Failed to set wake up irq\n");
			goto clr_wakeup_capable;
		}
	}

	platform_set_drvdata(pdev, i2c_dev);

	pm_runtime_set_autosuspend_delay(i2c_dev->dev,
					 STM32F7_AUTOSUSPEND_DELAY);
	pm_runtime_use_autosuspend(i2c_dev->dev);
	pm_runtime_set_active(i2c_dev->dev);
	pm_runtime_enable(i2c_dev->dev);

	pm_runtime_get_noresume(&pdev->dev);

	stm32f7_i2c_hw_config(i2c_dev);

	i2c_dev->smbus_mode = of_property_read_bool(pdev->dev.of_node, "smbus");

	ret = i2c_add_adapter(adap);
	if (ret)
		goto pm_disable;

	if (i2c_dev->smbus_mode) {
		ret = stm32f7_i2c_enable_smbus_host(i2c_dev);
		if (ret) {
			dev_err(i2c_dev->dev,
				"failed to enable SMBus Host-Notify protocol (%d)\n",
				ret);
			goto i2c_adapter_remove;
		}
	}

	if (of_property_read_bool(pdev->dev.of_node, "smbus-alert")) {
		ret = stm32f7_i2c_enable_smbus_alert(i2c_dev);
		if (ret) {
			dev_err(i2c_dev->dev,
				"failed to enable SMBus alert protocol (%d)\n",
				ret);
			goto i2c_disable_smbus_host;
		}
	}

	dev_info(i2c_dev->dev, "STM32F7 I2C-%d bus adapter\n", adap->nr);

	pm_runtime_mark_last_busy(i2c_dev->dev);
	pm_runtime_put_autosuspend(i2c_dev->dev);

	return 0;

i2c_disable_smbus_host:
	stm32f7_i2c_disable_smbus_host(i2c_dev);

i2c_adapter_remove:
	i2c_del_adapter(adap);

pm_disable:
	pm_runtime_put_noidle(i2c_dev->dev);
	pm_runtime_disable(i2c_dev->dev);
	pm_runtime_set_suspended(i2c_dev->dev);
	pm_runtime_dont_use_autosuspend(i2c_dev->dev);

	if (i2c_dev->wakeup_src)
		dev_pm_clear_wake_irq(i2c_dev->dev);

clr_wakeup_capable:
	if (i2c_dev->wakeup_src)
		device_set_wakeup_capable(i2c_dev->dev, false);

	if (i2c_dev->dma) {
		stm32_i2c_dma_free(i2c_dev->dma);
		i2c_dev->dma = NULL;
	}

fmp_clear:
	stm32f7_i2c_write_fm_plus_bits(i2c_dev, false);

	return ret;
}

static void stm32f7_i2c_remove(struct platform_device *pdev)
{
	struct stm32f7_i2c_dev *i2c_dev = platform_get_drvdata(pdev);

	stm32f7_i2c_disable_smbus_alert(i2c_dev);
	stm32f7_i2c_disable_smbus_host(i2c_dev);

	i2c_del_adapter(&i2c_dev->adap);
	pm_runtime_get_sync(i2c_dev->dev);

	if (i2c_dev->wakeup_src) {
		dev_pm_clear_wake_irq(i2c_dev->dev);
		/*
		 * enforce that wakeup is disabled and that the device
		 * is marked as non wakeup capable
		 */
		device_init_wakeup(i2c_dev->dev, false);
	}

	pm_runtime_put_noidle(i2c_dev->dev);
	pm_runtime_disable(i2c_dev->dev);
	pm_runtime_set_suspended(i2c_dev->dev);
	pm_runtime_dont_use_autosuspend(i2c_dev->dev);

	if (i2c_dev->dma) {
		stm32_i2c_dma_free(i2c_dev->dma);
		i2c_dev->dma = NULL;
	}

	stm32f7_i2c_write_fm_plus_bits(i2c_dev, false);
}

static int __maybe_unused stm32f7_i2c_runtime_suspend(struct device *dev)
{
	struct stm32f7_i2c_dev *i2c_dev = dev_get_drvdata(dev);

	if (!stm32f7_i2c_is_slave_registered(i2c_dev))
		clk_disable(i2c_dev->clk);

	return 0;
}

static int __maybe_unused stm32f7_i2c_runtime_resume(struct device *dev)
{
	struct stm32f7_i2c_dev *i2c_dev = dev_get_drvdata(dev);
	int ret;

	if (!stm32f7_i2c_is_slave_registered(i2c_dev)) {
		ret = clk_enable(i2c_dev->clk);
		if (ret) {
			dev_err(dev, "failed to enable clock\n");
			return ret;
		}
	}

	return 0;
}

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_resume_and_get(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->tmgr = readl_relaxed(i2c_dev->base + STM32F7_I2C_TIMINGR);
	stm32f7_i2c_write_fm_plus_bits(i2c_dev, false);

	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_resume_and_get(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);
	stm32f7_i2c_write_fm_plus_bits(i2c_dev, true);

	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);

	if (!device_may_wakeup(dev) && !device_wakeup_path(dev)) {
		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;

	if (!device_may_wakeup(dev) && !device_wakeup_path(dev)) {
		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[] = {
	{ .compatible = "st,stm32f7-i2c", .data = &stm32f7_setup},
	{ .compatible = "st,stm32mp15-i2c", .data = &stm32mp15_setup},
	{ .compatible = "st,stm32mp13-i2c", .data = &stm32mp13_setup},
	{ .compatible = "st,stm32mp25-i2c", .data = &stm32mp25_setup},
	{},
};
MODULE_DEVICE_TABLE(of, stm32f7_i2c_match);

static struct platform_driver stm32f7_i2c_driver = {
	.driver = {
		.name = "stm32f7-i2c",
		.of_match_table = stm32f7_i2c_match,
		.pm = &stm32f7_i2c_pm_ops,
	},
	.probe = stm32f7_i2c_probe,
	.remove_new = stm32f7_i2c_remove,
};

module_platform_driver(stm32f7_i2c_driver);

MODULE_AUTHOR("M'boumba Cedric Madianga <cedric.madianga@gmail.com>");
MODULE_DESCRIPTION("STMicroelectronics STM32F7 I2C driver");
MODULE_LICENSE("GPL v2");
