Commit 670ba0c8 authored by Catalin Marinas's avatar Catalin Marinas Committed by Bjorn Helgaas

PCI: Add generic domain handling

The handling of PCI domains (or PCI segments in ACPI speak) is usually a
straightforward affair but its implementation is currently left to the
architectural code, with pci_domain_nr(b) querying the value of the domain
associated with bus b.

This patch introduces CONFIG_PCI_DOMAINS_GENERIC as an option that can be
selected if an architecture wants a simple implementation where the value
of the domain associated with a bus is stored in struct pci_bus.

The architectures that select CONFIG_PCI_DOMAINS_GENERIC will then have to
implement pci_bus_assign_domain_nr() as a way of setting the domain number
associated with a root bus.  All child buses except the root bus will
inherit the domain_nr value from their parent.
Signed-off-by: default avatarCatalin Marinas <Catalin.Marinas@arm.com>
[Renamed pci_set_domain_nr() to pci_bus_assign_domain_nr()]
Signed-off-by: default avatarLiviu Dudau <Liviu.Dudau@arm.com>
Signed-off-by: default avatarBjorn Helgaas <bhelgaas@google.com>
CC: Arnd Bergmann <arnd@arndb.de>
parent 0b0b0893
...@@ -485,7 +485,7 @@ void pci_read_bridge_bases(struct pci_bus *child) ...@@ -485,7 +485,7 @@ void pci_read_bridge_bases(struct pci_bus *child)
} }
} }
static struct pci_bus *pci_alloc_bus(void) static struct pci_bus *pci_alloc_bus(struct pci_bus *parent)
{ {
struct pci_bus *b; struct pci_bus *b;
...@@ -500,6 +500,10 @@ static struct pci_bus *pci_alloc_bus(void) ...@@ -500,6 +500,10 @@ static struct pci_bus *pci_alloc_bus(void)
INIT_LIST_HEAD(&b->resources); INIT_LIST_HEAD(&b->resources);
b->max_bus_speed = PCI_SPEED_UNKNOWN; b->max_bus_speed = PCI_SPEED_UNKNOWN;
b->cur_bus_speed = PCI_SPEED_UNKNOWN; b->cur_bus_speed = PCI_SPEED_UNKNOWN;
#ifdef CONFIG_PCI_DOMAINS_GENERIC
if (parent)
b->domain_nr = parent->domain_nr;
#endif
return b; return b;
} }
...@@ -671,7 +675,7 @@ static struct pci_bus *pci_alloc_child_bus(struct pci_bus *parent, ...@@ -671,7 +675,7 @@ static struct pci_bus *pci_alloc_child_bus(struct pci_bus *parent,
/* /*
* Allocate a new bus, and inherit stuff from the parent.. * Allocate a new bus, and inherit stuff from the parent..
*/ */
child = pci_alloc_bus(); child = pci_alloc_bus(parent);
if (!child) if (!child)
return NULL; return NULL;
...@@ -1761,13 +1765,14 @@ struct pci_bus *pci_create_root_bus(struct device *parent, int bus, ...@@ -1761,13 +1765,14 @@ struct pci_bus *pci_create_root_bus(struct device *parent, int bus,
char bus_addr[64]; char bus_addr[64];
char *fmt; char *fmt;
b = pci_alloc_bus(); b = pci_alloc_bus(NULL);
if (!b) if (!b)
return NULL; return NULL;
b->sysdata = sysdata; b->sysdata = sysdata;
b->ops = ops; b->ops = ops;
b->number = b->busn_res.start = bus; b->number = b->busn_res.start = bus;
pci_bus_assign_domain_nr(b, parent);
b2 = pci_find_bus(pci_domain_nr(b), bus); b2 = pci_find_bus(pci_domain_nr(b), bus);
if (b2) { if (b2) {
/* If we already got to this bus through a different bridge, ignore it */ /* If we already got to this bus through a different bridge, ignore it */
......
...@@ -456,6 +456,9 @@ struct pci_bus { ...@@ -456,6 +456,9 @@ struct pci_bus {
unsigned char primary; /* number of primary bridge */ unsigned char primary; /* number of primary bridge */
unsigned char max_bus_speed; /* enum pci_bus_speed */ unsigned char max_bus_speed; /* enum pci_bus_speed */
unsigned char cur_bus_speed; /* enum pci_bus_speed */ unsigned char cur_bus_speed; /* enum pci_bus_speed */
#ifdef CONFIG_PCI_DOMAINS_GENERIC
int domain_nr;
#endif
char name[48]; char name[48];
...@@ -1288,6 +1291,24 @@ static inline int pci_domain_nr(struct pci_bus *bus) { return 0; } ...@@ -1288,6 +1291,24 @@ static inline int pci_domain_nr(struct pci_bus *bus) { return 0; }
static inline int pci_proc_domain(struct pci_bus *bus) { return 0; } static inline int pci_proc_domain(struct pci_bus *bus) { return 0; }
#endif /* CONFIG_PCI_DOMAINS */ #endif /* CONFIG_PCI_DOMAINS */
/*
* Generic implementation for PCI domain support. If your
* architecture does not need custom management of PCI
* domains then this implementation will be used
*/
#ifdef CONFIG_PCI_DOMAINS_GENERIC
static inline int pci_domain_nr(struct pci_bus *bus)
{
return bus->domain_nr;
}
void pci_bus_assign_domain_nr(struct pci_bus *bus, struct device *parent);
#else
static inline void pci_bus_assign_domain_nr(struct pci_bus *bus,
struct device *parent)
{
}
#endif
/* some architectures require additional setup to direct VGA traffic */ /* some architectures require additional setup to direct VGA traffic */
typedef int (*arch_set_vga_state_t)(struct pci_dev *pdev, bool decode, typedef int (*arch_set_vga_state_t)(struct pci_dev *pdev, bool decode,
unsigned int command_bits, u32 flags); unsigned int command_bits, u32 flags);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment