// SPDX-License-Identifier: GPL-2.0
/*
 * Renesas I3C Controller driver
 * Copyright (C) 2023-25 Renesas Electronics Corp.
 *
 * TODO: IBI support, HotJoin support, Target support
 */

#include <linux/bitfield.h>
#include <linux/bitops.h>
#include <linux/clk.h>
#include <linux/completion.h>
#include <linux/err.h>
#include <linux/errno.h>
#include <linux/i2c.h>
#include <linux/i3c/master.h>
#include <linux/interrupt.h>
#include <linux/ioport.h>
#include <linux/iopoll.h>
#include <linux/list.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/platform_device.h>
#include <linux/reset.h>
#include <linux/slab.h>
#include "../internals.h"

#define PRTS			0x00
#define  PRTS_PRTMD		BIT(0)

#define BCTL			0x14
#define  BCTL_INCBA		BIT(0)
#define  BCTL_HJACKCTL		BIT(8)
#define  BCTL_ABT		BIT(29)
#define  BCTL_BUSE		BIT(31)

#define MSDVAD			0x18
#define  MSDVAD_MDYAD(x)	FIELD_PREP(GENMASK(21, 16), x)
#define  MSDVAD_MDYADV		BIT(31)

#define RSTCTL			0x20
#define  RSTCTL_RI3CRST		BIT(0)
#define  RSTCTL_INTLRST		BIT(16)

#define INST			0x30

#define IBINCTL			0x58
#define  IBINCTL_NRHJCTL	BIT(0)
#define  IBINCTL_NRMRCTL	BIT(1)
#define  IBINCTL_NRSIRCTL	BIT(3)

#define SVCTL			0x64

#define REFCKCTL		0x70
#define  REFCKCTL_IREFCKS(x)	FIELD_PREP(GENMASK(2, 0), x)

#define STDBR			0x74
#define  STDBR_SBRLO(cond, x)	FIELD_PREP(GENMASK(7, 0), (x) >> (cond))
#define  STDBR_SBRHO(cond, x)	FIELD_PREP(GENMASK(15, 8), (x) >> (cond))
#define  STDBR_SBRLP(x)		FIELD_PREP(GENMASK(21, 16), x)
#define  STDBR_SBRHP(x)		FIELD_PREP(GENMASK(29, 24), x)
#define  STDBR_DSBRPO		BIT(31)

#define EXTBR			0x78
#define  EXTBR_EBRLO(x)		FIELD_PREP(GENMASK(7, 0), x)
#define  EXTBR_EBRHO(x)		FIELD_PREP(GENMASK(15, 8), x)
#define  EXTBR_EBRLP(x)		FIELD_PREP(GENMASK(21, 16), x)
#define  EXTBR_EBRHP(x)		FIELD_PREP(GENMASK(29, 24), x)

#define BFRECDT			0x7c
#define  BFRECDT_FRECYC(x)	FIELD_PREP(GENMASK(8, 0), x)

#define BAVLCDT			0x80
#define  BAVLCDT_AVLCYC(x)	FIELD_PREP(GENMASK(8, 0), x)

#define BIDLCDT			0x84
#define  BIDLCDT_IDLCYC(x)	FIELD_PREP(GENMASK(17, 0), x)

#define ACKCTL			0xa0
#define  ACKCTL_ACKT		BIT(1)
#define  ACKCTL_ACKTWP		BIT(2)

#define SCSTRCTL		0xa4
#define  SCSTRCTL_ACKTWE	BIT(0)
#define  SCSTRCTL_RWE		BIT(1)

#define SCSTLCTL		0xb0

#define CNDCTL			0x140
#define  CNDCTL_STCND		BIT(0)
#define  CNDCTL_SRCND		BIT(1)
#define  CNDCTL_SPCND		BIT(2)

#define NCMDQP			0x150 /* Normal Command Queue */
#define  NCMDQP_CMD_ATTR(x)	FIELD_PREP(GENMASK(2, 0), x)
#define  NCMDQP_IMMED_XFER	0x01
#define  NCMDQP_ADDR_ASSGN	0x02
#define  NCMDQP_TID(x)		FIELD_PREP(GENMASK(6, 3), x)
#define  NCMDQP_CMD(x)		FIELD_PREP(GENMASK(14, 7), x)
#define  NCMDQP_CP		BIT(15)
#define  NCMDQP_DEV_INDEX(x)	FIELD_PREP(GENMASK(20, 16), x)
#define  NCMDQP_BYTE_CNT(x)	FIELD_PREP(GENMASK(25, 23), x)
#define  NCMDQP_DEV_COUNT(x)	FIELD_PREP(GENMASK(29, 26), x)
#define  NCMDQP_MODE(x)		FIELD_PREP(GENMASK(28, 26), x)
#define  NCMDQP_RNW(x)		FIELD_PREP(GENMASK(29, 29), x)
#define  NCMDQP_ROC		BIT(30)
#define  NCMDQP_TOC		BIT(31)
#define  NCMDQP_DATA_LENGTH(x)	FIELD_PREP(GENMASK(31, 16), x)

#define NRSPQP			0x154 /* Normal Respone Queue */
#define  NRSPQP_NO_ERROR			0
#define  NRSPQP_ERROR_CRC		1
#define  NRSPQP_ERROR_PARITY		2
#define  NRSPQP_ERROR_FRAME		3
#define  NRSPQP_ERROR_IBA_NACK		4
#define  NRSPQP_ERROR_ADDRESS_NACK	5
#define  NRSPQP_ERROR_OVER_UNDER_FLOW	6
#define  NRSPQP_ERROR_TRANSF_ABORT	8
#define  NRSPQP_ERROR_I2C_W_NACK_ERR	9
#define  NRSPQP_ERROR_UNSUPPORTED	10
#define  NRSPQP_DATA_LEN(x)	FIELD_GET(GENMASK(15, 0), x)
#define  NRSPQP_ERR_STATUS(x)	FIELD_GET(GENMASK(31, 28), x)

#define NTDTBP0			0x158 /* Normal Transfer Data Buffer */
#define  NTDTBP0_DEPTH		16

#define NQTHCTL			0x190
#define  NQTHCTL_CMDQTH(x)	FIELD_PREP(GENMASK(1, 0), x)
#define  NQTHCTL_IBIDSSZ(x)	FIELD_PREP(GENMASK(23, 16), x)

#define NTBTHCTL0		0x194

#define NRQTHCTL		0x1c0

#define BST			0x1d0
#define  BST_STCNDDF		BIT(0)
#define  BST_SPCNDDF		BIT(1)
#define  BST_NACKDF		BIT(4)
#define  BST_TENDF		BIT(8)

#define BSTE			0x1d4
#define  BSTE_STCNDDE		BIT(0)
#define  BSTE_SPCNDDE		BIT(1)
#define  BSTE_NACKDE		BIT(4)
#define  BSTE_TENDE		BIT(8)
#define  BSTE_ALE		BIT(16)
#define  BSTE_TODE		BIT(20)
#define  BSTE_WUCNDDE		BIT(24)
#define  BSTE_ALL_FLAG		(BSTE_STCNDDE | BSTE_SPCNDDE |\
				BSTE_NACKDE | BSTE_TENDE |\
				BSTE_ALE | BSTE_TODE | BSTE_WUCNDDE)

#define BIE			0x1d8
#define  BIE_STCNDDIE		BIT(0)
#define  BIE_SPCNDDIE		BIT(1)
#define  BIE_NACKDIE		BIT(4)
#define  BIE_TENDIE		BIT(8)

#define NTST			0x1e0
#define  NTST_TDBEF0		BIT(0)
#define  NTST_RDBFF0		BIT(1)
#define  NTST_CMDQEF		BIT(3)
#define  NTST_RSPQFF		BIT(4)
#define  NTST_TABTF		BIT(5)
#define  NTST_TEF		BIT(9)

#define NTSTE			0x1e4
#define  NTSTE_TDBEE0		BIT(0)
#define  NTSTE_RDBFE0		BIT(1)
#define  NTSTE_IBIQEFE		BIT(2)
#define  NTSTE_CMDQEE		BIT(3)
#define  NTSTE_RSPQFE		BIT(4)
#define  NTSTE_TABTE		BIT(5)
#define  NTSTE_TEE		BIT(9)
#define  NTSTE_RSQFE		BIT(20)
#define  NTSTE_ALL_FLAG		(NTSTE_TDBEE0 | NTSTE_RDBFE0 |\
				NTSTE_IBIQEFE | NTSTE_CMDQEE |\
				NTSTE_RSPQFE | NTSTE_TABTE |\
				NTSTE_TEE | NTSTE_RSQFE)

#define NTIE			0x1e8
#define  NTIE_TDBEIE0		BIT(0)
#define  NTIE_RDBFIE0		BIT(1)
#define  NTIE_IBIQEFIE		BIT(2)
#define  NTIE_RSPQFIE		BIT(4)
#define  NTIE_RSQFIE		BIT(20)

#define BCST			0x210
#define  BCST_BFREF		BIT(0)

#define DATBAS(x)		(0x224 + 0x8 * (x))
#define  DATBAS_DVSTAD(x)	FIELD_PREP(GENMASK(6, 0), x)
#define  DATBAS_DVDYAD(x)	FIELD_PREP(GENMASK(23, 16), x)

#define NDBSTLV0		0x398
#define  NDBSTLV0_RDBLV(x)	FIELD_GET(GENMASK(15, 8), x)

#define RENESAS_I3C_MAX_DEVS	8
#define I2C_INIT_MSG		-1

enum i3c_internal_state {
	I3C_INTERNAL_STATE_DISABLED,
	I3C_INTERNAL_STATE_CONTROLLER_IDLE,
	I3C_INTERNAL_STATE_CONTROLLER_ENTDAA,
	I3C_INTERNAL_STATE_CONTROLLER_SETDASA,
	I3C_INTERNAL_STATE_CONTROLLER_WRITE,
	I3C_INTERNAL_STATE_CONTROLLER_READ,
	I3C_INTERNAL_STATE_CONTROLLER_COMMAND_WRITE,
	I3C_INTERNAL_STATE_CONTROLLER_COMMAND_READ,
};

enum renesas_i3c_event {
	I3C_COMMAND_ADDRESS_ASSIGNMENT,
	I3C_WRITE,
	I3C_READ,
	I3C_COMMAND_WRITE,
	I3C_COMMAND_READ,
};

struct renesas_i3c_cmd {
	u32 cmd0;
	u32 len;
	const void *tx_buf;
	u32 tx_count;
	void *rx_buf;
	u32 rx_count;
	u32 err;
	u8 rnw;
	/* i2c xfer */
	int i2c_bytes_left;
	int i2c_is_last;
	u8 *i2c_buf;
	const struct i2c_msg *msg;
};

struct renesas_i3c_xfer {
	struct list_head node;
	struct completion comp;
	int ret;
	bool is_i2c_xfer;
	unsigned int ncmds;
	struct renesas_i3c_cmd cmds[] __counted_by(ncmds);
};

struct renesas_i3c_xferqueue {
	struct list_head list;
	struct renesas_i3c_xfer *cur;
	/* Lock for accessing the xfer queue */
	spinlock_t lock;
};

struct renesas_i3c {
	struct i3c_master_controller base;
	enum i3c_internal_state internal_state;
	u16 maxdevs;
	u32 free_pos;
	u32 i2c_STDBR;
	u32 i3c_STDBR;
	u8 addrs[RENESAS_I3C_MAX_DEVS];
	struct renesas_i3c_xferqueue xferqueue;
	void __iomem *regs;
	struct clk *tclk;
};

struct renesas_i3c_i2c_dev_data {
	u8 index;
};

struct renesas_i3c_irq_desc {
	const char *name;
	irq_handler_t isr;
	const char *desc;
};

struct renesas_i3c_config {
	unsigned int has_pclkrw:1;
};

static inline void renesas_i3c_reg_update(void __iomem *reg, u32 mask, u32 val)
{
	u32 data = readl(reg);

	data &= ~mask;
	data |= (val & mask);
	writel(data, reg);
}

static inline u32 renesas_readl(void __iomem *base, u32 reg)
{
	return readl(base + reg);
}

static inline void renesas_writel(void __iomem *base, u32 reg, u32 val)
{
	writel(val, base + reg);
}

static void renesas_set_bit(void __iomem *base, u32 reg, u32 val)
{
	renesas_i3c_reg_update(base + reg, val, val);
}

static void renesas_clear_bit(void __iomem *base, u32 reg, u32 val)
{
	renesas_i3c_reg_update(base + reg, val, 0);
}

static inline struct renesas_i3c *to_renesas_i3c(struct i3c_master_controller *m)
{
	return container_of(m, struct renesas_i3c, base);
}

static inline u32 datbas_dvdyad_with_parity(u8 addr)
{
	return DATBAS_DVDYAD(addr | (parity8(addr) ? 0 : BIT(7)));
}

static int renesas_i3c_get_free_pos(struct renesas_i3c *i3c)
{
	if (!(i3c->free_pos & GENMASK(i3c->maxdevs - 1, 0)))
		return -ENOSPC;

	return ffs(i3c->free_pos) - 1;
}

static int renesas_i3c_get_addr_pos(struct renesas_i3c *i3c, u8 addr)
{
	int pos;

	for (pos = 0; pos < i3c->maxdevs; pos++) {
		if (addr == i3c->addrs[pos])
			return pos;
	}

	return -EINVAL;
}

static struct renesas_i3c_xfer *renesas_i3c_alloc_xfer(struct renesas_i3c *i3c,
						       unsigned int ncmds)
{
	struct renesas_i3c_xfer *xfer;

	xfer = kzalloc(struct_size(xfer, cmds, ncmds), GFP_KERNEL);
	if (!xfer)
		return NULL;

	INIT_LIST_HEAD(&xfer->node);
	xfer->ncmds = ncmds;
	xfer->ret = -ETIMEDOUT;

	return xfer;
}

