aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTejun Heo <tj@kernel.org>2011-01-26 11:49:18 -0500
committerBen Skeggs <bskeggs@redhat.com>2011-02-24 15:44:36 -0500
commitd82f8e6c802bb1244ce590d3877f7c66a8fb0ff0 (patch)
treecb7294e91455667978b9f01d4dcffe151f3bdd7e
parentf17811dfa7f07e3df6d0e3c4ab4af8eb47e8fabc (diff)
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: Tejun Heo <tj@kernel.org> Cc: David Airlie <airlied@linux.ie> Cc: dri-devel@lists.freedesktop.org Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_drv.h1
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_state.c10
-rw-r--r--drivers/gpu/drm/nouveau/nv50_display.c5
-rw-r--r--drivers/gpu/drm/nouveau/nv50_gpio.c11
4 files changed, 13 insertions, 14 deletions
diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h b/drivers/gpu/drm/nouveau/nouveau_drv.h
index 1c6279f588ba..2e3d7fb4912a 100644
--- a/drivers/gpu/drm/nouveau/nouveau_drv.h
+++ b/drivers/gpu/drm/nouveau/nouveau_drv.h
@@ -652,7 +652,6 @@ struct drm_nouveau_private {
652 /* interrupt handling */ 652 /* interrupt handling */
653 void (*irq_handler[32])(struct drm_device *); 653 void (*irq_handler[32])(struct drm_device *);
654 bool msi_enabled; 654 bool msi_enabled;
655 struct workqueue_struct *wq;
656 struct work_struct irq_work; 655 struct work_struct irq_work;
657 656
658 struct list_head vbl_waiting; 657 struct list_head vbl_waiting;
diff --git a/drivers/gpu/drm/nouveau/nouveau_state.c b/drivers/gpu/drm/nouveau/nouveau_state.c
index 2148d01354da..805c0b3fcdb7 100644
--- a/drivers/gpu/drm/nouveau/nouveau_state.c
+++ b/drivers/gpu/drm/nouveau/nouveau_state.c
@@ -929,12 +929,6 @@ int nouveau_load(struct drm_device *dev, unsigned long flags)
929 NV_DEBUG(dev, "vendor: 0x%X device: 0x%X class: 0x%X\n", 929 NV_DEBUG(dev, "vendor: 0x%X device: 0x%X class: 0x%X\n",
930 dev->pci_vendor, dev->pci_device, dev->pdev->class); 930 dev->pci_vendor, dev->pci_device, dev->pdev->class);
931 931
932 dev_priv->wq = create_workqueue("nouveau");
933 if (!dev_priv->wq) {
934 ret = -EINVAL;
935 goto err_priv;
936 }
937
938 /* resource 0 is mmio regs */ 932 /* resource 0 is mmio regs */
939 /* resource 1 is linear FB */ 933 /* resource 1 is linear FB */
940 /* resource 2 is RAMIN (mmio regs + 0x1000000) */ 934 /* resource 2 is RAMIN (mmio regs + 0x1000000) */
@@ -947,7 +941,7 @@ int nouveau_load(struct drm_device *dev, unsigned long flags)
947 NV_ERROR(dev, "Unable to initialize the mmio mapping. " 941 NV_ERROR(dev, "Unable to initialize the mmio mapping. "
948 "Please report your setup to " DRIVER_EMAIL "\n"); 942 "Please report your setup to " DRIVER_EMAIL "\n");
949 ret = -EINVAL; 943 ret = -EINVAL;
950 goto err_wq; 944 goto err_priv;
951 } 945 }
952 NV_DEBUG(dev, "regs mapped ok at 0x%llx\n", 946 NV_DEBUG(dev, "regs mapped ok at 0x%llx\n",
953 (unsigned long long)mmio_start_offs); 947 (unsigned long long)mmio_start_offs);
@@ -1054,8 +1048,6 @@ err_ramin:
1054 iounmap(dev_priv->ramin); 1048 iounmap(dev_priv->ramin);
1055err_mmio: 1049err_mmio:
1056 iounmap(dev_priv->mmio); 1050 iounmap(dev_priv->mmio);
1057err_wq:
1058 destroy_workqueue(dev_priv->wq);
1059err_priv: 1051err_priv:
1060 kfree(dev_priv); 1052 kfree(dev_priv);
1061 dev->dev_private = NULL; 1053 dev->dev_private = NULL;
diff --git a/drivers/gpu/drm/nouveau/nv50_display.c b/drivers/gpu/drm/nouveau/nv50_display.c
index 5096f2f45df8..a804a350800e 100644
--- a/drivers/gpu/drm/nouveau/nv50_display.c
+++ b/drivers/gpu/drm/nouveau/nv50_display.c
@@ -345,12 +345,15 @@ int nv50_display_create(struct drm_device *dev)
345void 345void
346nv50_display_destroy(struct drm_device *dev) 346nv50_display_destroy(struct drm_device *dev)
347{ 347{
348 struct drm_nouveau_private *dev_priv = dev->dev_private;
349
348 NV_DEBUG_KMS(dev, "\n"); 350 NV_DEBUG_KMS(dev, "\n");
349 351
350 drm_mode_config_cleanup(dev); 352 drm_mode_config_cleanup(dev);
351 353
352 nv50_display_disable(dev); 354 nv50_display_disable(dev);
353 nouveau_irq_unregister(dev, 26); 355 nouveau_irq_unregister(dev, 26);
356 flush_work_sync(&dev_priv->irq_work);
354} 357}
355 358
356static u16 359static u16
@@ -836,7 +839,7 @@ nv50_display_isr(struct drm_device *dev)
836 if (clock) { 839 if (clock) {
837 nv_wr32(dev, NV03_PMC_INTR_EN_0, 0); 840 nv_wr32(dev, NV03_PMC_INTR_EN_0, 0);
838 if (!work_pending(&dev_priv->irq_work)) 841 if (!work_pending(&dev_priv->irq_work))
839 queue_work(dev_priv->wq, &dev_priv->irq_work); 842 schedule_work(&dev_priv->irq_work);
840 delayed |= clock; 843 delayed |= clock;
841 intr1 &= ~clock; 844 intr1 &= ~clock;
842 } 845 }
diff --git a/drivers/gpu/drm/nouveau/nv50_gpio.c b/drivers/gpu/drm/nouveau/nv50_gpio.c
index 1710c080272f..d4f4206dad7e 100644
--- a/drivers/gpu/drm/nouveau/nv50_gpio.c
+++ b/drivers/gpu/drm/nouveau/nv50_gpio.c
@@ -137,6 +137,7 @@ nv50_gpio_irq_unregister(struct drm_device *dev, enum dcb_gpio_tag tag,
137 struct nv50_gpio_priv *priv = pgpio->priv; 137 struct nv50_gpio_priv *priv = pgpio->priv;
138 struct nv50_gpio_handler *gpioh, *tmp; 138 struct nv50_gpio_handler *gpioh, *tmp;
139 struct dcb_gpio_entry *gpio; 139 struct dcb_gpio_entry *gpio;
140 LIST_HEAD(tofree);
140 unsigned long flags; 141 unsigned long flags;
141 142
142 gpio = nouveau_bios_gpio_entry(dev, tag); 143 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 gpioh->handler != handler || 150 gpioh->handler != handler ||
150 gpioh->data != data) 151 gpioh->data != data)
151 continue; 152 continue;
152 list_del(&gpioh->head); 153 list_move(&gpioh->head, &tofree);
153 kfree(gpioh);
154 } 154 }
155 spin_unlock_irqrestore(&priv->lock, flags); 155 spin_unlock_irqrestore(&priv->lock, flags);
156
157 list_for_each_entry_safe(gpioh, tmp, &tofree, head) {
158 flush_work_sync(&gpioh->work);
159 kfree(gpioh);
160 }
156} 161}
157 162
158bool 163bool
@@ -291,7 +296,7 @@ nv50_gpio_isr(struct drm_device *dev)
291 continue; 296 continue;
292 gpioh->inhibit = true; 297 gpioh->inhibit = true;
293 298
294 queue_work(dev_priv->wq, &gpioh->work); 299 schedule_work(&gpioh->work);
295 } 300 }
296 spin_unlock(&priv->lock); 301 spin_unlock(&priv->lock);
297} 302}