2009-11-12 09:27:40 +03:00
# include <linux/init.h>
# include <linux/pci.h>
2010-02-10 12:20:11 +03:00
# include <linux/range.h>
2009-11-12 09:27:40 +03:00
# include "bus_numa.h"
2012-04-03 05:31:54 +04:00
LIST_HEAD ( pci_root_infos ) ;
2009-11-12 09:27:40 +03:00
2012-04-03 05:31:54 +04:00
static struct pci_root_info * x86_find_pci_root_info ( int bus )
2009-11-12 09:27:40 +03:00
{
struct pci_root_info * info ;
2012-04-03 05:31:54 +04:00
if ( list_empty ( & pci_root_infos ) )
return NULL ;
2009-11-12 09:27:40 +03:00
2012-04-03 05:31:54 +04:00
list_for_each_entry ( info , & pci_root_infos , list )
if ( info - > bus_min = = bus )
return info ;
return NULL ;
}
2009-11-12 09:27:40 +03:00
2012-04-03 05:31:54 +04:00
void x86_pci_root_bus_resources ( int bus , struct list_head * resources )
{
struct pci_root_info * info = x86_find_pci_root_info ( bus ) ;
struct pci_root_res * root_res ;
if ( ! info )
2011-10-29 02:28:14 +04:00
goto default_resources ;
2009-11-12 09:27:40 +03:00
2011-10-29 02:28:14 +04:00
printk ( KERN_DEBUG " PCI: root bus %02x: hardware-probed resources \n " ,
bus ) ;
2009-11-12 09:27:40 +03:00
2012-04-03 05:31:54 +04:00
list_for_each_entry ( root_res , & info - > resources , list ) {
2009-11-12 09:27:40 +03:00
struct resource * res ;
struct resource * root ;
2012-04-03 05:31:54 +04:00
res = & root_res - > res ;
2011-10-29 02:28:14 +04:00
pci_add_resource ( resources , res ) ;
2009-11-12 09:27:40 +03:00
if ( res - > flags & IORESOURCE_IO )
root = & ioport_resource ;
else
root = & iomem_resource ;
insert_resource ( root , res ) ;
}
2011-10-29 02:28:14 +04:00
return ;
default_resources :
/*
* We don ' t have any host bridge aperture information from the
* " native host bridge drivers, " e . g . , amd_bus or broadcom_bus ,
* so fall back to the defaults historically used by pci_create_bus ( ) .
*/
printk ( KERN_DEBUG " PCI: root bus %02x: using default resources \n " , bus ) ;
pci_add_resource ( resources , & ioport_resource ) ;
pci_add_resource ( resources , & iomem_resource ) ;
2009-11-12 09:27:40 +03:00
}
2012-04-03 05:31:54 +04:00
struct pci_root_info __init * alloc_pci_root_info ( int bus_min , int bus_max ,
int node , int link )
{
struct pci_root_info * info ;
info = kzalloc ( sizeof ( * info ) , GFP_KERNEL ) ;
if ( ! info )
return info ;
INIT_LIST_HEAD ( & info - > resources ) ;
info - > bus_min = bus_min ;
info - > bus_max = bus_max ;
info - > node = node ;
info - > link = link ;
list_add_tail ( & info - > list , & pci_root_infos ) ;
return info ;
}
2010-02-10 12:20:08 +03:00
void __devinit update_res ( struct pci_root_info * info , resource_size_t start ,
resource_size_t end , unsigned long flags , int merge )
2009-11-12 09:27:40 +03:00
{
struct resource * res ;
2012-04-03 05:31:54 +04:00
struct pci_root_res * root_res ;
2009-11-12 09:27:40 +03:00
if ( start > end )
return ;
2010-02-10 12:20:11 +03:00
if ( start = = MAX_RESOURCE )
return ;
2009-11-12 09:27:40 +03:00
if ( ! merge )
goto addit ;
/* try to merge it with old one */
2012-04-03 05:31:54 +04:00
list_for_each_entry ( root_res , & info - > resources , list ) {
2010-02-10 12:20:08 +03:00
resource_size_t final_start , final_end ;
resource_size_t common_start , common_end ;
2009-11-12 09:27:40 +03:00
2012-04-03 05:31:54 +04:00
res = & root_res - > res ;
2009-11-12 09:27:40 +03:00
if ( res - > flags ! = flags )
continue ;
2010-02-10 12:20:08 +03:00
common_start = max ( res - > start , start ) ;
common_end = min ( res - > end , end ) ;
2009-11-12 09:27:40 +03:00
if ( common_start > common_end + 1 )
continue ;
2010-02-10 12:20:08 +03:00
final_start = min ( res - > start , start ) ;
final_end = max ( res - > end , end ) ;
2009-11-12 09:27:40 +03:00
res - > start = final_start ;
res - > end = final_end ;
return ;
}
addit :
/* need to add that */
2012-04-03 05:31:54 +04:00
root_res = kzalloc ( sizeof ( * root_res ) , GFP_KERNEL ) ;
if ( ! root_res )
2009-11-12 09:27:40 +03:00
return ;
2012-04-03 05:31:54 +04:00
res = & root_res - > res ;
2009-11-12 09:27:40 +03:00
res - > name = info - > name ;
res - > flags = flags ;
res - > start = start ;
res - > end = end ;
2012-04-03 05:31:54 +04:00
list_add_tail ( & root_res - > list , & info - > resources ) ;
2009-11-12 09:27:40 +03:00
}