From: Corey Minyard <cminy...@mvista.com>

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 <cminy...@mvista.com>
---
 drivers/char/ipmi/ipmi_si_intf.c | 33 +++++++++++++++++++++++----------
 1 file changed, 23 insertions(+), 10 deletions(-)

diff --git a/drivers/char/ipmi/ipmi_si_intf.c b/drivers/char/ipmi/ipmi_si_intf.c
index 1c2ff8e..3a76934 100644
--- a/drivers/char/ipmi/ipmi_si_intf.c
+++ b/drivers/char/ipmi/ipmi_si_intf.c
@@ -3423,7 +3423,7 @@ static inline void wait_for_timer_and_thread(struct 
smi_info *smi_info)
                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;
 
@@ -3438,24 +3438,36 @@ static int is_new_interface(struct smi_info *info)
                         */
                        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",
@@ -3864,7 +3876,8 @@ static void cleanup_one_si(struct smi_info *to_clean)
                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);
-- 
2.7.4


------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
_______________________________________________
Openipmi-developer mailing list
Openipmi-developer@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/openipmi-developer

Reply via email to