| From e7a0c58e94b649c9eda4b39bca2071421d1c7e77 Mon Sep 17 00:00:00 2001 |
| From: Thomas Gleixner <tglx@linutronix.de> |
| Date: Wed, 29 Sep 2010 22:16:36 +0200 |
| Subject: [PATCH] isdn: hisax: Replace the bogus access to irq stats |
| |
| commit 40f08a724fcc21285cf3a75aec957aef908605c6 upstream. |
| |
| Abusing irq stats in a driver for counting interrupts is a horrible |
| idea and not safe with shared interrupts. Replace it by a local |
| interrupt counter. |
| |
| Noticed by the attempt to remove the irq stats export. |
| |
| Signed-off-by: Thomas Gleixner <tglx@linutronix.de> |
| Reviewed-by: Ingo Molnar <mingo@elte.hu> |
| Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com> |
| |
| diff --git a/drivers/isdn/hisax/config.c b/drivers/isdn/hisax/config.c |
| index 544cf4b..0a347a8 100644 |
| --- a/drivers/isdn/hisax/config.c |
| +++ b/drivers/isdn/hisax/config.c |
| @@ -801,6 +801,16 @@ static void closecard(int cardnr) |
| ll_unload(csta); |
| } |
| |
| +static irqreturn_t card_irq(int intno, void *dev_id) |
| +{ |
| + struct IsdnCardState *cs = dev_id; |
| + irqreturn_t ret = cs->irq_func(intno, cs); |
| + |
| + if (ret == IRQ_HANDLED) |
| + cs->irq_cnt++; |
| + return ret; |
| +} |
| + |
| static int init_card(struct IsdnCardState *cs) |
| { |
| int irq_cnt, cnt = 3, ret; |
| @@ -809,10 +819,10 @@ static int init_card(struct IsdnCardState *cs) |
| ret = cs->cardmsg(cs, CARD_INIT, NULL); |
| return(ret); |
| } |
| - irq_cnt = kstat_irqs(cs->irq); |
| + irq_cnt = cs->irq_cnt = 0; |
| printk(KERN_INFO "%s: IRQ %d count %d\n", CardType[cs->typ], |
| cs->irq, irq_cnt); |
| - if (request_irq(cs->irq, cs->irq_func, cs->irq_flags, "HiSax", cs)) { |
| + if (request_irq(cs->irq, card_irq, cs->irq_flags, "HiSax", cs)) { |
| printk(KERN_WARNING "HiSax: couldn't get interrupt %d\n", |
| cs->irq); |
| return 1; |
| @@ -822,8 +832,8 @@ static int init_card(struct IsdnCardState *cs) |
| /* Timeout 10ms */ |
| msleep(10); |
| printk(KERN_INFO "%s: IRQ %d count %d\n", |
| - CardType[cs->typ], cs->irq, kstat_irqs(cs->irq)); |
| - if (kstat_irqs(cs->irq) == irq_cnt) { |
| + CardType[cs->typ], cs->irq, cs->irq_cnt); |
| + if (cs->irq_cnt == irq_cnt) { |
| printk(KERN_WARNING |
| "%s: IRQ(%d) getting no interrupts during init %d\n", |
| CardType[cs->typ], cs->irq, 4 - cnt); |
| diff --git a/drivers/isdn/hisax/hisax.h b/drivers/isdn/hisax/hisax.h |
| index 832a878..32ab392 100644 |
| --- a/drivers/isdn/hisax/hisax.h |
| +++ b/drivers/isdn/hisax/hisax.h |
| @@ -959,6 +959,7 @@ struct IsdnCardState { |
| u_long event; |
| struct work_struct tqueue; |
| struct timer_list dbusytimer; |
| + unsigned int irq_cnt; |
| #ifdef ERROR_STATISTIC |
| int err_crc; |
| int err_tx; |
| -- |
| 1.7.4.4 |
| |