Enable interrupts on the IPMI BT driver
PATCH 1/1 Enable interrupts on the IPMI BT driver
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 <[email protected]>
drivers/char/ipmi/ipmi_si_intf.c +35 -5
@@ -100,6 +100,11 @@/* 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 };
@@ -876,6 +881,17 @@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 ,
@@ -1002,11 +1018,22 @@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,"
@@ -1025,6 +1052,9 @@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); }
drivers/char/ipmi/ipmi_bt_sm.c +0 -1
@@ -235,7 +235,6 @@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;