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 void acpi_pci_propagate_wakeup_enable(struct pci_bus *bus, bool enable) 113 { 114 while (bus->parent) { 115 if (!acpi_pm_device_sleep_wake(&bus->self->dev, enable)) 116 return; 117 bus = bus->parent; 118 } 119 120 /* We have reached the root bus. */ 121 if (bus->bridge) 122 acpi_pm_device_sleep_wake(bus->bridge, enable); 123 } 124 125 static int acpi_pci_sleep_wake(struct pci_dev *dev, bool enable) 126 { 127 if (acpi_pci_can_wakeup(dev)) 128 return acpi_pm_device_sleep_wake(&dev->dev, enable); 129 130 acpi_pci_propagate_wakeup_enable(dev->bus, enable); 131 return 0; 132 } 133 134 static struct pci_platform_pm_ops acpi_pci_platform_pm = { 135 .is_manageable = acpi_pci_power_manageable, 136 .set_state = acpi_pci_set_power_state, 137 .choose_state = acpi_pci_choose_state, 138 .can_wakeup = acpi_pci_can_wakeup, 139 .sleep_wake = acpi_pci_sleep_wake, 140 }; 141 142 /* ACPI bus type */ 143 static int acpi_pci_find_device(struct device *dev, acpi_handle *handle) 144 { 145 struct pci_dev * pci_dev; 146 acpi_integer addr; 147 148 pci_dev = to_pci_dev(dev); 149 /* Please ref to ACPI spec for the syntax of _ADR */ 150 addr = (PCI_SLOT(pci_dev->devfn) << 16) | PCI_FUNC(pci_dev->devfn); 151 *handle = acpi_get_child(DEVICE_ACPI_HANDLE(dev->parent), addr); 152 if (!*handle) 153 return -ENODEV; 154 return 0; 155 } 156 157 static int acpi_pci_find_root_bridge(struct device *dev, acpi_handle *handle) 158 { 159 int num; 160 unsigned int seg, bus; 161 162 /* 163 * The string should be the same as root bridge's name 164 * Please look at 'pci_scan_bus_parented' 165 */ 166 num = sscanf(dev_name(dev), "pci%04x:%02x", &seg, &bus); 167 if (num != 2) 168 return -ENODEV; 169 *handle = acpi_get_pci_rootbridge_handle(seg, bus); 170 if (!*handle) 171 return -ENODEV; 172 return 0; 173 } 174 175 static struct acpi_bus_type acpi_pci_bus = { 176 .bus = &pci_bus_type, 177 .find_device = acpi_pci_find_device, 178 .find_bridge = acpi_pci_find_root_bridge, 179 }; 180 181 static int __init acpi_pci_init(void) 182 { 183 int ret; 184 185 if (acpi_gbl_FADT.boot_flags & ACPI_FADT_NO_MSI) { 186 printk(KERN_INFO"ACPI FADT declares the system doesn't support MSI, so disable it\n"); 187 pci_no_msi(); 188 } 189 190 if (acpi_gbl_FADT.boot_flags & ACPI_FADT_NO_ASPM) { 191 printk(KERN_INFO"ACPI FADT declares the system doesn't support PCIe ASPM, so disable it\n"); 192 pcie_no_aspm(); 193 } 194 195 ret = register_acpi_bus_type(&acpi_pci_bus); 196 if (ret) 197 return 0; 198 pci_set_platform_pm(&acpi_pci_platform_pm); 199 return 0; 200 } 201 arch_initcall(acpi_pci_init); 202