diff options
28 files changed, 381 insertions, 91 deletions
diff --git a/drivers/gpu/drm/nouveau/Makefile b/drivers/gpu/drm/nouveau/Makefile index ccd0b38b3c3f..63c8cca71894 100644 --- a/drivers/gpu/drm/nouveau/Makefile +++ b/drivers/gpu/drm/nouveau/Makefile @@ -80,7 +80,8 @@ nouveau-y += core/engine/mpeg/nv50.o nouveau-y += core/engine/ppp/nv98.o nouveau-y += core/engine/vp/nv84.o -nouveau-y += nouveau_drv.o nouveau_state.o nouveau_channel.o nouveau_mem.o \ +nouveau-y += nouveau_drm.o \ + nouveau_drv.o nouveau_state.o nouveau_channel.o nouveau_mem.o \ nouveau_gpuobj.o nouveau_irq.o nouveau_notifier.o \ nouveau_sgdma.o nouveau_dma.o nouveau_util.o \ nouveau_bo.o nouveau_fence.o nouveau_gem.o nouveau_ttm.o \ diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/nv04.c b/drivers/gpu/drm/nouveau/core/engine/graph/nv04.c index 353d4d330cab..7f3a275157bb 100644 --- a/drivers/gpu/drm/nouveau/core/engine/graph/nv04.c +++ b/drivers/gpu/drm/nouveau/core/engine/graph/nv04.c @@ -24,7 +24,7 @@ #include "drmP.h" #include "drm.h" -#include "nouveau_drm.h" +#include <nouveau_drm.h> #include "nouveau_drv.h" #include "nouveau_hw.h" #include "nouveau_util.h" diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/nv10.c b/drivers/gpu/drm/nouveau/core/engine/graph/nv10.c index fb1d88a951de..19e303b423af 100644 --- a/drivers/gpu/drm/nouveau/core/engine/graph/nv10.c +++ b/drivers/gpu/drm/nouveau/core/engine/graph/nv10.c @@ -24,7 +24,7 @@ #include "drmP.h" #include "drm.h" -#include "nouveau_drm.h" +#include <nouveau_drm.h> #include "nouveau_drv.h" #include "nouveau_util.h" diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/nv20.c b/drivers/gpu/drm/nouveau/core/engine/graph/nv20.c index e34ea30758f6..718ecf761823 100644 --- a/drivers/gpu/drm/nouveau/core/engine/graph/nv20.c +++ b/drivers/gpu/drm/nouveau/core/engine/graph/nv20.c @@ -1,7 +1,7 @@ #include "drmP.h" #include "drm.h" #include "nouveau_drv.h" -#include "nouveau_drm.h" +#include <nouveau_drm.h> /* * NV20 diff --git a/drivers/gpu/drm/nouveau/core/subdev/fb/nv04.c b/drivers/gpu/drm/nouveau/core/subdev/fb/nv04.c index d5eedd67afe5..eef48440fbec 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/fb/nv04.c +++ b/drivers/gpu/drm/nouveau/core/subdev/fb/nv04.c @@ -1,7 +1,7 @@ #include "drmP.h" #include "drm.h" #include "nouveau_drv.h" -#include "nouveau_drm.h" +#include <nouveau_drm.h> int nv04_fb_vram_init(struct drm_device *dev) diff --git a/drivers/gpu/drm/nouveau/core/subdev/fb/nv10.c b/drivers/gpu/drm/nouveau/core/subdev/fb/nv10.c index 420b1608536d..09af63b55f59 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/fb/nv10.c +++ b/drivers/gpu/drm/nouveau/core/subdev/fb/nv10.c @@ -1,7 +1,7 @@ #include "drmP.h" #include "drm.h" #include "nouveau_drv.h" -#include "nouveau_drm.h" +#include <nouveau_drm.h> void nv10_fb_init_tile_region(struct drm_device *dev, int i, uint32_t addr, diff --git a/drivers/gpu/drm/nouveau/core/subdev/fb/nv20.c b/drivers/gpu/drm/nouveau/core/subdev/fb/nv20.c index 19bd64059a66..a7f056c367e4 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/fb/nv20.c +++ b/drivers/gpu/drm/nouveau/core/subdev/fb/nv20.c @@ -1,7 +1,7 @@ #include "drmP.h" #include "drm.h" #include "nouveau_drv.h" -#include "nouveau_drm.h" +#include <nouveau_drm.h> static struct drm_mm_node * nv20_fb_alloc_tag(struct drm_device *dev, uint32_t size) diff --git a/drivers/gpu/drm/nouveau/core/subdev/fb/nv30.c b/drivers/gpu/drm/nouveau/core/subdev/fb/nv30.c index e0135f0e2144..30639a065273 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/fb/nv30.c +++ b/drivers/gpu/drm/nouveau/core/subdev/fb/nv30.c @@ -27,7 +27,7 @@ #include "drmP.h" #include "drm.h" #include "nouveau_drv.h" -#include "nouveau_drm.h" +#include <nouveau_drm.h> void nv30_fb_init_tile_region(struct drm_device *dev, int i, uint32_t addr, diff --git a/drivers/gpu/drm/nouveau/core/subdev/fb/nv40.c b/drivers/gpu/drm/nouveau/core/subdev/fb/nv40.c index 7fbcb334c096..e08c2e1c8f1f 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/fb/nv40.c +++ b/drivers/gpu/drm/nouveau/core/subdev/fb/nv40.c @@ -1,7 +1,7 @@ #include "drmP.h" #include "drm.h" #include "nouveau_drv.h" -#include "nouveau_drm.h" +#include <nouveau_drm.h> void nv40_fb_set_tile_region(struct drm_device *dev, int i) diff --git a/drivers/gpu/drm/nouveau/core/subdev/fb/nv50.c b/drivers/gpu/drm/nouveau/core/subdev/fb/nv50.c index 3488358401a8..a145b1c81ecb 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/fb/nv50.c +++ b/drivers/gpu/drm/nouveau/core/subdev/fb/nv50.c @@ -1,7 +1,7 @@ #include "drmP.h" #include "drm.h" #include "nouveau_drv.h" -#include "nouveau_drm.h" +#include <nouveau_drm.h> #include <engine/fifo.h> struct nv50_fb_priv { diff --git a/drivers/gpu/drm/nouveau/core/subdev/fb/nvc0.c b/drivers/gpu/drm/nouveau/core/subdev/fb/nvc0.c index f376c39310df..f054331e37d8 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/fb/nvc0.c +++ b/drivers/gpu/drm/nouveau/core/subdev/fb/nvc0.c @@ -25,7 +25,7 @@ #include "drmP.h" #include "drm.h" #include "nouveau_drv.h" -#include "nouveau_drm.h" +#include <nouveau_drm.h> struct nvc0_fb_priv { struct page *r100c10_page; diff --git a/drivers/gpu/drm/nouveau/core/subdev/mc/nv04.c b/drivers/gpu/drm/nouveau/core/subdev/mc/nv04.c index 2af43a1cb2ec..60b146e4c53d 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/mc/nv04.c +++ b/drivers/gpu/drm/nouveau/core/subdev/mc/nv04.c @@ -1,7 +1,7 @@ #include "drmP.h" #include "drm.h" #include "nouveau_drv.h" -#include "nouveau_drm.h" +#include <nouveau_drm.h> int nv04_mc_init(struct drm_device *dev) diff --git a/drivers/gpu/drm/nouveau/core/subdev/mc/nv40.c b/drivers/gpu/drm/nouveau/core/subdev/mc/nv40.c index 03c0d4c3f355..74cfa03eddff 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/mc/nv40.c +++ b/drivers/gpu/drm/nouveau/core/subdev/mc/nv40.c @@ -1,7 +1,7 @@ #include "drmP.h" #include "drm.h" #include "nouveau_drv.h" -#include "nouveau_drm.h" +#include <nouveau_drm.h> int nv40_mc_init(struct drm_device *dev) diff --git a/drivers/gpu/drm/nouveau/core/subdev/timer/nv04.c b/drivers/gpu/drm/nouveau/core/subdev/timer/nv04.c index 55c945290e52..63333dc9ece0 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/timer/nv04.c +++ b/drivers/gpu/drm/nouveau/core/subdev/timer/nv04.c @@ -1,7 +1,7 @@ #include "drmP.h" #include "drm.h" #include "nouveau_drv.h" -#include "nouveau_drm.h" +#include <nouveau_drm.h> #include "nouveau_hw.h" int diff --git a/drivers/gpu/drm/nouveau/nouveau_acpi.c b/drivers/gpu/drm/nouveau/nouveau_acpi.c index 26ebffebe710..778cd149f7cd 100644 --- a/drivers/gpu/drm/nouveau/nouveau_acpi.c +++ b/drivers/gpu/drm/nouveau/nouveau_acpi.c @@ -12,7 +12,7 @@ #include "drm_sarea.h" #include "drm_crtc_helper.h" #include "nouveau_drv.h" -#include "nouveau_drm.h" +#include <nouveau_drm.h> #include "nv50_display.h" #include "nouveau_connector.h" diff --git a/drivers/gpu/drm/nouveau/nouveau_backlight.c b/drivers/gpu/drm/nouveau/nouveau_backlight.c index fa22b28e8777..7266902a74ed 100644 --- a/drivers/gpu/drm/nouveau/nouveau_backlight.c +++ b/drivers/gpu/drm/nouveau/nouveau_backlight.c @@ -35,7 +35,7 @@ #include "drmP.h" #include "nouveau_drv.h" -#include "nouveau_drm.h" +#include <nouveau_drm.h> #include "nouveau_reg.h" #include "nouveau_encoder.h" diff --git a/drivers/gpu/drm/nouveau/nouveau_bo.c b/drivers/gpu/drm/nouveau/nouveau_bo.c index f9e6fbb0094f..d95275437a4b 100644 --- a/drivers/gpu/drm/nouveau/nouveau_bo.c +++ b/drivers/gpu/drm/nouveau/nouveau_bo.c @@ -30,7 +30,7 @@ #include "drmP.h" #include "ttm/ttm_page_alloc.h" -#include "nouveau_drm.h" +#include <nouveau_drm.h> #include "nouveau_drv.h" #include "nouveau_dma.h" #include <core/mm.h> diff --git a/drivers/gpu/drm/nouveau/nouveau_channel.c b/drivers/gpu/drm/nouveau/nouveau_channel.c index 182fbd398f91..1dd5232a6d75 100644 --- a/drivers/gpu/drm/nouveau/nouveau_channel.c +++ b/drivers/gpu/drm/nouveau/nouveau_channel.c @@ -25,7 +25,7 @@ #include "drmP.h" #include "drm.h" #include "nouveau_drv.h" -#include "nouveau_drm.h" +#include <nouveau_drm.h> #include "nouveau_dma.h" #include <engine/fifo.h> #include <core/ramht.h> diff --git a/drivers/gpu/drm/nouveau/nouveau_drm.c b/drivers/gpu/drm/nouveau/nouveau_drm.c new file mode 100644 index 000000000000..c72d42636c89 --- /dev/null +++ b/drivers/gpu/drm/nouveau/nouveau_drm.c @@ -0,0 +1,285 @@ +/* + * Copyright 2012 Red Hat Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Authors: Ben Skeggs + */ + +#include <linux/module.h> +#include <linux/pci.h> + +#include <core/device.h> +#include <core/client.h> +#include <core/class.h> + +#include <subdev/device.h> + +#include "nouveau_drm.h" + +int __devinit nouveau_pci_probe(struct pci_dev *, const struct pci_device_id *); +void nouveau_pci_remove(struct pci_dev *); +int nouveau_pci_suspend(struct pci_dev *, pm_message_t); +int nouveau_pci_resume(struct pci_dev *); +int __init nouveau_init(struct pci_driver *); +void __exit nouveau_exit(struct pci_driver *); + +int nouveau_load(struct drm_device *, unsigned long); +int nouveau_unload(struct drm_device *); +void *nouveau_newpriv(struct drm_device *); + +MODULE_PARM_DESC(config, "option string to pass to driver core"); +static char *nouveau_config; +module_param_named(config, nouveau_config, charp, 0400); + +MODULE_PARM_DESC(debug, "debug string to pass to driver core"); +static char *nouveau_debug; +module_param_named(debug, nouveau_debug, charp, 0400); + +static u64 +nouveau_name(struct pci_dev *pdev) +{ + u64 name = (u64)pci_domain_nr(pdev->bus) << 32; + name |= pdev->bus->number << 16; + name |= PCI_SLOT(pdev->devfn) << 8; + return name | PCI_FUNC(pdev->devfn); +} + +static int +nouveau_cli_create(struct pci_dev *pdev, u32 name, int size, void **pcli) +{ + struct nouveau_cli *cli; + int ret; + + ret = nouveau_client_create_(name, nouveau_name(pdev), nouveau_config, + nouveau_debug, size, pcli); + cli = *pcli; + if (ret) + return ret; + + mutex_init(&cli->mutex); + return 0; +} + +static void +nouveau_cli_destroy(struct nouveau_cli *cli) +{ + struct nouveau_object *client = nv_object(cli); + nouveau_client_fini(&cli->base, false); + atomic_set(&client->refcount, 1); + nouveau_object_ref(NULL, &client); +} + +static int __devinit +nouveau_drm_probe(struct pci_dev *pdev, const struct pci_device_id *pent) +{ + struct nouveau_device *device; + int ret; + + ret = nouveau_device_create(pdev, nouveau_name(pdev), pci_name(pdev), + nouveau_config, nouveau_debug, &device); + if (ret) + return ret; + + pci_set_master(pdev); + + ret = nouveau_pci_probe(pdev, pent); + if (ret) { + nouveau_device_destroy(&device); + return ret; + } + + return 0; +} + +int +nouveau_drm_load(struct drm_device *dev, unsigned long flags) +{ + struct pci_dev *pdev = dev->pdev; + struct nouveau_drm *drm; + int ret; + + ret = nouveau_cli_create(pdev, 0, sizeof(*drm), (void**)&drm); + dev->dev_private = drm; + if (ret) + return ret; + + INIT_LIST_HEAD(&drm->clients); + drm->dev = dev; + + ret = nouveau_object_new(nv_object(drm), NVDRM_CLIENT, NVDRM_DEVICE, + 0x0080, &(struct nv_device_class) { + .device = ~0, + .disable = 0, + .debug0 = 0, + }, sizeof(struct nv_device_class), + &drm->device); + if (ret) + goto fail_device; + + ret = nouveau_load(dev, flags); + if (ret) + goto fail_device; + + return 0; + +fail_device: + nouveau_cli_destroy(&drm->client); + return ret; +} + +int +nouveau_drm_unload(struct drm_device *dev) +{ + struct nouveau_drm *drm = nouveau_newpriv(dev); + struct pci_dev *pdev = dev->pdev; + int ret; + + ret = nouveau_unload(dev); + if (ret) + return ret; + + pci_set_drvdata(pdev, drm->client.base.device); + nouveau_cli_destroy(&drm->client); + return 0; +} + +static void +nouveau_drm_remove(struct pci_dev *pdev) +{ + struct nouveau_device *device; + nouveau_pci_remove(pdev); + device = pci_get_drvdata(pdev); + nouveau_device_destroy(&device); +} + +int +nouveau_drm_suspend(struct pci_dev *pdev, pm_message_t pm_state) +{ + struct drm_device *dev = pci_get_drvdata(pdev); + struct nouveau_drm *drm = nouveau_newpriv(dev); + struct nouveau_cli *cli; + int ret; + + if (dev->switch_power_state == DRM_SWITCH_POWER_OFF || + pm_state.event == PM_EVENT_PRETHAW) + return 0; + + ret = nouveau_pci_suspend(pdev, pm_state); + if (ret) + return ret; + + list_for_each_entry(cli, &drm->clients, head) { + ret = nouveau_client_fini(&cli->base, true); + if (ret) + goto fail_client; + } + + ret = nouveau_client_fini(&drm->client.base, true); + if (ret) + goto fail_client; + + pci_save_state(pdev); + if (pm_state.event == PM_EVENT_SUSPEND) { + pci_disable_device(pdev); + pci_set_power_state(pdev, PCI_D3hot); + } + + return 0; + +fail_client: + list_for_each_entry_continue_reverse(cli, &drm->clients, head) { + nouveau_client_init(&cli->base); + } + + nouveau_pci_resume(pdev); + return ret; +} + +int +nouveau_drm_resume(struct pci_dev *pdev) +{ + struct drm_device *dev = pci_get_drvdata(pdev); + struct nouveau_drm *drm = nouveau_newpriv(dev); + struct nouveau_cli *cli; + int ret; + + if (dev->switch_power_state == DRM_SWITCH_POWER_OFF) + return 0; + + pci_set_power_state(pdev, PCI_D0); + pci_restore_state(pdev); + ret = pci_enable_device(pdev); + if (ret) + return ret; + pci_set_master(pdev); + + nouveau_client_init(&drm->client.base); + + list_for_each_entry(cli, &drm->clients, head) { + nouveau_client_init(&cli->base); + } + + return nouveau_pci_resume(pdev); +} + +static struct pci_device_id +nouveau_drm_pci_table[] = { + { + PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_ANY_ID), + .class = PCI_BASE_CLASS_DISPLAY << 16, + .class_mask = 0xff << 16, + }, + { + PCI_DEVICE(PCI_VENDOR_ID_NVIDIA_SGS, PCI_ANY_ID), + .class = PCI_BASE_CLASS_DISPLAY << 16, + .class_mask = 0xff << 16, + }, + {} +}; + +static struct pci_driver +nouveau_drm_pci_driver = { + .name = "nouveau", + .id_table = nouveau_drm_pci_table, + .probe = nouveau_drm_probe, + .remove = nouveau_drm_remove, + .suspend = nouveau_drm_suspend, + .resume = nouveau_drm_resume, +}; + +static int __init +nouveau_drm_init(void) +{ + return nouveau_init(&nouveau_drm_pci_driver); +} + +static void __exit +nouveau_drm_exit(void) +{ + nouveau_exit(&nouveau_drm_pci_driver); +} + +module_init(nouveau_drm_init); +module_exit(nouveau_drm_exit); + +MODULE_DEVICE_TABLE(pci, nouveau_drm_pci_table); +MODULE_AUTHOR("Nouveau Project"); +MODULE_DESCRIPTION("nVidia Riva/TNT/GeForce/Quadro/Tesla"); +MODULE_LICENSE("GPL and additional rights"); diff --git a/drivers/gpu/drm/nouveau/nouveau_drm.h b/drivers/gpu/drm/nouveau/nouveau_drm.h new file mode 100644 index 000000000000..ef5500f56864 --- /dev/null +++ b/drivers/gpu/drm/nouveau/nouveau_drm.h @@ -0,0 +1,47 @@ +#ifndef __NOUVEAU_DRMCLI_H__ +#define __NOUVEAU_DRMCLI_H__ + +#include <core/client.h> + +#include <drmP.h> +#include <drm/nouveau_drm.h> + +enum nouveau_drm_handle { + NVDRM_CLIENT = 0xffffffff, + NVDRM_DEVICE = 0xdddddddd, +}; + +struct nouveau_cli { + struct nouveau_client base; + struct list_head head; + struct mutex mutex; +}; + +struct nouveau_drm { + struct nouveau_cli client; + struct drm_device *dev; + + struct nouveau_object *device; + struct list_head clients; +}; + +int nouveau_drm_suspend(struct pci_dev *, pm_message_t); +int nouveau_drm_resume(struct pci_dev *); + +#define NV_PRINTK(level, code, drm, fmt, args...) \ + printk(level "nouveau " code "[ DRM][%s] " fmt, \ + pci_name((drm)->dev->pdev), ##args) +#define NV_FATAL(drm, fmt, args...) \ + NV_PRINTK(KERN_CRIT, "!", (drm), fmt, ##args) +#define NV_ERROR(drm, fmt, args...) \ + NV_PRINTK(KERN_ERR, "E", (drm), fmt, ##args) +#define NV_WARN(drm, fmt, args...) \ + NV_PRINTK(KERN_WARNING, "W", (drm), fmt, ##args) +#define NV_INFO(drm, fmt, args...) \ + NV_PRINTK(KERN_INFO, " ", (drm), fmt, ##args) +#define NV_DEBUG(drm, fmt, args...) do { \ + if (drm_debug & DRM_UT_DRIVER) \ + NV_PRINTK(KERN_DEBUG, "D", drm, fmt, ##args); \ +} while (0) + +#endif diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.c b/drivers/gpu/drm/nouveau/nouveau_drv.c index 33dd955e26d3..aa725d408250 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drv.c +++ b/drivers/gpu/drm/nouveau/nouveau_drv.c @@ -136,31 +136,15 @@ int nouveau_fbpercrtc; module_param_named(fbpercrtc, nouveau_fbpercrtc, int, 0400); #endif -static struct pci_device_id pciidlist[] = { - { - PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_ANY_ID), - .class = PCI_BASE_CLASS_DISPLAY << 16, - .class_mask = 0xff << 16, - }, - { - PCI_DEVICE(PCI_VENDOR_ID_NVIDIA_SGS, PCI_ANY_ID), - .class = PCI_BASE_CLASS_DISPLAY << 16, - .class_mask = 0xff << 16, - }, - {} -}; - -MODULE_DEVICE_TABLE(pci, pciidlist); - static struct drm_driver driver; -static int __devinit +int __devinit nouveau_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) { return drm_get_pci_dev(pdev, ent, &driver); } -static void +void nouveau_pci_remove(struct pci_dev *pdev) { struct drm_device *dev = pci_get_drvdata(pdev); @@ -179,12 +163,6 @@ nouveau_pci_suspend(struct pci_dev *pdev, pm_message_t pm_state) struct drm_crtc *crtc; int ret, i, e; - if (pm_state.event == PM_EVENT_PRETHAW) - return 0; - - if (dev->switch_power_state == DRM_SWITCH_POWER_OFF) - return 0; - NV_INFO(dev, "Disabling display...\n"); nouveau_display_fini(dev); @@ -246,14 +224,6 @@ nouveau_pci_suspend(struct pci_dev *pdev, pm_message_t pm_state) } nouveau_agp_fini(dev); - - NV_INFO(dev, "And we're gone!\n"); - pci_save_state(pdev); - if (pm_state.event == PM_EVENT_SUSPEND) { - pci_disable_device(pdev); - pci_set_power_state(pdev, PCI_D3hot); - } - return 0; out_abort: @@ -275,16 +245,6 @@ nouveau_pci_resume(struct pci_dev *pdev) struct drm_crtc *crtc; int ret, i; - if (dev->switch_power_state == DRM_SWITCH_POWER_OFF) - return 0; - - NV_INFO(dev, "We're back, enabling device...\n"); - pci_set_power_state(pdev, PCI_D0); - pci_restore_state(pdev); - if (pci_enable_device(pdev)) - return -1; - pci_set_master(dev->pdev); - /* Make sure the AGP controller is in a consistent state */ nouveau_agp_reset(dev); @@ -407,15 +367,18 @@ static const struct file_operations nouveau_driver_fops = { .llseek = noop_llseek, }; +int nouveau_drm_load(struct drm_device *, unsigned long); +int nouveau_drm_unload(struct drm_device *); + static struct drm_driver driver = { .driver_features = DRIVER_USE_AGP | DRIVER_PCI_DMA | DRIVER_SG | DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED | DRIVER_GEM | DRIVER_MODESET | DRIVER_PRIME, - .load = nouveau_load, + .load = nouveau_drm_load, .firstopen = nouveau_firstopen, .lastclose = nouveau_lastclose, - .unload = nouveau_unload, + .unload = nouveau_drm_unload, .open = nouveau_open, .preclose = nouveau_preclose, .postclose = nouveau_postclose, @@ -459,16 +422,7 @@ static struct drm_driver driver = { .patchlevel = DRIVER_PATCHLEVEL, }; -static struct pci_driver nouveau_pci_driver = { - .name = DRIVER_NAME, - .id_table = pciidlist, - .probe = nouveau_pci_probe, - .remove = nouveau_pci_remove, - .suspend = nouveau_pci_suspend, - .resume = nouveau_pci_resume -}; - -static int __init nouveau_init(void) +int __init nouveau_init(struct pci_driver *pdrv) { driver.num_ioctls = ARRAY_SIZE(nouveau_ioctls); @@ -485,21 +439,14 @@ static int __init nouveau_init(void) return 0; nouveau_register_dsm_handler(); - return drm_pci_init(&driver, &nouveau_pci_driver); + return drm_pci_init(&driver, pdrv); } -static void __exit nouveau_exit(void) +void __exit nouveau_exit(struct pci_driver *pdrv) { if (!nouveau_modeset) return; - drm_pci_exit(&driver, &nouveau_pci_driver); + drm_pci_exit(&driver, pdrv); nouveau_unregister_dsm_handler(); } - -module_init(nouveau_init); -module_exit(nouveau_exit); - -MODULE_AUTHOR(DRIVER_AUTHOR); -MODULE_DESCRIPTION(DRIVER_DESC); -MODULE_LICENSE("GPL and additional rights"); diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h b/drivers/gpu/drm/nouveau/nouveau_drv.h index 2158710cd6ad..d1bade37fcc6 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drv.h +++ b/drivers/gpu/drm/nouveau/nouveau_drv.h @@ -59,7 +59,7 @@ nouveau_fpriv(struct drm_file *file_priv) #define DRM_FILE_PAGE_OFFSET (0x100000000ULL >> PAGE_SHIFT) -#include "nouveau_drm.h" +#include <nouveau_drm.h> #include "nouveau_reg.h" #include <nouveau_bios.h> #include "nouveau_util.h" @@ -664,6 +664,8 @@ struct drm_nouveau_private { struct drm_device *dev; bool noaccel; + void *newpriv; + /* the card type, takes NV_* as values */ enum nouveau_card_type card_type; /* exact chipset, derived from NV_PMC_BOOT_0 */ diff --git a/drivers/gpu/drm/nouveau/nouveau_fbcon.c b/drivers/gpu/drm/nouveau/nouveau_fbcon.c index 1074bc5dd418..9b078033ec19 100644 --- a/drivers/gpu/drm/nouveau/nouveau_fbcon.c +++ b/drivers/gpu/drm/nouveau/nouveau_fbcon.c @@ -44,7 +44,7 @@ #include "drm_crtc_helper.h" #include "drm_fb_helper.h" #include "nouveau_drv.h" -#include "nouveau_drm.h" +#include <nouveau_drm.h> #include "nouveau_crtc.h" #include "nouveau_fb.h" #include "nouveau_fbcon.h" diff --git a/drivers/gpu/drm/nouveau/nouveau_gem.c b/drivers/gpu/drm/nouveau/nouveau_gem.c index 0c9399bb9bf6..c8bb9f230222 100644 --- a/drivers/gpu/drm/nouveau/nouveau_gem.c +++ b/drivers/gpu/drm/nouveau/nouveau_gem.c @@ -28,7 +28,7 @@ #include "drm.h" #include "nouveau_drv.h" -#include "nouveau_drm.h" +#include <nouveau_drm.h> #include "nouveau_dma.h" #include "nouveau_fence.h" diff --git a/drivers/gpu/drm/nouveau/nouveau_gpuobj.c b/drivers/gpu/drm/nouveau/nouveau_gpuobj.c index 0e5fb0dc83e9..69c6a2ec4a0d 100644 --- a/drivers/gpu/drm/nouveau/nouveau_gpuobj.c +++ b/drivers/gpu/drm/nouveau/nouveau_gpuobj.c @@ -33,7 +33,7 @@ #include "drmP.h" #include "drm.h" #include "nouveau_drv.h" -#include "nouveau_drm.h" +#include <nouveau_drm.h> #include <engine/fifo.h> #include <core/ramht.h> #include "nouveau_software.h" diff --git a/drivers/gpu/drm/nouveau/nouveau_irq.c b/drivers/gpu/drm/nouveau/nouveau_irq.c index f4b29882dd50..d36be7a51079 100644 --- a/drivers/gpu/drm/nouveau/nouveau_irq.c +++ b/drivers/gpu/drm/nouveau/nouveau_irq.c @@ -32,7 +32,7 @@ #include "drmP.h" #include "drm.h" -#include "nouveau_drm.h" +#include <nouveau_drm.h> #include "nouveau_drv.h" #include "nouveau_reg.h" #include <core/ramht.h> diff --git a/drivers/gpu/drm/nouveau/nouveau_prime.c b/drivers/gpu/drm/nouveau/nouveau_prime.c index a25cf2cb931f..cce47fa7cb52 100644 --- a/drivers/gpu/drm/nouveau/nouveau_prime.c +++ b/drivers/gpu/drm/nouveau/nouveau_prime.c @@ -26,7 +26,7 @@ #include "drm.h" #include "nouveau_drv.h" -#include "nouveau_drm.h" +#include <nouveau_drm.h> #include "nouveau_dma.h" #include <linux/dma-buf.h> diff --git a/drivers/gpu/drm/nouveau/nouveau_state.c b/drivers/gpu/drm/nouveau/nouveau_state.c index 31c570c2bc36..f3bf14c2aa9f 100644 --- a/drivers/gpu/drm/nouveau/nouveau_state.c +++ b/drivers/gpu/drm/nouveau/nouveau_state.c @@ -33,7 +33,7 @@ #include <linux/vga_switcheroo.h> #include "nouveau_drv.h" -#include "nouveau_drm.h" +#include <nouveau_drm.h> #include "nouveau_agp.h" #include "nouveau_fbcon.h" #include <core/ramht.h> @@ -1027,6 +1027,13 @@ static int nouveau_remove_conflicting_drivers(struct drm_device *dev) return 0; } +void * +nouveau_newpriv(struct drm_device *dev) +{ + struct drm_nouveau_private *dev_priv = dev->dev_private; + return dev_priv->newpriv; +} + int nouveau_load(struct drm_device *dev, unsigned long flags) { struct drm_nouveau_private *dev_priv; @@ -1039,6 +1046,7 @@ int nouveau_load(struct drm_device *dev, unsigned long flags) ret = -ENOMEM; goto err_out; } + dev_priv->newpriv = dev->dev_private; dev->dev_private = dev_priv; dev_priv->dev = dev; @@ -1214,8 +1222,8 @@ err_ramin: err_mmio: iounmap(dev_priv->mmio); err_priv: + dev->dev_private = dev_priv->newpriv; kfree(dev_priv); - dev->dev_private = NULL; err_out: return ret; } @@ -1234,8 +1242,8 @@ int nouveau_unload(struct drm_device *dev) iounmap(dev_priv->mmio); iounmap(dev_priv->ramin); + dev->dev_private = dev_priv->newpriv; kfree(dev_priv); - dev->dev_private = NULL; return 0; } |