Commit 9dbf68f9 authored by Corey Minyard's avatar Corey Minyard Committed by Linus Torvalds

[PATCH] ipmi: enable interrupts on the 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: default avatarCorey Minyard <minyard@acm.org>
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent ec26d79f
...@@ -235,7 +235,6 @@ static void reset_flags(struct si_sm_data *bt) ...@@ -235,7 +235,6 @@ static void reset_flags(struct si_sm_data *bt)
if (BT_STATUS & BT_B_BUSY) BT_CONTROL(BT_B_BUSY); if (BT_STATUS & BT_B_BUSY) BT_CONTROL(BT_B_BUSY);
BT_CONTROL(BT_CLR_WR_PTR); BT_CONTROL(BT_CLR_WR_PTR);
BT_CONTROL(BT_SMS_ATN); BT_CONTROL(BT_SMS_ATN);
BT_INTMASK_W(BT_BMC_HWRST);
#ifdef DEVELOPMENT_ONLY_NOT_FOR_PRODUCTION #ifdef DEVELOPMENT_ONLY_NOT_FOR_PRODUCTION
if (BT_STATUS & BT_B2H_ATN) { if (BT_STATUS & BT_B2H_ATN) {
int i; int i;
......
...@@ -100,6 +100,11 @@ enum si_intf_state { ...@@ -100,6 +100,11 @@ enum si_intf_state {
/* FIXME - add watchdog stuff. */ /* 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 { enum si_type {
SI_KCS, SI_SMIC, SI_BT SI_KCS, SI_SMIC, SI_BT
}; };
...@@ -875,6 +880,17 @@ static irqreturn_t si_irq_handler(int irq, void *data, struct pt_regs *regs) ...@@ -875,6 +880,17 @@ static irqreturn_t si_irq_handler(int irq, void *data, struct pt_regs *regs)
return IRQ_HANDLED; 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 = static struct ipmi_smi_handlers handlers =
{ {
.owner = THIS_MODULE, .owner = THIS_MODULE,
...@@ -1001,6 +1017,17 @@ static int std_irq_setup(struct smi_info *info) ...@@ -1001,6 +1017,17 @@ static int std_irq_setup(struct smi_info *info)
if (!info->irq) if (!info->irq)
return 0; return 0;
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, rv = request_irq(info->irq,
si_irq_handler, si_irq_handler,
SA_INTERRUPT, SA_INTERRUPT,
...@@ -1024,6 +1051,9 @@ static void std_irq_cleanup(struct smi_info *info) ...@@ -1024,6 +1051,9 @@ static void std_irq_cleanup(struct smi_info *info)
if (!info->irq) if (!info->irq)
return; 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); free_irq(info->irq, info);
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment