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

Frank Li
2025-12-19T16:36:35Z

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@intel.com>
> ---

Reviewed-by: Frank Li <Frank.Li@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@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-i3c