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()
422 list_for_each_entry(func, &slot->funcs, sibling) { in check_hotplug_bridge()
423 if (PCI_FUNC(dev->devfn) == func->function) { in check_hotplug_bridge()
424 dev->is_hotplug_bridge = 1; in check_hotplug_bridge()
434 list_for_each_entry(func, &slot->funcs, sibling) { in acpiphp_rescan_slot()
437 acpi_bus_scan(adev->handle); in acpiphp_rescan_slot()
441 return pci_scan_slot(slot->bus, PCI_DEVFN(slot->device, 0)); in acpiphp_rescan_slot()
446 struct pci_bus *bus = bridge->subordinate; in acpiphp_native_scan_bridge()
448 int max; in acpiphp_native_scan_bridge() local
453 max = bus->busn_res.start; in acpiphp_native_scan_bridge()
454 /* Scan already configured non-hotplug bridges */ in acpiphp_native_scan_bridge()
457 max = pci_scan_bridge(bus, dev, max, 0); in acpiphp_native_scan_bridge()
460 /* Scan non-hotplug bridges that need to be reconfigured */ in acpiphp_native_scan_bridge()
465 max = pci_scan_bridge(bus, dev, max, 1); in acpiphp_native_scan_bridge()
466 if (dev->subordinate) { in acpiphp_native_scan_bridge()
467 pcibios_resource_survey_bus(dev->subordinate); in acpiphp_native_scan_bridge()
468 pci_bus_size_bridges(dev->subordinate); in acpiphp_native_scan_bridge()
469 pci_bus_assign_resources(dev->subordinate); in acpiphp_native_scan_bridge()
475 * enable_slot - enable, configure a slot
485 struct pci_bus *bus = slot->bus; in enable_slot()
488 if (bridge && bus->self && hotplug_is_native(bus->self)) { in enable_slot()
493 * non-hotplug bridges to bring in additional devices such in enable_slot()
497 if (PCI_SLOT(dev->devfn) == slot->device) in enable_slot()
502 int max, pass; in enable_slot() local
505 max = acpiphp_max_busnr(bus); in enable_slot()
508 if (PCI_SLOT(dev->devfn) != slot->device) in enable_slot()
511 max = pci_scan_bridge(bus, dev, max, pass); in enable_slot()
512 if (pass && dev->subordinate) { in enable_slot()
514 pcibios_resource_survey_bus(dev->subordinate); in enable_slot()
515 __pci_bus_size_bridges(dev->subordinate, in enable_slot()
527 list_for_each_entry(dev, &bus->devices, bus_list) { in enable_slot()
530 dev->current_state = PCI_D0; in enable_slot()
535 slot->flags |= SLOT_ENABLED; in enable_slot()
536 list_for_each_entry(func, &slot->funcs, sibling) { in enable_slot()
537 dev = pci_get_slot(bus, PCI_DEVFN(slot->device, in enable_slot()
538 func->function)); in enable_slot()
542 slot->flags &= ~SLOT_ENABLED; in enable_slot()
550 * disable_slot - disable a slot
555 struct pci_bus *bus = slot->bus; in disable_slot()
560 * enable_slot() enumerates all functions in this device via in disable_slot()
562 * methods (_EJ0, etc.) or not. Therefore, we remove all functions in disable_slot()
565 list_for_each_entry_safe_reverse(dev, prev, &bus->devices, bus_list) in disable_slot()
566 if (PCI_SLOT(dev->devfn) == slot->device) in disable_slot()
569 list_for_each_entry(func, &slot->funcs, sibling) in disable_slot()
572 slot->flags &= ~SLOT_ENABLED; in disable_slot()
577 struct pci_bus *bus = slot->bus; in slot_no_hotplug()
580 list_for_each_entry(dev, &bus->devices, bus_list) { in slot_no_hotplug()
581 if (PCI_SLOT(dev->devfn) == slot->device && dev->ignore_hotplug) in slot_no_hotplug()
588 * get_slot_status - get ACPI slot status
592 * returned non-zero status, return it.
594 * If a slot doesn't have _STA and if any one of its functions'
605 list_for_each_entry(func, &slot->funcs, sibling) { in get_slot_status()
606 if (func->flags & FUNC_HAS_STA) { in get_slot_status()
614 if (pci_bus_read_dev_vendor_id(slot->bus, in get_slot_status()
615 PCI_DEVFN(slot->device, func->function), in get_slot_status()
629 if (pci_bus_read_dev_vendor_id(slot->bus, in get_slot_status()
630 PCI_DEVFN(slot->device, 0), &dvid, 0)) { in get_slot_status()
650 * trim_stale_devices - remove PCI devices that are not responding.
655 struct acpi_device *adev = ACPI_COMPANION(&dev->dev); in trim_stale_devices()
656 struct pci_bus *bus = dev->subordinate; in trim_stale_devices()
657 bool alive = dev->ignore_hotplug; in trim_stale_devices()
663 status = acpi_evaluate_integer(adev->handle, "_STA", NULL, &sta); in trim_stale_devices()
672 pci_walk_bus(dev->subordinate, pci_dev_set_disconnected, in trim_stale_devices()
682 pm_runtime_get_sync(&dev->dev); in trim_stale_devices()
683 list_for_each_entry_safe_reverse(child, tmp, &bus->devices, bus_list) in trim_stale_devices()
686 pm_runtime_put(&dev->dev); in trim_stale_devices()
691 * acpiphp_check_bridge - re-enumerate devices
692 * @bridge: where to begin re-enumeration
702 if (bridge->is_going_away) in acpiphp_check_bridge()
705 if (bridge->pci_dev) in acpiphp_check_bridge()
706 pm_runtime_get_sync(&bridge->pci_dev->dev); in acpiphp_check_bridge()
708 list_for_each_entry(slot, &bridge->slots, node) { in acpiphp_check_bridge()
709 struct pci_bus *bus = slot->bus; in acpiphp_check_bridge()
717 &bus->devices, bus_list) in acpiphp_check_bridge()
718 if (PCI_SLOT(dev->devfn) == slot->device) in acpiphp_check_bridge()
721 /* configure all functions */ in acpiphp_check_bridge()
728 if (bridge->pci_dev) in acpiphp_check_bridge()
729 pm_runtime_put(&bridge->pci_dev->dev); in acpiphp_check_bridge()
734 * arch specific code to fix-up the bus
742 list_for_each_entry_safe_reverse(dev, tmp, &bus->devices, bus_list) { in acpiphp_sanitize_bus()
744 struct resource *res = &dev->resource[i]; in acpiphp_sanitize_bus()
745 if ((res->flags & type_mask) && !res->start && in acpiphp_sanitize_bus()
746 res->end) { in acpiphp_sanitize_bus()
765 if (adev->hp) { in acpiphp_check_host_bridge()
766 bridge = to_acpiphp_root_context(adev->hp)->root_bridge; in acpiphp_check_host_bridge()
785 acpi_handle handle = context->hp.self->handle; in hotplug_event()
786 struct acpiphp_func *func = &context->func; in hotplug_event()
787 struct acpiphp_slot *slot = func->slot; in hotplug_event()
791 bridge = context->bridge; in hotplug_event()
801 /* bus re-enumerate */ in hotplug_event()
805 else if (!(slot->flags & SLOT_IS_GOING_AWAY)) in hotplug_event()
815 } else if (!(slot->flags & SLOT_IS_GOING_AWAY)) { in hotplug_event()
821 acpiphp_check_bridge(func->parent); in hotplug_event()
843 return -ENODATA; in acpiphp_hotplug_notify()
851 * acpiphp_enumerate_slots - Enumerate PCI slots for a given bus.
854 * A "slot" is an object associated with a PCI device number. All functions
867 adev = ACPI_COMPANION(bus->bridge); in acpiphp_enumerate_slots()
871 handle = adev->handle; in acpiphp_enumerate_slots()
876 INIT_LIST_HEAD(&bridge->slots); in acpiphp_enumerate_slots()
877 kref_init(&bridge->ref); in acpiphp_enumerate_slots()
878 bridge->pci_dev = pci_dev_get(bus->self); in acpiphp_enumerate_slots()
879 bridge->pci_bus = bus; in acpiphp_enumerate_slots()
886 get_device(&bus->dev); in acpiphp_enumerate_slots()
889 if (pci_is_root_bus(bridge->pci_bus)) { in acpiphp_enumerate_slots()
896 root_context->root_bridge = bridge; in acpiphp_enumerate_slots()
897 acpi_set_hp_context(adev, &root_context->hp); in acpiphp_enumerate_slots()
911 bridge->context = context; in acpiphp_enumerate_slots()
912 context->bridge = bridge; in acpiphp_enumerate_slots()
914 get_bridge(context->func.parent); in acpiphp_enumerate_slots()
920 list_add(&bridge->list, &bridge_list); in acpiphp_enumerate_slots()
935 put_device(&bus->dev); in acpiphp_enumerate_slots()
936 pci_dev_put(bridge->pci_dev); in acpiphp_enumerate_slots()
942 if (pci_is_root_bus(bridge->pci_bus)) { in acpiphp_drop_bridge()
947 adev = ACPI_COMPANION(bridge->pci_bus->bridge); in acpiphp_drop_bridge()
948 root_context = to_acpiphp_root_context(adev->hp); in acpiphp_drop_bridge()
949 adev->hp = NULL; in acpiphp_drop_bridge()
958 * acpiphp_remove_slots - Remove slot objects associated with a given bus.
970 if (bridge->pci_bus == bus) { in acpiphp_remove_slots()
980 * acpiphp_enable_slot - power on slot
987 if (slot->flags & SLOT_IS_GOING_AWAY) { in acpiphp_enable_slot()
989 return -ENODEV; in acpiphp_enable_slot()
992 /* configure all functions */ in acpiphp_enable_slot()
993 if (!(slot->flags & SLOT_ENABLED)) in acpiphp_enable_slot()
1001 * acpiphp_disable_and_eject_slot - power off and eject slot
1008 if (slot->flags & SLOT_IS_GOING_AWAY) in acpiphp_disable_and_eject_slot()
1009 return -ENODEV; in acpiphp_disable_and_eject_slot()
1011 /* unconfigure all functions */ in acpiphp_disable_and_eject_slot()
1014 list_for_each_entry(func, &slot->funcs, sibling) in acpiphp_disable_and_eject_slot()
1015 if (func->flags & FUNC_HAS_EJ0) { in acpiphp_disable_and_eject_slot()
1049 return (slot->flags & SLOT_ENABLED); in acpiphp_get_power_status()