forked from mirrors/linux
		
	PCI: Workaround missing pci_set_master in pci drivers
Ben Herrenschmidt found that commit 928bea9648 ("PCI: Delay enabling
bridges until they're needed") breaks PCI in some powerpc environments.
The reason is that the PCIe port driver will call pci_enable_device() on
the bridge, so the device is enabled, but skips pci_set_master because
pcie_port_auto and no acpi on powerpc.
Because of that, pci_enable_bridge() later on (called as a result of the
child device driver doing pci_enable_device) will see the bridge as
already enabled and will not call pci_set_master() on it.
Fixed by add checking in pci_enable_bridge, and call pci_set_master
if driver skip that.
That will make the code more robot and wade off problem for missing
pci_set_master in drivers.
Reported-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Signed-off-by: Yinghai Lu <yinghai@kernel.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
			
			
This commit is contained in:
		
							parent
							
								
									aeebc26457
								
							
						
					
					
						commit
						f41f064cf4
					
				
					 1 changed files with 7 additions and 1 deletions
				
			
		| 
						 | 
					@ -1155,8 +1155,14 @@ static void pci_enable_bridge(struct pci_dev *dev)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	pci_enable_bridge(dev->bus->self);
 | 
						pci_enable_bridge(dev->bus->self);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (pci_is_enabled(dev))
 | 
						if (pci_is_enabled(dev)) {
 | 
				
			||||||
 | 
							if (!dev->is_busmaster) {
 | 
				
			||||||
 | 
								dev_warn(&dev->dev, "driver skip pci_set_master, fix it!\n");
 | 
				
			||||||
 | 
								pci_set_master(dev);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
		return;
 | 
							return;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	retval = pci_enable_device(dev);
 | 
						retval = pci_enable_device(dev);
 | 
				
			||||||
	if (retval)
 | 
						if (retval)
 | 
				
			||||||
		dev_err(&dev->dev, "Error enabling bridge (%d), continuing\n",
 | 
							dev_err(&dev->dev, "Error enabling bridge (%d), continuing\n",
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in a new issue