Hi! > From: Jia-Ju Bai > > [ Upstream commit e36eaf94be8f7bc4e686246eed3cf92d845e2ef8 ] > > The driver may sleep while holding a spinlock. True. But you can't fix the bug by simply removing the locking, as now nothing prevents grgpio_irq_unmap() from running while grgpio_irq_map() is proceeding. grgpio_irq_map() lirq->irq = irq; (drops the lock) grgpio_irq_unmap() (gets the lock) if (lirq->irq == irq) { ... (proceeds to work with half-initialized structure) Best regards, Pavel > index 60a1556c570a4..c1be299e5567b 100644 > --- a/drivers/gpio/gpio-grgpio.c > +++ b/drivers/gpio/gpio-grgpio.c > @@ -258,17 +258,16 @@ static int grgpio_irq_map(struct irq_domain *d, unsigned int irq, > lirq->irq = irq; > uirq = &priv->uirqs[lirq->index]; > if (uirq->refcnt == 0) { > + spin_unlock_irqrestore(&priv->gc.bgpio_lock, flags); > ret = request_irq(uirq->uirq, grgpio_irq_handler, 0, > dev_name(priv->dev), priv); > if (ret) { > dev_err(priv->dev, > "Could not request underlying irq %d\n", > uirq->uirq); > - > - spin_unlock_irqrestore(&priv->gc.bgpio_lock, flags); > - > return ret; > } > + spin_lock_irqsave(&priv->gc.bgpio_lock, flags); > } > uirq->refcnt++; > > @@ -314,8 +313,11 @@ static void grgpio_irq_unmap(struct irq_domain *d, unsigned int irq) > if (index >= 0) { > uirq = &priv->uirqs[lirq->index]; > uirq->refcnt--; > - if (uirq->refcnt == 0) > + if (uirq->refcnt == 0) { > + spin_unlock_irqrestore(&priv->gc.bgpio_lock, flags); > free_irq(uirq->uirq, priv); > + return; > + } > } > > spin_unlock_irqrestore(&priv->gc.bgpio_lock, flags); -- (english) http://www.livejournal.com/~pavelmachek (cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html