aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/char/ipmi/ipmi_si_intf.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/char/ipmi/ipmi_si_intf.c')
-rw-r--r--drivers/char/ipmi/ipmi_si_intf.c40
1 files changed, 35 insertions, 5 deletions
diff --git a/drivers/char/ipmi/ipmi_si_intf.c b/drivers/char/ipmi/ipmi_si_intf.c
index 7522bd5f94da..5419440087fd 100644
--- a/drivers/char/ipmi/ipmi_si_intf.c
+++ b/drivers/char/ipmi/ipmi_si_intf.c
@@ -100,6 +100,11 @@ enum si_intf_state {
100 /* FIXME - add watchdog stuff. */ 100 /* FIXME - add watchdog stuff. */
101}; 101};
102 102
103/* Some BT-specific defines we need here. */
104#define IPMI_BT_INTMASK_REG 2
105#define IPMI_BT_INTMASK_CLEAR_IRQ_BIT 2
106#define IPMI_BT_INTMASK_ENABLE_IRQ_BIT 1
107
103enum si_type { 108enum si_type {
104 SI_KCS, SI_SMIC, SI_BT 109 SI_KCS, SI_SMIC, SI_BT
105}; 110};
@@ -875,6 +880,17 @@ static irqreturn_t si_irq_handler(int irq, void *data, struct pt_regs *regs)
875 return IRQ_HANDLED; 880 return IRQ_HANDLED;
876} 881}
877 882
883static irqreturn_t si_bt_irq_handler(int irq, void *data, struct pt_regs *regs)
884{
885 struct smi_info *smi_info = data;
886 /* We need to clear the IRQ flag for the BT interface. */
887 smi_info->io.outputb(&smi_info->io, IPMI_BT_INTMASK_REG,
888 IPMI_BT_INTMASK_CLEAR_IRQ_BIT
889 | IPMI_BT_INTMASK_ENABLE_IRQ_BIT);
890 return si_irq_handler(irq, data, regs);
891}
892
893
878static struct ipmi_smi_handlers handlers = 894static struct ipmi_smi_handlers handlers =
879{ 895{
880 .owner = THIS_MODULE, 896 .owner = THIS_MODULE,
@@ -1001,11 +1017,22 @@ static int std_irq_setup(struct smi_info *info)
1001 if (!info->irq) 1017 if (!info->irq)
1002 return 0; 1018 return 0;
1003 1019
1004 rv = request_irq(info->irq, 1020 if (info->si_type == SI_BT) {
1005 si_irq_handler, 1021 rv = request_irq(info->irq,
1006 SA_INTERRUPT, 1022 si_bt_irq_handler,
1007 DEVICE_NAME, 1023 SA_INTERRUPT,
1008 info); 1024 DEVICE_NAME,
1025 info);
1026 if (!rv)
1027 /* Enable the interrupt in the BT interface. */
1028 info->io.outputb(&info->io, IPMI_BT_INTMASK_REG,
1029 IPMI_BT_INTMASK_ENABLE_IRQ_BIT);
1030 } else
1031 rv = request_irq(info->irq,
1032 si_irq_handler,
1033 SA_INTERRUPT,
1034 DEVICE_NAME,
1035 info);
1009 if (rv) { 1036 if (rv) {
1010 printk(KERN_WARNING 1037 printk(KERN_WARNING
1011 "ipmi_si: %s unable to claim interrupt %d," 1038 "ipmi_si: %s unable to claim interrupt %d,"
@@ -1024,6 +1051,9 @@ static void std_irq_cleanup(struct smi_info *info)
1024 if (!info->irq) 1051 if (!info->irq)
1025 return; 1052 return;
1026 1053
1054 if (info->si_type == SI_BT)
1055 /* Disable the interrupt in the BT interface. */
1056 info->io.outputb(&info->io, IPMI_BT_INTMASK_REG, 0);
1027 free_irq(info->irq, info); 1057 free_irq(info->irq, info);
1028} 1058}
1029 1059