Message ID | 20210417031252.3020837-6-david.e.box@linux.intel.com (mailing list archive) |
---|---|
State | Accepted, archived |
Headers | show |
Series | intel_pmc_core: Add sub-state requirements and mode | expand |
Hi "David, Thank you for the patch! Perhaps something to improve: [auto build test WARNING on 823b31517ad3196324322804ee365d5fcff704d6] url: https://github.com/0day-ci/linux/commits/David-E-Box/intel_pmc_core-Add-sub-state-requirements-and-mode/20210417-111530 base: 823b31517ad3196324322804ee365d5fcff704d6 config: i386-randconfig-a001-20210417 (attached as .config) compiler: gcc-9 (Debian 9.3.0-22) 9.3.0 reproduce (this is a W=1 build): # https://github.com/0day-ci/linux/commit/703038f16e99686bf2538222cee482f823bfa60f git remote add linux-review https://github.com/0day-ci/linux git fetch --no-tags linux-review David-E-Box/intel_pmc_core-Add-sub-state-requirements-and-mode/20210417-111530 git checkout 703038f16e99686bf2538222cee482f823bfa60f # save the attached .config to linux build tree make W=1 W=1 ARCH=i386 If you fix the issue, kindly add following tag as appropriate Reported-by: kernel test robot <lkp@intel.com> All warnings (new ones prefixed by >>): In file included from drivers/platform/x86/intel_pmc_core.c:14: drivers/platform/x86/intel_pmc_core.c: In function 'pmc_core_get_tgl_lpm_reqs': >> drivers/platform/x86/intel_pmc_core.c:621:5: warning: format '%ld' expects argument of type 'long int', but argument 5 has type 'size_t' {aka 'unsigned int'} [-Wformat=] 621 | "_DSM returned unexpected buffer size," | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 622 | " have %d, expect %ld\n", size, lpm_size); | ~~~~~~~~ | | | size_t {aka unsigned int} include/linux/acpi.h:1073:42: note: in definition of macro 'acpi_handle_debug' 1073 | acpi_handle_printk(KERN_DEBUG, handle, fmt, ##__VA_ARGS__); \ | ^~~ drivers/platform/x86/intel_pmc_core.c:622:25: note: format string is defined here 622 | " have %d, expect %ld\n", size, lpm_size); | ~~^ | | | long int | %d vim +621 drivers/platform/x86/intel_pmc_core.c 597 598 static void pmc_core_get_tgl_lpm_reqs(struct platform_device *pdev) 599 { 600 struct pmc_dev *pmcdev = platform_get_drvdata(pdev); 601 const int num_maps = pmcdev->map->lpm_num_maps; 602 size_t lpm_size = LPM_MAX_NUM_MODES * num_maps * 4; 603 union acpi_object *out_obj; 604 struct acpi_device *adev; 605 guid_t s0ix_dsm_guid; 606 u32 *lpm_req_regs, *addr; 607 608 adev = ACPI_COMPANION(&pdev->dev); 609 if (!adev) 610 return; 611 612 guid_parse(ACPI_S0IX_DSM_UUID, &s0ix_dsm_guid); 613 614 out_obj = acpi_evaluate_dsm(adev->handle, &s0ix_dsm_guid, 0, 615 ACPI_GET_LOW_MODE_REGISTERS, NULL); 616 if (out_obj && out_obj->type == ACPI_TYPE_BUFFER) { 617 int size = out_obj->buffer.length; 618 619 if (size != lpm_size) { 620 acpi_handle_debug(adev->handle, > 621 "_DSM returned unexpected buffer size," 622 " have %d, expect %ld\n", size, lpm_size); 623 goto free_acpi_obj; 624 } 625 } else { 626 acpi_handle_debug(adev->handle, 627 "_DSM function 0 evaluation failed\n"); 628 goto free_acpi_obj; 629 } 630 631 addr = (u32 *)out_obj->buffer.pointer; 632 633 lpm_req_regs = devm_kzalloc(&pdev->dev, lpm_size * sizeof(u32), 634 GFP_KERNEL); 635 if (!lpm_req_regs) 636 goto free_acpi_obj; 637 638 memcpy(lpm_req_regs, addr, lpm_size); 639 pmcdev->lpm_req_regs = lpm_req_regs; 640 641 free_acpi_obj: 642 ACPI_FREE(out_obj); 643 } 644 --- 0-DAY CI Kernel Test Service, Intel Corporation https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org
Hi "David,
Thank you for the patch! Perhaps something to improve:
[auto build test WARNING on 823b31517ad3196324322804ee365d5fcff704d6]
url: https://github.com/0day-ci/linux/commits/David-E-Box/intel_pmc_core-Add-sub-state-requirements-and-mode/20210417-111530
base: 823b31517ad3196324322804ee365d5fcff704d6
config: i386-randconfig-a012-20210416 (attached as .config)
compiler: gcc-9 (Debian 9.3.0-22) 9.3.0
reproduce (this is a W=1 build):
# https://github.com/0day-ci/linux/commit/703038f16e99686bf2538222cee482f823bfa60f
git remote add linux-review https://github.com/0day-ci/linux
git fetch --no-tags linux-review David-E-Box/intel_pmc_core-Add-sub-state-requirements-and-mode/20210417-111530
git checkout 703038f16e99686bf2538222cee482f823bfa60f
# save the attached .config to linux build tree
make W=1 W=1 ARCH=i386
If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>
All warnings (new ones prefixed by >>):
drivers/platform/x86/intel_pmc_core.c: In function 'pmc_core_get_tgl_lpm_reqs':
>> <command-line>: warning: format '%ld' expects argument of type 'long int', but argument 5 has type 'size_t' {aka 'unsigned int'} [-Wformat=]
drivers/platform/x86/intel_pmc_core.c:12:21: note: in expansion of macro 'KBUILD_MODNAME'
12 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
| ^~~~~~~~~~~~~~
include/linux/dynamic_debug.h:129:15: note: in expansion of macro 'pr_fmt'
129 | func(&id, ##__VA_ARGS__); \
| ^~~~~~~~~~~
include/linux/dynamic_debug.h:147:2: note: in expansion of macro '__dynamic_func_call'
147 | __dynamic_func_call(__UNIQUE_ID(ddebug), fmt, func, ##__VA_ARGS__)
| ^~~~~~~~~~~~~~~~~~~
include/linux/acpi.h:1067:2: note: in expansion of macro '_dynamic_func_call'
1067 | _dynamic_func_call(fmt, __acpi_handle_debug, \
| ^~~~~~~~~~~~~~~~~~
drivers/platform/x86/intel_pmc_core.c:620:4: note: in expansion of macro 'acpi_handle_debug'
620 | acpi_handle_debug(adev->handle,
| ^~~~~~~~~~~~~~~~~
---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org
Hi David, On 4/17/21 5:12 AM, David E. Box wrote: > From: Gayatri Kammela <gayatri.kammela@intel.com> > > Platforms that support low power modes (LPM) such as Tiger Lake maintain > requirements for each sub-state that a readable in the PMC. However, unlike > LPM status registers, requirement registers are not memory mapped but are > available from an ACPI _DSM. Collect the requirements for Tiger Lake using > the _DSM method and store in a buffer. > > Signed-off-by: Gayatri Kammela <gayatri.kammela@intel.com> > Co-developed-by: David E. Box <david.e.box@linux.intel.com> > Signed-off-by: David E. Box <david.e.box@linux.intel.com> > Reviewed-by: Hans de Goede <hdegoede@redhat.com> Erm, I did not give my "Reviewed-by: Hans de Goede <hdegoede@redhat.com>" for this patch, because it still needed some work. Next time please only add my Reviewed-by to patches where I explicitly replied with a Reviewed-by. The same goes for patch 7/9 Regards, Hans > --- > > V2: - Move buffer allocation so that it does not need to be freed > (which was missing anyway) when an error is encountered. > - Use label to free out_obj after errors > - Use memcpy instead of memcpy_fromio for ACPI memory > > drivers/platform/x86/intel_pmc_core.c | 56 +++++++++++++++++++++++++++ > drivers/platform/x86/intel_pmc_core.h | 2 + > 2 files changed, 58 insertions(+) > > diff --git a/drivers/platform/x86/intel_pmc_core.c b/drivers/platform/x86/intel_pmc_core.c > index 0e59a84b51bf..97efe9a6bd01 100644 > --- a/drivers/platform/x86/intel_pmc_core.c > +++ b/drivers/platform/x86/intel_pmc_core.c > @@ -23,7 +23,9 @@ > #include <linux/slab.h> > #include <linux/suspend.h> > #include <linux/uaccess.h> > +#include <linux/uuid.h> > > +#include <acpi/acpi_bus.h> > #include <asm/cpu_device_id.h> > #include <asm/intel-family.h> > #include <asm/msr.h> > @@ -31,6 +33,9 @@ > > #include "intel_pmc_core.h" > > +#define ACPI_S0IX_DSM_UUID "57a6512e-3979-4e9d-9708-ff13b2508972" > +#define ACPI_GET_LOW_MODE_REGISTERS 1 > + > /* PKGC MSRs are common across Intel Core SoCs */ > static const struct pmc_bit_map msr_map[] = { > {"Package C2", MSR_PKG_C2_RESIDENCY}, > @@ -590,6 +595,53 @@ static const struct pmc_reg_map tgl_reg_map = { > .etr3_offset = ETR3_OFFSET, > }; > > +static void pmc_core_get_tgl_lpm_reqs(struct platform_device *pdev) > +{ > + struct pmc_dev *pmcdev = platform_get_drvdata(pdev); > + const int num_maps = pmcdev->map->lpm_num_maps; > + size_t lpm_size = LPM_MAX_NUM_MODES * num_maps * 4; > + union acpi_object *out_obj; > + struct acpi_device *adev; > + guid_t s0ix_dsm_guid; > + u32 *lpm_req_regs, *addr; > + > + adev = ACPI_COMPANION(&pdev->dev); > + if (!adev) > + return; > + > + guid_parse(ACPI_S0IX_DSM_UUID, &s0ix_dsm_guid); > + > + out_obj = acpi_evaluate_dsm(adev->handle, &s0ix_dsm_guid, 0, > + ACPI_GET_LOW_MODE_REGISTERS, NULL); > + if (out_obj && out_obj->type == ACPI_TYPE_BUFFER) { > + int size = out_obj->buffer.length; > + > + if (size != lpm_size) { > + acpi_handle_debug(adev->handle, > + "_DSM returned unexpected buffer size," > + " have %d, expect %ld\n", size, lpm_size); > + goto free_acpi_obj; > + } > + } else { > + acpi_handle_debug(adev->handle, > + "_DSM function 0 evaluation failed\n"); > + goto free_acpi_obj; > + } > + > + addr = (u32 *)out_obj->buffer.pointer; > + > + lpm_req_regs = devm_kzalloc(&pdev->dev, lpm_size * sizeof(u32), > + GFP_KERNEL); > + if (!lpm_req_regs) > + goto free_acpi_obj; > + > + memcpy(lpm_req_regs, addr, lpm_size); > + pmcdev->lpm_req_regs = lpm_req_regs; > + > +free_acpi_obj: > + ACPI_FREE(out_obj); > +} > + > static inline u32 pmc_core_reg_read(struct pmc_dev *pmcdev, int reg_offset) > { > return readl(pmcdev->regbase + reg_offset); > @@ -1424,10 +1476,14 @@ static int pmc_core_probe(struct platform_device *pdev) > return -ENOMEM; > > mutex_init(&pmcdev->lock); > + > pmcdev->pmc_xram_read_bit = pmc_core_check_read_lock_bit(pmcdev); > pmc_core_get_low_power_modes(pmcdev); > pmc_core_do_dmi_quirks(pmcdev); > > + if (pmcdev->map == &tgl_reg_map) > + pmc_core_get_tgl_lpm_reqs(pdev); > + > /* > * On TGL, due to a hardware limitation, the GBE LTR blocks PC10 when > * a cable is attached. Tell the PMC to ignore it. > diff --git a/drivers/platform/x86/intel_pmc_core.h b/drivers/platform/x86/intel_pmc_core.h > index aa44fd5399cc..64fb368f40f6 100644 > --- a/drivers/platform/x86/intel_pmc_core.h > +++ b/drivers/platform/x86/intel_pmc_core.h > @@ -294,6 +294,7 @@ struct pmc_reg_map { > * @s0ix_counter: S0ix residency (step adjusted) > * @num_lpm_modes: Count of enabled modes > * @lpm_en_modes: Array of enabled modes from lowest to highest priority > + * @lpm_req_regs: List of substate requirements > * > * pmc_dev contains info about power management controller device. > */ > @@ -310,6 +311,7 @@ struct pmc_dev { > u64 s0ix_counter; > int num_lpm_modes; > int lpm_en_modes[LPM_MAX_NUM_MODES]; > + u32 *lpm_req_regs; > }; > > #define pmc_for_each_mode(i, mode, pmcdev) \ >
Hi, On 4/17/21 5:12 AM, David E. Box wrote: > From: Gayatri Kammela <gayatri.kammela@intel.com> > > Platforms that support low power modes (LPM) such as Tiger Lake maintain > requirements for each sub-state that a readable in the PMC. However, unlike > LPM status registers, requirement registers are not memory mapped but are > available from an ACPI _DSM. Collect the requirements for Tiger Lake using > the _DSM method and store in a buffer. > > Signed-off-by: Gayatri Kammela <gayatri.kammela@intel.com> > Co-developed-by: David E. Box <david.e.box@linux.intel.com> > Signed-off-by: David E. Box <david.e.box@linux.intel.com> > Reviewed-by: Hans de Goede <hdegoede@redhat.com> > --- > > V2: - Move buffer allocation so that it does not need to be freed > (which was missing anyway) when an error is encountered. > - Use label to free out_obj after errors > - Use memcpy instead of memcpy_fromio for ACPI memory > > drivers/platform/x86/intel_pmc_core.c | 56 +++++++++++++++++++++++++++ > drivers/platform/x86/intel_pmc_core.h | 2 + > 2 files changed, 58 insertions(+) > > diff --git a/drivers/platform/x86/intel_pmc_core.c b/drivers/platform/x86/intel_pmc_core.c > index 0e59a84b51bf..97efe9a6bd01 100644 > --- a/drivers/platform/x86/intel_pmc_core.c > +++ b/drivers/platform/x86/intel_pmc_core.c > @@ -23,7 +23,9 @@ > #include <linux/slab.h> > #include <linux/suspend.h> > #include <linux/uaccess.h> > +#include <linux/uuid.h> > > +#include <acpi/acpi_bus.h> > #include <asm/cpu_device_id.h> > #include <asm/intel-family.h> > #include <asm/msr.h> > @@ -31,6 +33,9 @@ > > #include "intel_pmc_core.h" > > +#define ACPI_S0IX_DSM_UUID "57a6512e-3979-4e9d-9708-ff13b2508972" > +#define ACPI_GET_LOW_MODE_REGISTERS 1 > + > /* PKGC MSRs are common across Intel Core SoCs */ > static const struct pmc_bit_map msr_map[] = { > {"Package C2", MSR_PKG_C2_RESIDENCY}, > @@ -590,6 +595,53 @@ static const struct pmc_reg_map tgl_reg_map = { > .etr3_offset = ETR3_OFFSET, > }; > > +static void pmc_core_get_tgl_lpm_reqs(struct platform_device *pdev) > +{ > + struct pmc_dev *pmcdev = platform_get_drvdata(pdev); > + const int num_maps = pmcdev->map->lpm_num_maps; > + size_t lpm_size = LPM_MAX_NUM_MODES * num_maps * 4; The type of lpm_size should be an u32, so that it matches the type of out_obj->buffer.length. > + union acpi_object *out_obj; > + struct acpi_device *adev; > + guid_t s0ix_dsm_guid; > + u32 *lpm_req_regs, *addr; > + > + adev = ACPI_COMPANION(&pdev->dev); > + if (!adev) > + return; > + > + guid_parse(ACPI_S0IX_DSM_UUID, &s0ix_dsm_guid); > + > + out_obj = acpi_evaluate_dsm(adev->handle, &s0ix_dsm_guid, 0, > + ACPI_GET_LOW_MODE_REGISTERS, NULL); > + if (out_obj && out_obj->type == ACPI_TYPE_BUFFER) { > + int size = out_obj->buffer.length; out_obj->buffer.length is an u32, please make this an u32 too. > + > + if (size != lpm_size) { > + acpi_handle_debug(adev->handle, > + "_DSM returned unexpected buffer size," > + " have %d, expect %ld\n", size, lpm_size); And use %u here (twice), this should also fix the warnings reported by the kernel test robot. If there are no objections against the suggested changes, then I can fix this up while merging this. Please let me know if the suggested changes are ok with you. Regards, Hans > + goto free_acpi_obj; > + } > + } else { > + acpi_handle_debug(adev->handle, > + "_DSM function 0 evaluation failed\n"); > + goto free_acpi_obj; > + } > + > + addr = (u32 *)out_obj->buffer.pointer; > + > + lpm_req_regs = devm_kzalloc(&pdev->dev, lpm_size * sizeof(u32), > + GFP_KERNEL); > + if (!lpm_req_regs) > + goto free_acpi_obj; > + > + memcpy(lpm_req_regs, addr, lpm_size); > + pmcdev->lpm_req_regs = lpm_req_regs; > + > +free_acpi_obj: > + ACPI_FREE(out_obj); > +} > + > static inline u32 pmc_core_reg_read(struct pmc_dev *pmcdev, int reg_offset) > { > return readl(pmcdev->regbase + reg_offset); > @@ -1424,10 +1476,14 @@ static int pmc_core_probe(struct platform_device *pdev) > return -ENOMEM; > > mutex_init(&pmcdev->lock); > + > pmcdev->pmc_xram_read_bit = pmc_core_check_read_lock_bit(pmcdev); > pmc_core_get_low_power_modes(pmcdev); > pmc_core_do_dmi_quirks(pmcdev); > > + if (pmcdev->map == &tgl_reg_map) > + pmc_core_get_tgl_lpm_reqs(pdev); > + > /* > * On TGL, due to a hardware limitation, the GBE LTR blocks PC10 when > * a cable is attached. Tell the PMC to ignore it. > diff --git a/drivers/platform/x86/intel_pmc_core.h b/drivers/platform/x86/intel_pmc_core.h > index aa44fd5399cc..64fb368f40f6 100644 > --- a/drivers/platform/x86/intel_pmc_core.h > +++ b/drivers/platform/x86/intel_pmc_core.h > @@ -294,6 +294,7 @@ struct pmc_reg_map { > * @s0ix_counter: S0ix residency (step adjusted) > * @num_lpm_modes: Count of enabled modes > * @lpm_en_modes: Array of enabled modes from lowest to highest priority > + * @lpm_req_regs: List of substate requirements > * > * pmc_dev contains info about power management controller device. > */ > @@ -310,6 +311,7 @@ struct pmc_dev { > u64 s0ix_counter; > int num_lpm_modes; > int lpm_en_modes[LPM_MAX_NUM_MODES]; > + u32 *lpm_req_regs; > }; > > #define pmc_for_each_mode(i, mode, pmcdev) \ >
On Sat, 2021-04-17 at 11:00 +0200, Hans de Goede wrote: > Hi, > > On 4/17/21 5:12 AM, David E. Box wrote: > > From: Gayatri Kammela <gayatri.kammela@intel.com> > > > > Platforms that support low power modes (LPM) such as Tiger Lake > > maintain > > requirements for each sub-state that a readable in the PMC. > > However, unlike > > LPM status registers, requirement registers are not memory mapped > > but are > > available from an ACPI _DSM. Collect the requirements for Tiger > > Lake using > > the _DSM method and store in a buffer. > > > > Signed-off-by: Gayatri Kammela <gayatri.kammela@intel.com> > > Co-developed-by: David E. Box <david.e.box@linux.intel.com> > > Signed-off-by: David E. Box <david.e.box@linux.intel.com> > > Reviewed-by: Hans de Goede <hdegoede@redhat.com> > > --- > > > > V2: - Move buffer allocation so that it does not need to be > > freed > > (which was missing anyway) when an error is encountered. > > - Use label to free out_obj after errors > > - Use memcpy instead of memcpy_fromio for ACPI memory > > > > drivers/platform/x86/intel_pmc_core.c | 56 > > +++++++++++++++++++++++++++ > > drivers/platform/x86/intel_pmc_core.h | 2 + > > 2 files changed, 58 insertions(+) > > > > diff --git a/drivers/platform/x86/intel_pmc_core.c > > b/drivers/platform/x86/intel_pmc_core.c > > index 0e59a84b51bf..97efe9a6bd01 100644 > > --- a/drivers/platform/x86/intel_pmc_core.c > > +++ b/drivers/platform/x86/intel_pmc_core.c > > @@ -23,7 +23,9 @@ > > #include <linux/slab.h> > > #include <linux/suspend.h> > > #include <linux/uaccess.h> > > +#include <linux/uuid.h> > > > > +#include <acpi/acpi_bus.h> > > #include <asm/cpu_device_id.h> > > #include <asm/intel-family.h> > > #include <asm/msr.h> > > @@ -31,6 +33,9 @@ > > > > #include "intel_pmc_core.h" > > > > +#define ACPI_S0IX_DSM_UUID "57a6512e-3979-4e9d-9708- > > ff13b2508972" > > +#define ACPI_GET_LOW_MODE_REGISTERS 1 > > + > > /* PKGC MSRs are common across Intel Core SoCs */ > > static const struct pmc_bit_map msr_map[] = { > > {"Package C2", MSR_PKG_C2_RESIDENCY}, > > @@ -590,6 +595,53 @@ static const struct pmc_reg_map tgl_reg_map = > > { > > .etr3_offset = ETR3_OFFSET, > > }; > > > > +static void pmc_core_get_tgl_lpm_reqs(struct platform_device > > *pdev) > > +{ > > + struct pmc_dev *pmcdev = platform_get_drvdata(pdev); > > + const int num_maps = pmcdev->map->lpm_num_maps; > > + size_t lpm_size = LPM_MAX_NUM_MODES * num_maps * 4; > > The type of lpm_size should be an u32, so that it matches > the type of out_obj->buffer.length. > > > + union acpi_object *out_obj; > > + struct acpi_device *adev; > > + guid_t s0ix_dsm_guid; > > + u32 *lpm_req_regs, *addr; > > + > > + adev = ACPI_COMPANION(&pdev->dev); > > + if (!adev) > > + return; > > + > > + guid_parse(ACPI_S0IX_DSM_UUID, &s0ix_dsm_guid); > > + > > + out_obj = acpi_evaluate_dsm(adev->handle, &s0ix_dsm_guid, > > 0, > > + ACPI_GET_LOW_MODE_REGISTERS, > > NULL); > > + if (out_obj && out_obj->type == ACPI_TYPE_BUFFER) { > > + int size = out_obj->buffer.length; > > out_obj->buffer.length is an u32, please make this an u32 too. > > > + > > + if (size != lpm_size) { > > + acpi_handle_debug(adev->handle, > > + "_DSM returned unexpected buffer > > size," > > + " have %d, expect %ld\n", size, > > lpm_size); > > And use %u here (twice), this should also fix the warnings reported > by the kernel test robot. > > If there are no objections against the suggested changes, then I can > fix this up while merging this. > > Please let me know if the suggested changes are ok with you. Changes are good with me. Thanks for the fixup. David > > Regards, > > Hans > > > > + goto free_acpi_obj; > > + } > > + } else { > > + acpi_handle_debug(adev->handle, > > + "_DSM function 0 evaluation > > failed\n"); > > + goto free_acpi_obj; > > + } > > + > > + addr = (u32 *)out_obj->buffer.pointer; > > + > > + lpm_req_regs = devm_kzalloc(&pdev->dev, lpm_size * > > sizeof(u32), > > + GFP_KERNEL); > > + if (!lpm_req_regs) > > + goto free_acpi_obj; > > + > > + memcpy(lpm_req_regs, addr, lpm_size); > > + pmcdev->lpm_req_regs = lpm_req_regs; > > + > > +free_acpi_obj: > > + ACPI_FREE(out_obj); > > +} > > + > > static inline u32 pmc_core_reg_read(struct pmc_dev *pmcdev, int > > reg_offset) > > { > > return readl(pmcdev->regbase + reg_offset); > > @@ -1424,10 +1476,14 @@ static int pmc_core_probe(struct > > platform_device *pdev) > > return -ENOMEM; > > > > mutex_init(&pmcdev->lock); > > + > > pmcdev->pmc_xram_read_bit = > > pmc_core_check_read_lock_bit(pmcdev); > > pmc_core_get_low_power_modes(pmcdev); > > pmc_core_do_dmi_quirks(pmcdev); > > > > + if (pmcdev->map == &tgl_reg_map) > > + pmc_core_get_tgl_lpm_reqs(pdev); > > + > > /* > > * On TGL, due to a hardware limitation, the GBE LTR blocks > > PC10 when > > * a cable is attached. Tell the PMC to ignore it. > > diff --git a/drivers/platform/x86/intel_pmc_core.h > > b/drivers/platform/x86/intel_pmc_core.h > > index aa44fd5399cc..64fb368f40f6 100644 > > --- a/drivers/platform/x86/intel_pmc_core.h > > +++ b/drivers/platform/x86/intel_pmc_core.h > > @@ -294,6 +294,7 @@ struct pmc_reg_map { > > * @s0ix_counter: S0ix residency (step adjusted) > > * @num_lpm_modes: Count of enabled modes > > * @lpm_en_modes: Array of enabled modes from lowest to > > highest priority > > + * @lpm_req_regs: List of substate requirements > > * > > * pmc_dev contains info about power management controller device. > > */ > > @@ -310,6 +311,7 @@ struct pmc_dev { > > u64 s0ix_counter; > > int num_lpm_modes; > > int lpm_en_modes[LPM_MAX_NUM_MODES]; > > + u32 *lpm_req_regs; > > }; > > > > #define pmc_for_each_mode(i, mode, pmcdev) \ > > >
On Sat, 2021-04-17 at 10:52 +0200, Hans de Goede wrote: > Hi David, > > On 4/17/21 5:12 AM, David E. Box wrote: > > From: Gayatri Kammela <gayatri.kammela@intel.com> > > > > Platforms that support low power modes (LPM) such as Tiger Lake > > maintain > > requirements for each sub-state that a readable in the PMC. > > However, unlike > > LPM status registers, requirement registers are not memory mapped > > but are > > available from an ACPI _DSM. Collect the requirements for Tiger > > Lake using > > the _DSM method and store in a buffer. > > > > Signed-off-by: Gayatri Kammela <gayatri.kammela@intel.com> > > Co-developed-by: David E. Box <david.e.box@linux.intel.com> > > Signed-off-by: David E. Box <david.e.box@linux.intel.com> > > Reviewed-by: Hans de Goede <hdegoede@redhat.com> > > Erm, I did not give my "Reviewed-by: Hans de Goede < > hdegoede@redhat.com>" > for this patch, because it still needed some work. > > Next time please only add my Reviewed-by to patches where I > explicitly replied with a Reviewed-by. Sure thing. Sorry about that. David > The same goes for patch 7/9 > > Regards, > > Hans > > > > > --- > > > > V2: - Move buffer allocation so that it does not need to be > > freed > > (which was missing anyway) when an error is encountered. > > - Use label to free out_obj after errors > > - Use memcpy instead of memcpy_fromio for ACPI memory > > > > drivers/platform/x86/intel_pmc_core.c | 56 > > +++++++++++++++++++++++++++ > > drivers/platform/x86/intel_pmc_core.h | 2 + > > 2 files changed, 58 insertions(+) > > > > diff --git a/drivers/platform/x86/intel_pmc_core.c > > b/drivers/platform/x86/intel_pmc_core.c > > index 0e59a84b51bf..97efe9a6bd01 100644 > > --- a/drivers/platform/x86/intel_pmc_core.c > > +++ b/drivers/platform/x86/intel_pmc_core.c > > @@ -23,7 +23,9 @@ > > #include <linux/slab.h> > > #include <linux/suspend.h> > > #include <linux/uaccess.h> > > +#include <linux/uuid.h> > > > > +#include <acpi/acpi_bus.h> > > #include <asm/cpu_device_id.h> > > #include <asm/intel-family.h> > > #include <asm/msr.h> > > @@ -31,6 +33,9 @@ > > > > #include "intel_pmc_core.h" > > > > +#define ACPI_S0IX_DSM_UUID "57a6512e-3979-4e9d-9708- > > ff13b2508972" > > +#define ACPI_GET_LOW_MODE_REGISTERS 1 > > + > > /* PKGC MSRs are common across Intel Core SoCs */ > > static const struct pmc_bit_map msr_map[] = { > > {"Package C2", MSR_PKG_C2_RESIDENCY}, > > @@ -590,6 +595,53 @@ static const struct pmc_reg_map tgl_reg_map = > > { > > .etr3_offset = ETR3_OFFSET, > > }; > > > > +static void pmc_core_get_tgl_lpm_reqs(struct platform_device > > *pdev) > > +{ > > + struct pmc_dev *pmcdev = platform_get_drvdata(pdev); > > + const int num_maps = pmcdev->map->lpm_num_maps; > > + size_t lpm_size = LPM_MAX_NUM_MODES * num_maps * 4; > > + union acpi_object *out_obj; > > + struct acpi_device *adev; > > + guid_t s0ix_dsm_guid; > > + u32 *lpm_req_regs, *addr; > > + > > + adev = ACPI_COMPANION(&pdev->dev); > > + if (!adev) > > + return; > > + > > + guid_parse(ACPI_S0IX_DSM_UUID, &s0ix_dsm_guid); > > + > > + out_obj = acpi_evaluate_dsm(adev->handle, &s0ix_dsm_guid, > > 0, > > + ACPI_GET_LOW_MODE_REGISTERS, > > NULL); > > + if (out_obj && out_obj->type == ACPI_TYPE_BUFFER) { > > + int size = out_obj->buffer.length; > > + > > + if (size != lpm_size) { > > + acpi_handle_debug(adev->handle, > > + "_DSM returned unexpected buffer > > size," > > + " have %d, expect %ld\n", size, > > lpm_size); > > + goto free_acpi_obj; > > + } > > + } else { > > + acpi_handle_debug(adev->handle, > > + "_DSM function 0 evaluation > > failed\n"); > > + goto free_acpi_obj; > > + } > > + > > + addr = (u32 *)out_obj->buffer.pointer; > > + > > + lpm_req_regs = devm_kzalloc(&pdev->dev, lpm_size * > > sizeof(u32), > > + GFP_KERNEL); > > + if (!lpm_req_regs) > > + goto free_acpi_obj; > > + > > + memcpy(lpm_req_regs, addr, lpm_size); > > + pmcdev->lpm_req_regs = lpm_req_regs; > > + > > +free_acpi_obj: > > + ACPI_FREE(out_obj); > > +} > > + > > static inline u32 pmc_core_reg_read(struct pmc_dev *pmcdev, int > > reg_offset) > > { > > return readl(pmcdev->regbase + reg_offset); > > @@ -1424,10 +1476,14 @@ static int pmc_core_probe(struct > > platform_device *pdev) > > return -ENOMEM; > > > > mutex_init(&pmcdev->lock); > > + > > pmcdev->pmc_xram_read_bit = > > pmc_core_check_read_lock_bit(pmcdev); > > pmc_core_get_low_power_modes(pmcdev); > > pmc_core_do_dmi_quirks(pmcdev); > > > > + if (pmcdev->map == &tgl_reg_map) > > + pmc_core_get_tgl_lpm_reqs(pdev); > > + > > /* > > * On TGL, due to a hardware limitation, the GBE LTR blocks > > PC10 when > > * a cable is attached. Tell the PMC to ignore it. > > diff --git a/drivers/platform/x86/intel_pmc_core.h > > b/drivers/platform/x86/intel_pmc_core.h > > index aa44fd5399cc..64fb368f40f6 100644 > > --- a/drivers/platform/x86/intel_pmc_core.h > > +++ b/drivers/platform/x86/intel_pmc_core.h > > @@ -294,6 +294,7 @@ struct pmc_reg_map { > > * @s0ix_counter: S0ix residency (step adjusted) > > * @num_lpm_modes: Count of enabled modes > > * @lpm_en_modes: Array of enabled modes from lowest to > > highest priority > > + * @lpm_req_regs: List of substate requirements > > * > > * pmc_dev contains info about power management controller device. > > */ > > @@ -310,6 +311,7 @@ struct pmc_dev { > > u64 s0ix_counter; > > int num_lpm_modes; > > int lpm_en_modes[LPM_MAX_NUM_MODES]; > > + u32 *lpm_req_regs; > > }; > > > > #define pmc_for_each_mode(i, mode, pmcdev) \ > > >
diff --git a/drivers/platform/x86/intel_pmc_core.c b/drivers/platform/x86/intel_pmc_core.c index 0e59a84b51bf..97efe9a6bd01 100644 --- a/drivers/platform/x86/intel_pmc_core.c +++ b/drivers/platform/x86/intel_pmc_core.c @@ -23,7 +23,9 @@ #include <linux/slab.h> #include <linux/suspend.h> #include <linux/uaccess.h> +#include <linux/uuid.h> +#include <acpi/acpi_bus.h> #include <asm/cpu_device_id.h> #include <asm/intel-family.h> #include <asm/msr.h> @@ -31,6 +33,9 @@ #include "intel_pmc_core.h" +#define ACPI_S0IX_DSM_UUID "57a6512e-3979-4e9d-9708-ff13b2508972" +#define ACPI_GET_LOW_MODE_REGISTERS 1 + /* PKGC MSRs are common across Intel Core SoCs */ static const struct pmc_bit_map msr_map[] = { {"Package C2", MSR_PKG_C2_RESIDENCY}, @@ -590,6 +595,53 @@ static const struct pmc_reg_map tgl_reg_map = { .etr3_offset = ETR3_OFFSET, }; +static void pmc_core_get_tgl_lpm_reqs(struct platform_device *pdev) +{ + struct pmc_dev *pmcdev = platform_get_drvdata(pdev); + const int num_maps = pmcdev->map->lpm_num_maps; + size_t lpm_size = LPM_MAX_NUM_MODES * num_maps * 4; + union acpi_object *out_obj; + struct acpi_device *adev; + guid_t s0ix_dsm_guid; + u32 *lpm_req_regs, *addr; + + adev = ACPI_COMPANION(&pdev->dev); + if (!adev) + return; + + guid_parse(ACPI_S0IX_DSM_UUID, &s0ix_dsm_guid); + + out_obj = acpi_evaluate_dsm(adev->handle, &s0ix_dsm_guid, 0, + ACPI_GET_LOW_MODE_REGISTERS, NULL); + if (out_obj && out_obj->type == ACPI_TYPE_BUFFER) { + int size = out_obj->buffer.length; + + if (size != lpm_size) { + acpi_handle_debug(adev->handle, + "_DSM returned unexpected buffer size," + " have %d, expect %ld\n", size, lpm_size); + goto free_acpi_obj; + } + } else { + acpi_handle_debug(adev->handle, + "_DSM function 0 evaluation failed\n"); + goto free_acpi_obj; + } + + addr = (u32 *)out_obj->buffer.pointer; + + lpm_req_regs = devm_kzalloc(&pdev->dev, lpm_size * sizeof(u32), + GFP_KERNEL); + if (!lpm_req_regs) + goto free_acpi_obj; + + memcpy(lpm_req_regs, addr, lpm_size); + pmcdev->lpm_req_regs = lpm_req_regs; + +free_acpi_obj: + ACPI_FREE(out_obj); +} + static inline u32 pmc_core_reg_read(struct pmc_dev *pmcdev, int reg_offset) { return readl(pmcdev->regbase + reg_offset); @@ -1424,10 +1476,14 @@ static int pmc_core_probe(struct platform_device *pdev) return -ENOMEM; mutex_init(&pmcdev->lock); + pmcdev->pmc_xram_read_bit = pmc_core_check_read_lock_bit(pmcdev); pmc_core_get_low_power_modes(pmcdev); pmc_core_do_dmi_quirks(pmcdev); + if (pmcdev->map == &tgl_reg_map) + pmc_core_get_tgl_lpm_reqs(pdev); + /* * On TGL, due to a hardware limitation, the GBE LTR blocks PC10 when * a cable is attached. Tell the PMC to ignore it. diff --git a/drivers/platform/x86/intel_pmc_core.h b/drivers/platform/x86/intel_pmc_core.h index aa44fd5399cc..64fb368f40f6 100644 --- a/drivers/platform/x86/intel_pmc_core.h +++ b/drivers/platform/x86/intel_pmc_core.h @@ -294,6 +294,7 @@ struct pmc_reg_map { * @s0ix_counter: S0ix residency (step adjusted) * @num_lpm_modes: Count of enabled modes * @lpm_en_modes: Array of enabled modes from lowest to highest priority + * @lpm_req_regs: List of substate requirements * * pmc_dev contains info about power management controller device. */ @@ -310,6 +311,7 @@ struct pmc_dev { u64 s0ix_counter; int num_lpm_modes; int lpm_en_modes[LPM_MAX_NUM_MODES]; + u32 *lpm_req_regs; }; #define pmc_for_each_mode(i, mode, pmcdev) \