drivers/ieee802154/at86rf230: rework irq handler
Fix LOCKDEP bug message for the irq handler spinlock. Make the irq processing code more explicit and stable. Signed-off-by: Alexander Smirnov <alex.bluesman.smirnov@gmail.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
4d27de149b
commit
5b00f2eef3
@ -543,6 +543,13 @@ at86rf230_xmit(struct ieee802154_dev *dev, struct sk_buff *skb)
|
|||||||
int rc;
|
int rc;
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
|
|
||||||
|
spin_lock(&lp->lock);
|
||||||
|
if (lp->irq_disabled) {
|
||||||
|
spin_unlock(&lp->lock);
|
||||||
|
return -EBUSY;
|
||||||
|
}
|
||||||
|
spin_unlock(&lp->lock);
|
||||||
|
|
||||||
might_sleep();
|
might_sleep();
|
||||||
|
|
||||||
rc = at86rf230_state(dev, STATE_FORCE_TX_ON);
|
rc = at86rf230_state(dev, STATE_FORCE_TX_ON);
|
||||||
@ -592,12 +599,8 @@ static int at86rf230_rx(struct at86rf230_local *lp)
|
|||||||
if (!skb)
|
if (!skb)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
if (at86rf230_write_subreg(lp, SR_RX_PDT_DIS, 1) ||
|
if (at86rf230_read_fbuf(lp, skb_put(skb, len), &len, &lqi))
|
||||||
at86rf230_read_fbuf(lp, skb_put(skb, len), &len, &lqi) ||
|
|
||||||
at86rf230_write_subreg(lp, SR_RX_SAFE_MODE, 1) ||
|
|
||||||
at86rf230_write_subreg(lp, SR_RX_PDT_DIS, 0)) {
|
|
||||||
goto err;
|
goto err;
|
||||||
}
|
|
||||||
|
|
||||||
if (len < 2)
|
if (len < 2)
|
||||||
goto err;
|
goto err;
|
||||||
@ -633,7 +636,6 @@ static void at86rf230_irqwork(struct work_struct *work)
|
|||||||
int rc;
|
int rc;
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
|
|
||||||
spin_lock_irqsave(&lp->lock, flags);
|
|
||||||
rc = at86rf230_read_subreg(lp, RG_IRQ_STATUS, 0xff, 0, &val);
|
rc = at86rf230_read_subreg(lp, RG_IRQ_STATUS, 0xff, 0, &val);
|
||||||
status |= val;
|
status |= val;
|
||||||
|
|
||||||
@ -643,31 +645,33 @@ static void at86rf230_irqwork(struct work_struct *work)
|
|||||||
status &= ~IRQ_TRX_UR; /* FIXME: possibly handle ???*/
|
status &= ~IRQ_TRX_UR; /* FIXME: possibly handle ???*/
|
||||||
|
|
||||||
if (status & IRQ_TRX_END) {
|
if (status & IRQ_TRX_END) {
|
||||||
|
spin_lock_irqsave(&lp->lock, flags);
|
||||||
status &= ~IRQ_TRX_END;
|
status &= ~IRQ_TRX_END;
|
||||||
if (lp->is_tx) {
|
if (lp->is_tx) {
|
||||||
lp->is_tx = 0;
|
lp->is_tx = 0;
|
||||||
|
spin_unlock_irqrestore(&lp->lock, flags);
|
||||||
complete(&lp->tx_complete);
|
complete(&lp->tx_complete);
|
||||||
} else {
|
} else {
|
||||||
|
spin_unlock_irqrestore(&lp->lock, flags);
|
||||||
at86rf230_rx(lp);
|
at86rf230_rx(lp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (lp->irq_disabled) {
|
spin_lock_irqsave(&lp->lock, flags);
|
||||||
lp->irq_disabled = 0;
|
lp->irq_disabled = 0;
|
||||||
enable_irq(lp->spi->irq);
|
|
||||||
}
|
|
||||||
spin_unlock_irqrestore(&lp->lock, flags);
|
spin_unlock_irqrestore(&lp->lock, flags);
|
||||||
|
|
||||||
|
enable_irq(lp->spi->irq);
|
||||||
}
|
}
|
||||||
|
|
||||||
static irqreturn_t at86rf230_isr(int irq, void *data)
|
static irqreturn_t at86rf230_isr(int irq, void *data)
|
||||||
{
|
{
|
||||||
struct at86rf230_local *lp = data;
|
struct at86rf230_local *lp = data;
|
||||||
|
|
||||||
|
disable_irq_nosync(irq);
|
||||||
|
|
||||||
spin_lock(&lp->lock);
|
spin_lock(&lp->lock);
|
||||||
if (!lp->irq_disabled) {
|
lp->irq_disabled = 1;
|
||||||
disable_irq_nosync(irq);
|
|
||||||
lp->irq_disabled = 1;
|
|
||||||
}
|
|
||||||
spin_unlock(&lp->lock);
|
spin_unlock(&lp->lock);
|
||||||
|
|
||||||
schedule_work(&lp->irqwork);
|
schedule_work(&lp->irqwork);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user