diff options
Diffstat (limited to 'drivers/gpu/drm/nouveau/nouveau_state.c')
-rw-r--r-- | drivers/gpu/drm/nouveau/nouveau_state.c | 40 |
1 files changed, 28 insertions, 12 deletions
diff --git a/drivers/gpu/drm/nouveau/nouveau_state.c b/drivers/gpu/drm/nouveau/nouveau_state.c index a4851af5b05..eb8f084d5f5 100644 --- a/drivers/gpu/drm/nouveau/nouveau_state.c +++ b/drivers/gpu/drm/nouveau/nouveau_state.c | |||
@@ -29,6 +29,7 @@ | |||
29 | #include "drm_sarea.h" | 29 | #include "drm_sarea.h" |
30 | #include "drm_crtc_helper.h" | 30 | #include "drm_crtc_helper.h" |
31 | #include <linux/vgaarb.h> | 31 | #include <linux/vgaarb.h> |
32 | #include <linux/vga_switcheroo.h> | ||
32 | 33 | ||
33 | #include "nouveau_drv.h" | 34 | #include "nouveau_drv.h" |
34 | #include "nouveau_drm.h" | 35 | #include "nouveau_drm.h" |
@@ -371,6 +372,30 @@ out_err: | |||
371 | return ret; | 372 | return ret; |
372 | } | 373 | } |
373 | 374 | ||
375 | static void nouveau_switcheroo_set_state(struct pci_dev *pdev, | ||
376 | enum vga_switcheroo_state state) | ||
377 | { | ||
378 | pm_message_t pmm = { .event = PM_EVENT_SUSPEND }; | ||
379 | if (state == VGA_SWITCHEROO_ON) { | ||
380 | printk(KERN_ERR "VGA switcheroo: switched nouveau on\n"); | ||
381 | nouveau_pci_resume(pdev); | ||
382 | } else { | ||
383 | printk(KERN_ERR "VGA switcheroo: switched nouveau off\n"); | ||
384 | nouveau_pci_suspend(pdev, pmm); | ||
385 | } | ||
386 | } | ||
387 | |||
388 | static bool nouveau_switcheroo_can_switch(struct pci_dev *pdev) | ||
389 | { | ||
390 | struct drm_device *dev = pci_get_drvdata(pdev); | ||
391 | bool can_switch; | ||
392 | |||
393 | spin_lock(&dev->count_lock); | ||
394 | can_switch = (dev->open_count == 0); | ||
395 | spin_unlock(&dev->count_lock); | ||
396 | return can_switch; | ||
397 | } | ||
398 | |||
374 | int | 399 | int |
375 | nouveau_card_init(struct drm_device *dev) | 400 | nouveau_card_init(struct drm_device *dev) |
376 | { | 401 | { |
@@ -384,6 +409,8 @@ nouveau_card_init(struct drm_device *dev) | |||
384 | return 0; | 409 | return 0; |
385 | 410 | ||
386 | vga_client_register(dev->pdev, dev, NULL, nouveau_vga_set_decode); | 411 | vga_client_register(dev->pdev, dev, NULL, nouveau_vga_set_decode); |
412 | vga_switcheroo_register_client(dev->pdev, nouveau_switcheroo_set_state, | ||
413 | nouveau_switcheroo_can_switch); | ||
387 | 414 | ||
388 | /* Initialise internal driver API hooks */ | 415 | /* Initialise internal driver API hooks */ |
389 | ret = nouveau_init_engine_ptrs(dev); | 416 | ret = nouveau_init_engine_ptrs(dev); |
@@ -391,6 +418,7 @@ nouveau_card_init(struct drm_device *dev) | |||
391 | goto out; | 418 | goto out; |
392 | engine = &dev_priv->engine; | 419 | engine = &dev_priv->engine; |
393 | dev_priv->init_state = NOUVEAU_CARD_INIT_FAILED; | 420 | dev_priv->init_state = NOUVEAU_CARD_INIT_FAILED; |
421 | spin_lock_init(&dev_priv->context_switch_lock); | ||
394 | 422 | ||
395 | /* Parse BIOS tables / Run init tables if card not POSTed */ | 423 | /* Parse BIOS tables / Run init tables if card not POSTed */ |
396 | if (drm_core_check_feature(dev, DRIVER_MODESET)) { | 424 | if (drm_core_check_feature(dev, DRIVER_MODESET)) { |
@@ -617,11 +645,6 @@ int nouveau_load(struct drm_device *dev, unsigned long flags) | |||
617 | NV_DEBUG(dev, "vendor: 0x%X device: 0x%X class: 0x%X\n", | 645 | NV_DEBUG(dev, "vendor: 0x%X device: 0x%X class: 0x%X\n", |
618 | dev->pci_vendor, dev->pci_device, dev->pdev->class); | 646 | dev->pci_vendor, dev->pci_device, dev->pdev->class); |
619 | 647 | ||
620 | dev_priv->acpi_dsm = nouveau_dsm_probe(dev); | ||
621 | |||
622 | if (dev_priv->acpi_dsm) | ||
623 | nouveau_hybrid_setup(dev); | ||
624 | |||
625 | dev_priv->wq = create_workqueue("nouveau"); | 648 | dev_priv->wq = create_workqueue("nouveau"); |
626 | if (!dev_priv->wq) | 649 | if (!dev_priv->wq) |
627 | return -EINVAL; | 650 | return -EINVAL; |
@@ -776,13 +799,6 @@ int nouveau_unload(struct drm_device *dev) | |||
776 | return 0; | 799 | return 0; |
777 | } | 800 | } |
778 | 801 | ||
779 | int | ||
780 | nouveau_ioctl_card_init(struct drm_device *dev, void *data, | ||
781 | struct drm_file *file_priv) | ||
782 | { | ||
783 | return nouveau_card_init(dev); | ||
784 | } | ||
785 | |||
786 | int nouveau_ioctl_getparam(struct drm_device *dev, void *data, | 802 | int nouveau_ioctl_getparam(struct drm_device *dev, void *data, |
787 | struct drm_file *file_priv) | 803 | struct drm_file *file_priv) |
788 | { | 804 | { |