diff options
author | Tejun Heo <tj@kernel.org> | 2011-01-26 11:49:18 -0500 |
---|---|---|
committer | Ben Skeggs <bskeggs@redhat.com> | 2011-02-24 15:44:36 -0500 |
commit | d82f8e6c802bb1244ce590d3877f7c66a8fb0ff0 (patch) | |
tree | cb7294e91455667978b9f01d4dcffe151f3bdd7e | |
parent | f17811dfa7f07e3df6d0e3c4ab4af8eb47e8fabc (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.h | 1 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nouveau_state.c | 10 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nv50_display.c | 5 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nv50_gpio.c | 11 |
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); |
1055 | err_mmio: | 1049 | err_mmio: |
1056 | iounmap(dev_priv->mmio); | 1050 | iounmap(dev_priv->mmio); |
1057 | err_wq: | ||
1058 | destroy_workqueue(dev_priv->wq); | ||
1059 | err_priv: | 1051 | err_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) | |||
345 | void | 345 | void |
346 | nv50_display_destroy(struct drm_device *dev) | 346 | nv50_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 | ||
356 | static u16 | 359 | static 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 | ||
158 | bool | 163 | bool |
@@ -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 | } |