Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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

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
Loading
Loading
Loading
Loading
+0 −1
Original line number Diff line number Diff line
@@ -652,7 +652,6 @@ struct drm_nouveau_private {
	/* interrupt handling */
	void (*irq_handler[32])(struct drm_device *);
	bool msi_enabled;
	struct workqueue_struct *wq;
	struct work_struct irq_work;

	struct list_head vbl_waiting;
+1 −9
Original line number Diff line number Diff line
@@ -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",
		 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 1 is linear FB */
	/* resource 2 is RAMIN (mmio regs + 0x1000000) */
@@ -947,7 +941,7 @@ int nouveau_load(struct drm_device *dev, unsigned long flags)
		NV_ERROR(dev, "Unable to initialize the mmio mapping. "
			 "Please report your setup to " DRIVER_EMAIL "\n");
		ret = -EINVAL;
		goto err_wq;
		goto err_priv;
	}
	NV_DEBUG(dev, "regs mapped ok at 0x%llx\n",
					(unsigned long long)mmio_start_offs);
@@ -1054,8 +1048,6 @@ err_ramin:
	iounmap(dev_priv->ramin);
err_mmio:
	iounmap(dev_priv->mmio);
err_wq:
	destroy_workqueue(dev_priv->wq);
err_priv:
	kfree(dev_priv);
	dev->dev_private = NULL;
+4 −1
Original line number Diff line number Diff line
@@ -345,12 +345,15 @@ int nv50_display_create(struct drm_device *dev)
void
nv50_display_destroy(struct drm_device *dev)
{
	struct drm_nouveau_private *dev_priv = dev->dev_private;

	NV_DEBUG_KMS(dev, "\n");

	drm_mode_config_cleanup(dev);

	nv50_display_disable(dev);
	nouveau_irq_unregister(dev, 26);
	flush_work_sync(&dev_priv->irq_work);
}

static u16
@@ -836,7 +839,7 @@ nv50_display_isr(struct drm_device *dev)
		if (clock) {
			nv_wr32(dev, NV03_PMC_INTR_EN_0, 0);
			if (!work_pending(&dev_priv->irq_work))
				queue_work(dev_priv->wq, &dev_priv->irq_work);
				schedule_work(&dev_priv->irq_work);
			delayed |= clock;
			intr1 &= ~clock;
		}
+8 −3
Original line number Diff line number Diff line
@@ -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);
}