@ -90,6 +90,27 @@ int pci_get_ff(enum pci_size_t size)
}
}
}
}
static void pci_dev_find_ofnode ( struct udevice * bus , phys_addr_t bdf ,
ofnode * rnode )
{
struct fdt_pci_addr addr ;
ofnode node ;
int ret ;
dev_for_each_subnode ( node , bus ) {
ret = ofnode_read_pci_addr ( node , FDT_PCI_SPACE_CONFIG , " reg " ,
& addr ) ;
if ( ret )
continue ;
if ( PCI_MASK_BUS ( addr . phys_hi ) ! = PCI_MASK_BUS ( bdf ) )
continue ;
* rnode = node ;
break ;
}
} ;
int pci_bus_find_devfn ( struct udevice * bus , pci_dev_t find_devfn ,
int pci_bus_find_devfn ( struct udevice * bus , pci_dev_t find_devfn ,
struct udevice * * devp )
struct udevice * * devp )
{
{
@ -641,6 +662,7 @@ static int pci_find_and_bind_driver(struct udevice *parent,
pci_dev_t bdf , struct udevice * * devp )
pci_dev_t bdf , struct udevice * * devp )
{
{
struct pci_driver_entry * start , * entry ;
struct pci_driver_entry * start , * entry ;
ofnode node = ofnode_null ( ) ;
const char * drv ;
const char * drv ;
int n_ents ;
int n_ents ;
int ret ;
int ret ;
@ -651,6 +673,10 @@ static int pci_find_and_bind_driver(struct udevice *parent,
debug ( " %s: Searching for driver: vendor=%x, device=%x \n " , __func__ ,
debug ( " %s: Searching for driver: vendor=%x, device=%x \n " , __func__ ,
find_id - > vendor , find_id - > device ) ;
find_id - > vendor , find_id - > device ) ;
/* Determine optional OF node */
pci_dev_find_ofnode ( parent , bdf , & node ) ;
start = ll_entry_start ( struct pci_driver_entry , pci_driver_entry ) ;
start = ll_entry_start ( struct pci_driver_entry , pci_driver_entry ) ;
n_ents = ll_entry_count ( struct pci_driver_entry , pci_driver_entry ) ;
n_ents = ll_entry_count ( struct pci_driver_entry , pci_driver_entry ) ;
for ( entry = start ; entry ! = start + n_ents ; entry + + ) {
for ( entry = start ; entry ! = start + n_ents ; entry + + ) {
@ -684,8 +710,8 @@ static int pci_find_and_bind_driver(struct udevice *parent,
* find another driver . For now this doesn ' t seem
* find another driver . For now this doesn ' t seem
* necesssary , so just bind the first match .
* necesssary , so just bind the first match .
*/
*/
ret = device_bind ( parent , drv , drv - > name , NULL , - 1 ,
ret = device_bind_ofnode ( parent , drv , drv - > name , NULL ,
& dev ) ;
node , & dev ) ;
if ( ret )
if ( ret )
goto error ;
goto error ;
debug ( " %s: Match found: %s \n " , __func__ , drv - > name ) ;
debug ( " %s: Match found: %s \n " , __func__ , drv - > name ) ;
@ -712,7 +738,7 @@ static int pci_find_and_bind_driver(struct udevice *parent,
return - ENOMEM ;
return - ENOMEM ;
drv = bridge ? " pci_bridge_drv " : " pci_generic_drv " ;
drv = bridge ? " pci_bridge_drv " : " pci_generic_drv " ;
ret = device_bind_driver ( parent , drv , str , devp ) ;
ret = device_bind_driver_to_node ( parent , drv , str , node , devp ) ;
if ( ret ) {
if ( ret ) {
debug ( " %s: Failed to bind generic driver: %d \n " , __func__ , ret ) ;
debug ( " %s: Failed to bind generic driver: %d \n " , __func__ , ret ) ;
free ( str ) ;
free ( str ) ;