ACPI: IPMI: Add helper to wait for when SMI is selected
JIRA: https://issues.redhat.com/browse/RHEL-54149 commit 670e98a34a9e44cd384bafbda681c8c8e072b714 Author: Kai-Heng Feng <kai.heng.feng@canonical.com> Date: Sun, 28 Apr 2024 10:07:34 +0000 On Dell servers, many APCI methods of acpi_power_meter module evaluate variables inside IPMI region, so the region handler needs to be installed. In addition to that, the handler needs to be fully functional, and that depends on SMI being selected. So add a helper to let acpi_power_meter know when the handler is installed and ready to be used. Signed-off-by: Kai-Heng Feng <kai.heng.feng@canonical.com> Acked-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com> Link: https://lore.kernel.org/r/20240320084317.366853-1-kai.heng.feng@canonical.com Signed-off-by: Guenter Roeck <linux@roeck-us.net> Signed-off-by: Mark Langsdorf <mlangsdo@redhat.com>
This commit is contained in:
parent
0c94e8e008
commit
f2dbe917ea
|
@ -22,6 +22,8 @@ MODULE_LICENSE("GPL");
|
|||
/* the IPMI timeout is 5s */
|
||||
#define IPMI_TIMEOUT (5000)
|
||||
#define ACPI_IPMI_MAX_MSG_LENGTH 64
|
||||
/* 2s should be suffient for SMI being selected */
|
||||
#define ACPI_IPMI_SMI_SELECTION_TIMEOUT (2 * HZ)
|
||||
|
||||
struct acpi_ipmi_device {
|
||||
/* the device list attached to driver_data.ipmi_devices */
|
||||
|
@ -54,6 +56,7 @@ struct ipmi_driver_data {
|
|||
* to this selected global IPMI system interface.
|
||||
*/
|
||||
struct acpi_ipmi_device *selected_smi;
|
||||
struct completion smi_selection_done;
|
||||
};
|
||||
|
||||
struct acpi_ipmi_msg {
|
||||
|
@ -463,8 +466,10 @@ static void ipmi_register_bmc(int iface, struct device *dev)
|
|||
if (temp->handle == handle)
|
||||
goto err_lock;
|
||||
}
|
||||
if (!driver_data.selected_smi)
|
||||
if (!driver_data.selected_smi) {
|
||||
driver_data.selected_smi = ipmi_device;
|
||||
complete(&driver_data.smi_selection_done);
|
||||
}
|
||||
list_add_tail(&ipmi_device->head, &driver_data.ipmi_devices);
|
||||
mutex_unlock(&driver_data.ipmi_lock);
|
||||
|
||||
|
@ -578,6 +583,20 @@ out_msg:
|
|||
return status;
|
||||
}
|
||||
|
||||
int acpi_wait_for_acpi_ipmi(void)
|
||||
{
|
||||
long ret;
|
||||
|
||||
ret = wait_for_completion_interruptible_timeout(&driver_data.smi_selection_done,
|
||||
ACPI_IPMI_SMI_SELECTION_TIMEOUT);
|
||||
|
||||
if (ret <= 0)
|
||||
return -ETIMEDOUT;
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(acpi_wait_for_acpi_ipmi);
|
||||
|
||||
static int __init acpi_ipmi_init(void)
|
||||
{
|
||||
int result;
|
||||
|
@ -586,6 +605,8 @@ static int __init acpi_ipmi_init(void)
|
|||
if (acpi_disabled)
|
||||
return 0;
|
||||
|
||||
init_completion(&driver_data.smi_selection_done);
|
||||
|
||||
status = acpi_install_address_space_handler(ACPI_ROOT_OBJECT,
|
||||
ACPI_ADR_SPACE_IPMI,
|
||||
&acpi_ipmi_space_handler,
|
||||
|
|
|
@ -984,11 +984,16 @@ static inline void acpi_put_acpi_dev(struct acpi_device *adev)
|
|||
{
|
||||
acpi_dev_put(adev);
|
||||
}
|
||||
|
||||
int acpi_wait_for_acpi_ipmi(void);
|
||||
|
||||
#else /* CONFIG_ACPI */
|
||||
|
||||
static inline int register_acpi_bus_type(void *bus) { return 0; }
|
||||
static inline int unregister_acpi_bus_type(void *bus) { return 0; }
|
||||
|
||||
static inline int acpi_wait_for_acpi_ipmi(void) { return 0; }
|
||||
|
||||
#endif /* CONFIG_ACPI */
|
||||
|
||||
#endif /*__ACPI_BUS_H__*/
|
||||
|
|
Loading…
Reference in New Issue