diff mbox series

[RFC,5/8] lib: add small API for handling register snapshots

Message ID 20210529002508.3839467-6-dmitry.baryshkov@linaro.org
State New
Headers show
Series drm/msm: split DSI PHY to generic PHY subsystem | expand

Commit Message

Dmitry Baryshkov May 29, 2021, 12:25 a.m. UTC
Add small API covering lists of register dumps. Currently this is a part
of MSM DRM driver, but is extracted as it might be usefull to other
drivers too.

Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>

---
 include/linux/dump_state.h | 78 ++++++++++++++++++++++++++++++++++++++
 lib/Kconfig                |  3 ++
 lib/Makefile               |  1 +
 lib/dump_state.c           | 51 +++++++++++++++++++++++++
 4 files changed, 133 insertions(+)
 create mode 100644 include/linux/dump_state.h
 create mode 100644 lib/dump_state.c

-- 
2.30.2

Comments

Rob Clark June 3, 2021, 2:45 p.m. UTC | #1
On Fri, May 28, 2021 at 5:25 PM Dmitry Baryshkov
<dmitry.baryshkov@linaro.org> wrote:
>
> Add small API covering lists of register dumps. Currently this is a part
> of MSM DRM driver, but is extracted as it might be usefull to other
> drivers too.
>
> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
> ---
>  include/linux/dump_state.h | 78 ++++++++++++++++++++++++++++++++++++++
>  lib/Kconfig                |  3 ++
>  lib/Makefile               |  1 +
>  lib/dump_state.c           | 51 +++++++++++++++++++++++++
>  4 files changed, 133 insertions(+)
>  create mode 100644 include/linux/dump_state.h
>  create mode 100644 lib/dump_state.c
>
[snip]
> diff --git a/lib/dump_state.c b/lib/dump_state.c
> new file mode 100644
> index 000000000000..58d88be65c0a
> --- /dev/null
> +++ b/lib/dump_state.c
> @@ -0,0 +1,51 @@
> +/* SPDX-License-Identifier: GPL-2.0-only */
> +/*
> + * Copyright (c) 2020-2021, The Linux Foundation. All rights reserved.
> + * Copyright (c) 2021, Linaro Ltd
> + */
> +
> +#include <linux/dump_state.h>
> +#include <linux/slab.h>
> +
> +void dump_state_free_blocks(struct dump_state *state)
> +{
> +       struct dump_state_block *block, *tmp;
> +
> +       list_for_each_entry_safe(block, tmp, &state->blocks, node) {
> +               list_del(&block->node);
> +               kfree(block);
> +       }
> +}
> +EXPORT_SYMBOL(dump_state_free_blocks);

nit, perhaps EXPORT_SYMBOL_GPL()?

BR,
-R

