diff options
Diffstat (limited to 'drivers/acpi')
-rw-r--r-- | drivers/acpi/pci_root.c | 21 | ||||
-rw-r--r-- | drivers/acpi/scan.c | 33 |
2 files changed, 40 insertions, 14 deletions
diff --git a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c index 6fc204a52493..0da18bde6a16 100644 --- a/drivers/acpi/pci_root.c +++ b/drivers/acpi/pci_root.c @@ -729,7 +729,8 @@ next: } } -static void acpi_pci_root_remap_iospace(struct resource_entry *entry) +static void acpi_pci_root_remap_iospace(struct fwnode_handle *fwnode, + struct resource_entry *entry) { #ifdef PCI_IOBASE struct resource *res = entry->res; @@ -738,7 +739,7 @@ static void acpi_pci_root_remap_iospace(struct resource_entry *entry) resource_size_t length = resource_size(res); unsigned long port; - if (pci_register_io_range(cpu_addr, length)) + if (pci_register_io_range(fwnode, cpu_addr, length)) goto err; port = pci_address_to_pio(cpu_addr); @@ -780,7 +781,8 @@ int acpi_pci_probe_root_resources(struct acpi_pci_root_info *info) else { resource_list_for_each_entry_safe(entry, tmp, list) { if (entry->res->flags & IORESOURCE_IO) - acpi_pci_root_remap_iospace(entry); + acpi_pci_root_remap_iospace(&device->fwnode, + entry); if (entry->res->flags & IORESOURCE_DISABLED) resource_list_destroy_entry(entry); @@ -871,6 +873,7 @@ struct pci_bus *acpi_pci_root_create(struct acpi_pci_root *root, struct acpi_device *device = root->device; int node = acpi_get_node(device->handle); struct pci_bus *bus; + struct pci_host_bridge *host_bridge; info->root = root; info->bridge = device; @@ -895,9 +898,17 @@ struct pci_bus *acpi_pci_root_create(struct acpi_pci_root *root, if (!bus) goto out_release_info; + host_bridge = to_pci_host_bridge(bus->bridge); + if (!(root->osc_control_set & OSC_PCI_EXPRESS_NATIVE_HP_CONTROL)) + host_bridge->native_hotplug = 0; + if (!(root->osc_control_set & OSC_PCI_EXPRESS_AER_CONTROL)) + host_bridge->native_aer = 0; + if (!(root->osc_control_set & OSC_PCI_EXPRESS_PME_CONTROL)) + host_bridge->native_pme = 0; + pci_scan_child_bus(bus); - pci_set_host_bridge_release(to_pci_host_bridge(bus->bridge), - acpi_pci_root_release_info, info); + pci_set_host_bridge_release(host_bridge, acpi_pci_root_release_info, + info); if (node != NUMA_NO_NODE) dev_printk(KERN_DEBUG, &bus->dev, "on NUMA node %d\n", node); return bus; diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c index 490498eca0d3..cc234e6a6297 100644 --- a/drivers/acpi/scan.c +++ b/drivers/acpi/scan.c @@ -1525,11 +1525,25 @@ static int acpi_check_serial_bus_slave(struct acpi_resource *ares, void *data) return -1; } -static bool acpi_is_serial_bus_slave(struct acpi_device *device) +static bool acpi_is_indirect_io_slave(struct acpi_device *device) +{ + struct acpi_device *parent = device->parent; + const struct acpi_device_id indirect_io_hosts[] = { + {"HISI0191", 0}, + {} + }; + + return parent && !acpi_match_device_ids(parent, indirect_io_hosts); +} + +static bool acpi_device_enumeration_by_parent(struct acpi_device *device) { struct list_head resource_list; bool is_serial_bus_slave = false; + if (acpi_is_indirect_io_slave(device)) + return true; + /* Macs use device properties in lieu of _CRS resources */ if (x86_apple_machine && (fwnode_property_present(&device->fwnode, "spiSclkPeriod") || @@ -1561,7 +1575,8 @@ void acpi_init_device_object(struct acpi_device *device, acpi_handle handle, acpi_bus_get_flags(device); device->flags.match_driver = false; device->flags.initialized = true; - device->flags.serial_bus_slave = acpi_is_serial_bus_slave(device); + device->flags.enumeration_by_parent = + acpi_device_enumeration_by_parent(device); acpi_device_clear_enumerated(device); device_initialize(&device->dev); dev_set_uevent_suppress(&device->dev, true); @@ -1859,10 +1874,10 @@ static acpi_status acpi_bus_check_add(acpi_handle handle, u32 lvl_not_used, static void acpi_default_enumeration(struct acpi_device *device) { /* - * Do not enumerate SPI/I2C/UART slaves as they will be enumerated by - * their respective parents. + * Do not enumerate devices with enumeration_by_parent flag set as + * they will be enumerated by their respective parents. */ - if (!device->flags.serial_bus_slave) { + if (!device->flags.enumeration_by_parent) { acpi_create_platform_device(device, NULL); acpi_device_set_enumerated(device); } else { @@ -1959,7 +1974,7 @@ static void acpi_bus_attach(struct acpi_device *device) return; device->flags.match_driver = true; - if (ret > 0 && !device->flags.serial_bus_slave) { + if (ret > 0 && !device->flags.enumeration_by_parent) { acpi_device_set_enumerated(device); goto ok; } @@ -1968,10 +1983,10 @@ static void acpi_bus_attach(struct acpi_device *device) if (ret < 0) return; - if (!device->pnp.type.platform_id && !device->flags.serial_bus_slave) - acpi_device_set_enumerated(device); - else + if (device->pnp.type.platform_id || device->flags.enumeration_by_parent) acpi_default_enumeration(device); + else + acpi_device_set_enumerated(device); ok: list_for_each_entry(child, &device->children, node) |