| 1 | // SPDX-License-Identifier: GPL-2.0-or-later | 
|---|
| 2 | /* | 
|---|
| 3 | *  pci_root.c - ACPI PCI Root Bridge Driver ($Revision: 40 $) | 
|---|
| 4 | * | 
|---|
| 5 | *  Copyright (C) 2001, 2002 Andy Grover <andrew.grover@intel.com> | 
|---|
| 6 | *  Copyright (C) 2001, 2002 Paul Diefenbaugh <paul.s.diefenbaugh@intel.com> | 
|---|
| 7 | */ | 
|---|
| 8 |  | 
|---|
| 9 | #define pr_fmt(fmt) "ACPI: " fmt | 
|---|
| 10 |  | 
|---|
| 11 | #include <linux/kernel.h> | 
|---|
| 12 | #include <linux/module.h> | 
|---|
| 13 | #include <linux/init.h> | 
|---|
| 14 | #include <linux/types.h> | 
|---|
| 15 | #include <linux/mutex.h> | 
|---|
| 16 | #include <linux/pm.h> | 
|---|
| 17 | #include <linux/pm_runtime.h> | 
|---|
| 18 | #include <linux/pci.h> | 
|---|
| 19 | #include <linux/pci-acpi.h> | 
|---|
| 20 | #include <linux/dmar.h> | 
|---|
| 21 | #include <linux/acpi.h> | 
|---|
| 22 | #include <linux/slab.h> | 
|---|
| 23 | #include <linux/dmi.h> | 
|---|
| 24 | #include <linux/platform_data/x86/apple.h> | 
|---|
| 25 | #include "internal.h" | 
|---|
| 26 |  | 
|---|
| 27 | #define ACPI_PCI_ROOT_CLASS		"pci_bridge" | 
|---|
| 28 | #define ACPI_PCI_ROOT_DEVICE_NAME	"PCI Root Bridge" | 
|---|
| 29 | static int acpi_pci_root_add(struct acpi_device *device, | 
|---|
| 30 | const struct acpi_device_id *not_used); | 
|---|
| 31 | static void acpi_pci_root_remove(struct acpi_device *device); | 
|---|
| 32 |  | 
|---|
| 33 | static int acpi_pci_root_scan_dependent(struct acpi_device *adev) | 
|---|
| 34 | { | 
|---|
| 35 | acpiphp_check_host_bridge(adev); | 
|---|
| 36 | return 0; | 
|---|
| 37 | } | 
|---|
| 38 |  | 
|---|
| 39 | #define ACPI_PCIE_REQ_SUPPORT (OSC_PCI_EXT_CONFIG_SUPPORT \ | 
|---|
| 40 | | OSC_PCI_ASPM_SUPPORT \ | 
|---|
| 41 | | OSC_PCI_CLOCK_PM_SUPPORT \ | 
|---|
| 42 | | OSC_PCI_MSI_SUPPORT) | 
|---|
| 43 |  | 
|---|
| 44 | static const struct acpi_device_id root_device_ids[] = { | 
|---|
| 45 | { "PNP0A03", 0}, | 
|---|
| 46 | {.id: "", .driver_data: 0}, | 
|---|
| 47 | }; | 
|---|
| 48 |  | 
|---|
| 49 | static struct acpi_scan_handler pci_root_handler = { | 
|---|
| 50 | .ids = root_device_ids, | 
|---|
| 51 | .attach = acpi_pci_root_add, | 
|---|
| 52 | .detach = acpi_pci_root_remove, | 
|---|
| 53 | .hotplug = { | 
|---|
| 54 | .enabled = true, | 
|---|
| 55 | .scan_dependent = acpi_pci_root_scan_dependent, | 
|---|
| 56 | }, | 
|---|
| 57 | }; | 
|---|
| 58 |  | 
|---|
| 59 | /** | 
|---|
| 60 | * acpi_is_root_bridge - determine whether an ACPI CA node is a PCI root bridge | 
|---|
| 61 | * @handle:  the ACPI CA node in question. | 
|---|
| 62 | * | 
|---|
| 63 | * Note: we could make this API take a struct acpi_device * instead, but | 
|---|
| 64 | * for now, it's more convenient to operate on an acpi_handle. | 
|---|
| 65 | */ | 
|---|
| 66 | int acpi_is_root_bridge(acpi_handle handle) | 
|---|
| 67 | { | 
|---|
| 68 | struct acpi_device *device = acpi_fetch_acpi_dev(handle); | 
|---|
| 69 | int ret; | 
|---|
| 70 |  | 
|---|
| 71 | if (!device) | 
|---|
| 72 | return 0; | 
|---|
| 73 |  | 
|---|
| 74 | ret = acpi_match_device_ids(device, ids: root_device_ids); | 
|---|
| 75 | if (ret) | 
|---|
| 76 | return 0; | 
|---|
| 77 | else | 
|---|
| 78 | return 1; | 
|---|
| 79 | } | 
|---|
| 80 | EXPORT_SYMBOL_GPL(acpi_is_root_bridge); | 
|---|
| 81 |  | 
|---|
| 82 | static acpi_status | 
|---|
| 83 | get_root_bridge_busnr_callback(struct acpi_resource *resource, void *data) | 
|---|
| 84 | { | 
|---|
| 85 | struct resource *res = data; | 
|---|
| 86 | struct acpi_resource_address64 address; | 
|---|
| 87 | acpi_status status; | 
|---|
| 88 |  | 
|---|
| 89 | status = acpi_resource_to_address64(resource, out: &address); | 
|---|
| 90 | if (ACPI_FAILURE(status)) | 
|---|
| 91 | return AE_OK; | 
|---|
| 92 |  | 
|---|
| 93 | if ((address.address.address_length > 0) && | 
|---|
| 94 | (address.resource_type == ACPI_BUS_NUMBER_RANGE)) { | 
|---|
| 95 | res->start = address.address.minimum; | 
|---|
| 96 | res->end = address.address.minimum + address.address.address_length - 1; | 
|---|
| 97 | } | 
|---|
| 98 |  | 
|---|
| 99 | return AE_OK; | 
|---|
| 100 | } | 
|---|
| 101 |  | 
|---|
| 102 | static acpi_status try_get_root_bridge_busnr(acpi_handle handle, | 
|---|
| 103 | struct resource *res) | 
|---|
| 104 | { | 
|---|
| 105 | acpi_status status; | 
|---|
| 106 |  | 
|---|
| 107 | res->start = -1; | 
|---|
| 108 | status = | 
|---|
| 109 | acpi_walk_resources(device: handle, METHOD_NAME__CRS, | 
|---|
| 110 | user_function: get_root_bridge_busnr_callback, context: res); | 
|---|
| 111 | if (ACPI_FAILURE(status)) | 
|---|
| 112 | return status; | 
|---|
| 113 | if (res->start == -1) | 
|---|
| 114 | return AE_ERROR; | 
|---|
| 115 | return AE_OK; | 
|---|
| 116 | } | 
|---|
| 117 |  | 
|---|
| 118 | struct pci_osc_bit_struct { | 
|---|
| 119 | u32 bit; | 
|---|
| 120 | char *desc; | 
|---|
| 121 | }; | 
|---|
| 122 |  | 
|---|
| 123 | static struct pci_osc_bit_struct pci_osc_support_bit[] = { | 
|---|
| 124 | { OSC_PCI_EXT_CONFIG_SUPPORT, "ExtendedConfig"}, | 
|---|
| 125 | { OSC_PCI_ASPM_SUPPORT, "ASPM"}, | 
|---|
| 126 | { OSC_PCI_CLOCK_PM_SUPPORT, "ClockPM"}, | 
|---|
| 127 | { OSC_PCI_SEGMENT_GROUPS_SUPPORT, "Segments"}, | 
|---|
| 128 | { OSC_PCI_MSI_SUPPORT, "MSI"}, | 
|---|
| 129 | { OSC_PCI_EDR_SUPPORT, "EDR"}, | 
|---|
| 130 | { OSC_PCI_HPX_TYPE_3_SUPPORT, "HPX-Type3"}, | 
|---|
| 131 | }; | 
|---|
| 132 |  | 
|---|
| 133 | static struct pci_osc_bit_struct pci_osc_control_bit[] = { | 
|---|
| 134 | { OSC_PCI_EXPRESS_NATIVE_HP_CONTROL, "PCIeHotplug"}, | 
|---|
| 135 | { OSC_PCI_SHPC_NATIVE_HP_CONTROL, "SHPCHotplug"}, | 
|---|
| 136 | { OSC_PCI_EXPRESS_PME_CONTROL, "PME"}, | 
|---|
| 137 | { OSC_PCI_EXPRESS_AER_CONTROL, "AER"}, | 
|---|
| 138 | { OSC_PCI_EXPRESS_CAPABILITY_CONTROL, "PCIeCapability"}, | 
|---|
| 139 | { OSC_PCI_EXPRESS_LTR_CONTROL, "LTR"}, | 
|---|
| 140 | { OSC_PCI_EXPRESS_DPC_CONTROL, "DPC"}, | 
|---|
| 141 | }; | 
|---|
| 142 |  | 
|---|
| 143 | static struct pci_osc_bit_struct cxl_osc_support_bit[] = { | 
|---|
| 144 | { OSC_CXL_1_1_PORT_REG_ACCESS_SUPPORT, "CXL11PortRegAccess"}, | 
|---|
| 145 | { OSC_CXL_2_0_PORT_DEV_REG_ACCESS_SUPPORT, "CXL20PortDevRegAccess"}, | 
|---|
| 146 | { OSC_CXL_PROTOCOL_ERR_REPORTING_SUPPORT, "CXLProtocolErrorReporting"}, | 
|---|
| 147 | { OSC_CXL_NATIVE_HP_SUPPORT, "CXLNativeHotPlug"}, | 
|---|
| 148 | }; | 
|---|
| 149 |  | 
|---|
| 150 | static struct pci_osc_bit_struct cxl_osc_control_bit[] = { | 
|---|
| 151 | { OSC_CXL_ERROR_REPORTING_CONTROL, "CXLMemErrorReporting"}, | 
|---|
| 152 | }; | 
|---|
| 153 |  | 
|---|
| 154 | static void decode_osc_bits(struct acpi_pci_root *root, char *msg, u32 word, | 
|---|
| 155 | struct pci_osc_bit_struct *table, int size) | 
|---|
| 156 | { | 
|---|
| 157 | char buf[80]; | 
|---|
| 158 | int i, len = 0; | 
|---|
| 159 | struct pci_osc_bit_struct *entry; | 
|---|
| 160 |  | 
|---|
| 161 | buf[0] = '\0'; | 
|---|
| 162 | for (i = 0, entry = table; i < size; i++, entry++) | 
|---|
| 163 | if (word & entry->bit) | 
|---|
| 164 | len += scnprintf(buf: buf + len, size: sizeof(buf) - len, fmt: "%s%s", | 
|---|
| 165 | len ? " ": "", entry->desc); | 
|---|
| 166 |  | 
|---|
| 167 | dev_info(&root->device->dev, "_OSC: %s [%s]\n", msg, buf); | 
|---|
| 168 | } | 
|---|
| 169 |  | 
|---|
| 170 | static void decode_osc_support(struct acpi_pci_root *root, char *msg, u32 word) | 
|---|
| 171 | { | 
|---|
| 172 | decode_osc_bits(root, msg, word, table: pci_osc_support_bit, | 
|---|
| 173 | ARRAY_SIZE(pci_osc_support_bit)); | 
|---|
| 174 | } | 
|---|
| 175 |  | 
|---|
| 176 | static void decode_osc_control(struct acpi_pci_root *root, char *msg, u32 word) | 
|---|
| 177 | { | 
|---|
| 178 | decode_osc_bits(root, msg, word, table: pci_osc_control_bit, | 
|---|
| 179 | ARRAY_SIZE(pci_osc_control_bit)); | 
|---|
| 180 | } | 
|---|
| 181 |  | 
|---|
| 182 | static void decode_cxl_osc_support(struct acpi_pci_root *root, char *msg, u32 word) | 
|---|
| 183 | { | 
|---|
| 184 | decode_osc_bits(root, msg, word, table: cxl_osc_support_bit, | 
|---|
| 185 | ARRAY_SIZE(cxl_osc_support_bit)); | 
|---|
| 186 | } | 
|---|
| 187 |  | 
|---|
| 188 | static void decode_cxl_osc_control(struct acpi_pci_root *root, char *msg, u32 word) | 
|---|
| 189 | { | 
|---|
| 190 | decode_osc_bits(root, msg, word, table: cxl_osc_control_bit, | 
|---|
| 191 | ARRAY_SIZE(cxl_osc_control_bit)); | 
|---|
| 192 | } | 
|---|
| 193 |  | 
|---|
| 194 | static inline bool is_pcie(struct acpi_pci_root *root) | 
|---|
| 195 | { | 
|---|
| 196 | return root->bridge_type == ACPI_BRIDGE_TYPE_PCIE; | 
|---|
| 197 | } | 
|---|
| 198 |  | 
|---|
| 199 | static inline bool is_cxl(struct acpi_pci_root *root) | 
|---|
| 200 | { | 
|---|
| 201 | return root->bridge_type == ACPI_BRIDGE_TYPE_CXL; | 
|---|
| 202 | } | 
|---|
| 203 |  | 
|---|
| 204 | static u8 pci_osc_uuid_str[] = "33DB4D5B-1FF7-401C-9657-7441C03DD766"; | 
|---|
| 205 | static u8 cxl_osc_uuid_str[] = "68F2D50B-C469-4d8A-BD3D-941A103FD3FC"; | 
|---|
| 206 |  | 
|---|
| 207 | static char *to_uuid(struct acpi_pci_root *root) | 
|---|
| 208 | { | 
|---|
| 209 | if (is_cxl(root)) | 
|---|
| 210 | return cxl_osc_uuid_str; | 
|---|
| 211 | return pci_osc_uuid_str; | 
|---|
| 212 | } | 
|---|
| 213 |  | 
|---|
| 214 | static int cap_length(struct acpi_pci_root *root) | 
|---|
| 215 | { | 
|---|
| 216 | if (is_cxl(root)) | 
|---|
| 217 | return sizeof(u32) * OSC_CXL_CAPABILITY_DWORDS; | 
|---|
| 218 | return sizeof(u32) * OSC_PCI_CAPABILITY_DWORDS; | 
|---|
| 219 | } | 
|---|
| 220 |  | 
|---|
| 221 | static acpi_status acpi_pci_run_osc(struct acpi_pci_root *root, | 
|---|
| 222 | const u32 *capbuf, u32 *pci_control, | 
|---|
| 223 | u32 *cxl_control) | 
|---|
| 224 | { | 
|---|
| 225 | struct acpi_osc_context context = { | 
|---|
| 226 | .uuid_str = to_uuid(root), | 
|---|
| 227 | .rev = 1, | 
|---|
| 228 | .cap.length = cap_length(root), | 
|---|
| 229 | .cap.pointer = (void *)capbuf, | 
|---|
| 230 | }; | 
|---|
| 231 | acpi_status status; | 
|---|
| 232 |  | 
|---|
| 233 | status = acpi_run_osc(handle: root->device->handle, context: &context); | 
|---|
| 234 | if (ACPI_SUCCESS(status)) { | 
|---|
| 235 | *pci_control = acpi_osc_ctx_get_pci_control(context: &context); | 
|---|
| 236 | if (is_cxl(root)) | 
|---|
| 237 | *cxl_control = acpi_osc_ctx_get_cxl_control(context: &context); | 
|---|
| 238 | kfree(objp: context.ret.pointer); | 
|---|
| 239 | } | 
|---|
| 240 | return status; | 
|---|
| 241 | } | 
|---|
| 242 |  | 
|---|
| 243 | static acpi_status acpi_pci_query_osc(struct acpi_pci_root *root, u32 support, | 
|---|
| 244 | u32 *control, u32 cxl_support, | 
|---|
| 245 | u32 *cxl_control) | 
|---|
| 246 | { | 
|---|
| 247 | acpi_status status; | 
|---|
| 248 | u32 pci_result, cxl_result, capbuf[OSC_CXL_CAPABILITY_DWORDS]; | 
|---|
| 249 |  | 
|---|
| 250 | support |= root->osc_support_set; | 
|---|
| 251 |  | 
|---|
| 252 | capbuf[OSC_QUERY_DWORD] = OSC_QUERY_ENABLE; | 
|---|
| 253 | capbuf[OSC_SUPPORT_DWORD] = support; | 
|---|
| 254 | capbuf[OSC_CONTROL_DWORD] = *control | root->osc_control_set; | 
|---|
| 255 |  | 
|---|
| 256 | if (is_cxl(root)) { | 
|---|
| 257 | cxl_support |= root->osc_ext_support_set; | 
|---|
| 258 | capbuf[OSC_EXT_SUPPORT_DWORD] = cxl_support; | 
|---|
| 259 | capbuf[OSC_EXT_CONTROL_DWORD] = *cxl_control | root->osc_ext_control_set; | 
|---|
| 260 | } | 
|---|
| 261 |  | 
|---|
| 262 | retry: | 
|---|
| 263 | status = acpi_pci_run_osc(root, capbuf, pci_control: &pci_result, cxl_control: &cxl_result); | 
|---|
| 264 | if (ACPI_SUCCESS(status)) { | 
|---|
| 265 | root->osc_support_set = support; | 
|---|
| 266 | *control = pci_result; | 
|---|
| 267 | if (is_cxl(root)) { | 
|---|
| 268 | root->osc_ext_support_set = cxl_support; | 
|---|
| 269 | *cxl_control = cxl_result; | 
|---|
| 270 | } | 
|---|
| 271 | } else if (is_cxl(root)) { | 
|---|
| 272 | /* | 
|---|
| 273 | * CXL _OSC is optional on CXL 1.1 hosts. Fall back to PCIe _OSC | 
|---|
| 274 | * upon any failure using CXL _OSC. | 
|---|
| 275 | */ | 
|---|
| 276 | root->bridge_type = ACPI_BRIDGE_TYPE_PCIE; | 
|---|
| 277 | goto retry; | 
|---|
| 278 | } | 
|---|
| 279 | return status; | 
|---|
| 280 | } | 
|---|
| 281 |  | 
|---|
| 282 | struct acpi_pci_root *acpi_pci_find_root(acpi_handle handle) | 
|---|
| 283 | { | 
|---|
| 284 | struct acpi_device *device = acpi_fetch_acpi_dev(handle); | 
|---|
| 285 | struct acpi_pci_root *root; | 
|---|
| 286 |  | 
|---|
| 287 | if (!device || acpi_match_device_ids(device, ids: root_device_ids)) | 
|---|
| 288 | return NULL; | 
|---|
| 289 |  | 
|---|
| 290 | root = acpi_driver_data(d: device); | 
|---|
| 291 |  | 
|---|
| 292 | return root; | 
|---|
| 293 | } | 
|---|
| 294 | EXPORT_SYMBOL_GPL(acpi_pci_find_root); | 
|---|
| 295 |  | 
|---|
| 296 | /** | 
|---|
| 297 | * acpi_get_pci_dev - convert ACPI CA handle to struct pci_dev | 
|---|
| 298 | * @handle: the handle in question | 
|---|
| 299 | * | 
|---|
| 300 | * Given an ACPI CA handle, the desired PCI device is located in the | 
|---|
| 301 | * list of PCI devices. | 
|---|
| 302 | * | 
|---|
| 303 | * If the device is found, its reference count is increased and this | 
|---|
| 304 | * function returns a pointer to its data structure.  The caller must | 
|---|
| 305 | * decrement the reference count by calling pci_dev_put(). | 
|---|
| 306 | * If no device is found, %NULL is returned. | 
|---|
| 307 | */ | 
|---|
| 308 | struct pci_dev *acpi_get_pci_dev(acpi_handle handle) | 
|---|
| 309 | { | 
|---|
| 310 | struct acpi_device *adev = acpi_fetch_acpi_dev(handle); | 
|---|
| 311 | struct acpi_device_physical_node *pn; | 
|---|
| 312 | struct pci_dev *pci_dev = NULL; | 
|---|
| 313 |  | 
|---|
| 314 | if (!adev) | 
|---|
| 315 | return NULL; | 
|---|
| 316 |  | 
|---|
| 317 | mutex_lock(lock: &adev->physical_node_lock); | 
|---|
| 318 |  | 
|---|
| 319 | list_for_each_entry(pn, &adev->physical_node_list, node) { | 
|---|
| 320 | if (dev_is_pci(pn->dev)) { | 
|---|
| 321 | get_device(dev: pn->dev); | 
|---|
| 322 | pci_dev = to_pci_dev(pn->dev); | 
|---|
| 323 | break; | 
|---|
| 324 | } | 
|---|
| 325 | } | 
|---|
| 326 |  | 
|---|
| 327 | mutex_unlock(lock: &adev->physical_node_lock); | 
|---|
| 328 |  | 
|---|
| 329 | return pci_dev; | 
|---|
| 330 | } | 
|---|
| 331 | EXPORT_SYMBOL_GPL(acpi_get_pci_dev); | 
|---|
| 332 |  | 
|---|
| 333 | /** | 
|---|
| 334 | * acpi_pci_osc_control_set - Request control of PCI root _OSC features. | 
|---|
| 335 | * @handle: ACPI handle of a PCI root bridge (or PCIe Root Complex). | 
|---|
| 336 | * @mask: Mask of _OSC bits to request control of, place to store control mask. | 
|---|
| 337 | * @support: _OSC supported capability. | 
|---|
| 338 | * @cxl_mask: Mask of CXL _OSC control bits, place to store control mask. | 
|---|
| 339 | * @cxl_support: CXL _OSC supported capability. | 
|---|
| 340 | * | 
|---|
| 341 | * Run _OSC query for @mask and if that is successful, compare the returned | 
|---|
| 342 | * mask of control bits with @req.  If all of the @req bits are set in the | 
|---|
| 343 | * returned mask, run _OSC request for it. | 
|---|
| 344 | * | 
|---|
| 345 | * The variable at the @mask address may be modified regardless of whether or | 
|---|
| 346 | * not the function returns success.  On success it will contain the mask of | 
|---|
| 347 | * _OSC bits the BIOS has granted control of, but its contents are meaningless | 
|---|
| 348 | * on failure. | 
|---|
| 349 | **/ | 
|---|
| 350 | static acpi_status acpi_pci_osc_control_set(acpi_handle handle, u32 *mask, | 
|---|
| 351 | u32 support, u32 *cxl_mask, | 
|---|
| 352 | u32 cxl_support) | 
|---|
| 353 | { | 
|---|
| 354 | u32 req = OSC_PCI_EXPRESS_CAPABILITY_CONTROL; | 
|---|
| 355 | struct acpi_pci_root *root; | 
|---|
| 356 | acpi_status status; | 
|---|
| 357 | u32 ctrl, cxl_ctrl = 0, capbuf[OSC_CXL_CAPABILITY_DWORDS]; | 
|---|
| 358 |  | 
|---|
| 359 | if (!mask) | 
|---|
| 360 | return AE_BAD_PARAMETER; | 
|---|
| 361 |  | 
|---|
| 362 | root = acpi_pci_find_root(handle); | 
|---|
| 363 | if (!root) | 
|---|
| 364 | return AE_NOT_EXIST; | 
|---|
| 365 |  | 
|---|
| 366 | ctrl   = *mask; | 
|---|
| 367 | *mask |= root->osc_control_set; | 
|---|
| 368 |  | 
|---|
| 369 | if (is_cxl(root)) { | 
|---|
| 370 | cxl_ctrl = *cxl_mask; | 
|---|
| 371 | *cxl_mask |= root->osc_ext_control_set; | 
|---|
| 372 | } | 
|---|
| 373 |  | 
|---|
| 374 | /* Need to check the available controls bits before requesting them. */ | 
|---|
| 375 | do { | 
|---|
| 376 | u32 pci_missing = 0, cxl_missing = 0; | 
|---|
| 377 |  | 
|---|
| 378 | status = acpi_pci_query_osc(root, support, control: mask, cxl_support, | 
|---|
| 379 | cxl_control: cxl_mask); | 
|---|
| 380 | if (ACPI_FAILURE(status)) | 
|---|
| 381 | return status; | 
|---|
| 382 | if (is_cxl(root)) { | 
|---|
| 383 | if (ctrl == *mask && cxl_ctrl == *cxl_mask) | 
|---|
| 384 | break; | 
|---|
| 385 | pci_missing = ctrl & ~(*mask); | 
|---|
| 386 | cxl_missing = cxl_ctrl & ~(*cxl_mask); | 
|---|
| 387 | } else { | 
|---|
| 388 | if (ctrl == *mask) | 
|---|
| 389 | break; | 
|---|
| 390 | pci_missing = ctrl & ~(*mask); | 
|---|
| 391 | } | 
|---|
| 392 | if (pci_missing) | 
|---|
| 393 | decode_osc_control(root, msg: "platform does not support", | 
|---|
| 394 | word: pci_missing); | 
|---|
| 395 | if (cxl_missing) | 
|---|
| 396 | decode_cxl_osc_control(root, msg: "CXL platform does not support", | 
|---|
| 397 | word: cxl_missing); | 
|---|
| 398 | ctrl = *mask; | 
|---|
| 399 | cxl_ctrl = *cxl_mask; | 
|---|
| 400 | } while (*mask || *cxl_mask); | 
|---|
| 401 |  | 
|---|
| 402 | /* No need to request _OSC if the control was already granted. */ | 
|---|
| 403 | if ((root->osc_control_set & ctrl) == ctrl && | 
|---|
| 404 | (root->osc_ext_control_set & cxl_ctrl) == cxl_ctrl) | 
|---|
| 405 | return AE_OK; | 
|---|
| 406 |  | 
|---|
| 407 | if ((ctrl & req) != req) { | 
|---|
| 408 | decode_osc_control(root, msg: "not requesting control; platform does not support", | 
|---|
| 409 | word: req & ~(ctrl)); | 
|---|
| 410 | return AE_SUPPORT; | 
|---|
| 411 | } | 
|---|
| 412 |  | 
|---|
| 413 | capbuf[OSC_QUERY_DWORD] = 0; | 
|---|
| 414 | capbuf[OSC_SUPPORT_DWORD] = root->osc_support_set; | 
|---|
| 415 | capbuf[OSC_CONTROL_DWORD] = ctrl; | 
|---|
| 416 | if (is_cxl(root)) { | 
|---|
| 417 | capbuf[OSC_EXT_SUPPORT_DWORD] = root->osc_ext_support_set; | 
|---|
| 418 | capbuf[OSC_EXT_CONTROL_DWORD] = cxl_ctrl; | 
|---|
| 419 | } | 
|---|
| 420 |  | 
|---|
| 421 | status = acpi_pci_run_osc(root, capbuf, pci_control: mask, cxl_control: cxl_mask); | 
|---|
| 422 | if (ACPI_FAILURE(status)) | 
|---|
| 423 | return status; | 
|---|
| 424 |  | 
|---|
| 425 | root->osc_control_set = *mask; | 
|---|
| 426 | root->osc_ext_control_set = *cxl_mask; | 
|---|
| 427 | return AE_OK; | 
|---|
| 428 | } | 
|---|
| 429 |  | 
|---|
| 430 | static u32 calculate_support(void) | 
|---|
| 431 | { | 
|---|
| 432 | u32 support; | 
|---|
| 433 |  | 
|---|
| 434 | /* | 
|---|
| 435 | * All supported architectures that use ACPI have support for | 
|---|
| 436 | * PCI domains, so we indicate this in _OSC support capabilities. | 
|---|
| 437 | */ | 
|---|
| 438 | support = OSC_PCI_SEGMENT_GROUPS_SUPPORT; | 
|---|
| 439 | support |= OSC_PCI_HPX_TYPE_3_SUPPORT; | 
|---|
| 440 | if (pci_ext_cfg_avail()) | 
|---|
| 441 | support |= OSC_PCI_EXT_CONFIG_SUPPORT; | 
|---|
| 442 | if (pcie_aspm_support_enabled()) | 
|---|
| 443 | support |= OSC_PCI_ASPM_SUPPORT | OSC_PCI_CLOCK_PM_SUPPORT; | 
|---|
| 444 | if (pci_msi_enabled()) | 
|---|
| 445 | support |= OSC_PCI_MSI_SUPPORT; | 
|---|
| 446 | if (IS_ENABLED(CONFIG_PCIE_EDR)) | 
|---|
| 447 | support |= OSC_PCI_EDR_SUPPORT; | 
|---|
| 448 |  | 
|---|
| 449 | return support; | 
|---|
| 450 | } | 
|---|
| 451 |  | 
|---|
| 452 | /* | 
|---|
| 453 | * Background on hotplug support, and making it depend on only | 
|---|
| 454 | * CONFIG_HOTPLUG_PCI_PCIE vs. also considering CONFIG_MEMORY_HOTPLUG: | 
|---|
| 455 | * | 
|---|
| 456 | * CONFIG_ACPI_HOTPLUG_MEMORY does depend on CONFIG_MEMORY_HOTPLUG, but | 
|---|
| 457 | * there is no existing _OSC for memory hotplug support. The reason is that | 
|---|
| 458 | * ACPI memory hotplug requires the OS to acknowledge / coordinate with | 
|---|
| 459 | * memory plug events via a scan handler. On the CXL side the equivalent | 
|---|
| 460 | * would be if Linux supported the Mechanical Retention Lock [1], or | 
|---|
| 461 | * otherwise had some coordination for the driver of a PCI device | 
|---|
| 462 | * undergoing hotplug to be consulted on whether the hotplug should | 
|---|
| 463 | * proceed or not. | 
|---|
| 464 | * | 
|---|
| 465 | * The concern is that if Linux says no to supporting CXL hotplug then | 
|---|
| 466 | * the BIOS may say no to giving the OS hotplug control of any other PCIe | 
|---|
| 467 | * device. So the question here is not whether hotplug is enabled, it's | 
|---|
| 468 | * whether it is handled natively by the at all OS, and if | 
|---|
| 469 | * CONFIG_HOTPLUG_PCI_PCIE is enabled then the answer is "yes". | 
|---|
| 470 | * | 
|---|
| 471 | * Otherwise, the plan for CXL coordinated remove, since the kernel does | 
|---|
| 472 | * not support blocking hotplug, is to require the memory device to be | 
|---|
| 473 | * disabled before hotplug is attempted. When CONFIG_MEMORY_HOTPLUG is | 
|---|
| 474 | * disabled that step will fail and the remove attempt cancelled by the | 
|---|
| 475 | * user. If that is not honored and the card is removed anyway then it | 
|---|
| 476 | * does not matter if CONFIG_MEMORY_HOTPLUG is enabled or not, it will | 
|---|
| 477 | * cause a crash and other badness. | 
|---|
| 478 | * | 
|---|
| 479 | * Therefore, just say yes to CXL hotplug and require removal to | 
|---|
| 480 | * be coordinated by userspace unless and until the kernel grows better | 
|---|
| 481 | * mechanisms for doing "managed" removal of devices in consultation with | 
|---|
| 482 | * the driver. | 
|---|
| 483 | * | 
|---|
| 484 | * [1]: https://lore.kernel.org/all/20201122014203.4706-1-ashok.raj@intel.com/ | 
|---|
| 485 | */ | 
|---|
| 486 | static u32 calculate_cxl_support(void) | 
|---|
| 487 | { | 
|---|
| 488 | u32 support; | 
|---|
| 489 |  | 
|---|
| 490 | support = OSC_CXL_2_0_PORT_DEV_REG_ACCESS_SUPPORT; | 
|---|
| 491 | support |= OSC_CXL_1_1_PORT_REG_ACCESS_SUPPORT; | 
|---|
| 492 | if (pci_aer_available()) | 
|---|
| 493 | support |= OSC_CXL_PROTOCOL_ERR_REPORTING_SUPPORT; | 
|---|
| 494 | if (IS_ENABLED(CONFIG_HOTPLUG_PCI_PCIE)) | 
|---|
| 495 | support |= OSC_CXL_NATIVE_HP_SUPPORT; | 
|---|
| 496 |  | 
|---|
| 497 | return support; | 
|---|
| 498 | } | 
|---|
| 499 |  | 
|---|
| 500 | static u32 calculate_control(void) | 
|---|
| 501 | { | 
|---|
| 502 | u32 control; | 
|---|
| 503 |  | 
|---|
| 504 | control = OSC_PCI_EXPRESS_CAPABILITY_CONTROL | 
|---|
| 505 | | OSC_PCI_EXPRESS_PME_CONTROL; | 
|---|
| 506 |  | 
|---|
| 507 | if (IS_ENABLED(CONFIG_PCIEASPM)) | 
|---|
| 508 | control |= OSC_PCI_EXPRESS_LTR_CONTROL; | 
|---|
| 509 |  | 
|---|
| 510 | if (IS_ENABLED(CONFIG_HOTPLUG_PCI_PCIE)) | 
|---|
| 511 | control |= OSC_PCI_EXPRESS_NATIVE_HP_CONTROL; | 
|---|
| 512 |  | 
|---|
| 513 | if (IS_ENABLED(CONFIG_HOTPLUG_PCI_SHPC)) | 
|---|
| 514 | control |= OSC_PCI_SHPC_NATIVE_HP_CONTROL; | 
|---|
| 515 |  | 
|---|
| 516 | if (pci_aer_available()) | 
|---|
| 517 | control |= OSC_PCI_EXPRESS_AER_CONTROL; | 
|---|
| 518 |  | 
|---|
| 519 | /* | 
|---|
| 520 | * Per the Downstream Port Containment Related Enhancements ECN to | 
|---|
| 521 | * the PCI Firmware Spec, r3.2, sec 4.5.1, table 4-5, | 
|---|
| 522 | * OSC_PCI_EXPRESS_DPC_CONTROL indicates the OS supports both DPC | 
|---|
| 523 | * and EDR. | 
|---|
| 524 | */ | 
|---|
| 525 | if (IS_ENABLED(CONFIG_PCIE_DPC) && IS_ENABLED(CONFIG_PCIE_EDR)) | 
|---|
| 526 | control |= OSC_PCI_EXPRESS_DPC_CONTROL; | 
|---|
| 527 |  | 
|---|
| 528 | return control; | 
|---|
| 529 | } | 
|---|
| 530 |  | 
|---|
| 531 | static u32 calculate_cxl_control(void) | 
|---|
| 532 | { | 
|---|
| 533 | u32 control = 0; | 
|---|
| 534 |  | 
|---|
| 535 | if (IS_ENABLED(CONFIG_MEMORY_FAILURE)) | 
|---|
| 536 | control |= OSC_CXL_ERROR_REPORTING_CONTROL; | 
|---|
| 537 |  | 
|---|
| 538 | return control; | 
|---|
| 539 | } | 
|---|
| 540 |  | 
|---|
| 541 | static bool os_control_query_checks(struct acpi_pci_root *root, u32 support) | 
|---|
| 542 | { | 
|---|
| 543 | struct acpi_device *device = root->device; | 
|---|
| 544 |  | 
|---|
| 545 | if (pcie_ports_disabled) { | 
|---|
| 546 | dev_info(&device->dev, "PCIe port services disabled; not requesting _OSC control\n"); | 
|---|
| 547 | return false; | 
|---|
| 548 | } | 
|---|
| 549 |  | 
|---|
| 550 | if ((support & ACPI_PCIE_REQ_SUPPORT) != ACPI_PCIE_REQ_SUPPORT) { | 
|---|
| 551 | decode_osc_support(root, msg: "not requesting OS control; OS requires", | 
|---|
| 552 | ACPI_PCIE_REQ_SUPPORT); | 
|---|
| 553 | return false; | 
|---|
| 554 | } | 
|---|
| 555 |  | 
|---|
| 556 | return true; | 
|---|
| 557 | } | 
|---|
| 558 |  | 
|---|
| 559 | static void negotiate_os_control(struct acpi_pci_root *root, int *no_aspm) | 
|---|
| 560 | { | 
|---|
| 561 | u32 support, control = 0, requested = 0; | 
|---|
| 562 | u32 cxl_support = 0, cxl_control = 0, cxl_requested = 0; | 
|---|
| 563 | acpi_status status; | 
|---|
| 564 | struct acpi_device *device = root->device; | 
|---|
| 565 | acpi_handle handle = device->handle; | 
|---|
| 566 |  | 
|---|
| 567 | /* | 
|---|
| 568 | * Apple always return failure on _OSC calls when _OSI("Darwin") has | 
|---|
| 569 | * been called successfully. We know the feature set supported by the | 
|---|
| 570 | * platform, so avoid calling _OSC at all | 
|---|
| 571 | */ | 
|---|
| 572 | if (x86_apple_machine) { | 
|---|
| 573 | root->osc_control_set = ~OSC_PCI_EXPRESS_PME_CONTROL; | 
|---|
| 574 | decode_osc_control(root, msg: "OS assumes control of", | 
|---|
| 575 | word: root->osc_control_set); | 
|---|
| 576 | return; | 
|---|
| 577 | } | 
|---|
| 578 |  | 
|---|
| 579 | support = calculate_support(); | 
|---|
| 580 |  | 
|---|
| 581 | decode_osc_support(root, msg: "OS supports", word: support); | 
|---|
| 582 |  | 
|---|
| 583 | if (os_control_query_checks(root, support)) | 
|---|
| 584 | requested = control = calculate_control(); | 
|---|
| 585 |  | 
|---|
| 586 | if (is_cxl(root)) { | 
|---|
| 587 | cxl_support = calculate_cxl_support(); | 
|---|
| 588 | decode_cxl_osc_support(root, msg: "OS supports", word: cxl_support); | 
|---|
| 589 | cxl_requested = cxl_control = calculate_cxl_control(); | 
|---|
| 590 | } | 
|---|
| 591 |  | 
|---|
| 592 | status = acpi_pci_osc_control_set(handle, mask: &control, support, | 
|---|
| 593 | cxl_mask: &cxl_control, cxl_support); | 
|---|
| 594 | if (ACPI_SUCCESS(status)) { | 
|---|
| 595 | if (control) | 
|---|
| 596 | decode_osc_control(root, msg: "OS now controls", word: control); | 
|---|
| 597 | if (cxl_control) | 
|---|
| 598 | decode_cxl_osc_control(root, msg: "OS now controls", | 
|---|
| 599 | word: cxl_control); | 
|---|
| 600 |  | 
|---|
| 601 | if (acpi_gbl_FADT.boot_flags & ACPI_FADT_NO_ASPM) { | 
|---|
| 602 | /* | 
|---|
| 603 | * We have ASPM control, but the FADT indicates that | 
|---|
| 604 | * it's unsupported. Leave existing configuration | 
|---|
| 605 | * intact and prevent the OS from touching it. | 
|---|
| 606 | */ | 
|---|
| 607 | dev_info(&device->dev, "FADT indicates ASPM is unsupported, using BIOS configuration\n"); | 
|---|
| 608 | *no_aspm = 1; | 
|---|
| 609 | } | 
|---|
| 610 | } else { | 
|---|
| 611 | /* | 
|---|
| 612 | * We want to disable ASPM here, but aspm_disabled | 
|---|
| 613 | * needs to remain in its state from boot so that we | 
|---|
| 614 | * properly handle PCIe 1.1 devices.  So we set this | 
|---|
| 615 | * flag here, to defer the action until after the ACPI | 
|---|
| 616 | * root scan. | 
|---|
| 617 | */ | 
|---|
| 618 | *no_aspm = 1; | 
|---|
| 619 |  | 
|---|
| 620 | /* _OSC is optional for PCI host bridges */ | 
|---|
| 621 | if (status == AE_NOT_FOUND && !is_pcie(root)) | 
|---|
| 622 | return; | 
|---|
| 623 |  | 
|---|
| 624 | if (control) { | 
|---|
| 625 | decode_osc_control(root, msg: "OS requested", word: requested); | 
|---|
| 626 | decode_osc_control(root, msg: "platform willing to grant", word: control); | 
|---|
| 627 | } | 
|---|
| 628 | if (cxl_control) { | 
|---|
| 629 | decode_cxl_osc_control(root, msg: "OS requested", word: cxl_requested); | 
|---|
| 630 | decode_cxl_osc_control(root, msg: "platform willing to grant", | 
|---|
| 631 | word: cxl_control); | 
|---|
| 632 | } | 
|---|
| 633 |  | 
|---|
| 634 | dev_info(&device->dev, "_OSC: platform retains control of PCIe features (%s)\n", | 
|---|
| 635 | acpi_format_exception(status)); | 
|---|
| 636 | } | 
|---|
| 637 | } | 
|---|
| 638 |  | 
|---|
| 639 | static int acpi_pci_root_add(struct acpi_device *device, | 
|---|
| 640 | const struct acpi_device_id *not_used) | 
|---|
| 641 | { | 
|---|
| 642 | unsigned long long segment, bus; | 
|---|
| 643 | acpi_status status; | 
|---|
| 644 | int result; | 
|---|
| 645 | struct acpi_pci_root *root; | 
|---|
| 646 | acpi_handle handle = device->handle; | 
|---|
| 647 | int no_aspm = 0; | 
|---|
| 648 | bool hotadd = system_state == SYSTEM_RUNNING; | 
|---|
| 649 | const char *acpi_hid; | 
|---|
| 650 |  | 
|---|
| 651 | root = kzalloc(sizeof(struct acpi_pci_root), GFP_KERNEL); | 
|---|
| 652 | if (!root) | 
|---|
| 653 | return -ENOMEM; | 
|---|
| 654 |  | 
|---|
| 655 | segment = 0; | 
|---|
| 656 | status = acpi_evaluate_integer(handle, METHOD_NAME__SEG, NULL, | 
|---|
| 657 | data: &segment); | 
|---|
| 658 | if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) { | 
|---|
| 659 | dev_err(&device->dev, "can't evaluate _SEG\n"); | 
|---|
| 660 | result = -ENODEV; | 
|---|
| 661 | goto end; | 
|---|
| 662 | } | 
|---|
| 663 |  | 
|---|
| 664 | /* Check _CRS first, then _BBN.  If no _BBN, default to zero. */ | 
|---|
| 665 | root->secondary.flags = IORESOURCE_BUS; | 
|---|
| 666 | status = try_get_root_bridge_busnr(handle, res: &root->secondary); | 
|---|
| 667 | if (ACPI_FAILURE(status)) { | 
|---|
| 668 | /* | 
|---|
| 669 | * We need both the start and end of the downstream bus range | 
|---|
| 670 | * to interpret _CBA (MMCONFIG base address), so it really is | 
|---|
| 671 | * supposed to be in _CRS.  If we don't find it there, all we | 
|---|
| 672 | * can do is assume [_BBN-0xFF] or [0-0xFF]. | 
|---|
| 673 | */ | 
|---|
| 674 | root->secondary.end = 0xFF; | 
|---|
| 675 | dev_warn(&device->dev, | 
|---|
| 676 | FW_BUG "no secondary bus range in _CRS\n"); | 
|---|
| 677 | status = acpi_evaluate_integer(handle, METHOD_NAME__BBN, | 
|---|
| 678 | NULL, data: &bus); | 
|---|
| 679 | if (ACPI_SUCCESS(status)) | 
|---|
| 680 | root->secondary.start = bus; | 
|---|
| 681 | else if (status == AE_NOT_FOUND) | 
|---|
| 682 | root->secondary.start = 0; | 
|---|
| 683 | else { | 
|---|
| 684 | dev_err(&device->dev, "can't evaluate _BBN\n"); | 
|---|
| 685 | result = -ENODEV; | 
|---|
| 686 | goto end; | 
|---|
| 687 | } | 
|---|
| 688 | } | 
|---|
| 689 |  | 
|---|
| 690 | root->device = device; | 
|---|
| 691 | root->segment = segment & 0xFFFF; | 
|---|
| 692 | strscpy(acpi_device_name(device), ACPI_PCI_ROOT_DEVICE_NAME); | 
|---|
| 693 | strscpy(acpi_device_class(device), ACPI_PCI_ROOT_CLASS); | 
|---|
| 694 | device->driver_data = root; | 
|---|
| 695 |  | 
|---|
| 696 | if (hotadd && dmar_device_add(handle)) { | 
|---|
| 697 | result = -ENXIO; | 
|---|
| 698 | goto end; | 
|---|
| 699 | } | 
|---|
| 700 |  | 
|---|
| 701 | pr_info( "%s [%s] (domain %04x %pR)\n", | 
|---|
| 702 | acpi_device_name(device), acpi_device_bid(device), | 
|---|
| 703 | root->segment, &root->secondary); | 
|---|
| 704 |  | 
|---|
| 705 | root->mcfg_addr = acpi_pci_root_get_mcfg_addr(handle); | 
|---|
| 706 |  | 
|---|
| 707 | acpi_hid = acpi_device_hid(device: root->device); | 
|---|
| 708 | if (strcmp(acpi_hid, "PNP0A08") == 0) | 
|---|
| 709 | root->bridge_type = ACPI_BRIDGE_TYPE_PCIE; | 
|---|
| 710 | else if (strcmp(acpi_hid, "ACPI0016") == 0) | 
|---|
| 711 | root->bridge_type = ACPI_BRIDGE_TYPE_CXL; | 
|---|
| 712 | else | 
|---|
| 713 | dev_dbg(&device->dev, "Assuming non-PCIe host bridge\n"); | 
|---|
| 714 |  | 
|---|
| 715 | negotiate_os_control(root, no_aspm: &no_aspm); | 
|---|
| 716 |  | 
|---|
| 717 | /* | 
|---|
| 718 | * TBD: Need PCI interface for enumeration/configuration of roots. | 
|---|
| 719 | */ | 
|---|
| 720 |  | 
|---|
| 721 | /* | 
|---|
| 722 | * Scan the Root Bridge | 
|---|
| 723 | * -------------------- | 
|---|
| 724 | * Must do this prior to any attempt to bind the root device, as the | 
|---|
| 725 | * PCI namespace does not get created until this call is made (and | 
|---|
| 726 | * thus the root bridge's pci_dev does not exist). | 
|---|
| 727 | */ | 
|---|
| 728 | root->bus = pci_acpi_scan_root(root); | 
|---|
| 729 | if (!root->bus) { | 
|---|
| 730 | dev_err(&device->dev, | 
|---|
| 731 | "Bus %04x:%02x not present in PCI namespace\n", | 
|---|
| 732 | root->segment, (unsigned int)root->secondary.start); | 
|---|
| 733 | device->driver_data = NULL; | 
|---|
| 734 | result = -ENODEV; | 
|---|
| 735 | goto remove_dmar; | 
|---|
| 736 | } | 
|---|
| 737 |  | 
|---|
| 738 | if (no_aspm) | 
|---|
| 739 | pcie_no_aspm(); | 
|---|
| 740 |  | 
|---|
| 741 | pci_acpi_add_bus_pm_notifier(dev: device); | 
|---|
| 742 | device_set_wakeup_capable(dev: root->bus->bridge, capable: device->wakeup.flags.valid); | 
|---|
| 743 |  | 
|---|
| 744 | if (hotadd) { | 
|---|
| 745 | pcibios_resource_survey_bus(bus: root->bus); | 
|---|
| 746 | pci_assign_unassigned_root_bus_resources(bus: root->bus); | 
|---|
| 747 | /* | 
|---|
| 748 | * This is only called for the hotadd case. For the boot-time | 
|---|
| 749 | * case, we need to wait until after PCI initialization in | 
|---|
| 750 | * order to deal with IOAPICs mapped in on a PCI BAR. | 
|---|
| 751 | * | 
|---|
| 752 | * This is currently x86-specific, because acpi_ioapic_add() | 
|---|
| 753 | * is an empty function without CONFIG_ACPI_HOTPLUG_IOAPIC. | 
|---|
| 754 | * And CONFIG_ACPI_HOTPLUG_IOAPIC depends on CONFIG_X86_IO_APIC | 
|---|
| 755 | * (see drivers/acpi/Kconfig). | 
|---|
| 756 | */ | 
|---|
| 757 | acpi_ioapic_add(root: root->device->handle); | 
|---|
| 758 | } | 
|---|
| 759 |  | 
|---|
| 760 | pci_lock_rescan_remove(); | 
|---|
| 761 | pci_bus_add_devices(bus: root->bus); | 
|---|
| 762 | pci_unlock_rescan_remove(); | 
|---|
| 763 | return 1; | 
|---|
| 764 |  | 
|---|
| 765 | remove_dmar: | 
|---|
| 766 | if (hotadd) | 
|---|
| 767 | dmar_device_remove(handle); | 
|---|
| 768 | end: | 
|---|
| 769 | kfree(objp: root); | 
|---|
| 770 | return result; | 
|---|
| 771 | } | 
|---|
| 772 |  | 
|---|
| 773 | static void acpi_pci_root_remove(struct acpi_device *device) | 
|---|
| 774 | { | 
|---|
| 775 | struct acpi_pci_root *root = acpi_driver_data(d: device); | 
|---|
| 776 |  | 
|---|
| 777 | pci_lock_rescan_remove(); | 
|---|
| 778 |  | 
|---|
| 779 | pci_stop_root_bus(bus: root->bus); | 
|---|
| 780 |  | 
|---|
| 781 | pci_ioapic_remove(root); | 
|---|
| 782 | device_set_wakeup_capable(dev: root->bus->bridge, capable: false); | 
|---|
| 783 | pci_acpi_remove_bus_pm_notifier(dev: device); | 
|---|
| 784 |  | 
|---|
| 785 | pci_remove_root_bus(bus: root->bus); | 
|---|
| 786 | WARN_ON(acpi_ioapic_remove(root)); | 
|---|
| 787 |  | 
|---|
| 788 | dmar_device_remove(handle: device->handle); | 
|---|
| 789 |  | 
|---|
| 790 | pci_unlock_rescan_remove(); | 
|---|
| 791 |  | 
|---|
| 792 | kfree(objp: root); | 
|---|
| 793 | } | 
|---|
| 794 |  | 
|---|
| 795 | /* | 
|---|
| 796 | * Following code to support acpi_pci_root_create() is copied from | 
|---|
| 797 | * arch/x86/pci/acpi.c and modified so it could be reused by x86, IA64 | 
|---|
| 798 | * and ARM64. | 
|---|
| 799 | */ | 
|---|
| 800 | static void acpi_pci_root_validate_resources(struct device *dev, | 
|---|
| 801 | struct list_head *resources, | 
|---|
| 802 | unsigned long type) | 
|---|
| 803 | { | 
|---|
| 804 | LIST_HEAD(list); | 
|---|
| 805 | struct resource *res1, *res2, *root = NULL; | 
|---|
| 806 | struct resource_entry *tmp, *entry, *entry2; | 
|---|
| 807 |  | 
|---|
| 808 | BUG_ON((type & (IORESOURCE_MEM | IORESOURCE_IO)) == 0); | 
|---|
| 809 | root = (type & IORESOURCE_MEM) ? &iomem_resource : &ioport_resource; | 
|---|
| 810 |  | 
|---|
| 811 | list_splice_init(list: resources, head: &list); | 
|---|
| 812 | resource_list_for_each_entry_safe(entry, tmp, &list) { | 
|---|
| 813 | bool free = false; | 
|---|
| 814 | resource_size_t end; | 
|---|
| 815 |  | 
|---|
| 816 | res1 = entry->res; | 
|---|
| 817 | if (!(res1->flags & type)) | 
|---|
| 818 | goto next; | 
|---|
| 819 |  | 
|---|
| 820 | /* Exclude non-addressable range or non-addressable portion */ | 
|---|
| 821 | end = min(res1->end, root->end); | 
|---|
| 822 | if (end <= res1->start) { | 
|---|
| 823 | dev_info(dev, "host bridge window %pR (ignored, not CPU addressable)\n", | 
|---|
| 824 | res1); | 
|---|
| 825 | free = true; | 
|---|
| 826 | goto next; | 
|---|
| 827 | } else if (res1->end != end) { | 
|---|
| 828 | dev_info(dev, "host bridge window %pR ([%#llx-%#llx] ignored, not CPU addressable)\n", | 
|---|
| 829 | res1, (unsigned long long)end + 1, | 
|---|
| 830 | (unsigned long long)res1->end); | 
|---|
| 831 | res1->end = end; | 
|---|
| 832 | } | 
|---|
| 833 |  | 
|---|
| 834 | resource_list_for_each_entry(entry2, resources) { | 
|---|
| 835 | res2 = entry2->res; | 
|---|
| 836 | if (!(res2->flags & type)) | 
|---|
| 837 | continue; | 
|---|
| 838 |  | 
|---|
| 839 | /* | 
|---|
| 840 | * I don't like throwing away windows because then | 
|---|
| 841 | * our resources no longer match the ACPI _CRS, but | 
|---|
| 842 | * the kernel resource tree doesn't allow overlaps. | 
|---|
| 843 | */ | 
|---|
| 844 | if (resource_union(r1: res1, r2: res2, r: res2)) { | 
|---|
| 845 | dev_info(dev, "host bridge window expanded to %pR; %pR ignored\n", | 
|---|
| 846 | res2, res1); | 
|---|
| 847 | free = true; | 
|---|
| 848 | goto next; | 
|---|
| 849 | } | 
|---|
| 850 | } | 
|---|
| 851 |  | 
|---|
| 852 | next: | 
|---|
| 853 | resource_list_del(entry); | 
|---|
| 854 | if (free) | 
|---|
| 855 | resource_list_free_entry(entry); | 
|---|
| 856 | else | 
|---|
| 857 | resource_list_add_tail(entry, head: resources); | 
|---|
| 858 | } | 
|---|
| 859 | } | 
|---|
| 860 |  | 
|---|
| 861 | static void acpi_pci_root_remap_iospace(const struct fwnode_handle *fwnode, | 
|---|
| 862 | struct resource_entry *entry) | 
|---|
| 863 | { | 
|---|
| 864 | #ifdef PCI_IOBASE | 
|---|
| 865 | struct resource *res = entry->res; | 
|---|
| 866 | resource_size_t cpu_addr = res->start; | 
|---|
| 867 | resource_size_t pci_addr = cpu_addr - entry->offset; | 
|---|
| 868 | resource_size_t length = resource_size(res); | 
|---|
| 869 | unsigned long port; | 
|---|
| 870 |  | 
|---|
| 871 | if (pci_register_io_range(fwnode, cpu_addr, length)) | 
|---|
| 872 | goto err; | 
|---|
| 873 |  | 
|---|
| 874 | port = pci_address_to_pio(cpu_addr); | 
|---|
| 875 | if (port == (unsigned long)-1) | 
|---|
| 876 | goto err; | 
|---|
| 877 |  | 
|---|
| 878 | res->start = port; | 
|---|
| 879 | res->end = port + length - 1; | 
|---|
| 880 | entry->offset = port - pci_addr; | 
|---|
| 881 |  | 
|---|
| 882 | if (pci_remap_iospace(res, cpu_addr) < 0) | 
|---|
| 883 | goto err; | 
|---|
| 884 |  | 
|---|
| 885 | pr_info( "Remapped I/O %pa to %pR\n", &cpu_addr, res); | 
|---|
| 886 | return; | 
|---|
| 887 | err: | 
|---|
| 888 | res->flags |= IORESOURCE_DISABLED; | 
|---|
| 889 | #endif | 
|---|
| 890 | } | 
|---|
| 891 |  | 
|---|
| 892 | int acpi_pci_probe_root_resources(struct acpi_pci_root_info *info) | 
|---|
| 893 | { | 
|---|
| 894 | int ret; | 
|---|
| 895 | struct list_head *list = &info->resources; | 
|---|
| 896 | struct acpi_device *device = info->bridge; | 
|---|
| 897 | struct resource_entry *entry, *tmp; | 
|---|
| 898 | unsigned long flags; | 
|---|
| 899 |  | 
|---|
| 900 | flags = IORESOURCE_IO | IORESOURCE_MEM | IORESOURCE_MEM_8AND16BIT; | 
|---|
| 901 | ret = acpi_dev_get_resources(adev: device, list, | 
|---|
| 902 | preproc: acpi_dev_filter_resource_type_cb, | 
|---|
| 903 | preproc_data: (void *)flags); | 
|---|
| 904 | if (ret < 0) | 
|---|
| 905 | dev_warn(&device->dev, | 
|---|
| 906 | "failed to parse _CRS method, error code %d\n", ret); | 
|---|
| 907 | else if (ret == 0) | 
|---|
| 908 | dev_dbg(&device->dev, | 
|---|
| 909 | "no IO and memory resources present in _CRS\n"); | 
|---|
| 910 | else { | 
|---|
| 911 | resource_list_for_each_entry_safe(entry, tmp, list) { | 
|---|
| 912 | if (entry->res->flags & IORESOURCE_IO) | 
|---|
| 913 | acpi_pci_root_remap_iospace(fwnode: &device->fwnode, | 
|---|
| 914 | entry); | 
|---|
| 915 |  | 
|---|
| 916 | if (entry->res->flags & IORESOURCE_DISABLED) | 
|---|
| 917 | resource_list_destroy_entry(entry); | 
|---|
| 918 | else | 
|---|
| 919 | entry->res->name = info->name; | 
|---|
| 920 | } | 
|---|
| 921 | acpi_pci_root_validate_resources(dev: &device->dev, resources: list, | 
|---|
| 922 | IORESOURCE_MEM); | 
|---|
| 923 | acpi_pci_root_validate_resources(dev: &device->dev, resources: list, | 
|---|
| 924 | IORESOURCE_IO); | 
|---|
| 925 | } | 
|---|
| 926 |  | 
|---|
| 927 | return ret; | 
|---|
| 928 | } | 
|---|
| 929 |  | 
|---|
| 930 | static void pci_acpi_root_add_resources(struct acpi_pci_root_info *info) | 
|---|
| 931 | { | 
|---|
| 932 | struct resource_entry *entry, *tmp; | 
|---|
| 933 | struct resource *res, *conflict, *root = NULL; | 
|---|
| 934 |  | 
|---|
| 935 | resource_list_for_each_entry_safe(entry, tmp, &info->resources) { | 
|---|
| 936 | res = entry->res; | 
|---|
| 937 | if (res->flags & IORESOURCE_MEM) | 
|---|
| 938 | root = &iomem_resource; | 
|---|
| 939 | else if (res->flags & IORESOURCE_IO) | 
|---|
| 940 | root = &ioport_resource; | 
|---|
| 941 | else | 
|---|
| 942 | continue; | 
|---|
| 943 |  | 
|---|
| 944 | /* | 
|---|
| 945 | * Some legacy x86 host bridge drivers use iomem_resource and | 
|---|
| 946 | * ioport_resource as default resource pool, skip it. | 
|---|
| 947 | */ | 
|---|
| 948 | if (res == root) | 
|---|
| 949 | continue; | 
|---|
| 950 |  | 
|---|
| 951 | conflict = insert_resource_conflict(parent: root, new: res); | 
|---|
| 952 | if (conflict) { | 
|---|
| 953 | dev_info(&info->bridge->dev, | 
|---|
| 954 | "ignoring host bridge window %pR (conflicts with %s %pR)\n", | 
|---|
| 955 | res, conflict->name, conflict); | 
|---|
| 956 | resource_list_destroy_entry(entry); | 
|---|
| 957 | } | 
|---|
| 958 | } | 
|---|
| 959 | } | 
|---|
| 960 |  | 
|---|
| 961 | static void __acpi_pci_root_release_info(struct acpi_pci_root_info *info) | 
|---|
| 962 | { | 
|---|
| 963 | struct resource *res; | 
|---|
| 964 | struct resource_entry *entry, *tmp; | 
|---|
| 965 |  | 
|---|
| 966 | if (!info) | 
|---|
| 967 | return; | 
|---|
| 968 |  | 
|---|
| 969 | resource_list_for_each_entry_safe(entry, tmp, &info->resources) { | 
|---|
| 970 | res = entry->res; | 
|---|
| 971 | if (res->parent && | 
|---|
| 972 | (res->flags & (IORESOURCE_MEM | IORESOURCE_IO))) | 
|---|
| 973 | release_resource(new: res); | 
|---|
| 974 | resource_list_destroy_entry(entry); | 
|---|
| 975 | } | 
|---|
| 976 |  | 
|---|
| 977 | info->ops->release_info(info); | 
|---|
| 978 | } | 
|---|
| 979 |  | 
|---|
| 980 | static void acpi_pci_root_release_info(struct pci_host_bridge *bridge) | 
|---|
| 981 | { | 
|---|
| 982 | struct resource *res; | 
|---|
| 983 | struct resource_entry *entry; | 
|---|
| 984 |  | 
|---|
| 985 | resource_list_for_each_entry(entry, &bridge->windows) { | 
|---|
| 986 | res = entry->res; | 
|---|
| 987 | if (res->flags & IORESOURCE_IO) | 
|---|
| 988 | pci_unmap_iospace(res); | 
|---|
| 989 | if (res->parent && | 
|---|
| 990 | (res->flags & (IORESOURCE_MEM | IORESOURCE_IO))) | 
|---|
| 991 | release_resource(new: res); | 
|---|
| 992 | } | 
|---|
| 993 | __acpi_pci_root_release_info(info: bridge->release_data); | 
|---|
| 994 | } | 
|---|
| 995 |  | 
|---|
| 996 | struct pci_bus *acpi_pci_root_create(struct acpi_pci_root *root, | 
|---|
| 997 | struct acpi_pci_root_ops *ops, | 
|---|
| 998 | struct acpi_pci_root_info *info, | 
|---|
| 999 | void *sysdata) | 
|---|
| 1000 | { | 
|---|
| 1001 | int ret, busnum = root->secondary.start; | 
|---|
| 1002 | struct acpi_device *device = root->device; | 
|---|
| 1003 | int node = acpi_get_node(handle: device->handle); | 
|---|
| 1004 | struct pci_bus *bus; | 
|---|
| 1005 | struct pci_host_bridge *host_bridge; | 
|---|
| 1006 |  | 
|---|
| 1007 | info->root = root; | 
|---|
| 1008 | info->bridge = device; | 
|---|
| 1009 | info->ops = ops; | 
|---|
| 1010 | INIT_LIST_HEAD(list: &info->resources); | 
|---|
| 1011 | snprintf(buf: info->name, size: sizeof(info->name), fmt: "PCI Bus %04x:%02x", | 
|---|
| 1012 | root->segment, busnum); | 
|---|
| 1013 |  | 
|---|
| 1014 | if (ops->init_info && ops->init_info(info)) | 
|---|
| 1015 | goto out_release_info; | 
|---|
| 1016 | if (ops->prepare_resources) | 
|---|
| 1017 | ret = ops->prepare_resources(info); | 
|---|
| 1018 | else | 
|---|
| 1019 | ret = acpi_pci_probe_root_resources(info); | 
|---|
| 1020 | if (ret < 0) | 
|---|
| 1021 | goto out_release_info; | 
|---|
| 1022 |  | 
|---|
| 1023 | pci_acpi_root_add_resources(info); | 
|---|
| 1024 | pci_add_resource(resources: &info->resources, res: &root->secondary); | 
|---|
| 1025 | bus = pci_create_root_bus(NULL, bus: busnum, ops: ops->pci_ops, | 
|---|
| 1026 | sysdata, resources: &info->resources); | 
|---|
| 1027 | if (!bus) | 
|---|
| 1028 | goto out_release_info; | 
|---|
| 1029 |  | 
|---|
| 1030 | host_bridge = to_pci_host_bridge(bus->bridge); | 
|---|
| 1031 | if (!(root->osc_control_set & OSC_PCI_EXPRESS_NATIVE_HP_CONTROL)) | 
|---|
| 1032 | host_bridge->native_pcie_hotplug = 0; | 
|---|
| 1033 | if (!(root->osc_control_set & OSC_PCI_SHPC_NATIVE_HP_CONTROL)) | 
|---|
| 1034 | host_bridge->native_shpc_hotplug = 0; | 
|---|
| 1035 | if (!(root->osc_control_set & OSC_PCI_EXPRESS_AER_CONTROL)) | 
|---|
| 1036 | host_bridge->native_aer = 0; | 
|---|
| 1037 | if (!(root->osc_control_set & OSC_PCI_EXPRESS_PME_CONTROL)) | 
|---|
| 1038 | host_bridge->native_pme = 0; | 
|---|
| 1039 | if (!(root->osc_control_set & OSC_PCI_EXPRESS_LTR_CONTROL)) | 
|---|
| 1040 | host_bridge->native_ltr = 0; | 
|---|
| 1041 | if (!(root->osc_control_set & OSC_PCI_EXPRESS_DPC_CONTROL)) | 
|---|
| 1042 | host_bridge->native_dpc = 0; | 
|---|
| 1043 |  | 
|---|
| 1044 | if (!(root->osc_ext_control_set & OSC_CXL_ERROR_REPORTING_CONTROL)) | 
|---|
| 1045 | host_bridge->native_cxl_error = 0; | 
|---|
| 1046 |  | 
|---|
| 1047 | acpi_dev_power_up_children_with_adr(adev: device); | 
|---|
| 1048 |  | 
|---|
| 1049 | pci_scan_child_bus(bus); | 
|---|
| 1050 | pci_set_host_bridge_release(bridge: host_bridge, release_fn: acpi_pci_root_release_info, | 
|---|
| 1051 | release_data: info); | 
|---|
| 1052 | if (node != NUMA_NO_NODE) | 
|---|
| 1053 | dev_printk(KERN_DEBUG, &bus->dev, "on NUMA node %d\n", node); | 
|---|
| 1054 | return bus; | 
|---|
| 1055 |  | 
|---|
| 1056 | out_release_info: | 
|---|
| 1057 | __acpi_pci_root_release_info(info); | 
|---|
| 1058 | return NULL; | 
|---|
| 1059 | } | 
|---|
| 1060 |  | 
|---|
| 1061 | void __init acpi_pci_root_init(void) | 
|---|
| 1062 | { | 
|---|
| 1063 | if (acpi_pci_disabled) | 
|---|
| 1064 | return; | 
|---|
| 1065 |  | 
|---|
| 1066 | pci_acpi_crs_quirks(); | 
|---|
| 1067 | acpi_scan_add_handler_with_hotplug(handler: &pci_root_handler, hotplug_profile_name: "pci_root"); | 
|---|
| 1068 | } | 
|---|
| 1069 |  | 
|---|