> +
> +struct dump_state_block *dump_state_allocate_block_va(void __iomem *base_addr, size_t len, gfp_t gfp, const char *fmt, va_list args)
> +{
> +       struct dump_state_block *block = kzalloc(sizeof(*block) + len, gfp);
> +
> +       if (!block)
> +               return ERR_PTR(-ENOMEM);
> +
> +       vsnprintf(block->name, sizeof(block->name), fmt, args);
> +
> +       INIT_LIST_HEAD(&block->node);
> +       block->size = len;
> +       block->base_addr = base_addr;
> +
> +       return block;
> +}
> +EXPORT_SYMBOL(dump_state_allocate_block);
> +
> +struct dump_state_block *dump_state_allocate_block(void __iomem *base_addr, size_t len, gfp_t gfp, const char *fmt, ...)
> +{
> +       struct dump_state_block *block;
> +       va_list va;
> +
> +       va_start(va, fmt);
> +
> +       block = dump_state_allocate_block_va(base_addr, len, gfp, fmt, va);
> +
> +       va_end(va);
> +
> +       return block;
> +}
> +EXPORT_SYMBOL(dump_state_allocate_block_va);
> --
> 2.30.2
>
Dmitry Baryshkov June 3, 2021, 4:33 p.m. UTC | #2
On Thu, 3 Jun 2021 at 17:41, Rob Clark <robdclark@gmail.com> wrote:
>
> On Fri, May 28, 2021 at 5:25 PM Dmitry Baryshkov
> <dmitry.baryshkov@linaro.org> wrote:
> >
> > Add small API covering lists of register dumps. Currently this is a part
> > of MSM DRM driver, but is extracted as it might be usefull to other
> > drivers too.
> >
> > Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
> > ---
> >  include/linux/dump_state.h | 78 ++++++++++++++++++++++++++++++++++++++
> >  lib/Kconfig                |  3 ++
> >  lib/Makefile               |  1 +
> >  lib/dump_state.c           | 51 +++++++++++++++++++++++++
> >  4 files changed, 133 insertions(+)
> >  create mode 100644 include/linux/dump_state.h
> >  create mode 100644 lib/dump_state.c
> >
> [snip]
> > diff --git a/lib/dump_state.c b/lib/dump_state.c
> > new file mode 100644
> > index 000000000000..58d88be65c0a
> > --- /dev/null
> > +++ b/lib/dump_state.c
> > @@ -0,0 +1,51 @@
> > +/* SPDX-License-Identifier: GPL-2.0-only */
> > +/*
> > + * Copyright (c) 2020-2021, The Linux Foundation. All rights reserved.
> > + * Copyright (c) 2021, Linaro Ltd
> > + */
> > +
> > +#include <linux/dump_state.h>
> > +#include <linux/slab.h>
> > +
> > +void dump_state_free_blocks(struct dump_state *state)
> > +{
> > +       struct dump_state_block *block, *tmp;
> > +
> > +       list_for_each_entry_safe(block, tmp, &state->blocks, node) {
> > +               list_del(&block->node);
> > +               kfree(block);
> > +       }
> > +}
> > +EXPORT_SYMBOL(dump_state_free_blocks);
>
> nit, perhaps EXPORT_SYMBOL_GPL()?

I don't really care. What is the current recommendation?

>
> BR,
> -R
>
> > +
> > +struct dump_state_block *dump_state_allocate_block_va(void __iomem *base_addr, size_t len, gfp_t gfp, const char *fmt, va_list args)
> > +{
> > +       struct dump_state_block *block = kzalloc(sizeof(*block) + len, gfp);
> > +
> > +       if (!block)
> > +               return ERR_PTR(-ENOMEM);
> > +
> > +       vsnprintf(block->name, sizeof(block->name), fmt, args);
> > +
> > +       INIT_LIST_HEAD(&block->node);
> > +       block->size = len;
> > +       block->base_addr = base_addr;
> > +
> > +       return block;
> > +}
> > +EXPORT_SYMBOL(dump_state_allocate_block);
> > +
> > +struct dump_state_block *dump_state_allocate_block(void __iomem *base_addr, size_t len, gfp_t gfp, const char *fmt, ...)
> > +{
> > +       struct dump_state_block *block;
> > +       va_list va;
> > +
> > +       va_start(va, fmt);
> > +
> > +       block = dump_state_allocate_block_va(base_addr, len, gfp, fmt, va);
> > +
> > +       va_end(va);
> > +
> > +       return block;
> > +}
> > +EXPORT_SYMBOL(dump_state_allocate_block_va);
> > --
> > 2.30.2
> >
Rob Clark June 8, 2021, 5:04 p.m. UTC | #3
On Thu, Jun 3, 2021 at 9:33 AM Dmitry Baryshkov
<dmitry.baryshkov@linaro.org> wrote:
>
> On Thu, 3 Jun 2021 at 17:41, Rob Clark <robdclark@gmail.com> wrote:
> >
> > On Fri, May 28, 2021 at 5:25 PM Dmitry Baryshkov
> > <dmitry.baryshkov@linaro.org> wrote:
> > >
> > > Add small API covering lists of register dumps. Currently this is a part
> > > of MSM DRM driver, but is extracted as it might be usefull to other
> > > drivers too.
> > >
> > > Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
> > > ---
> > >  include/linux/dump_state.h | 78 ++++++++++++++++++++++++++++++++++++++
> > >  lib/Kconfig                |  3 ++
> > >  lib/Makefile               |  1 +
> > >  lib/dump_state.c           | 51 +++++++++++++++++++++++++
> > >  4 files changed, 133 insertions(+)
> > >  create mode 100644 include/linux/dump_state.h
> > >  create mode 100644 lib/dump_state.c
> > >
> > [snip]
> > > diff --git a/lib/dump_state.c b/lib/dump_state.c
> > > new file mode 100644
> > > index 000000000000..58d88be65c0a
> > > --- /dev/null
> > > +++ b/lib/dump_state.c
> > > @@ -0,0 +1,51 @@
> > > +/* SPDX-License-Identifier: GPL-2.0-only */
> > > +/*
> > > + * Copyright (c) 2020-2021, The Linux Foundation. All rights reserved.
> > > + * Copyright (c) 2021, Linaro Ltd
> > > + */
> > > +
> > > +#include <linux/dump_state.h>
> > > +#include <linux/slab.h>
> > > +
> > > +void dump_state_free_blocks(struct dump_state *state)
> > > +{
> > > +       struct dump_state_block *block, *tmp;
> > > +
> > > +       list_for_each_entry_safe(block, tmp, &state->blocks, node) {
> > > +               list_del(&block->node);
> > > +               kfree(block);
> > > +       }
> > > +}
> > > +EXPORT_SYMBOL(dump_state_free_blocks);
> >
> > nit, perhaps EXPORT_SYMBOL_GPL()?
>
> I don't really care. What is the current recommendation?

