[PATCH 08/17] i3c: mipi-i3c-hci: Cache DAT in memory for Runtime PM restore

Frank Li Frank.li at nxp.com
Fri Dec 19 08:36:19 PST 2025


On Fri, Dec 19, 2025 at 04:45:25PM +0200, Adrian Hunter wrote:
> Prepare for Runtime PM support, which requires restoring the Device Address
> Table (DAT) registers after resume.  Maintain a copy of DAT in memory so it
> can be reprogrammed when the controller is powered back up.
>
> Signed-off-by: Adrian Hunter <adrian.hunter at intel.com>
> ---

Reviewed-by: Frank Li <Frank.Li at nxp.com>

>  drivers/i3c/master/mipi-i3c-hci/dat_v1.c | 29 +++++++++++++++++++-----
>  drivers/i3c/master/mipi-i3c-hci/hci.h    |  6 +++++
>  2 files changed, 29 insertions(+), 6 deletions(-)
>
> diff --git a/drivers/i3c/master/mipi-i3c-hci/dat_v1.c b/drivers/i3c/master/mipi-i3c-hci/dat_v1.c
> index c60ef5d77ca3..644ab939be1c 100644
> --- a/drivers/i3c/master/mipi-i3c-hci/dat_v1.c
> +++ b/drivers/i3c/master/mipi-i3c-hci/dat_v1.c
> @@ -34,13 +34,26 @@
>  /*	DAT_0_IBI_PAYLOAD		W0_BIT_(12) */
>  #define DAT_0_STATIC_ADDRESS		W0_MASK(6, 0)
>
> -#define dat_w0_read(i)		readl(hci->DAT_regs + (i) * 8)
> -#define dat_w1_read(i)		readl(hci->DAT_regs + (i) * 8 + 4)
> -#define dat_w0_write(i, v)	writel(v, hci->DAT_regs + (i) * 8)
> -#define dat_w1_write(i, v)	writel(v, hci->DAT_regs + (i) * 8 + 4)
> +#define dat_w0_read(i)		hci->DAT[i].w0
> +#define dat_w1_read(i)		hci->DAT[i].w1
> +#define dat_w0_write(i, v)	hci_dat_w0_write(hci, i, v)
> +#define dat_w1_write(i, v)	hci_dat_w1_write(hci, i, v)
> +
> +static inline void hci_dat_w0_write(struct i3c_hci *hci, int i, u32 v)
> +{
> +	hci->DAT[i].w0 = v;
> +	writel(v, hci->DAT_regs + i * 8);
> +}
> +
> +static inline void hci_dat_w1_write(struct i3c_hci *hci, int i, u32 v)
> +{
> +	hci->DAT[i].w1 = v;
> +	writel(v, hci->DAT_regs + i * 8 + 4);
> +}
>
>  static int hci_dat_v1_init(struct i3c_hci *hci)
>  {
> +	struct device *dev = hci->master.dev.parent;
>  	unsigned int dat_idx;
>
>  	if (!hci->DAT_regs) {
> @@ -54,9 +67,13 @@ static int hci_dat_v1_init(struct i3c_hci *hci)
>  		return -EOPNOTSUPP;
>  	}
>
> -	if (!hci->DAT_data) {
> -		struct device *dev = hci->master.dev.parent;
> +	if (!hci->DAT) {
> +		hci->DAT = devm_kcalloc(dev, hci->DAT_entries, hci->DAT_entry_size, GFP_KERNEL);
> +		if (!hci->DAT)
> +			return -ENOMEM;
> +	}
>
> +	if (!hci->DAT_data) {
>  		/* use a bitmap for faster free slot search */
>  		hci->DAT_data = devm_bitmap_zalloc(dev, hci->DAT_entries, GFP_KERNEL);
>  		if (!hci->DAT_data)
> diff --git a/drivers/i3c/master/mipi-i3c-hci/hci.h b/drivers/i3c/master/mipi-i3c-hci/hci.h
> index fd08b701d094..aa8a03594e64 100644
> --- a/drivers/i3c/master/mipi-i3c-hci/hci.h
> +++ b/drivers/i3c/master/mipi-i3c-hci/hci.h
> @@ -31,6 +31,11 @@
>
>  struct hci_cmd_ops;
>
> +struct dat_words {
> +	u32 w0;
> +	u32 w1;
> +};
> +
>  /* Our main structure */
>  struct i3c_hci {
>  	struct i3c_master_controller master;
> @@ -51,6 +56,7 @@ struct i3c_hci {
>  	unsigned int DAT_entries;
>  	unsigned int DAT_entry_size;
>  	void *DAT_data;
> +	struct dat_words *DAT;
>  	unsigned int DCT_entries;
>  	unsigned int DCT_entry_size;
>  	u8 version_major;
> --
> 2.51.0
>
>
> --
> linux-i3c mailing list
> linux-i3c at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-i3c



More information about the linux-i3c mailing list