From 863981e96738983919de841ec669e157e6bdaeb0 Mon Sep 17 00:00:00 2001 From: André Fabian Silva Delgado Date: Sun, 11 Sep 2016 04:34:46 -0300 Subject: Linux-libre 4.7.1-gnu --- drivers/gpu/drm/i915/i915_dma.c | 524 ++++++++++++++++++++++++++++------------ 1 file changed, 363 insertions(+), 161 deletions(-) (limited to 'drivers/gpu/drm/i915/i915_dma.c') diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index 1c6d227aa..b3198fcd0 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c @@ -50,6 +50,66 @@ #include #include +static unsigned int i915_load_fail_count; + +bool __i915_inject_load_failure(const char *func, int line) +{ + if (i915_load_fail_count >= i915.inject_load_failure) + return false; + + if (++i915_load_fail_count == i915.inject_load_failure) { + DRM_INFO("Injecting failure at checkpoint %u [%s:%d]\n", + i915.inject_load_failure, func, line); + return true; + } + + return false; +} + +#define FDO_BUG_URL "https://bugs.freedesktop.org/enter_bug.cgi?product=DRI" +#define FDO_BUG_MSG "Please file a bug at " FDO_BUG_URL " against DRM/Intel " \ + "providing the dmesg log by booting with drm.debug=0xf" + +void +__i915_printk(struct drm_i915_private *dev_priv, const char *level, + const char *fmt, ...) +{ + static bool shown_bug_once; + struct device *dev = dev_priv->dev->dev; + bool is_error = level[1] <= KERN_ERR[1]; + bool is_debug = level[1] == KERN_DEBUG[1]; + struct va_format vaf; + va_list args; + + if (is_debug && !(drm_debug & DRM_UT_DRIVER)) + return; + + va_start(args, fmt); + + vaf.fmt = fmt; + vaf.va = &args; + + dev_printk(level, dev, "[" DRM_NAME ":%ps] %pV", + __builtin_return_address(0), &vaf); + + if (is_error && !shown_bug_once) { + dev_notice(dev, "%s", FDO_BUG_MSG); + shown_bug_once = true; + } + + va_end(args); +} + +static bool i915_error_injected(struct drm_i915_private *dev_priv) +{ + return i915.inject_load_failure && + i915_load_fail_count == i915.inject_load_failure; +} + +#define i915_load_error(dev_priv, fmt, ...) \ + __i915_printk(dev_priv, \ + i915_error_injected(dev_priv) ? KERN_DEBUG : KERN_ERR, \ + fmt, ##__VA_ARGS__) static int i915_getparam(struct drm_device *dev, void *data, struct drm_file *file_priv) @@ -87,16 +147,16 @@ static int i915_getparam(struct drm_device *dev, void *data, value = 1; break; case I915_PARAM_HAS_BSD: - value = intel_ring_initialized(&dev_priv->ring[VCS]); + value = intel_engine_initialized(&dev_priv->engine[VCS]); break; case I915_PARAM_HAS_BLT: - value = intel_ring_initialized(&dev_priv->ring[BCS]); + value = intel_engine_initialized(&dev_priv->engine[BCS]); break; case I915_PARAM_HAS_VEBOX: - value = intel_ring_initialized(&dev_priv->ring[VECS]); + value = intel_engine_initialized(&dev_priv->engine[VECS]); break; case I915_PARAM_HAS_BSD2: - value = intel_ring_initialized(&dev_priv->ring[VCS2]); + value = intel_engine_initialized(&dev_priv->engine[VCS2]); break; case I915_PARAM_HAS_RELAXED_FENCING: value = 1; @@ -197,13 +257,6 @@ static int i915_get_bridge_dev(struct drm_device *dev) return 0; } -#define MCHBAR_I915 0x44 -#define MCHBAR_I965 0x48 -#define MCHBAR_SIZE (4*4096) - -#define DEVEN_REG 0x54 -#define DEVEN_MCHBAR_EN (1 << 28) - /* Allocate space for the MCH regs if needed, return nonzero on error */ static int intel_alloc_mchbar_resource(struct drm_device *dev) @@ -265,7 +318,7 @@ intel_setup_mchbar(struct drm_device *dev) dev_priv->mchbar_need_disable = false; if (IS_I915G(dev) || IS_I915GM(dev)) { - pci_read_config_dword(dev_priv->bridge_dev, DEVEN_REG, &temp); + pci_read_config_dword(dev_priv->bridge_dev, DEVEN, &temp); enabled = !!(temp & DEVEN_MCHBAR_EN); } else { pci_read_config_dword(dev_priv->bridge_dev, mchbar_reg, &temp); @@ -283,7 +336,7 @@ intel_setup_mchbar(struct drm_device *dev) /* Space is allocated or reserved, so enable it. */ if (IS_I915G(dev) || IS_I915GM(dev)) { - pci_write_config_dword(dev_priv->bridge_dev, DEVEN_REG, + pci_write_config_dword(dev_priv->bridge_dev, DEVEN, temp | DEVEN_MCHBAR_EN); } else { pci_read_config_dword(dev_priv->bridge_dev, mchbar_reg, &temp); @@ -296,17 +349,24 @@ intel_teardown_mchbar(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; int mchbar_reg = INTEL_INFO(dev)->gen >= 4 ? MCHBAR_I965 : MCHBAR_I915; - u32 temp; if (dev_priv->mchbar_need_disable) { if (IS_I915G(dev) || IS_I915GM(dev)) { - pci_read_config_dword(dev_priv->bridge_dev, DEVEN_REG, &temp); - temp &= ~DEVEN_MCHBAR_EN; - pci_write_config_dword(dev_priv->bridge_dev, DEVEN_REG, temp); + u32 deven_val; + + pci_read_config_dword(dev_priv->bridge_dev, DEVEN, + &deven_val); + deven_val &= ~DEVEN_MCHBAR_EN; + pci_write_config_dword(dev_priv->bridge_dev, DEVEN, + deven_val); } else { - pci_read_config_dword(dev_priv->bridge_dev, mchbar_reg, &temp); - temp &= ~1; - pci_write_config_dword(dev_priv->bridge_dev, mchbar_reg, temp); + u32 mchbar_val; + + pci_read_config_dword(dev_priv->bridge_dev, mchbar_reg, + &mchbar_val); + mchbar_val &= ~1; + pci_write_config_dword(dev_priv->bridge_dev, mchbar_reg, + mchbar_val); } } @@ -370,6 +430,9 @@ static int i915_load_modeset_init(struct drm_device *dev) struct drm_i915_private *dev_priv = dev->dev_private; int ret; + if (i915_inject_load_failure()) + return -ENODEV; + ret = intel_bios_init(dev_priv); if (ret) DRM_INFO("failed to find VBIOS tables\n"); @@ -413,9 +476,6 @@ static int i915_load_modeset_init(struct drm_device *dev) intel_modeset_gem_init(dev); - /* Always safe in the mode setting case. */ - /* FIXME: do pre/post-mode set stuff in core KMS code */ - dev->vblank_disable_allowed = true; if (INTEL_INFO(dev)->num_pipes == 0) return 0; @@ -444,7 +504,7 @@ static int i915_load_modeset_init(struct drm_device *dev) cleanup_gem: mutex_lock(&dev->struct_mutex); - i915_gem_cleanup_ringbuffer(dev); + i915_gem_cleanup_engines(dev); i915_gem_context_fini(dev); mutex_unlock(&dev->struct_mutex); cleanup_irq: @@ -453,6 +513,7 @@ cleanup_irq: intel_teardown_gmbus(dev); cleanup_csr: intel_csr_ucode_fini(dev_priv); + intel_power_domains_fini(dev_priv); vga_switcheroo_unregister_client(dev->pdev); cleanup_vga_client: vga_client_register(dev->pdev, NULL, NULL, NULL); @@ -465,6 +526,7 @@ static int i915_kick_out_firmware_fb(struct drm_i915_private *dev_priv) { struct apertures_struct *ap; struct pci_dev *pdev = dev_priv->dev->pdev; + struct i915_ggtt *ggtt = &dev_priv->ggtt; bool primary; int ret; @@ -472,8 +534,8 @@ static int i915_kick_out_firmware_fb(struct drm_i915_private *dev_priv) if (!ap) return -ENOMEM; - ap->ranges[0].base = dev_priv->gtt.mappable_base; - ap->ranges[0].size = dev_priv->gtt.mappable_end; + ap->ranges[0].base = ggtt->mappable_base; + ap->ranges[0].size = ggtt->mappable_end; primary = pdev->resource[PCI_ROM_RESOURCE].flags & IORESOURCE_ROM_SHADOW; @@ -853,6 +915,10 @@ static void intel_device_info_runtime_init(struct drm_device *dev) else if (INTEL_INFO(dev)->gen >= 9) gen9_sseu_info_init(dev); + /* Snooping is broken on BXT A stepping. */ + info->has_snoop = !info->has_llc; + info->has_snoop &= !IS_BXT_REVID(dev, 0, BXT_REVID_A1); + DRM_DEBUG_DRIVER("slice total: %u\n", info->slice_total); DRM_DEBUG_DRIVER("subslice total: %u\n", info->subslice_total); DRM_DEBUG_DRIVER("subslice per slice: %u\n", info->subslice_per_slice); @@ -929,6 +995,84 @@ static void i915_workqueues_cleanup(struct drm_i915_private *dev_priv) destroy_workqueue(dev_priv->wq); } +/** + * i915_driver_init_early - setup state not requiring device access + * @dev_priv: device private + * + * Initialize everything that is a "SW-only" state, that is state not + * requiring accessing the device or exposing the driver via kernel internal + * or userspace interfaces. Example steps belonging here: lock initialization, + * system memory allocation, setting up device specific attributes and + * function hooks not requiring accessing the device. + */ +static int i915_driver_init_early(struct drm_i915_private *dev_priv, + struct drm_device *dev, + struct intel_device_info *info) +{ + struct intel_device_info *device_info; + int ret = 0; + + if (i915_inject_load_failure()) + return -ENODEV; + + /* Setup the write-once "constant" device info */ + device_info = (struct intel_device_info *)&dev_priv->info; + memcpy(device_info, info, sizeof(dev_priv->info)); + device_info->device_id = dev->pdev->device; + + spin_lock_init(&dev_priv->irq_lock); + spin_lock_init(&dev_priv->gpu_error.lock); + mutex_init(&dev_priv->backlight_lock); + spin_lock_init(&dev_priv->uncore.lock); + spin_lock_init(&dev_priv->mm.object_stat_lock); + spin_lock_init(&dev_priv->mmio_flip_lock); + mutex_init(&dev_priv->sb_lock); + mutex_init(&dev_priv->modeset_restore_lock); + mutex_init(&dev_priv->av_mutex); + mutex_init(&dev_priv->wm.wm_mutex); + mutex_init(&dev_priv->pps_mutex); + + ret = i915_workqueues_init(dev_priv); + if (ret < 0) + return ret; + + /* This must be called before any calls to HAS_PCH_* */ + intel_detect_pch(dev); + + intel_pm_setup(dev); + intel_init_dpio(dev_priv); + intel_power_domains_init(dev_priv); + intel_irq_init(dev_priv); + intel_init_display_hooks(dev_priv); + intel_init_clock_gating_hooks(dev_priv); + intel_init_audio_hooks(dev_priv); + i915_gem_load_init(dev); + + intel_display_crc_init(dev); + + i915_dump_device_info(dev_priv); + + /* Not all pre-production machines fall into this category, only the + * very first ones. Almost everything should work, except for maybe + * suspend/resume. And we don't implement workarounds that affect only + * pre-production machines. */ + if (IS_HSW_EARLY_SDV(dev)) + DRM_INFO("This is an early pre-production Haswell machine. " + "It may not be fully functional.\n"); + + return 0; +} + +/** + * i915_driver_cleanup_early - cleanup the setup done in i915_driver_init_early() + * @dev_priv: device private + */ +static void i915_driver_cleanup_early(struct drm_i915_private *dev_priv) +{ + i915_gem_load_cleanup(dev_priv->dev); + i915_workqueues_cleanup(dev_priv); +} + static int i915_mmio_setup(struct drm_device *dev) { struct drm_i915_private *dev_priv = to_i915(dev); @@ -970,97 +1114,93 @@ static void i915_mmio_cleanup(struct drm_device *dev) } /** - * i915_driver_load - setup chip and create an initial config - * @dev: DRM device - * @flags: startup flags + * i915_driver_init_mmio - setup device MMIO + * @dev_priv: device private * - * The driver load routine has to do several things: - * - drive output discovery via intel_modeset_init() - * - initialize the memory manager - * - allocate initial config memory - * - setup the DRM framebuffer with the allocated memory + * Setup minimal device state necessary for MMIO accesses later in the + * initialization sequence. The setup here should avoid any other device-wide + * side effects or exposing the driver via kernel internal or user space + * interfaces. */ -int i915_driver_load(struct drm_device *dev, unsigned long flags) +static int i915_driver_init_mmio(struct drm_i915_private *dev_priv) { - struct drm_i915_private *dev_priv; - struct intel_device_info *info, *device_info; - int ret = 0; - uint32_t aperture_size; - - info = (struct intel_device_info *) flags; - - dev_priv = kzalloc(sizeof(*dev_priv), GFP_KERNEL); - if (dev_priv == NULL) - return -ENOMEM; - - dev->dev_private = dev_priv; - dev_priv->dev = dev; + struct drm_device *dev = dev_priv->dev; + int ret; - /* Setup the write-once "constant" device info */ - device_info = (struct intel_device_info *)&dev_priv->info; - memcpy(device_info, info, sizeof(dev_priv->info)); - device_info->device_id = dev->pdev->device; + if (i915_inject_load_failure()) + return -ENODEV; - spin_lock_init(&dev_priv->irq_lock); - spin_lock_init(&dev_priv->gpu_error.lock); - mutex_init(&dev_priv->backlight_lock); - spin_lock_init(&dev_priv->uncore.lock); - spin_lock_init(&dev_priv->mm.object_stat_lock); - spin_lock_init(&dev_priv->mmio_flip_lock); - mutex_init(&dev_priv->sb_lock); - mutex_init(&dev_priv->modeset_restore_lock); - mutex_init(&dev_priv->av_mutex); + if (i915_get_bridge_dev(dev)) + return -EIO; - ret = i915_workqueues_init(dev_priv); + ret = i915_mmio_setup(dev); if (ret < 0) - goto out_free_priv; + goto put_bridge; - intel_pm_setup(dev); + intel_uncore_init(dev); - intel_runtime_pm_get(dev_priv); + return 0; - intel_display_crc_init(dev); +put_bridge: + pci_dev_put(dev_priv->bridge_dev); - i915_dump_device_info(dev_priv); + return ret; +} - /* Not all pre-production machines fall into this category, only the - * very first ones. Almost everything should work, except for maybe - * suspend/resume. And we don't implement workarounds that affect only - * pre-production machines. */ - if (IS_HSW_EARLY_SDV(dev)) - DRM_INFO("This is an early pre-production Haswell machine. " - "It may not be fully functional.\n"); +/** + * i915_driver_cleanup_mmio - cleanup the setup done in i915_driver_init_mmio() + * @dev_priv: device private + */ +static void i915_driver_cleanup_mmio(struct drm_i915_private *dev_priv) +{ + struct drm_device *dev = dev_priv->dev; - if (i915_get_bridge_dev(dev)) { - ret = -EIO; - goto out_runtime_pm_put; - } + intel_uncore_fini(dev); + i915_mmio_cleanup(dev); + pci_dev_put(dev_priv->bridge_dev); +} - ret = i915_mmio_setup(dev); - if (ret < 0) - goto put_bridge; +/** + * i915_driver_init_hw - setup state requiring device access + * @dev_priv: device private + * + * Setup state that requires accessing the device, but doesn't require + * exposing the driver via kernel internal or userspace interfaces. + */ +static int i915_driver_init_hw(struct drm_i915_private *dev_priv) +{ + struct drm_device *dev = dev_priv->dev; + struct i915_ggtt *ggtt = &dev_priv->ggtt; + uint32_t aperture_size; + int ret; - /* This must be called before any calls to HAS_PCH_* */ - intel_detect_pch(dev); + if (i915_inject_load_failure()) + return -ENODEV; - intel_uncore_init(dev); + intel_device_info_runtime_init(dev); - ret = i915_gem_gtt_init(dev); + ret = i915_ggtt_init_hw(dev); if (ret) - goto out_uncore_fini; + return ret; + + ret = i915_ggtt_enable_hw(dev); + if (ret) { + DRM_ERROR("failed to enable GGTT\n"); + goto out_ggtt; + } /* WARNING: Apparently we must kick fbdev drivers before vgacon, * otherwise the vga fbdev driver falls over. */ ret = i915_kick_out_firmware_fb(dev_priv); if (ret) { DRM_ERROR("failed to remove conflicting framebuffer drivers\n"); - goto out_gtt; + goto out_ggtt; } ret = i915_kick_out_vgacon(dev_priv); if (ret) { DRM_ERROR("failed to remove conflicting VGA console\n"); - goto out_gtt; + goto out_ggtt; } pci_set_master(dev->pdev); @@ -1080,26 +1220,27 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) if (IS_BROADWATER(dev) || IS_CRESTLINE(dev)) dma_set_coherent_mask(&dev->pdev->dev, DMA_BIT_MASK(32)); - aperture_size = dev_priv->gtt.mappable_end; + aperture_size = ggtt->mappable_end; - dev_priv->gtt.mappable = - io_mapping_create_wc(dev_priv->gtt.mappable_base, + ggtt->mappable = + io_mapping_create_wc(ggtt->mappable_base, aperture_size); - if (dev_priv->gtt.mappable == NULL) { + if (!ggtt->mappable) { ret = -EIO; - goto out_gtt; + goto out_ggtt; } - dev_priv->gtt.mtrr = arch_phys_wc_add(dev_priv->gtt.mappable_base, + ggtt->mtrr = arch_phys_wc_add(ggtt->mappable_base, aperture_size); - intel_irq_init(dev_priv); + pm_qos_add_request(&dev_priv->pm_qos, PM_QOS_CPU_DMA_LATENCY, + PM_QOS_DEFAULT_VALUE); + intel_uncore_sanitize(dev); intel_opregion_setup(dev); - i915_gem_load_init(dev); - i915_gem_shrinker_init(dev_priv); + i915_gem_load_init_fences(dev_priv); /* On the 945G/GM, the chipset reports the MSI capability on the * integrated graphics even though the support isn't actually there @@ -1117,24 +1258,44 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) DRM_DEBUG_DRIVER("can't enable MSI"); } - intel_device_info_runtime_init(dev); + return 0; - intel_init_dpio(dev_priv); +out_ggtt: + i915_ggtt_cleanup_hw(dev); - if (INTEL_INFO(dev)->num_pipes) { - ret = drm_vblank_init(dev, INTEL_INFO(dev)->num_pipes); - if (ret) - goto out_gem_unload; - } + return ret; +} - intel_power_domains_init(dev_priv); +/** + * i915_driver_cleanup_hw - cleanup the setup done in i915_driver_init_hw() + * @dev_priv: device private + */ +static void i915_driver_cleanup_hw(struct drm_i915_private *dev_priv) +{ + struct drm_device *dev = dev_priv->dev; + struct i915_ggtt *ggtt = &dev_priv->ggtt; - ret = i915_load_modeset_init(dev); - if (ret < 0) { - DRM_ERROR("failed to init modeset\n"); - goto out_power_well; - } + if (dev->pdev->msi_enabled) + pci_disable_msi(dev->pdev); + pm_qos_remove_request(&dev_priv->pm_qos); + arch_phys_wc_del(ggtt->mtrr); + io_mapping_free(ggtt->mappable); + i915_ggtt_cleanup_hw(dev); +} + +/** + * i915_driver_register - register the driver with the rest of the system + * @dev_priv: device private + * + * Perform any steps necessary to make the driver available via kernel + * internal or userspace interfaces. + */ +static void i915_driver_register(struct drm_i915_private *dev_priv) +{ + struct drm_device *dev = dev_priv->dev; + + i915_gem_shrinker_init(dev_priv); /* * Notify a valid surface after modesetting, * when running inside a VM. @@ -1144,48 +1305,107 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) i915_setup_sysfs(dev); - if (INTEL_INFO(dev)->num_pipes) { + if (INTEL_INFO(dev_priv)->num_pipes) { /* Must be done after probing outputs */ intel_opregion_init(dev); acpi_video_register(); } - if (IS_GEN5(dev)) + if (IS_GEN5(dev_priv)) intel_gpu_ips_init(dev_priv); - intel_runtime_pm_enable(dev_priv); - i915_audio_component_init(dev_priv); +} + +/** + * i915_driver_unregister - cleanup the registration done in i915_driver_regiser() + * @dev_priv: device private + */ +static void i915_driver_unregister(struct drm_i915_private *dev_priv) +{ + i915_audio_component_cleanup(dev_priv); + intel_gpu_ips_teardown(); + acpi_video_unregister(); + intel_opregion_fini(dev_priv->dev); + i915_teardown_sysfs(dev_priv->dev); + i915_gem_shrinker_cleanup(dev_priv); +} + +/** + * i915_driver_load - setup chip and create an initial config + * @dev: DRM device + * @flags: startup flags + * + * The driver load routine has to do several things: + * - drive output discovery via intel_modeset_init() + * - initialize the memory manager + * - allocate initial config memory + * - setup the DRM framebuffer with the allocated memory + */ +int i915_driver_load(struct drm_device *dev, unsigned long flags) +{ + struct drm_i915_private *dev_priv; + int ret = 0; + + dev_priv = kzalloc(sizeof(*dev_priv), GFP_KERNEL); + if (dev_priv == NULL) + return -ENOMEM; + + dev->dev_private = dev_priv; + /* Must be set before calling __i915_printk */ + dev_priv->dev = dev; + + ret = i915_driver_init_early(dev_priv, dev, + (struct intel_device_info *)flags); + + if (ret < 0) + goto out_free_priv; + + intel_runtime_pm_get(dev_priv); + + ret = i915_driver_init_mmio(dev_priv); + if (ret < 0) + goto out_runtime_pm_put; + + ret = i915_driver_init_hw(dev_priv); + if (ret < 0) + goto out_cleanup_mmio; + + /* + * TODO: move the vblank init and parts of modeset init steps into one + * of the i915_driver_init_/i915_driver_register functions according + * to the role/effect of the given init step. + */ + if (INTEL_INFO(dev)->num_pipes) { + ret = drm_vblank_init(dev, INTEL_INFO(dev)->num_pipes); + if (ret) + goto out_cleanup_hw; + } + + ret = i915_load_modeset_init(dev); + if (ret < 0) + goto out_cleanup_vblank; + + i915_driver_register(dev_priv); + + intel_runtime_pm_enable(dev_priv); intel_runtime_pm_put(dev_priv); return 0; -out_power_well: - intel_power_domains_fini(dev_priv); +out_cleanup_vblank: drm_vblank_cleanup(dev); -out_gem_unload: - i915_gem_shrinker_cleanup(dev_priv); - - if (dev->pdev->msi_enabled) - pci_disable_msi(dev->pdev); - - intel_teardown_mchbar(dev); - pm_qos_remove_request(&dev_priv->pm_qos); - arch_phys_wc_del(dev_priv->gtt.mtrr); - io_mapping_free(dev_priv->gtt.mappable); -out_gtt: - i915_global_gtt_cleanup(dev); -out_uncore_fini: - intel_uncore_fini(dev); - i915_mmio_cleanup(dev); -put_bridge: - pci_dev_put(dev_priv->bridge_dev); - i915_gem_load_cleanup(dev); +out_cleanup_hw: + i915_driver_cleanup_hw(dev_priv); +out_cleanup_mmio: + i915_driver_cleanup_mmio(dev_priv); out_runtime_pm_put: intel_runtime_pm_put(dev_priv); - i915_workqueues_cleanup(dev_priv); + i915_driver_cleanup_early(dev_priv); out_free_priv: + i915_load_error(dev_priv, "Device initialization failed (%d)\n", ret); + kfree(dev_priv); return ret; @@ -1198,26 +1418,15 @@ int i915_driver_unload(struct drm_device *dev) intel_fbdev_fini(dev); - i915_audio_component_cleanup(dev_priv); - ret = i915_gem_suspend(dev); if (ret) { DRM_ERROR("failed to idle hardware: %d\n", ret); return ret; } - intel_power_domains_fini(dev_priv); - - intel_gpu_ips_teardown(); + intel_display_power_get(dev_priv, POWER_DOMAIN_INIT); - i915_teardown_sysfs(dev); - - i915_gem_shrinker_cleanup(dev_priv); - - io_mapping_free(dev_priv->gtt.mappable); - arch_phys_wc_del(dev_priv->gtt.mtrr); - - acpi_video_unregister(); + i915_driver_unregister(dev_priv); drm_vblank_cleanup(dev); @@ -1246,31 +1455,24 @@ int i915_driver_unload(struct drm_device *dev) cancel_delayed_work_sync(&dev_priv->gpu_error.hangcheck_work); i915_destroy_error_state(dev); - if (dev->pdev->msi_enabled) - pci_disable_msi(dev->pdev); - - intel_opregion_fini(dev); - /* Flush any outstanding unpin_work. */ flush_workqueue(dev_priv->wq); intel_guc_ucode_fini(dev); mutex_lock(&dev->struct_mutex); - i915_gem_cleanup_ringbuffer(dev); + i915_gem_cleanup_engines(dev); i915_gem_context_fini(dev); mutex_unlock(&dev->struct_mutex); intel_fbc_cleanup_cfb(dev_priv); - pm_qos_remove_request(&dev_priv->pm_qos); + intel_power_domains_fini(dev_priv); - i915_global_gtt_cleanup(dev); + i915_driver_cleanup_hw(dev_priv); + i915_driver_cleanup_mmio(dev_priv); - intel_uncore_fini(dev); - i915_mmio_cleanup(dev); + intel_display_power_put(dev_priv, POWER_DOMAIN_INIT); - i915_gem_load_cleanup(dev); - pci_dev_put(dev_priv->bridge_dev); - i915_workqueues_cleanup(dev_priv); + i915_driver_cleanup_early(dev_priv); kfree(dev_priv); return 0; -- cgit v1.2.3-54-g00ecf