AFAIU it is to default to EXPORT_SYMBOL_GPL() unless there is a good reason..

BR,
-R

> >
> > BR,
> > -R
> >
> > > +
> > > +struct dump_state_block *dump_state_allocate_block_va(void __iomem *base_addr, size_t len, gfp_t gfp, const char *fmt, va_list args)
> > > +{
> > > +       struct dump_state_block *block = kzalloc(sizeof(*block) + len, gfp);
> > > +
> > > +       if (!block)
> > > +               return ERR_PTR(-ENOMEM);
> > > +
> > > +       vsnprintf(block->name, sizeof(block->name), fmt, args);
> > > +
> > > +       INIT_LIST_HEAD(&block->node);
> > > +       block->size = len;
> > > +       block->base_addr = base_addr;
> > > +
> > > +       return block;
> > > +}
> > > +EXPORT_SYMBOL(dump_state_allocate_block);
> > > +
> > > +struct dump_state_block *dump_state_allocate_block(void __iomem *base_addr, size_t len, gfp_t gfp, const char *fmt, ...)
> > > +{
> > > +       struct dump_state_block *block;
> > > +       va_list va;
> > > +
> > > +       va_start(va, fmt);
> > > +
> > > +       block = dump_state_allocate_block_va(base_addr, len, gfp, fmt, va);
> > > +
> > > +       va_end(va);
> > > +
> > > +       return block;
> > > +}
> > > +EXPORT_SYMBOL(dump_state_allocate_block_va);
> > > --
> > > 2.30.2
> > >
>
>
>
> --
> With best wishes
> Dmitry
diff mbox series

Patch

