aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/char
diff options
context:
space:
mode:
authorBen Hutchings <ben@decadent.org.uk>2010-03-23 23:36:31 -0400
committerDave Airlie <airlied@redhat.com>2010-05-18 20:13:19 -0400
commit6fd024893911dcb51b4a0aa71971db5ba38f7071 (patch)
tree78c8730b790ab1ad038a780f766e4b08371a69b9 /drivers/char
parentd831692a1a8e9ceaaa9bb16bb3fc503b7e372558 (diff)
amd64-agp: Probe unknown AGP devices the right way
The current initialisation code probes 'unsupported' AGP devices simply by calling its own probe function. It does not lock these devices or even check whether another driver is already bound to them. We must use the device core to manage this. So if the specific device id table didn't match anything and agp_try_unsupported=1, switch the device id table and call driver_attach() again. Signed-off-by: Ben Hutchings <ben@decadent.org.uk> Signed-off-by: Dave Airlie <airlied@redhat.com>
Diffstat (limited to 'drivers/char')
-rw-r--r--drivers/char/agp/amd64-agp.c27
1 files changed, 15 insertions, 12 deletions
diff --git a/drivers/char/agp/amd64-agp.c b/drivers/char/agp/amd64-agp.c
index 73703b115cd2..67ea3a60de74 100644
--- a/drivers/char/agp/amd64-agp.c
+++ b/drivers/char/agp/amd64-agp.c
@@ -500,6 +500,10 @@ static int __devinit agp_amd64_probe(struct pci_dev *pdev,
500 u8 cap_ptr; 500 u8 cap_ptr;
501 int err; 501 int err;
502 502
503 /* The Highlander principle */
504 if (agp_bridges_found)
505 return -ENODEV;
506
503 cap_ptr = pci_find_capability(pdev, PCI_CAP_ID_AGP); 507 cap_ptr = pci_find_capability(pdev, PCI_CAP_ID_AGP);
504 if (!cap_ptr) 508 if (!cap_ptr)
505 return -ENODEV; 509 return -ENODEV;
@@ -563,6 +567,8 @@ static void __devexit agp_amd64_remove(struct pci_dev *pdev)
563 amd64_aperture_sizes[bridge->aperture_size_idx].size); 567 amd64_aperture_sizes[bridge->aperture_size_idx].size);
564 agp_remove_bridge(bridge); 568 agp_remove_bridge(bridge);
565 agp_put_bridge(bridge); 569 agp_put_bridge(bridge);
570
571 agp_bridges_found--;
566} 572}
567 573
568#ifdef CONFIG_PM 574#ifdef CONFIG_PM
@@ -710,6 +716,11 @@ static struct pci_device_id agp_amd64_pci_table[] = {
710 716
711MODULE_DEVICE_TABLE(pci, agp_amd64_pci_table); 717MODULE_DEVICE_TABLE(pci, agp_amd64_pci_table);
712 718
719static DEFINE_PCI_DEVICE_TABLE(agp_amd64_pci_promisc_table) = {
720 { PCI_DEVICE_CLASS(0, 0) },
721 { }
722};
723
713static struct pci_driver agp_amd64_pci_driver = { 724static struct pci_driver agp_amd64_pci_driver = {
714 .name = "agpgart-amd64", 725 .name = "agpgart-amd64",
715 .id_table = agp_amd64_pci_table, 726 .id_table = agp_amd64_pci_table,
@@ -735,7 +746,6 @@ int __init agp_amd64_init(void)
735 return err; 746 return err;
736 747
737 if (agp_bridges_found == 0) { 748 if (agp_bridges_found == 0) {
738 struct pci_dev *dev;
739 if (!agp_try_unsupported && !agp_try_unsupported_boot) { 749 if (!agp_try_unsupported && !agp_try_unsupported_boot) {
740 printk(KERN_INFO PFX "No supported AGP bridge found.\n"); 750 printk(KERN_INFO PFX "No supported AGP bridge found.\n");
741#ifdef MODULE 751#ifdef MODULE
@@ -751,17 +761,10 @@ int __init agp_amd64_init(void)
751 return -ENODEV; 761 return -ENODEV;
752 762
753 /* Look for any AGP bridge */ 763 /* Look for any AGP bridge */
754 dev = NULL; 764 agp_amd64_pci_driver.id_table = agp_amd64_pci_promisc_table;
755 err = -ENODEV; 765 err = driver_attach(&agp_amd64_pci_driver.driver);
756 for_each_pci_dev(dev) { 766 if (err == 0 && agp_bridges_found == 0)
757 if (!pci_find_capability(dev, PCI_CAP_ID_AGP)) 767 err = -ENODEV;
758 continue;
759 /* Only one bridge supported right now */
760 if (agp_amd64_probe(dev, NULL) == 0) {
761 err = 0;
762 break;
763 }
764 }
765 } 768 }
766 return err; 769 return err;
767} 770}