Commit cad3688f authored by Chris Wilson's avatar Chris Wilson

drm/i915: Split device release from unload

We may need to keep our memory management alive after we have unloaded
the physical pci device. For example, if we have exported an object via
dmabuf, that will keep the device around but the pci device may be
removed before the dmabuf itself is released, use of the pci hardware
will be revoked, but the memory and object management needs to persist
for the dmabuf.
Signed-off-by: default avatarChris Wilson <chris@chris-wilson.co.uk>
Reviewed-by: default avatarJoonas Lahtinen <joonas.lahtinen@linux.intel.com>
Link: http://patchwork.freedesktop.org/patch/msgid/20170210163523.17533-1-chris@chris-wilson.co.uk
parent 317eaa95
...@@ -1231,8 +1231,7 @@ int i915_driver_load(struct pci_dev *pdev, const struct pci_device_id *ent) ...@@ -1231,8 +1231,7 @@ int i915_driver_load(struct pci_dev *pdev, const struct pci_device_id *ent)
ret = drm_dev_init(&dev_priv->drm, &driver, &pdev->dev); ret = drm_dev_init(&dev_priv->drm, &driver, &pdev->dev);
if (ret) { if (ret) {
DRM_DEV_ERROR(&pdev->dev, "allocation failed\n"); DRM_DEV_ERROR(&pdev->dev, "allocation failed\n");
kfree(dev_priv); goto out_free;
return ret;
} }
dev_priv->drm.pdev = pdev; dev_priv->drm.pdev = pdev;
...@@ -1240,7 +1239,7 @@ int i915_driver_load(struct pci_dev *pdev, const struct pci_device_id *ent) ...@@ -1240,7 +1239,7 @@ int i915_driver_load(struct pci_dev *pdev, const struct pci_device_id *ent)
ret = pci_enable_device(pdev); ret = pci_enable_device(pdev);
if (ret) if (ret)
goto out_free_priv; goto out_fini;
pci_set_drvdata(pdev, &dev_priv->drm); pci_set_drvdata(pdev, &dev_priv->drm);
...@@ -1304,9 +1303,11 @@ int i915_driver_load(struct pci_dev *pdev, const struct pci_device_id *ent) ...@@ -1304,9 +1303,11 @@ int i915_driver_load(struct pci_dev *pdev, const struct pci_device_id *ent)
i915_driver_cleanup_early(dev_priv); i915_driver_cleanup_early(dev_priv);
out_pci_disable: out_pci_disable:
pci_disable_device(pdev); pci_disable_device(pdev);
out_free_priv: out_fini:
i915_load_error(dev_priv, "Device initialization failed (%d)\n", ret); i915_load_error(dev_priv, "Device initialization failed (%d)\n", ret);
drm_dev_unref(&dev_priv->drm); drm_dev_fini(&dev_priv->drm);
out_free:
kfree(dev_priv);
return ret; return ret;
} }
...@@ -1385,8 +1386,16 @@ void i915_driver_unload(struct drm_device *dev) ...@@ -1385,8 +1386,16 @@ void i915_driver_unload(struct drm_device *dev)
i915_driver_cleanup_mmio(dev_priv); i915_driver_cleanup_mmio(dev_priv);
intel_display_power_put(dev_priv, POWER_DOMAIN_INIT); intel_display_power_put(dev_priv, POWER_DOMAIN_INIT);
}
static void i915_driver_release(struct drm_device *dev)
{
struct drm_i915_private *dev_priv = to_i915(dev);
i915_driver_cleanup_early(dev_priv); i915_driver_cleanup_early(dev_priv);
drm_dev_fini(&dev_priv->drm);
kfree(dev_priv);
} }
static int i915_driver_open(struct drm_device *dev, struct drm_file *file) static int i915_driver_open(struct drm_device *dev, struct drm_file *file)
...@@ -2630,6 +2639,7 @@ static struct drm_driver driver = { ...@@ -2630,6 +2639,7 @@ static struct drm_driver driver = {
.driver_features = .driver_features =
DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED | DRIVER_GEM | DRIVER_PRIME | DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED | DRIVER_GEM | DRIVER_PRIME |
DRIVER_RENDER | DRIVER_MODESET | DRIVER_ATOMIC, DRIVER_RENDER | DRIVER_MODESET | DRIVER_ATOMIC,
.release = i915_driver_release,
.open = i915_driver_open, .open = i915_driver_open,
.lastclose = i915_driver_lastclose, .lastclose = i915_driver_lastclose,
.preclose = i915_driver_preclose, .preclose = i915_driver_preclose,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment