Commit 1907f9db authored by Alan Cox's avatar Alan Cox Committed by Linus Torvalds

[PATCH] stallion ressurection, phase 1

This gets the stallion driver working again non-SMP. Patch by Wayne
Meissner
Signed-off-by: default avatarAlan Cox <alan@redhat.com>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent 5a5df221
......@@ -174,14 +174,6 @@ static stlport_t stl_dummyport;
*/
static char stl_unwanted[SC26198_RXFIFOSIZE];
/*
* Keep track of what interrupts we have requested for us.
* We don't need to request an interrupt twice if it is being
* shared with another Stallion board.
*/
static int stl_gotintrs[STL_MAXBRDS];
static int stl_numintrs;
/*****************************************************************************/
static stlbrd_t *stl_brds[STL_MAXBRDS];
......@@ -504,7 +496,6 @@ static int stl_readproc(char *page, char **start, off_t off, int count, int *eof
static int stl_brdinit(stlbrd_t *brdp);
static int stl_initports(stlbrd_t *brdp, stlpanel_t *panelp);
static int stl_mapirq(int irq, char *name);
static int stl_getserial(stlport_t *portp, struct serial_struct __user *sp);
static int stl_setserial(stlport_t *portp, struct serial_struct __user *sp);
static int stl_getbrdstats(combrd_t __user *bp);
......@@ -513,11 +504,11 @@ static int stl_clrportstats(stlport_t *portp, comstats_t __user *cp);
static int stl_getportstruct(stlport_t __user *arg);
static int stl_getbrdstruct(stlbrd_t __user *arg);
static int stl_waitcarrier(stlport_t *portp, struct file *filp);
static void stl_eiointr(stlbrd_t *brdp);
static void stl_echatintr(stlbrd_t *brdp);
static void stl_echmcaintr(stlbrd_t *brdp);
static void stl_echpciintr(stlbrd_t *brdp);
static void stl_echpci64intr(stlbrd_t *brdp);
static int stl_eiointr(stlbrd_t *brdp);
static int stl_echatintr(stlbrd_t *brdp);
static int stl_echmcaintr(stlbrd_t *brdp);
static int stl_echpciintr(stlbrd_t *brdp);
static int stl_echpci64intr(stlbrd_t *brdp);
static void stl_offintr(void *private);
static void *stl_memalloc(int len);
static stlbrd_t *stl_allocbrd(void);
......@@ -807,6 +798,9 @@ static void __exit stallion_module_exit(void)
for (i = 0; (i < stl_nrbrds); i++) {
if ((brdp = stl_brds[i]) == (stlbrd_t *) NULL)
continue;
free_irq(brdp->irq, brdp);
for (j = 0; (j < STL_MAXPANELS); j++) {
panelp = brdp->panels[j];
if (panelp == (stlpanel_t *) NULL)
......@@ -832,9 +826,6 @@ static void __exit stallion_module_exit(void)
stl_brds[i] = (stlbrd_t *) NULL;
}
for (i = 0; (i < stl_numintrs); i++)
free_irq(stl_gotintrs[i], NULL);
restore_flags(flags);
}
......@@ -1992,23 +1983,14 @@ static int stl_readproc(char *page, char **start, off_t off, int count, int *eof
static irqreturn_t stl_intr(int irq, void *dev_id, struct pt_regs *regs)
{
stlbrd_t *brdp;
int i;
int handled = 0;
stlbrd_t *brdp = (stlbrd_t *) dev_id;
#ifdef DEBUG
printk("stl_intr(irq=%d,regs=%x)\n", irq, (int) regs);
printk("stl_intr(brdp=%x,irq=%d,regs=%x)\n", (int) brdp, irq,
(int) regs);
#endif
for (i = 0; (i < stl_nrbrds); i++) {
if ((brdp = stl_brds[i]) == (stlbrd_t *) NULL)
continue;
if (brdp->state == 0)
continue;
handled = 1;
(* brdp->isr)(brdp);
}
return IRQ_RETVAL(handled);
return IRQ_RETVAL((* brdp->isr)(brdp));
}
/*****************************************************************************/
......@@ -2017,15 +1999,19 @@ static irqreturn_t stl_intr(int irq, void *dev_id, struct pt_regs *regs)
* Interrupt service routine for EasyIO board types.
*/
static void stl_eiointr(stlbrd_t *brdp)
static int stl_eiointr(stlbrd_t *brdp)
{
stlpanel_t *panelp;
unsigned int iobase;
int handled = 0;
panelp = brdp->panels[0];
iobase = panelp->iobase;
while (inb(brdp->iostatus) & EIO_INTRPEND)
while (inb(brdp->iostatus) & EIO_INTRPEND) {
handled = 1;
(* panelp->isr)(panelp, iobase);
}
return handled;
}
/*****************************************************************************/
......@@ -2034,15 +2020,17 @@ static void stl_eiointr(stlbrd_t *brdp)
* Interrupt service routine for ECH-AT board types.
*/
static void stl_echatintr(stlbrd_t *brdp)
static int stl_echatintr(stlbrd_t *brdp)
{
stlpanel_t *panelp;
unsigned int ioaddr;
int bnknr;
int handled = 0;
outb((brdp->ioctrlval | ECH_BRDENABLE), brdp->ioctrl);
while (inb(brdp->iostatus) & ECH_INTRPEND) {
handled = 1;
for (bnknr = 0; (bnknr < brdp->nrbnks); bnknr++) {
ioaddr = brdp->bnkstataddr[bnknr];
if (inb(ioaddr) & ECH_PNLINTRPEND) {
......@@ -2053,6 +2041,8 @@ static void stl_echatintr(stlbrd_t *brdp)
}
outb((brdp->ioctrlval | ECH_BRDDISABLE), brdp->ioctrl);
return handled;
}
/*****************************************************************************/
......@@ -2061,13 +2051,15 @@ static void stl_echatintr(stlbrd_t *brdp)
* Interrupt service routine for ECH-MCA board types.
*/
static void stl_echmcaintr(stlbrd_t *brdp)
static int stl_echmcaintr(stlbrd_t *brdp)
{
stlpanel_t *panelp;
unsigned int ioaddr;
int bnknr;
int handled = 0;
while (inb(brdp->iostatus) & ECH_INTRPEND) {
handled = 1;
for (bnknr = 0; (bnknr < brdp->nrbnks); bnknr++) {
ioaddr = brdp->bnkstataddr[bnknr];
if (inb(ioaddr) & ECH_PNLINTRPEND) {
......@@ -2076,6 +2068,7 @@ static void stl_echmcaintr(stlbrd_t *brdp)
}
}
}
return handled;
}
/*****************************************************************************/
......@@ -2084,11 +2077,12 @@ static void stl_echmcaintr(stlbrd_t *brdp)
* Interrupt service routine for ECH-PCI board types.
*/
static void stl_echpciintr(stlbrd_t *brdp)
static int stl_echpciintr(stlbrd_t *brdp)
{
stlpanel_t *panelp;
unsigned int ioaddr;
int bnknr, recheck;
int handled = 0;
while (1) {
recheck = 0;
......@@ -2099,11 +2093,13 @@ static void stl_echpciintr(stlbrd_t *brdp)
panelp = brdp->bnk2panel[bnknr];
(* panelp->isr)(panelp, (ioaddr & 0xfffc));
recheck++;
handled = 1;
}
}
if (! recheck)
break;
}
return handled;
}
/*****************************************************************************/
......@@ -2112,13 +2108,15 @@ static void stl_echpciintr(stlbrd_t *brdp)
* Interrupt service routine for ECH-8/64-PCI board types.
*/
static void stl_echpci64intr(stlbrd_t *brdp)
static int stl_echpci64intr(stlbrd_t *brdp)
{
stlpanel_t *panelp;
unsigned int ioaddr;
int bnknr;
int handled = 0;
while (inb(brdp->ioctrl) & 0x1) {
handled = 1;
for (bnknr = 0; (bnknr < brdp->nrbnks); bnknr++) {
ioaddr = brdp->bnkstataddr[bnknr];
if (inb(ioaddr) & ECH_PNLINTRPEND) {
......@@ -2127,6 +2125,8 @@ static void stl_echpci64intr(stlbrd_t *brdp)
}
}
}
return handled;
}
/*****************************************************************************/
......@@ -2173,39 +2173,6 @@ static void stl_offintr(void *private)
/*****************************************************************************/
/*
* Map in interrupt vector to this driver. Check that we don't
* already have this vector mapped, we might be sharing this
* interrupt across multiple boards.
*/
static int __init stl_mapirq(int irq, char *name)
{
int rc, i;
#ifdef DEBUG
printk("stl_mapirq(irq=%d,name=%s)\n", irq, name);
#endif
rc = 0;
for (i = 0; (i < stl_numintrs); i++) {
if (stl_gotintrs[i] == irq)
break;
}
if (i >= stl_numintrs) {
if (request_irq(irq, stl_intr, SA_SHIRQ, name, NULL) != 0) {
printk("STALLION: failed to register interrupt "
"routine for %s irq=%d\n", name, irq);
rc = -ENODEV;
} else {
stl_gotintrs[stl_numintrs++] = irq;
}
}
return(rc);
}
/*****************************************************************************/
/*
* Initialize all the ports on a panel.
*/
......@@ -2389,7 +2356,13 @@ static inline int stl_initeio(stlbrd_t *brdp)
brdp->nrpanels = 1;
brdp->state |= BRD_FOUND;
brdp->hwid = status;
rc = stl_mapirq(brdp->irq, name);
if (request_irq(brdp->irq, stl_intr, SA_SHIRQ, name, brdp) != 0) {
printk("STALLION: failed to register interrupt "
"routine for %s irq=%d\n", name, brdp->irq);
rc = -ENODEV;
} else {
rc = 0;
}
return(rc);
}
......@@ -2594,7 +2567,14 @@ static inline int stl_initech(stlbrd_t *brdp)
outb((brdp->ioctrlval | ECH_BRDDISABLE), brdp->ioctrl);
brdp->state |= BRD_FOUND;
i = stl_mapirq(brdp->irq, name);
if (request_irq(brdp->irq, stl_intr, SA_SHIRQ, name, brdp) != 0) {
printk("STALLION: failed to register interrupt "
"routine for %s irq=%d\n", name, brdp->irq);
i = -ENODEV;
} else {
i = 0;
}
return(i);
}
......
......@@ -126,7 +126,7 @@ typedef struct stlbrd {
int nrbnks;
int irq;
int irqtype;
void (*isr)(struct stlbrd *brdp);
int (*isr)(struct stlbrd *brdp);
unsigned int ioaddr1;
unsigned int ioaddr2;
unsigned int iosize1;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment