aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/char/agp
diff options
context:
space:
mode:
authorDaniel Vetter <daniel.vetter@ffwll.ch>2012-06-08 09:55:40 -0400
committerDaniel Vetter <daniel.vetter@ffwll.ch>2012-06-12 16:19:49 -0400
commit14be93ddff61eb196382aeaa3ac86f4db844aeb0 (patch)
tree0cfde7c3f444899508e2d07adb4245d4eb33216b /drivers/char/agp
parent7e8f6306fe155d6fc3fe99d666be95b4ed24427d (diff)
drm/i915 + agp/intel-gtt: prep work for direct setup
To be able to directly set up the intel-gtt code from drm/i915 and avoid setting up the fake-agp driver we need to prepare a few things: - pass both the bridge and gpu pci_dev to the probe function and add code to handle the gpu pdev both being present (for drm/i915) and not present (fake agp). - add refcounting to the remove function so that unloading drm/i915 doesn't kill the fake agp driver v2: Fix up the cleanup and refcount, noticed by Jani Nikula. Reviewed-by: Jani Nikula <jani.nikula@linux.intel.com> Signed-Off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Diffstat (limited to 'drivers/char/agp')
-rw-r--r--drivers/char/agp/intel-agp.c5
-rw-r--r--drivers/char/agp/intel-agp.h3
-rw-r--r--drivers/char/agp/intel-gtt.c46
3 files changed, 40 insertions, 14 deletions
diff --git a/drivers/char/agp/intel-agp.c b/drivers/char/agp/intel-agp.c
index 764f70c5e690..c98c5689bb0b 100644
--- a/drivers/char/agp/intel-agp.c
+++ b/drivers/char/agp/intel-agp.c
@@ -12,6 +12,7 @@
12#include <asm/smp.h> 12#include <asm/smp.h>
13#include "agp.h" 13#include "agp.h"
14#include "intel-agp.h" 14#include "intel-agp.h"
15#include <drm/intel-gtt.h>
15 16
16int intel_agp_enabled; 17int intel_agp_enabled;
17EXPORT_SYMBOL(intel_agp_enabled); 18EXPORT_SYMBOL(intel_agp_enabled);
@@ -747,7 +748,7 @@ static int __devinit agp_intel_probe(struct pci_dev *pdev,
747 748
748 bridge->capndx = cap_ptr; 749 bridge->capndx = cap_ptr;
749 750
750 if (intel_gmch_probe(pdev, bridge)) 751 if (intel_gmch_probe(pdev, NULL, bridge))
751 goto found_gmch; 752 goto found_gmch;
752 753
753 for (i = 0; intel_agp_chipsets[i].name != NULL; i++) { 754 for (i = 0; intel_agp_chipsets[i].name != NULL; i++) {
@@ -824,7 +825,7 @@ static void __devexit agp_intel_remove(struct pci_dev *pdev)
824 825
825 agp_remove_bridge(bridge); 826 agp_remove_bridge(bridge);
826 827
827 intel_gmch_remove(pdev); 828 intel_gmch_remove();
828 829
829 agp_put_bridge(bridge); 830 agp_put_bridge(bridge);
830} 831}
diff --git a/drivers/char/agp/intel-agp.h b/drivers/char/agp/intel-agp.h
index c0091753a0d1..cf2e764b1760 100644
--- a/drivers/char/agp/intel-agp.h
+++ b/drivers/char/agp/intel-agp.h
@@ -250,7 +250,4 @@
250#define PCI_DEVICE_ID_INTEL_HASWELL_SDV 0x0c16 /* SDV */ 250#define PCI_DEVICE_ID_INTEL_HASWELL_SDV 0x0c16 /* SDV */
251#define PCI_DEVICE_ID_INTEL_HASWELL_E_HB 0x0c04 251#define PCI_DEVICE_ID_INTEL_HASWELL_E_HB 0x0c04
252 252
253int intel_gmch_probe(struct pci_dev *pdev,
254 struct agp_bridge_data *bridge);
255void intel_gmch_remove(struct pci_dev *pdev);
256#endif 253#endif
diff --git a/drivers/char/agp/intel-gtt.c b/drivers/char/agp/intel-gtt.c
index 5e6c89e1d5eb..cea9f9905c7d 100644
--- a/drivers/char/agp/intel-gtt.c
+++ b/drivers/char/agp/intel-gtt.c
@@ -75,6 +75,7 @@ static struct _intel_private {
75 struct resource ifp_resource; 75 struct resource ifp_resource;
76 int resource_valid; 76 int resource_valid;
77 struct page *scratch_page; 77 struct page *scratch_page;
78 int refcount;
78} intel_private; 79} intel_private;
79 80
80#define INTEL_GTT_GEN intel_private.driver->gen 81#define INTEL_GTT_GEN intel_private.driver->gen
@@ -1522,14 +1523,32 @@ static int find_gmch(u16 device)
1522 return 1; 1523 return 1;
1523} 1524}
1524 1525
1525int intel_gmch_probe(struct pci_dev *pdev, 1526int intel_gmch_probe(struct pci_dev *bridge_pdev, struct pci_dev *gpu_pdev,
1526 struct agp_bridge_data *bridge) 1527 struct agp_bridge_data *bridge)
1527{ 1528{
1528 int i, mask; 1529 int i, mask;
1529 intel_private.driver = NULL; 1530
1531 /*
1532 * Can be called from the fake agp driver but also directly from
1533 * drm/i915.ko. Hence we need to check whether everything is set up
1534 * already.
1535 */
1536 if (intel_private.driver) {
1537 intel_private.refcount++;
1538 return 1;
1539 }
1530 1540
1531 for (i = 0; intel_gtt_chipsets[i].name != NULL; i++) { 1541 for (i = 0; intel_gtt_chipsets[i].name != NULL; i++) {
1532 if (find_gmch(intel_gtt_chipsets[i].gmch_chip_id)) { 1542 if (gpu_pdev) {
1543 if (gpu_pdev->device ==
1544 intel_gtt_chipsets[i].gmch_chip_id) {
1545 intel_private.pcidev = pci_dev_get(gpu_pdev);
1546 intel_private.driver =
1547 intel_gtt_chipsets[i].gtt_driver;
1548
1549 break;
1550 }
1551 } else if (find_gmch(intel_gtt_chipsets[i].gmch_chip_id)) {
1533 intel_private.driver = 1552 intel_private.driver =
1534 intel_gtt_chipsets[i].gtt_driver; 1553 intel_gtt_chipsets[i].gtt_driver;
1535 break; 1554 break;
@@ -1539,15 +1558,17 @@ int intel_gmch_probe(struct pci_dev *pdev,
1539 if (!intel_private.driver) 1558 if (!intel_private.driver)
1540 return 0; 1559 return 0;
1541 1560
1561 intel_private.refcount++;
1562
1542 if (bridge) { 1563 if (bridge) {
1543 bridge->driver = &intel_fake_agp_driver; 1564 bridge->driver = &intel_fake_agp_driver;
1544 bridge->dev_private_data = &intel_private; 1565 bridge->dev_private_data = &intel_private;
1545 bridge->dev = pdev; 1566 bridge->dev = bridge_pdev;
1546 } 1567 }
1547 1568
1548 intel_private.bridge_dev = pci_dev_get(pdev); 1569 intel_private.bridge_dev = pci_dev_get(bridge_pdev);
1549 1570
1550 dev_info(&pdev->dev, "Intel %s Chipset\n", intel_gtt_chipsets[i].name); 1571 dev_info(&bridge_pdev->dev, "Intel %s Chipset\n", intel_gtt_chipsets[i].name);
1551 1572
1552 mask = intel_private.driver->dma_mask_size; 1573 mask = intel_private.driver->dma_mask_size;
1553 if (pci_set_dma_mask(intel_private.pcidev, DMA_BIT_MASK(mask))) 1574 if (pci_set_dma_mask(intel_private.pcidev, DMA_BIT_MASK(mask)))
@@ -1557,8 +1578,11 @@ int intel_gmch_probe(struct pci_dev *pdev,
1557 pci_set_consistent_dma_mask(intel_private.pcidev, 1578 pci_set_consistent_dma_mask(intel_private.pcidev,
1558 DMA_BIT_MASK(mask)); 1579 DMA_BIT_MASK(mask));
1559 1580
1560 if (intel_gtt_init() != 0) 1581 if (intel_gtt_init() != 0) {
1582 intel_gmch_remove();
1583
1561 return 0; 1584 return 0;
1585 }
1562 1586
1563 return 1; 1587 return 1;
1564} 1588}
@@ -1577,12 +1601,16 @@ void intel_gtt_chipset_flush(void)
1577} 1601}
1578EXPORT_SYMBOL(intel_gtt_chipset_flush); 1602EXPORT_SYMBOL(intel_gtt_chipset_flush);
1579 1603
1580void intel_gmch_remove(struct pci_dev *pdev) 1604void intel_gmch_remove(void)
1581{ 1605{
1606 if (--intel_private.refcount)
1607 return;
1608
1582 if (intel_private.pcidev) 1609 if (intel_private.pcidev)
1583 pci_dev_put(intel_private.pcidev); 1610 pci_dev_put(intel_private.pcidev);
1584 if (intel_private.bridge_dev) 1611 if (intel_private.bridge_dev)
1585 pci_dev_put(intel_private.bridge_dev); 1612 pci_dev_put(intel_private.bridge_dev);
1613 intel_private.driver = NULL;
1586} 1614}
1587EXPORT_SYMBOL(intel_gmch_remove); 1615EXPORT_SYMBOL(intel_gmch_remove);
1588 1616