Commit 14dad372 authored by Kai Germaschewski's avatar Kai Germaschewski

ISDN/HiSax: Share interrupt handler for ISAC/HSCX cards

Except for a minor performance penalty, using the same IRQ handler
for cards which used the same code anyway seems perfectly natural...
parent c2cacbb4
......@@ -175,42 +175,6 @@ static struct bc_hw_ops hscx_ops = {
.write_fifo = hscx_write_fifo,
};
static void
asuscom_interrupt(int intno, void *dev_id, struct pt_regs *regs)
{
struct IsdnCardState *cs = dev_id;
u8 val;
spin_lock(&cs->lock);
val = hscx_read(cs, 1, HSCX_ISTA);
Start_HSCX:
if (val)
hscx_int_main(cs, val);
val = isac_read(cs, ISAC_ISTA);
Start_ISAC:
if (val)
isac_interrupt(cs, val);
val = hscx_read(cs, 1, HSCX_ISTA);
if (val) {
if (cs->debug & L1_DEB_HSCX)
debugl1(cs, "HSCX IntStat after IntRoutine");
goto Start_HSCX;
}
val = isac_read(cs, ISAC_ISTA);
if (val) {
if (cs->debug & L1_DEB_ISAC)
debugl1(cs, "ISAC IntStat after IntRoutine");
goto Start_ISAC;
}
hscx_write(cs, 0, HSCX_MASK, 0xFF);
hscx_write(cs, 1, HSCX_MASK, 0xFF);
isac_write(cs, ISAC_MASK, 0xFF);
isac_write(cs, ISAC_MASK, 0x0);
hscx_write(cs, 0, HSCX_MASK, 0x0);
hscx_write(cs, 1, HSCX_MASK, 0x0);
spin_unlock(&cs->lock);
}
static void
asuscom_ipac_interrupt(int intno, void *dev_id, struct pt_regs *regs)
{
......@@ -310,7 +274,7 @@ static struct card_ops asuscom_ops = {
.init = asuscom_init,
.reset = asuscom_reset,
.release = asuscom_release,
.irq_func = asuscom_interrupt,
.irq_func = hscxisac_irq,
};
static struct card_ops asuscom_ipac_ops = {
......
......@@ -315,53 +315,26 @@ elsa_interrupt(int intno, void *dev_id, struct pt_regs *regs)
{
struct IsdnCardState *cs = dev_id;
u8 val;
int icnt=5;
spin_lock(&cs->lock);
if ((cs->typ == ISDN_CTYPE_ELSA_PCMCIA) && (*cs->busy_flag == 1)) {
/* The card tends to generate interrupts while being removed
causing us to just crash the kernel. bad. */
printk(KERN_WARNING "Elsa: card not available!\n");
goto unlock;
return;
}
#if ARCOFI_USE
if (cs->hw.elsa.MFlag) {
val = serial_inp(cs, UART_IIR);
if (!(val & UART_IIR_NO_INT)) {
debugl1(cs,"IIR %02x", val);
spin_lock(&cs->lock);
rs_interrupt_elsa(intno, cs);
spin_unlock(&cs->lock);
}
}
#endif
val = hscx_read(cs, 1, HSCX_ISTA);
Start_HSCX:
if (val) {
hscx_int_main(cs, val);
}
val = isac_read(cs, ISAC_ISTA);
Start_ISAC:
if (val) {
isac_interrupt(cs, val);
}
val = hscx_read(cs, 1, HSCX_ISTA);
if (val && icnt) {
if (cs->debug & L1_DEB_HSCX)
debugl1(cs, "HSCX IntStat after IntRoutine");
icnt--;
goto Start_HSCX;
}
val = isac_read(cs, ISAC_ISTA);
if (val && icnt) {
if (cs->debug & L1_DEB_ISAC)
debugl1(cs, "ISAC IntStat after IntRoutine");
icnt--;
goto Start_ISAC;
}
if (!icnt)
printk(KERN_WARNING"ELSA IRQ LOOP\n");
hscx_write(cs, 0, HSCX_MASK, 0xFF);
hscx_write(cs, 1, HSCX_MASK, 0xFF);
isac_write(cs, ISAC_MASK, 0xFF);
hscxisac_irq(intno, dev_id, regs);
if (cs->hw.elsa.status & ELSA_TIMER_AKTIV) {
if (!TimerRun(cs)) {
/* Timer Restart */
......@@ -381,11 +354,6 @@ elsa_interrupt(int intno, void *dev_id, struct pt_regs *regs)
#endif
if (cs->hw.elsa.trig)
byteout(cs->hw.elsa.trig, 0x00);
hscx_write(cs, 0, HSCX_MASK, 0x00);
hscx_write(cs, 1, HSCX_MASK, 0x00);
isac_write(cs, ISAC_MASK, 0x00);
unlock:
spin_unlock(&cs->lock);
}
static void
......
......@@ -38,3 +38,4 @@ extern int HscxVersion(struct IsdnCardState *cs, char *s);
extern void modehscx(struct BCState *bcs, int mode, int bc);
extern void inithscxisac(struct IsdnCardState *cs);
extern void hscx_int_main(struct IsdnCardState *cs, u8 val);
extern void hscxisac_irq(int intno, void *dev_id, struct pt_regs *regs);
......@@ -170,3 +170,56 @@ hscx_int_main(struct IsdnCardState *cs, u8 val)
hscx_interrupt(cs, exval, 0);
}
}
/* ====================================================================== */
static inline u8
isac_read(struct IsdnCardState *cs, u8 addr)
{
return cs->dc_hw_ops->read_reg(cs, addr);
}
static inline void
isac_write(struct IsdnCardState *cs, u8 addr, u8 val)
{
cs->dc_hw_ops->write_reg(cs, addr, val);
}
void
hscxisac_irq(int intno, void *dev_id, struct pt_regs *regs)
{
struct IsdnCardState *cs = dev_id;
u8 val;
int count = 0;
spin_lock(&cs->lock);
val = hscx_read(&cs->bcs[1], HSCX_ISTA);
Start_HSCX:
if (val)
hscx_int_main(cs, val);
val = isac_read(cs, ISAC_ISTA);
Start_ISAC:
if (val)
isac_interrupt(cs, val);
count++;
val = hscx_read(&cs->bcs[1], HSCX_ISTA);
if (val && count < 5) {
if (cs->debug & L1_DEB_HSCX)
debugl1(cs, "HSCX IntStat after IntRoutine");
goto Start_HSCX;
}
val = isac_read(cs, ISAC_ISTA);
if (val && count < 5) {
if (cs->debug & L1_DEB_ISAC)
debugl1(cs, "ISAC IntStat after IntRoutine");
goto Start_ISAC;
}
hscx_write(&cs->bcs[0], HSCX_MASK, 0xFF);
hscx_write(&cs->bcs[1], HSCX_MASK, 0xFF);
isac_write(cs, ISAC_MASK, 0xFF);
isac_write(cs, ISAC_MASK, 0x0);
hscx_write(&cs->bcs[0], HSCX_MASK, 0x0);
hscx_write(&cs->bcs[1], HSCX_MASK, 0x0);
spin_unlock(&cs->lock);
}
......@@ -140,42 +140,6 @@ static struct bc_hw_ops hscx_ops = {
.write_fifo = hscx_write_fifo,
};
static void
ix1_interrupt(int intno, void *dev_id, struct pt_regs *regs)
{
struct IsdnCardState *cs = dev_id;
u8 val;
spin_lock(&cs->lock);
val = hscx_read(cs, 1, HSCX_ISTA);
Start_HSCX:
if (val)
hscx_int_main(cs, val);
val = isac_read(cs, ISAC_ISTA);
Start_ISAC:
if (val)
isac_interrupt(cs, val);
val = hscx_read(cs, 1, HSCX_ISTA);
if (val) {
if (cs->debug & L1_DEB_HSCX)
debugl1(cs, "HSCX IntStat after IntRoutine");
goto Start_HSCX;
}
val = isac_read(cs, ISAC_ISTA);
if (val) {
if (cs->debug & L1_DEB_ISAC)
debugl1(cs, "ISAC IntStat after IntRoutine");
goto Start_ISAC;
}
hscx_write(cs, 0, HSCX_MASK, 0xFF);
hscx_write(cs, 1, HSCX_MASK, 0xFF);
isac_write(cs, ISAC_MASK, 0xFF);
isac_write(cs, ISAC_MASK, 0x0);
hscx_write(cs, 0, HSCX_MASK, 0x0);
hscx_write(cs, 1, HSCX_MASK, 0x0);
spin_unlock(&cs->lock);
}
static void
ix1_release(struct IsdnCardState *cs)
{
......@@ -208,7 +172,7 @@ static struct card_ops ix1_ops = {
.init = inithscxisac,
.reset = ix1_reset,
.release = ix1_release,
.irq_func = ix1_interrupt,
.irq_func = hscxisac_irq,
};
#ifdef __ISAPNP__
......
......@@ -132,42 +132,6 @@ static struct bc_hw_ops hscx_ops = {
.write_fifo = hscx_write_fifo,
};
static void
mic_interrupt(int intno, void *dev_id, struct pt_regs *regs)
{
struct IsdnCardState *cs = dev_id;
u8 val;
spin_lock(&cs->lock);
val = hscx_read(cs, 1, HSCX_ISTA);
Start_HSCX:
if (val)
hscx_int_main(cs, val);
val = isac_read(cs, ISAC_ISTA);
Start_ISAC:
if (val)
isac_interrupt(cs, val);
val = hscx_read(cs, 1, HSCX_ISTA);
if (val) {
if (cs->debug & L1_DEB_HSCX)
debugl1(cs, "HSCX IntStat after IntRoutine");
goto Start_HSCX;
}
val = isac_read(cs, ISAC_ISTA);
if (val) {
if (cs->debug & L1_DEB_ISAC)
debugl1(cs, "ISAC IntStat after IntRoutine");
goto Start_ISAC;
}
hscx_write(cs, 0, HSCX_MASK, 0xFF);
hscx_write(cs, 1, HSCX_MASK, 0xFF);
isac_write(cs, ISAC_MASK, 0xFF);
isac_write(cs, ISAC_MASK, 0x0);
hscx_write(cs, 0, HSCX_MASK, 0x0);
hscx_write(cs, 1, HSCX_MASK, 0x0);
spin_unlock(&cs->lock);
}
static void
mic_release(struct IsdnCardState *cs)
{
......@@ -184,7 +148,7 @@ mic_card_msg(struct IsdnCardState *cs, int mt, void *arg)
static struct card_ops mic_ops = {
.init = inithscxisac,
.release = mic_release,
.irq_func = mic_interrupt,
.irq_func = hscxisac_irq,
};
int __init
......
......@@ -155,9 +155,7 @@ static void
niccy_interrupt(int intno, void *dev_id, struct pt_regs *regs)
{
struct IsdnCardState *cs = dev_id;
u8 val;
spin_lock(&cs->lock);
if (cs->subtyp == NICCY_PCI) {
int ival;
ival = inl(cs->hw.niccy.cfg_reg + PCI_IRQ_CTRL_REG);
......@@ -165,33 +163,7 @@ niccy_interrupt(int intno, void *dev_id, struct pt_regs *regs)
return;
outl(ival, cs->hw.niccy.cfg_reg + PCI_IRQ_CTRL_REG);
}
val = hscx_read(cs, 1, HSCX_ISTA);
Start_HSCX:
if (val)
hscx_int_main(cs, val);
val = isac_read(cs, ISAC_ISTA);
Start_ISAC:
if (val)
isac_interrupt(cs, val);
val = hscx_read(cs, 1, HSCX_ISTA);
if (val) {
if (cs->debug & L1_DEB_HSCX)
debugl1(cs, "HSCX IntStat after IntRoutine");
goto Start_HSCX;
}
val = isac_read(cs, ISAC_ISTA);
if (val) {
if (cs->debug & L1_DEB_ISAC)
debugl1(cs, "ISAC IntStat after IntRoutine");
goto Start_ISAC;
}
hscx_write(cs, 0, HSCX_MASK, 0xFF);
hscx_write(cs, 1, HSCX_MASK, 0xFF);
isac_write(cs, ISAC_MASK, 0xFF);
isac_write(cs, ISAC_MASK, 0x0);
hscx_write(cs, 0, HSCX_MASK, 0x0);
hscx_write(cs, 1, HSCX_MASK, 0x0);
spin_unlock(&cs->lock);
hscxisac_irq(intno, dev_id, regs);
}
void
......
......@@ -166,47 +166,6 @@ static struct bc_hw_ops hscx_ops = {
.write_fifo = hscx_write_fifo,
};
static void
s0box_interrupt(int intno, void *dev_id, struct pt_regs *regs)
{
#define MAXCOUNT 5
struct IsdnCardState *cs = dev_id;
u8 val;
int count = 0;
spin_lock(&cs->lock);
val = hscx_read(cs, 1, HSCX_ISTA);
Start_HSCX:
if (val)
hscx_int_main(cs, val);
val = isac_read(cs, ISAC_ISTA);
Start_ISAC:
if (val)
isac_interrupt(cs, val);
count++;
val = hscx_read(cs, 1, HSCX_ISTA);
if (val && count < MAXCOUNT) {
if (cs->debug & L1_DEB_HSCX)
debugl1(cs, "HSCX IntStat after IntRoutine");
goto Start_HSCX;
}
val = isac_read(cs, ISAC_ISTA);
if (val && count < MAXCOUNT) {
if (cs->debug & L1_DEB_ISAC)
debugl1(cs, "ISAC IntStat after IntRoutine");
goto Start_ISAC;
}
if (count >= MAXCOUNT)
printk(KERN_WARNING "S0Box: more than %d loops in s0box_interrupt\n", count);
hscx_write(cs, 0, HSCX_MASK, 0xFF);
hscx_write(cs, 1, HSCX_MASK, 0xFF);
isac_write(cs, ISAC_MASK, 0xFF);
isac_write(cs, ISAC_MASK, 0x0);
hscx_write(cs, 0, HSCX_MASK, 0x0);
hscx_write(cs, 1, HSCX_MASK, 0x0);
spin_unlock(&cs->lock);
}
void
s0box_release(struct IsdnCardState *cs)
{
......@@ -222,7 +181,7 @@ S0Box_card_msg(struct IsdnCardState *cs, int mt, void *arg)
static struct card_ops s0box_ops = {
.init = inithscxisac,
.release = s0box_release,
.irq_func = s0box_interrupt,
.irq_func = hscxisac_irq,
};
int __init
......
......@@ -136,42 +136,9 @@ static void
saphir_interrupt(int intno, void *dev_id, struct pt_regs *regs)
{
struct IsdnCardState *cs = dev_id;
u8 val;
spin_lock(&cs->lock);
val = hscx_read(cs, 1, HSCX_ISTA);
Start_HSCX:
if (val)
hscx_int_main(cs, val);
val = isac_read(cs, ISAC_ISTA);
Start_ISAC:
if (val)
isac_interrupt(cs, val);
val = hscx_read(cs, 1, HSCX_ISTA);
if (val) {
if (cs->debug & L1_DEB_HSCX)
debugl1(cs, "HSCX IntStat after IntRoutine");
goto Start_HSCX;
}
val = isac_read(cs, ISAC_ISTA);
if (val) {
if (cs->debug & L1_DEB_ISAC)
debugl1(cs, "ISAC IntStat after IntRoutine");
goto Start_ISAC;
}
/* Watchdog */
if (cs->hw.saphir.timer.function)
mod_timer(&cs->hw.saphir.timer, jiffies+1*HZ);
else
printk(KERN_WARNING "saphir: Spurious timer!\n");
hscx_write(cs, 0, HSCX_MASK, 0xFF);
hscx_write(cs, 1, HSCX_MASK, 0xFF);
isac_write(cs, ISAC_MASK, 0xFF);
isac_write(cs, ISAC_MASK, 0x0);
hscx_write(cs, 0, HSCX_MASK, 0x0);
hscx_write(cs, 1, HSCX_MASK, 0x0);
spin_unlock(&cs->lock);
hscxisac_irq(intno, dev_id, regs);
mod_timer(&cs->hw.saphir.timer, jiffies+1*HZ);
}
static void
......
......@@ -289,12 +289,6 @@ static void
sedlbauer_interrupt(int intno, void *dev_id, struct pt_regs *regs)
{
struct IsdnCardState *cs = dev_id;
u8 val;
if (!cs) {
printk(KERN_WARNING "Sedlbauer: Spurious interrupt!\n");
return;
}
if ((cs->hw.sedl.bus == SEDL_BUS_PCMCIA) && (*cs->busy_flag == 1)) {
/* The card tends to generate interrupts while being removed
......@@ -302,33 +296,7 @@ sedlbauer_interrupt(int intno, void *dev_id, struct pt_regs *regs)
printk(KERN_WARNING "Sedlbauer: card not available!\n");
return;
}
val = hscx_read(cs, 1, HSCX_ISTA);
Start_HSCX:
if (val)
hscx_int_main(cs, val);
val = isac_read(cs, ISAC_ISTA);
Start_ISAC:
if (val)
isac_interrupt(cs, val);
val = hscx_read(cs, 1, HSCX_ISTA);
if (val) {
if (cs->debug & L1_DEB_HSCX)
debugl1(cs, "HSCX IntStat after IntRoutine");
goto Start_HSCX;
}
val = isac_read(cs, ISAC_ISTA);
if (val) {
if (cs->debug & L1_DEB_ISAC)
debugl1(cs, "ISAC IntStat after IntRoutine");
goto Start_ISAC;
}
hscx_write(cs, 0, HSCX_MASK, 0xFF);
hscx_write(cs, 1, HSCX_MASK, 0xFF);
isac_write(cs, ISAC_MASK, 0xFF);
isac_write(cs, ISAC_MASK, 0x0);
hscx_write(cs, 0, HSCX_MASK, 0x0);
hscx_write(cs, 1, HSCX_MASK, 0x0);
hscxisac_irq(intno, dev_id, regs);
}
static void
......
......@@ -115,32 +115,9 @@ static void
sportster_interrupt(int intno, void *dev_id, struct pt_regs *regs)
{
struct IsdnCardState *cs = dev_id;
u8 val;
spin_lock(&cs->lock);
val = hscx_read(cs, 1, HSCX_ISTA);
Start_HSCX:
if (val)
hscx_int_main(cs, val);
val = isac_read(cs, ISAC_ISTA);
Start_ISAC:
if (val)
isac_interrupt(cs, val);
val = hscx_read(cs, 1, HSCX_ISTA);
if (val) {
if (cs->debug & L1_DEB_HSCX)
debugl1(cs, "HSCX IntStat after IntRoutine");
goto Start_HSCX;
}
val = isac_read(cs, ISAC_ISTA);
if (val) {
if (cs->debug & L1_DEB_ISAC)
debugl1(cs, "ISAC IntStat after IntRoutine");
goto Start_ISAC;
}
/* get a new irq impulse if there any pending */
hscxisac_irq(intno, dev_id, regs);
bytein(cs->hw.spt.cfg_reg + SPORTSTER_RES_IRQ +1);
spin_unlock(&cs->lock);
}
static void
......
......@@ -110,44 +110,6 @@ static struct bc_hw_ops hscx_ops = {
.write_fifo = hscx_write_fifo,
};
static void
teles0_interrupt(int intno, void *dev_id, struct pt_regs *regs)
{
struct IsdnCardState *cs = dev_id;
u8 val;
int count = 0;
spin_lock(&cs->lock);
val = hscx_read(cs, 1, HSCX_ISTA);
Start_HSCX:
if (val)
hscx_int_main(cs, val);
val = isac_read(cs, ISAC_ISTA);
Start_ISAC:
if (val)
isac_interrupt(cs, val);
count++;
val = hscx_read(cs, 1, HSCX_ISTA);
if (val && count < 5) {
if (cs->debug & L1_DEB_HSCX)
debugl1(cs, "HSCX IntStat after IntRoutine");
goto Start_HSCX;
}
val = isac_read(cs, ISAC_ISTA);
if (val && count < 5) {
if (cs->debug & L1_DEB_ISAC)
debugl1(cs, "ISAC IntStat after IntRoutine");
goto Start_ISAC;
}
hscx_write(cs, 0, HSCX_MASK, 0xFF);
hscx_write(cs, 1, HSCX_MASK, 0xFF);
isac_write(cs, ISAC_MASK, 0xFF);
isac_write(cs, ISAC_MASK, 0x0);
hscx_write(cs, 0, HSCX_MASK, 0x0);
hscx_write(cs, 1, HSCX_MASK, 0x0);
spin_unlock(&cs->lock);
}
static void
teles0_release(struct IsdnCardState *cs)
{
......@@ -215,7 +177,7 @@ static struct card_ops teles0_ops = {
.init = inithscxisac,
.reset = teles0_reset,
.release = teles0_release,
.irq_func = teles0_interrupt,
.irq_func = hscxisac_irq,
};
int __init
......
......@@ -113,47 +113,6 @@ static struct bc_hw_ops hscx_ops = {
.write_fifo = hscx_write_fifo,
};
static void
teles3_interrupt(int intno, void *dev_id, struct pt_regs *regs)
{
#define MAXCOUNT 5
struct IsdnCardState *cs = dev_id;
u8 val;
int count = 0;
spin_lock(&cs->lock);
val = readreg(cs->hw.teles3.hscx[1], HSCX_ISTA);
Start_HSCX:
if (val)
hscx_int_main(cs, val);
val = readreg(cs->hw.teles3.isac, ISAC_ISTA);
Start_ISAC:
if (val)
isac_interrupt(cs, val);
count++;
val = readreg(cs->hw.teles3.hscx[1], HSCX_ISTA);
if (val && count < MAXCOUNT) {
if (cs->debug & L1_DEB_HSCX)
debugl1(cs, "HSCX IntStat after IntRoutine");
goto Start_HSCX;
}
val = readreg(cs->hw.teles3.isac, ISAC_ISTA);
if (val && count < MAXCOUNT) {
if (cs->debug & L1_DEB_ISAC)
debugl1(cs, "ISAC IntStat after IntRoutine");
goto Start_ISAC;
}
if (count >= MAXCOUNT)
printk(KERN_WARNING "Teles3: more than %d loops in teles3_interrupt\n", count);
hscx_write(cs, 0, HSCX_MASK, 0xFF);
hscx_write(cs, 1, HSCX_MASK, 0xFF);
isac_write(cs, ISAC_MASK, 0xFF);
isac_write(cs, ISAC_MASK, 0x0);
hscx_write(cs, 0, HSCX_MASK, 0x0);
hscx_write(cs, 1, HSCX_MASK, 0x0);
spin_unlock(&cs->lock);
}
inline static void
release_ioregs(struct IsdnCardState *cs, int mask)
{
......@@ -248,7 +207,7 @@ static struct card_ops teles3_ops = {
.init = inithscxisac,
.reset = teles3_reset,
.release = teles3_release,
.irq_func = teles3_interrupt,
.irq_func = hscxisac_irq,
};
#ifdef __ISAPNP__
......
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