Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit dc1544ea authored by Len Brown's avatar Len Brown
Browse files

Merge branch 'bjorn-pci-root-v4-2.6.35' into release

parents 6e320ec1 57283776
Loading
Loading
Loading
Loading
+4 −1
Original line number Original line Diff line number Diff line
@@ -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;
+4 −1
Original line number Original line Diff line number Diff line
@@ -224,8 +224,11 @@ get_current_resources(struct acpi_device *device, int busnum,
	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;
+40 −27
Original line number Original line Diff line number Diff line
@@ -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;
	}
	}
+1 −1
Original line number Original line Diff line number Diff line
@@ -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 */
+1 −2
Original line number Original line Diff line number Diff line
@@ -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);


/* --------------------------------------------------------------------------
/* --------------------------------------------------------------------------