Merge branch 'bjorn-pci-root-v4-2.6.35' into release
This commit is contained in:
commit
dc1544ea5d
5 changed files with 50 additions and 32 deletions
|
@ -335,8 +335,11 @@ pcibios_setup_root_windows(struct pci_bus *bus, struct pci_controller *ctrl)
|
||||||
}
|
}
|
||||||
|
|
||||||
struct pci_bus * __devinit
|
struct pci_bus * __devinit
|
||||||
pci_acpi_scan_root(struct acpi_device *device, int domain, int bus)
|
pci_acpi_scan_root(struct acpi_pci_root *root)
|
||||||
{
|
{
|
||||||
|
struct acpi_device *device = root->device;
|
||||||
|
int domain = root->segment;
|
||||||
|
int bus = root->secondary.start;
|
||||||
struct pci_controller *controller;
|
struct pci_controller *controller;
|
||||||
unsigned int windows = 0;
|
unsigned int windows = 0;
|
||||||
struct pci_bus *pbus;
|
struct pci_bus *pbus;
|
||||||
|
|
|
@ -224,8 +224,11 @@ res_alloc_fail:
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct pci_bus * __devinit pci_acpi_scan_root(struct acpi_device *device, int domain, int busnum)
|
struct pci_bus * __devinit pci_acpi_scan_root(struct acpi_pci_root *root)
|
||||||
{
|
{
|
||||||
|
struct acpi_device *device = root->device;
|
||||||
|
int domain = root->segment;
|
||||||
|
int busnum = root->secondary.start;
|
||||||
struct pci_bus *bus;
|
struct pci_bus *bus;
|
||||||
struct pci_sysdata *sd;
|
struct pci_sysdata *sd;
|
||||||
int node;
|
int node;
|
||||||
|
|
|
@ -120,7 +120,8 @@ acpi_handle acpi_get_pci_rootbridge_handle(unsigned int seg, unsigned int bus)
|
||||||
struct acpi_pci_root *root;
|
struct acpi_pci_root *root;
|
||||||
|
|
||||||
list_for_each_entry(root, &acpi_pci_roots, node)
|
list_for_each_entry(root, &acpi_pci_roots, node)
|
||||||
if ((root->segment == (u16) seg) && (root->bus_nr == (u16) bus))
|
if ((root->segment == (u16) seg) &&
|
||||||
|
(root->secondary.start == (u16) bus))
|
||||||
return root->device->handle;
|
return root->device->handle;
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
@ -154,7 +155,7 @@ EXPORT_SYMBOL_GPL(acpi_is_root_bridge);
|
||||||
static acpi_status
|
static acpi_status
|
||||||
get_root_bridge_busnr_callback(struct acpi_resource *resource, void *data)
|
get_root_bridge_busnr_callback(struct acpi_resource *resource, void *data)
|
||||||
{
|
{
|
||||||
int *busnr = data;
|
struct resource *res = data;
|
||||||
struct acpi_resource_address64 address;
|
struct acpi_resource_address64 address;
|
||||||
|
|
||||||
if (resource->type != ACPI_RESOURCE_TYPE_ADDRESS16 &&
|
if (resource->type != ACPI_RESOURCE_TYPE_ADDRESS16 &&
|
||||||
|
@ -164,28 +165,27 @@ get_root_bridge_busnr_callback(struct acpi_resource *resource, void *data)
|
||||||
|
|
||||||
acpi_resource_to_address64(resource, &address);
|
acpi_resource_to_address64(resource, &address);
|
||||||
if ((address.address_length > 0) &&
|
if ((address.address_length > 0) &&
|
||||||
(address.resource_type == ACPI_BUS_NUMBER_RANGE))
|
(address.resource_type == ACPI_BUS_NUMBER_RANGE)) {
|
||||||
*busnr = address.minimum;
|
res->start = address.minimum;
|
||||||
|
res->end = address.minimum + address.address_length - 1;
|
||||||
|
}
|
||||||
|
|
||||||
return AE_OK;
|
return AE_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static acpi_status try_get_root_bridge_busnr(acpi_handle handle,
|
static acpi_status try_get_root_bridge_busnr(acpi_handle handle,
|
||||||
unsigned long long *bus)
|
struct resource *res)
|
||||||
{
|
{
|
||||||
acpi_status status;
|
acpi_status status;
|
||||||
int busnum;
|
|
||||||
|
|
||||||
busnum = -1;
|
res->start = -1;
|
||||||
status =
|
status =
|
||||||
acpi_walk_resources(handle, METHOD_NAME__CRS,
|
acpi_walk_resources(handle, METHOD_NAME__CRS,
|
||||||
get_root_bridge_busnr_callback, &busnum);
|
get_root_bridge_busnr_callback, res);
|
||||||
if (ACPI_FAILURE(status))
|
if (ACPI_FAILURE(status))
|
||||||
return status;
|
return status;
|
||||||
/* Check if we really get a bus number from _CRS */
|
if (res->start == -1)
|
||||||
if (busnum == -1)
|
|
||||||
return AE_ERROR;
|
return AE_ERROR;
|
||||||
*bus = busnum;
|
|
||||||
return AE_OK;
|
return AE_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -429,34 +429,47 @@ static int __devinit acpi_pci_root_add(struct acpi_device *device)
|
||||||
struct acpi_device *child;
|
struct acpi_device *child;
|
||||||
u32 flags, base_flags;
|
u32 flags, base_flags;
|
||||||
|
|
||||||
|
root = kzalloc(sizeof(struct acpi_pci_root), GFP_KERNEL);
|
||||||
|
if (!root)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
segment = 0;
|
segment = 0;
|
||||||
status = acpi_evaluate_integer(device->handle, METHOD_NAME__SEG, NULL,
|
status = acpi_evaluate_integer(device->handle, METHOD_NAME__SEG, NULL,
|
||||||
&segment);
|
&segment);
|
||||||
if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) {
|
if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) {
|
||||||
printk(KERN_ERR PREFIX "can't evaluate _SEG\n");
|
printk(KERN_ERR PREFIX "can't evaluate _SEG\n");
|
||||||
return -ENODEV;
|
result = -ENODEV;
|
||||||
|
goto end;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check _CRS first, then _BBN. If no _BBN, default to zero. */
|
/* Check _CRS first, then _BBN. If no _BBN, default to zero. */
|
||||||
bus = 0;
|
root->secondary.flags = IORESOURCE_BUS;
|
||||||
status = try_get_root_bridge_busnr(device->handle, &bus);
|
status = try_get_root_bridge_busnr(device->handle, &root->secondary);
|
||||||
if (ACPI_FAILURE(status)) {
|
if (ACPI_FAILURE(status)) {
|
||||||
|
/*
|
||||||
|
* We need both the start and end of the downstream bus range
|
||||||
|
* to interpret _CBA (MMCONFIG base address), so it really is
|
||||||
|
* supposed to be in _CRS. If we don't find it there, all we
|
||||||
|
* can do is assume [_BBN-0xFF] or [0-0xFF].
|
||||||
|
*/
|
||||||
|
root->secondary.end = 0xFF;
|
||||||
|
printk(KERN_WARNING FW_BUG PREFIX
|
||||||
|
"no secondary bus range in _CRS\n");
|
||||||
status = acpi_evaluate_integer(device->handle, METHOD_NAME__BBN, NULL, &bus);
|
status = acpi_evaluate_integer(device->handle, METHOD_NAME__BBN, NULL, &bus);
|
||||||
if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) {
|
if (ACPI_SUCCESS(status))
|
||||||
printk(KERN_ERR PREFIX
|
root->secondary.start = bus;
|
||||||
"no bus number in _CRS and can't evaluate _BBN\n");
|
else if (status == AE_NOT_FOUND)
|
||||||
return -ENODEV;
|
root->secondary.start = 0;
|
||||||
|
else {
|
||||||
|
printk(KERN_ERR PREFIX "can't evaluate _BBN\n");
|
||||||
|
result = -ENODEV;
|
||||||
|
goto end;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
root = kzalloc(sizeof(struct acpi_pci_root), GFP_KERNEL);
|
|
||||||
if (!root)
|
|
||||||
return -ENOMEM;
|
|
||||||
|
|
||||||
INIT_LIST_HEAD(&root->node);
|
INIT_LIST_HEAD(&root->node);
|
||||||
root->device = device;
|
root->device = device;
|
||||||
root->segment = segment & 0xFFFF;
|
root->segment = segment & 0xFFFF;
|
||||||
root->bus_nr = bus & 0xFF;
|
|
||||||
strcpy(acpi_device_name(device), ACPI_PCI_ROOT_DEVICE_NAME);
|
strcpy(acpi_device_name(device), ACPI_PCI_ROOT_DEVICE_NAME);
|
||||||
strcpy(acpi_device_class(device), ACPI_PCI_ROOT_CLASS);
|
strcpy(acpi_device_class(device), ACPI_PCI_ROOT_CLASS);
|
||||||
device->driver_data = root;
|
device->driver_data = root;
|
||||||
|
@ -475,9 +488,9 @@ static int __devinit acpi_pci_root_add(struct acpi_device *device)
|
||||||
/* TBD: Locking */
|
/* TBD: Locking */
|
||||||
list_add_tail(&root->node, &acpi_pci_roots);
|
list_add_tail(&root->node, &acpi_pci_roots);
|
||||||
|
|
||||||
printk(KERN_INFO PREFIX "%s [%s] (%04x:%02x)\n",
|
printk(KERN_INFO PREFIX "%s [%s] (domain %04x %pR)\n",
|
||||||
acpi_device_name(device), acpi_device_bid(device),
|
acpi_device_name(device), acpi_device_bid(device),
|
||||||
root->segment, root->bus_nr);
|
root->segment, &root->secondary);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Scan the Root Bridge
|
* Scan the Root Bridge
|
||||||
|
@ -486,11 +499,11 @@ static int __devinit acpi_pci_root_add(struct acpi_device *device)
|
||||||
* PCI namespace does not get created until this call is made (and
|
* PCI namespace does not get created until this call is made (and
|
||||||
* thus the root bridge's pci_dev does not exist).
|
* thus the root bridge's pci_dev does not exist).
|
||||||
*/
|
*/
|
||||||
root->bus = pci_acpi_scan_root(device, segment, bus);
|
root->bus = pci_acpi_scan_root(root);
|
||||||
if (!root->bus) {
|
if (!root->bus) {
|
||||||
printk(KERN_ERR PREFIX
|
printk(KERN_ERR PREFIX
|
||||||
"Bus %04x:%02x not present in PCI namespace\n",
|
"Bus %04x:%02x not present in PCI namespace\n",
|
||||||
root->segment, root->bus_nr);
|
root->segment, (unsigned int)root->secondary.start);
|
||||||
result = -ENODEV;
|
result = -ENODEV;
|
||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
|
|
|
@ -373,7 +373,7 @@ struct acpi_pci_root {
|
||||||
struct acpi_pci_id id;
|
struct acpi_pci_id id;
|
||||||
struct pci_bus *bus;
|
struct pci_bus *bus;
|
||||||
u16 segment;
|
u16 segment;
|
||||||
u8 bus_nr;
|
struct resource secondary; /* downstream bus range */
|
||||||
|
|
||||||
u32 osc_support_set; /* _OSC state of support bits */
|
u32 osc_support_set; /* _OSC state of support bits */
|
||||||
u32 osc_control_set; /* _OSC state of control bits */
|
u32 osc_control_set; /* _OSC state of control bits */
|
||||||
|
|
|
@ -104,8 +104,7 @@ int acpi_pci_bind_root(struct acpi_device *device);
|
||||||
|
|
||||||
/* Arch-defined function to add a bus to the system */
|
/* Arch-defined function to add a bus to the system */
|
||||||
|
|
||||||
struct pci_bus *pci_acpi_scan_root(struct acpi_device *device, int domain,
|
struct pci_bus *pci_acpi_scan_root(struct acpi_pci_root *root);
|
||||||
int bus);
|
|
||||||
void pci_acpi_crs_quirks(void);
|
void pci_acpi_crs_quirks(void);
|
||||||
|
|
||||||
/* --------------------------------------------------------------------------
|
/* --------------------------------------------------------------------------
|
||||||
|
|
Loading…
Add table
Reference in a new issue