diff --git a/include/linux/dump_state.h b/include/linux/dump_state.h
new file mode 100644
index 000000000000..9cf2cd2e99a6
--- /dev/null
+++ b/include/linux/dump_state.h
@@ -0,0 +1,78 @@ 
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2020-2021, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2021, Linaro Ltd
+ */
+
+#ifndef LINUX_DUMP_STATE_H
+#define LINUX_DUMP_STATE_H
+
+#include <linux/list.h>
+#include <linux/sizes.h>
+
+/**
+ * struct dump_state_block - structure to store each hardware block state
+ * @name: name of the block
+ * @drm_dev: handle to the linked list head
+ * @size: size of the register space of this hardware block
+ * @state: array holding the register dump of this hardware block
+ * @base_addr: starting address of this hardware block's register space
+ */
+struct dump_state_block {
+	char name[SZ_128];
+	struct list_head node;
+	void __iomem *base_addr;
+	size_t size;
+	u8 state[0] __aligned(8);
+};
+
+/**
+ * struct dump_state - structure to store reg dump state
+ * @blocks: hardware blocks info related to this dump state
+ */
+struct dump_state {
+	struct list_head blocks;
+};
+
+static inline void dump_state_init(struct dump_state *state)
+{
+	INIT_LIST_HEAD(&state->blocks);
+}
+
+#define dump_state_for_each_block(state, block) \
+	list_for_each_entry(block, &(state)->blocks, node)
+
+/**
+ * dump_state_free_blocks - free allocated blocks
+ * @state:	    handle to struct dump_state
+ */
+void dump_state_free_blocks(struct dump_state *state);
+
+/**
+ * dump_state_allocate_block - allocate data block for register dumps
+ * @len:            size of the register space of the hardware block
+ * @base_addr:      starting address of the register space of the hardware block
+ * @gfp:            type of memory allocation
+ * @fmt:            format in which the block names need to be printed
+ *
+ * Returns: new block
+ */
+extern __printf(4, 5)
+struct dump_state_block *dump_state_allocate_block(void __iomem *base_addr, size_t len, gfp_t gfp, const char *fmt, ...);
+
+/**
+ * dump_state_allocate_block_va - allocate data block for register dumps
+ * @len:            size of the register space of the hardware block
+ * @base_addr:      starting address of the register space of the hardware block
+ * @gfp:            type of memory allocation
+ * @fmt:            format in which the block names need to be printed
+ *
+ * Returns: new block
+ */
+extern __printf(4, 0)
+struct dump_state_block *dump_state_allocate_block_va(void __iomem *base_addr, size_t len, gfp_t gfp, const char *fmt, va_list args);
+
+#define dump_state_add_block(state, block) \
+	list_add_tail(&(state)->blocks, &(block)->node)
+
+#endif
diff --git a/lib/Kconfig b/lib/Kconfig
index ac3b30697b2b..ab654232ecb6 100644
--- a/lib/Kconfig
+++ b/lib/Kconfig
@@ -704,3 +704,6 @@  config PLDMFW
 
 config ASN1_ENCODER
        tristate
+
+config DUMP_STATE
+	tristate
diff --git a/lib/Makefile b/lib/Makefile
index 2cc359ec1fdd..4836a0e3aef2 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -356,3 +356,4 @@  obj-$(CONFIG_BITS_TEST) += test_bits.o
 obj-$(CONFIG_CMDLINE_KUNIT_TEST) += cmdline_kunit.o
 
 obj-$(CONFIG_GENERIC_LIB_DEVMEM_IS_ALLOWED) += devmem_is_allowed.o
+obj-$(CONFIG_DUMP_STATE) += dump_state.o
diff --git a/lib/dump_state.c b/lib/dump_state.c
new file mode 100644
index 000000000000..58d88be65c0a
--- /dev/null
+++ b/lib/dump_state.c
@@ -0,0 +1,51 @@ 
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2020-2021, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2021, Linaro Ltd
+ */
+
+#include <linux/dump_state.h>
+#include <linux/slab.h>
+
+void dump_state_free_blocks(struct dump_state *state)
+{
+	struct dump_state_block *block, *tmp;
+
+	list_for_each_entry_safe(block, tmp, &state->blocks, node) {
+		list_del(&block->node);
+		kfree(block);
+	}
+}
+EXPORT_SYMBOL(dump_state_free_blocks);
+
+struct dump_state_block *dump_state_allocate_block_va(void __iomem *base_addr, size_t len, gfp_t gfp, const char *fmt, va_list args)
+{
+	struct dump_state_block *block = kzalloc(sizeof(*block) + len, gfp);
+
+	if (!block)
+		return ERR_PTR(-ENOMEM);
+
+	vsnprintf(block->name, sizeof(block->name), fmt, args);
+
+	INIT_LIST_HEAD(&block->node);
+	block->size = len;
+	block->base_addr = base_addr;
+
+	return block;
+}
+EXPORT_SYMBOL(dump_state_allocate_block);
+
+struct dump_state_block *dump_state_allocate_block(void __iomem *base_addr, size_t len, gfp_t gfp, const char *fmt, ...)
+{
+	struct dump_state_block *block;
+	va_list va;
+
+	va_start(va, fmt);
+
+	block = dump_state_allocate_block_va(base_addr, len, gfp, fmt, va);
+
+	va_end(va);
+
+	return block;
+}
+EXPORT_SYMBOL(dump_state_allocate_block_va);