[Intel-gfx] [PATCH] drm/i915: get the bridge device once.

Dave Airlie airlied at gmail.com
Tue Aug 4 03:43:41 CEST 2009


From: Dave Airlie <airlied at redhat.com>

The driver gets the bridge device in a number of places, upcoming
vga arb code paths need the bridge device, however they need it in
under a lock, and the pci lookup can allocate memory. So clean
this code up before then and get the bridge once for the driver lifetime.

Signed-off-by: Dave Airlie <airlied at redhat.com>
---
 drivers/gpu/drm/i915/i915_dma.c        |   33 +++++++++++-----
 drivers/gpu/drm/i915/i915_drv.h        |    1 +
 drivers/gpu/drm/i915/i915_gem_tiling.c |   65 ++++++++++----------------------
 3 files changed, 44 insertions(+), 55 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c
index 8c47831..3724b57 100644
--- a/drivers/gpu/drm/i915/i915_dma.c
+++ b/drivers/gpu/drm/i915/i915_dma.c
@@ -875,6 +875,18 @@ static int i915_set_status_page(struct drm_device *dev, void *data,
 	return 0;
 }
 
+static int i915_get_bridge_dev(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+
+	dev_priv->bridge_dev = pci_get_bus_and_slot(0, PCI_DEVFN(0,0));
+	if (!dev_priv->bridge_dev) {
+		DRM_ERROR("bridge device not found\n");
+		return -1;
+	}
+	return 0;
+}
+
 /**
  * i915_probe_agp - get AGP bootup configuration
  * @pdev: PCI device
@@ -888,20 +900,13 @@ static int i915_set_status_page(struct drm_device *dev, void *data,
 static int i915_probe_agp(struct drm_device *dev, uint32_t *aperture_size,
 			  uint32_t *preallocated_size)
 {
-	struct pci_dev *bridge_dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
 	u16 tmp = 0;
 	unsigned long overhead;
 	unsigned long stolen;
 
-	bridge_dev = pci_get_bus_and_slot(0, PCI_DEVFN(0,0));
-	if (!bridge_dev) {
-		DRM_ERROR("bridge device not found\n");
-		return -1;
-	}
-
 	/* Get the fb aperture size and "stolen" memory amount. */
-	pci_read_config_word(bridge_dev, INTEL_GMCH_CTRL, &tmp);
-	pci_dev_put(bridge_dev);
+	pci_read_config_word(dev_priv->bridge_dev, INTEL_GMCH_CTRL, &tmp);
 
 	*aperture_size = 1024 * 1024;
 	*preallocated_size = 1024 * 1024;
@@ -1153,11 +1158,16 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags)
 	base = drm_get_resource_start(dev, mmio_bar);
 	size = drm_get_resource_len(dev, mmio_bar);
 
+	if (i915_get_bridge_dev(dev)) {
+		ret = -EIO;
+		goto free_priv;
+	}
+
 	dev_priv->regs = ioremap(base, size);
 	if (!dev_priv->regs) {
 		DRM_ERROR("failed to map registers\n");
 		ret = -EIO;
-		goto free_priv;
+		goto put_bridge;
 	}
 
         dev_priv->mm.gtt_mapping =
@@ -1260,6 +1270,8 @@ out_iomapfree:
 	io_mapping_free(dev_priv->mm.gtt_mapping);
 out_rmmap:
 	iounmap(dev_priv->regs);
+put_bridge:
+	pci_dev_put(dev_priv->bridge_dev);
 free_priv:
 	kfree(dev_priv);
 	return ret;
@@ -1301,6 +1313,7 @@ int i915_driver_unload(struct drm_device *dev)
 		i915_gem_lastclose(dev);
 	}
 
+	pci_dev_put(dev_priv->bridge_dev);
 	kfree(dev->dev_private);
 
 	return 0;
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 5f3a259..3731165 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -156,6 +156,7 @@ typedef struct drm_i915_private {
 
 	void __iomem *regs;
 
+	struct pci_dev *bridge_dev;
 	drm_i915_ring_buffer_t ring;
 
 	drm_dma_handle_t *status_page_dmah;
diff --git a/drivers/gpu/drm/i915/i915_gem_tiling.c b/drivers/gpu/drm/i915/i915_gem_tiling.c
index a2d527b..64ae507 100644
--- a/drivers/gpu/drm/i915/i915_gem_tiling.c
+++ b/drivers/gpu/drm/i915/i915_gem_tiling.c
@@ -94,23 +94,15 @@
 static int
 intel_alloc_mchbar_resource(struct drm_device *dev)
 {
-	struct pci_dev *bridge_dev;
 	drm_i915_private_t *dev_priv = dev->dev_private;
 	int reg = IS_I965G(dev) ? MCHBAR_I965 : MCHBAR_I915;
 	u32 temp_lo, temp_hi = 0;
 	u64 mchbar_addr;
 	int ret = 0;
 
-	bridge_dev = pci_get_bus_and_slot(0, PCI_DEVFN(0,0));
-	if (!bridge_dev) {
-		DRM_DEBUG("no bridge dev?!\n");
-		ret = -ENODEV;
-		goto out;
-	}
-
 	if (IS_I965G(dev))
-		pci_read_config_dword(bridge_dev, reg + 4, &temp_hi);
-	pci_read_config_dword(bridge_dev, reg, &temp_lo);
+		pci_read_config_dword(dev_priv->bridge_dev, reg + 4, &temp_hi);
+	pci_read_config_dword(dev_priv->bridge_dev, reg, &temp_lo);
 	mchbar_addr = ((u64)temp_hi << 32) | temp_lo;
 
 	/* If ACPI doesn't have it, assume we need to allocate it ourselves */
@@ -118,30 +110,28 @@ intel_alloc_mchbar_resource(struct drm_device *dev)
 	if (mchbar_addr &&
 	    pnp_range_reserved(mchbar_addr, mchbar_addr + MCHBAR_SIZE)) {
 		ret = 0;
-		goto out_put;
+		goto out;
 	}
 #endif
 
 	/* Get some space for it */
-	ret = pci_bus_alloc_resource(bridge_dev->bus, &dev_priv->mch_res,
+	ret = pci_bus_alloc_resource(dev_priv->bridge_dev->bus, &dev_priv->mch_res,
 				     MCHBAR_SIZE, MCHBAR_SIZE,
 				     PCIBIOS_MIN_MEM,
 				     0,   pcibios_align_resource,
-				     bridge_dev);
+				     dev_priv->bridge_dev);
 	if (ret) {
 		DRM_DEBUG("failed bus alloc: %d\n", ret);
 		dev_priv->mch_res.start = 0;
-		goto out_put;
+		goto out;
 	}
 
 	if (IS_I965G(dev))
-		pci_write_config_dword(bridge_dev, reg + 4,
+		pci_write_config_dword(dev_priv->bridge_dev, reg + 4,
 				       upper_32_bits(dev_priv->mch_res.start));
 
-	pci_write_config_dword(bridge_dev, reg,
+	pci_write_config_dword(dev_priv->bridge_dev, reg,
 			       lower_32_bits(dev_priv->mch_res.start));
-out_put:
-	pci_dev_put(bridge_dev);
 out:
 	return ret;
 }
@@ -150,44 +140,36 @@ out:
 static bool
 intel_setup_mchbar(struct drm_device *dev)
 {
-	struct pci_dev *bridge_dev;
+	drm_i915_private_t *dev_priv = dev->dev_private;
 	int mchbar_reg = IS_I965G(dev) ? MCHBAR_I965 : MCHBAR_I915;
 	u32 temp;
 	bool need_disable = false, enabled;
 
-	bridge_dev = pci_get_bus_and_slot(0, PCI_DEVFN(0,0));
-	if (!bridge_dev) {
-		DRM_DEBUG("no bridge dev?!\n");
-		goto out;
-	}
-
 	if (IS_I915G(dev) || IS_I915GM(dev)) {
-		pci_read_config_dword(bridge_dev, DEVEN_REG, &temp);
+		pci_read_config_dword(dev_priv->bridge_dev, DEVEN_REG, &temp);
 		enabled = !!(temp & DEVEN_MCHBAR_EN);
 	} else {
-		pci_read_config_dword(bridge_dev, mchbar_reg, &temp);
+		pci_read_config_dword(dev_priv->bridge_dev, mchbar_reg, &temp);
 		enabled = temp & 1;
 	}
 
 	/* If it's already enabled, don't have to do anything */
 	if (enabled)
-		goto out_put;
+		goto out;
 
 	if (intel_alloc_mchbar_resource(dev))
-		goto out_put;
+		goto out;
 
 	need_disable = true;
 
 	/* Space is allocated or reserved, so enable it. */
 	if (IS_I915G(dev) || IS_I915GM(dev)) {
-		pci_write_config_dword(bridge_dev, DEVEN_REG,
+		pci_write_config_dword(dev_priv->bridge_dev, DEVEN_REG,
 				       temp | DEVEN_MCHBAR_EN);
 	} else {
-		pci_read_config_dword(bridge_dev, mchbar_reg, &temp);
-		pci_write_config_dword(bridge_dev, mchbar_reg, temp | 1);
+		pci_read_config_dword(dev_priv->bridge_dev, mchbar_reg, &temp);
+		pci_write_config_dword(dev_priv->bridge_dev, mchbar_reg, temp | 1);
 	}
-out_put:
-	pci_dev_put(bridge_dev);
 out:
 	return need_disable;
 }
@@ -196,25 +178,18 @@ static void
 intel_teardown_mchbar(struct drm_device *dev, bool disable)
 {
 	drm_i915_private_t *dev_priv = dev->dev_private;
-	struct pci_dev *bridge_dev;
 	int mchbar_reg = IS_I965G(dev) ? MCHBAR_I965 : MCHBAR_I915;
 	u32 temp;
 
-	bridge_dev = pci_get_bus_and_slot(0, PCI_DEVFN(0,0));
-	if (!bridge_dev) {
-		DRM_DEBUG("no bridge dev?!\n");
-		return;
-	}
-
 	if (disable) {
 		if (IS_I915G(dev) || IS_I915GM(dev)) {
-			pci_read_config_dword(bridge_dev, DEVEN_REG, &temp);
+			pci_read_config_dword(dev_priv->bridge_dev, DEVEN_REG, &temp);
 			temp &= ~DEVEN_MCHBAR_EN;
-			pci_write_config_dword(bridge_dev, DEVEN_REG, temp);
+			pci_write_config_dword(dev_priv->bridge_dev, DEVEN_REG, temp);
 		} else {
-			pci_read_config_dword(bridge_dev, mchbar_reg, &temp);
+			pci_read_config_dword(dev_priv->bridge_dev, mchbar_reg, &temp);
 			temp &= ~1;
-			pci_write_config_dword(bridge_dev, mchbar_reg, temp);
+			pci_write_config_dword(dev_priv->bridge_dev, mchbar_reg, temp);
 		}
 	}
 
-- 
1.6.0.6




More information about the Intel-gfx mailing list