|
@@ -137,6 +137,7 @@ nv50_gpio_irq_unregister(struct drm_device *dev, enum dcb_gpio_tag tag,
|
|
|
struct nv50_gpio_priv *priv = pgpio->priv;
|
|
|
struct nv50_gpio_handler *gpioh, *tmp;
|
|
|
struct dcb_gpio_entry *gpio;
|
|
|
+ LIST_HEAD(tofree);
|
|
|
unsigned long flags;
|
|
|
|
|
|
gpio = nouveau_bios_gpio_entry(dev, tag);
|
|
@@ -149,10 +150,14 @@ nv50_gpio_irq_unregister(struct drm_device *dev, enum dcb_gpio_tag tag,
|
|
|
gpioh->handler != handler ||
|
|
|
gpioh->data != data)
|
|
|
continue;
|
|
|
- list_del(&gpioh->head);
|
|
|
- kfree(gpioh);
|
|
|
+ list_move(&gpioh->head, &tofree);
|
|
|
}
|
|
|
spin_unlock_irqrestore(&priv->lock, flags);
|
|
|
+
|
|
|
+ list_for_each_entry_safe(gpioh, tmp, &tofree, head) {
|
|
|
+ flush_work_sync(&gpioh->work);
|
|
|
+ kfree(gpioh);
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
bool
|
|
@@ -291,7 +296,7 @@ nv50_gpio_isr(struct drm_device *dev)
|
|
|
continue;
|
|
|
gpioh->inhibit = true;
|
|
|
|
|
|
- queue_work(dev_priv->wq, &gpioh->work);
|
|
|
+ schedule_work(&gpioh->work);
|
|
|
}
|
|
|
spin_unlock(&priv->lock);
|
|
|
}
|