diff options
author | Ralf Baechle <ralf@linux-mips.org> | 1999-10-09 00:00:47 +0000 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 1999-10-09 00:00:47 +0000 |
commit | d6434e1042f3b0a6dfe1b1f615af369486f9b1fa (patch) | |
tree | e2be02f33984c48ec019c654051d27964e42c441 /drivers/isdn/hisax/telespci.c | |
parent | 609d1e803baf519487233b765eb487f9ec227a18 (diff) |
Merge with 2.3.19.
Diffstat (limited to 'drivers/isdn/hisax/telespci.c')
-rw-r--r-- | drivers/isdn/hisax/telespci.c | 98 |
1 files changed, 69 insertions, 29 deletions
diff --git a/drivers/isdn/hisax/telespci.c b/drivers/isdn/hisax/telespci.c index 88592aa8d..9ffe99918 100644 --- a/drivers/isdn/hisax/telespci.c +++ b/drivers/isdn/hisax/telespci.c @@ -1,4 +1,4 @@ -/* $Id: telespci.c,v 2.5 1998/11/15 23:55:28 keil Exp $ +/* $Id: telespci.c,v 2.9 1999/08/11 21:01:34 keil Exp $ * telespci.c low level stuff for Teles PCI isdn cards * @@ -7,6 +7,19 @@ * * * $Log: telespci.c,v $ + * Revision 2.9 1999/08/11 21:01:34 keil + * new PCI codefix + * + * Revision 2.8 1999/08/10 16:02:10 calle + * struct pci_dev changed in 2.3.13. Made the necessary changes. + * + * Revision 2.7 1999/07/12 21:05:34 keil + * fix race in IRQ handling + * added watchdog for lost IRQs + * + * Revision 2.6 1999/07/01 08:12:15 keil + * Common HiSax version for 2.0, 2.1, 2.2 and 2.3 kernel + * * Revision 2.5 1998/11/15 23:55:28 keil * changes from 2.0 * @@ -24,16 +37,17 @@ */ #define __NO_VERSION__ #include <linux/config.h> -#include <linux/string.h> #include "hisax.h" #include "isac.h" #include "hscx.h" #include "isdnl1.h" #include <linux/pci.h> +#ifndef COMPAT_HAS_NEW_PCI +#include <linux/bios32.h> +#endif extern const char *CardType[]; - -const char *telespci_revision = "$Revision: 2.5 $"; +const char *telespci_revision = "$Revision: 2.9 $"; #define ZORAN_PO_RQ_PEN 0x02000000 #define ZORAN_PO_WR 0x00800000 @@ -243,35 +257,27 @@ telespci_interrupt(int intno, void *dev_id, struct pt_regs *regs) { #define MAXCOUNT 20 struct IsdnCardState *cs = dev_id; - u_char val, stat = 0; + u_char val; if (!cs) { printk(KERN_WARNING "TelesPCI: Spurious interrupt!\n"); return; } val = readhscx(cs->hw.teles0.membase, 1, HSCX_ISTA); - if (val) { + if (val) hscx_int_main(cs, val); - stat |= 1; - } val = readisac(cs->hw.teles0.membase, ISAC_ISTA); - if (val) { + if (val) isac_interrupt(cs, val); - stat |= 2; - } /* Clear interrupt register for Zoran PCI controller */ writel(0x70000000, cs->hw.teles0.membase + 0x3C); - if (stat & 1) { - writehscx(cs->hw.teles0.membase, 0, HSCX_MASK, 0xFF); - writehscx(cs->hw.teles0.membase, 1, HSCX_MASK, 0xFF); - writehscx(cs->hw.teles0.membase, 0, HSCX_MASK, 0x0); - writehscx(cs->hw.teles0.membase, 1, HSCX_MASK, 0x0); - } - if (stat & 2) { - writeisac(cs->hw.teles0.membase, ISAC_MASK, 0xFF); - writeisac(cs->hw.teles0.membase, ISAC_MASK, 0x0); - } + writehscx(cs->hw.teles0.membase, 0, HSCX_MASK, 0xFF); + writehscx(cs->hw.teles0.membase, 1, HSCX_MASK, 0xFF); + writeisac(cs->hw.teles0.membase, ISAC_MASK, 0xFF); + writeisac(cs->hw.teles0.membase, ISAC_MASK, 0x0); + writehscx(cs->hw.teles0.membase, 0, HSCX_MASK, 0x0); + writehscx(cs->hw.teles0.membase, 1, HSCX_MASK, 0x0); } void @@ -289,9 +295,6 @@ TelesPCI_card_msg(struct IsdnCardState *cs, int mt, void *arg) case CARD_RELEASE: release_io_telespci(cs); return(0); - case CARD_SETIRQ: - return(request_irq(cs->irq, &telespci_interrupt, - I4L_IRQ_FLAG | SA_SHIRQ, "HiSax", cs)); case CARD_INIT: inithscxisac(cs, 3); return(0); @@ -301,20 +304,29 @@ TelesPCI_card_msg(struct IsdnCardState *cs, int mt, void *arg) return(0); } +#ifdef COMPAT_HAS_NEW_PCI static struct pci_dev *dev_tel __initdata = NULL; +#else +static int pci_index __initdata = 0; +#endif -__initfunc(int -setup_telespci(struct IsdnCard *card)) +int __init +setup_telespci(struct IsdnCard *card) { struct IsdnCardState *cs = card->cs; char tmp[64]; +#ifndef COMPAT_HAS_NEW_PCI + u_char pci_bus, pci_device_fn, pci_irq; + u_int pci_memaddr; + u_char found = 0; +#endif strcpy(tmp, telespci_revision); printk(KERN_INFO "HiSax: Teles/PCI driver Rev. %s\n", HiSax_getrev(tmp)); if (cs->typ != ISDN_CTYPE_TELESPCI) return (0); - #if CONFIG_PCI +#ifdef COMPAT_HAS_NEW_PCI if (!pci_present()) { printk(KERN_ERR "TelesPCI: no PCI bus present\n"); return(0); @@ -325,15 +337,41 @@ setup_telespci(struct IsdnCard *card)) printk(KERN_WARNING "Teles: No IRQ for PCI card found\n"); return(0); } - cs->hw.teles0.membase = (u_int) ioremap(dev_tel->base_address[0], + cs->hw.teles0.membase = (u_int) ioremap(get_pcibase(dev_tel, 0), PAGE_SIZE); printk(KERN_INFO "Found: Zoran, base-address: 0x%lx, irq: 0x%x\n", - dev_tel->base_address[0], dev_tel->irq); + get_pcibase(dev_tel, 0), dev_tel->irq); } else { printk(KERN_WARNING "TelesPCI: No PCI card found\n"); return(0); } #else + for (; pci_index < 0xff; pci_index++) { + if (pcibios_find_device (0x11DE, 0x6120, + pci_index, &pci_bus, &pci_device_fn) + == PCIBIOS_SUCCESSFUL) { + found = 1; + } else { + break; + } + pcibios_read_config_dword(pci_bus, pci_device_fn, + PCI_BASE_ADDRESS_0, &pci_memaddr); + pcibios_read_config_byte(pci_bus, pci_device_fn, + PCI_INTERRUPT_LINE, &pci_irq); + + printk(KERN_INFO "Found: Zoran, base-address: 0x%x," + " irq: 0x%x\n", pci_memaddr, pci_irq); + break; + } + if (!found) { + printk(KERN_WARNING "TelesPCI: No PCI card found\n"); + return(0); + } + pci_index++; + cs->irq = pci_irq; + cs->hw.teles0.membase = (u_int) vremap(pci_memaddr, PAGE_SIZE); +#endif /* COMPAT_HAS_NEW_PCI */ +#else printk(KERN_WARNING "HiSax: Teles/PCI and NO_PCI_BIOS\n"); printk(KERN_WARNING "HiSax: Teles/PCI unable to config\n"); return (0); @@ -361,6 +399,8 @@ setup_telespci(struct IsdnCard *card)) cs->BC_Write_Reg = &WriteHSCX; cs->BC_Send_Data = &hscx_fill_fifo; cs->cardmsg = &TelesPCI_card_msg; + cs->irq_func = &telespci_interrupt; + cs->irq_flags |= SA_SHIRQ; ISACVersion(cs, "TelesPCI:"); if (HscxVersion(cs, "TelesPCI:")) { printk(KERN_WARNING |