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; ...@@ -174,14 +174,6 @@ static stlport_t stl_dummyport;
*/ */
static char stl_unwanted[SC26198_RXFIFOSIZE]; 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]; 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 ...@@ -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_brdinit(stlbrd_t *brdp);
static int stl_initports(stlbrd_t *brdp, stlpanel_t *panelp); 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_getserial(stlport_t *portp, struct serial_struct __user *sp);
static int stl_setserial(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); static int stl_getbrdstats(combrd_t __user *bp);
...@@ -513,11 +504,11 @@ static int stl_clrportstats(stlport_t *portp, comstats_t __user *cp); ...@@ -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_getportstruct(stlport_t __user *arg);
static int stl_getbrdstruct(stlbrd_t __user *arg); static int stl_getbrdstruct(stlbrd_t __user *arg);
static int stl_waitcarrier(stlport_t *portp, struct file *filp); static int stl_waitcarrier(stlport_t *portp, struct file *filp);
static void stl_eiointr(stlbrd_t *brdp); static int stl_eiointr(stlbrd_t *brdp);
static void stl_echatintr(stlbrd_t *brdp); static int stl_echatintr(stlbrd_t *brdp);
static void stl_echmcaintr(stlbrd_t *brdp); static int stl_echmcaintr(stlbrd_t *brdp);
static void stl_echpciintr(stlbrd_t *brdp); static int stl_echpciintr(stlbrd_t *brdp);
static void stl_echpci64intr(stlbrd_t *brdp); static int stl_echpci64intr(stlbrd_t *brdp);
static void stl_offintr(void *private); static void stl_offintr(void *private);
static void *stl_memalloc(int len); static void *stl_memalloc(int len);
static stlbrd_t *stl_allocbrd(void); static stlbrd_t *stl_allocbrd(void);
...@@ -807,6 +798,9 @@ static void __exit stallion_module_exit(void) ...@@ -807,6 +798,9 @@ static void __exit stallion_module_exit(void)
for (i = 0; (i < stl_nrbrds); i++) { for (i = 0; (i < stl_nrbrds); i++) {
if ((brdp = stl_brds[i]) == (stlbrd_t *) NULL) if ((brdp = stl_brds[i]) == (stlbrd_t *) NULL)
continue; continue;
free_irq(brdp->irq, brdp);
for (j = 0; (j < STL_MAXPANELS); j++) { for (j = 0; (j < STL_MAXPANELS); j++) {
panelp = brdp->panels[j]; panelp = brdp->panels[j];
if (panelp == (stlpanel_t *) NULL) if (panelp == (stlpanel_t *) NULL)
...@@ -832,9 +826,6 @@ static void __exit stallion_module_exit(void) ...@@ -832,9 +826,6 @@ static void __exit stallion_module_exit(void)
stl_brds[i] = (stlbrd_t *) NULL; stl_brds[i] = (stlbrd_t *) NULL;
} }
for (i = 0; (i < stl_numintrs); i++)
free_irq(stl_gotintrs[i], NULL);
restore_flags(flags); restore_flags(flags);
} }
...@@ -1992,23 +1983,14 @@ static int stl_readproc(char *page, char **start, off_t off, int count, int *eof ...@@ -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) static irqreturn_t stl_intr(int irq, void *dev_id, struct pt_regs *regs)
{ {
stlbrd_t *brdp; stlbrd_t *brdp = (stlbrd_t *) dev_id;
int i;
int handled = 0;
#ifdef DEBUG #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 #endif
for (i = 0; (i < stl_nrbrds); i++) { return IRQ_RETVAL((* brdp->isr)(brdp));
if ((brdp = stl_brds[i]) == (stlbrd_t *) NULL)
continue;
if (brdp->state == 0)
continue;
handled = 1;
(* brdp->isr)(brdp);
}
return IRQ_RETVAL(handled);
} }
/*****************************************************************************/ /*****************************************************************************/
...@@ -2017,15 +1999,19 @@ static irqreturn_t stl_intr(int irq, void *dev_id, struct pt_regs *regs) ...@@ -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. * Interrupt service routine for EasyIO board types.
*/ */
static void stl_eiointr(stlbrd_t *brdp) static int stl_eiointr(stlbrd_t *brdp)
{ {
stlpanel_t *panelp; stlpanel_t *panelp;
unsigned int iobase; unsigned int iobase;
int handled = 0;
panelp = brdp->panels[0]; panelp = brdp->panels[0];
iobase = panelp->iobase; iobase = panelp->iobase;
while (inb(brdp->iostatus) & EIO_INTRPEND) while (inb(brdp->iostatus) & EIO_INTRPEND) {
handled = 1;
(* panelp->isr)(panelp, iobase); (* panelp->isr)(panelp, iobase);
}
return handled;
} }
/*****************************************************************************/ /*****************************************************************************/
...@@ -2034,15 +2020,17 @@ static void stl_eiointr(stlbrd_t *brdp) ...@@ -2034,15 +2020,17 @@ static void stl_eiointr(stlbrd_t *brdp)
* Interrupt service routine for ECH-AT board types. * 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; stlpanel_t *panelp;
unsigned int ioaddr; unsigned int ioaddr;
int bnknr; int bnknr;
int handled = 0;
outb((brdp->ioctrlval | ECH_BRDENABLE), brdp->ioctrl); outb((brdp->ioctrlval | ECH_BRDENABLE), brdp->ioctrl);
while (inb(brdp->iostatus) & ECH_INTRPEND) { while (inb(brdp->iostatus) & ECH_INTRPEND) {
handled = 1;
for (bnknr = 0; (bnknr < brdp->nrbnks); bnknr++) { for (bnknr = 0; (bnknr < brdp->nrbnks); bnknr++) {
ioaddr = brdp->bnkstataddr[bnknr]; ioaddr = brdp->bnkstataddr[bnknr];
if (inb(ioaddr) & ECH_PNLINTRPEND) { if (inb(ioaddr) & ECH_PNLINTRPEND) {
...@@ -2053,6 +2041,8 @@ static void stl_echatintr(stlbrd_t *brdp) ...@@ -2053,6 +2041,8 @@ static void stl_echatintr(stlbrd_t *brdp)
} }
outb((brdp->ioctrlval | ECH_BRDDISABLE), brdp->ioctrl); outb((brdp->ioctrlval | ECH_BRDDISABLE), brdp->ioctrl);
return handled;
} }
/*****************************************************************************/ /*****************************************************************************/
...@@ -2061,13 +2051,15 @@ static void stl_echatintr(stlbrd_t *brdp) ...@@ -2061,13 +2051,15 @@ static void stl_echatintr(stlbrd_t *brdp)
* Interrupt service routine for ECH-MCA board types. * 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; stlpanel_t *panelp;
unsigned int ioaddr; unsigned int ioaddr;
int bnknr; int bnknr;
int handled = 0;
while (inb(brdp->iostatus) & ECH_INTRPEND) { while (inb(brdp->iostatus) & ECH_INTRPEND) {
handled = 1;
for (bnknr = 0; (bnknr < brdp->nrbnks); bnknr++) { for (bnknr = 0; (bnknr < brdp->nrbnks); bnknr++) {
ioaddr = brdp->bnkstataddr[bnknr]; ioaddr = brdp->bnkstataddr[bnknr];
if (inb(ioaddr) & ECH_PNLINTRPEND) { if (inb(ioaddr) & ECH_PNLINTRPEND) {
...@@ -2076,6 +2068,7 @@ static void stl_echmcaintr(stlbrd_t *brdp) ...@@ -2076,6 +2068,7 @@ static void stl_echmcaintr(stlbrd_t *brdp)
} }
} }
} }
return handled;
} }
/*****************************************************************************/ /*****************************************************************************/
...@@ -2084,11 +2077,12 @@ static void stl_echmcaintr(stlbrd_t *brdp) ...@@ -2084,11 +2077,12 @@ static void stl_echmcaintr(stlbrd_t *brdp)
* Interrupt service routine for ECH-PCI board types. * 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; stlpanel_t *panelp;
unsigned int ioaddr; unsigned int ioaddr;
int bnknr, recheck; int bnknr, recheck;
int handled = 0;
while (1) { while (1) {
recheck = 0; recheck = 0;
...@@ -2099,11 +2093,13 @@ static void stl_echpciintr(stlbrd_t *brdp) ...@@ -2099,11 +2093,13 @@ static void stl_echpciintr(stlbrd_t *brdp)
panelp = brdp->bnk2panel[bnknr]; panelp = brdp->bnk2panel[bnknr];
(* panelp->isr)(panelp, (ioaddr & 0xfffc)); (* panelp->isr)(panelp, (ioaddr & 0xfffc));
recheck++; recheck++;
handled = 1;
} }
} }
if (! recheck) if (! recheck)
break; break;
} }
return handled;
} }
/*****************************************************************************/ /*****************************************************************************/
...@@ -2112,13 +2108,15 @@ static void stl_echpciintr(stlbrd_t *brdp) ...@@ -2112,13 +2108,15 @@ static void stl_echpciintr(stlbrd_t *brdp)
* Interrupt service routine for ECH-8/64-PCI board types. * 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; stlpanel_t *panelp;
unsigned int ioaddr; unsigned int ioaddr;
int bnknr; int bnknr;
int handled = 0;
while (inb(brdp->ioctrl) & 0x1) { while (inb(brdp->ioctrl) & 0x1) {
handled = 1;
for (bnknr = 0; (bnknr < brdp->nrbnks); bnknr++) { for (bnknr = 0; (bnknr < brdp->nrbnks); bnknr++) {
ioaddr = brdp->bnkstataddr[bnknr]; ioaddr = brdp->bnkstataddr[bnknr];
if (inb(ioaddr) & ECH_PNLINTRPEND) { if (inb(ioaddr) & ECH_PNLINTRPEND) {
...@@ -2127,6 +2125,8 @@ static void stl_echpci64intr(stlbrd_t *brdp) ...@@ -2127,6 +2125,8 @@ static void stl_echpci64intr(stlbrd_t *brdp)
} }
} }
} }
return handled;
} }
/*****************************************************************************/ /*****************************************************************************/
...@@ -2173,39 +2173,6 @@ static void stl_offintr(void *private) ...@@ -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. * Initialize all the ports on a panel.
*/ */
...@@ -2389,7 +2356,13 @@ static inline int stl_initeio(stlbrd_t *brdp) ...@@ -2389,7 +2356,13 @@ static inline int stl_initeio(stlbrd_t *brdp)
brdp->nrpanels = 1; brdp->nrpanels = 1;
brdp->state |= BRD_FOUND; brdp->state |= BRD_FOUND;
brdp->hwid = status; 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); return(rc);
} }
...@@ -2594,7 +2567,14 @@ static inline int stl_initech(stlbrd_t *brdp) ...@@ -2594,7 +2567,14 @@ static inline int stl_initech(stlbrd_t *brdp)
outb((brdp->ioctrlval | ECH_BRDDISABLE), brdp->ioctrl); outb((brdp->ioctrlval | ECH_BRDDISABLE), brdp->ioctrl);
brdp->state |= BRD_FOUND; 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); return(i);
} }
......
...@@ -126,7 +126,7 @@ typedef struct stlbrd { ...@@ -126,7 +126,7 @@ typedef struct stlbrd {
int nrbnks; int nrbnks;
int irq; int irq;
int irqtype; int irqtype;
void (*isr)(struct stlbrd *brdp); int (*isr)(struct stlbrd *brdp);
unsigned int ioaddr1; unsigned int ioaddr1;
unsigned int ioaddr2; unsigned int ioaddr2;
unsigned int iosize1; 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