From db7155b5e3d6e808c9e888e76a8f95690964a456 Mon Sep 17 00:00:00 2001 From: Xi Pardee Date: Fri, 7 Feb 2025 14:56:07 -0800 Subject: [PATCH 01/16] platform/x86:intel/pmc: Make tgl_core_generic_init() static MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Make tgl_core_generic_init() a static function as the function has no callers outside of tgl.c. Remove the prototype in core.h and reorder the code in tgl.c. Signed-off-by: Xi Pardee Reviewed-by: Ilpo Järvinen Link: https://lore.kernel.org/r/20250207225615.401235-2-xi.pardee@linux.intel.com Signed-off-by: Ilpo Järvinen --- drivers/platform/x86/intel/pmc/core.h | 1 - drivers/platform/x86/intel/pmc/tgl.c | 22 +++++++++++----------- 2 files changed, 11 insertions(+), 12 deletions(-) diff --git a/drivers/platform/x86/intel/pmc/core.h b/drivers/platform/x86/intel/pmc/core.h index b9d3291d0bf2..a1886d8e1ef3 100644 --- a/drivers/platform/x86/intel/pmc/core.h +++ b/drivers/platform/x86/intel/pmc/core.h @@ -597,7 +597,6 @@ int cnp_core_init(struct pmc_dev *pmcdev); int icl_core_init(struct pmc_dev *pmcdev); int tgl_core_init(struct pmc_dev *pmcdev); int tgl_l_core_init(struct pmc_dev *pmcdev); -int tgl_core_generic_init(struct pmc_dev *pmcdev, int pch_tp); int adl_core_init(struct pmc_dev *pmcdev); int mtl_core_init(struct pmc_dev *pmcdev); int arl_core_init(struct pmc_dev *pmcdev); diff --git a/drivers/platform/x86/intel/pmc/tgl.c b/drivers/platform/x86/intel/pmc/tgl.c index e0580de18077..4fec43d212d0 100644 --- a/drivers/platform/x86/intel/pmc/tgl.c +++ b/drivers/platform/x86/intel/pmc/tgl.c @@ -285,17 +285,7 @@ free_acpi_obj: ACPI_FREE(out_obj); } -int tgl_l_core_init(struct pmc_dev *pmcdev) -{ - return tgl_core_generic_init(pmcdev, PCH_LP); -} - -int tgl_core_init(struct pmc_dev *pmcdev) -{ - return tgl_core_generic_init(pmcdev, PCH_H); -} - -int tgl_core_generic_init(struct pmc_dev *pmcdev, int pch_tp) +static int tgl_core_generic_init(struct pmc_dev *pmcdev, int pch_tp) { struct pmc *pmc = pmcdev->pmcs[PMC_IDX_MAIN]; int ret; @@ -317,3 +307,13 @@ int tgl_core_generic_init(struct pmc_dev *pmcdev, int pch_tp) return 0; } + +int tgl_l_core_init(struct pmc_dev *pmcdev) +{ + return tgl_core_generic_init(pmcdev, PCH_LP); +} + +int tgl_core_init(struct pmc_dev *pmcdev) +{ + return tgl_core_generic_init(pmcdev, PCH_H); +} -- 2.51.0 From 78eaf4d12d7c4ec6cf2f5ed8d8737ae0da390930 Mon Sep 17 00:00:00 2001 From: Xi Pardee Date: Fri, 7 Feb 2025 14:56:08 -0800 Subject: [PATCH 02/16] platform/x86/intel/pmc: Remove duplicate enum MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Remove duplicate enum PMC_IDX_SOC. PMC_IDX_SOC has the same value as PMC_IDX_MAIN. Replace it with PMC_IDX_MAIN to avoid confusion. Signed-off-by: Xi Pardee Reviewed-by: Ilpo Järvinen Link: https://lore.kernel.org/r/20250207225615.401235-3-xi.pardee@linux.intel.com Signed-off-by: Ilpo Järvinen --- drivers/platform/x86/intel/pmc/arl.c | 2 +- drivers/platform/x86/intel/pmc/core.h | 1 - drivers/platform/x86/intel/pmc/lnl.c | 2 +- drivers/platform/x86/intel/pmc/mtl.c | 2 +- 4 files changed, 3 insertions(+), 4 deletions(-) diff --git a/drivers/platform/x86/intel/pmc/arl.c b/drivers/platform/x86/intel/pmc/arl.c index 05dec4f5019f..ad976cc83eca 100644 --- a/drivers/platform/x86/intel/pmc/arl.c +++ b/drivers/platform/x86/intel/pmc/arl.c @@ -693,7 +693,7 @@ static int arl_resume(struct pmc_dev *pmcdev) int arl_core_init(struct pmc_dev *pmcdev) { - struct pmc *pmc = pmcdev->pmcs[PMC_IDX_SOC]; + struct pmc *pmc = pmcdev->pmcs[PMC_IDX_MAIN]; int ret; int func = 0; bool ssram_init = true; diff --git a/drivers/platform/x86/intel/pmc/core.h b/drivers/platform/x86/intel/pmc/core.h index a1886d8e1ef3..a0f6cc427ddc 100644 --- a/drivers/platform/x86/intel/pmc/core.h +++ b/drivers/platform/x86/intel/pmc/core.h @@ -430,7 +430,6 @@ struct pmc_dev { enum pmc_index { PMC_IDX_MAIN, - PMC_IDX_SOC = PMC_IDX_MAIN, PMC_IDX_IOE, PMC_IDX_PCH, PMC_IDX_MAX diff --git a/drivers/platform/x86/intel/pmc/lnl.c b/drivers/platform/x86/intel/pmc/lnl.c index be029f12cdf4..09b13df90d68 100644 --- a/drivers/platform/x86/intel/pmc/lnl.c +++ b/drivers/platform/x86/intel/pmc/lnl.c @@ -553,7 +553,7 @@ static int lnl_resume(struct pmc_dev *pmcdev) int lnl_core_init(struct pmc_dev *pmcdev) { int ret; - struct pmc *pmc = pmcdev->pmcs[PMC_IDX_SOC]; + struct pmc *pmc = pmcdev->pmcs[PMC_IDX_MAIN]; lnl_d3_fixup(); diff --git a/drivers/platform/x86/intel/pmc/mtl.c b/drivers/platform/x86/intel/pmc/mtl.c index 02949fed76e9..07687a3e436d 100644 --- a/drivers/platform/x86/intel/pmc/mtl.c +++ b/drivers/platform/x86/intel/pmc/mtl.c @@ -992,7 +992,7 @@ static int mtl_resume(struct pmc_dev *pmcdev) int mtl_core_init(struct pmc_dev *pmcdev) { - struct pmc *pmc = pmcdev->pmcs[PMC_IDX_SOC]; + struct pmc *pmc = pmcdev->pmcs[PMC_IDX_MAIN]; int ret; int func = 2; bool ssram_init = true; -- 2.51.0 From ac6bef0d54014cc010831ec86ac425f482a981ae Mon Sep 17 00:00:00 2001 From: Xi Pardee Date: Fri, 7 Feb 2025 14:56:09 -0800 Subject: [PATCH 03/16] platform/x86:intel/pmc: Create generic_core_init() for all platforms MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Create a generic_core_init() function for all architectures to reduce duplicate code in each architecture file. Create an info structure to catch the variations between each architecture and pass it to the generic init function. Convert all architectures to call the generic core init function. Signed-off-by: Xi Pardee Link: https://lore.kernel.org/r/20250207225615.401235-4-xi.pardee@linux.intel.com Reviewed-by: Ilpo Järvinen Signed-off-by: Ilpo Järvinen --- drivers/platform/x86/intel/pmc/adl.c | 21 +++++-------- drivers/platform/x86/intel/pmc/arl.c | 43 +++++++-------------------- drivers/platform/x86/intel/pmc/cnp.c | 21 +++++-------- drivers/platform/x86/intel/pmc/core.c | 42 ++++++++++++++++++++++++++ drivers/platform/x86/intel/pmc/core.h | 22 ++++++++++++++ drivers/platform/x86/intel/pmc/icl.c | 17 ++++------- drivers/platform/x86/intel/pmc/lnl.c | 22 +++++--------- drivers/platform/x86/intel/pmc/mtl.c | 42 +++++++------------------- drivers/platform/x86/intel/pmc/spt.c | 17 ++++------- drivers/platform/x86/intel/pmc/tgl.c | 31 +++++++++---------- 10 files changed, 131 insertions(+), 147 deletions(-) diff --git a/drivers/platform/x86/intel/pmc/adl.c b/drivers/platform/x86/intel/pmc/adl.c index e7878558fd90..ac37f4ece9c7 100644 --- a/drivers/platform/x86/intel/pmc/adl.c +++ b/drivers/platform/x86/intel/pmc/adl.c @@ -311,20 +311,13 @@ const struct pmc_reg_map adl_reg_map = { .pson_residency_counter_step = TGL_PSON_RES_COUNTER_STEP, }; +static struct pmc_dev_info adl_pmc_dev = { + .map = &adl_reg_map, + .suspend = cnl_suspend, + .resume = cnl_resume, +}; + int adl_core_init(struct pmc_dev *pmcdev) { - struct pmc *pmc = pmcdev->pmcs[PMC_IDX_MAIN]; - int ret; - - pmcdev->suspend = cnl_suspend; - pmcdev->resume = cnl_resume; - - pmc->map = &adl_reg_map; - ret = get_primary_reg_base(pmc); - if (ret) - return ret; - - pmc_core_get_low_power_modes(pmcdev); - - return 0; + return generic_core_init(pmcdev, &adl_pmc_dev); } diff --git a/drivers/platform/x86/intel/pmc/arl.c b/drivers/platform/x86/intel/pmc/arl.c index ad976cc83eca..91f8e9ab1c2e 100644 --- a/drivers/platform/x86/intel/pmc/arl.c +++ b/drivers/platform/x86/intel/pmc/arl.c @@ -691,40 +691,17 @@ static int arl_resume(struct pmc_dev *pmcdev) return cnl_resume(pmcdev); } +static struct pmc_dev_info arl_pmc_dev = { + .pci_func = 0, + .dmu_guid = ARL_PMT_DMU_GUID, + .regmap_list = arl_pmc_info_list, + .map = &arl_socs_reg_map, + .suspend = cnl_suspend, + .resume = arl_resume, +}; + int arl_core_init(struct pmc_dev *pmcdev) { - struct pmc *pmc = pmcdev->pmcs[PMC_IDX_MAIN]; - int ret; - int func = 0; - bool ssram_init = true; - arl_d3_fixup(); - pmcdev->suspend = cnl_suspend; - pmcdev->resume = arl_resume; - pmcdev->regmap_list = arl_pmc_info_list; - - /* - * If ssram init fails use legacy method to at least get the - * primary PMC - */ - ret = pmc_core_ssram_init(pmcdev, func); - if (ret) { - ssram_init = false; - pmc->map = &arl_socs_reg_map; - - ret = get_primary_reg_base(pmc); - if (ret) - return ret; - } - - pmc_core_get_low_power_modes(pmcdev); - pmc_core_punit_pmt_init(pmcdev, ARL_PMT_DMU_GUID); - - if (ssram_init) { - ret = pmc_core_ssram_get_lpm_reqs(pmcdev); - if (ret) - return ret; - } - - return 0; + return generic_core_init(pmcdev, &arl_pmc_dev); } diff --git a/drivers/platform/x86/intel/pmc/cnp.c b/drivers/platform/x86/intel/pmc/cnp.c index fc5193fdf8a8..6d268058e40b 100644 --- a/drivers/platform/x86/intel/pmc/cnp.c +++ b/drivers/platform/x86/intel/pmc/cnp.c @@ -274,20 +274,13 @@ int cnl_resume(struct pmc_dev *pmcdev) return pmc_core_resume_common(pmcdev); } +static struct pmc_dev_info cnp_pmc_dev = { + .map = &cnp_reg_map, + .suspend = cnl_suspend, + .resume = cnl_resume, +}; + int cnp_core_init(struct pmc_dev *pmcdev) { - struct pmc *pmc = pmcdev->pmcs[PMC_IDX_MAIN]; - int ret; - - pmcdev->suspend = cnl_suspend; - pmcdev->resume = cnl_resume; - - pmc->map = &cnp_reg_map; - ret = get_primary_reg_base(pmc); - if (ret) - return ret; - - pmc_core_get_low_power_modes(pmcdev); - - return 0; + return generic_core_init(pmcdev, &cnp_pmc_dev); } diff --git a/drivers/platform/x86/intel/pmc/core.c b/drivers/platform/x86/intel/pmc/core.c index 10f04b944117..d1cbf49ce5bc 100644 --- a/drivers/platform/x86/intel/pmc/core.c +++ b/drivers/platform/x86/intel/pmc/core.c @@ -1345,6 +1345,48 @@ static void pmc_core_dbgfs_register(struct pmc_dev *pmcdev) } } +/* + * When supported, ssram init is used to achieve all available PMCs. + * If ssram init fails, this function uses legacy method to at least get the + * primary PMC. + */ +int generic_core_init(struct pmc_dev *pmcdev, struct pmc_dev_info *pmc_dev_info) +{ + struct pmc *pmc = pmcdev->pmcs[PMC_IDX_MAIN]; + bool ssram; + int ret; + + pmcdev->suspend = pmc_dev_info->suspend; + pmcdev->resume = pmc_dev_info->resume; + + ssram = pmc_dev_info->regmap_list != NULL; + if (ssram) { + pmcdev->regmap_list = pmc_dev_info->regmap_list; + ret = pmc_core_ssram_init(pmcdev, pmc_dev_info->pci_func); + if (ret) { + dev_warn(&pmcdev->pdev->dev, + "ssram init failed, %d, using legacy init\n", ret); + ssram = false; + } + } + + if (!ssram) { + pmc->map = pmc_dev_info->map; + ret = get_primary_reg_base(pmc); + if (ret) + return ret; + } + + pmc_core_get_low_power_modes(pmcdev); + if (pmc_dev_info->dmu_guid) + pmc_core_punit_pmt_init(pmcdev, pmc_dev_info->dmu_guid); + + if (ssram) + return pmc_core_ssram_get_lpm_reqs(pmcdev); + + return 0; +} + static const struct x86_cpu_id intel_pmc_core_ids[] = { X86_MATCH_VFM(INTEL_SKYLAKE_L, spt_core_init), X86_MATCH_VFM(INTEL_SKYLAKE, spt_core_init), diff --git a/drivers/platform/x86/intel/pmc/core.h b/drivers/platform/x86/intel/pmc/core.h index a0f6cc427ddc..7c9e999ee631 100644 --- a/drivers/platform/x86/intel/pmc/core.h +++ b/drivers/platform/x86/intel/pmc/core.h @@ -435,6 +435,27 @@ enum pmc_index { PMC_IDX_MAX }; +/** + * struct pmc_dev_info - Structure to keep PMC device info + * @pci_func: Function number of the primary PMC + * @dmu_guid: Die Management Unit GUID + * @regmap_list: Pointer to a list of pmc_info structure that could be + * available for the platform. When set, this field implies + * SSRAM support. + * @map: Pointer to a pmc_reg_map struct that contains platform + * specific attributes of the primary PMC + * @suspend: Function to perform platform specific suspend + * @resume: Function to perform platform specific resume + */ +struct pmc_dev_info { + u8 pci_func; + u32 dmu_guid; + struct pmc_info *regmap_list; + const struct pmc_reg_map *map; + void (*suspend)(struct pmc_dev *pmcdev); + int (*resume)(struct pmc_dev *pmcdev); +}; + extern const struct pmc_bit_map msr_map[]; extern const struct pmc_bit_map spt_pll_map[]; extern const struct pmc_bit_map spt_mphy_map[]; @@ -591,6 +612,7 @@ extern void pmc_core_set_device_d3(unsigned int device); extern int pmc_core_ssram_init(struct pmc_dev *pmcdev, int func); +int generic_core_init(struct pmc_dev *pmcdev, struct pmc_dev_info *pmc_dev_info); int spt_core_init(struct pmc_dev *pmcdev); int cnp_core_init(struct pmc_dev *pmcdev); int icl_core_init(struct pmc_dev *pmcdev); diff --git a/drivers/platform/x86/intel/pmc/icl.c b/drivers/platform/x86/intel/pmc/icl.c index 71b0fd6cb7d8..0e4565dea045 100644 --- a/drivers/platform/x86/intel/pmc/icl.c +++ b/drivers/platform/x86/intel/pmc/icl.c @@ -50,18 +50,11 @@ const struct pmc_reg_map icl_reg_map = { .etr3_offset = ETR3_OFFSET, }; +static struct pmc_dev_info icl_pmc_dev = { + .map = &icl_reg_map, +}; + int icl_core_init(struct pmc_dev *pmcdev) { - struct pmc *pmc = pmcdev->pmcs[PMC_IDX_MAIN]; - int ret; - - pmc->map = &icl_reg_map; - - ret = get_primary_reg_base(pmc); - if (ret) - return ret; - - pmc_core_get_low_power_modes(pmcdev); - - return ret; + return generic_core_init(pmcdev, &icl_pmc_dev); } diff --git a/drivers/platform/x86/intel/pmc/lnl.c b/drivers/platform/x86/intel/pmc/lnl.c index 09b13df90d68..1142e65225be 100644 --- a/drivers/platform/x86/intel/pmc/lnl.c +++ b/drivers/platform/x86/intel/pmc/lnl.c @@ -550,22 +550,14 @@ static int lnl_resume(struct pmc_dev *pmcdev) return cnl_resume(pmcdev); } +static struct pmc_dev_info lnl_pmc_dev = { + .map = &lnl_socm_reg_map, + .suspend = cnl_suspend, + .resume = lnl_resume, +}; + int lnl_core_init(struct pmc_dev *pmcdev) { - int ret; - struct pmc *pmc = pmcdev->pmcs[PMC_IDX_MAIN]; - lnl_d3_fixup(); - - pmcdev->suspend = cnl_suspend; - pmcdev->resume = lnl_resume; - - pmc->map = &lnl_socm_reg_map; - ret = get_primary_reg_base(pmc); - if (ret) - return ret; - - pmc_core_get_low_power_modes(pmcdev); - - return 0; + return generic_core_init(pmcdev, &lnl_pmc_dev); } diff --git a/drivers/platform/x86/intel/pmc/mtl.c b/drivers/platform/x86/intel/pmc/mtl.c index 07687a3e436d..28ea8fe8a493 100644 --- a/drivers/platform/x86/intel/pmc/mtl.c +++ b/drivers/platform/x86/intel/pmc/mtl.c @@ -990,39 +990,17 @@ static int mtl_resume(struct pmc_dev *pmcdev) return cnl_resume(pmcdev); } +static struct pmc_dev_info mtl_pmc_dev = { + .pci_func = 2, + .dmu_guid = MTL_PMT_DMU_GUID, + .regmap_list = mtl_pmc_info_list, + .map = &mtl_socm_reg_map, + .suspend = cnl_suspend, + .resume = mtl_resume, +}; + int mtl_core_init(struct pmc_dev *pmcdev) { - struct pmc *pmc = pmcdev->pmcs[PMC_IDX_MAIN]; - int ret; - int func = 2; - bool ssram_init = true; - mtl_d3_fixup(); - - pmcdev->suspend = cnl_suspend; - pmcdev->resume = mtl_resume; - pmcdev->regmap_list = mtl_pmc_info_list; - - /* - * If ssram init fails use legacy method to at least get the - * primary PMC - */ - ret = pmc_core_ssram_init(pmcdev, func); - if (ret) { - ssram_init = false; - dev_warn(&pmcdev->pdev->dev, - "ssram init failed, %d, using legacy init\n", ret); - pmc->map = &mtl_socm_reg_map; - ret = get_primary_reg_base(pmc); - if (ret) - return ret; - } - - pmc_core_get_low_power_modes(pmcdev); - pmc_core_punit_pmt_init(pmcdev, MTL_PMT_DMU_GUID); - - if (ssram_init) - return pmc_core_ssram_get_lpm_reqs(pmcdev); - - return 0; + return generic_core_init(pmcdev, &mtl_pmc_dev); } diff --git a/drivers/platform/x86/intel/pmc/spt.c b/drivers/platform/x86/intel/pmc/spt.c index ab993a69e33e..ab5f66fcb0c3 100644 --- a/drivers/platform/x86/intel/pmc/spt.c +++ b/drivers/platform/x86/intel/pmc/spt.c @@ -134,18 +134,11 @@ const struct pmc_reg_map spt_reg_map = { .pm_vric1_offset = SPT_PMC_VRIC1_OFFSET, }; +static struct pmc_dev_info spt_pmc_dev = { + .map = &spt_reg_map, +}; + int spt_core_init(struct pmc_dev *pmcdev) { - struct pmc *pmc = pmcdev->pmcs[PMC_IDX_MAIN]; - int ret; - - pmc->map = &spt_reg_map; - - ret = get_primary_reg_base(pmc); - if (ret) - return ret; - - pmc_core_get_low_power_modes(pmcdev); - - return ret; + return generic_core_init(pmcdev, &spt_pmc_dev); } diff --git a/drivers/platform/x86/intel/pmc/tgl.c b/drivers/platform/x86/intel/pmc/tgl.c index 4fec43d212d0..bc3cb949c672 100644 --- a/drivers/platform/x86/intel/pmc/tgl.c +++ b/drivers/platform/x86/intel/pmc/tgl.c @@ -285,35 +285,36 @@ free_acpi_obj: ACPI_FREE(out_obj); } -static int tgl_core_generic_init(struct pmc_dev *pmcdev, int pch_tp) -{ - struct pmc *pmc = pmcdev->pmcs[PMC_IDX_MAIN]; - int ret; +static struct pmc_dev_info tgl_l_pmc_dev = { + .map = &tgl_reg_map, + .suspend = cnl_suspend, + .resume = cnl_resume, +}; - if (pch_tp == PCH_H) - pmc->map = &tgl_h_reg_map; - else - pmc->map = &tgl_reg_map; +static struct pmc_dev_info tgl_pmc_dev = { + .map = &tgl_h_reg_map, + .suspend = cnl_suspend, + .resume = cnl_resume, +}; - pmcdev->suspend = cnl_suspend; - pmcdev->resume = cnl_resume; +static int tgl_core_generic_init(struct pmc_dev *pmcdev, struct pmc_dev_info *pmc_dev_info) +{ + int ret; - ret = get_primary_reg_base(pmc); + ret = generic_core_init(pmcdev, pmc_dev_info); if (ret) return ret; - pmc_core_get_low_power_modes(pmcdev); pmc_core_get_tgl_lpm_reqs(pmcdev->pdev); - return 0; } int tgl_l_core_init(struct pmc_dev *pmcdev) { - return tgl_core_generic_init(pmcdev, PCH_LP); + return tgl_core_generic_init(pmcdev, &tgl_l_pmc_dev); } int tgl_core_init(struct pmc_dev *pmcdev) { - return tgl_core_generic_init(pmcdev, PCH_H); + return tgl_core_generic_init(pmcdev, &tgl_pmc_dev); } -- 2.51.0 From 45fa1a0d4d8759787bf62b49019952e2d56a66f9 Mon Sep 17 00:00:00 2001 From: Xi Pardee Date: Fri, 7 Feb 2025 14:56:10 -0800 Subject: [PATCH 04/16] platform/x86/intel/pmc: Remove simple init functions MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Remove simple init functions to avoid duplicate code. Store init function performing architecture specific action in the corresponding pmc_dev_info structure. Replace init function with pmc_dev_info structure in X86_MATCH_VFM() of core.c. Signed-off-by: Xi Pardee Link: https://lore.kernel.org/r/20250207225615.401235-5-xi.pardee@linux.intel.com Reviewed-by: Ilpo Järvinen Signed-off-by: Ilpo Järvinen --- drivers/platform/x86/intel/pmc/adl.c | 7 +-- drivers/platform/x86/intel/pmc/arl.c | 15 ++++--- drivers/platform/x86/intel/pmc/cnp.c | 6 +-- drivers/platform/x86/intel/pmc/core.c | 61 +++++++++++++++------------ drivers/platform/x86/intel/pmc/core.h | 21 +++++---- drivers/platform/x86/intel/pmc/icl.c | 7 +-- drivers/platform/x86/intel/pmc/lnl.c | 15 ++++--- drivers/platform/x86/intel/pmc/mtl.c | 15 ++++--- drivers/platform/x86/intel/pmc/spt.c | 7 +-- drivers/platform/x86/intel/pmc/tgl.c | 34 ++++++--------- 10 files changed, 86 insertions(+), 102 deletions(-) diff --git a/drivers/platform/x86/intel/pmc/adl.c b/drivers/platform/x86/intel/pmc/adl.c index ac37f4ece9c7..de361a316d51 100644 --- a/drivers/platform/x86/intel/pmc/adl.c +++ b/drivers/platform/x86/intel/pmc/adl.c @@ -311,13 +311,8 @@ const struct pmc_reg_map adl_reg_map = { .pson_residency_counter_step = TGL_PSON_RES_COUNTER_STEP, }; -static struct pmc_dev_info adl_pmc_dev = { +struct pmc_dev_info adl_pmc_dev = { .map = &adl_reg_map, .suspend = cnl_suspend, .resume = cnl_resume, }; - -int adl_core_init(struct pmc_dev *pmcdev) -{ - return generic_core_init(pmcdev, &adl_pmc_dev); -} diff --git a/drivers/platform/x86/intel/pmc/arl.c b/drivers/platform/x86/intel/pmc/arl.c index 91f8e9ab1c2e..f57da4e01f6f 100644 --- a/drivers/platform/x86/intel/pmc/arl.c +++ b/drivers/platform/x86/intel/pmc/arl.c @@ -691,17 +691,18 @@ static int arl_resume(struct pmc_dev *pmcdev) return cnl_resume(pmcdev); } -static struct pmc_dev_info arl_pmc_dev = { +static int arl_core_init(struct pmc_dev *pmcdev, struct pmc_dev_info *pmc_dev_info) +{ + arl_d3_fixup(); + return generic_core_init(pmcdev, pmc_dev_info); +} + +struct pmc_dev_info arl_pmc_dev = { .pci_func = 0, .dmu_guid = ARL_PMT_DMU_GUID, .regmap_list = arl_pmc_info_list, .map = &arl_socs_reg_map, .suspend = cnl_suspend, .resume = arl_resume, + .init = arl_core_init, }; - -int arl_core_init(struct pmc_dev *pmcdev) -{ - arl_d3_fixup(); - return generic_core_init(pmcdev, &arl_pmc_dev); -} diff --git a/drivers/platform/x86/intel/pmc/cnp.c b/drivers/platform/x86/intel/pmc/cnp.c index 6d268058e40b..f147ec51c7fd 100644 --- a/drivers/platform/x86/intel/pmc/cnp.c +++ b/drivers/platform/x86/intel/pmc/cnp.c @@ -274,13 +274,9 @@ int cnl_resume(struct pmc_dev *pmcdev) return pmc_core_resume_common(pmcdev); } -static struct pmc_dev_info cnp_pmc_dev = { +struct pmc_dev_info cnp_pmc_dev = { .map = &cnp_reg_map, .suspend = cnl_suspend, .resume = cnl_resume, }; -int cnp_core_init(struct pmc_dev *pmcdev) -{ - return generic_core_init(pmcdev, &cnp_pmc_dev); -} diff --git a/drivers/platform/x86/intel/pmc/core.c b/drivers/platform/x86/intel/pmc/core.c index d1cbf49ce5bc..628cb22221fb 100644 --- a/drivers/platform/x86/intel/pmc/core.c +++ b/drivers/platform/x86/intel/pmc/core.c @@ -1388,29 +1388,29 @@ int generic_core_init(struct pmc_dev *pmcdev, struct pmc_dev_info *pmc_dev_info) } static const struct x86_cpu_id intel_pmc_core_ids[] = { - X86_MATCH_VFM(INTEL_SKYLAKE_L, spt_core_init), - X86_MATCH_VFM(INTEL_SKYLAKE, spt_core_init), - X86_MATCH_VFM(INTEL_KABYLAKE_L, spt_core_init), - X86_MATCH_VFM(INTEL_KABYLAKE, spt_core_init), - X86_MATCH_VFM(INTEL_CANNONLAKE_L, cnp_core_init), - X86_MATCH_VFM(INTEL_ICELAKE_L, icl_core_init), - X86_MATCH_VFM(INTEL_ICELAKE_NNPI, icl_core_init), - X86_MATCH_VFM(INTEL_COMETLAKE, cnp_core_init), - X86_MATCH_VFM(INTEL_COMETLAKE_L, cnp_core_init), - X86_MATCH_VFM(INTEL_TIGERLAKE_L, tgl_l_core_init), - X86_MATCH_VFM(INTEL_TIGERLAKE, tgl_core_init), - X86_MATCH_VFM(INTEL_ATOM_TREMONT, tgl_l_core_init), - X86_MATCH_VFM(INTEL_ATOM_TREMONT_L, icl_core_init), - X86_MATCH_VFM(INTEL_ROCKETLAKE, tgl_core_init), - X86_MATCH_VFM(INTEL_ALDERLAKE_L, tgl_l_core_init), - X86_MATCH_VFM(INTEL_ATOM_GRACEMONT, tgl_l_core_init), - X86_MATCH_VFM(INTEL_ALDERLAKE, adl_core_init), - X86_MATCH_VFM(INTEL_RAPTORLAKE_P, tgl_l_core_init), - X86_MATCH_VFM(INTEL_RAPTORLAKE, adl_core_init), - X86_MATCH_VFM(INTEL_RAPTORLAKE_S, adl_core_init), - X86_MATCH_VFM(INTEL_METEORLAKE_L, mtl_core_init), - X86_MATCH_VFM(INTEL_ARROWLAKE, arl_core_init), - X86_MATCH_VFM(INTEL_LUNARLAKE_M, lnl_core_init), + X86_MATCH_VFM(INTEL_SKYLAKE_L, &spt_pmc_dev), + X86_MATCH_VFM(INTEL_SKYLAKE, &spt_pmc_dev), + X86_MATCH_VFM(INTEL_KABYLAKE_L, &spt_pmc_dev), + X86_MATCH_VFM(INTEL_KABYLAKE, &spt_pmc_dev), + X86_MATCH_VFM(INTEL_CANNONLAKE_L, &cnp_pmc_dev), + X86_MATCH_VFM(INTEL_ICELAKE_L, &icl_pmc_dev), + X86_MATCH_VFM(INTEL_ICELAKE_NNPI, &icl_pmc_dev), + X86_MATCH_VFM(INTEL_COMETLAKE, &cnp_pmc_dev), + X86_MATCH_VFM(INTEL_COMETLAKE_L, &cnp_pmc_dev), + X86_MATCH_VFM(INTEL_TIGERLAKE_L, &tgl_l_pmc_dev), + X86_MATCH_VFM(INTEL_TIGERLAKE, &tgl_pmc_dev), + X86_MATCH_VFM(INTEL_ATOM_TREMONT, &tgl_l_pmc_dev), + X86_MATCH_VFM(INTEL_ATOM_TREMONT_L, &icl_pmc_dev), + X86_MATCH_VFM(INTEL_ROCKETLAKE, &tgl_pmc_dev), + X86_MATCH_VFM(INTEL_ALDERLAKE_L, &tgl_l_pmc_dev), + X86_MATCH_VFM(INTEL_ATOM_GRACEMONT, &tgl_l_pmc_dev), + X86_MATCH_VFM(INTEL_ALDERLAKE, &adl_pmc_dev), + X86_MATCH_VFM(INTEL_RAPTORLAKE_P, &tgl_l_pmc_dev), + X86_MATCH_VFM(INTEL_RAPTORLAKE, &adl_pmc_dev), + X86_MATCH_VFM(INTEL_RAPTORLAKE_S, &adl_pmc_dev), + X86_MATCH_VFM(INTEL_METEORLAKE_L, &mtl_pmc_dev), + X86_MATCH_VFM(INTEL_ARROWLAKE, &arl_pmc_dev), + X86_MATCH_VFM(INTEL_LUNARLAKE_M, &lnl_pmc_dev), {} }; @@ -1494,7 +1494,7 @@ static int pmc_core_probe(struct platform_device *pdev) static bool device_initialized; struct pmc_dev *pmcdev; const struct x86_cpu_id *cpu_id; - int (*core_init)(struct pmc_dev *pmcdev); + struct pmc_dev_info *pmc_dev_info; struct pmc *primary_pmc; int ret; @@ -1514,7 +1514,7 @@ static int pmc_core_probe(struct platform_device *pdev) if (!cpu_id) return -ENODEV; - core_init = (int (*)(struct pmc_dev *))cpu_id->driver_data; + pmc_dev_info = (struct pmc_dev_info *)cpu_id->driver_data; /* Primary PMC */ primary_pmc = devm_kzalloc(&pdev->dev, sizeof(*primary_pmc), GFP_KERNEL); @@ -1536,11 +1536,16 @@ static int pmc_core_probe(struct platform_device *pdev) * Sunrisepoint PCH regmap can't be used. Use Cannon Lake PCH regmap * in this case. */ - if (core_init == spt_core_init && !pci_dev_present(pmc_pci_ids)) - core_init = cnp_core_init; + if (pmc_dev_info == &spt_pmc_dev && !pci_dev_present(pmc_pci_ids)) + pmc_dev_info = &cnp_pmc_dev; mutex_init(&pmcdev->lock); - ret = core_init(pmcdev); + + if (pmc_dev_info->init) + ret = pmc_dev_info->init(pmcdev, pmc_dev_info); + else + ret = generic_core_init(pmcdev, pmc_dev_info); + if (ret) { pmc_core_clean_structure(pdev); return ret; diff --git a/drivers/platform/x86/intel/pmc/core.h b/drivers/platform/x86/intel/pmc/core.h index 7c9e999ee631..b004b784bfeb 100644 --- a/drivers/platform/x86/intel/pmc/core.h +++ b/drivers/platform/x86/intel/pmc/core.h @@ -446,6 +446,7 @@ enum pmc_index { * specific attributes of the primary PMC * @suspend: Function to perform platform specific suspend * @resume: Function to perform platform specific resume + * @init: Function to perform platform specific init action */ struct pmc_dev_info { u8 pci_func; @@ -454,6 +455,7 @@ struct pmc_dev_info { const struct pmc_reg_map *map; void (*suspend)(struct pmc_dev *pmcdev); int (*resume)(struct pmc_dev *pmcdev); + int (*init)(struct pmc_dev *pmcdev, struct pmc_dev_info *pmc_dev_info); }; extern const struct pmc_bit_map msr_map[]; @@ -613,15 +615,16 @@ extern void pmc_core_set_device_d3(unsigned int device); extern int pmc_core_ssram_init(struct pmc_dev *pmcdev, int func); int generic_core_init(struct pmc_dev *pmcdev, struct pmc_dev_info *pmc_dev_info); -int spt_core_init(struct pmc_dev *pmcdev); -int cnp_core_init(struct pmc_dev *pmcdev); -int icl_core_init(struct pmc_dev *pmcdev); -int tgl_core_init(struct pmc_dev *pmcdev); -int tgl_l_core_init(struct pmc_dev *pmcdev); -int adl_core_init(struct pmc_dev *pmcdev); -int mtl_core_init(struct pmc_dev *pmcdev); -int arl_core_init(struct pmc_dev *pmcdev); -int lnl_core_init(struct pmc_dev *pmcdev); + +extern struct pmc_dev_info spt_pmc_dev; +extern struct pmc_dev_info cnp_pmc_dev; +extern struct pmc_dev_info icl_pmc_dev; +extern struct pmc_dev_info tgl_l_pmc_dev; +extern struct pmc_dev_info tgl_pmc_dev; +extern struct pmc_dev_info adl_pmc_dev; +extern struct pmc_dev_info mtl_pmc_dev; +extern struct pmc_dev_info arl_pmc_dev; +extern struct pmc_dev_info lnl_pmc_dev; void cnl_suspend(struct pmc_dev *pmcdev); int cnl_resume(struct pmc_dev *pmcdev); diff --git a/drivers/platform/x86/intel/pmc/icl.c b/drivers/platform/x86/intel/pmc/icl.c index 0e4565dea045..6952c8ef58a0 100644 --- a/drivers/platform/x86/intel/pmc/icl.c +++ b/drivers/platform/x86/intel/pmc/icl.c @@ -50,11 +50,6 @@ const struct pmc_reg_map icl_reg_map = { .etr3_offset = ETR3_OFFSET, }; -static struct pmc_dev_info icl_pmc_dev = { +struct pmc_dev_info icl_pmc_dev = { .map = &icl_reg_map, }; - -int icl_core_init(struct pmc_dev *pmcdev) -{ - return generic_core_init(pmcdev, &icl_pmc_dev); -} diff --git a/drivers/platform/x86/intel/pmc/lnl.c b/drivers/platform/x86/intel/pmc/lnl.c index 1142e65225be..5a78807b9bc2 100644 --- a/drivers/platform/x86/intel/pmc/lnl.c +++ b/drivers/platform/x86/intel/pmc/lnl.c @@ -550,14 +550,15 @@ static int lnl_resume(struct pmc_dev *pmcdev) return cnl_resume(pmcdev); } -static struct pmc_dev_info lnl_pmc_dev = { +static int lnl_core_init(struct pmc_dev *pmcdev, struct pmc_dev_info *pmc_dev_info) +{ + lnl_d3_fixup(); + return generic_core_init(pmcdev, pmc_dev_info); +} + +struct pmc_dev_info lnl_pmc_dev = { .map = &lnl_socm_reg_map, .suspend = cnl_suspend, .resume = lnl_resume, + .init = lnl_core_init, }; - -int lnl_core_init(struct pmc_dev *pmcdev) -{ - lnl_d3_fixup(); - return generic_core_init(pmcdev, &lnl_pmc_dev); -} diff --git a/drivers/platform/x86/intel/pmc/mtl.c b/drivers/platform/x86/intel/pmc/mtl.c index 28ea8fe8a493..705b7e1b0b86 100644 --- a/drivers/platform/x86/intel/pmc/mtl.c +++ b/drivers/platform/x86/intel/pmc/mtl.c @@ -990,17 +990,18 @@ static int mtl_resume(struct pmc_dev *pmcdev) return cnl_resume(pmcdev); } -static struct pmc_dev_info mtl_pmc_dev = { +static int mtl_core_init(struct pmc_dev *pmcdev, struct pmc_dev_info *pmc_dev_info) +{ + mtl_d3_fixup(); + return generic_core_init(pmcdev, pmc_dev_info); +} + +struct pmc_dev_info mtl_pmc_dev = { .pci_func = 2, .dmu_guid = MTL_PMT_DMU_GUID, .regmap_list = mtl_pmc_info_list, .map = &mtl_socm_reg_map, .suspend = cnl_suspend, .resume = mtl_resume, + .init = mtl_core_init, }; - -int mtl_core_init(struct pmc_dev *pmcdev) -{ - mtl_d3_fixup(); - return generic_core_init(pmcdev, &mtl_pmc_dev); -} diff --git a/drivers/platform/x86/intel/pmc/spt.c b/drivers/platform/x86/intel/pmc/spt.c index ab5f66fcb0c3..956b2ec1c751 100644 --- a/drivers/platform/x86/intel/pmc/spt.c +++ b/drivers/platform/x86/intel/pmc/spt.c @@ -134,11 +134,6 @@ const struct pmc_reg_map spt_reg_map = { .pm_vric1_offset = SPT_PMC_VRIC1_OFFSET, }; -static struct pmc_dev_info spt_pmc_dev = { +struct pmc_dev_info spt_pmc_dev = { .map = &spt_reg_map, }; - -int spt_core_init(struct pmc_dev *pmcdev) -{ - return generic_core_init(pmcdev, &spt_pmc_dev); -} diff --git a/drivers/platform/x86/intel/pmc/tgl.c b/drivers/platform/x86/intel/pmc/tgl.c index bc3cb949c672..758bd8d162e5 100644 --- a/drivers/platform/x86/intel/pmc/tgl.c +++ b/drivers/platform/x86/intel/pmc/tgl.c @@ -285,19 +285,7 @@ free_acpi_obj: ACPI_FREE(out_obj); } -static struct pmc_dev_info tgl_l_pmc_dev = { - .map = &tgl_reg_map, - .suspend = cnl_suspend, - .resume = cnl_resume, -}; - -static struct pmc_dev_info tgl_pmc_dev = { - .map = &tgl_h_reg_map, - .suspend = cnl_suspend, - .resume = cnl_resume, -}; - -static int tgl_core_generic_init(struct pmc_dev *pmcdev, struct pmc_dev_info *pmc_dev_info) +static int tgl_core_init(struct pmc_dev *pmcdev, struct pmc_dev_info *pmc_dev_info) { int ret; @@ -309,12 +297,16 @@ static int tgl_core_generic_init(struct pmc_dev *pmcdev, struct pmc_dev_info *pm return 0; } -int tgl_l_core_init(struct pmc_dev *pmcdev) -{ - return tgl_core_generic_init(pmcdev, &tgl_l_pmc_dev); -} +struct pmc_dev_info tgl_l_pmc_dev = { + .map = &tgl_reg_map, + .suspend = cnl_suspend, + .resume = cnl_resume, + .init = tgl_core_init, +}; -int tgl_core_init(struct pmc_dev *pmcdev) -{ - return tgl_core_generic_init(pmcdev, &tgl_pmc_dev); -} +struct pmc_dev_info tgl_pmc_dev = { + .map = &tgl_h_reg_map, + .suspend = cnl_suspend, + .resume = cnl_resume, + .init = tgl_core_init, +}; -- 2.51.0 From bd820906ea9dc3acfcac9de4f1be89b78609e2ac Mon Sep 17 00:00:00 2001 From: Xi Pardee Date: Fri, 7 Feb 2025 14:56:12 -0800 Subject: [PATCH 05/16] platform/x86/intel/pmc: Add Arrow Lake U/H support to intel_pmc_core driver MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Add Arrow Lake U and Arrow Lake H support in intel_pmc_core driver. Signed-off-by: Rajvi Jingar Signed-off-by: Xi Pardee Link: https://lore.kernel.org/r/20250207225615.401235-7-xi.pardee@linux.intel.com Reviewed-by: Ilpo Järvinen Signed-off-by: Ilpo Järvinen --- drivers/platform/x86/intel/pmc/arl.c | 37 +++++++++++++++++++++++++++ drivers/platform/x86/intel/pmc/core.c | 2 ++ drivers/platform/x86/intel/pmc/core.h | 1 + 3 files changed, 40 insertions(+) diff --git a/drivers/platform/x86/intel/pmc/arl.c b/drivers/platform/x86/intel/pmc/arl.c index f57da4e01f6f..54b0e8e56de9 100644 --- a/drivers/platform/x86/intel/pmc/arl.c +++ b/drivers/platform/x86/intel/pmc/arl.c @@ -16,6 +16,7 @@ #define IOEP_LPM_REQ_GUID 0x5077612 #define SOCS_LPM_REQ_GUID 0x8478657 #define PCHS_LPM_REQ_GUID 0x9684572 +#define SOCM_LPM_REQ_GUID 0x2625030 static const u8 ARL_LPM_REG_INDEX[] = {0, 4, 5, 6, 8, 9, 10, 11, 12, 13, 14, 15, 16, 20}; @@ -650,6 +651,7 @@ const struct pmc_reg_map arl_pchs_reg_map = { .etr3_offset = ETR3_OFFSET, }; +#define PMC_DEVID_SOCM 0x777f #define PMC_DEVID_SOCS 0xae7f #define PMC_DEVID_IOEP 0x7ecf #define PMC_DEVID_PCHS 0x7f27 @@ -669,11 +671,17 @@ static struct pmc_info arl_pmc_info_list[] = { .devid = PMC_DEVID_PCHS, .map = &arl_pchs_reg_map, }, + { + .guid = SOCM_LPM_REQ_GUID, + .devid = PMC_DEVID_SOCM, + .map = &mtl_socm_reg_map, + }, {} }; #define ARL_NPU_PCI_DEV 0xad1d #define ARL_GNA_PCI_DEV 0xae4c +#define ARL_H_GNA_PCI_DEV 0x774c /* * Set power state of select devices that do not have drivers to D3 * so that they do not block Package C entry. @@ -684,6 +692,12 @@ static void arl_d3_fixup(void) pmc_core_set_device_d3(ARL_GNA_PCI_DEV); } +static void arl_h_d3_fixup(void) +{ + pmc_core_set_device_d3(ARL_NPU_PCI_DEV); + pmc_core_set_device_d3(ARL_H_GNA_PCI_DEV); +} + static int arl_resume(struct pmc_dev *pmcdev) { arl_d3_fixup(); @@ -691,12 +705,25 @@ static int arl_resume(struct pmc_dev *pmcdev) return cnl_resume(pmcdev); } +static int arl_h_resume(struct pmc_dev *pmcdev) +{ + arl_h_d3_fixup(); + + return cnl_resume(pmcdev); +} + static int arl_core_init(struct pmc_dev *pmcdev, struct pmc_dev_info *pmc_dev_info) { arl_d3_fixup(); return generic_core_init(pmcdev, pmc_dev_info); } +static int arl_h_core_init(struct pmc_dev *pmcdev, struct pmc_dev_info *pmc_dev_info) +{ + arl_h_d3_fixup(); + return generic_core_init(pmcdev, pmc_dev_info); +} + struct pmc_dev_info arl_pmc_dev = { .pci_func = 0, .dmu_guid = ARL_PMT_DMU_GUID, @@ -706,3 +733,13 @@ struct pmc_dev_info arl_pmc_dev = { .resume = arl_resume, .init = arl_core_init, }; + +struct pmc_dev_info arl_h_pmc_dev = { + .pci_func = 2, + .dmu_guid = ARL_PMT_DMU_GUID, + .regmap_list = arl_pmc_info_list, + .map = &mtl_socm_reg_map, + .suspend = cnl_suspend, + .resume = arl_h_resume, + .init = arl_h_core_init, +}; diff --git a/drivers/platform/x86/intel/pmc/core.c b/drivers/platform/x86/intel/pmc/core.c index 628cb22221fb..d819478fea29 100644 --- a/drivers/platform/x86/intel/pmc/core.c +++ b/drivers/platform/x86/intel/pmc/core.c @@ -1410,6 +1410,8 @@ static const struct x86_cpu_id intel_pmc_core_ids[] = { X86_MATCH_VFM(INTEL_RAPTORLAKE_S, &adl_pmc_dev), X86_MATCH_VFM(INTEL_METEORLAKE_L, &mtl_pmc_dev), X86_MATCH_VFM(INTEL_ARROWLAKE, &arl_pmc_dev), + X86_MATCH_VFM(INTEL_ARROWLAKE_H, &arl_h_pmc_dev), + X86_MATCH_VFM(INTEL_ARROWLAKE_U, &arl_h_pmc_dev), X86_MATCH_VFM(INTEL_LUNARLAKE_M, &lnl_pmc_dev), {} }; diff --git a/drivers/platform/x86/intel/pmc/core.h b/drivers/platform/x86/intel/pmc/core.h index b004b784bfeb..987fde3ffc1c 100644 --- a/drivers/platform/x86/intel/pmc/core.h +++ b/drivers/platform/x86/intel/pmc/core.h @@ -624,6 +624,7 @@ extern struct pmc_dev_info tgl_pmc_dev; extern struct pmc_dev_info adl_pmc_dev; extern struct pmc_dev_info mtl_pmc_dev; extern struct pmc_dev_info arl_pmc_dev; +extern struct pmc_dev_info arl_h_pmc_dev; extern struct pmc_dev_info lnl_pmc_dev; void cnl_suspend(struct pmc_dev *pmcdev); -- 2.51.0 From 1046cac109225eda0973b898e053aeb3d6c10e1d Mon Sep 17 00:00:00 2001 From: Sybil Isabel Dorsett Date: Mon, 3 Feb 2025 16:33:15 +0000 Subject: [PATCH 06/16] platform/x86: thinkpad_acpi: Fix invalid fan speed on ThinkPad X120e MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit On ThinkPad X120e, fan speed is reported in ticks per revolution rather than RPM. Recalculate the fan speed value reported for ThinkPad X120e to RPM based on a 22.5 kHz clock. Based on the information on https://www.thinkwiki.org/wiki/How_to_control_fan_speed, the same problem is highly likely to be relevant to at least Edge11, but Edge11 is not addressed in this patch. Signed-off-by: Sybil Isabel Dorsett Reviewed-by: Ilpo Järvinen Link: https://lore.kernel.org/r/20250203163255.5525-1-sybdorsett@proton.me Signed-off-by: Ilpo Järvinen --- drivers/platform/x86/thinkpad_acpi.c | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/drivers/platform/x86/thinkpad_acpi.c b/drivers/platform/x86/thinkpad_acpi.c index 1fcb0f99695a..e7778ea41478 100644 --- a/drivers/platform/x86/thinkpad_acpi.c +++ b/drivers/platform/x86/thinkpad_acpi.c @@ -7885,6 +7885,7 @@ static struct ibm_struct volume_driver_data = { #define FAN_NS_CTRL_STATUS BIT(2) /* Bit which determines control is enabled or not */ #define FAN_NS_CTRL BIT(4) /* Bit which determines control is by host or EC */ +#define FAN_CLOCK_TPM (22500*60) /* Ticks per minute for a 22.5 kHz clock */ enum { /* Fan control constants */ fan_status_offset = 0x2f, /* EC register 0x2f */ @@ -7940,6 +7941,7 @@ static int fan_watchdog_maxinterval; static bool fan_with_ns_addr; static bool ecfw_with_fan_dec_rpm; +static bool fan_speed_in_tpr; static struct mutex fan_mutex; @@ -8142,8 +8144,11 @@ static int fan_get_speed(unsigned int *speed) !acpi_ec_read(fan_rpm_offset + 1, &hi))) return -EIO; - if (likely(speed)) + if (likely(speed)) { *speed = (hi << 8) | lo; + if (fan_speed_in_tpr && *speed != 0) + *speed = FAN_CLOCK_TPM / *speed; + } break; case TPACPI_FAN_RD_TPEC_NS: if (!acpi_ec_read(fan_rpm_status_ns, &lo)) @@ -8176,8 +8181,11 @@ static int fan2_get_speed(unsigned int *speed) if (rc) return -EIO; - if (likely(speed)) + if (likely(speed)) { *speed = (hi << 8) | lo; + if (fan_speed_in_tpr && *speed != 0) + *speed = FAN_CLOCK_TPM / *speed; + } break; case TPACPI_FAN_RD_TPEC_NS: @@ -8788,6 +8796,7 @@ static const struct attribute_group fan_driver_attr_group = { #define TPACPI_FAN_NOFAN 0x0008 /* no fan available */ #define TPACPI_FAN_NS 0x0010 /* For EC with non-Standard register addresses */ #define TPACPI_FAN_DECRPM 0x0020 /* For ECFW's with RPM in register as decimal */ +#define TPACPI_FAN_TPR 0x0040 /* Fan speed is in Ticks Per Revolution */ static const struct tpacpi_quirk fan_quirk_table[] __initconst = { TPACPI_QEC_IBM('1', 'Y', TPACPI_FAN_Q1), @@ -8817,6 +8826,7 @@ static const struct tpacpi_quirk fan_quirk_table[] __initconst = { TPACPI_Q_LNV3('R', '0', 'V', TPACPI_FAN_NS), /* 11e Gen5 KL-Y */ TPACPI_Q_LNV3('N', '1', 'O', TPACPI_FAN_NOFAN), /* X1 Tablet (2nd gen) */ TPACPI_Q_LNV3('R', '0', 'Q', TPACPI_FAN_DECRPM),/* L480 */ + TPACPI_Q_LNV('8', 'F', TPACPI_FAN_TPR), /* ThinkPad x120e */ }; static int __init fan_init(struct ibm_init_struct *iibm) @@ -8887,6 +8897,8 @@ static int __init fan_init(struct ibm_init_struct *iibm) if (quirks & TPACPI_FAN_Q1) fan_quirk1_setup(); + if (quirks & TPACPI_FAN_TPR) + fan_speed_in_tpr = true; /* Try and probe the 2nd fan */ tp_features.second_fan = 1; /* needed for get_speed to work */ res = fan2_get_speed(&speed); -- 2.51.0 From 9cff907cbf8c7fb5345918dbcc7b74a01656f34f Mon Sep 17 00:00:00 2001 From: Mark Pearson Date: Thu, 6 Feb 2025 14:39:41 -0500 Subject: [PATCH 07/16] platform/x86: thinkpad_acpi: Support for V9 DYTC platform profiles MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Newer Thinkpad AMD platforms are using V9 DYTC and this changes the profiles used for PSC mode. Add support for this update. Tested on P14s G5 AMD Signed-off-by: Mark Pearson Link: https://lore.kernel.org/r/20250206193953.58365-1-mpearson-lenovo@squebb.ca Reviewed-by: Ilpo Järvinen Signed-off-by: Ilpo Järvinen --- drivers/platform/x86/thinkpad_acpi.c | 34 ++++++++++++++++++---------- 1 file changed, 22 insertions(+), 12 deletions(-) diff --git a/drivers/platform/x86/thinkpad_acpi.c b/drivers/platform/x86/thinkpad_acpi.c index e7778ea41478..99cdea723d32 100644 --- a/drivers/platform/x86/thinkpad_acpi.c +++ b/drivers/platform/x86/thinkpad_acpi.c @@ -10331,6 +10331,10 @@ static struct ibm_struct proxsensor_driver_data = { #define DYTC_MODE_PSC_BALANCE 5 /* Default mode aka balanced */ #define DYTC_MODE_PSC_PERFORM 7 /* High power mode aka performance */ +#define DYTC_MODE_PSCV9_LOWPOWER 1 /* Low power mode */ +#define DYTC_MODE_PSCV9_BALANCE 3 /* Default mode aka balanced */ +#define DYTC_MODE_PSCV9_PERFORM 4 /* High power mode aka performance */ + #define DYTC_ERR_MASK 0xF /* Bits 0-3 in cmd result are the error result */ #define DYTC_ERR_SUCCESS 1 /* CMD completed successful */ @@ -10351,6 +10355,10 @@ static int dytc_capabilities; static bool dytc_mmc_get_available; static int profile_force; +static int platform_psc_profile_lowpower = DYTC_MODE_PSC_LOWPOWER; +static int platform_psc_profile_balanced = DYTC_MODE_PSC_BALANCE; +static int platform_psc_profile_performance = DYTC_MODE_PSC_PERFORM; + static int convert_dytc_to_profile(int funcmode, int dytcmode, enum platform_profile_option *profile) { @@ -10372,19 +10380,15 @@ static int convert_dytc_to_profile(int funcmode, int dytcmode, } return 0; case DYTC_FUNCTION_PSC: - switch (dytcmode) { - case DYTC_MODE_PSC_LOWPOWER: + if (dytcmode == platform_psc_profile_lowpower) *profile = PLATFORM_PROFILE_LOW_POWER; - break; - case DYTC_MODE_PSC_BALANCE: + else if (dytcmode == platform_psc_profile_balanced) *profile = PLATFORM_PROFILE_BALANCED; - break; - case DYTC_MODE_PSC_PERFORM: + else if (dytcmode == platform_psc_profile_performance) *profile = PLATFORM_PROFILE_PERFORMANCE; - break; - default: /* Unknown mode */ + else return -EINVAL; - } + return 0; case DYTC_FUNCTION_AMT: /* For now return balanced. It's the closest we have to 'auto' */ @@ -10405,19 +10409,19 @@ static int convert_profile_to_dytc(enum platform_profile_option profile, int *pe if (dytc_capabilities & BIT(DYTC_FC_MMC)) *perfmode = DYTC_MODE_MMC_LOWPOWER; else if (dytc_capabilities & BIT(DYTC_FC_PSC)) - *perfmode = DYTC_MODE_PSC_LOWPOWER; + *perfmode = platform_psc_profile_lowpower; break; case PLATFORM_PROFILE_BALANCED: if (dytc_capabilities & BIT(DYTC_FC_MMC)) *perfmode = DYTC_MODE_MMC_BALANCE; else if (dytc_capabilities & BIT(DYTC_FC_PSC)) - *perfmode = DYTC_MODE_PSC_BALANCE; + *perfmode = platform_psc_profile_balanced; break; case PLATFORM_PROFILE_PERFORMANCE: if (dytc_capabilities & BIT(DYTC_FC_MMC)) *perfmode = DYTC_MODE_MMC_PERFORM; else if (dytc_capabilities & BIT(DYTC_FC_PSC)) - *perfmode = DYTC_MODE_PSC_PERFORM; + *perfmode = platform_psc_profile_performance; break; default: /* Unknown profile */ return -EOPNOTSUPP; @@ -10611,6 +10615,7 @@ static int tpacpi_dytc_profile_init(struct ibm_init_struct *iibm) if (output & BIT(DYTC_QUERY_ENABLE_BIT)) dytc_version = (output >> DYTC_QUERY_REV_BIT) & 0xF; + dbg_printk(TPACPI_DBG_INIT, "DYTC version %d\n", dytc_version); /* Check DYTC is enabled and supports mode setting */ if (dytc_version < 5) return -ENODEV; @@ -10649,6 +10654,11 @@ static int tpacpi_dytc_profile_init(struct ibm_init_struct *iibm) } } else if (dytc_capabilities & BIT(DYTC_FC_PSC)) { /* PSC MODE */ pr_debug("PSC is supported\n"); + if (dytc_version >= 9) { /* update profiles for DYTC 9 and up */ + platform_psc_profile_lowpower = DYTC_MODE_PSCV9_LOWPOWER; + platform_psc_profile_balanced = DYTC_MODE_PSCV9_BALANCE; + platform_psc_profile_performance = DYTC_MODE_PSCV9_PERFORM; + } } else { dbg_printk(TPACPI_DBG_INIT, "No DYTC support available\n"); return -ENODEV; -- 2.51.0 From fc22b06fbd2afefa1eddff69a6fd30c539cef577 Mon Sep 17 00:00:00 2001 From: Sakari Ailus Date: Tue, 11 Feb 2025 09:28:39 +0200 Subject: [PATCH 08/16] platform/x86: int3472: Use correct type for "polarity", call it gpio_flags MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Struct gpiod_lookup flags field's type is unsigned long. Thus use unsigned long for values to be assigned to that field. Similarly, also call the field gpio_flags which it really is. Signed-off-by: Sakari Ailus Reviewed-by: Hans de Goede Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20250211072841.7713-2-sakari.ailus@linux.intel.com Reviewed-by: Ilpo Järvinen Signed-off-by: Ilpo Järvinen --- drivers/platform/x86/intel/int3472/discrete.c | 39 ++++++++++--------- 1 file changed, 20 insertions(+), 19 deletions(-) diff --git a/drivers/platform/x86/intel/int3472/discrete.c b/drivers/platform/x86/intel/int3472/discrete.c index 31015ebe20d8..b891b064fbf7 100644 --- a/drivers/platform/x86/intel/int3472/discrete.c +++ b/drivers/platform/x86/intel/int3472/discrete.c @@ -55,7 +55,7 @@ static void skl_int3472_log_sensor_module_name(struct int3472_discrete_device *i static int skl_int3472_fill_gpiod_lookup(struct gpiod_lookup *table_entry, struct acpi_resource_gpio *agpio, - const char *func, u32 polarity) + const char *func, unsigned long gpio_flags) { char *path = agpio->resource_source.string_ptr; struct acpi_device *adev; @@ -70,14 +70,14 @@ static int skl_int3472_fill_gpiod_lookup(struct gpiod_lookup *table_entry, if (!adev) return -ENODEV; - *table_entry = GPIO_LOOKUP(acpi_dev_name(adev), agpio->pin_table[0], func, polarity); + *table_entry = GPIO_LOOKUP(acpi_dev_name(adev), agpio->pin_table[0], func, gpio_flags); return 0; } static int skl_int3472_map_gpio_to_sensor(struct int3472_discrete_device *int3472, struct acpi_resource_gpio *agpio, - const char *func, u32 polarity) + const char *func, unsigned long gpio_flags) { int ret; @@ -87,7 +87,7 @@ static int skl_int3472_map_gpio_to_sensor(struct int3472_discrete_device *int347 } ret = skl_int3472_fill_gpiod_lookup(&int3472->gpios.table[int3472->n_sensor_gpios], - agpio, func, polarity); + agpio, func, gpio_flags); if (ret) return ret; @@ -100,7 +100,7 @@ static int skl_int3472_map_gpio_to_sensor(struct int3472_discrete_device *int347 static struct gpio_desc * skl_int3472_gpiod_get_from_temp_lookup(struct int3472_discrete_device *int3472, struct acpi_resource_gpio *agpio, - const char *func, u32 polarity) + const char *func, unsigned long gpio_flags) { struct gpio_desc *desc; int ret; @@ -111,7 +111,7 @@ skl_int3472_gpiod_get_from_temp_lookup(struct int3472_discrete_device *int3472, return ERR_PTR(-ENOMEM); lookup->dev_id = dev_name(int3472->dev); - ret = skl_int3472_fill_gpiod_lookup(&lookup->table[0], agpio, func, polarity); + ret = skl_int3472_fill_gpiod_lookup(&lookup->table[0], agpio, func, gpio_flags); if (ret) return ERR_PTR(ret); @@ -122,32 +122,33 @@ skl_int3472_gpiod_get_from_temp_lookup(struct int3472_discrete_device *int3472, return desc; } -static void int3472_get_func_and_polarity(u8 type, const char **func, u32 *polarity) +static void int3472_get_func_and_polarity(u8 type, const char **func, + unsigned long *gpio_flags) { switch (type) { case INT3472_GPIO_TYPE_RESET: *func = "reset"; - *polarity = GPIO_ACTIVE_LOW; + *gpio_flags = GPIO_ACTIVE_LOW; break; case INT3472_GPIO_TYPE_POWERDOWN: *func = "powerdown"; - *polarity = GPIO_ACTIVE_LOW; + *gpio_flags = GPIO_ACTIVE_LOW; break; case INT3472_GPIO_TYPE_CLK_ENABLE: *func = "clk-enable"; - *polarity = GPIO_ACTIVE_HIGH; + *gpio_flags = GPIO_ACTIVE_HIGH; break; case INT3472_GPIO_TYPE_PRIVACY_LED: *func = "privacy-led"; - *polarity = GPIO_ACTIVE_HIGH; + *gpio_flags = GPIO_ACTIVE_HIGH; break; case INT3472_GPIO_TYPE_POWER_ENABLE: *func = "power-enable"; - *polarity = GPIO_ACTIVE_HIGH; + *gpio_flags = GPIO_ACTIVE_HIGH; break; default: *func = "unknown"; - *polarity = GPIO_ACTIVE_HIGH; + *gpio_flags = GPIO_ACTIVE_HIGH; break; } } @@ -194,7 +195,7 @@ static int skl_int3472_handle_gpio_resources(struct acpi_resource *ares, struct gpio_desc *gpio; const char *err_msg; const char *func; - u32 polarity; + unsigned long gpio_flags; int ret; if (!acpi_gpio_get_io_resource(ares, &agpio)) @@ -217,7 +218,7 @@ static int skl_int3472_handle_gpio_resources(struct acpi_resource *ares, type = FIELD_GET(INT3472_GPIO_DSM_TYPE, obj->integer.value); - int3472_get_func_and_polarity(type, &func, &polarity); + int3472_get_func_and_polarity(type, &func, &gpio_flags); pin = FIELD_GET(INT3472_GPIO_DSM_PIN, obj->integer.value); /* Pin field is not really used under Windows and wraps around at 8 bits */ @@ -227,16 +228,16 @@ static int skl_int3472_handle_gpio_resources(struct acpi_resource *ares, active_value = FIELD_GET(INT3472_GPIO_DSM_SENSOR_ON_VAL, obj->integer.value); if (!active_value) - polarity ^= GPIO_ACTIVE_LOW; + gpio_flags ^= GPIO_ACTIVE_LOW; dev_dbg(int3472->dev, "%s %s pin %d active-%s\n", func, agpio->resource_source.string_ptr, agpio->pin_table[0], - str_high_low(polarity == GPIO_ACTIVE_HIGH)); + str_high_low(gpio_flags == GPIO_ACTIVE_HIGH)); switch (type) { case INT3472_GPIO_TYPE_RESET: case INT3472_GPIO_TYPE_POWERDOWN: - ret = skl_int3472_map_gpio_to_sensor(int3472, agpio, func, polarity); + ret = skl_int3472_map_gpio_to_sensor(int3472, agpio, func, gpio_flags); if (ret) err_msg = "Failed to map GPIO pin to sensor\n"; @@ -244,7 +245,7 @@ static int skl_int3472_handle_gpio_resources(struct acpi_resource *ares, case INT3472_GPIO_TYPE_CLK_ENABLE: case INT3472_GPIO_TYPE_PRIVACY_LED: case INT3472_GPIO_TYPE_POWER_ENABLE: - gpio = skl_int3472_gpiod_get_from_temp_lookup(int3472, agpio, func, polarity); + gpio = skl_int3472_gpiod_get_from_temp_lookup(int3472, agpio, func, gpio_flags); if (IS_ERR(gpio)) { ret = PTR_ERR(gpio); err_msg = "Failed to get GPIO\n"; -- 2.51.0 From 569617dbbd06286fb73f3f1c2ac91e51d863c7de Mon Sep 17 00:00:00 2001 From: Sakari Ailus Date: Tue, 11 Feb 2025 09:28:40 +0200 Subject: [PATCH 09/16] platform/x86: int3472: Call "reset" GPIO "enable" for INT347E MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit The DT bindings for ov7251 specify "enable" GPIO (xshutdown in documentation) but the int3472 indiscriminately provides this as a "reset" GPIO to sensor drivers. Take this into account by assigning it as "enable" with active high polarity for INT347E devices, i.e. ov7251. "reset" with active low polarity remains the default GPIO name for other devices. Signed-off-by: Sakari Ailus Reviewed-by: Hans de Goede Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20250211072841.7713-3-sakari.ailus@linux.intel.com Reviewed-by: Ilpo Järvinen Signed-off-by: Ilpo Järvinen --- drivers/platform/x86/intel/int3472/discrete.c | 52 +++++++++++++++++-- 1 file changed, 48 insertions(+), 4 deletions(-) diff --git a/drivers/platform/x86/intel/int3472/discrete.c b/drivers/platform/x86/intel/int3472/discrete.c index b891b064fbf7..092252eb95a8 100644 --- a/drivers/platform/x86/intel/int3472/discrete.c +++ b/drivers/platform/x86/intel/int3472/discrete.c @@ -2,6 +2,7 @@ /* Author: Dan Scally */ #include +#include #include #include #include @@ -122,10 +123,53 @@ skl_int3472_gpiod_get_from_temp_lookup(struct int3472_discrete_device *int3472, return desc; } -static void int3472_get_func_and_polarity(u8 type, const char **func, - unsigned long *gpio_flags) +/** + * struct int3472_gpio_map - Map GPIOs to whatever is expected by the + * sensor driver (as in DT bindings) + * @hid: The ACPI HID of the device without the instance number e.g. INT347E + * @type_from: The GPIO type from ACPI ?SDT + * @type_to: The assigned GPIO type, typically same as @type_from + * @func: The function, e.g. "enable" + * @polarity_low: GPIO_ACTIVE_LOW true if the @polarity_low is true, + * GPIO_ACTIVE_HIGH otherwise + */ +struct int3472_gpio_map { + const char *hid; + u8 type_from; + u8 type_to; + bool polarity_low; + const char *func; +}; + +static const struct int3472_gpio_map int3472_gpio_map[] = { + { "INT347E", INT3472_GPIO_TYPE_RESET, INT3472_GPIO_TYPE_RESET, false, "enable" }, +}; + +static void int3472_get_func_and_polarity(struct acpi_device *adev, u8 *type, + const char **func, unsigned long *gpio_flags) { - switch (type) { + unsigned int i; + + for (i = 0; i < ARRAY_SIZE(int3472_gpio_map); i++) { + /* + * Map the firmware-provided GPIO to whatever a driver expects + * (as in DT bindings). First check if the type matches with the + * GPIO map, then further check that the device _HID matches. + */ + if (*type != int3472_gpio_map[i].type_from) + continue; + + if (!acpi_dev_hid_uid_match(adev, int3472_gpio_map[i].hid, NULL)) + continue; + + *type = int3472_gpio_map[i].type_to; + *gpio_flags = int3472_gpio_map[i].polarity_low ? + GPIO_ACTIVE_LOW : GPIO_ACTIVE_HIGH; + *func = int3472_gpio_map[i].func; + return; + } + + switch (*type) { case INT3472_GPIO_TYPE_RESET: *func = "reset"; *gpio_flags = GPIO_ACTIVE_LOW; @@ -218,7 +262,7 @@ static int skl_int3472_handle_gpio_resources(struct acpi_resource *ares, type = FIELD_GET(INT3472_GPIO_DSM_TYPE, obj->integer.value); - int3472_get_func_and_polarity(type, &func, &gpio_flags); + int3472_get_func_and_polarity(int3472->sensor, &type, &func, &gpio_flags); pin = FIELD_GET(INT3472_GPIO_DSM_PIN, obj->integer.value); /* Pin field is not really used under Windows and wraps around at 8 bits */ -- 2.51.0 From b3e127dacad60a384c92baafdc74f1508bf7dd47 Mon Sep 17 00:00:00 2001 From: Mark Pearson Date: Tue, 11 Feb 2025 12:36:11 -0500 Subject: [PATCH 10/16] platform/x86: thinkpad_acpi: Fix registration of tpacpi platform driver MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit The recent platform profile changes prevent the tpacpi platform driver from registering. This error is seen in the kernel logs, and the various tpacpi entries are not created: [ 7550.642171] platform thinkpad_acpi: Resources present before probing This happens because devm_platform_profile_register() is called before tpacpi_pdev probes (thanks to Kurt Borja for identifying the root cause). For now revert back to the old platform_profile_register to fix the issue. This is quick fix and will be re-implemented later as more testing is needed for full solution. Tested on X1 Carbon G12. Fixes: 31658c916fa6 ("platform/x86: thinkpad_acpi: Use devm_platform_profile_register()") Signed-off-by: Mark Pearson Reviewed-by: Kurt Borja Link: https://lore.kernel.org/r/20250211173620.16522-1-mpearson-lenovo@squebb.ca Reviewed-by: Ilpo Järvinen Signed-off-by: Ilpo Järvinen --- drivers/platform/x86/thinkpad_acpi.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/drivers/platform/x86/thinkpad_acpi.c b/drivers/platform/x86/thinkpad_acpi.c index 99cdea723d32..72a10ed2017c 100644 --- a/drivers/platform/x86/thinkpad_acpi.c +++ b/drivers/platform/x86/thinkpad_acpi.c @@ -10668,8 +10668,8 @@ static int tpacpi_dytc_profile_init(struct ibm_init_struct *iibm) "DYTC version %d: thermal mode available\n", dytc_version); /* Create platform_profile structure and register */ - tpacpi_pprof = devm_platform_profile_register(&tpacpi_pdev->dev, "thinkpad-acpi", - NULL, &dytc_profile_ops); + tpacpi_pprof = platform_profile_register(&tpacpi_pdev->dev, "thinkpad-acpi-profile", + NULL, &dytc_profile_ops); /* * If for some reason platform_profiles aren't enabled * don't quit terminally. @@ -10687,8 +10687,15 @@ static int tpacpi_dytc_profile_init(struct ibm_init_struct *iibm) return 0; } +static void dytc_profile_exit(void) +{ + if (!IS_ERR_OR_NULL(tpacpi_pprof)) + platform_profile_remove(tpacpi_pprof); +} + static struct ibm_struct dytc_profile_driver_data = { .name = "dytc-profile", + .exit = dytc_profile_exit, }; /************************************************************************* -- 2.51.0 From 81b251c66bdfe263fb5e7a16838512ddaeed77df Mon Sep 17 00:00:00 2001 From: Sakari Ailus Date: Tue, 11 Feb 2025 09:28:41 +0200 Subject: [PATCH 11/16] platform/x86: int3472: Call "func" "con_id" instead MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit "con_id" is an established variable name for the GPIO naming for drivers. Use it instead of "func" in the int3472 driver, too. Signed-off-by: Sakari Ailus Reviewed-by: Hans de Goede Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20250211072841.7713-4-sakari.ailus@linux.intel.com Reviewed-by: Ilpo Järvinen Signed-off-by: Ilpo Järvinen --- drivers/platform/x86/intel/int3472/discrete.c | 48 +++++++++---------- 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/drivers/platform/x86/intel/int3472/discrete.c b/drivers/platform/x86/intel/int3472/discrete.c index 092252eb95a8..30ff8f3ea1f5 100644 --- a/drivers/platform/x86/intel/int3472/discrete.c +++ b/drivers/platform/x86/intel/int3472/discrete.c @@ -56,7 +56,7 @@ static void skl_int3472_log_sensor_module_name(struct int3472_discrete_device *i static int skl_int3472_fill_gpiod_lookup(struct gpiod_lookup *table_entry, struct acpi_resource_gpio *agpio, - const char *func, unsigned long gpio_flags) + const char *con_id, unsigned long gpio_flags) { char *path = agpio->resource_source.string_ptr; struct acpi_device *adev; @@ -71,14 +71,14 @@ static int skl_int3472_fill_gpiod_lookup(struct gpiod_lookup *table_entry, if (!adev) return -ENODEV; - *table_entry = GPIO_LOOKUP(acpi_dev_name(adev), agpio->pin_table[0], func, gpio_flags); + *table_entry = GPIO_LOOKUP(acpi_dev_name(adev), agpio->pin_table[0], con_id, gpio_flags); return 0; } static int skl_int3472_map_gpio_to_sensor(struct int3472_discrete_device *int3472, struct acpi_resource_gpio *agpio, - const char *func, unsigned long gpio_flags) + const char *con_id, unsigned long gpio_flags) { int ret; @@ -88,7 +88,7 @@ static int skl_int3472_map_gpio_to_sensor(struct int3472_discrete_device *int347 } ret = skl_int3472_fill_gpiod_lookup(&int3472->gpios.table[int3472->n_sensor_gpios], - agpio, func, gpio_flags); + agpio, con_id, gpio_flags); if (ret) return ret; @@ -101,7 +101,7 @@ static int skl_int3472_map_gpio_to_sensor(struct int3472_discrete_device *int347 static struct gpio_desc * skl_int3472_gpiod_get_from_temp_lookup(struct int3472_discrete_device *int3472, struct acpi_resource_gpio *agpio, - const char *func, unsigned long gpio_flags) + const char *con_id, unsigned long gpio_flags) { struct gpio_desc *desc; int ret; @@ -112,12 +112,12 @@ skl_int3472_gpiod_get_from_temp_lookup(struct int3472_discrete_device *int3472, return ERR_PTR(-ENOMEM); lookup->dev_id = dev_name(int3472->dev); - ret = skl_int3472_fill_gpiod_lookup(&lookup->table[0], agpio, func, gpio_flags); + ret = skl_int3472_fill_gpiod_lookup(&lookup->table[0], agpio, con_id, gpio_flags); if (ret) return ERR_PTR(ret); gpiod_add_lookup_table(lookup); - desc = devm_gpiod_get(int3472->dev, func, GPIOD_OUT_LOW); + desc = devm_gpiod_get(int3472->dev, con_id, GPIOD_OUT_LOW); gpiod_remove_lookup_table(lookup); return desc; @@ -129,7 +129,7 @@ skl_int3472_gpiod_get_from_temp_lookup(struct int3472_discrete_device *int3472, * @hid: The ACPI HID of the device without the instance number e.g. INT347E * @type_from: The GPIO type from ACPI ?SDT * @type_to: The assigned GPIO type, typically same as @type_from - * @func: The function, e.g. "enable" + * @con_id: The name of the GPIO for the device * @polarity_low: GPIO_ACTIVE_LOW true if the @polarity_low is true, * GPIO_ACTIVE_HIGH otherwise */ @@ -138,15 +138,15 @@ struct int3472_gpio_map { u8 type_from; u8 type_to; bool polarity_low; - const char *func; + const char *con_id; }; static const struct int3472_gpio_map int3472_gpio_map[] = { { "INT347E", INT3472_GPIO_TYPE_RESET, INT3472_GPIO_TYPE_RESET, false, "enable" }, }; -static void int3472_get_func_and_polarity(struct acpi_device *adev, u8 *type, - const char **func, unsigned long *gpio_flags) +static void int3472_get_con_id_and_polarity(struct acpi_device *adev, u8 *type, + const char **con_id, unsigned long *gpio_flags) { unsigned int i; @@ -165,33 +165,33 @@ static void int3472_get_func_and_polarity(struct acpi_device *adev, u8 *type, *type = int3472_gpio_map[i].type_to; *gpio_flags = int3472_gpio_map[i].polarity_low ? GPIO_ACTIVE_LOW : GPIO_ACTIVE_HIGH; - *func = int3472_gpio_map[i].func; + *con_id = int3472_gpio_map[i].con_id; return; } switch (*type) { case INT3472_GPIO_TYPE_RESET: - *func = "reset"; + *con_id = "reset"; *gpio_flags = GPIO_ACTIVE_LOW; break; case INT3472_GPIO_TYPE_POWERDOWN: - *func = "powerdown"; + *con_id = "powerdown"; *gpio_flags = GPIO_ACTIVE_LOW; break; case INT3472_GPIO_TYPE_CLK_ENABLE: - *func = "clk-enable"; + *con_id = "clk-enable"; *gpio_flags = GPIO_ACTIVE_HIGH; break; case INT3472_GPIO_TYPE_PRIVACY_LED: - *func = "privacy-led"; + *con_id = "privacy-led"; *gpio_flags = GPIO_ACTIVE_HIGH; break; case INT3472_GPIO_TYPE_POWER_ENABLE: - *func = "power-enable"; + *con_id = "power-enable"; *gpio_flags = GPIO_ACTIVE_HIGH; break; default: - *func = "unknown"; + *con_id = "unknown"; *gpio_flags = GPIO_ACTIVE_HIGH; break; } @@ -238,7 +238,7 @@ static int skl_int3472_handle_gpio_resources(struct acpi_resource *ares, union acpi_object *obj; struct gpio_desc *gpio; const char *err_msg; - const char *func; + const char *con_id; unsigned long gpio_flags; int ret; @@ -262,26 +262,26 @@ static int skl_int3472_handle_gpio_resources(struct acpi_resource *ares, type = FIELD_GET(INT3472_GPIO_DSM_TYPE, obj->integer.value); - int3472_get_func_and_polarity(int3472->sensor, &type, &func, &gpio_flags); + int3472_get_con_id_and_polarity(int3472->sensor, &type, &con_id, &gpio_flags); pin = FIELD_GET(INT3472_GPIO_DSM_PIN, obj->integer.value); /* Pin field is not really used under Windows and wraps around at 8 bits */ if (pin != (agpio->pin_table[0] & 0xff)) dev_dbg(int3472->dev, FW_BUG "%s %s pin number mismatch _DSM %d resource %d\n", - func, agpio->resource_source.string_ptr, pin, agpio->pin_table[0]); + con_id, agpio->resource_source.string_ptr, pin, agpio->pin_table[0]); active_value = FIELD_GET(INT3472_GPIO_DSM_SENSOR_ON_VAL, obj->integer.value); if (!active_value) gpio_flags ^= GPIO_ACTIVE_LOW; - dev_dbg(int3472->dev, "%s %s pin %d active-%s\n", func, + dev_dbg(int3472->dev, "%s %s pin %d active-%s\n", con_id, agpio->resource_source.string_ptr, agpio->pin_table[0], str_high_low(gpio_flags == GPIO_ACTIVE_HIGH)); switch (type) { case INT3472_GPIO_TYPE_RESET: case INT3472_GPIO_TYPE_POWERDOWN: - ret = skl_int3472_map_gpio_to_sensor(int3472, agpio, func, gpio_flags); + ret = skl_int3472_map_gpio_to_sensor(int3472, agpio, con_id, gpio_flags); if (ret) err_msg = "Failed to map GPIO pin to sensor\n"; @@ -289,7 +289,7 @@ static int skl_int3472_handle_gpio_resources(struct acpi_resource *ares, case INT3472_GPIO_TYPE_CLK_ENABLE: case INT3472_GPIO_TYPE_PRIVACY_LED: case INT3472_GPIO_TYPE_POWER_ENABLE: - gpio = skl_int3472_gpiod_get_from_temp_lookup(int3472, agpio, func, gpio_flags); + gpio = skl_int3472_gpiod_get_from_temp_lookup(int3472, agpio, con_id, gpio_flags); if (IS_ERR(gpio)) { ret = PTR_ERR(gpio); err_msg = "Failed to get GPIO\n"; -- 2.51.0 From 9cf1c75bfda5168b82ba19576267d5cad0327b9f Mon Sep 17 00:00:00 2001 From: Thorsten Blum Date: Mon, 10 Feb 2025 13:31:03 +0100 Subject: [PATCH 12/16] sonypi: Use str_on_off() helper in sonypi_display_info() MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Remove hard-coded strings by using the str_on_off() helper function. Signed-off-by: Thorsten Blum Link: https://lore.kernel.org/r/20250210123103.112938-2-thorsten.blum@linux.dev Reviewed-by: Ilpo Järvinen Signed-off-by: Ilpo Järvinen --- drivers/char/sonypi.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/drivers/char/sonypi.c b/drivers/char/sonypi.c index f887569fd3d0..677bb5ac950a 100644 --- a/drivers/char/sonypi.c +++ b/drivers/char/sonypi.c @@ -37,6 +37,7 @@ #include #include #include +#include #include #include @@ -1268,12 +1269,12 @@ static void sonypi_display_info(void) "compat = %s, mask = 0x%08lx, useinput = %s, acpi = %s\n", sonypi_device.model, verbose, - fnkeyinit ? "on" : "off", - camera ? "on" : "off", - compat ? "on" : "off", + str_on_off(fnkeyinit), + str_on_off(camera), + str_on_off(compat), mask, - useinput ? "on" : "off", - SONYPI_ACPI_ACTIVE ? "on" : "off"); + str_on_off(useinput), + str_on_off(SONYPI_ACPI_ACTIVE)); printk(KERN_INFO "sonypi: enabled at irq=%d, port1=0x%x, port2=0x%x\n", sonypi_device.irq, sonypi_device.ioport1, sonypi_device.ioport2); -- 2.51.0 From d026feb03bdcde33e22a75777d59ed9d8725bcdd Mon Sep 17 00:00:00 2001 From: Xi Pardee Date: Tue, 11 Feb 2025 17:05:56 -0800 Subject: [PATCH 13/16] platform/x86:intel/pmc: Move arch specific action to init function MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Move arch specific action from core.c to the init() function of spt.c. Signed-off-by: Xi Pardee Link: https://lore.kernel.org/r/20250212010621.1003663-1-xi.pardee@linux.intel.com Reviewed-by: Ilpo Järvinen Signed-off-by: Ilpo Järvinen --- drivers/platform/x86/intel/pmc/core.c | 13 ------------- drivers/platform/x86/intel/pmc/spt.c | 21 +++++++++++++++++++++ 2 files changed, 21 insertions(+), 13 deletions(-) diff --git a/drivers/platform/x86/intel/pmc/core.c b/drivers/platform/x86/intel/pmc/core.c index 1b85800ec10f..28e0c09dd599 100644 --- a/drivers/platform/x86/intel/pmc/core.c +++ b/drivers/platform/x86/intel/pmc/core.c @@ -1418,11 +1418,6 @@ static const struct x86_cpu_id intel_pmc_core_ids[] = { MODULE_DEVICE_TABLE(x86cpu, intel_pmc_core_ids); -static const struct pci_device_id pmc_pci_ids[] = { - { PCI_VDEVICE(INTEL, SPT_PMC_PCI_DEVICE_ID) }, - { } -}; - /* * This quirk can be used on those platforms where * the platform BIOS enforces 24Mhz crystal to shutdown @@ -1533,14 +1528,6 @@ static int pmc_core_probe(struct platform_device *pdev) if (!pmcdev->pkgc_res_cnt) return -ENOMEM; - /* - * Coffee Lake has CPU ID of Kaby Lake and Cannon Lake PCH. So here - * Sunrisepoint PCH regmap can't be used. Use Cannon Lake PCH regmap - * in this case. - */ - if (pmc_dev_info == &spt_pmc_dev && !pci_dev_present(pmc_pci_ids)) - pmc_dev_info = &cnp_pmc_dev; - mutex_init(&pmcdev->lock); if (pmc_dev_info->init) diff --git a/drivers/platform/x86/intel/pmc/spt.c b/drivers/platform/x86/intel/pmc/spt.c index 956b2ec1c751..440594acac6c 100644 --- a/drivers/platform/x86/intel/pmc/spt.c +++ b/drivers/platform/x86/intel/pmc/spt.c @@ -8,6 +8,8 @@ * */ +#include + #include "core.h" const struct pmc_bit_map spt_pll_map[] = { @@ -134,6 +136,25 @@ const struct pmc_reg_map spt_reg_map = { .pm_vric1_offset = SPT_PMC_VRIC1_OFFSET, }; +static const struct pci_device_id spt_pmc_pci_id[] = { + { PCI_VDEVICE(INTEL, SPT_PMC_PCI_DEVICE_ID) }, + { } +}; + +static int spt_core_init(struct pmc_dev *pmcdev, struct pmc_dev_info *pmc_dev_info) +{ + /* + * Coffee Lake has CPU ID of Kaby Lake and Cannon Lake PCH. So here + * Sunrisepoint PCH regmap can't be used. Use Cannon Lake PCH regmap + * in this case. + */ + if (!pci_dev_present(spt_pmc_pci_id)) + return generic_core_init(pmcdev, &cnp_pmc_dev); + + return generic_core_init(pmcdev, pmc_dev_info); +} + struct pmc_dev_info spt_pmc_dev = { .map = &spt_reg_map, + .init = spt_core_init, }; -- 2.51.0 From d497c47481f8e8f13e3191c9a707ed942d3bb3d7 Mon Sep 17 00:00:00 2001 From: Ovidiu Panait Date: Mon, 10 Feb 2025 17:53:33 +0200 Subject: [PATCH 14/16] platform/x86: ideapad-laptop: use dev_groups to register attribute groups MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Instead of manually adding/removing attribute groups, set (struct device_driver).dev_groups pointer to have the driver core do it. Signed-off-by: Ovidiu Panait Link: https://lore.kernel.org/r/20250210155333.1145867-1-ovidiu.panait.oss@gmail.com Reviewed-by: Ilpo Järvinen Signed-off-by: Ilpo Järvinen --- drivers/platform/x86/ideapad-laptop.c | 23 ++--------------------- 1 file changed, 2 insertions(+), 21 deletions(-) diff --git a/drivers/platform/x86/ideapad-laptop.c b/drivers/platform/x86/ideapad-laptop.c index 30bd366d7b58..17a09b7784ed 100644 --- a/drivers/platform/x86/ideapad-laptop.c +++ b/drivers/platform/x86/ideapad-laptop.c @@ -854,6 +854,7 @@ static const struct attribute_group ideapad_attribute_group = { .is_visible = ideapad_is_visible, .attrs = ideapad_attributes }; +__ATTRIBUTE_GROUPS(ideapad_attribute); /* * DYTC Platform profile @@ -1244,21 +1245,6 @@ static void ideapad_unregister_rfkill(struct ideapad_private *priv, int dev) rfkill_destroy(priv->rfk[dev]); } -/* - * Platform device - */ -static int ideapad_sysfs_init(struct ideapad_private *priv) -{ - return device_add_group(&priv->platform_device->dev, - &ideapad_attribute_group); -} - -static void ideapad_sysfs_exit(struct ideapad_private *priv) -{ - device_remove_group(&priv->platform_device->dev, - &ideapad_attribute_group); -} - /* * input device */ @@ -2175,10 +2161,6 @@ static int ideapad_acpi_add(struct platform_device *pdev) ideapad_check_features(priv); - err = ideapad_sysfs_init(priv); - if (err) - return err; - ideapad_debugfs_init(priv); err = ideapad_input_init(priv); @@ -2265,7 +2247,6 @@ backlight_failed: input_failed: ideapad_debugfs_exit(priv); - ideapad_sysfs_exit(priv); return err; } @@ -2293,7 +2274,6 @@ static void ideapad_acpi_remove(struct platform_device *pdev) ideapad_kbd_bl_exit(priv); ideapad_input_exit(priv); ideapad_debugfs_exit(priv); - ideapad_sysfs_exit(priv); } #ifdef CONFIG_PM_SLEEP @@ -2325,6 +2305,7 @@ static struct platform_driver ideapad_acpi_driver = { .name = "ideapad_acpi", .pm = &ideapad_pm, .acpi_match_table = ACPI_PTR(ideapad_device_ids), + .dev_groups = ideapad_attribute_groups, }, }; -- 2.51.0 From c86e269c4da6dca2beaf99bdc6fd9f0a9f69035f Mon Sep 17 00:00:00 2001 From: Kurt Borja Date: Fri, 14 Feb 2025 16:45:35 -0500 Subject: [PATCH 15/16] platform/x86: dell: Use *-y instead of *-objs in Makefile MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit The `objs` suffix is reserved for user-space tools. Use the `y` suffix instead, which is usually used for kernel drivers. Suggested-by: Andy Shevchenko Signed-off-by: Kurt Borja Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20250214214535.4947-1-kuurtb@gmail.com Reviewed-by: Ilpo Järvinen Signed-off-by: Ilpo Järvinen --- drivers/platform/x86/dell/Makefile | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/platform/x86/dell/Makefile b/drivers/platform/x86/dell/Makefile index 8ac9a933c770..c7501c25e627 100644 --- a/drivers/platform/x86/dell/Makefile +++ b/drivers/platform/x86/dell/Makefile @@ -5,7 +5,7 @@ # obj-$(CONFIG_ALIENWARE_WMI) += alienware-wmi.o -alienware-wmi-objs := alienware-wmi-base.o +alienware-wmi-y := alienware-wmi-base.o alienware-wmi-$(CONFIG_ALIENWARE_WMI_LEGACY) += alienware-wmi-legacy.o alienware-wmi-$(CONFIG_ALIENWARE_WMI_WMAX) += alienware-wmi-wmax.o obj-$(CONFIG_DCDBAS) += dcdbas.o @@ -14,14 +14,14 @@ obj-$(CONFIG_DELL_RBTN) += dell-rbtn.o obj-$(CONFIG_DELL_RBU) += dell_rbu.o obj-$(CONFIG_DELL_PC) += dell-pc.o obj-$(CONFIG_DELL_SMBIOS) += dell-smbios.o -dell-smbios-objs := dell-smbios-base.o +dell-smbios-y := dell-smbios-base.o dell-smbios-$(CONFIG_DELL_SMBIOS_WMI) += dell-smbios-wmi.o dell-smbios-$(CONFIG_DELL_SMBIOS_SMM) += dell-smbios-smm.o obj-$(CONFIG_DELL_SMO8800) += dell-smo8800.o obj-$(CONFIG_DELL_SMO8800) += dell-lis3lv02d.o obj-$(CONFIG_DELL_UART_BACKLIGHT) += dell-uart-backlight.o obj-$(CONFIG_DELL_WMI) += dell-wmi.o -dell-wmi-objs := dell-wmi-base.o +dell-wmi-y := dell-wmi-base.o dell-wmi-$(CONFIG_DELL_WMI_PRIVACY) += dell-wmi-privacy.o obj-$(CONFIG_DELL_WMI_AIO) += dell-wmi-aio.o obj-$(CONFIG_DELL_WMI_DESCRIPTOR) += dell-wmi-descriptor.o -- 2.51.0 From 27cc2914e495d314d19c7c1f74687bb28bc292e8 Mon Sep 17 00:00:00 2001 From: Armin Wolf Date: Sun, 16 Feb 2025 20:32:44 +0100 Subject: [PATCH 16/16] hwmon: (hp-wmi-sensors) Use the WMI bus API when accessing sensors MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Since the driver already binds to HP_WMI_NUMERIC_SENSOR_GUID, using wmidev_block_query() allows for faster sensor access. Acked-by: Guenter Roeck Tested-by: James Seo Reviewed-by: James Seo Signed-off-by: Armin Wolf Link: https://lore.kernel.org/r/20250216193251.866125-2-W_Armin@gmx.de Reviewed-by: Ilpo Järvinen Signed-off-by: Ilpo Järvinen --- drivers/hwmon/hp-wmi-sensors.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/hwmon/hp-wmi-sensors.c b/drivers/hwmon/hp-wmi-sensors.c index d6bdad26feb1..03c684ba83bd 100644 --- a/drivers/hwmon/hp-wmi-sensors.c +++ b/drivers/hwmon/hp-wmi-sensors.c @@ -1197,7 +1197,7 @@ static int hp_wmi_update_info(struct hp_wmi_sensors *state, if (time_after(jiffies, info->last_updated + HZ)) { mutex_lock(&state->lock); - wobj = hp_wmi_get_wobj(HP_WMI_NUMERIC_SENSOR_GUID, instance); + wobj = wmidev_block_query(state->wdev, instance); if (!wobj) { ret = -EIO; goto out_unlock; @@ -1745,7 +1745,7 @@ static int init_numeric_sensors(struct hp_wmi_sensors *state, return -ENOMEM; for (i = 0, info = info_arr; i < icount; i++, info++) { - wobj = hp_wmi_get_wobj(HP_WMI_NUMERIC_SENSOR_GUID, i); + wobj = wmidev_block_query(state->wdev, i); if (!wobj) return -EIO; -- 2.51.0