| From 7e030d6dff713250c7dcfb543cad2addaf479b0e Mon Sep 17 00:00:00 2001 |
| From: Corey Minyard <cminyard@mvista.com> |
| Date: Fri, 8 Sep 2017 14:05:58 -0500 |
| Subject: ipmi: Prefer ACPI system interfaces over SMBIOS ones |
| |
| From: Corey Minyard <cminyard@mvista.com> |
| |
| commit 7e030d6dff713250c7dcfb543cad2addaf479b0e upstream. |
| |
| The recent changes to add SMBIOS (DMI) IPMI interfaces as platform |
| devices caused DMI to be selected before ACPI, causing ACPI type |
| of operations to not work. |
| |
| Signed-off-by: Corey Minyard <cminyard@mvista.com> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| |
| --- |
| drivers/char/ipmi/ipmi_si_intf.c | 33 +++++++++++++++++++++++---------- |
| 1 file changed, 23 insertions(+), 10 deletions(-) |
| |
| --- a/drivers/char/ipmi/ipmi_si_intf.c |
| +++ b/drivers/char/ipmi/ipmi_si_intf.c |
| @@ -3424,7 +3424,7 @@ static inline void wait_for_timer_and_th |
| del_timer_sync(&smi_info->si_timer); |
| } |
| |
| -static int is_new_interface(struct smi_info *info) |
| +static struct smi_info *find_dup_si(struct smi_info *info) |
| { |
| struct smi_info *e; |
| |
| @@ -3439,24 +3439,36 @@ static int is_new_interface(struct smi_i |
| */ |
| if (info->slave_addr && !e->slave_addr) |
| e->slave_addr = info->slave_addr; |
| - return 0; |
| + return e; |
| } |
| } |
| |
| - return 1; |
| + return NULL; |
| } |
| |
| static int add_smi(struct smi_info *new_smi) |
| { |
| int rv = 0; |
| + struct smi_info *dup; |
| |
| mutex_lock(&smi_infos_lock); |
| - if (!is_new_interface(new_smi)) { |
| - pr_info(PFX "%s-specified %s state machine: duplicate\n", |
| - ipmi_addr_src_to_str(new_smi->addr_source), |
| - si_to_str[new_smi->si_type]); |
| - rv = -EBUSY; |
| - goto out_err; |
| + dup = find_dup_si(new_smi); |
| + if (dup) { |
| + if (new_smi->addr_source == SI_ACPI && |
| + dup->addr_source == SI_SMBIOS) { |
| + /* We prefer ACPI over SMBIOS. */ |
| + dev_info(dup->dev, |
| + "Removing SMBIOS-specified %s state machine in favor of ACPI\n", |
| + si_to_str[new_smi->si_type]); |
| + cleanup_one_si(dup); |
| + } else { |
| + dev_info(new_smi->dev, |
| + "%s-specified %s state machine: duplicate\n", |
| + ipmi_addr_src_to_str(new_smi->addr_source), |
| + si_to_str[new_smi->si_type]); |
| + rv = -EBUSY; |
| + goto out_err; |
| + } |
| } |
| |
| pr_info(PFX "Adding %s-specified %s state machine\n", |
| @@ -3865,7 +3877,8 @@ static void cleanup_one_si(struct smi_in |
| poll(to_clean); |
| schedule_timeout_uninterruptible(1); |
| } |
| - disable_si_irq(to_clean, false); |
| + if (to_clean->handlers) |
| + disable_si_irq(to_clean, false); |
| while (to_clean->curr_msg || (to_clean->si_state != SI_NORMAL)) { |
| poll(to_clean); |
| schedule_timeout_uninterruptible(1); |