2020-02-27 23:33:39

by Kammela, Gayatri

[permalink] [raw]
Subject: [PATCH v2 0/4] platform/x86: intel_pmc_core: Add bug fixes or code

Hi,

This patch series consists of bug fixes and code optimization for the
series https://patchwork.kernel.org/patch/11365325/

Patch 1: Relocate both pmc_core_slps0_display() and pmc_core_lpm_display()
Patch 2: Make pmc_core_lpm_display() generic
Patch 3: Remove the duplicate if() condition to create debugfs entry
Patch 4: Add back slp_s0_offset attribute back to tgl_reg_map

Changes since v1:
1) Changed the order of the patches i.e., patch 2 in v1 is made first in
the order for v2.
2) Fixed the warnings reported by kbuild test robot.

Gayatri Kammela (4):
platform/x86: intel_pmc_core: fix: Relocate pmc_core_slps0_display()
and pmc_core_lpm_display() to outside of CONFIG_DEBUG_FS
platform/x86: intel_pmc_core: fix: Make pmc_core_lpm_display() generic
for platforms that support sub-states
platform/x86: intel_pmc_core: fix: Remove the duplicate if() to create
debugfs entry for substate_live_status_registers
platform/x86: intel_pmc_core: fix: Add slp_s0_offset attribute back to
tgl_reg_map

drivers/platform/x86/intel_pmc_core.c | 140 ++++++++++++++------------
1 file changed, 75 insertions(+), 65 deletions(-)

base-commit: 7adb1e8aeeb5d4d88012568b2049599c1a247cf2

Cc: Chen Zhou <[email protected]>
Cc: Andy Shevchenko <[email protected]>
Cc: David Box <[email protected]>
--
2.17.1


2020-02-27 23:33:51

by Kammela, Gayatri

[permalink] [raw]
Subject: [PATCH v2 4/4] platform/x86: intel_pmc_core: fix: Add slp_s0_offset attribute back to tgl_reg_map

If platforms such as Tiger Lake has sub-states of S0ix, then attributes
such as slps0_dbg_offset become invalid. But slp_s0_offset is still
valid as it is used to get the pmcdev_base_addr.

Hence, add back slp_s0_offset and remove slps0_dbg_offset attributes.