static void renesas_i3c_start_xfer_locked(struct renesas_i3c *i3c)
{
	struct renesas_i3c_xfer *xfer = i3c->xferqueue.cur;
	struct renesas_i3c_cmd *cmd;
	u32 cmd1;

	if (!xfer)
		return;

	cmd = xfer->cmds;

	switch (i3c->internal_state) {
	case I3C_INTERNAL_STATE_CONTROLLER_ENTDAA:
	case I3C_INTERNAL_STATE_CONTROLLER_SETDASA:
		renesas_set_bit(i3c->regs, NTIE, NTIE_RSPQFIE);
		renesas_writel(i3c->regs, NCMDQP, cmd->cmd0);
		renesas_writel(i3c->regs, NCMDQP, 0);
		break;
	case I3C_INTERNAL_STATE_CONTROLLER_WRITE:
	case I3C_INTERNAL_STATE_CONTROLLER_COMMAND_WRITE:
		renesas_set_bit(i3c->regs, NTIE, NTIE_RSPQFIE);
		if (cmd->len <= 4) {
			cmd->cmd0 |= NCMDQP_CMD_ATTR(NCMDQP_IMMED_XFER);
			cmd->cmd0 |= NCMDQP_BYTE_CNT(cmd->len);
			cmd->tx_count = cmd->len;
			cmd1 = cmd->len == 0 ? 0 : *(u32 *)cmd->tx_buf;
		} else {
			cmd1 = NCMDQP_DATA_LENGTH(cmd->len);
		}
		renesas_writel(i3c->regs, NCMDQP, cmd->cmd0);
		renesas_writel(i3c->regs, NCMDQP, cmd1);
		break;
	case I3C_INTERNAL_STATE_CONTROLLER_READ:
	case I3C_INTERNAL_STATE_CONTROLLER_COMMAND_READ:
		renesas_set_bit(i3c->regs, NTIE, NTIE_RDBFIE0);
		cmd1 = NCMDQP_DATA_LENGTH(cmd->len);
		renesas_writel(i3c->regs, NCMDQP, cmd->cmd0);
		renesas_writel(i3c->regs, NCMDQP, cmd1);
		break;
	default:
		break;
	}

	/* Clear the command queue empty flag */
	renesas_clear_bit(i3c->regs, NTST, NTST_CMDQEF);
}

static void renesas_i3c_dequeue_xfer_locked(struct renesas_i3c *i3c,
					    struct renesas_i3c_xfer *xfer)
{
	if (i3c->xferqueue.cur == xfer)
		i3c->xferqueue.cur = NULL;
	else
		list_del_init(&xfer->node);
}

static void renesas_i3c_dequeue_xfer(struct renesas_i3c *i3c, struct renesas_i3c_xfer *xfer)
{
	scoped_guard(spinlock_irqsave, &i3c->xferqueue.lock)
		renesas_i3c_dequeue_xfer_locked(i3c, xfer);
}

static void renesas_i3c_enqueue_xfer(struct renesas_i3c *i3c, struct renesas_i3c_xfer *xfer)
{
	reinit_completion(&xfer->comp);
	scoped_guard(spinlock_irqsave, &i3c->xferqueue.lock) {
		if (i3c->xferqueue.cur) {
			list_add_tail(&xfer->node, &i3c->xferqueue.list);
		} else {
			i3c->xferqueue.cur = xfer;
			if (!xfer->is_i2c_xfer)
				renesas_i3c_start_xfer_locked(i3c);
		}
	}
}

static void renesas_i3c_wait_xfer(struct renesas_i3c *i3c, struct renesas_i3c_xfer *xfer)
{
	unsigned long time_left;

	renesas_i3c_enqueue_xfer(i3c, xfer);

	time_left = wait_for_completion_timeout(&xfer->comp, msecs_to_jiffies(1000));
	if (!time_left)
		renesas_i3c_dequeue_xfer(i3c, xfer);
}

static void renesas_i3c_set_prts(struct renesas_i3c *i3c, u32 val)
{
	/* Required sequence according to tnrza0140ae */
	renesas_set_bit(i3c->regs, RSTCTL, RSTCTL_INTLRST);
	renesas_writel(i3c->regs, PRTS, val);
	renesas_clear_bit(i3c->regs, RSTCTL, RSTCTL_INTLRST);
}

static void renesas_i3c_bus_enable(struct i3c_master_controller *m, bool i3c_mode)
{
	struct renesas_i3c *i3c = to_renesas_i3c(m);

	/* Setup either I3C or I2C protocol */
	if (i3c_mode) {
		renesas_i3c_set_prts(i3c, 0);
		/* Revisit: INCBA handling, especially after I2C transfers */
		renesas_set_bit(i3c->regs, BCTL, BCTL_HJACKCTL | BCTL_INCBA);
		renesas_set_bit(i3c->regs, MSDVAD, MSDVAD_MDYADV);
		renesas_writel(i3c->regs, STDBR, i3c->i3c_STDBR);
	} else {
		renesas_i3c_set_prts(i3c, PRTS_PRTMD);
		renesas_writel(i3c->regs, STDBR, i3c->i2c_STDBR);
	}

	/* Enable I3C bus */
	renesas_set_bit(i3c->regs, BCTL, BCTL_BUSE);
}

static int renesas_i3c_reset(struct renesas_i3c *i3c)
{
	u32 val;

	renesas_writel(i3c->regs, BCTL, 0);
	renesas_set_bit(i3c->regs, RSTCTL, RSTCTL_RI3CRST);

	return read_poll_timeout(renesas_readl, val, !(val & RSTCTL_RI3CRST),
				 0, 1000, false, i3c->regs, RSTCTL);
}

static int renesas_i3c_bus_init(struct i3c_master_controller *m)
{
	struct renesas_i3c *i3c = to_renesas_i3c(m);
	struct i3c_bus *bus = i3c_master_get_bus(m);
	struct i3c_device_info info = {};
	struct i2c_timings t;
	unsigned long rate;
	u32 double_SBR, val;
	int cks, pp_high_ticks, pp_low_ticks, i3c_total_ticks;
	int od_high_ticks, od_low_ticks, i2c_total_ticks;
	int ret;

	rate = clk_get_rate(i3c->tclk);
	if (!rate)
		return -EINVAL;

	ret = renesas_i3c_reset(i3c);
	if (ret)
		return ret;

	i2c_total_ticks = DIV_ROUND_UP(rate, bus->scl_rate.i2c);
	i3c_total_ticks = DIV_ROUND_UP(rate, bus->scl_rate.i3c);

	i2c_parse_fw_timings(&m->dev, &t, true);

	for (cks = 0; cks < 7; cks++) {
		/* SCL low-period calculation in Open-drain mode */
		od_low_ticks = ((i2c_total_ticks * 6) / 10);

		/* SCL clock calculation in Push-Pull mode */
		if (bus->mode == I3C_BUS_MODE_PURE)
			pp_high_ticks = ((i3c_total_ticks * 5) / 10);
		else
			pp_high_ticks = DIV_ROUND_UP(I3C_BUS_THIGH_MIXED_MAX_NS,
						     NSEC_PER_SEC / rate);
		pp_low_ticks = i3c_total_ticks - pp_high_ticks;

		if ((od_low_ticks / 2) <= 0xFF && pp_low_ticks < 0x3F)
			break;

		i2c_total_ticks /= 2;
		i3c_total_ticks /= 2;
		rate /= 2;
	}

	/* SCL clock period calculation in Open-drain mode */
	if ((od_low_ticks / 2) > 0xFF || pp_low_ticks > 0x3F) {
		dev_err(&m->dev, "invalid speed (i2c-scl = %lu Hz, i3c-scl = %lu Hz). Too slow.\n",
			(unsigned long)bus->scl_rate.i2c, (unsigned long)bus->scl_rate.i3c);
		return -EINVAL;
	}

	/* SCL high-period calculation in Open-drain mode */
	od_high_ticks = i2c_total_ticks - od_low_ticks;

	/* Standard Bit Rate setting */
	double_SBR = od_low_ticks > 0xFF ? 1 : 0;
	i3c->i3c_STDBR = (double_SBR ? STDBR_DSBRPO : 0) |
			STDBR_SBRLO(double_SBR, od_low_ticks) |
			STDBR_SBRHO(double_SBR, od_high_ticks) |
			STDBR_SBRLP(pp_low_ticks) |
			STDBR_SBRHP(pp_high_ticks);

	od_low_ticks -= t.scl_fall_ns / (NSEC_PER_SEC / rate) + 1;
	od_high_ticks -= t.scl_rise_ns / (NSEC_PER_SEC / rate) + 1;
	i3c->i2c_STDBR = (double_SBR ? STDBR_DSBRPO : 0) |
			STDBR_SBRLO(double_SBR, od_low_ticks) |
			STDBR_SBRHO(double_SBR, od_high_ticks) |
			STDBR_SBRLP(pp_low_ticks) |
			STDBR_SBRHP(pp_high_ticks);
	renesas_writel(i3c->regs, STDBR, i3c->i3c_STDBR);

	/* Extended Bit Rate setting */
	renesas_writel(i3c->regs, EXTBR, EXTBR_EBRLO(od_low_ticks) |
					   EXTBR_EBRHO(od_high_ticks) |
					   EXTBR_EBRLP(pp_low_ticks) |
					   EXTBR_EBRHP(pp_high_ticks));

	renesas_writel(i3c->regs, REFCKCTL, REFCKCTL_IREFCKS(cks));

	/* Disable Slave Mode */
	renesas_writel(i3c->regs, SVCTL, 0);

	/* Initialize Queue/Buffer threshold */
	renesas_writel(i3c->regs, NQTHCTL, NQTHCTL_IBIDSSZ(6) |
					     NQTHCTL_CMDQTH(1));

	/* The only supported configuration is two entries*/
	renesas_writel(i3c->regs, NTBTHCTL0, 0);
	/* Interrupt when there is one entry in the queue */
	renesas_writel(i3c->regs, NRQTHCTL, 0);

	/* Enable all Bus/Transfer Status Flags */
	renesas_writel(i3c->regs, BSTE, BSTE_ALL_FLAG);
	renesas_writel(i3c->regs, NTSTE, NTSTE_ALL_FLAG);

	/* Interrupt enable settings */
	renesas_writel(i3c->regs, BIE, BIE_NACKDIE | BIE_TENDIE);
	renesas_writel(i3c->regs, NTIE, 0);

	/* Clear Status register */
	renesas_writel(i3c->regs, NTST, 0);
	renesas_writel(i3c->regs, INST, 0);
	renesas_writel(i3c->regs, BST, 0);

	/* Hot-Join Acknowlege setting. */
	renesas_set_bit(i3c->regs, BCTL, BCTL_HJACKCTL);

	renesas_writel(i3c->regs, IBINCTL, IBINCTL_NRHJCTL | IBINCTL_NRMRCTL |
					     IBINCTL_NRSIRCTL);

	renesas_writel(i3c->regs, SCSTLCTL, 0);
	renesas_set_bit(i3c->regs, SCSTRCTL, SCSTRCTL_ACKTWE);

	/* Bus condition timing */
	val = DIV_ROUND_UP(I3C_BUS_TBUF_MIXED_FM_MIN_NS, NSEC_PER_SEC / rate);
	renesas_writel(i3c->regs, BFRECDT, BFRECDT_FRECYC(val));

	val = DIV_ROUND_UP(I3C_BUS_TAVAL_MIN_NS, NSEC_PER_SEC / rate);
	renesas_writel(i3c->regs, BAVLCDT, BAVLCDT_AVLCYC(val));

	val = DIV_ROUND_UP(I3C_BUS_TIDLE_MIN_NS, NSEC_PER_SEC / rate);
	renesas_writel(i3c->regs, BIDLCDT, BIDLCDT_IDLCYC(val));

	ret = i3c_master_get_free_addr(m, 0);
	if (ret < 0)
		return ret;

	renesas_writel(i3c->regs, MSDVAD, MSDVAD_MDYAD(ret) | MSDVAD_MDYADV);

	memset(&info, 0, sizeof(info));
	info.dyn_addr = ret;
	return i3c_master_set_info(&i3c->base, &info);
}

static void renesas_i3c_bus_cleanup(struct i3c_master_controller *m)
{
	struct renesas_i3c *i3c = to_renesas_i3c(m);

	renesas_i3c_reset(i3c);
}

static int renesas_i3c_daa(struct i3c_master_controller *m)
{
	struct renesas_i3c *i3c = to_renesas_i3c(m);
	struct renesas_i3c_cmd *cmd;
	u32 olddevs, newdevs;
	u8 last_addr = 0, pos;
	int ret;

	struct renesas_i3c_xfer *xfer __free(kfree) = renesas_i3c_alloc_xfer(i3c, 1);
	if (!xfer)
		return -ENOMEM;

	/* Enable I3C bus. */
	renesas_i3c_bus_enable(m, true);

	olddevs = ~(i3c->free_pos);
	i3c->internal_state = I3C_INTERNAL_STATE_CONTROLLER_ENTDAA;

	/* Setting DATBASn registers for target devices. */
	for (pos = 0; pos < i3c->maxdevs; pos++) {
		if (olddevs & BIT(pos))
			continue;

		ret = i3c_master_get_free_addr(m, last_addr + 1);
		if (ret < 0)
			return -ENOSPC;

		i3c->addrs[pos] = ret;
		last_addr = ret;

		renesas_writel(i3c->regs, DATBAS(pos), datbas_dvdyad_with_parity(ret));
	}

	init_completion(&xfer->comp);
	cmd = xfer->cmds;
	cmd->rx_count = 0;

	ret = renesas_i3c_get_free_pos(i3c);
	if (ret < 0)
		return ret;

	/*
	 * Setup the command descriptor to start the ENTDAA command
	 * and starting at the selected device index.
	 */
	cmd->cmd0 = NCMDQP_CMD_ATTR(NCMDQP_ADDR_ASSGN) | NCMDQP_ROC |
		    NCMDQP_TID(I3C_COMMAND_ADDRESS_ASSIGNMENT) |
		    NCMDQP_CMD(I3C_CCC_ENTDAA) | NCMDQP_DEV_INDEX(ret) |
		    NCMDQP_DEV_COUNT(i3c->maxdevs - ret) | NCMDQP_TOC;

	renesas_i3c_wait_xfer(i3c, xfer);

	newdevs = GENMASK(i3c->maxdevs - cmd->rx_count - 1, 0);
	newdevs &= ~olddevs;

	for (pos = 0; pos < i3c->maxdevs; pos++) {
		if (newdevs & BIT(pos))
			i3c_master_add_i3c_dev_locked(m, i3c->addrs[pos]);
	}

	return ret < 0 ? ret : 0;
}

