[parisc-linux-cvs] multi-diva change
Paul Bame
bame@fc.hp.com
Tue, 14 Jan 2003 13:17:50 -0700
Index: drivers/char/serial.c
===================================================================
RCS file: /var/cvs/linux/drivers/char/serial.c,v
retrieving revision 1.41
diff -u -r1.41 serial.c
--- drivers/char/serial.c 13 Jan 2003 15:41:06 -0000 1.41
+++ drivers/char/serial.c 14 Jan 2003 20:11:52 -0000
@@ -268,7 +268,7 @@
#ifdef CONFIG_SERIAL_SHARE_IRQ
#define HP_DIVA_CHECKTIME (1*HZ)
static struct timer_list hp_diva_timer;
-static int hp_diva_irq = -1;
+static int hp_diva_count = 0;
#endif /* CONFIG_SERIAL_SHARE_IRQ */
/* serial subtype definitions */
@@ -807,6 +807,19 @@
}
#ifdef CONFIG_SERIAL_SHARE_IRQ
+static inline int is_hp_diva_info(struct async_struct *info)
+{
+ struct pci_dev *dev = info->state->dev;
+ return (dev && dev->vendor == PCI_VENDOR_ID_HP &&
+ dev->device == PCI_DEVICE_ID_HP_SAS);
+}
+
+static inline int is_hp_diva_irq(int irq)
+{
+ struct async_struct *info = IRQ_ports[irq];
+ return (info && is_hp_diva_info(info));
+}
+
/*
* It is possible to "use up" transmit empty interrupts in some
* cases with HP Diva cards. Figure out if there _should_ be a
@@ -817,7 +830,7 @@
{
int iir = serial_in(info, UART_IIR);
- if (irq == hp_diva_irq &&
+ if (is_hp_diva_info(info) &&
(iir & UART_IIR_NO_INT) != 0 &&
(info->IER & UART_IER_THRI) != 0 &&
(info->xmit.head != info->xmit.tail || info->x_char) &&
@@ -1123,7 +1136,7 @@
#ifdef CONFIG_SERIAL_SHARE_IRQ
if (info->next_port) {
do {
- if (i != hp_diva_irq) {
+ if (!is_hp_diva_info(info)) {
serial_out(info, UART_IER, 0);
info->IER |= UART_IER_THRI;
serial_out(info, UART_IER, info->IER);
@@ -1169,15 +1182,16 @@
static void hp_diva_check(unsigned long dummy)
{
static unsigned long last_strobe;
- struct async_struct *info;
unsigned long flags;
+ int i;
if (time_after_eq(jiffies, last_strobe + HP_DIVA_CHECKTIME)) {
- info = IRQ_ports[hp_diva_irq];
- if (info) {
- save_flags(flags); cli();
- rs_interrupt(hp_diva_irq, NULL, NULL);
- restore_flags(flags);
+ for (i = 0; i < NR_IRQS; i++) {
+ if (is_hp_diva_irq(i)) {
+ save_flags(flags); cli();
+ rs_interrupt(i, NULL, NULL);
+ restore_flags(flags);
+ }
}
}
last_strobe = jiffies;
@@ -4325,7 +4339,7 @@
if (!enable)
return 0;
- hp_diva_irq = dev->irq;
+ hp_diva_count++;
switch (dev->subsystem_device) {
case 0x1049: /* Prelude Diva 1 */
@@ -5800,7 +5814,7 @@
/* printk("Unloading %s: version %s\n", serial_name, serial_version); */
del_timer_sync(&serial_timer);
#ifdef CONFIG_SERIAL_SHARE_IRQ
- if (hp_diva_irq != -1)
+ if (hp_diva_count > 0)
del_timer_sync(&hp_diva_timer);
#endif /* CONFIG_SERIAL_SHARE_IRQ */
save_flags(flags); cli();