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 <linux/pci-aspm.h> 15 #include <acpi/acpi.h> 16 #include <acpi/acpi_bus.h> 17 18 #include <linux/pci-acpi.h> 19 #include "pci.h" 20 21 /* 22 * _SxD returns the D-state with the highest power 23 * (lowest D-state number) supported in the S-state "x". 24 * 25 * If the devices does not have a _PRW 26 * (Power Resources for Wake) supporting system wakeup from "x" 27 * then the OS is free to choose a lower power (higher number 28 * D-state) than the return value from _SxD. 29 * 30 * But if _PRW is enabled at S-state "x", the OS 31 * must not choose a power lower than _SxD -- 32 * unless the device has an _SxW method specifying 33 * the lowest power (highest D-state number) the device 34 * may enter while still able to wake the system. 35 * 36 * ie. depending on global OS policy: 37 * 38 * if (_PRW at S-state x) 39 * choose from highest power _SxD to lowest power _SxW 40 * else // no _PRW at S-state x 41 * choose highest power _SxD or any lower power 42 */ 43 44 static pci_power_t acpi_pci_choose_state(struct pci_dev *pdev) 45 { 46 int acpi_state; 47 48 acpi_state = acpi_pm_device_sleep_state(&pdev->dev, NULL); 49 if (acpi_state < 0) 50 return PCI_POWER_ERROR; 51 52 switch (acpi_state) { 53 case ACPI_STATE_D0: 54 return PCI_D0; 55 case ACPI_STATE_D1: 56 return PCI_D1; 57 case ACPI_STATE_D2: 58 return PCI_D2; 59 case ACPI_STATE_D3: 60 return PCI_D3hot; 61 } 62 return PCI_POWER_ERROR; 63 } 64 65 static bool acpi_pci_power_manageable(struct pci_dev *dev) 66 { 67 acpi_handle handle = DEVICE_ACPI_HANDLE(&dev->dev); 68 69 return handle ? acpi_bus_power_manageable(handle) : false; 70 } 71 72 static int acpi_pci_set_power_state(struct pci_dev *dev, pci_power_t state) 73 { 74 acpi_handle handle = DEVICE_ACPI_HANDLE(&dev->dev); 75 acpi_handle tmp; 76 static const u8 state_conv[] = { 77 [PCI_D0] = ACPI_STATE_D0, 78 [PCI_D1] = ACPI_STATE_D1, 79 [PCI_D2] = ACPI_STATE_D2, 80 [PCI_D3hot] = ACPI_STATE_D3, 81 [PCI_D3cold] = ACPI_STATE_D3 82 }; 83 int error = -EINVAL; 84 85 /* If the ACPI device has _EJ0, ignore the device */ 86 if (!handle || ACPI_SUCCESS(acpi_get_handle(handle, "_EJ0", &tmp))) 87 return -ENODEV; 88 89 switch (state) { 90 case PCI_D0: 91 case PCI_D1: 92 case PCI_D2: 93 case PCI_D3hot: 94 case PCI_D3cold: 95 error = acpi_bus_set_power(handle, state_conv[state]); 96 } 97 98 if (!error) 99 dev_printk(KERN_INFO, &dev->dev, 100 "power state changed by ACPI to D%d\n", state); 101 102 return error; 103 } 104 105 static bool acpi_pci_can_wakeup(struct pci_dev *dev) 106 { 107 acpi_handle handle = DEVICE_ACPI_HANDLE(&dev->dev); 108 109 return handle ? acpi_bus_can_wakeup(handle) : false; 110 } 111 112 static int acpi_pci_sleep_wake(struct pci_dev *dev, bool enable) 113 { 114 int error = acpi_pm_device_sleep_wake(&dev->dev, enable); 115 116 if (!error) 117 dev_printk(KERN_INFO, &dev->dev, 118 "wake-up capability %s by ACPI\n", 119 enable ? "enabled" : "disabled"); 120 return error; 121 } 122 123 static struct pci_platform_pm_ops acpi_pci_platform_pm = { 124 .is_manageable = acpi_pci_power_manageable, 125 .set_state = acpi_pci_set_power_state, 126 .choose_state = acpi_pci_choose_state, 127 .can_wakeup = acpi_pci_can_wakeup, 128 .sleep_wake = acpi_pci_sleep_wake, 129 }; 130 131 /* ACPI bus type */ 132 static int acpi_pci_find_device(struct device *dev, acpi_handle *handle) 133 { 134 struct pci_dev * pci_dev; 135 acpi_integer addr; 136 137 pci_dev = to_pci_dev(dev); 138 /* Please ref to ACPI spec for the syntax of _ADR */ 139 addr = (PCI_SLOT(pci_dev->devfn) << 16) | PCI_FUNC(pci_dev->devfn); 140 *handle = acpi_get_child(DEVICE_ACPI_HANDLE(dev->parent), addr); 141 if (!*handle) 142 return -ENODEV; 143 return 0; 144 } 145 146 static int acpi_pci_find_root_bridge(struct device *dev, acpi_handle *handle) 147 { 148 int num; 149 unsigned int seg, bus; 150 151 /* 152 * The string should be the same as root bridge's name 153 * Please look at 'pci_scan_bus_parented' 154 */ 155 num = sscanf(dev_name(dev), "pci%04x:%02x", &seg, &bus); 156 if (num != 2) 157 return -ENODEV; 158 *handle = acpi_get_pci_rootbridge_handle(seg, bus); 159 if (!*handle) 160 return -ENODEV; 161 return 0; 162 } 163 164 static struct acpi_bus_type acpi_pci_bus = { 165 .bus = &pci_bus_type, 166 .find_device = acpi_pci_find_device, 167 .find_bridge = acpi_pci_find_root_bridge, 168 }; 169 170 static int __init acpi_pci_init(void) 171 { 172 int ret; 173 174 if (acpi_gbl_FADT.boot_flags & ACPI_FADT_NO_MSI) { 175 printk(KERN_INFO"ACPI FADT declares the system doesn't support MSI, so disable it\n"); 176 pci_no_msi(); 177 } 178 179 if (acpi_gbl_FADT.boot_flags & ACPI_FADT_NO_ASPM) { 180 printk(KERN_INFO"ACPI FADT declares the system doesn't support PCIe ASPM, so disable it\n"); 181 pcie_no_aspm(); 182 } 183 184 ret = register_acpi_bus_type(&acpi_pci_bus); 185 if (ret) 186 return 0; 187 pci_set_platform_pm(&acpi_pci_platform_pm); 188 return 0; 189 } 190 arch_initcall(acpi_pci_init); 191