static bool renesas_i3c_supports_ccc_cmd(struct i3c_master_controller *m,
						const struct i3c_ccc_cmd *cmd)
{
	if (cmd->ndests > 1)
		return false;

	switch (cmd->id) {
	case I3C_CCC_ENEC(true):
	case I3C_CCC_ENEC(false):
	case I3C_CCC_DISEC(true):
	case I3C_CCC_DISEC(false):
	case I3C_CCC_ENTAS(0, true):
	case I3C_CCC_ENTAS(1, true):
	case I3C_CCC_ENTAS(2, true):
	case I3C_CCC_ENTAS(3, true):
	case I3C_CCC_ENTAS(0, false):
	case I3C_CCC_ENTAS(1, false):
	case I3C_CCC_ENTAS(2, false):
	case I3C_CCC_ENTAS(3, false):
	case I3C_CCC_RSTDAA(true):
	case I3C_CCC_RSTDAA(false):
	case I3C_CCC_ENTDAA:
	case I3C_CCC_DEFSLVS:
	case I3C_CCC_SETMWL(true):
	case I3C_CCC_SETMWL(false):
	case I3C_CCC_SETMRL(true):
	case I3C_CCC_SETMRL(false):
	case I3C_CCC_ENTTM:
	case I3C_CCC_SETDASA:
	case I3C_CCC_SETNEWDA:
	case I3C_CCC_GETMWL:
	case I3C_CCC_GETMRL:
	case I3C_CCC_GETPID:
	case I3C_CCC_GETBCR:
	case I3C_CCC_GETDCR:
	case I3C_CCC_GETSTATUS:
	case I3C_CCC_GETACCMST:
	case I3C_CCC_GETMXDS:
		return true;
	default:
		return false;
	}
}

static int renesas_i3c_send_ccc_cmd(struct i3c_master_controller *m,
					   struct i3c_ccc_cmd *ccc)
{
	struct renesas_i3c *i3c = to_renesas_i3c(m);
	struct renesas_i3c_xfer *xfer;
	struct renesas_i3c_cmd *cmd;
	int ret, pos = 0;

	if (ccc->id & I3C_CCC_DIRECT) {
		pos = renesas_i3c_get_addr_pos(i3c, ccc->dests[0].addr);
		if (pos < 0)
			return pos;
	}

	xfer = renesas_i3c_alloc_xfer(i3c, 1);
	if (!xfer)
		return -ENOMEM;

	renesas_i3c_bus_enable(m, true);

	init_completion(&xfer->comp);
	cmd = xfer->cmds;
	cmd->rnw = ccc->rnw;
	cmd->cmd0 = 0;

	/* Calculate the command descriptor. */
	switch (ccc->id) {
	case I3C_CCC_SETDASA:
		renesas_writel(i3c->regs, DATBAS(pos),
			DATBAS_DVSTAD(ccc->dests[0].addr) |
			DATBAS_DVDYAD(*(u8 *)ccc->dests[0].payload.data >> 1));
		cmd->cmd0 = NCMDQP_CMD_ATTR(NCMDQP_ADDR_ASSGN) | NCMDQP_ROC |
			NCMDQP_TID(I3C_COMMAND_ADDRESS_ASSIGNMENT) |
			NCMDQP_CMD(I3C_CCC_SETDASA) | NCMDQP_DEV_INDEX(pos) |
			NCMDQP_DEV_COUNT(0) | NCMDQP_TOC;
		i3c->internal_state = I3C_INTERNAL_STATE_CONTROLLER_SETDASA;
		break;
	default:
		/* Calculate the command descriptor. */
		cmd->cmd0 = NCMDQP_TID(I3C_COMMAND_WRITE) | NCMDQP_MODE(0) |
				NCMDQP_RNW(ccc->rnw) | NCMDQP_CMD(ccc->id) |
				NCMDQP_ROC | NCMDQP_TOC | NCMDQP_CP |
				NCMDQP_DEV_INDEX(pos);

		if (ccc->rnw) {
			cmd->rx_buf = ccc->dests[0].payload.data;
			cmd->len = ccc->dests[0].payload.len;
			cmd->rx_count = 0;
			i3c->internal_state = I3C_INTERNAL_STATE_CONTROLLER_COMMAND_READ;
		} else {
			cmd->tx_buf = ccc->dests[0].payload.data;
			cmd->len = ccc->dests[0].payload.len;
			cmd->tx_count = 0;
			i3c->internal_state = I3C_INTERNAL_STATE_CONTROLLER_COMMAND_WRITE;
		}
	}

	renesas_i3c_wait_xfer(i3c, xfer);

	ret = xfer->ret;
	if (ret)
		ccc->err = I3C_ERROR_M2;

	kfree(xfer);

	return ret;
}

static int renesas_i3c_priv_xfers(struct i3c_dev_desc *dev, struct i3c_priv_xfer *i3c_xfers,
					 int i3c_nxfers)
{
	struct i3c_master_controller *m = i3c_dev_get_master(dev);
	struct renesas_i3c *i3c = to_renesas_i3c(m);
	struct renesas_i3c_i2c_dev_data *data = i3c_dev_get_master_data(dev);
	struct renesas_i3c_xfer *xfer;
	int i;

	/* Enable I3C bus. */
	renesas_i3c_bus_enable(m, true);

	xfer = renesas_i3c_alloc_xfer(i3c, 1);
	if (!xfer)
		return -ENOMEM;

	init_completion(&xfer->comp);

	for (i = 0; i < i3c_nxfers; i++) {
		struct renesas_i3c_cmd *cmd = xfer->cmds;

		/* Calculate the Transfer Command Descriptor */
		cmd->rnw = i3c_xfers[i].rnw;
		cmd->cmd0 = NCMDQP_DEV_INDEX(data->index) | NCMDQP_MODE(0) |
			    NCMDQP_RNW(cmd->rnw) | NCMDQP_ROC | NCMDQP_TOC;

		if (i3c_xfers[i].rnw) {
			cmd->rx_count = 0;
			cmd->cmd0 |= NCMDQP_TID(I3C_READ);
			cmd->rx_buf = i3c_xfers[i].data.in;
			cmd->len = i3c_xfers[i].len;
			i3c->internal_state = I3C_INTERNAL_STATE_CONTROLLER_READ;
		} else {
			cmd->tx_count = 0;
			cmd->cmd0 |= NCMDQP_TID(I3C_WRITE);
			cmd->tx_buf = i3c_xfers[i].data.out;
			cmd->len = i3c_xfers[i].len;
			i3c->internal_state = I3C_INTERNAL_STATE_CONTROLLER_WRITE;
		}

		if (!i3c_xfers[i].rnw && i3c_xfers[i].len > 4) {
			i3c_writel_fifo(i3c->regs + NTDTBP0, cmd->tx_buf, cmd->len);
			if (cmd->len > NTDTBP0_DEPTH * sizeof(u32))
				renesas_set_bit(i3c->regs, NTIE, NTIE_TDBEIE0);
		}

		renesas_i3c_wait_xfer(i3c, xfer);
	}

	return 0;
}