Cc: Chen Zhou <[email protected]>
Cc: Andy Shevchenko <[email protected]>
Cc: David E. Box <[email protected]>
Signed-off-by: Gayatri Kammela <[email protected]>
---
drivers/platform/x86/intel_pmc_core.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/platform/x86/intel_pmc_core.c b/drivers/platform/x86/intel_pmc_core.c
index f6cc80987257..364a3c4e1c89 100644
--- a/drivers/platform/x86/intel_pmc_core.c
+++ b/drivers/platform/x86/intel_pmc_core.c
@@ -557,9 +557,9 @@ static const struct pmc_bit_map *tgl_lpm_maps[] = {

static const struct pmc_reg_map tgl_reg_map = {
.pfear_sts = ext_tgl_pfear_map,
+ .slp_s0_offset = CNP_PMC_SLP_S0_RES_COUNTER_OFFSET,
.ltr_show_sts = cnp_ltr_show_map,
.msr_sts = msr_map,
- .slps0_dbg_offset = CNP_PMC_SLPS0_DBG_OFFSET,
.ltr_ignore_offset = CNP_PMC_LTR_IGNORE_OFFSET,
.regmap_length = CNP_PMC_MMIO_REG_LEN,
.ppfear0_offset = CNP_PMC_HOST_PPFEAR0A,
--
2.17.1

2020-02-27 23:34:13

by Kammela, Gayatri

[permalink] [raw]
Subject: [PATCH v2 2/4] platform/x86: intel_pmc_core: fix: Make pmc_core_lpm_display() generic for platforms that support sub-states

Currently pmc_core_lpm_display() uses array of struct pointers i.e.,
tgl_lpm_maps for Tiger Lake directly to iterate through and to get the
number of status/live status registers which is hardcoded and cannot
be re-used for future platforms that support sub-states. To maintain
readability, make pmc_core_lpm_display() generic, so that it can re-used
for future platforms.

Cc: Chen Zhou <[email protected]>
Cc: Andy Shevchenko <[email protected]>
Cc: David E. Box <[email protected]>
Suggested-by: Andy Shevchenko <[email protected]>
Signed-off-by: Gayatri Kammela <[email protected]>
---
drivers/platform/x86/intel_pmc_core.c | 19 ++++++++++++++++---
1 file changed, 16 insertions(+), 3 deletions(-)

diff --git a/drivers/platform/x86/intel_pmc_core.c b/drivers/platform/x86/intel_pmc_core.c
index 20b2f49726cf..3f000b6c8d8e 100644
--- a/drivers/platform/x86/intel_pmc_core.c
+++ b/drivers/platform/x86/intel_pmc_core.c
@@ -20,6 +20,7 @@
#include <linux/module.h>
#include <linux/pci.h>
#include <linux/platform_device.h>
+#include <linux/slab.h>
#include <linux/suspend.h>
#include <linux/uaccess.h>

@@ -639,15 +640,27 @@ static void pmc_core_slps0_display(struct pmc_dev *pmcdev, struct device *dev,
}
}

+static int pmc_core_lpm_get_arr_size(const struct pmc_bit_map **maps)
+{
+ int idx, arr_size = 0;
+
+ for (idx = 0; maps[idx]; idx++)
+ arr_size++;
+
+ return arr_size;
+}
+
static void pmc_core_lpm_display(struct pmc_dev *pmcdev, struct device *dev,
struct seq_file *s, u32 offset,
const char *str,
const struct pmc_bit_map **maps)
{
- u32 lpm_regs[ARRAY_SIZE(tgl_lpm_maps)-1];
- int index, idx, len = 32, bit_mask;
+ int arr_size = pmc_core_lpm_get_arr_size(maps);
+ int index, idx, bit_mask, len = 32;
+ u32 *lpm_regs;

- for (index = 0; tgl_lpm_maps[index]; index++) {
+ lpm_regs = kmalloc_array(arr_size, sizeof(*lpm_regs), GFP_KERNEL);
+ for (index = 0; maps[index]; index++) {
lpm_regs[index] = pmc_core_reg_read(pmcdev, offset);
offset += 4;
}
--
2.17.1

2020-02-27 23:35:06

by Kammela, Gayatri

[permalink] [raw]
Subject: [PATCH v2 1/4] platform/x86: intel_pmc_core: fix: Relocate pmc_core_slps0_display() and pmc_core_lpm_display() to outside of CONFIG_DEBUG_FS

Since pmc_core_slps0_display() and pmc_core_lpm_display() is responsible
for dumping as well as displaying debug registers, there is no need for
these two functions to be defined under CONFIG_DEBUG_FS.

Hence, relocate these functions from under CONFIG_DEBUG_FS to above the
block.

Cc: Chen Zhou <[email protected]>
Cc: Andy Shevchenko <[email protected]>
Cc: David E. Box <[email protected]>
Signed-off-by: Gayatri Kammela <[email protected]>
---
drivers/platform/x86/intel_pmc_core.c | 122 +++++++++++++-------------
1 file changed, 61 insertions(+), 61 deletions(-)

diff --git a/drivers/platform/x86/intel_pmc_core.c b/drivers/platform/x86/intel_pmc_core.c
index f4a36fbabf4c..20b2f49726cf 100644
--- a/drivers/platform/x86/intel_pmc_core.c
+++ b/drivers/platform/x86/intel_pmc_core.c
@@ -612,6 +612,67 @@ static int pmc_core_check_read_lock_bit(void)
return value & BIT(pmcdev->map->pm_read_disable_bit);
}

+static void pmc_core_slps0_display(struct pmc_dev *pmcdev, struct device *dev,
+ struct seq_file *s)
+{
+ const struct pmc_bit_map **maps = pmcdev->map->slps0_dbg_maps;
+ const struct pmc_bit_map *map;
+ int offset = pmcdev->map->slps0_dbg_offset;
+ u32 data;
+
+ while (*maps) {
+ map = *maps;
+ data = pmc_core_reg_read(pmcdev, offset);
+ offset += 4;
+ while (map->name) {
+ if (dev)
+ dev_dbg(dev, "SLP_S0_DBG: %-32s\tState: %s\n",
+ map->name,
+ data & map->bit_mask ? "Yes" : "No");
+ if (s)
+ seq_printf(s, "SLP_S0_DBG: %-32s\tState: %s\n",
+ map->name,
+ data & map->bit_mask ? "Yes" : "No");
+ ++map;
+ }
+ ++maps;
+ }
+}
+
+static void pmc_core_lpm_display(struct pmc_dev *pmcdev, struct device *dev,
+ struct seq_file *s, u32 offset,
+ const char *str,
+ const struct pmc_bit_map **maps)
+{
+ u32 lpm_regs[ARRAY_SIZE(tgl_lpm_maps)-1];
+ int index, idx, len = 32, bit_mask;
+
+ for (index = 0; tgl_lpm_maps[index]; index++) {
+ lpm_regs[index] = pmc_core_reg_read(pmcdev, offset);
+ offset += 4;
+ }
+
+ for (idx = 0; maps[idx]; idx++) {
+ if (dev)
+ dev_dbg(dev, "\nLPM_%s_%d:\t0x%x\n", str, idx,
+ lpm_regs[idx]);
+ if (s)
+ seq_printf(s, "\nLPM_%s_%d:\t0x%x\n", str, idx,
+ lpm_regs[idx]);
+ for (index = 0; maps[idx][index].name && index < len; index++) {
+ bit_mask = maps[idx][index].bit_mask;
+ if (dev)
+ dev_dbg(dev, "%-30s %-30d\n",
+ maps[idx][index].name,
+ lpm_regs[idx] & bit_mask ? 1 : 0);
+ if (s)
+ seq_printf(s, "%-30s %-30d\n",
+ maps[idx][index].name,
+ lpm_regs[idx] & bit_mask ? 1 : 0);
+ }
+ }
+}
+
#if IS_ENABLED(CONFIG_DEBUG_FS)
static bool slps0_dbg_latch;

@@ -844,33 +905,6 @@ static void pmc_core_slps0_dbg_latch(struct pmc_dev *pmcdev, bool reset)
mutex_unlock(&pmcdev->lock);
}

-static void pmc_core_slps0_display(struct pmc_dev *pmcdev, struct device *dev,
- struct seq_file *s)
-{
- const struct pmc_bit_map **maps = pmcdev->map->slps0_dbg_maps;
- const struct pmc_bit_map *map;
- int offset = pmcdev->map->slps0_dbg_offset;
- u32 data;
-
- while (*maps) {
- map = *maps;
- data = pmc_core_reg_read(pmcdev, offset);
- offset += 4;
- while (map->name) {
- if (dev)
- dev_dbg(dev, "SLP_S0_DBG: %-32s\tState: %s\n",
- map->name,
- data & map->bit_mask ? "Yes" : "No");
- if (s)
- seq_printf(s, "SLP_S0_DBG: %-32s\tState: %s\n",
- map->name,
- data & map->bit_mask ? "Yes" : "No");
- ++map;
- }
- ++maps;
- }
-}
-
static int pmc_core_slps0_dbg_show(struct seq_file *s, void *unused)
{
struct pmc_dev *pmcdev = s->private;
@@ -974,40 +1008,6 @@ static int pmc_core_substate_res_show(struct seq_file *s, void *unused)
}
DEFINE_SHOW_ATTRIBUTE(pmc_core_substate_res);

-static void pmc_core_lpm_display(struct pmc_dev *pmcdev, struct device *dev,
- struct seq_file *s, u32 offset,
- const char *str,
- const struct pmc_bit_map **maps)
-{
- u32 lpm_regs[ARRAY_SIZE(tgl_lpm_maps)-1];
- int index, idx, len = 32, bit_mask;
-
- for (index = 0; tgl_lpm_maps[index]; index++) {
- lpm_regs[index] = pmc_core_reg_read(pmcdev, offset);
- offset += 4;
- }
-
- for (idx = 0; maps[idx]; idx++) {
- if (dev)
- dev_dbg(dev, "\nLPM_%s_%d:\t0x%x\n", str, idx,
- lpm_regs[idx]);
- if (s)
- seq_printf(s, "\nLPM_%s_%d:\t0x%x\n", str, idx,
- lpm_regs[idx]);
- for (index = 0; maps[idx][index].name && index < len; index++) {
- bit_mask = maps[idx][index].bit_mask;
- if (dev)
- dev_dbg(dev, "%-30s %-30d\n",
- maps[idx][index].name,
- lpm_regs[idx] & bit_mask ? 1 : 0);
- if (s)
- seq_printf(s, "%-30s %-30d\n",
- maps[idx][index].name,
- lpm_regs[idx] & bit_mask ? 1 : 0);
- }
- }
-}
-
static int pmc_core_substate_sts_regs_show(struct seq_file *s, void *unused)
{
struct pmc_dev *pmcdev = s->private;
--
2.17.1

2020-02-27 23:35:37

by Kammela, Gayatri

[permalink] [raw]
Subject: [PATCH v2 3/4] platform/x86: intel_pmc_core: fix: Remove the duplicate if() to create debugfs entry for substate_live_status_registers

A debugfs entry for substate_live_status_registers is created only if
the platform has sub-states, which requires the same condition to create
substate_status_registers debugfs entry. Hence remove the redundant
condition and re-use the exisiting one.

Cc: Chen Zhou <[email protected]>
Cc: Andy Shevchenko <[email protected]>
Cc: David E. Box <[email protected]>
Signed-off-by: Gayatri Kammela <[email protected]>
---
drivers/platform/x86/intel_pmc_core.c | 3 ---
1 file changed, 3 deletions(-)

diff --git a/drivers/platform/x86/intel_pmc_core.c b/drivers/platform/x86/intel_pmc_core.c
index 3f000b6c8d8e..f6cc80987257 100644
--- a/drivers/platform/x86/intel_pmc_core.c
+++ b/drivers/platform/x86/intel_pmc_core.c
@@ -1121,9 +1121,6 @@ static void pmc_core_dbgfs_register(struct pmc_dev *pmcdev)
debugfs_create_file("substate_status_registers", 0444,
pmcdev->dbgfs_dir, pmcdev,
&pmc_core_substate_sts_regs_fops);
- }
-
- if (pmcdev->map->lpm_status_offset) {
debugfs_create_file("substate_live_status_registers", 0444,
pmcdev->dbgfs_dir, pmcdev,
&pmc_core_substate_l_sts_regs_fops);
--
2.17.1

2020-02-28 10:06:46

by Andy Shevchenko

[permalink] [raw]
Subject: Re: [PATCH v2 2/4] platform/x86: intel_pmc_core: fix: Make pmc_core_lpm_display() generic for platforms that support sub-states

On Thu, Feb 27, 2020 at 03:29:14PM -0800, Gayatri Kammela wrote:
> Currently pmc_core_lpm_display() uses array of struct pointers i.e.,
> tgl_lpm_maps for Tiger Lake directly to iterate through and to get the
> number of status/live status registers which is hardcoded and cannot
> be re-used for future platforms that support sub-states. To maintain
> readability, make pmc_core_lpm_display() generic, so that it can re-used
> for future platforms.

This patch need more work, see below.
That said, I would prefer to see it last in the series for next version.

...

> + lpm_regs = kmalloc_array(arr_size, sizeof(*lpm_regs), GFP_KERNEL);

No error check?
Besides that it is obvious memory leak.

> + for (index = 0; maps[index]; index++) {
> lpm_regs[index] = pmc_core_reg_read(pmcdev, offset);
> offset += 4;
> }

--
With Best Regards,
Andy Shevchenko


2020-02-28 17:34:06

by Kammela, Gayatri

[permalink] [raw]
Subject: RE: [PATCH v2 2/4] platform/x86: intel_pmc_core: fix: Make pmc_core_lpm_display() generic for platforms that support sub-states


> -----Original Message-----
> From: Andy Shevchenko <[email protected]>
> Sent: Friday, February 28, 2020 2:06 AM
> To: Kammela, Gayatri <[email protected]>
> Cc: [email protected]; [email protected];
> Somayaji, Vishwanath <[email protected]>;
> [email protected]; Westerberg, Mika <[email protected]>;
> [email protected]; Prestopine, Charles D
> <[email protected]>; Chen Zhou <[email protected]>;
> Box, David E <[email protected]>
> Subject: Re: [PATCH v2 2/4] platform/x86: intel_pmc_core: fix: Make
> pmc_core_lpm_display() generic for platforms that support sub-states
>
> On Thu, Feb 27, 2020 at 03:29:14PM -0800, Gayatri Kammela wrote:
> > Currently pmc_core_lpm_display() uses array of struct pointers i.e.,
> > tgl_lpm_maps for Tiger Lake directly to iterate through and to get the
> > number of status/live status registers which is hardcoded and cannot
> > be re-used for future platforms that support sub-states. To maintain
> > readability, make pmc_core_lpm_display() generic, so that it can
> > re-used for future platforms.
>
> This patch need more work, see below.
> That said, I would prefer to see it last in the series for next version.


Sure, I will put this patch last in the series in v3.

>
> ...
>
> > + lpm_regs = kmalloc_array(arr_size, sizeof(*lpm_regs), GFP_KERNEL);
>
> No error check?
> Besides that it is obvious memory leak.

Sorry my bad, I will put the check and free the memory. I will update this in v3

>
> > + for (index = 0; maps[index]; index++) {
> > lpm_regs[index] = pmc_core_reg_read(pmcdev, offset);
> > offset += 4;
> > }
>
> --
> With Best Regards,
> Andy Shevchenko
>