Commit d82f8e6c authored by Tejun Heo's avatar Tejun Heo Committed by Ben Skeggs

drm/nouveau: use system_wq instead of dev_priv->wq

With cmwq, there's no reason for nouveau to use a dedicated workqueue.
Drop dev_priv->wq and use system_wq instead.  Each work item is sync
flushed when the containing structure is unregistered/destroyed.

Note that this change also makes sure that nv50_gpio_handler is not
freed while the contained work item is still running.
Signed-off-by: default avatarTejun Heo <tj@kernel.org>
Cc: David Airlie <airlied@linux.ie>
Cc: dri-devel@lists.freedesktop.org
Signed-off-by: default avatarBen Skeggs <bskeggs@redhat.com>
parent f17811df
...@@ -652,7 +652,6 @@ struct drm_nouveau_private { ...@@ -652,7 +652,6 @@ struct drm_nouveau_private {
/* interrupt handling */ /* interrupt handling */
void (*irq_handler[32])(struct drm_device *); void (*irq_handler[32])(struct drm_device *);
bool msi_enabled; bool msi_enabled;
struct workqueue_struct *wq;
struct work_struct irq_work; struct work_struct irq_work;
struct list_head vbl_waiting; struct list_head vbl_waiting;
......
...@@ -929,12 +929,6 @@ int nouveau_load(struct drm_device *dev, unsigned long flags) ...@@ -929,12 +929,6 @@ int nouveau_load(struct drm_device *dev, unsigned long flags)
NV_DEBUG(dev, "vendor: 0x%X device: 0x%X class: 0x%X\n", NV_DEBUG(dev, "vendor: 0x%X device: 0x%X class: 0x%X\n",
dev->pci_vendor, dev->pci_device, dev->pdev->class); dev->pci_vendor, dev->pci_device, dev->pdev->class);
dev_priv->wq = create_workqueue("nouveau");
if (!dev_priv->wq) {
ret = -EINVAL;
goto err_priv;
}
/* resource 0 is mmio regs */ /* resource 0 is mmio regs */
/* resource 1 is linear FB */ /* resource 1 is linear FB */
/* resource 2 is RAMIN (mmio regs + 0x1000000) */ /* resource 2 is RAMIN (mmio regs + 0x1000000) */
...@@ -947,7 +941,7 @@ int nouveau_load(struct drm_device *dev, unsigned long flags) ...@@ -947,7 +941,7 @@ int nouveau_load(struct drm_device *dev, unsigned long flags)
NV_ERROR(dev, "Unable to initialize the mmio mapping. " NV_ERROR(dev, "Unable to initialize the mmio mapping. "
"Please report your setup to " DRIVER_EMAIL "\n"); "Please report your setup to " DRIVER_EMAIL "\n");
ret = -EINVAL; ret = -EINVAL;
goto err_wq; goto err_priv;
} }
NV_DEBUG(dev, "regs mapped ok at 0x%llx\n", NV_DEBUG(dev, "regs mapped ok at 0x%llx\n",
(unsigned long long)mmio_start_offs); (unsigned long long)mmio_start_offs);
...@@ -1054,8 +1048,6 @@ int nouveau_load(struct drm_device *dev, unsigned long flags) ...@@ -1054,8 +1048,6 @@ int nouveau_load(struct drm_device *dev, unsigned long flags)
iounmap(dev_priv->ramin); iounmap(dev_priv->ramin);
err_mmio: err_mmio:
iounmap(dev_priv->mmio); iounmap(dev_priv->mmio);
err_wq:
destroy_workqueue(dev_priv->wq);
err_priv: err_priv:
kfree(dev_priv); kfree(dev_priv);
dev->dev_private = NULL; dev->dev_private = NULL;
......
...@@ -345,12 +345,15 @@ int nv50_display_create(struct drm_device *dev) ...@@ -345,12 +345,15 @@ int nv50_display_create(struct drm_device *dev)
void void
nv50_display_destroy(struct drm_device *dev) nv50_display_destroy(struct drm_device *dev)
{ {
struct drm_nouveau_private *dev_priv = dev->dev_private;
NV_DEBUG_KMS(dev, "\n"); NV_DEBUG_KMS(dev, "\n");
drm_mode_config_cleanup(dev); drm_mode_config_cleanup(dev);
nv50_display_disable(dev); nv50_display_disable(dev);
nouveau_irq_unregister(dev, 26); nouveau_irq_unregister(dev, 26);
flush_work_sync(&dev_priv->irq_work);
} }
static u16 static u16
...@@ -836,7 +839,7 @@ nv50_display_isr(struct drm_device *dev) ...@@ -836,7 +839,7 @@ nv50_display_isr(struct drm_device *dev)
if (clock) { if (clock) {
nv_wr32(dev, NV03_PMC_INTR_EN_0, 0); nv_wr32(dev, NV03_PMC_INTR_EN_0, 0);
if (!work_pending(&dev_priv->irq_work)) if (!work_pending(&dev_priv->irq_work))
queue_work(dev_priv->wq, &dev_priv->irq_work); schedule_work(&dev_priv->irq_work);
delayed |= clock; delayed |= clock;
intr1 &= ~clock; intr1 &= ~clock;
} }
......
...@@ -137,6 +137,7 @@ nv50_gpio_irq_unregister(struct drm_device *dev, enum dcb_gpio_tag tag, ...@@ -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_priv *priv = pgpio->priv;
struct nv50_gpio_handler *gpioh, *tmp; struct nv50_gpio_handler *gpioh, *tmp;
struct dcb_gpio_entry *gpio; struct dcb_gpio_entry *gpio;
LIST_HEAD(tofree);
unsigned long flags; unsigned long flags;
gpio = nouveau_bios_gpio_entry(dev, tag); gpio = nouveau_bios_gpio_entry(dev, tag);
...@@ -149,10 +150,14 @@ nv50_gpio_irq_unregister(struct drm_device *dev, enum dcb_gpio_tag tag, ...@@ -149,10 +150,14 @@ nv50_gpio_irq_unregister(struct drm_device *dev, enum dcb_gpio_tag tag,
gpioh->handler != handler || gpioh->handler != handler ||
gpioh->data != data) gpioh->data != data)
continue; continue;
list_del(&gpioh->head); list_move(&gpioh->head, &tofree);
kfree(gpioh);
} }
spin_unlock_irqrestore(&priv->lock, flags); spin_unlock_irqrestore(&priv->lock, flags);
list_for_each_entry_safe(gpioh, tmp, &tofree, head) {
flush_work_sync(&gpioh->work);
kfree(gpioh);
}
} }
bool bool
...@@ -291,7 +296,7 @@ nv50_gpio_isr(struct drm_device *dev) ...@@ -291,7 +296,7 @@ nv50_gpio_isr(struct drm_device *dev)
continue; continue;
gpioh->inhibit = true; gpioh->inhibit = true;
queue_work(dev_priv->wq, &gpioh->work); schedule_work(&gpioh->work);
} }
spin_unlock(&priv->lock); spin_unlock(&priv->lock);
} }
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment