Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

platform/x86/amd/pmf: Fix the custom bios input handling mechanism

Originally, the 'amd_pmf_get_custom_bios_inputs()' function was written
under the assumption that the BIOS would only send a single pending
request for the driver to process. However, following OEM enablement, it
became clear that multiple pending requests for custom BIOS inputs might
be sent at the same time, a scenario that the current code logic does not
support when it comes to handling multiple custom BIOS inputs.

To address this, the code logic needs to be improved to not only manage
multiple simultaneous custom BIOS inputs but also to ensure it is scalable
for future additional inputs.

Co-developed-by: Patil Rajesh Reddy <Patil.Reddy@amd.com>
Signed-off-by: Patil Rajesh Reddy <Patil.Reddy@amd.com>
Tested-by: Yijun Shen <Yijun.Shen@Dell.com>
Signed-off-by: Shyam Sundar S K <Shyam-sundar.S-k@amd.com>
Link: https://patch.msgid.link/20250901110140.2519072-3-Shyam-sundar.S-k@amd.com
Reviewed-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>

authored by

Shyam Sundar S K and committed by
Ilpo Järvinen
d82e3d2d f10ea2df

+44 -19
+7 -8
drivers/platform/x86/amd/pmf/pmf.h
··· 623 623 TA_MAX, 624 624 }; 625 625 626 - enum apmf_smartpc_custom_bios_inputs { 627 - APMF_SMARTPC_CUSTOM_BIOS_INPUT1, 628 - APMF_SMARTPC_CUSTOM_BIOS_INPUT2, 626 + struct amd_pmf_pb_bitmap { 627 + const char *name; 628 + u32 bit_mask; 629 629 }; 630 630 631 - enum apmf_preq_smartpc { 632 - NOTIFY_CUSTOM_BIOS_INPUT1 = 5, 633 - NOTIFY_CUSTOM_BIOS_INPUT2, 631 + static const struct amd_pmf_pb_bitmap custom_bios_inputs[] __used = { 632 + {"NOTIFY_CUSTOM_BIOS_INPUT1", BIT(5)}, 633 + {"NOTIFY_CUSTOM_BIOS_INPUT2", BIT(6)}, 634 634 }; 635 635 636 636 enum platform_type { ··· 690 690 u32 power_slider; 691 691 u32 lid_state; 692 692 bool user_present; 693 - u32 bios_input1; 694 - u32 bios_input2; 693 + u32 bios_input_1[2]; 695 694 u32 monitor_count; 696 695 u32 rsvd2[2]; 697 696 u32 bat_design;
+37 -11
drivers/platform/x86/amd/pmf/spc.c
··· 70 70 } 71 71 } 72 72 73 + static u32 amd_pmf_get_ta_custom_bios_inputs(struct ta_pmf_enact_table *in, int index) 74 + { 75 + switch (index) { 76 + case 0 ... 1: 77 + return in->ev_info.bios_input_1[index]; 78 + default: 79 + return 0; 80 + } 81 + } 82 + 73 83 void amd_pmf_dump_ta_inputs(struct amd_pmf_dev *dev, struct ta_pmf_enact_table *in) 74 84 { 85 + int i; 86 + 75 87 dev_dbg(dev->dev, "==== TA inputs START ====\n"); 76 88 dev_dbg(dev->dev, "Slider State: %s\n", ta_slider_as_str(in->ev_info.power_slider)); 77 89 dev_dbg(dev->dev, "Power Source: %s\n", amd_pmf_source_as_str(in->ev_info.power_source)); ··· 102 90 dev_dbg(dev->dev, "Platform type: %s\n", platform_type_as_str(in->ev_info.platform_type)); 103 91 dev_dbg(dev->dev, "Laptop placement: %s\n", 104 92 laptop_placement_as_str(in->ev_info.device_state)); 105 - dev_dbg(dev->dev, "Custom BIOS input1: %u\n", in->ev_info.bios_input1); 106 - dev_dbg(dev->dev, "Custom BIOS input2: %u\n", in->ev_info.bios_input2); 93 + for (i = 0; i < ARRAY_SIZE(custom_bios_inputs); i++) 94 + dev_dbg(dev->dev, "Custom BIOS input%d: %u\n", i + 1, 95 + amd_pmf_get_ta_custom_bios_inputs(in, i)); 107 96 dev_dbg(dev->dev, "==== TA inputs END ====\n"); 108 97 } 109 98 #else 110 99 void amd_pmf_dump_ta_inputs(struct amd_pmf_dev *dev, struct ta_pmf_enact_table *in) {} 111 100 #endif 112 101 102 + /* 103 + * This helper function sets the appropriate BIOS input value in the TA enact 104 + * table based on the provided index. We need this approach because the custom 105 + * BIOS input array is not continuous, due to the existing TA structure layout. 106 + */ 107 + static void amd_pmf_set_ta_custom_bios_input(struct ta_pmf_enact_table *in, int index, u32 value) 108 + { 109 + switch (index) { 110 + case 0 ... 1: 111 + in->ev_info.bios_input_1[index] = value; 112 + break; 113 + default: 114 + return; 115 + } 116 + } 117 + 113 118 static void amd_pmf_get_custom_bios_inputs(struct amd_pmf_dev *pdev, 114 119 struct ta_pmf_enact_table *in) 115 120 { 121 + unsigned int i; 122 + 116 123 if (!pdev->req.pending_req) 117 124 return; 118 125 119 - switch (pdev->req.pending_req) { 120 - case BIT(NOTIFY_CUSTOM_BIOS_INPUT1): 121 - in->ev_info.bios_input1 = pdev->req.custom_policy[APMF_SMARTPC_CUSTOM_BIOS_INPUT1]; 122 - break; 123 - case BIT(NOTIFY_CUSTOM_BIOS_INPUT2): 124 - in->ev_info.bios_input2 = pdev->req.custom_policy[APMF_SMARTPC_CUSTOM_BIOS_INPUT2]; 125 - break; 126 - default: 127 - dev_dbg(pdev->dev, "Invalid preq for BIOS input: 0x%x\n", pdev->req.pending_req); 126 + for (i = 0; i < ARRAY_SIZE(custom_bios_inputs); i++) { 127 + if (!(pdev->req.pending_req & custom_bios_inputs[i].bit_mask)) 128 + continue; 129 + amd_pmf_set_ta_custom_bios_input(in, i, pdev->req.custom_policy[i]); 128 130 } 129 131 130 132 /* Clear pending requests after handling */