ALSA: oxygen: rewrite PCIe bridge initialization
authorClemens Ladisch <clemens@ladisch.de>
Wed, 6 Oct 2010 08:57:50 +0000 (10:57 +0200)
committerTakashi Iwai <tiwai@suse.de>
Wed, 6 Oct 2010 14:27:12 +0000 (16:27 +0200)
Change the PCIe/PCI bridge initialization code to configure only the
bridge that is actually connected to the sound chip, instead of any
bridge found in the system.  The new code also makes it easier to add
other bridges.

Signed-off-by: Clemens Ladisch <clemens@ladisch.de>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
sound/pci/oxygen/oxygen_lib.c

index 7e93cf8..d10cc6e 100644 (file)
@@ -308,25 +308,31 @@ static void oxygen_restore_eeprom(struct oxygen *chip,
        }
 }
 
-static void pci_bridge_magic(void)
+static void configure_pcie_bridge(struct pci_dev *pci)
 {
-       struct pci_dev *pci = NULL;
+       enum { PI7C9X110 };
+       static const struct pci_device_id bridge_ids[] = {
+               { PCI_DEVICE(0x12d8, 0xe110), .driver_data = PI7C9X110 },
+               { }
+       };
+       struct pci_dev *bridge;
+       const struct pci_device_id *id;
        u32 tmp;
 
-       for (;;) {
-               /* If there is any Pericom PI7C9X110 PCI-E/PCI bridge ... */
-               pci = pci_get_device(0x12d8, 0xe110, pci);
-               if (!pci)
-                       break;
-               /*
-                * ... configure its secondary internal arbiter to park to
-                * the secondary port, instead of to the last master.
-                */
-               if (!pci_read_config_dword(pci, 0x40, &tmp)) {
-                       tmp |= 1;
-                       pci_write_config_dword(pci, 0x40, tmp);
-               }
-               /* Why?  Try asking C-Media. */
+       if (!pci->bus || !pci->bus->self)
+               return;
+       bridge = pci->bus->self;
+
+       id = pci_match_id(bridge_ids, bridge);
+       if (!id)
+               return;
+
+       switch (id->driver_data) {
+       case PI7C9X110: /* Pericom PI7C9X110 PCIe/PCI bridge */
+               pci_read_config_dword(bridge, 0x40, &tmp);
+               tmp |= 1;       /* park the PCI arbiter to the sound chip */
+               pci_write_config_dword(bridge, 0x40, tmp);
+               break;
        }
 }
 
@@ -613,7 +619,7 @@ int oxygen_pci_probe(struct pci_dev *pci, int index, char *id,
        snd_card_set_dev(card, &pci->dev);
        card->private_free = oxygen_card_free;
 
-       pci_bridge_magic();
+       configure_pcie_bridge(pci);
        oxygen_init(chip);
        chip->model.init(chip);