(tentative patch, for comments) The irq_disabled flag is part of an intricate locking mechanism whose only purpose seems to be to enforce how the program's logic works anyway.
Furthermore, since the worker calls enable_irq, we shouldn't free the interrupt before flushing the work. Also, there was an unreachable call to ieee802154_unregister_device. Signed-off-by: Werner Almesberger <wer...@almesberger.net> --- drivers/ieee802154/at86rf230.c | 27 ++++++++++----------------- 1 files changed, 10 insertions(+), 17 deletions(-) diff --git a/drivers/ieee802154/at86rf230.c b/drivers/ieee802154/at86rf230.c index d979f4b..62d6075 100644 --- a/drivers/ieee802154/at86rf230.c +++ b/drivers/ieee802154/at86rf230.c @@ -59,7 +59,6 @@ struct at86rf230_local { struct ieee802154_dev *dev; spinlock_t lock; - unsigned irq_disabled:1; /* P: lock */ unsigned is_tx:1; /* P: lock */ }; @@ -460,12 +459,7 @@ static void at86rf230_irqwork(struct work_struct *work) } while (status != 0); - spin_lock_irqsave(&lp->lock, flags); - if (lp->irq_disabled) { - lp->irq_disabled = 0; - enable_irq(lp->spi->irq); - } - spin_unlock_irqrestore(&lp->lock, flags); + enable_irq(lp->spi->irq); } static irqreturn_t at86rf230_isr(int irq, void *data) @@ -474,13 +468,7 @@ static irqreturn_t at86rf230_isr(int irq, void *data) dev_dbg(&lp->spi->dev, "IRQ!\n"); - spin_lock(&lp->lock); - if (!lp->irq_disabled) { - disable_irq_nosync(irq); - lp->irq_disabled = 1; - } - spin_unlock(&lp->lock); - + disable_irq_nosync(irq); schedule_work(&lp->irqwork); return IRQ_HANDLED; @@ -757,10 +745,10 @@ static int __devinit at86rf230_probe(struct spi_device *spi) return rc; - ieee802154_unregister_device(lp->dev); err_irq: - free_irq(spi->irq, lp); + disable_irq(spi->irq); flush_work(&lp->irqwork); + free_irq(spi->irq, lp); err_gpio_dir: if (gpio_is_valid(lp->slp_tr)) gpio_free(lp->slp_tr); @@ -779,10 +767,15 @@ static int __devexit at86rf230_remove(struct spi_device *spi) { struct at86rf230_local *lp = spi_get_drvdata(spi); + /* + * @@@ this looks wrong - what if a frame arrives before + * disable_irq ? -- wa + */ ieee802154_unregister_device(lp->dev); - free_irq(spi->irq, lp); + disable_irq(spi->irq); flush_work(&lp->irqwork); + free_irq(spi->irq, lp); if (gpio_is_valid(lp->slp_tr)) gpio_free(lp->slp_tr); -- 1.7.0.4 ------------------------------------------------------------------------------ EditLive Enterprise is the world's most technically advanced content authoring tool. Experience the power of Track Changes, Inline Image Editing and ensure content is compliant with Accessibility Checking. http://p.sf.net/sfu/ephox-dev2dev _______________________________________________ Linux-zigbee-devel mailing list Linux-zigbee-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/linux-zigbee-devel