diff options
Diffstat (limited to 'sound/pci/oxygen/oxygen_lib.c')
| -rw-r--r-- | sound/pci/oxygen/oxygen_lib.c | 40 | 
1 files changed, 23 insertions, 17 deletions
diff --git a/sound/pci/oxygen/oxygen_lib.c b/sound/pci/oxygen/oxygen_lib.c index 7e93cf88443..d10cc6ee1a6 100644 --- a/sound/pci/oxygen/oxygen_lib.c +++ b/sound/pci/oxygen/oxygen_lib.c @@ -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);  |