Lines Matching +full:max +full:- +full:functions
1 // SPDX-License-Identifier: GPL-2.0+
3 * ACPI PCI HotPlug glue functions to ACPI CA subsystem
5 * Copyright (C) 2002,2003 Takayoshi Kochi (t-kochi@bq.jp.nec.com)
6 * Copyright (C) 2002 Hiroshi Aono (h-aono@ap.jp.nec.com)
8 * Copyright (C) 2003-2005 Matthew Wilcox (willy@infradead.org)
9 * Copyright (C) 2003-2005 Hewlett Packard
21 * - The one in acpiphp_bridge has its refcount elevated by pci_get_slot()
24 * - When a P2P bridge is present, we elevate the refcount on the subordinate
35 #include <linux/pci-acpi.h>
54 * acpiphp_init_context - Create hotplug context and grab a reference to it.
67 context->refcount = 1; in acpiphp_init_context()
68 context->hp.notify = acpiphp_hotplug_notify; in acpiphp_init_context()
69 context->hp.fixup = acpiphp_post_dock_fixup; in acpiphp_init_context()
70 acpi_set_hp_context(adev, &context->hp); in acpiphp_init_context()
75 * acpiphp_get_context - Get hotplug context and grab a reference to it.
84 if (!adev->hp) in acpiphp_get_context()
87 context = to_acpiphp_context(adev->hp); in acpiphp_get_context()
88 context->refcount++; in acpiphp_get_context()
93 * acpiphp_put_context - Drop a reference to ACPI hotplug context.
102 if (--context->refcount) in acpiphp_put_context()
105 WARN_ON(context->bridge); in acpiphp_put_context()
106 context->hp.self->hp = NULL; in acpiphp_put_context()
112 kref_get(&bridge->ref); in get_bridge()
117 kref_put(&bridge->ref, free_bridge); in put_bridge()
130 if (context->func.parent->is_going_away) { in acpiphp_grab_context()
136 get_bridge(context->func.parent); in acpiphp_grab_context()
146 put_bridge(context->func.parent); in acpiphp_let_context_go()
160 list_for_each_entry_safe(slot, next, &bridge->slots, node) { in free_bridge()
161 list_for_each_entry_safe(func, tmp, &slot->funcs, sibling) in free_bridge()
167 context = bridge->context; in free_bridge()
171 put_bridge(context->func.parent); in free_bridge()
172 context->bridge = NULL; in free_bridge()
176 put_device(&bridge->pci_bus->dev); in free_bridge()
177 pci_dev_put(bridge->pci_dev); in free_bridge()
184 * acpiphp_post_dock_fixup - Post-dock fixups for PCI devices.
187 * TBD - figure out a way to only call fixups for systems that require them.
198 bus = context->func.slot->bus; in acpiphp_post_dock_fixup()
199 if (!bus->self) in acpiphp_post_dock_fixup()
205 pci_read_config_dword(bus->self, PCI_PRIMARY_BUS, &buses); in acpiphp_post_dock_fixup()
207 if (((buses >> 8) & 0xff) != bus->busn_res.start) { in acpiphp_post_dock_fixup()
209 | ((unsigned int)(bus->primary) << 0) in acpiphp_post_dock_fixup()
210 | ((unsigned int)(bus->busn_res.start) << 8) in acpiphp_post_dock_fixup()
211 | ((unsigned int)(bus->busn_res.end) << 16); in acpiphp_post_dock_fixup()
212 pci_write_config_dword(bus->self, PCI_PRIMARY_BUS, buses); in acpiphp_post_dock_fixup()
220 * acpiphp_add_context - Add ACPIPHP context to an ACPI device object.
237 struct pci_bus *pbus = bridge->pci_bus; in acpiphp_add_context()
238 struct pci_dev *pdev = bridge->pci_dev; in acpiphp_add_context()
262 newfunc = &context->func; in acpiphp_add_context()
263 newfunc->function = function; in acpiphp_add_context()
264 newfunc->parent = bridge; in acpiphp_add_context()
272 newfunc->flags = FUNC_HAS_EJ0; in acpiphp_add_context()
275 newfunc->flags |= FUNC_HAS_STA; in acpiphp_add_context()
278 list_for_each_entry(slot, &bridge->slots, node) in acpiphp_add_context()
279 if (slot->device == device) in acpiphp_add_context()
290 slot->bus = bridge->pci_bus; in acpiphp_add_context()
291 slot->device = device; in acpiphp_add_context()
292 INIT_LIST_HEAD(&slot->funcs); in acpiphp_add_context()
294 list_add_tail(&slot->node, &bridge->slots); in acpiphp_add_context()
297 * Expose slots to user space for functions that have _EJ0 or _RMV or in acpiphp_add_context()
308 bridge->nr_slots++; in acpiphp_add_context()
311 sun = bridge->nr_slots; in acpiphp_add_context()
314 sun, pci_domain_nr(pbus), pbus->number, device); in acpiphp_add_context()
318 slot->slot = NULL; in acpiphp_add_context()
319 bridge->nr_slots--; in acpiphp_add_context()
320 if (retval == -EBUSY) in acpiphp_add_context()
329 newfunc->slot = slot; in acpiphp_add_context()
330 list_add_tail(&newfunc->sibling, &slot->funcs); in acpiphp_add_context()
334 slot->flags |= SLOT_ENABLED; in acpiphp_add_context()
344 list_for_each_entry(slot, &bridge->slots, node) { in cleanup_bridge()
345 list_for_each_entry(func, &slot->funcs, sibling) { in cleanup_bridge()
349 adev->hp->notify = NULL; in cleanup_bridge()
350 adev->hp->fixup = NULL; in cleanup_bridge()
353 slot->flags |= SLOT_IS_GOING_AWAY; in cleanup_bridge()
354 if (slot->slot) in cleanup_bridge()
359 list_del(&bridge->list); in cleanup_bridge()
363 bridge->is_going_away = true; in cleanup_bridge()
368 * acpiphp_max_busnr - return the highest reserved bus number under the given bus.
374 unsigned char max, n; in acpiphp_max_busnr() local
379 * that is equivalent to the bus->subordinate in acpiphp_max_busnr()
381 * bus->subordinate value because it could have in acpiphp_max_busnr()
384 max = bus->busn_res.start; in acpiphp_max_busnr()
386 list_for_each_entry(tmp, &bus->children, node) { in acpiphp_max_busnr()
388 if (n > max) in acpiphp_max_busnr()
389 max = n; in acpiphp_max_busnr()
391 return max; in acpiphp_max_busnr()
398 list_for_each_entry(func, &slot->funcs, sibling) { in acpiphp_set_acpi_region()
411 if (dev->is_hotplug_bridge) in check_hotplug_bridge()
414 list_for_each_entry(func, &slot->funcs, sibling) { in check_hotplug_bridge()
415 if (PCI_FUNC(dev->devfn) == func->function) { in check_hotplug_bridge()
416 dev->is_hotplug_bridge = 1; in check_hotplug_bridge()
426 list_for_each_entry(func, &slot->funcs, sibling) { in acpiphp_rescan_slot()
429 acpi_bus_scan(adev->handle); in acpiphp_rescan_slot()
433 return pci_scan_slot(slot->bus, PCI_DEVFN(slot->device, 0)); in acpiphp_rescan_slot()
438 struct pci_bus *bus = bridge->subordinate; in acpiphp_native_scan_bridge()
440 int max; in acpiphp_native_scan_bridge() local
445 max = bus->busn_res.start; in acpiphp_native_scan_bridge()
446 /* Scan already configured non-hotplug bridges */ in acpiphp_native_scan_bridge()
449 max = pci_scan_bridge(bus, dev, max, 0); in acpiphp_native_scan_bridge()
452 /* Scan non-hotplug bridges that need to be reconfigured */ in acpiphp_native_scan_bridge()
457 max = pci_scan_bridge(bus, dev, max, 1); in acpiphp_native_scan_bridge()
458 if (dev->subordinate) { in acpiphp_native_scan_bridge()
459 pcibios_resource_survey_bus(dev->subordinate); in acpiphp_native_scan_bridge()
460 pci_bus_size_bridges(dev->subordinate); in acpiphp_native_scan_bridge()
461 pci_bus_assign_resources(dev->subordinate); in acpiphp_native_scan_bridge()
467 * enable_slot - enable, configure a slot
477 struct pci_bus *bus = slot->bus; in enable_slot()
480 if (bridge && bus->self && hotplug_is_native(bus->self)) { in enable_slot()
485 * non-hotplug bridges to bring in additional devices such in enable_slot()
489 if (PCI_SLOT(dev->devfn) == slot->device) in enable_slot()
494 int max, pass; in enable_slot() local
497 max = acpiphp_max_busnr(bus); in enable_slot()
500 if (PCI_SLOT(dev->devfn) != slot->device) in enable_slot()
503 max = pci_scan_bridge(bus, dev, max, pass); in enable_slot()
504 if (pass && dev->subordinate) { in enable_slot()
506 pcibios_resource_survey_bus(dev->subordinate); in enable_slot()
507 __pci_bus_size_bridges(dev->subordinate, in enable_slot()
519 list_for_each_entry(dev, &bus->devices, bus_list) { in enable_slot()
522 dev->current_state = PCI_D0; in enable_slot()
527 slot->flags |= SLOT_ENABLED; in enable_slot()
528 list_for_each_entry(func, &slot->funcs, sibling) { in enable_slot()
529 dev = pci_get_slot(bus, PCI_DEVFN(slot->device, in enable_slot()
530 func->function)); in enable_slot()
534 slot->flags &= ~SLOT_ENABLED; in enable_slot()
542 * disable_slot - disable a slot
547 struct pci_bus *bus = slot->bus; in disable_slot()
552 * enable_slot() enumerates all functions in this device via in disable_slot()
554 * methods (_EJ0, etc.) or not. Therefore, we remove all functions in disable_slot()
557 list_for_each_entry_safe_reverse(dev, prev, &bus->devices, bus_list) in disable_slot()
558 if (PCI_SLOT(dev->devfn) == slot->device) in disable_slot()
561 list_for_each_entry(func, &slot->funcs, sibling) in disable_slot()
564 slot->flags &= ~SLOT_ENABLED; in disable_slot()
569 struct pci_bus *bus = slot->bus; in slot_no_hotplug()
572 list_for_each_entry(dev, &bus->devices, bus_list) { in slot_no_hotplug()
573 if (PCI_SLOT(dev->devfn) == slot->device && dev->ignore_hotplug) in slot_no_hotplug()
580 * get_slot_status - get ACPI slot status
584 * returned non-zero status, return it.
586 * If a slot doesn't have _STA and if any one of its functions'
597 list_for_each_entry(func, &slot->funcs, sibling) { in get_slot_status()
598 if (func->flags & FUNC_HAS_STA) { in get_slot_status()
606 if (pci_bus_read_dev_vendor_id(slot->bus, in get_slot_status()
607 PCI_DEVFN(slot->device, func->function), in get_slot_status()
621 if (pci_bus_read_dev_vendor_id(slot->bus, in get_slot_status()
622 PCI_DEVFN(slot->device, 0), &dvid, 0)) { in get_slot_status()
642 * trim_stale_devices - remove PCI devices that are not responding.
647 struct acpi_device *adev = ACPI_COMPANION(&dev->dev); in trim_stale_devices()
648 struct pci_bus *bus = dev->subordinate; in trim_stale_devices()
649 bool alive = dev->ignore_hotplug; in trim_stale_devices()
655 status = acpi_evaluate_integer(adev->handle, "_STA", NULL, &sta); in trim_stale_devices()
664 pci_walk_bus(dev->subordinate, pci_dev_set_disconnected, in trim_stale_devices()
674 pm_runtime_get_sync(&dev->dev); in trim_stale_devices()
675 list_for_each_entry_safe_reverse(child, tmp, &bus->devices, bus_list) in trim_stale_devices()
678 pm_runtime_put(&dev->dev); in trim_stale_devices()
683 * acpiphp_check_bridge - re-enumerate devices
684 * @bridge: where to begin re-enumeration
694 if (bridge->is_going_away) in acpiphp_check_bridge()
697 if (bridge->pci_dev) in acpiphp_check_bridge()
698 pm_runtime_get_sync(&bridge->pci_dev->dev); in acpiphp_check_bridge()
700 list_for_each_entry(slot, &bridge->slots, node) { in acpiphp_check_bridge()
701 struct pci_bus *bus = slot->bus; in acpiphp_check_bridge()
709 &bus->devices, bus_list) in acpiphp_check_bridge()
710 if (PCI_SLOT(dev->devfn) == slot->device) in acpiphp_check_bridge()
713 /* configure all functions */ in acpiphp_check_bridge()
720 if (bridge->pci_dev) in acpiphp_check_bridge()
721 pm_runtime_put(&bridge->pci_dev->dev); in acpiphp_check_bridge()
726 * arch specific code to fix-up the bus
734 list_for_each_entry_safe_reverse(dev, tmp, &bus->devices, bus_list) { in acpiphp_sanitize_bus()
736 struct resource *res = &dev->resource[i]; in acpiphp_sanitize_bus()
737 if ((res->flags & type_mask) && !res->start && in acpiphp_sanitize_bus()
738 res->end) { in acpiphp_sanitize_bus()
757 if (adev->hp) { in acpiphp_check_host_bridge()
758 bridge = to_acpiphp_root_context(adev->hp)->root_bridge; in acpiphp_check_host_bridge()
777 acpi_handle handle = context->hp.self->handle; in hotplug_event()
778 struct acpiphp_func *func = &context->func; in hotplug_event()
779 struct acpiphp_slot *slot = func->slot; in hotplug_event()
783 bridge = context->bridge; in hotplug_event()
793 /* bus re-enumerate */ in hotplug_event()
797 else if (!(slot->flags & SLOT_IS_GOING_AWAY)) in hotplug_event()
807 } else if (!(slot->flags & SLOT_IS_GOING_AWAY)) { in hotplug_event()
813 acpiphp_check_bridge(func->parent); in hotplug_event()
835 return -ENODATA; in acpiphp_hotplug_notify()
843 * acpiphp_enumerate_slots - Enumerate PCI slots for a given bus.
846 * A "slot" is an object associated with a PCI device number. All functions
859 adev = ACPI_COMPANION(bus->bridge); in acpiphp_enumerate_slots()
863 handle = adev->handle; in acpiphp_enumerate_slots()
868 INIT_LIST_HEAD(&bridge->slots); in acpiphp_enumerate_slots()
869 kref_init(&bridge->ref); in acpiphp_enumerate_slots()
870 bridge->pci_dev = pci_dev_get(bus->self); in acpiphp_enumerate_slots()
871 bridge->pci_bus = bus; in acpiphp_enumerate_slots()
878 get_device(&bus->dev); in acpiphp_enumerate_slots()
881 if (pci_is_root_bus(bridge->pci_bus)) { in acpiphp_enumerate_slots()
888 root_context->root_bridge = bridge; in acpiphp_enumerate_slots()
889 acpi_set_hp_context(adev, &root_context->hp); in acpiphp_enumerate_slots()
903 bridge->context = context; in acpiphp_enumerate_slots()
904 context->bridge = bridge; in acpiphp_enumerate_slots()
906 get_bridge(context->func.parent); in acpiphp_enumerate_slots()
912 list_add(&bridge->list, &bridge_list); in acpiphp_enumerate_slots()
927 put_device(&bus->dev); in acpiphp_enumerate_slots()
928 pci_dev_put(bridge->pci_dev); in acpiphp_enumerate_slots()
934 if (pci_is_root_bus(bridge->pci_bus)) { in acpiphp_drop_bridge()
939 adev = ACPI_COMPANION(bridge->pci_bus->bridge); in acpiphp_drop_bridge()
940 root_context = to_acpiphp_root_context(adev->hp); in acpiphp_drop_bridge()
941 adev->hp = NULL; in acpiphp_drop_bridge()
950 * acpiphp_remove_slots - Remove slot objects associated with a given bus.
962 if (bridge->pci_bus == bus) { in acpiphp_remove_slots()
972 * acpiphp_enable_slot - power on slot
979 if (slot->flags & SLOT_IS_GOING_AWAY) { in acpiphp_enable_slot()
981 return -ENODEV; in acpiphp_enable_slot()
984 /* configure all functions */ in acpiphp_enable_slot()
985 if (!(slot->flags & SLOT_ENABLED)) in acpiphp_enable_slot()
993 * acpiphp_disable_and_eject_slot - power off and eject slot
1000 if (slot->flags & SLOT_IS_GOING_AWAY) in acpiphp_disable_and_eject_slot()
1001 return -ENODEV; in acpiphp_disable_and_eject_slot()
1003 /* unconfigure all functions */ in acpiphp_disable_and_eject_slot()
1006 list_for_each_entry(func, &slot->funcs, sibling) in acpiphp_disable_and_eject_slot()
1007 if (func->flags & FUNC_HAS_EJ0) { in acpiphp_disable_and_eject_slot()
1041 return (slot->flags & SLOT_ENABLED); in acpiphp_get_power_status()