1 // SPDX-License-Identifier: GPL-2.0+ 2 /* 3 * Common ACPI functions for hot plug platforms 4 * 5 * Copyright (C) 2006 Intel Corporation 6 * 7 * All rights reserved. 8 * 9 * Send feedback to <kristen.c.accardi@intel.com> 10 * 11 */ 12 13 #include <linux/module.h> 14 #include <linux/moduleparam.h> 15 #include <linux/kernel.h> 16 #include <linux/types.h> 17 #include <linux/pci.h> 18 #include <linux/pci_hotplug.h> 19 #include <linux/acpi.h> 20 #include <linux/pci-acpi.h> 21 #include <linux/slab.h> 22 23 #define MY_NAME "acpi_pcihp" 24 25 #define dbg(fmt, arg...) do { if (debug_acpi) printk(KERN_DEBUG "%s: %s: " fmt, MY_NAME, __func__, ## arg); } while (0) 26 #define err(format, arg...) printk(KERN_ERR "%s: " format, MY_NAME, ## arg) 27 #define info(format, arg...) printk(KERN_INFO "%s: " format, MY_NAME, ## arg) 28 #define warn(format, arg...) printk(KERN_WARNING "%s: " format, MY_NAME, ## arg) 29 30 #define METHOD_NAME__SUN "_SUN" 31 #define METHOD_NAME_OSHP "OSHP" 32 33 static bool debug_acpi; 34 35 /* acpi_run_oshp - get control of hotplug from the firmware 36 * 37 * @handle - the handle of the hotplug controller. 38 */ 39 static acpi_status acpi_run_oshp(acpi_handle handle) 40 { 41 acpi_status status; 42 struct acpi_buffer string = { ACPI_ALLOCATE_BUFFER, NULL }; 43 44 acpi_get_name(handle, ACPI_FULL_PATHNAME, &string); 45 46 /* run OSHP */ 47 status = acpi_evaluate_object(handle, METHOD_NAME_OSHP, NULL, NULL); 48 if (ACPI_FAILURE(status)) 49 if (status != AE_NOT_FOUND) 50 printk(KERN_ERR "%s:%s OSHP fails=0x%x\n", 51 __func__, (char *)string.pointer, status); 52 else 53 dbg("%s:%s OSHP not found\n", 54 __func__, (char *)string.pointer); 55 else 56 pr_debug("%s:%s OSHP passes\n", __func__, 57 (char *)string.pointer); 58 59 kfree(string.pointer); 60 return status; 61 } 62 63 /** 64 * acpi_get_hp_hw_control_from_firmware 65 * @dev: the pci_dev of the bridge that has a hotplug controller 66 * 67 * Attempt to take hotplug control from firmware. 68 */ 69 int acpi_get_hp_hw_control_from_firmware(struct pci_dev *pdev) 70 { 71 const struct pci_host_bridge *host; 72 const struct acpi_pci_root *root; 73 acpi_status status; 74 acpi_handle chandle, handle; 75 struct acpi_buffer string = { ACPI_ALLOCATE_BUFFER, NULL }; 76 77 /* 78 * Per PCI firmware specification, we should run the ACPI _OSC 79 * method to get control of hotplug hardware before using it. If 80 * an _OSC is missing, we look for an OSHP to do the same thing. 81 * To handle different BIOS behavior, we look for _OSC on a root 82 * bridge preferentially (according to PCI fw spec). Later for 83 * OSHP within the scope of the hotplug controller and its parents, 84 * up to the host bridge under which this controller exists. 85 */ 86 if (shpchp_is_native(pdev)) 87 return 0; 88 89 /* If _OSC exists, we should not evaluate OSHP */ 90 host = pci_find_host_bridge(pdev->bus); 91 root = acpi_pci_find_root(ACPI_HANDLE(&host->dev)); 92 if (root->osc_support_set) 93 goto no_control; 94 95 handle = ACPI_HANDLE(&pdev->dev); 96 if (!handle) { 97 /* 98 * This hotplug controller was not listed in the ACPI name 99 * space at all. Try to get ACPI handle of parent PCI bus. 100 */ 101 struct pci_bus *pbus; 102 for (pbus = pdev->bus; pbus; pbus = pbus->parent) { 103 handle = acpi_pci_get_bridge_handle(pbus); 104 if (handle) 105 break; 106 } 107 } 108 109 while (handle) { 110 acpi_get_name(handle, ACPI_FULL_PATHNAME, &string); 111 pci_info(pdev, "Requesting control of SHPC hotplug via OSHP (%s)\n", 112 (char *)string.pointer); 113 status = acpi_run_oshp(handle); 114 if (ACPI_SUCCESS(status)) 115 goto got_one; 116 if (acpi_is_root_bridge(handle)) 117 break; 118 chandle = handle; 119 status = acpi_get_parent(chandle, &handle); 120 if (ACPI_FAILURE(status)) 121 break; 122 } 123 no_control: 124 pci_info(pdev, "Cannot get control of SHPC hotplug\n"); 125 kfree(string.pointer); 126 return -ENODEV; 127 got_one: 128 pci_info(pdev, "Gained control of SHPC hotplug (%s)\n", 129 (char *)string.pointer); 130 kfree(string.pointer); 131 return 0; 132 } 133 EXPORT_SYMBOL(acpi_get_hp_hw_control_from_firmware); 134 135 static int pcihp_is_ejectable(acpi_handle handle) 136 { 137 acpi_status status; 138 unsigned long long removable; 139 if (!acpi_has_method(handle, "_ADR")) 140 return 0; 141 if (acpi_has_method(handle, "_EJ0")) 142 return 1; 143 status = acpi_evaluate_integer(handle, "_RMV", NULL, &removable); 144 if (ACPI_SUCCESS(status) && removable) 145 return 1; 146 return 0; 147 } 148 149 /** 150 * acpi_pcihp_check_ejectable - check if handle is ejectable ACPI PCI slot 151 * @pbus: the PCI bus of the PCI slot corresponding to 'handle' 152 * @handle: ACPI handle to check 153 * 154 * Return 1 if handle is ejectable PCI slot, 0 otherwise. 155 */ 156 int acpi_pci_check_ejectable(struct pci_bus *pbus, acpi_handle handle) 157 { 158 acpi_handle bridge_handle, parent_handle; 159 160 bridge_handle = acpi_pci_get_bridge_handle(pbus); 161 if (!bridge_handle) 162 return 0; 163 if ((ACPI_FAILURE(acpi_get_parent(handle, &parent_handle)))) 164 return 0; 165 if (bridge_handle != parent_handle) 166 return 0; 167 return pcihp_is_ejectable(handle); 168 } 169 EXPORT_SYMBOL_GPL(acpi_pci_check_ejectable); 170 171 static acpi_status 172 check_hotplug(acpi_handle handle, u32 lvl, void *context, void **rv) 173 { 174 int *found = (int *)context; 175 if (pcihp_is_ejectable(handle)) { 176 *found = 1; 177 return AE_CTRL_TERMINATE; 178 } 179 return AE_OK; 180 } 181 182 /** 183 * acpi_pci_detect_ejectable - check if the PCI bus has ejectable slots 184 * @handle - handle of the PCI bus to scan 185 * 186 * Returns 1 if the PCI bus has ACPI based ejectable slots, 0 otherwise. 187 */ 188 int acpi_pci_detect_ejectable(acpi_handle handle) 189 { 190 int found = 0; 191 192 if (!handle) 193 return found; 194 195 acpi_walk_namespace(ACPI_TYPE_DEVICE, handle, 1, 196 check_hotplug, NULL, (void *)&found, NULL); 197 return found; 198 } 199 EXPORT_SYMBOL_GPL(acpi_pci_detect_ejectable); 200 201 module_param(debug_acpi, bool, 0644); 202 MODULE_PARM_DESC(debug_acpi, "Debugging mode for ACPI enabled or not"); 203