diff options
Diffstat (limited to 'drivers/char/ipmi')
-rw-r--r-- | drivers/char/ipmi/ipmi_bt_sm.c | 1 | ||||
-rw-r--r-- | drivers/char/ipmi/ipmi_si_intf.c | 40 |
2 files changed, 35 insertions, 6 deletions
diff --git a/drivers/char/ipmi/ipmi_bt_sm.c b/drivers/char/ipmi/ipmi_bt_sm.c index 225b330115bb..5ce9c6269033 100644 --- a/drivers/char/ipmi/ipmi_bt_sm.c +++ b/drivers/char/ipmi/ipmi_bt_sm.c | |||
@@ -235,7 +235,6 @@ static void reset_flags(struct si_sm_data *bt) | |||
235 | if (BT_STATUS & BT_B_BUSY) BT_CONTROL(BT_B_BUSY); | 235 | if (BT_STATUS & BT_B_BUSY) BT_CONTROL(BT_B_BUSY); |
236 | BT_CONTROL(BT_CLR_WR_PTR); | 236 | BT_CONTROL(BT_CLR_WR_PTR); |
237 | BT_CONTROL(BT_SMS_ATN); | 237 | BT_CONTROL(BT_SMS_ATN); |
238 | BT_INTMASK_W(BT_BMC_HWRST); | ||
239 | #ifdef DEVELOPMENT_ONLY_NOT_FOR_PRODUCTION | 238 | #ifdef DEVELOPMENT_ONLY_NOT_FOR_PRODUCTION |
240 | if (BT_STATUS & BT_B2H_ATN) { | 239 | if (BT_STATUS & BT_B2H_ATN) { |
241 | int i; | 240 | int i; |
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 | |||
103 | enum si_type { | 108 | enum 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 | ||
883 | static 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 | |||
878 | static struct ipmi_smi_handlers handlers = | 894 | static 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 | ||