1 /* 2 * File: pci-acpi.c 3 * Purpose: Provide PCI support in ACPI 4 * 5 * Copyright (C) 2005 David Shaohua Li <shaohua.li@intel.com> 6 * Copyright (C) 2004 Tom Long Nguyen <tom.l.nguyen@intel.com> 7 * Copyright (C) 2004 Intel Corp. 8 */ 9 10 #include <linux/delay.h> 11 #include <linux/init.h> 12 #include <linux/pci.h> 13 #include <linux/module.h> 14 #include <acpi/acpi.h> 15 #include <acpi/acnamesp.h> 16 #include <acpi/acresrc.h> 17 #include <acpi/acpi_bus.h> 18 19 #include <linux/pci-acpi.h> 20 #include "pci.h" 21 22 static u32 ctrlset_buf[3] = {0, 0, 0}; 23 static u32 global_ctrlsets = 0; 24 static u8 OSC_UUID[16] = {0x5B, 0x4D, 0xDB, 0x33, 0xF7, 0x1F, 0x1C, 0x40, 0x96, 0x57, 0x74, 0x41, 0xC0, 0x3D, 0xD7, 0x66}; 25 26 static acpi_status 27 acpi_query_osc ( 28 acpi_handle handle, 29 u32 level, 30 void *context, 31 void **retval ) 32 { 33 acpi_status status; 34 struct acpi_object_list input; 35 union acpi_object in_params[4]; 36 struct acpi_buffer output; 37 union acpi_object out_obj; 38 u32 osc_dw0; 39 40 /* Setting up output buffer */ 41 output.length = sizeof(out_obj) + 3*sizeof(u32); 42 output.pointer = &out_obj; 43 44 /* Setting up input parameters */ 45 input.count = 4; 46 input.pointer = in_params; 47 in_params[0].type = ACPI_TYPE_BUFFER; 48 in_params[0].buffer.length = 16; 49 in_params[0].buffer.pointer = OSC_UUID; 50 in_params[1].type = ACPI_TYPE_INTEGER; 51 in_params[1].integer.value = 1; 52 in_params[2].type = ACPI_TYPE_INTEGER; 53 in_params[2].integer.value = 3; 54 in_params[3].type = ACPI_TYPE_BUFFER; 55 in_params[3].buffer.length = 12; 56 in_params[3].buffer.pointer = (u8 *)context; 57 58 status = acpi_evaluate_object(handle, "_OSC", &input, &output); 59 if (ACPI_FAILURE (status)) { 60 printk(KERN_DEBUG 61 "Evaluate _OSC Set fails. Status = 0x%04x\n", status); 62 return status; 63 } 64 if (out_obj.type != ACPI_TYPE_BUFFER) { 65 printk(KERN_DEBUG 66 "Evaluate _OSC returns wrong type\n"); 67 return AE_TYPE; 68 } 69 osc_dw0 = *((u32 *) out_obj.buffer.pointer); 70 if (osc_dw0) { 71 if (osc_dw0 & OSC_REQUEST_ERROR) 72 printk(KERN_DEBUG "_OSC request fails\n"); 73 if (osc_dw0 & OSC_INVALID_UUID_ERROR) 74 printk(KERN_DEBUG "_OSC invalid UUID\n"); 75 if (osc_dw0 & OSC_INVALID_REVISION_ERROR) 76 printk(KERN_DEBUG "_OSC invalid revision\n"); 77 if (osc_dw0 & OSC_CAPABILITIES_MASK_ERROR) { 78 /* Update Global Control Set */ 79 global_ctrlsets = *((u32 *)(out_obj.buffer.pointer+8)); 80 return AE_OK; 81 } 82 return AE_ERROR; 83 } 84 85 /* Update Global Control Set */ 86 global_ctrlsets = *((u32 *)(out_obj.buffer.pointer + 8)); 87 return AE_OK; 88 } 89 90 91 static acpi_status 92 acpi_run_osc ( 93 acpi_handle handle, 94 void *context) 95 { 96 acpi_status status; 97 struct acpi_object_list input; 98 union acpi_object in_params[4]; 99 struct acpi_buffer output; 100 union acpi_object out_obj; 101 u32 osc_dw0; 102 103 /* Setting up output buffer */ 104 output.length = sizeof(out_obj) + 3*sizeof(u32); 105 output.pointer = &out_obj; 106 107 /* Setting up input parameters */ 108 input.count = 4; 109 input.pointer = in_params; 110 in_params[0].type = ACPI_TYPE_BUFFER; 111 in_params[0].buffer.length = 16; 112 in_params[0].buffer.pointer = OSC_UUID; 113 in_params[1].type = ACPI_TYPE_INTEGER; 114 in_params[1].integer.value = 1; 115 in_params[2].type = ACPI_TYPE_INTEGER; 116 in_params[2].integer.value = 3; 117 in_params[3].type = ACPI_TYPE_BUFFER; 118 in_params[3].buffer.length = 12; 119 in_params[3].buffer.pointer = (u8 *)context; 120 121 status = acpi_evaluate_object(handle, "_OSC", &input, &output); 122 if (ACPI_FAILURE (status)) { 123 printk(KERN_DEBUG 124 "Evaluate _OSC Set fails. Status = 0x%04x\n", status); 125 return status; 126 } 127 if (out_obj.type != ACPI_TYPE_BUFFER) { 128 printk(KERN_DEBUG 129 "Evaluate _OSC returns wrong type\n"); 130 return AE_TYPE; 131 } 132 osc_dw0 = *((u32 *) out_obj.buffer.pointer); 133 if (osc_dw0) { 134 if (osc_dw0 & OSC_REQUEST_ERROR) 135 printk(KERN_DEBUG "_OSC request fails\n"); 136 if (osc_dw0 & OSC_INVALID_UUID_ERROR) 137 printk(KERN_DEBUG "_OSC invalid UUID\n"); 138 if (osc_dw0 & OSC_INVALID_REVISION_ERROR) 139 printk(KERN_DEBUG "_OSC invalid revision\n"); 140 if (osc_dw0 & OSC_CAPABILITIES_MASK_ERROR) { 141 printk(KERN_DEBUG "_OSC FW not grant req. control\n"); 142 return AE_SUPPORT; 143 } 144 return AE_ERROR; 145 } 146 return AE_OK; 147 } 148 149 /** 150 * pci_osc_support_set - register OS support to Firmware 151 * @flags: OS support bits 152 * 153 * Update OS support fields and doing a _OSC Query to obtain an update 154 * from Firmware on supported control bits. 155 **/ 156 acpi_status pci_osc_support_set(u32 flags) 157 { 158 u32 temp; 159 160 if (!(flags & OSC_SUPPORT_MASKS)) { 161 return AE_TYPE; 162 } 163 ctrlset_buf[OSC_SUPPORT_TYPE] |= (flags & OSC_SUPPORT_MASKS); 164 165 /* do _OSC query for all possible controls */ 166 temp = ctrlset_buf[OSC_CONTROL_TYPE]; 167 ctrlset_buf[OSC_QUERY_TYPE] = OSC_QUERY_ENABLE; 168 ctrlset_buf[OSC_CONTROL_TYPE] = OSC_CONTROL_MASKS; 169 acpi_get_devices ( PCI_ROOT_HID_STRING, 170 acpi_query_osc, 171 ctrlset_buf, 172 NULL ); 173 ctrlset_buf[OSC_QUERY_TYPE] = !OSC_QUERY_ENABLE; 174 ctrlset_buf[OSC_CONTROL_TYPE] = temp; 175 return AE_OK; 176 } 177 EXPORT_SYMBOL(pci_osc_support_set); 178 179 /** 180 * pci_osc_control_set - commit requested control to Firmware 181 * @handle: acpi_handle for the target ACPI object 182 * @flags: driver's requested control bits 183 * 184 * Attempt to take control from Firmware on requested control bits. 185 **/ 186 acpi_status pci_osc_control_set(acpi_handle handle, u32 flags) 187 { 188 acpi_status status; 189 u32 ctrlset; 190 191 ctrlset = (flags & OSC_CONTROL_MASKS); 192 if (!ctrlset) { 193 return AE_TYPE; 194 } 195 if (ctrlset_buf[OSC_SUPPORT_TYPE] && 196 ((global_ctrlsets & ctrlset) != ctrlset)) { 197 return AE_SUPPORT; 198 } 199 ctrlset_buf[OSC_CONTROL_TYPE] |= ctrlset; 200 status = acpi_run_osc(handle, ctrlset_buf); 201 if (ACPI_FAILURE (status)) { 202 ctrlset_buf[OSC_CONTROL_TYPE] &= ~ctrlset; 203 } 204 205 return status; 206 } 207 EXPORT_SYMBOL(pci_osc_control_set); 208 209 /* 210 * _SxD returns the D-state with the highest power 211 * (lowest D-state number) supported in the S-state "x". 212 * 213 * If the devices does not have a _PRW 214 * (Power Resources for Wake) supporting system wakeup from "x" 215 * then the OS is free to choose a lower power (higher number 216 * D-state) than the return value from _SxD. 217 * 218 * But if _PRW is enabled at S-state "x", the OS 219 * must not choose a power lower than _SxD -- 220 * unless the device has an _SxW method specifying 221 * the lowest power (highest D-state number) the device 222 * may enter while still able to wake the system. 223 * 224 * ie. depending on global OS policy: 225 * 226 * if (_PRW at S-state x) 227 * choose from highest power _SxD to lowest power _SxW 228 * else // no _PRW at S-state x 229 * choose highest power _SxD or any lower power 230 * 231 * currently we simply return _SxD, if present. 232 */ 233 234 static int acpi_pci_choose_state(struct pci_dev *pdev, pm_message_t state) 235 { 236 /* TBD */ 237 238 return -ENODEV; 239 } 240 241 static int acpi_pci_set_power_state(struct pci_dev *dev, pci_power_t state) 242 { 243 acpi_handle handle = DEVICE_ACPI_HANDLE(&dev->dev); 244 static int state_conv[] = { 245 [0] = 0, 246 [1] = 1, 247 [2] = 2, 248 [3] = 3, 249 [4] = 3 250 }; 251 int acpi_state = state_conv[(int __force) state]; 252 253 if (!handle) 254 return -ENODEV; 255 return acpi_bus_set_power(handle, acpi_state); 256 } 257 258 259 /* ACPI bus type */ 260 static int pci_acpi_find_device(struct device *dev, acpi_handle *handle) 261 { 262 struct pci_dev * pci_dev; 263 acpi_integer addr; 264 265 pci_dev = to_pci_dev(dev); 266 /* Please ref to ACPI spec for the syntax of _ADR */ 267 addr = (PCI_SLOT(pci_dev->devfn) << 16) | PCI_FUNC(pci_dev->devfn); 268 *handle = acpi_get_child(DEVICE_ACPI_HANDLE(dev->parent), addr); 269 if (!*handle) 270 return -ENODEV; 271 return 0; 272 } 273 274 static int pci_acpi_find_root_bridge(struct device *dev, acpi_handle *handle) 275 { 276 int num; 277 unsigned int seg, bus; 278 279 /* 280 * The string should be the same as root bridge's name 281 * Please look at 'pci_scan_bus_parented' 282 */ 283 num = sscanf(dev->bus_id, "pci%04x:%02x", &seg, &bus); 284 if (num != 2) 285 return -ENODEV; 286 *handle = acpi_get_pci_rootbridge_handle(seg, bus); 287 if (!*handle) 288 return -ENODEV; 289 return 0; 290 } 291 292 static struct acpi_bus_type pci_acpi_bus = { 293 .bus = &pci_bus_type, 294 .find_device = pci_acpi_find_device, 295 .find_bridge = pci_acpi_find_root_bridge, 296 }; 297 298 static int __init pci_acpi_init(void) 299 { 300 int ret; 301 302 ret = register_acpi_bus_type(&pci_acpi_bus); 303 if (ret) 304 return 0; 305 platform_pci_choose_state = acpi_pci_choose_state; 306 platform_pci_set_power_state = acpi_pci_set_power_state; 307 return 0; 308 } 309 arch_initcall(pci_acpi_init); 310