static int renesas_i3c_attach_i3c_dev(struct i3c_dev_desc *dev)
{
	struct i3c_master_controller *m = i3c_dev_get_master(dev);
	struct renesas_i3c *i3c = to_renesas_i3c(m);
	struct renesas_i3c_i2c_dev_data *data;
	int pos;

	pos = renesas_i3c_get_free_pos(i3c);
	if (pos < 0)
		return pos;

	data = kzalloc(sizeof(*data), GFP_KERNEL);
	if (!data)
		return -ENOMEM;

	data->index = pos;
	i3c->addrs[pos] = dev->info.dyn_addr ? : dev->info.static_addr;
	i3c->free_pos &= ~BIT(pos);

	renesas_writel(i3c->regs, DATBAS(pos), DATBAS_DVSTAD(dev->info.static_addr) |
				    datbas_dvdyad_with_parity(i3c->addrs[pos]));
	i3c_dev_set_master_data(dev, data);

	return 0;
}

static int renesas_i3c_reattach_i3c_dev(struct i3c_dev_desc *dev,
					       u8 old_dyn_addr)
{
	struct i3c_master_controller *m = i3c_dev_get_master(dev);
	struct renesas_i3c *i3c = to_renesas_i3c(m);
	struct renesas_i3c_i2c_dev_data *data = i3c_dev_get_master_data(dev);

	i3c->addrs[data->index] = dev->info.dyn_addr ? dev->info.dyn_addr :
							dev->info.static_addr;

	return 0;
}

static void renesas_i3c_detach_i3c_dev(struct i3c_dev_desc *dev)
{
	struct renesas_i3c_i2c_dev_data *data = i3c_dev_get_master_data(dev);
	struct i3c_master_controller *m = i3c_dev_get_master(dev);
	struct renesas_i3c *i3c = to_renesas_i3c(m);

	i3c_dev_set_master_data(dev, NULL);
	i3c->addrs[data->index] = 0;
	i3c->free_pos |= BIT(data->index);
	kfree(data);
}

static int renesas_i3c_i2c_xfers(struct i2c_dev_desc *dev,
					struct i2c_msg *i2c_xfers,
					int i2c_nxfers)
{
	struct i3c_master_controller *m = i2c_dev_get_master(dev);
	struct renesas_i3c *i3c = to_renesas_i3c(m);
	struct renesas_i3c_cmd *cmd;
	u8 start_bit = CNDCTL_STCND;
	int i;

	struct renesas_i3c_xfer *xfer __free(kfree) = renesas_i3c_alloc_xfer(i3c, 1);
	if (!xfer)
		return -ENOMEM;

	if (!i2c_nxfers)
		return 0;

	renesas_i3c_bus_enable(m, false);

	init_completion(&xfer->comp);
	xfer->is_i2c_xfer = true;
	cmd = xfer->cmds;

	if (!(renesas_readl(i3c->regs, BCST) & BCST_BFREF)) {
		cmd->err = -EBUSY;
		return cmd->err;
	}

	renesas_writel(i3c->regs, BST, 0);

	renesas_i3c_enqueue_xfer(i3c, xfer);

	for (i = 0; i < i2c_nxfers; i++) {
		cmd->i2c_bytes_left = I2C_INIT_MSG;
		cmd->i2c_buf = i2c_xfers[i].buf;
		cmd->msg = &i2c_xfers[i];
		cmd->i2c_is_last = (i == i2c_nxfers - 1);

		renesas_set_bit(i3c->regs, BIE, BIE_NACKDIE);
		renesas_set_bit(i3c->regs, NTIE, NTIE_TDBEIE0);
		renesas_set_bit(i3c->regs, BIE, BIE_STCNDDIE);

		/* Issue Start condition */
		renesas_set_bit(i3c->regs, CNDCTL, start_bit);

		renesas_set_bit(i3c->regs, NTSTE, NTSTE_TDBEE0);

		wait_for_completion_timeout(&xfer->comp, m->i2c.timeout);

		if (cmd->err)
			break;

		start_bit = CNDCTL_SRCND;
	}

	renesas_i3c_dequeue_xfer(i3c, xfer);
	return cmd->err;
}

static int renesas_i3c_attach_i2c_dev(struct i2c_dev_desc *dev)
{
	struct i3c_master_controller *m = i2c_dev_get_master(dev);
	struct renesas_i3c *i3c = to_renesas_i3c(m);
	struct renesas_i3c_i2c_dev_data *data;
	int pos;

	pos = renesas_i3c_get_free_pos(i3c);
	if (pos < 0)
		return pos;

	data = kzalloc(sizeof(*data), GFP_KERNEL);
	if (!data)
		return -ENOMEM;

	data->index = pos;
	i3c->addrs[pos] = dev->addr;
	i3c->free_pos &= ~BIT(pos);
	i2c_dev_set_master_data(dev, data);

	return 0;
}

static void renesas_i3c_detach_i2c_dev(struct i2c_dev_desc *dev)
{
	struct renesas_i3c_i2c_dev_data *data = i2c_dev_get_master_data(dev);
	struct i3c_master_controller *m = i2c_dev_get_master(dev);
	struct renesas_i3c *i3c = to_renesas_i3c(m);

	i2c_dev_set_master_data(dev, NULL);
	i3c->addrs[data->index] = 0;
	i3c->free_pos |= BIT(data->index);
	kfree(data);
}

static irqreturn_t renesas_i3c_tx_isr(int irq, void *data)
{
	struct renesas_i3c *i3c = data;
	struct renesas_i3c_xfer *xfer;
	struct renesas_i3c_cmd *cmd;
	u8 val;

	scoped_guard(spinlock, &i3c->xferqueue.lock) {
		xfer = i3c->xferqueue.cur;
		cmd = xfer->cmds;

		if (xfer->is_i2c_xfer) {
			if (!cmd->i2c_bytes_left)
				return IRQ_NONE;

			if (cmd->i2c_bytes_left != I2C_INIT_MSG) {
				val = *cmd->i2c_buf;
				cmd->i2c_buf++;
				cmd->i2c_bytes_left--;
				renesas_writel(i3c->regs, NTDTBP0, val);
			}

			if (cmd->i2c_bytes_left == 0) {
				renesas_clear_bit(i3c->regs, NTIE, NTIE_TDBEIE0);
				renesas_set_bit(i3c->regs, BIE, BIE_TENDIE);
			}

			/* Clear the Transmit Buffer Empty status flag. */
			renesas_clear_bit(i3c->regs, NTST, NTST_TDBEF0);
		} else {
			i3c_writel_fifo(i3c->regs + NTDTBP0, cmd->tx_buf, cmd->len);
		}
	}

	return IRQ_HANDLED;
}

