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

Commit 1f779cd7 authored by Dave Airlie's avatar Dave Airlie
Browse files

Merge branch 'linux-4.12' of git://github.com/skeggsb/linux into drm-fixes

4 nouveau regression fixes.

* 'linux-4.12' of git://github.com/skeggsb/linux:
  drm/nouveau/tmr: fully separate alarm execution/pending lists
  drm/nouveau: enable autosuspend only when it'll actually be used
  drm/nouveau: replace multiple open-coded runpm support checks with function
  drm/nouveau/kms/nv50: add null check before pointer dereference
parents 3c2993b8 b4e382ca
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -4,6 +4,7 @@

struct nvkm_alarm {
	struct list_head head;
	struct list_head exec;
	u64 timestamp;
	void (*func)(struct nvkm_alarm *);
};
+17 −21
Original line number Diff line number Diff line
@@ -80,7 +80,7 @@ int nouveau_modeset = -1;
module_param_named(modeset, nouveau_modeset, int, 0400);

MODULE_PARM_DESC(runpm, "disable (0), force enable (1), optimus only default (-1)");
int nouveau_runtime_pm = -1;
static int nouveau_runtime_pm = -1;
module_param_named(runpm, nouveau_runtime_pm, int, 0400);

static struct drm_driver driver_stub;
@@ -495,7 +495,7 @@ nouveau_drm_load(struct drm_device *dev, unsigned long flags)
	nouveau_fbcon_init(dev);
	nouveau_led_init(dev);

	if (nouveau_runtime_pm != 0) {
	if (nouveau_pmops_runtime()) {
		pm_runtime_use_autosuspend(dev->dev);
		pm_runtime_set_autosuspend_delay(dev->dev, 5000);
		pm_runtime_set_active(dev->dev);
@@ -527,7 +527,7 @@ nouveau_drm_unload(struct drm_device *dev)
{
	struct nouveau_drm *drm = nouveau_drm(dev);

	if (nouveau_runtime_pm != 0) {
	if (nouveau_pmops_runtime()) {
		pm_runtime_get_sync(dev->dev);
		pm_runtime_forbid(dev->dev);
	}
@@ -726,6 +726,14 @@ nouveau_pmops_thaw(struct device *dev)
	return nouveau_do_resume(drm_dev, false);
}

bool
nouveau_pmops_runtime()
{
	if (nouveau_runtime_pm == -1)
		return nouveau_is_optimus() || nouveau_is_v1_dsm();
	return nouveau_runtime_pm == 1;
}

static int
nouveau_pmops_runtime_suspend(struct device *dev)
{
@@ -733,14 +741,7 @@ nouveau_pmops_runtime_suspend(struct device *dev)
	struct drm_device *drm_dev = pci_get_drvdata(pdev);
	int ret;

	if (nouveau_runtime_pm == 0) {
		pm_runtime_forbid(dev);
		return -EBUSY;
	}

	/* are we optimus enabled? */
	if (nouveau_runtime_pm == -1 && !nouveau_is_optimus() && !nouveau_is_v1_dsm()) {
		DRM_DEBUG_DRIVER("failing to power off - not optimus\n");
	if (!nouveau_pmops_runtime()) {
		pm_runtime_forbid(dev);
		return -EBUSY;
	}
@@ -765,8 +766,10 @@ nouveau_pmops_runtime_resume(struct device *dev)
	struct nvif_device *device = &nouveau_drm(drm_dev)->client.device;
	int ret;

	if (nouveau_runtime_pm == 0)
		return -EINVAL;
	if (!nouveau_pmops_runtime()) {
		pm_runtime_forbid(dev);
		return -EBUSY;
	}

	pci_set_power_state(pdev, PCI_D0);
	pci_restore_state(pdev);
@@ -796,14 +799,7 @@ nouveau_pmops_runtime_idle(struct device *dev)
	struct nouveau_drm *drm = nouveau_drm(drm_dev);
	struct drm_crtc *crtc;

	if (nouveau_runtime_pm == 0) {
		pm_runtime_forbid(dev);
		return -EBUSY;
	}

	/* are we optimus enabled? */
	if (nouveau_runtime_pm == -1 && !nouveau_is_optimus() && !nouveau_is_v1_dsm()) {
		DRM_DEBUG_DRIVER("failing to power off - not optimus\n");
	if (!nouveau_pmops_runtime()) {
		pm_runtime_forbid(dev);
		return -EBUSY;
	}
+1 −2
Original line number Diff line number Diff line
@@ -108,8 +108,6 @@ nouveau_cli(struct drm_file *fpriv)
#include <nvif/object.h>
#include <nvif/device.h>

extern int nouveau_runtime_pm;

struct nouveau_drm {
	struct nouveau_cli client;
	struct drm_device *dev;
@@ -195,6 +193,7 @@ nouveau_drm(struct drm_device *dev)

int nouveau_pmops_suspend(struct device *);
int nouveau_pmops_resume(struct device *);
bool nouveau_pmops_runtime(void);

#include <nvkm/core/tegra.h>

+2 −11
Original line number Diff line number Diff line
@@ -87,7 +87,7 @@ void
nouveau_vga_init(struct nouveau_drm *drm)
{
	struct drm_device *dev = drm->dev;
	bool runtime = false;
	bool runtime = nouveau_pmops_runtime();

	/* only relevant for PCI devices */
	if (!dev->pdev)
@@ -99,10 +99,6 @@ nouveau_vga_init(struct nouveau_drm *drm)
	if (pci_is_thunderbolt_attached(dev->pdev))
		return;

	if (nouveau_runtime_pm == 1)
		runtime = true;
	if ((nouveau_runtime_pm == -1) && (nouveau_is_optimus() || nouveau_is_v1_dsm()))
		runtime = true;
	vga_switcheroo_register_client(dev->pdev, &nouveau_switcheroo_ops, runtime);

	if (runtime && nouveau_is_v1_dsm() && !nouveau_is_optimus())
@@ -113,18 +109,13 @@ void
nouveau_vga_fini(struct nouveau_drm *drm)
{
	struct drm_device *dev = drm->dev;
	bool runtime = false;
	bool runtime = nouveau_pmops_runtime();

	vga_client_register(dev->pdev, NULL, NULL, NULL);

	if (pci_is_thunderbolt_attached(dev->pdev))
		return;

	if (nouveau_runtime_pm == 1)
		runtime = true;
	if ((nouveau_runtime_pm == -1) && (nouveau_is_optimus() || nouveau_is_v1_dsm()))
		runtime = true;

	vga_switcheroo_unregister_client(dev->pdev);
	if (runtime && nouveau_is_v1_dsm() && !nouveau_is_optimus())
		vga_switcheroo_fini_domain_pm_ops(drm->dev->dev);
+2 −1
Original line number Diff line number Diff line
@@ -2107,6 +2107,7 @@ nv50_head_atomic_check(struct drm_crtc *crtc, struct drm_crtc_state *state)
					asyc->set.dither = true;
			}
		} else {
			if (asyc)
				asyc->set.mask = ~0;
			asyh->set.mask = ~0;
		}
Loading