[PATCH] ipmi: enable interrupts on the BT driver
authorCorey Minyard <minyard@acm.org>
Sun, 1 May 2005 15:59:11 +0000 (08:59 -0700)
committerLinus Torvalds <torvalds@ppc970.osdl.org>
Sun, 1 May 2005 15:59:11 +0000 (08:59 -0700)
Enable interrupts for a BT interface.  There is a specific register that
needs to be set up to enable interrupts that also must be modified to clear
the irq.

Also, don't reset the BMC on a BT interface.  That's probably not a good
idea as the BMC may be performing other important functions and a reset
should only be a last resort.  Also, that register is also used to
enable/disable interrupts to the BT; modifying it may screw up the
interrupts.

Signed-off-by: Corey Minyard <minyard@acm.org>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
drivers/char/ipmi/ipmi_bt_sm.c
drivers/char/ipmi/ipmi_si_intf.c

index 225b330115bb69a29a707c77b6281fb06d379148..5ce9c62690334cdf50ada526ec2c2a123b087849 100644 (file)
@@ -235,7 +235,6 @@ static void reset_flags(struct si_sm_data *bt)
        if (BT_STATUS & BT_B_BUSY) BT_CONTROL(BT_B_BUSY);
        BT_CONTROL(BT_CLR_WR_PTR);
        BT_CONTROL(BT_SMS_ATN);
-       BT_INTMASK_W(BT_BMC_HWRST);
 #ifdef DEVELOPMENT_ONLY_NOT_FOR_PRODUCTION
        if (BT_STATUS & BT_B2H_ATN) {
                int i;
index 7522bd5f94dacad038f42b0e533947812273901b..5419440087fd6844c923da80d790bd3ca91acbcc 100644 (file)
@@ -100,6 +100,11 @@ enum si_intf_state {
        /* FIXME - add watchdog stuff. */
 };
 
+/* Some BT-specific defines we need here. */
+#define IPMI_BT_INTMASK_REG            2
+#define IPMI_BT_INTMASK_CLEAR_IRQ_BIT  2
+#define IPMI_BT_INTMASK_ENABLE_IRQ_BIT 1
+
 enum si_type {
     SI_KCS, SI_SMIC, SI_BT
 };
@@ -875,6 +880,17 @@ static irqreturn_t si_irq_handler(int irq, void *data, struct pt_regs *regs)
        return IRQ_HANDLED;
 }
 
+static irqreturn_t si_bt_irq_handler(int irq, void *data, struct pt_regs *regs)
+{
+       struct smi_info *smi_info = data;
+       /* We need to clear the IRQ flag for the BT interface. */
+       smi_info->io.outputb(&smi_info->io, IPMI_BT_INTMASK_REG,
+                            IPMI_BT_INTMASK_CLEAR_IRQ_BIT
+                            | IPMI_BT_INTMASK_ENABLE_IRQ_BIT);
+       return si_irq_handler(irq, data, regs);
+}
+
+
 static struct ipmi_smi_handlers handlers =
 {
        .owner                  = THIS_MODULE,
@@ -1001,11 +1017,22 @@ static int std_irq_setup(struct smi_info *info)
        if (!info->irq)
                return 0;
 
-       rv = request_irq(info->irq,
-                        si_irq_handler,
-                        SA_INTERRUPT,
-                        DEVICE_NAME,
-                        info);
+       if (info->si_type == SI_BT) {
+               rv = request_irq(info->irq,
+                                si_bt_irq_handler,
+                                SA_INTERRUPT,
+                                DEVICE_NAME,
+                                info);
+               if (!rv)
+                       /* Enable the interrupt in the BT interface. */
+                       info->io.outputb(&info->io, IPMI_BT_INTMASK_REG,
+                                        IPMI_BT_INTMASK_ENABLE_IRQ_BIT);
+       } else
+               rv = request_irq(info->irq,
+                                si_irq_handler,
+                                SA_INTERRUPT,
+                                DEVICE_NAME,
+                                info);
        if (rv) {
                printk(KERN_WARNING
                       "ipmi_si: %s unable to claim interrupt %d,"
@@ -1024,6 +1051,9 @@ static void std_irq_cleanup(struct smi_info *info)
        if (!info->irq)
                return;
 
+       if (info->si_type == SI_BT)
+               /* Disable the interrupt in the BT interface. */
+               info->io.outputb(&info->io, IPMI_BT_INTMASK_REG, 0);
        free_irq(info->irq, info);
 }