static irqreturn_t renesas_i3c_resp_isr(int irq, void *data)
{
	struct renesas_i3c *i3c = data;
	struct renesas_i3c_xfer *xfer;
	struct renesas_i3c_cmd *cmd;
	u32 resp_descriptor = renesas_readl(i3c->regs, NRSPQP);
	u32 bytes_remaining = 0;
	u32 ntst, data_len;
	int ret = 0;

	scoped_guard(spinlock, &i3c->xferqueue.lock) {
		xfer = i3c->xferqueue.cur;
		cmd = xfer->cmds;

		/* Clear the Respone Queue Full status flag*/
		renesas_clear_bit(i3c->regs, NTST, NTST_RSPQFF);

		data_len = NRSPQP_DATA_LEN(resp_descriptor);

		switch (i3c->internal_state) {
		case I3C_INTERNAL_STATE_CONTROLLER_ENTDAA:
			cmd->rx_count = data_len;
			break;
		case I3C_INTERNAL_STATE_CONTROLLER_WRITE:
		case I3C_INTERNAL_STATE_CONTROLLER_COMMAND_WRITE:
			/* Disable the transmit IRQ if it hasn't been disabled already. */
			renesas_clear_bit(i3c->regs, NTIE, NTIE_TDBEIE0);
			break;
		case I3C_INTERNAL_STATE_CONTROLLER_READ:
		case I3C_INTERNAL_STATE_CONTROLLER_COMMAND_READ:
			if (NDBSTLV0_RDBLV(renesas_readl(i3c->regs, NDBSTLV0)) && !cmd->err)
				bytes_remaining = data_len - cmd->rx_count;

			i3c_readl_fifo(i3c->regs + NTDTBP0, cmd->rx_buf, bytes_remaining);
			renesas_clear_bit(i3c->regs, NTIE, NTIE_RDBFIE0);
			break;
		default:
			break;
		}

		switch (NRSPQP_ERR_STATUS(resp_descriptor)) {
		case NRSPQP_NO_ERROR:
			break;
		case NRSPQP_ERROR_PARITY:
		case NRSPQP_ERROR_IBA_NACK:
		case NRSPQP_ERROR_TRANSF_ABORT:
		case NRSPQP_ERROR_CRC:
		case NRSPQP_ERROR_FRAME:
			ret = -EIO;
			break;
		case NRSPQP_ERROR_OVER_UNDER_FLOW:
			ret = -ENOSPC;
			break;
		case NRSPQP_ERROR_UNSUPPORTED:
			ret = -EOPNOTSUPP;
			break;
		case NRSPQP_ERROR_I2C_W_NACK_ERR:
		case NRSPQP_ERROR_ADDRESS_NACK:
		default:
			ret = -EINVAL;
			break;
		}

		/*
		 * If the transfer was aborted, then the abort flag must be cleared
		 * before notifying the application that a transfer has completed.
		 */
		ntst = renesas_readl(i3c->regs, NTST);
		if (ntst & NTST_TABTF)
			renesas_clear_bit(i3c->regs, BCTL, BCTL_ABT);

		/* Clear error status flags. */
		renesas_clear_bit(i3c->regs, NTST, NTST_TEF | NTST_TABTF);

		xfer->ret = ret;
		complete(&xfer->comp);

		xfer = list_first_entry_or_null(&i3c->xferqueue.list,
						struct renesas_i3c_xfer, node);
		if (xfer)
			list_del_init(&xfer->node);

		i3c->xferqueue.cur = xfer;
	}

	return IRQ_HANDLED;
}

static irqreturn_t renesas_i3c_tend_isr(int irq, void *data)
{
	struct renesas_i3c *i3c = data;
	struct renesas_i3c_xfer *xfer;
	struct renesas_i3c_cmd *cmd;

	scoped_guard(spinlock, &i3c->xferqueue.lock) {
		xfer = i3c->xferqueue.cur;
		cmd = xfer->cmds;

		if (xfer->is_i2c_xfer) {
			if (renesas_readl(i3c->regs, BST) & BST_NACKDF) {
				/* We got a NACKIE */
				renesas_readl(i3c->regs, NTDTBP0); /* dummy read */
				renesas_clear_bit(i3c->regs, BST, BST_NACKDF);
				cmd->err = -ENXIO;
			} else if (cmd->i2c_bytes_left) {
				renesas_set_bit(i3c->regs, NTIE, NTIE_TDBEIE0);
				return IRQ_NONE;
			}

			if (cmd->i2c_is_last || cmd->err) {
				renesas_clear_bit(i3c->regs, BIE, BIE_TENDIE);
				renesas_set_bit(i3c->regs, BIE, BIE_SPCNDDIE);
				renesas_set_bit(i3c->regs, CNDCTL, CNDCTL_SPCND);
			} else {
				/* Transfer is complete, but do not send STOP */
				renesas_clear_bit(i3c->regs, NTSTE, NTSTE_TDBEE0);
				renesas_clear_bit(i3c->regs, BIE, BIE_TENDIE);
				xfer->ret = 0;
				complete(&xfer->comp);
			}
		}

		/* Clear the Transmit Buffer Empty status flag. */
		renesas_clear_bit(i3c->regs, BST, BST_TENDF);
	}

	return IRQ_HANDLED;
}

static irqreturn_t renesas_i3c_rx_isr(int irq, void *data)
{
	struct renesas_i3c *i3c = data;
	struct renesas_i3c_xfer *xfer;
	struct renesas_i3c_cmd *cmd;
	int read_bytes;

	/* If resp_isr already read the data and updated 'xfer', we can just leave */
	if (!(renesas_readl(i3c->regs, NTIE) & NTIE_RDBFIE0))
		return IRQ_NONE;

	scoped_guard(spinlock, &i3c->xferqueue.lock) {
		xfer = i3c->xferqueue.cur;
		cmd = xfer->cmds;

		if (xfer->is_i2c_xfer) {
			if (!cmd->i2c_bytes_left)
				return IRQ_NONE;

			if (cmd->i2c_bytes_left == I2C_INIT_MSG) {
				cmd->i2c_bytes_left = cmd->msg->len;
				renesas_set_bit(i3c->regs, SCSTRCTL, SCSTRCTL_RWE);
				renesas_readl(i3c->regs, NTDTBP0); /* dummy read */
				if (cmd->i2c_bytes_left == 1)
					renesas_writel(i3c->regs, ACKCTL, ACKCTL_ACKT | ACKCTL_ACKTWP);
				return IRQ_HANDLED;
			}

			if (cmd->i2c_bytes_left == 1) {
				/* STOP must come before we set ACKCTL! */
				if (cmd->i2c_is_last) {
					renesas_set_bit(i3c->regs, BIE, BIE_SPCNDDIE);
					renesas_clear_bit(i3c->regs, BST, BST_SPCNDDF);
					renesas_set_bit(i3c->regs, CNDCTL, CNDCTL_SPCND);
				}
				renesas_writel(i3c->regs, ACKCTL, ACKCTL_ACKT | ACKCTL_ACKTWP);
			} else {
				renesas_writel(i3c->regs, ACKCTL, ACKCTL_ACKTWP);
			}

			/* Reading acks the RIE interrupt */
			*cmd->i2c_buf = renesas_readl(i3c->regs, NTDTBP0);
			cmd->i2c_buf++;
			cmd->i2c_bytes_left--;
		} else {
			read_bytes = NDBSTLV0_RDBLV(renesas_readl(i3c->regs, NDBSTLV0)) * sizeof(u32);
			i3c_readl_fifo(i3c->regs + NTDTBP0, cmd->rx_buf, read_bytes);
			cmd->rx_count = read_bytes;
		}

		/* Clear the Read Buffer Full status flag. */
		renesas_clear_bit(i3c->regs, NTST, NTST_RDBFF0);
	}

	return IRQ_HANDLED;
}

static irqreturn_t renesas_i3c_stop_isr(int irq, void *data)
{
	struct renesas_i3c *i3c = data;
	struct renesas_i3c_xfer *xfer;

	scoped_guard(spinlock, &i3c->xferqueue.lock) {
		xfer = i3c->xferqueue.cur;

		/* read back registers to confirm writes have fully propagated */
		renesas_writel(i3c->regs, BST, 0);
		renesas_readl(i3c->regs, BST);
		renesas_writel(i3c->regs, BIE, 0);
		renesas_clear_bit(i3c->regs, NTST, NTST_TDBEF0 | NTST_RDBFF0);
		renesas_clear_bit(i3c->regs, SCSTRCTL, SCSTRCTL_RWE);

		xfer->ret = 0;
		complete(&xfer->comp);
	}

	return IRQ_HANDLED;
}

static irqreturn_t renesas_i3c_start_isr(int irq, void *data)
{
	struct renesas_i3c *i3c = data;
	struct renesas_i3c_xfer *xfer;
	struct renesas_i3c_cmd *cmd;
	u8 val;

	scoped_guard(spinlock, &i3c->xferqueue.lock) {
		xfer = i3c->xferqueue.cur;
		cmd = xfer->cmds;

		if (xfer->is_i2c_xfer) {
			if (!cmd->i2c_bytes_left)
				return IRQ_NONE;

			if (cmd->i2c_bytes_left == I2C_INIT_MSG) {
				if (cmd->msg->flags & I2C_M_RD) {
					/* On read, switch over to receive interrupt */
					renesas_clear_bit(i3c->regs, NTIE, NTIE_TDBEIE0);
					renesas_set_bit(i3c->regs, NTIE, NTIE_RDBFIE0);
				} else {
					/* On write, initialize length */
					cmd->i2c_bytes_left = cmd->msg->len;
				}

				val = i2c_8bit_addr_from_msg(cmd->msg);
				renesas_writel(i3c->regs, NTDTBP0, val);
			}
		}

		renesas_clear_bit(i3c->regs, BIE, BIE_STCNDDIE);
		renesas_clear_bit(i3c->regs, BST, BST_STCNDDF);
	}

	return IRQ_HANDLED;
}

static const struct i3c_master_controller_ops renesas_i3c_ops = {
	.bus_init = renesas_i3c_bus_init,
	.bus_cleanup = renesas_i3c_bus_cleanup,
	.attach_i3c_dev = renesas_i3c_attach_i3c_dev,
	.reattach_i3c_dev = renesas_i3c_reattach_i3c_dev,
	.detach_i3c_dev = renesas_i3c_detach_i3c_dev,
	.do_daa = renesas_i3c_daa,
	.supports_ccc_cmd = renesas_i3c_supports_ccc_cmd,
	.send_ccc_cmd = renesas_i3c_send_ccc_cmd,
	.priv_xfers = renesas_i3c_priv_xfers,
	.attach_i2c_dev = renesas_i3c_attach_i2c_dev,
	.detach_i2c_dev = renesas_i3c_detach_i2c_dev,
	.i2c_xfers = renesas_i3c_i2c_xfers,
};

static const struct renesas_i3c_irq_desc renesas_i3c_irqs[] = {
	{ .name = "resp", .isr = renesas_i3c_resp_isr, .desc = "i3c-resp" },
	{ .name = "rx", .isr = renesas_i3c_rx_isr, .desc = "i3c-rx" },
	{ .name = "tx", .isr = renesas_i3c_tx_isr, .desc = "i3c-tx" },
	{ .name = "st", .isr = renesas_i3c_start_isr, .desc = "i3c-start" },
	{ .name = "sp", .isr = renesas_i3c_stop_isr, .desc = "i3c-stop" },
	{ .name = "tend", .isr = renesas_i3c_tend_isr, .desc = "i3c-tend" },
	{ .name = "nack", .isr = renesas_i3c_tend_isr, .desc = "i3c-nack" },
};

static int renesas_i3c_probe(struct platform_device *pdev)
{
	struct renesas_i3c *i3c;
	struct reset_control *reset;
	struct clk *clk;
	const struct renesas_i3c_config *config = of_device_get_match_data(&pdev->dev);
	int ret, i;

	if (!config)
		return -ENODATA;

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

	i3c->regs = devm_platform_ioremap_resource(pdev, 0);
	if (IS_ERR(i3c->regs))
		return PTR_ERR(i3c->regs);

	clk = devm_clk_get_enabled(&pdev->dev, "pclk");
	if (IS_ERR(clk))
		return PTR_ERR(clk);

	if (config->has_pclkrw) {
		clk = devm_clk_get_enabled(&pdev->dev, "pclkrw");
		if (IS_ERR(clk))
			return PTR_ERR(clk);
	}

	i3c->tclk = devm_clk_get_enabled(&pdev->dev, "tclk");
	if (IS_ERR(i3c->tclk))
		return PTR_ERR(i3c->tclk);

	reset = devm_reset_control_get_optional_exclusive_deasserted(&pdev->dev, "tresetn");
	if (IS_ERR(reset))
		return dev_err_probe(&pdev->dev, PTR_ERR(reset),
				     "Error: missing tresetn ctrl\n");

	reset = devm_reset_control_get_optional_exclusive_deasserted(&pdev->dev, "presetn");
	if (IS_ERR(reset))
		return dev_err_probe(&pdev->dev, PTR_ERR(reset),
				     "Error: missing presetn ctrl\n");

	spin_lock_init(&i3c->xferqueue.lock);
	INIT_LIST_HEAD(&i3c->xferqueue.list);

	ret = renesas_i3c_reset(i3c);
	if (ret)
		return ret;

	for (i = 0; i < ARRAY_SIZE(renesas_i3c_irqs); i++) {
		ret = platform_get_irq_byname(pdev, renesas_i3c_irqs[i].name);
		if (ret < 0)
			return ret;

		ret = devm_request_irq(&pdev->dev, ret, renesas_i3c_irqs[i].isr,
				       0, renesas_i3c_irqs[i].desc, i3c);
		if (ret)
			return ret;
	}

	platform_set_drvdata(pdev, i3c);

	i3c->maxdevs = RENESAS_I3C_MAX_DEVS;
	i3c->free_pos = GENMASK(i3c->maxdevs - 1, 0);

	return i3c_master_register(&i3c->base, &pdev->dev, &renesas_i3c_ops, false);
}

static void renesas_i3c_remove(struct platform_device *pdev)
{
	struct renesas_i3c *i3c = platform_get_drvdata(pdev);

	i3c_master_unregister(&i3c->base);
}

static const struct renesas_i3c_config empty_i3c_config = {
};

static const struct renesas_i3c_config r9a09g047_i3c_config = {
	.has_pclkrw = 1,
};

static const struct of_device_id renesas_i3c_of_ids[] = {
	{ .compatible = "renesas,r9a08g045-i3c", .data = &empty_i3c_config },
	{ .compatible = "renesas,r9a09g047-i3c", .data = &r9a09g047_i3c_config },
	{ /* sentinel */ },
};
MODULE_DEVICE_TABLE(of, renesas_i3c_of_ids);

static struct platform_driver renesas_i3c = {
	.probe = renesas_i3c_probe,
	.remove = renesas_i3c_remove,
	.driver = {
		.name = "renesas-i3c",
		.of_match_table = renesas_i3c_of_ids,
	},
};
module_platform_driver(renesas_i3c);

MODULE_AUTHOR("Wolfram Sang <wsa+renesas@sang-engineering.com>");
MODULE_AUTHOR("Renesas BSP teams");
MODULE_DESCRIPTION("Renesas I3C controller driver");
MODULE_LICENSE("GPL");
