aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorCorey Minyard <minyard@acm.org>2005-05-01 11:59:11 -0400
committerLinus Torvalds <torvalds@ppc970.osdl.org>2005-05-01 11:59:11 -0400
commit9dbf68f97d585265eaadd15aea308efd9ae39d34 (patch)
tree84d804f3eb491b4d03f5afc8a38ddf2326fcc17c
parentec26d79f4f5822283e0bffa44a542fd13c5146e4 (diff)
[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: Corey Minyard <minyard@acm.org> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
-rw-r--r--drivers/char/ipmi/ipmi_bt_sm.c1
-rw-r--r--drivers/char/ipmi/ipmi_si_intf.c40
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
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