11da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 21da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * drivers/pci/pci-driver.c 31da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 42b937303188807b498d1a3163f60305f0941538eGreg Kroah-Hartman * (C) Copyright 2002-2004, 2007 Greg Kroah-Hartman <greg@kroah.com> 52b937303188807b498d1a3163f60305f0941538eGreg Kroah-Hartman * (C) Copyright 2007 Novell Inc. 62b937303188807b498d1a3163f60305f0941538eGreg Kroah-Hartman * 72b937303188807b498d1a3163f60305f0941538eGreg Kroah-Hartman * Released under the GPL v2 only. 82b937303188807b498d1a3163f60305f0941538eGreg Kroah-Hartman * 91da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/pci.h> 121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/module.h> 131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/init.h> 141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/device.h> 15d42c69972b853fd33a26c8c7405624be41a22136Andi Kleen#include <linux/mempolicy.h> 164e57b6817880946a3a78d5d8cad1ace363f7e449Tim Schmielau#include <linux/string.h> 174e57b6817880946a3a78d5d8cad1ace363f7e449Tim Schmielau#include <linux/slab.h> 188c65b4a60450590e79a28e9717ceffa9e4debb3fTim Schmielau#include <linux/sched.h> 19873392ca514f87eae39f53b6944caf85b1a047cbRusty Russell#include <linux/cpu.h> 206cbf82148ff286ec22a55be6836c3a5bffc489c1Rafael J. Wysocki#include <linux/pm_runtime.h> 21eea3fc0357eb89d0b2d1af37bdfb83eb4076a542Rafael J. Wysocki#include <linux/suspend.h> 221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include "pci.h" 231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2475865858971add95809c5c9cd35dc4cfba08e33bGreg Kroah-Hartmanstruct pci_dynid { 2575865858971add95809c5c9cd35dc4cfba08e33bGreg Kroah-Hartman struct list_head node; 2675865858971add95809c5c9cd35dc4cfba08e33bGreg Kroah-Hartman struct pci_device_id id; 2775865858971add95809c5c9cd35dc4cfba08e33bGreg Kroah-Hartman}; 281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 299dba910e9de2c4aa15ec1286f10052c107ef48caTejun Heo/** 309dba910e9de2c4aa15ec1286f10052c107ef48caTejun Heo * pci_add_dynid - add a new PCI device ID to this driver and re-probe devices 319dba910e9de2c4aa15ec1286f10052c107ef48caTejun Heo * @drv: target pci driver 329dba910e9de2c4aa15ec1286f10052c107ef48caTejun Heo * @vendor: PCI vendor ID 339dba910e9de2c4aa15ec1286f10052c107ef48caTejun Heo * @device: PCI device ID 349dba910e9de2c4aa15ec1286f10052c107ef48caTejun Heo * @subvendor: PCI subvendor ID 359dba910e9de2c4aa15ec1286f10052c107ef48caTejun Heo * @subdevice: PCI subdevice ID 369dba910e9de2c4aa15ec1286f10052c107ef48caTejun Heo * @class: PCI class 379dba910e9de2c4aa15ec1286f10052c107ef48caTejun Heo * @class_mask: PCI class mask 389dba910e9de2c4aa15ec1286f10052c107ef48caTejun Heo * @driver_data: private driver data 399dba910e9de2c4aa15ec1286f10052c107ef48caTejun Heo * 409dba910e9de2c4aa15ec1286f10052c107ef48caTejun Heo * Adds a new dynamic pci device ID to this driver and causes the 419dba910e9de2c4aa15ec1286f10052c107ef48caTejun Heo * driver to probe for all devices again. @drv must have been 429dba910e9de2c4aa15ec1286f10052c107ef48caTejun Heo * registered prior to calling this function. 439dba910e9de2c4aa15ec1286f10052c107ef48caTejun Heo * 449dba910e9de2c4aa15ec1286f10052c107ef48caTejun Heo * CONTEXT: 459dba910e9de2c4aa15ec1286f10052c107ef48caTejun Heo * Does GFP_KERNEL allocation. 469dba910e9de2c4aa15ec1286f10052c107ef48caTejun Heo * 479dba910e9de2c4aa15ec1286f10052c107ef48caTejun Heo * RETURNS: 489dba910e9de2c4aa15ec1286f10052c107ef48caTejun Heo * 0 on success, -errno on failure. 499dba910e9de2c4aa15ec1286f10052c107ef48caTejun Heo */ 509dba910e9de2c4aa15ec1286f10052c107ef48caTejun Heoint pci_add_dynid(struct pci_driver *drv, 519dba910e9de2c4aa15ec1286f10052c107ef48caTejun Heo unsigned int vendor, unsigned int device, 529dba910e9de2c4aa15ec1286f10052c107ef48caTejun Heo unsigned int subvendor, unsigned int subdevice, 539dba910e9de2c4aa15ec1286f10052c107ef48caTejun Heo unsigned int class, unsigned int class_mask, 549dba910e9de2c4aa15ec1286f10052c107ef48caTejun Heo unsigned long driver_data) 559dba910e9de2c4aa15ec1286f10052c107ef48caTejun Heo{ 569dba910e9de2c4aa15ec1286f10052c107ef48caTejun Heo struct pci_dynid *dynid; 579dba910e9de2c4aa15ec1286f10052c107ef48caTejun Heo int retval; 589dba910e9de2c4aa15ec1286f10052c107ef48caTejun Heo 599dba910e9de2c4aa15ec1286f10052c107ef48caTejun Heo dynid = kzalloc(sizeof(*dynid), GFP_KERNEL); 609dba910e9de2c4aa15ec1286f10052c107ef48caTejun Heo if (!dynid) 619dba910e9de2c4aa15ec1286f10052c107ef48caTejun Heo return -ENOMEM; 629dba910e9de2c4aa15ec1286f10052c107ef48caTejun Heo 639dba910e9de2c4aa15ec1286f10052c107ef48caTejun Heo dynid->id.vendor = vendor; 649dba910e9de2c4aa15ec1286f10052c107ef48caTejun Heo dynid->id.device = device; 659dba910e9de2c4aa15ec1286f10052c107ef48caTejun Heo dynid->id.subvendor = subvendor; 669dba910e9de2c4aa15ec1286f10052c107ef48caTejun Heo dynid->id.subdevice = subdevice; 679dba910e9de2c4aa15ec1286f10052c107ef48caTejun Heo dynid->id.class = class; 689dba910e9de2c4aa15ec1286f10052c107ef48caTejun Heo dynid->id.class_mask = class_mask; 699dba910e9de2c4aa15ec1286f10052c107ef48caTejun Heo dynid->id.driver_data = driver_data; 703d3c2ae1101c1f2dff7e2f9d514769779dbd2737Greg Kroah-Hartman 719dba910e9de2c4aa15ec1286f10052c107ef48caTejun Heo spin_lock(&drv->dynids.lock); 729dba910e9de2c4aa15ec1286f10052c107ef48caTejun Heo list_add_tail(&dynid->node, &drv->dynids.list); 739dba910e9de2c4aa15ec1286f10052c107ef48caTejun Heo spin_unlock(&drv->dynids.lock); 749dba910e9de2c4aa15ec1286f10052c107ef48caTejun Heo 759dba910e9de2c4aa15ec1286f10052c107ef48caTejun Heo retval = driver_attach(&drv->driver); 769dba910e9de2c4aa15ec1286f10052c107ef48caTejun Heo 779dba910e9de2c4aa15ec1286f10052c107ef48caTejun Heo return retval; 789dba910e9de2c4aa15ec1286f10052c107ef48caTejun Heo} 799dba910e9de2c4aa15ec1286f10052c107ef48caTejun Heo 809dba910e9de2c4aa15ec1286f10052c107ef48caTejun Heostatic void pci_free_dynids(struct pci_driver *drv) 819dba910e9de2c4aa15ec1286f10052c107ef48caTejun Heo{ 829dba910e9de2c4aa15ec1286f10052c107ef48caTejun Heo struct pci_dynid *dynid, *n; 833d3c2ae1101c1f2dff7e2f9d514769779dbd2737Greg Kroah-Hartman 849dba910e9de2c4aa15ec1286f10052c107ef48caTejun Heo spin_lock(&drv->dynids.lock); 859dba910e9de2c4aa15ec1286f10052c107ef48caTejun Heo list_for_each_entry_safe(dynid, n, &drv->dynids.list, node) { 869dba910e9de2c4aa15ec1286f10052c107ef48caTejun Heo list_del(&dynid->node); 879dba910e9de2c4aa15ec1286f10052c107ef48caTejun Heo kfree(dynid); 889dba910e9de2c4aa15ec1286f10052c107ef48caTejun Heo } 899dba910e9de2c4aa15ec1286f10052c107ef48caTejun Heo spin_unlock(&drv->dynids.lock); 909dba910e9de2c4aa15ec1286f10052c107ef48caTejun Heo} 919dba910e9de2c4aa15ec1286f10052c107ef48caTejun Heo 929dba910e9de2c4aa15ec1286f10052c107ef48caTejun Heo/* 939dba910e9de2c4aa15ec1286f10052c107ef48caTejun Heo * Dynamic device ID manipulation via sysfs is disabled for !CONFIG_HOTPLUG 949dba910e9de2c4aa15ec1286f10052c107ef48caTejun Heo */ 959dba910e9de2c4aa15ec1286f10052c107ef48caTejun Heo#ifdef CONFIG_HOTPLUG 961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/** 979dba910e9de2c4aa15ec1286f10052c107ef48caTejun Heo * store_new_id - sysfs frontend to pci_add_dynid() 988f7020d36374dda9366fee1343f8eacfe8f5e641Randy Dunlap * @driver: target device driver 998f7020d36374dda9366fee1343f8eacfe8f5e641Randy Dunlap * @buf: buffer for scanning device ID data 1008f7020d36374dda9366fee1343f8eacfe8f5e641Randy Dunlap * @count: input size 1011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 1029dba910e9de2c4aa15ec1286f10052c107ef48caTejun Heo * Allow PCI IDs to be added to an existing driver via sysfs. 1031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 104f8eb1005a5bdb019d2a4ff3ef8d8e8015b22afcbRandy Dunlapstatic ssize_t 1051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstore_new_id(struct device_driver *driver, const char *buf, size_t count) 1061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 1071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct pci_driver *pdrv = to_pci_driver(driver); 108b41d6cf38e27a940d998d989526a9748de1bf028Jean Delvare const struct pci_device_id *ids = pdrv->id_table; 1096ba186361ed2cda7e174856a3ab8a8e3237b3c3dJean Delvare __u32 vendor, device, subvendor=PCI_ANY_ID, 1101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds subdevice=PCI_ANY_ID, class=0, class_mask=0; 1111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned long driver_data=0; 1121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int fields=0; 1139dba910e9de2c4aa15ec1286f10052c107ef48caTejun Heo int retval; 1141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 115b41d6cf38e27a940d998d989526a9748de1bf028Jean Delvare fields = sscanf(buf, "%x %x %x %x %x %x %lx", 1161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds &vendor, &device, &subvendor, &subdevice, 1171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds &class, &class_mask, &driver_data); 1186ba186361ed2cda7e174856a3ab8a8e3237b3c3dJean Delvare if (fields < 2) 1191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -EINVAL; 1201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 121b41d6cf38e27a940d998d989526a9748de1bf028Jean Delvare /* Only accept driver_data values that match an existing id_table 122b41d6cf38e27a940d998d989526a9748de1bf028Jean Delvare entry */ 1232debb4d2019fa05a0896f1591dea0e0dc21bc046Chris Wright if (ids) { 1242debb4d2019fa05a0896f1591dea0e0dc21bc046Chris Wright retval = -EINVAL; 1252debb4d2019fa05a0896f1591dea0e0dc21bc046Chris Wright while (ids->vendor || ids->subvendor || ids->class_mask) { 1262debb4d2019fa05a0896f1591dea0e0dc21bc046Chris Wright if (driver_data == ids->driver_data) { 1272debb4d2019fa05a0896f1591dea0e0dc21bc046Chris Wright retval = 0; 1282debb4d2019fa05a0896f1591dea0e0dc21bc046Chris Wright break; 1292debb4d2019fa05a0896f1591dea0e0dc21bc046Chris Wright } 1302debb4d2019fa05a0896f1591dea0e0dc21bc046Chris Wright ids++; 131b41d6cf38e27a940d998d989526a9748de1bf028Jean Delvare } 1322debb4d2019fa05a0896f1591dea0e0dc21bc046Chris Wright if (retval) /* No match */ 1332debb4d2019fa05a0896f1591dea0e0dc21bc046Chris Wright return retval; 134b41d6cf38e27a940d998d989526a9748de1bf028Jean Delvare } 135b41d6cf38e27a940d998d989526a9748de1bf028Jean Delvare 1369dba910e9de2c4aa15ec1286f10052c107ef48caTejun Heo retval = pci_add_dynid(pdrv, vendor, device, subvendor, subdevice, 1379dba910e9de2c4aa15ec1286f10052c107ef48caTejun Heo class, class_mask, driver_data); 138b19441af185559118e8247382ea4f2f76ebffc6dGreg Kroah-Hartman if (retval) 139b19441af185559118e8247382ea4f2f76ebffc6dGreg Kroah-Hartman return retval; 1401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return count; 1411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 1421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic DRIVER_ATTR(new_id, S_IWUSR, NULL, store_new_id); 1431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1440994375e9614f78657031e04e30019b9cdb62795Chris Wright/** 1450994375e9614f78657031e04e30019b9cdb62795Chris Wright * store_remove_id - remove a PCI device ID from this driver 1460994375e9614f78657031e04e30019b9cdb62795Chris Wright * @driver: target device driver 1470994375e9614f78657031e04e30019b9cdb62795Chris Wright * @buf: buffer for scanning device ID data 1480994375e9614f78657031e04e30019b9cdb62795Chris Wright * @count: input size 1490994375e9614f78657031e04e30019b9cdb62795Chris Wright * 1500994375e9614f78657031e04e30019b9cdb62795Chris Wright * Removes a dynamic pci device ID to this driver. 1510994375e9614f78657031e04e30019b9cdb62795Chris Wright */ 1520994375e9614f78657031e04e30019b9cdb62795Chris Wrightstatic ssize_t 1530994375e9614f78657031e04e30019b9cdb62795Chris Wrightstore_remove_id(struct device_driver *driver, const char *buf, size_t count) 1540994375e9614f78657031e04e30019b9cdb62795Chris Wright{ 1550994375e9614f78657031e04e30019b9cdb62795Chris Wright struct pci_dynid *dynid, *n; 1560994375e9614f78657031e04e30019b9cdb62795Chris Wright struct pci_driver *pdrv = to_pci_driver(driver); 1570994375e9614f78657031e04e30019b9cdb62795Chris Wright __u32 vendor, device, subvendor = PCI_ANY_ID, 1580994375e9614f78657031e04e30019b9cdb62795Chris Wright subdevice = PCI_ANY_ID, class = 0, class_mask = 0; 1590994375e9614f78657031e04e30019b9cdb62795Chris Wright int fields = 0; 1600994375e9614f78657031e04e30019b9cdb62795Chris Wright int retval = -ENODEV; 1610994375e9614f78657031e04e30019b9cdb62795Chris Wright 1620994375e9614f78657031e04e30019b9cdb62795Chris Wright fields = sscanf(buf, "%x %x %x %x %x %x", 1630994375e9614f78657031e04e30019b9cdb62795Chris Wright &vendor, &device, &subvendor, &subdevice, 1640994375e9614f78657031e04e30019b9cdb62795Chris Wright &class, &class_mask); 1650994375e9614f78657031e04e30019b9cdb62795Chris Wright if (fields < 2) 1660994375e9614f78657031e04e30019b9cdb62795Chris Wright return -EINVAL; 1670994375e9614f78657031e04e30019b9cdb62795Chris Wright 1680994375e9614f78657031e04e30019b9cdb62795Chris Wright spin_lock(&pdrv->dynids.lock); 1690994375e9614f78657031e04e30019b9cdb62795Chris Wright list_for_each_entry_safe(dynid, n, &pdrv->dynids.list, node) { 1700994375e9614f78657031e04e30019b9cdb62795Chris Wright struct pci_device_id *id = &dynid->id; 1710994375e9614f78657031e04e30019b9cdb62795Chris Wright if ((id->vendor == vendor) && 1720994375e9614f78657031e04e30019b9cdb62795Chris Wright (id->device == device) && 1730994375e9614f78657031e04e30019b9cdb62795Chris Wright (subvendor == PCI_ANY_ID || id->subvendor == subvendor) && 1740994375e9614f78657031e04e30019b9cdb62795Chris Wright (subdevice == PCI_ANY_ID || id->subdevice == subdevice) && 1750994375e9614f78657031e04e30019b9cdb62795Chris Wright !((id->class ^ class) & class_mask)) { 1760994375e9614f78657031e04e30019b9cdb62795Chris Wright list_del(&dynid->node); 1770994375e9614f78657031e04e30019b9cdb62795Chris Wright kfree(dynid); 1780994375e9614f78657031e04e30019b9cdb62795Chris Wright retval = 0; 1790994375e9614f78657031e04e30019b9cdb62795Chris Wright break; 1800994375e9614f78657031e04e30019b9cdb62795Chris Wright } 1810994375e9614f78657031e04e30019b9cdb62795Chris Wright } 1820994375e9614f78657031e04e30019b9cdb62795Chris Wright spin_unlock(&pdrv->dynids.lock); 1830994375e9614f78657031e04e30019b9cdb62795Chris Wright 1840994375e9614f78657031e04e30019b9cdb62795Chris Wright if (retval) 1850994375e9614f78657031e04e30019b9cdb62795Chris Wright return retval; 1860994375e9614f78657031e04e30019b9cdb62795Chris Wright return count; 1870994375e9614f78657031e04e30019b9cdb62795Chris Wright} 1880994375e9614f78657031e04e30019b9cdb62795Chris Wrightstatic DRIVER_ATTR(remove_id, S_IWUSR, NULL, store_remove_id); 1890994375e9614f78657031e04e30019b9cdb62795Chris Wright 1901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int 191ed283e9f0a2cc0541870828c76c6c6997c51a318Alan Sternpci_create_newid_files(struct pci_driver *drv) 1921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 1931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int error = 0; 1940994375e9614f78657031e04e30019b9cdb62795Chris Wright 195ed283e9f0a2cc0541870828c76c6c6997c51a318Alan Stern if (drv->probe != NULL) { 196ed283e9f0a2cc0541870828c76c6c6997c51a318Alan Stern error = driver_create_file(&drv->driver, &driver_attr_new_id); 197ed283e9f0a2cc0541870828c76c6c6997c51a318Alan Stern if (error == 0) { 198ed283e9f0a2cc0541870828c76c6c6997c51a318Alan Stern error = driver_create_file(&drv->driver, 199ed283e9f0a2cc0541870828c76c6c6997c51a318Alan Stern &driver_attr_remove_id); 200ed283e9f0a2cc0541870828c76c6c6997c51a318Alan Stern if (error) 201ed283e9f0a2cc0541870828c76c6c6997c51a318Alan Stern driver_remove_file(&drv->driver, 202ed283e9f0a2cc0541870828c76c6c6997c51a318Alan Stern &driver_attr_new_id); 203ed283e9f0a2cc0541870828c76c6c6997c51a318Alan Stern } 204ed283e9f0a2cc0541870828c76c6c6997c51a318Alan Stern } 2050994375e9614f78657031e04e30019b9cdb62795Chris Wright return error; 2060994375e9614f78657031e04e30019b9cdb62795Chris Wright} 2070994375e9614f78657031e04e30019b9cdb62795Chris Wright 208ed283e9f0a2cc0541870828c76c6c6997c51a318Alan Sternstatic void pci_remove_newid_files(struct pci_driver *drv) 2090994375e9614f78657031e04e30019b9cdb62795Chris Wright{ 2100994375e9614f78657031e04e30019b9cdb62795Chris Wright driver_remove_file(&drv->driver, &driver_attr_remove_id); 211ed283e9f0a2cc0541870828c76c6c6997c51a318Alan Stern driver_remove_file(&drv->driver, &driver_attr_new_id); 2120994375e9614f78657031e04e30019b9cdb62795Chris Wright} 2131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#else /* !CONFIG_HOTPLUG */ 214ed283e9f0a2cc0541870828c76c6c6997c51a318Alan Sternstatic inline int pci_create_newid_files(struct pci_driver *drv) 2151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 2161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 2171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 218ed283e9f0a2cc0541870828c76c6c6997c51a318Alan Sternstatic inline void pci_remove_newid_files(struct pci_driver *drv) {} 2191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif 2201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/** 22275865858971add95809c5c9cd35dc4cfba08e33bGreg Kroah-Hartman * pci_match_id - See if a pci device matches a given pci_id table 2231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * @ids: array of PCI device id structures to search in 22475865858971add95809c5c9cd35dc4cfba08e33bGreg Kroah-Hartman * @dev: the PCI device structure to match against. 22575865858971add95809c5c9cd35dc4cfba08e33bGreg Kroah-Hartman * 2261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Used by a driver to check whether a PCI device present in the 22775865858971add95809c5c9cd35dc4cfba08e33bGreg Kroah-Hartman * system is in its list of supported devices. Returns the matching 2281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * pci_device_id structure or %NULL if there is no match. 22975865858971add95809c5c9cd35dc4cfba08e33bGreg Kroah-Hartman * 2308b60756a628a73bc8bf8b59d8716cb3f09b7e7ebRandy Dunlap * Deprecated, don't use this as it will not catch any dynamic ids 23175865858971add95809c5c9cd35dc4cfba08e33bGreg Kroah-Hartman * that a driver might want to check for. 2321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 23375865858971add95809c5c9cd35dc4cfba08e33bGreg Kroah-Hartmanconst struct pci_device_id *pci_match_id(const struct pci_device_id *ids, 23475865858971add95809c5c9cd35dc4cfba08e33bGreg Kroah-Hartman struct pci_dev *dev) 2351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 23675865858971add95809c5c9cd35dc4cfba08e33bGreg Kroah-Hartman if (ids) { 23775865858971add95809c5c9cd35dc4cfba08e33bGreg Kroah-Hartman while (ids->vendor || ids->subvendor || ids->class_mask) { 23875865858971add95809c5c9cd35dc4cfba08e33bGreg Kroah-Hartman if (pci_match_one_device(ids, dev)) 23975865858971add95809c5c9cd35dc4cfba08e33bGreg Kroah-Hartman return ids; 24075865858971add95809c5c9cd35dc4cfba08e33bGreg Kroah-Hartman ids++; 24175865858971add95809c5c9cd35dc4cfba08e33bGreg Kroah-Hartman } 2421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 2431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return NULL; 2441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 2451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/** 247ae9608af9e300395ec032479621f32688c121141Randy Dunlap * pci_match_device - Tell if a PCI device structure has a matching PCI device id structure 24875865858971add95809c5c9cd35dc4cfba08e33bGreg Kroah-Hartman * @drv: the PCI driver to match against 24939ba487fe22a63b3df7c543c82d01db0f0fed700Henrik Kretzschmar * @dev: the PCI device structure to match against 25075865858971add95809c5c9cd35dc4cfba08e33bGreg Kroah-Hartman * 25175865858971add95809c5c9cd35dc4cfba08e33bGreg Kroah-Hartman * Used by a driver to check whether a PCI device present in the 25275865858971add95809c5c9cd35dc4cfba08e33bGreg Kroah-Hartman * system is in its list of supported devices. Returns the matching 25375865858971add95809c5c9cd35dc4cfba08e33bGreg Kroah-Hartman * pci_device_id structure or %NULL if there is no match. 2541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 255d73460d79bc88de74221d73723ed61a0081b7a36Adrian Bunkstatic const struct pci_device_id *pci_match_device(struct pci_driver *drv, 256d73460d79bc88de74221d73723ed61a0081b7a36Adrian Bunk struct pci_dev *dev) 25775865858971add95809c5c9cd35dc4cfba08e33bGreg Kroah-Hartman{ 25875865858971add95809c5c9cd35dc4cfba08e33bGreg Kroah-Hartman struct pci_dynid *dynid; 2591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2607461b60afa62b26943e97861d87b9f9a32d7fd9cRussell King /* Look at the dynamic ids first, before the static ones */ 26175865858971add95809c5c9cd35dc4cfba08e33bGreg Kroah-Hartman spin_lock(&drv->dynids.lock); 26275865858971add95809c5c9cd35dc4cfba08e33bGreg Kroah-Hartman list_for_each_entry(dynid, &drv->dynids.list, node) { 26375865858971add95809c5c9cd35dc4cfba08e33bGreg Kroah-Hartman if (pci_match_one_device(&dynid->id, dev)) { 26475865858971add95809c5c9cd35dc4cfba08e33bGreg Kroah-Hartman spin_unlock(&drv->dynids.lock); 26575865858971add95809c5c9cd35dc4cfba08e33bGreg Kroah-Hartman return &dynid->id; 26675865858971add95809c5c9cd35dc4cfba08e33bGreg Kroah-Hartman } 2671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 26875865858971add95809c5c9cd35dc4cfba08e33bGreg Kroah-Hartman spin_unlock(&drv->dynids.lock); 2697461b60afa62b26943e97861d87b9f9a32d7fd9cRussell King 2707461b60afa62b26943e97861d87b9f9a32d7fd9cRussell King return pci_match_id(drv->id_table, dev); 2711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 2721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 273873392ca514f87eae39f53b6944caf85b1a047cbRusty Russellstruct drv_dev_and_id { 274873392ca514f87eae39f53b6944caf85b1a047cbRusty Russell struct pci_driver *drv; 275873392ca514f87eae39f53b6944caf85b1a047cbRusty Russell struct pci_dev *dev; 276873392ca514f87eae39f53b6944caf85b1a047cbRusty Russell const struct pci_device_id *id; 277873392ca514f87eae39f53b6944caf85b1a047cbRusty Russell}; 278873392ca514f87eae39f53b6944caf85b1a047cbRusty Russell 279873392ca514f87eae39f53b6944caf85b1a047cbRusty Russellstatic long local_pci_probe(void *_ddi) 280873392ca514f87eae39f53b6944caf85b1a047cbRusty Russell{ 281873392ca514f87eae39f53b6944caf85b1a047cbRusty Russell struct drv_dev_and_id *ddi = _ddi; 282f3ec4f87d607f40497afdb5ac03f11e2ea253d52Alan Stern struct device *dev = &ddi->dev->dev; 283f3ec4f87d607f40497afdb5ac03f11e2ea253d52Alan Stern int rc; 284f3ec4f87d607f40497afdb5ac03f11e2ea253d52Alan Stern 285f3ec4f87d607f40497afdb5ac03f11e2ea253d52Alan Stern /* Unbound PCI devices are always set to disabled and suspended. 286f3ec4f87d607f40497afdb5ac03f11e2ea253d52Alan Stern * During probe, the device is set to enabled and active and the 287f3ec4f87d607f40497afdb5ac03f11e2ea253d52Alan Stern * usage count is incremented. If the driver supports runtime PM, 288f3ec4f87d607f40497afdb5ac03f11e2ea253d52Alan Stern * it should call pm_runtime_put_noidle() in its probe routine and 289f3ec4f87d607f40497afdb5ac03f11e2ea253d52Alan Stern * pm_runtime_get_noresume() in its remove routine. 290f3ec4f87d607f40497afdb5ac03f11e2ea253d52Alan Stern */ 291f3ec4f87d607f40497afdb5ac03f11e2ea253d52Alan Stern pm_runtime_get_noresume(dev); 292f3ec4f87d607f40497afdb5ac03f11e2ea253d52Alan Stern pm_runtime_set_active(dev); 293f3ec4f87d607f40497afdb5ac03f11e2ea253d52Alan Stern pm_runtime_enable(dev); 294f3ec4f87d607f40497afdb5ac03f11e2ea253d52Alan Stern 295f3ec4f87d607f40497afdb5ac03f11e2ea253d52Alan Stern rc = ddi->drv->probe(ddi->dev, ddi->id); 296f3ec4f87d607f40497afdb5ac03f11e2ea253d52Alan Stern if (rc) { 297f3ec4f87d607f40497afdb5ac03f11e2ea253d52Alan Stern pm_runtime_disable(dev); 298f3ec4f87d607f40497afdb5ac03f11e2ea253d52Alan Stern pm_runtime_set_suspended(dev); 299f3ec4f87d607f40497afdb5ac03f11e2ea253d52Alan Stern pm_runtime_put_noidle(dev); 300f3ec4f87d607f40497afdb5ac03f11e2ea253d52Alan Stern } 301f3ec4f87d607f40497afdb5ac03f11e2ea253d52Alan Stern return rc; 302873392ca514f87eae39f53b6944caf85b1a047cbRusty Russell} 303873392ca514f87eae39f53b6944caf85b1a047cbRusty Russell 304d42c69972b853fd33a26c8c7405624be41a22136Andi Kleenstatic int pci_call_probe(struct pci_driver *drv, struct pci_dev *dev, 305d42c69972b853fd33a26c8c7405624be41a22136Andi Kleen const struct pci_device_id *id) 306d42c69972b853fd33a26c8c7405624be41a22136Andi Kleen{ 307873392ca514f87eae39f53b6944caf85b1a047cbRusty Russell int error, node; 308873392ca514f87eae39f53b6944caf85b1a047cbRusty Russell struct drv_dev_and_id ddi = { drv, dev, id }; 309873392ca514f87eae39f53b6944caf85b1a047cbRusty Russell 310873392ca514f87eae39f53b6944caf85b1a047cbRusty Russell /* Execute driver initialization on node where the device's 311873392ca514f87eae39f53b6944caf85b1a047cbRusty Russell bus is attached to. This way the driver likely allocates 312873392ca514f87eae39f53b6944caf85b1a047cbRusty Russell its local memory on the right node without any need to 313873392ca514f87eae39f53b6944caf85b1a047cbRusty Russell change it. */ 314873392ca514f87eae39f53b6944caf85b1a047cbRusty Russell node = dev_to_node(&dev->dev); 315f70316dace2bb99730800d47044acb818c6735f6Mike Travis if (node >= 0) { 316873392ca514f87eae39f53b6944caf85b1a047cbRusty Russell int cpu; 317873392ca514f87eae39f53b6944caf85b1a047cbRusty Russell 318873392ca514f87eae39f53b6944caf85b1a047cbRusty Russell get_online_cpus(); 319a70f730282019f487aa33a84e5ac9a5e89c5abd0Rusty Russell cpu = cpumask_any_and(cpumask_of_node(node), cpu_online_mask); 320873392ca514f87eae39f53b6944caf85b1a047cbRusty Russell if (cpu < nr_cpu_ids) 321873392ca514f87eae39f53b6944caf85b1a047cbRusty Russell error = work_on_cpu(cpu, local_pci_probe, &ddi); 322873392ca514f87eae39f53b6944caf85b1a047cbRusty Russell else 323873392ca514f87eae39f53b6944caf85b1a047cbRusty Russell error = local_pci_probe(&ddi); 324873392ca514f87eae39f53b6944caf85b1a047cbRusty Russell put_online_cpus(); 325873392ca514f87eae39f53b6944caf85b1a047cbRusty Russell } else 326873392ca514f87eae39f53b6944caf85b1a047cbRusty Russell error = local_pci_probe(&ddi); 327d42c69972b853fd33a26c8c7405624be41a22136Andi Kleen return error; 328d42c69972b853fd33a26c8c7405624be41a22136Andi Kleen} 329d42c69972b853fd33a26c8c7405624be41a22136Andi Kleen 3301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/** 33123ea3793fd368fd6a1ea20659699e280e2996658Randy Dunlap * __pci_device_probe - check if a driver wants to claim a specific PCI device 3328f7020d36374dda9366fee1343f8eacfe8f5e641Randy Dunlap * @drv: driver to call to check if it wants the PCI device 3338f7020d36374dda9366fee1343f8eacfe8f5e641Randy Dunlap * @pci_dev: PCI device being probed 3341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 3358f7020d36374dda9366fee1343f8eacfe8f5e641Randy Dunlap * returns 0 on success, else error. 3361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * side-effect: pci_dev->driver is set to drv when drv claims pci_dev. 3371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 3381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int 3391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds__pci_device_probe(struct pci_driver *drv, struct pci_dev *pci_dev) 34075865858971add95809c5c9cd35dc4cfba08e33bGreg Kroah-Hartman{ 34175865858971add95809c5c9cd35dc4cfba08e33bGreg Kroah-Hartman const struct pci_device_id *id; 3421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int error = 0; 3431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!pci_dev->driver && drv->probe) { 34575865858971add95809c5c9cd35dc4cfba08e33bGreg Kroah-Hartman error = -ENODEV; 34675865858971add95809c5c9cd35dc4cfba08e33bGreg Kroah-Hartman 34775865858971add95809c5c9cd35dc4cfba08e33bGreg Kroah-Hartman id = pci_match_device(drv, pci_dev); 34875865858971add95809c5c9cd35dc4cfba08e33bGreg Kroah-Hartman if (id) 349d42c69972b853fd33a26c8c7405624be41a22136Andi Kleen error = pci_call_probe(drv, pci_dev, id); 35075865858971add95809c5c9cd35dc4cfba08e33bGreg Kroah-Hartman if (error >= 0) { 35175865858971add95809c5c9cd35dc4cfba08e33bGreg Kroah-Hartman pci_dev->driver = drv; 35275865858971add95809c5c9cd35dc4cfba08e33bGreg Kroah-Hartman error = 0; 35375865858971add95809c5c9cd35dc4cfba08e33bGreg Kroah-Hartman } 3541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 3551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return error; 3561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 3571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int pci_device_probe(struct device * dev) 3591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 3601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int error = 0; 3611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct pci_driver *drv; 3621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct pci_dev *pci_dev; 3631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds drv = to_pci_driver(dev->driver); 3651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pci_dev = to_pci_dev(dev); 3661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pci_dev_get(pci_dev); 3671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds error = __pci_device_probe(drv, pci_dev); 3681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (error) 3691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pci_dev_put(pci_dev); 3701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return error; 3721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 3731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int pci_device_remove(struct device * dev) 3751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 3761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct pci_dev * pci_dev = to_pci_dev(dev); 3771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct pci_driver * drv = pci_dev->driver; 3781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (drv) { 380f3ec4f87d607f40497afdb5ac03f11e2ea253d52Alan Stern if (drv->remove) { 381f3ec4f87d607f40497afdb5ac03f11e2ea253d52Alan Stern pm_runtime_get_sync(dev); 3821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds drv->remove(pci_dev); 383f3ec4f87d607f40497afdb5ac03f11e2ea253d52Alan Stern pm_runtime_put_noidle(dev); 384f3ec4f87d607f40497afdb5ac03f11e2ea253d52Alan Stern } 3851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pci_dev->driver = NULL; 3861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 3871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 388f3ec4f87d607f40497afdb5ac03f11e2ea253d52Alan Stern /* Undo the runtime PM settings in local_pci_probe() */ 389f3ec4f87d607f40497afdb5ac03f11e2ea253d52Alan Stern pm_runtime_disable(dev); 390f3ec4f87d607f40497afdb5ac03f11e2ea253d52Alan Stern pm_runtime_set_suspended(dev); 391f3ec4f87d607f40497afdb5ac03f11e2ea253d52Alan Stern pm_runtime_put_noidle(dev); 392f3ec4f87d607f40497afdb5ac03f11e2ea253d52Alan Stern 3931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* 3942449e06a5696b7af1c8a369b04c97f3b139cf3bbShaohua Li * If the device is still on, set the power state as "unknown", 3952449e06a5696b7af1c8a369b04c97f3b139cf3bbShaohua Li * since it might change by the next time we load the driver. 3962449e06a5696b7af1c8a369b04c97f3b139cf3bbShaohua Li */ 3972449e06a5696b7af1c8a369b04c97f3b139cf3bbShaohua Li if (pci_dev->current_state == PCI_D0) 3982449e06a5696b7af1c8a369b04c97f3b139cf3bbShaohua Li pci_dev->current_state = PCI_UNKNOWN; 3992449e06a5696b7af1c8a369b04c97f3b139cf3bbShaohua Li 4002449e06a5696b7af1c8a369b04c97f3b139cf3bbShaohua Li /* 4011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * We would love to complain here if pci_dev->is_enabled is set, that 4021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * the driver should have called pci_disable_device(), but the 4031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * unfortunate fact is there are too many odd BIOS and bridge setups 4041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * that don't like drivers doing that all of the time. 4051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Oh well, we can dream of sane hardware when we sleep, no matter how 4061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * horrible the crap we have to deal with is when we are awake... 4071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 4081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pci_dev_put(pci_dev); 4101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 4111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 4121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 413bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysockistatic void pci_device_shutdown(struct device *dev) 414bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki{ 415bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki struct pci_dev *pci_dev = to_pci_dev(dev); 416bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki struct pci_driver *drv = pci_dev->driver; 417bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki 418bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki if (drv && drv->shutdown) 419bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki drv->shutdown(pci_dev); 420bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki pci_msi_shutdown(pci_dev); 421bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki pci_msix_shutdown(pci_dev); 4225b415f1e79e0c09366f26e3eabe751642059285aRafael J. Wysocki 4235b415f1e79e0c09366f26e3eabe751642059285aRafael J. Wysocki /* 4245b415f1e79e0c09366f26e3eabe751642059285aRafael J. Wysocki * Devices may be enabled to wake up by runtime PM, but they need not 4255b415f1e79e0c09366f26e3eabe751642059285aRafael J. Wysocki * be supposed to wake up the system from its "power off" state (e.g. 4265b415f1e79e0c09366f26e3eabe751642059285aRafael J. Wysocki * ACPI S5). Therefore disable wakeup for all devices that aren't 4275b415f1e79e0c09366f26e3eabe751642059285aRafael J. Wysocki * supposed to wake up the system at this point. The state argument 4285b415f1e79e0c09366f26e3eabe751642059285aRafael J. Wysocki * will be ignored by pci_enable_wake(). 4295b415f1e79e0c09366f26e3eabe751642059285aRafael J. Wysocki */ 4305b415f1e79e0c09366f26e3eabe751642059285aRafael J. Wysocki if (!device_may_wakeup(dev)) 4315b415f1e79e0c09366f26e3eabe751642059285aRafael J. Wysocki pci_enable_wake(pci_dev, PCI_UNKNOWN, false); 432bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki} 433bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki 434aa33860158114d0df3c7997bc1dd41c0168e1c2aRafael J. Wysocki#ifdef CONFIG_PM 4356cbf82148ff286ec22a55be6836c3a5bffc489c1Rafael J. Wysocki 4366cbf82148ff286ec22a55be6836c3a5bffc489c1Rafael J. Wysocki/* Auxiliary functions used for system resume and run-time resume. */ 4376cbf82148ff286ec22a55be6836c3a5bffc489c1Rafael J. Wysocki 4386cbf82148ff286ec22a55be6836c3a5bffc489c1Rafael J. Wysocki/** 4396cbf82148ff286ec22a55be6836c3a5bffc489c1Rafael J. Wysocki * pci_restore_standard_config - restore standard config registers of PCI device 4406cbf82148ff286ec22a55be6836c3a5bffc489c1Rafael J. Wysocki * @pci_dev: PCI device to handle 4416cbf82148ff286ec22a55be6836c3a5bffc489c1Rafael J. Wysocki */ 4426cbf82148ff286ec22a55be6836c3a5bffc489c1Rafael J. Wysockistatic int pci_restore_standard_config(struct pci_dev *pci_dev) 4436cbf82148ff286ec22a55be6836c3a5bffc489c1Rafael J. Wysocki{ 4446cbf82148ff286ec22a55be6836c3a5bffc489c1Rafael J. Wysocki pci_update_current_state(pci_dev, PCI_UNKNOWN); 4456cbf82148ff286ec22a55be6836c3a5bffc489c1Rafael J. Wysocki 4466cbf82148ff286ec22a55be6836c3a5bffc489c1Rafael J. Wysocki if (pci_dev->current_state != PCI_D0) { 4476cbf82148ff286ec22a55be6836c3a5bffc489c1Rafael J. Wysocki int error = pci_set_power_state(pci_dev, PCI_D0); 4486cbf82148ff286ec22a55be6836c3a5bffc489c1Rafael J. Wysocki if (error) 4496cbf82148ff286ec22a55be6836c3a5bffc489c1Rafael J. Wysocki return error; 4506cbf82148ff286ec22a55be6836c3a5bffc489c1Rafael J. Wysocki } 4516cbf82148ff286ec22a55be6836c3a5bffc489c1Rafael J. Wysocki 4521d3c16a818e992c199844954d95c17fd7ce6cbbaJon Mason pci_restore_state(pci_dev); 4531d3c16a818e992c199844954d95c17fd7ce6cbbaJon Mason return 0; 4546cbf82148ff286ec22a55be6836c3a5bffc489c1Rafael J. Wysocki} 4556cbf82148ff286ec22a55be6836c3a5bffc489c1Rafael J. Wysocki 4566cbf82148ff286ec22a55be6836c3a5bffc489c1Rafael J. Wysockistatic void pci_pm_default_resume_early(struct pci_dev *pci_dev) 4576cbf82148ff286ec22a55be6836c3a5bffc489c1Rafael J. Wysocki{ 4586cbf82148ff286ec22a55be6836c3a5bffc489c1Rafael J. Wysocki pci_restore_standard_config(pci_dev); 4596cbf82148ff286ec22a55be6836c3a5bffc489c1Rafael J. Wysocki pci_fixup_device(pci_fixup_resume_early, pci_dev); 4606cbf82148ff286ec22a55be6836c3a5bffc489c1Rafael J. Wysocki} 4616cbf82148ff286ec22a55be6836c3a5bffc489c1Rafael J. Wysocki 4626cbf82148ff286ec22a55be6836c3a5bffc489c1Rafael J. Wysocki#endif 4636cbf82148ff286ec22a55be6836c3a5bffc489c1Rafael J. Wysocki 464bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki#ifdef CONFIG_PM_SLEEP 465bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki 466bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki/* 467bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki * Default "suspend" method for devices that have no driver provided suspend, 468fa58d305d9925b01830e535896a7227a868a9e15Rafael J. Wysocki * or not even a driver at all (second part). 469bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki */ 470bb8089454391ac5577215aec1f1991adcd4b4cbfRafael J. Wysockistatic void pci_pm_set_unknown_state(struct pci_dev *pci_dev) 471bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki{ 472bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki /* 473bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki * mark its power state as "unknown", since we don't know if 474bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki * e.g. the BIOS will change its device state when we suspend. 475bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki */ 476bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki if (pci_dev->current_state == PCI_D0) 477bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki pci_dev->current_state = PCI_UNKNOWN; 478bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki} 479bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki 480bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki/* 481bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki * Default "resume" method for devices that have no driver provided resume, 482355a72d75b3b4f4877db4c9070c798238028ecb5Rafael J. Wysocki * or not even a driver at all (second part). 483355a72d75b3b4f4877db4c9070c798238028ecb5Rafael J. Wysocki */ 484bb8089454391ac5577215aec1f1991adcd4b4cbfRafael J. Wysockistatic int pci_pm_reenable_device(struct pci_dev *pci_dev) 485355a72d75b3b4f4877db4c9070c798238028ecb5Rafael J. Wysocki{ 486355a72d75b3b4f4877db4c9070c798238028ecb5Rafael J. Wysocki int retval; 487355a72d75b3b4f4877db4c9070c798238028ecb5Rafael J. Wysocki 488bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki /* if the device was enabled before suspend, reenable */ 489bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki retval = pci_reenable_device(pci_dev); 490bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki /* 491bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki * if the device was busmaster before the suspend, make it busmaster 492bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki * again 493bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki */ 494bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki if (pci_dev->is_busmaster) 495bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki pci_set_master(pci_dev); 496bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki 497bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki return retval; 498bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki} 499bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki 500bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysockistatic int pci_legacy_suspend(struct device *dev, pm_message_t state) 5011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 5021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct pci_dev * pci_dev = to_pci_dev(dev); 5031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct pci_driver * drv = pci_dev->driver; 50446939f8b15e44f065d052e89ea4f2adc81fdc740Rafael J. Wysocki 505026694920579590c73b5c56705d543568ed5ad41Andrew Morton if (drv && drv->suspend) { 50699dadce8756bf08f5f8baf749533d044f6b3ff25Rafael J. Wysocki pci_power_t prev = pci_dev->current_state; 50746939f8b15e44f065d052e89ea4f2adc81fdc740Rafael J. Wysocki int error; 508aa8c6c93747f7b55fa11e1624fec8ca33763a805Rafael J. Wysocki 50957ef80266e14ecc363380268fedc64e519047b4aFrans Pop error = drv->suspend(pci_dev, state); 51057ef80266e14ecc363380268fedc64e519047b4aFrans Pop suspend_report_result(drv->suspend, error); 51157ef80266e14ecc363380268fedc64e519047b4aFrans Pop if (error) 51257ef80266e14ecc363380268fedc64e519047b4aFrans Pop return error; 513aa8c6c93747f7b55fa11e1624fec8ca33763a805Rafael J. Wysocki 51446939f8b15e44f065d052e89ea4f2adc81fdc740Rafael J. Wysocki if (!pci_dev->state_saved && pci_dev->current_state != PCI_D0 51599dadce8756bf08f5f8baf749533d044f6b3ff25Rafael J. Wysocki && pci_dev->current_state != PCI_UNKNOWN) { 51699dadce8756bf08f5f8baf749533d044f6b3ff25Rafael J. Wysocki WARN_ONCE(pci_dev->current_state != prev, 51799dadce8756bf08f5f8baf749533d044f6b3ff25Rafael J. Wysocki "PCI PM: Device state not saved by %pF\n", 51899dadce8756bf08f5f8baf749533d044f6b3ff25Rafael J. Wysocki drv->suspend); 51999dadce8756bf08f5f8baf749533d044f6b3ff25Rafael J. Wysocki } 520026694920579590c73b5c56705d543568ed5ad41Andrew Morton } 521ad8cfa1defee14a5181d9b63e666318c51cfaeedRafael J. Wysocki 522ad8cfa1defee14a5181d9b63e666318c51cfaeedRafael J. Wysocki pci_fixup_device(pci_fixup_suspend, pci_dev); 523ad8cfa1defee14a5181d9b63e666318c51cfaeedRafael J. Wysocki 52446939f8b15e44f065d052e89ea4f2adc81fdc740Rafael J. Wysocki return 0; 5251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 5261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 527bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysockistatic int pci_legacy_suspend_late(struct device *dev, pm_message_t state) 528cbd69dbbf1adfce6e048f15afc8629901ca9dae5Linus Torvalds{ 529cbd69dbbf1adfce6e048f15afc8629901ca9dae5Linus Torvalds struct pci_dev * pci_dev = to_pci_dev(dev); 530cbd69dbbf1adfce6e048f15afc8629901ca9dae5Linus Torvalds struct pci_driver * drv = pci_dev->driver; 531cbd69dbbf1adfce6e048f15afc8629901ca9dae5Linus Torvalds 532cbd69dbbf1adfce6e048f15afc8629901ca9dae5Linus Torvalds if (drv && drv->suspend_late) { 53346939f8b15e44f065d052e89ea4f2adc81fdc740Rafael J. Wysocki pci_power_t prev = pci_dev->current_state; 53446939f8b15e44f065d052e89ea4f2adc81fdc740Rafael J. Wysocki int error; 53546939f8b15e44f065d052e89ea4f2adc81fdc740Rafael J. Wysocki 53657ef80266e14ecc363380268fedc64e519047b4aFrans Pop error = drv->suspend_late(pci_dev, state); 53757ef80266e14ecc363380268fedc64e519047b4aFrans Pop suspend_report_result(drv->suspend_late, error); 53846939f8b15e44f065d052e89ea4f2adc81fdc740Rafael J. Wysocki if (error) 53946939f8b15e44f065d052e89ea4f2adc81fdc740Rafael J. Wysocki return error; 54046939f8b15e44f065d052e89ea4f2adc81fdc740Rafael J. Wysocki 54146939f8b15e44f065d052e89ea4f2adc81fdc740Rafael J. Wysocki if (!pci_dev->state_saved && pci_dev->current_state != PCI_D0 54246939f8b15e44f065d052e89ea4f2adc81fdc740Rafael J. Wysocki && pci_dev->current_state != PCI_UNKNOWN) { 54346939f8b15e44f065d052e89ea4f2adc81fdc740Rafael J. Wysocki WARN_ONCE(pci_dev->current_state != prev, 54446939f8b15e44f065d052e89ea4f2adc81fdc740Rafael J. Wysocki "PCI PM: Device state not saved by %pF\n", 54546939f8b15e44f065d052e89ea4f2adc81fdc740Rafael J. Wysocki drv->suspend_late); 54646939f8b15e44f065d052e89ea4f2adc81fdc740Rafael J. Wysocki return 0; 54746939f8b15e44f065d052e89ea4f2adc81fdc740Rafael J. Wysocki } 548cbd69dbbf1adfce6e048f15afc8629901ca9dae5Linus Torvalds } 54946939f8b15e44f065d052e89ea4f2adc81fdc740Rafael J. Wysocki 55046939f8b15e44f065d052e89ea4f2adc81fdc740Rafael J. Wysocki if (!pci_dev->state_saved) 55146939f8b15e44f065d052e89ea4f2adc81fdc740Rafael J. Wysocki pci_save_state(pci_dev); 55246939f8b15e44f065d052e89ea4f2adc81fdc740Rafael J. Wysocki 55346939f8b15e44f065d052e89ea4f2adc81fdc740Rafael J. Wysocki pci_pm_set_unknown_state(pci_dev); 55446939f8b15e44f065d052e89ea4f2adc81fdc740Rafael J. Wysocki 55546939f8b15e44f065d052e89ea4f2adc81fdc740Rafael J. Wysocki return 0; 556cbd69dbbf1adfce6e048f15afc8629901ca9dae5Linus Torvalds} 5571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 558f6dc1e5e3d4b523e1616b43beddb04e4fb1d376aRafael J. Wysockistatic int pci_legacy_resume_early(struct device *dev) 559f6dc1e5e3d4b523e1616b43beddb04e4fb1d376aRafael J. Wysocki{ 560f6dc1e5e3d4b523e1616b43beddb04e4fb1d376aRafael J. Wysocki struct pci_dev * pci_dev = to_pci_dev(dev); 561f6dc1e5e3d4b523e1616b43beddb04e4fb1d376aRafael J. Wysocki struct pci_driver * drv = pci_dev->driver; 562f6dc1e5e3d4b523e1616b43beddb04e4fb1d376aRafael J. Wysocki 563aa8c6c93747f7b55fa11e1624fec8ca33763a805Rafael J. Wysocki return drv && drv->resume_early ? 564aa8c6c93747f7b55fa11e1624fec8ca33763a805Rafael J. Wysocki drv->resume_early(pci_dev) : 0; 565f6dc1e5e3d4b523e1616b43beddb04e4fb1d376aRafael J. Wysocki} 566f6dc1e5e3d4b523e1616b43beddb04e4fb1d376aRafael J. Wysocki 567bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysockistatic int pci_legacy_resume(struct device *dev) 5681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 5691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct pci_dev * pci_dev = to_pci_dev(dev); 5701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct pci_driver * drv = pci_dev->driver; 5711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 572ad8cfa1defee14a5181d9b63e666318c51cfaeedRafael J. Wysocki pci_fixup_device(pci_fixup_resume, pci_dev); 573ad8cfa1defee14a5181d9b63e666318c51cfaeedRafael J. Wysocki 574aa8c6c93747f7b55fa11e1624fec8ca33763a805Rafael J. Wysocki return drv && drv->resume ? 575aa8c6c93747f7b55fa11e1624fec8ca33763a805Rafael J. Wysocki drv->resume(pci_dev) : pci_pm_reenable_device(pci_dev); 5761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 5771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 578571ff7584bb9e05fca0eb79752ae55a46faf3a98Rafael J. Wysocki/* Auxiliary functions used by the new power management framework */ 579571ff7584bb9e05fca0eb79752ae55a46faf3a98Rafael J. Wysocki 5805294e256717923f4a3297bb8b802f5e0625763f3Rafael J. Wysockistatic void pci_pm_default_resume(struct pci_dev *pci_dev) 581571ff7584bb9e05fca0eb79752ae55a46faf3a98Rafael J. Wysocki{ 582734104292ff77dc71fe626b4ebd91b314547ca1bRafael J. Wysocki pci_fixup_device(pci_fixup_resume, pci_dev); 583734104292ff77dc71fe626b4ebd91b314547ca1bRafael J. Wysocki 5845294e256717923f4a3297bb8b802f5e0625763f3Rafael J. Wysocki if (!pci_is_bridge(pci_dev)) 5855294e256717923f4a3297bb8b802f5e0625763f3Rafael J. Wysocki pci_enable_wake(pci_dev, PCI_D0, false); 586571ff7584bb9e05fca0eb79752ae55a46faf3a98Rafael J. Wysocki} 587571ff7584bb9e05fca0eb79752ae55a46faf3a98Rafael J. Wysocki 5885294e256717923f4a3297bb8b802f5e0625763f3Rafael J. Wysockistatic void pci_pm_default_suspend(struct pci_dev *pci_dev) 589734104292ff77dc71fe626b4ebd91b314547ca1bRafael J. Wysocki{ 5905294e256717923f4a3297bb8b802f5e0625763f3Rafael J. Wysocki /* Disable non-bridge devices without PM support */ 591cbbc2f6b0d438f80831c20124137ea92f0e5149bRafael J. Wysocki if (!pci_is_bridge(pci_dev)) 592cbbc2f6b0d438f80831c20124137ea92f0e5149bRafael J. Wysocki pci_disable_enabled_device(pci_dev); 593734104292ff77dc71fe626b4ebd91b314547ca1bRafael J. Wysocki} 594734104292ff77dc71fe626b4ebd91b314547ca1bRafael J. Wysocki 59507e836e8d1f3688311d97fe1bf46980b0f9ae9c1Rafael J. Wysockistatic bool pci_has_legacy_pm_support(struct pci_dev *pci_dev) 59607e836e8d1f3688311d97fe1bf46980b0f9ae9c1Rafael J. Wysocki{ 59707e836e8d1f3688311d97fe1bf46980b0f9ae9c1Rafael J. Wysocki struct pci_driver *drv = pci_dev->driver; 598bb8089454391ac5577215aec1f1991adcd4b4cbfRafael J. Wysocki bool ret = drv && (drv->suspend || drv->suspend_late || drv->resume 59907e836e8d1f3688311d97fe1bf46980b0f9ae9c1Rafael J. Wysocki || drv->resume_early); 600bb8089454391ac5577215aec1f1991adcd4b4cbfRafael J. Wysocki 601bb8089454391ac5577215aec1f1991adcd4b4cbfRafael J. Wysocki /* 602bb8089454391ac5577215aec1f1991adcd4b4cbfRafael J. Wysocki * Legacy PM support is used by default, so warn if the new framework is 603bb8089454391ac5577215aec1f1991adcd4b4cbfRafael J. Wysocki * supported as well. Drivers are supposed to support either the 604bb8089454391ac5577215aec1f1991adcd4b4cbfRafael J. Wysocki * former, or the latter, but not both at the same time. 605bb8089454391ac5577215aec1f1991adcd4b4cbfRafael J. Wysocki */ 60682440a8253e09047410ff4df5c202be15645573fDavid Fries WARN(ret && drv->driver.pm, "driver %s device %04x:%04x\n", 60782440a8253e09047410ff4df5c202be15645573fDavid Fries drv->name, pci_dev->vendor, pci_dev->device); 608bb8089454391ac5577215aec1f1991adcd4b4cbfRafael J. Wysocki 609bb8089454391ac5577215aec1f1991adcd4b4cbfRafael J. Wysocki return ret; 61007e836e8d1f3688311d97fe1bf46980b0f9ae9c1Rafael J. Wysocki} 61107e836e8d1f3688311d97fe1bf46980b0f9ae9c1Rafael J. Wysocki 612571ff7584bb9e05fca0eb79752ae55a46faf3a98Rafael J. Wysocki/* New power management framework */ 613571ff7584bb9e05fca0eb79752ae55a46faf3a98Rafael J. Wysocki 614bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysockistatic int pci_pm_prepare(struct device *dev) 615bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki{ 616bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki struct device_driver *drv = dev->driver; 617bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki int error = 0; 618bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki 6196cbf82148ff286ec22a55be6836c3a5bffc489c1Rafael J. Wysocki /* 620eea3fc0357eb89d0b2d1af37bdfb83eb4076a542Rafael J. Wysocki * If a PCI device configured to wake up the system from sleep states 621eea3fc0357eb89d0b2d1af37bdfb83eb4076a542Rafael J. Wysocki * has been suspended at run time and there's a resume request pending 622eea3fc0357eb89d0b2d1af37bdfb83eb4076a542Rafael J. Wysocki * for it, this is equivalent to the device signaling wakeup, so the 623eea3fc0357eb89d0b2d1af37bdfb83eb4076a542Rafael J. Wysocki * system suspend operation should be aborted. 624eea3fc0357eb89d0b2d1af37bdfb83eb4076a542Rafael J. Wysocki */ 625eea3fc0357eb89d0b2d1af37bdfb83eb4076a542Rafael J. Wysocki pm_runtime_get_noresume(dev); 626eea3fc0357eb89d0b2d1af37bdfb83eb4076a542Rafael J. Wysocki if (pm_runtime_barrier(dev) && device_may_wakeup(dev)) 627eea3fc0357eb89d0b2d1af37bdfb83eb4076a542Rafael J. Wysocki pm_wakeup_event(dev, 0); 628eea3fc0357eb89d0b2d1af37bdfb83eb4076a542Rafael J. Wysocki 629eea3fc0357eb89d0b2d1af37bdfb83eb4076a542Rafael J. Wysocki if (pm_wakeup_pending()) { 630eea3fc0357eb89d0b2d1af37bdfb83eb4076a542Rafael J. Wysocki pm_runtime_put_sync(dev); 631eea3fc0357eb89d0b2d1af37bdfb83eb4076a542Rafael J. Wysocki return -EBUSY; 632eea3fc0357eb89d0b2d1af37bdfb83eb4076a542Rafael J. Wysocki } 633eea3fc0357eb89d0b2d1af37bdfb83eb4076a542Rafael J. Wysocki 634eea3fc0357eb89d0b2d1af37bdfb83eb4076a542Rafael J. Wysocki /* 6356cbf82148ff286ec22a55be6836c3a5bffc489c1Rafael J. Wysocki * PCI devices suspended at run time need to be resumed at this 6366cbf82148ff286ec22a55be6836c3a5bffc489c1Rafael J. Wysocki * point, because in general it is necessary to reconfigure them for 6376cbf82148ff286ec22a55be6836c3a5bffc489c1Rafael J. Wysocki * system suspend. Namely, if the device is supposed to wake up the 6386cbf82148ff286ec22a55be6836c3a5bffc489c1Rafael J. Wysocki * system from the sleep state, we may need to reconfigure it for this 6396cbf82148ff286ec22a55be6836c3a5bffc489c1Rafael J. Wysocki * purpose. In turn, if the device is not supposed to wake up the 6406cbf82148ff286ec22a55be6836c3a5bffc489c1Rafael J. Wysocki * system from the sleep state, we'll have to prevent it from signaling 6416cbf82148ff286ec22a55be6836c3a5bffc489c1Rafael J. Wysocki * wake-up. 6426cbf82148ff286ec22a55be6836c3a5bffc489c1Rafael J. Wysocki */ 643eea3fc0357eb89d0b2d1af37bdfb83eb4076a542Rafael J. Wysocki pm_runtime_resume(dev); 6446cbf82148ff286ec22a55be6836c3a5bffc489c1Rafael J. Wysocki 645bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki if (drv && drv->pm && drv->pm->prepare) 646bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki error = drv->pm->prepare(dev); 647bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki 648bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki return error; 649bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki} 650bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki 651bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysockistatic void pci_pm_complete(struct device *dev) 652bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki{ 653bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki struct device_driver *drv = dev->driver; 654bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki 655bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki if (drv && drv->pm && drv->pm->complete) 656bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki drv->pm->complete(dev); 657a5f76d5eba157bf637beb2dd18026db2917c512eRafael J. Wysocki 658a5f76d5eba157bf637beb2dd18026db2917c512eRafael J. Wysocki pm_runtime_put_sync(dev); 659bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki} 660bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki 6616cbf82148ff286ec22a55be6836c3a5bffc489c1Rafael J. Wysocki#else /* !CONFIG_PM_SLEEP */ 6626cbf82148ff286ec22a55be6836c3a5bffc489c1Rafael J. Wysocki 6636cbf82148ff286ec22a55be6836c3a5bffc489c1Rafael J. Wysocki#define pci_pm_prepare NULL 6646cbf82148ff286ec22a55be6836c3a5bffc489c1Rafael J. Wysocki#define pci_pm_complete NULL 6656cbf82148ff286ec22a55be6836c3a5bffc489c1Rafael J. Wysocki 6666cbf82148ff286ec22a55be6836c3a5bffc489c1Rafael J. Wysocki#endif /* !CONFIG_PM_SLEEP */ 6676cbf82148ff286ec22a55be6836c3a5bffc489c1Rafael J. Wysocki 668bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki#ifdef CONFIG_SUSPEND 669bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki 670bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysockistatic int pci_pm_suspend(struct device *dev) 671bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki{ 672bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki struct pci_dev *pci_dev = to_pci_dev(dev); 6738150f32b90f630ad3e460f026ce338cb81685bc9Dmitry Torokhov const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL; 674bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki 675ad8cfa1defee14a5181d9b63e666318c51cfaeedRafael J. Wysocki if (pci_has_legacy_pm_support(pci_dev)) 676ad8cfa1defee14a5181d9b63e666318c51cfaeedRafael J. Wysocki return pci_legacy_suspend(dev, PMSG_SUSPEND); 677bb8089454391ac5577215aec1f1991adcd4b4cbfRafael J. Wysocki 6785294e256717923f4a3297bb8b802f5e0625763f3Rafael J. Wysocki if (!pm) { 6795294e256717923f4a3297bb8b802f5e0625763f3Rafael J. Wysocki pci_pm_default_suspend(pci_dev); 6805294e256717923f4a3297bb8b802f5e0625763f3Rafael J. Wysocki goto Fixup; 6815294e256717923f4a3297bb8b802f5e0625763f3Rafael J. Wysocki } 6825294e256717923f4a3297bb8b802f5e0625763f3Rafael J. Wysocki 6835294e256717923f4a3297bb8b802f5e0625763f3Rafael J. Wysocki if (pm->suspend) { 6845294e256717923f4a3297bb8b802f5e0625763f3Rafael J. Wysocki pci_power_t prev = pci_dev->current_state; 6855294e256717923f4a3297bb8b802f5e0625763f3Rafael J. Wysocki int error; 6865294e256717923f4a3297bb8b802f5e0625763f3Rafael J. Wysocki 687ddb7c9d29fac34626aef2af9f19787a888e4ca9cRafael J. Wysocki error = pm->suspend(dev); 688ddb7c9d29fac34626aef2af9f19787a888e4ca9cRafael J. Wysocki suspend_report_result(pm->suspend, error); 6895294e256717923f4a3297bb8b802f5e0625763f3Rafael J. Wysocki if (error) 6905294e256717923f4a3297bb8b802f5e0625763f3Rafael J. Wysocki return error; 6915294e256717923f4a3297bb8b802f5e0625763f3Rafael J. Wysocki 69246939f8b15e44f065d052e89ea4f2adc81fdc740Rafael J. Wysocki if (!pci_dev->state_saved && pci_dev->current_state != PCI_D0 6935294e256717923f4a3297bb8b802f5e0625763f3Rafael J. Wysocki && pci_dev->current_state != PCI_UNKNOWN) { 6945294e256717923f4a3297bb8b802f5e0625763f3Rafael J. Wysocki WARN_ONCE(pci_dev->current_state != prev, 6955294e256717923f4a3297bb8b802f5e0625763f3Rafael J. Wysocki "PCI PM: State of device not saved by %pF\n", 6965294e256717923f4a3297bb8b802f5e0625763f3Rafael J. Wysocki pm->suspend); 6975294e256717923f4a3297bb8b802f5e0625763f3Rafael J. Wysocki } 698bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki } 699fa58d305d9925b01830e535896a7227a868a9e15Rafael J. Wysocki 7005294e256717923f4a3297bb8b802f5e0625763f3Rafael J. Wysocki Fixup: 7015294e256717923f4a3297bb8b802f5e0625763f3Rafael J. Wysocki pci_fixup_device(pci_fixup_suspend, pci_dev); 7025294e256717923f4a3297bb8b802f5e0625763f3Rafael J. Wysocki 7035294e256717923f4a3297bb8b802f5e0625763f3Rafael J. Wysocki return 0; 704bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki} 705bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki 706bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysockistatic int pci_pm_suspend_noirq(struct device *dev) 707c8958177224622411b9979eabb5610e30b06034bGreg Kroah-Hartman{ 708355a72d75b3b4f4877db4c9070c798238028ecb5Rafael J. Wysocki struct pci_dev *pci_dev = to_pci_dev(dev); 7098150f32b90f630ad3e460f026ce338cb81685bc9Dmitry Torokhov const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL; 710c8958177224622411b9979eabb5610e30b06034bGreg Kroah-Hartman 711bb8089454391ac5577215aec1f1991adcd4b4cbfRafael J. Wysocki if (pci_has_legacy_pm_support(pci_dev)) 712bb8089454391ac5577215aec1f1991adcd4b4cbfRafael J. Wysocki return pci_legacy_suspend_late(dev, PMSG_SUSPEND); 713bb8089454391ac5577215aec1f1991adcd4b4cbfRafael J. Wysocki 714931ff68a5a53fa84bcdf9b1b179a80e54e034bd0Rafael J. Wysocki if (!pm) { 715931ff68a5a53fa84bcdf9b1b179a80e54e034bd0Rafael J. Wysocki pci_save_state(pci_dev); 71646939f8b15e44f065d052e89ea4f2adc81fdc740Rafael J. Wysocki return 0; 717931ff68a5a53fa84bcdf9b1b179a80e54e034bd0Rafael J. Wysocki } 71846939f8b15e44f065d052e89ea4f2adc81fdc740Rafael J. Wysocki 71946939f8b15e44f065d052e89ea4f2adc81fdc740Rafael J. Wysocki if (pm->suspend_noirq) { 72046939f8b15e44f065d052e89ea4f2adc81fdc740Rafael J. Wysocki pci_power_t prev = pci_dev->current_state; 72146939f8b15e44f065d052e89ea4f2adc81fdc740Rafael J. Wysocki int error; 72246939f8b15e44f065d052e89ea4f2adc81fdc740Rafael J. Wysocki 72346939f8b15e44f065d052e89ea4f2adc81fdc740Rafael J. Wysocki error = pm->suspend_noirq(dev); 72446939f8b15e44f065d052e89ea4f2adc81fdc740Rafael J. Wysocki suspend_report_result(pm->suspend_noirq, error); 72546939f8b15e44f065d052e89ea4f2adc81fdc740Rafael J. Wysocki if (error) 72646939f8b15e44f065d052e89ea4f2adc81fdc740Rafael J. Wysocki return error; 72746939f8b15e44f065d052e89ea4f2adc81fdc740Rafael J. Wysocki 72846939f8b15e44f065d052e89ea4f2adc81fdc740Rafael J. Wysocki if (!pci_dev->state_saved && pci_dev->current_state != PCI_D0 72946939f8b15e44f065d052e89ea4f2adc81fdc740Rafael J. Wysocki && pci_dev->current_state != PCI_UNKNOWN) { 73046939f8b15e44f065d052e89ea4f2adc81fdc740Rafael J. Wysocki WARN_ONCE(pci_dev->current_state != prev, 73146939f8b15e44f065d052e89ea4f2adc81fdc740Rafael J. Wysocki "PCI PM: State of device not saved by %pF\n", 73246939f8b15e44f065d052e89ea4f2adc81fdc740Rafael J. Wysocki pm->suspend_noirq); 73346939f8b15e44f065d052e89ea4f2adc81fdc740Rafael J. Wysocki return 0; 73446939f8b15e44f065d052e89ea4f2adc81fdc740Rafael J. Wysocki } 735bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki } 736bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki 73746939f8b15e44f065d052e89ea4f2adc81fdc740Rafael J. Wysocki if (!pci_dev->state_saved) { 73846939f8b15e44f065d052e89ea4f2adc81fdc740Rafael J. Wysocki pci_save_state(pci_dev); 73946939f8b15e44f065d052e89ea4f2adc81fdc740Rafael J. Wysocki if (!pci_is_bridge(pci_dev)) 74046939f8b15e44f065d052e89ea4f2adc81fdc740Rafael J. Wysocki pci_prepare_to_sleep(pci_dev); 74146939f8b15e44f065d052e89ea4f2adc81fdc740Rafael J. Wysocki } 742d67e37d7933ba3b28a63ff38c957e433aaca5dc4Rafael J. Wysocki 74346939f8b15e44f065d052e89ea4f2adc81fdc740Rafael J. Wysocki pci_pm_set_unknown_state(pci_dev); 74446939f8b15e44f065d052e89ea4f2adc81fdc740Rafael J. Wysocki 7450659cf9dcd148f6771c056fa95976fda9c5abf9dAlan Stern /* 7460659cf9dcd148f6771c056fa95976fda9c5abf9dAlan Stern * Some BIOSes from ASUS have a bug: If a USB EHCI host controller's 7470659cf9dcd148f6771c056fa95976fda9c5abf9dAlan Stern * PCI COMMAND register isn't 0, the BIOS assumes that the controller 7480659cf9dcd148f6771c056fa95976fda9c5abf9dAlan Stern * hasn't been quiesced and tries to turn it off. If the controller 7490659cf9dcd148f6771c056fa95976fda9c5abf9dAlan Stern * is already in D3, this can hang or cause memory corruption. 7500659cf9dcd148f6771c056fa95976fda9c5abf9dAlan Stern * 7510659cf9dcd148f6771c056fa95976fda9c5abf9dAlan Stern * Since the value of the COMMAND register doesn't matter once the 7520659cf9dcd148f6771c056fa95976fda9c5abf9dAlan Stern * device has been suspended, we can safely set it to 0 here. 7530659cf9dcd148f6771c056fa95976fda9c5abf9dAlan Stern */ 7540659cf9dcd148f6771c056fa95976fda9c5abf9dAlan Stern if (pci_dev->class == PCI_CLASS_SERIAL_USB_EHCI) 7550659cf9dcd148f6771c056fa95976fda9c5abf9dAlan Stern pci_write_config_word(pci_dev, PCI_COMMAND, 0); 7560659cf9dcd148f6771c056fa95976fda9c5abf9dAlan Stern 75746939f8b15e44f065d052e89ea4f2adc81fdc740Rafael J. Wysocki return 0; 758c8958177224622411b9979eabb5610e30b06034bGreg Kroah-Hartman} 7591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 760f6dc1e5e3d4b523e1616b43beddb04e4fb1d376aRafael J. Wysockistatic int pci_pm_resume_noirq(struct device *dev) 761bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki{ 762bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki struct pci_dev *pci_dev = to_pci_dev(dev); 763bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki struct device_driver *drv = dev->driver; 764355a72d75b3b4f4877db4c9070c798238028ecb5Rafael J. Wysocki int error = 0; 765bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki 7666cbf82148ff286ec22a55be6836c3a5bffc489c1Rafael J. Wysocki pci_pm_default_resume_early(pci_dev); 767aa8c6c93747f7b55fa11e1624fec8ca33763a805Rafael J. Wysocki 768ad8cfa1defee14a5181d9b63e666318c51cfaeedRafael J. Wysocki if (pci_has_legacy_pm_support(pci_dev)) 769f6dc1e5e3d4b523e1616b43beddb04e4fb1d376aRafael J. Wysocki return pci_legacy_resume_early(dev); 770bb8089454391ac5577215aec1f1991adcd4b4cbfRafael J. Wysocki 771f6dc1e5e3d4b523e1616b43beddb04e4fb1d376aRafael J. Wysocki if (drv && drv->pm && drv->pm->resume_noirq) 772f6dc1e5e3d4b523e1616b43beddb04e4fb1d376aRafael J. Wysocki error = drv->pm->resume_noirq(dev); 773bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki 774bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki return error; 775bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki} 776bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki 777f6dc1e5e3d4b523e1616b43beddb04e4fb1d376aRafael J. Wysockistatic int pci_pm_resume(struct device *dev) 778bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki{ 779355a72d75b3b4f4877db4c9070c798238028ecb5Rafael J. Wysocki struct pci_dev *pci_dev = to_pci_dev(dev); 7808150f32b90f630ad3e460f026ce338cb81685bc9Dmitry Torokhov const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL; 781bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki int error = 0; 782bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki 783418e4da33f45fd7bdcce48778b149b780ff730bcRafael J. Wysocki /* 784418e4da33f45fd7bdcce48778b149b780ff730bcRafael J. Wysocki * This is necessary for the suspend error path in which resume is 785418e4da33f45fd7bdcce48778b149b780ff730bcRafael J. Wysocki * called without restoring the standard config registers of the device. 786418e4da33f45fd7bdcce48778b149b780ff730bcRafael J. Wysocki */ 787418e4da33f45fd7bdcce48778b149b780ff730bcRafael J. Wysocki if (pci_dev->state_saved) 788418e4da33f45fd7bdcce48778b149b780ff730bcRafael J. Wysocki pci_restore_standard_config(pci_dev); 789418e4da33f45fd7bdcce48778b149b780ff730bcRafael J. Wysocki 790ad8cfa1defee14a5181d9b63e666318c51cfaeedRafael J. Wysocki if (pci_has_legacy_pm_support(pci_dev)) 791f6dc1e5e3d4b523e1616b43beddb04e4fb1d376aRafael J. Wysocki return pci_legacy_resume(dev); 792bb8089454391ac5577215aec1f1991adcd4b4cbfRafael J. Wysocki 7935294e256717923f4a3297bb8b802f5e0625763f3Rafael J. Wysocki pci_pm_default_resume(pci_dev); 794734104292ff77dc71fe626b4ebd91b314547ca1bRafael J. Wysocki 7955294e256717923f4a3297bb8b802f5e0625763f3Rafael J. Wysocki if (pm) { 7965294e256717923f4a3297bb8b802f5e0625763f3Rafael J. Wysocki if (pm->resume) 7975294e256717923f4a3297bb8b802f5e0625763f3Rafael J. Wysocki error = pm->resume(dev); 7985294e256717923f4a3297bb8b802f5e0625763f3Rafael J. Wysocki } else { 7995294e256717923f4a3297bb8b802f5e0625763f3Rafael J. Wysocki pci_pm_reenable_device(pci_dev); 8005294e256717923f4a3297bb8b802f5e0625763f3Rafael J. Wysocki } 801bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki 802999cce4a52d5abdda5d2cec6bac241899bc19e4cRafael J. Wysocki return error; 803bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki} 804bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki 805bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki#else /* !CONFIG_SUSPEND */ 806bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki 807bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki#define pci_pm_suspend NULL 808bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki#define pci_pm_suspend_noirq NULL 809bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki#define pci_pm_resume NULL 810bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki#define pci_pm_resume_noirq NULL 811bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki 812bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki#endif /* !CONFIG_SUSPEND */ 813bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki 8141f112cee07b314e244ee9e71d9c1e6950dc13327Rafael J. Wysocki#ifdef CONFIG_HIBERNATE_CALLBACKS 815bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki 816bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysockistatic int pci_pm_freeze(struct device *dev) 817bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki{ 818bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki struct pci_dev *pci_dev = to_pci_dev(dev); 8198150f32b90f630ad3e460f026ce338cb81685bc9Dmitry Torokhov const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL; 820bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki 821ad8cfa1defee14a5181d9b63e666318c51cfaeedRafael J. Wysocki if (pci_has_legacy_pm_support(pci_dev)) 822ad8cfa1defee14a5181d9b63e666318c51cfaeedRafael J. Wysocki return pci_legacy_suspend(dev, PMSG_FREEZE); 823bb8089454391ac5577215aec1f1991adcd4b4cbfRafael J. Wysocki 8245294e256717923f4a3297bb8b802f5e0625763f3Rafael J. Wysocki if (!pm) { 8255294e256717923f4a3297bb8b802f5e0625763f3Rafael J. Wysocki pci_pm_default_suspend(pci_dev); 8265294e256717923f4a3297bb8b802f5e0625763f3Rafael J. Wysocki return 0; 827bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki } 828bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki 8295294e256717923f4a3297bb8b802f5e0625763f3Rafael J. Wysocki if (pm->freeze) { 8305294e256717923f4a3297bb8b802f5e0625763f3Rafael J. Wysocki int error; 8315294e256717923f4a3297bb8b802f5e0625763f3Rafael J. Wysocki 8325294e256717923f4a3297bb8b802f5e0625763f3Rafael J. Wysocki error = pm->freeze(dev); 8335294e256717923f4a3297bb8b802f5e0625763f3Rafael J. Wysocki suspend_report_result(pm->freeze, error); 8345294e256717923f4a3297bb8b802f5e0625763f3Rafael J. Wysocki if (error) 8355294e256717923f4a3297bb8b802f5e0625763f3Rafael J. Wysocki return error; 8365294e256717923f4a3297bb8b802f5e0625763f3Rafael J. Wysocki } 8375294e256717923f4a3297bb8b802f5e0625763f3Rafael J. Wysocki 8385294e256717923f4a3297bb8b802f5e0625763f3Rafael J. Wysocki return 0; 839bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki} 840bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki 841bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysockistatic int pci_pm_freeze_noirq(struct device *dev) 842bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki{ 843355a72d75b3b4f4877db4c9070c798238028ecb5Rafael J. Wysocki struct pci_dev *pci_dev = to_pci_dev(dev); 844adf094931ffb25ef4b381559918f1a34181a5273Rafael J. Wysocki struct device_driver *drv = dev->driver; 845bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki 846bb8089454391ac5577215aec1f1991adcd4b4cbfRafael J. Wysocki if (pci_has_legacy_pm_support(pci_dev)) 847bb8089454391ac5577215aec1f1991adcd4b4cbfRafael J. Wysocki return pci_legacy_suspend_late(dev, PMSG_FREEZE); 848bb8089454391ac5577215aec1f1991adcd4b4cbfRafael J. Wysocki 849d67e37d7933ba3b28a63ff38c957e433aaca5dc4Rafael J. Wysocki if (drv && drv->pm && drv->pm->freeze_noirq) { 85046939f8b15e44f065d052e89ea4f2adc81fdc740Rafael J. Wysocki int error; 85146939f8b15e44f065d052e89ea4f2adc81fdc740Rafael J. Wysocki 852d67e37d7933ba3b28a63ff38c957e433aaca5dc4Rafael J. Wysocki error = drv->pm->freeze_noirq(dev); 853d67e37d7933ba3b28a63ff38c957e433aaca5dc4Rafael J. Wysocki suspend_report_result(drv->pm->freeze_noirq, error); 85446939f8b15e44f065d052e89ea4f2adc81fdc740Rafael J. Wysocki if (error) 85546939f8b15e44f065d052e89ea4f2adc81fdc740Rafael J. Wysocki return error; 856bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki } 857bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki 85846939f8b15e44f065d052e89ea4f2adc81fdc740Rafael J. Wysocki if (!pci_dev->state_saved) 85946939f8b15e44f065d052e89ea4f2adc81fdc740Rafael J. Wysocki pci_save_state(pci_dev); 860d67e37d7933ba3b28a63ff38c957e433aaca5dc4Rafael J. Wysocki 86146939f8b15e44f065d052e89ea4f2adc81fdc740Rafael J. Wysocki pci_pm_set_unknown_state(pci_dev); 86246939f8b15e44f065d052e89ea4f2adc81fdc740Rafael J. Wysocki 86346939f8b15e44f065d052e89ea4f2adc81fdc740Rafael J. Wysocki return 0; 864bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki} 865bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki 866f6dc1e5e3d4b523e1616b43beddb04e4fb1d376aRafael J. Wysockistatic int pci_pm_thaw_noirq(struct device *dev) 867bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki{ 868355a72d75b3b4f4877db4c9070c798238028ecb5Rafael J. Wysocki struct pci_dev *pci_dev = to_pci_dev(dev); 869bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki struct device_driver *drv = dev->driver; 870bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki int error = 0; 871bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki 872ad8cfa1defee14a5181d9b63e666318c51cfaeedRafael J. Wysocki if (pci_has_legacy_pm_support(pci_dev)) 873f6dc1e5e3d4b523e1616b43beddb04e4fb1d376aRafael J. Wysocki return pci_legacy_resume_early(dev); 874bb8089454391ac5577215aec1f1991adcd4b4cbfRafael J. Wysocki 875f6dc1e5e3d4b523e1616b43beddb04e4fb1d376aRafael J. Wysocki pci_update_current_state(pci_dev, PCI_D0); 876d67e37d7933ba3b28a63ff38c957e433aaca5dc4Rafael J. Wysocki 877f6dc1e5e3d4b523e1616b43beddb04e4fb1d376aRafael J. Wysocki if (drv && drv->pm && drv->pm->thaw_noirq) 878f6dc1e5e3d4b523e1616b43beddb04e4fb1d376aRafael J. Wysocki error = drv->pm->thaw_noirq(dev); 879bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki 880bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki return error; 881bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki} 882bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki 883f6dc1e5e3d4b523e1616b43beddb04e4fb1d376aRafael J. Wysockistatic int pci_pm_thaw(struct device *dev) 884bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki{ 885355a72d75b3b4f4877db4c9070c798238028ecb5Rafael J. Wysocki struct pci_dev *pci_dev = to_pci_dev(dev); 8868150f32b90f630ad3e460f026ce338cb81685bc9Dmitry Torokhov const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL; 887bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki int error = 0; 888bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki 889ad8cfa1defee14a5181d9b63e666318c51cfaeedRafael J. Wysocki if (pci_has_legacy_pm_support(pci_dev)) 890f6dc1e5e3d4b523e1616b43beddb04e4fb1d376aRafael J. Wysocki return pci_legacy_resume(dev); 891bb8089454391ac5577215aec1f1991adcd4b4cbfRafael J. Wysocki 8925294e256717923f4a3297bb8b802f5e0625763f3Rafael J. Wysocki if (pm) { 8935294e256717923f4a3297bb8b802f5e0625763f3Rafael J. Wysocki if (pm->thaw) 8945294e256717923f4a3297bb8b802f5e0625763f3Rafael J. Wysocki error = pm->thaw(dev); 8955294e256717923f4a3297bb8b802f5e0625763f3Rafael J. Wysocki } else { 8965294e256717923f4a3297bb8b802f5e0625763f3Rafael J. Wysocki pci_pm_reenable_device(pci_dev); 8975294e256717923f4a3297bb8b802f5e0625763f3Rafael J. Wysocki } 898bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki 8994b77b0a2ba27d64f58f16d8d4d48d8319dda36ffRafael J. Wysocki pci_dev->state_saved = false; 9004b77b0a2ba27d64f58f16d8d4d48d8319dda36ffRafael J. Wysocki 901bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki return error; 902bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki} 903bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki 904bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysockistatic int pci_pm_poweroff(struct device *dev) 905bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki{ 906355a72d75b3b4f4877db4c9070c798238028ecb5Rafael J. Wysocki struct pci_dev *pci_dev = to_pci_dev(dev); 9078150f32b90f630ad3e460f026ce338cb81685bc9Dmitry Torokhov const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL; 908bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki 909ad8cfa1defee14a5181d9b63e666318c51cfaeedRafael J. Wysocki if (pci_has_legacy_pm_support(pci_dev)) 910ad8cfa1defee14a5181d9b63e666318c51cfaeedRafael J. Wysocki return pci_legacy_suspend(dev, PMSG_HIBERNATE); 911bb8089454391ac5577215aec1f1991adcd4b4cbfRafael J. Wysocki 9125294e256717923f4a3297bb8b802f5e0625763f3Rafael J. Wysocki if (!pm) { 9135294e256717923f4a3297bb8b802f5e0625763f3Rafael J. Wysocki pci_pm_default_suspend(pci_dev); 9145294e256717923f4a3297bb8b802f5e0625763f3Rafael J. Wysocki goto Fixup; 9155294e256717923f4a3297bb8b802f5e0625763f3Rafael J. Wysocki } 9165294e256717923f4a3297bb8b802f5e0625763f3Rafael J. Wysocki 9175294e256717923f4a3297bb8b802f5e0625763f3Rafael J. Wysocki if (pm->poweroff) { 91846939f8b15e44f065d052e89ea4f2adc81fdc740Rafael J. Wysocki int error; 91946939f8b15e44f065d052e89ea4f2adc81fdc740Rafael J. Wysocki 920ddb7c9d29fac34626aef2af9f19787a888e4ca9cRafael J. Wysocki error = pm->poweroff(dev); 921ddb7c9d29fac34626aef2af9f19787a888e4ca9cRafael J. Wysocki suspend_report_result(pm->poweroff, error); 92246939f8b15e44f065d052e89ea4f2adc81fdc740Rafael J. Wysocki if (error) 92346939f8b15e44f065d052e89ea4f2adc81fdc740Rafael J. Wysocki return error; 924bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki } 925bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki 9265294e256717923f4a3297bb8b802f5e0625763f3Rafael J. Wysocki Fixup: 9275294e256717923f4a3297bb8b802f5e0625763f3Rafael J. Wysocki pci_fixup_device(pci_fixup_suspend, pci_dev); 928c9b9972b3c88272be02d971346285d1c67fbb95fRafael J. Wysocki 92946939f8b15e44f065d052e89ea4f2adc81fdc740Rafael J. Wysocki return 0; 930bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki} 931bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki 932bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysockistatic int pci_pm_poweroff_noirq(struct device *dev) 933bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki{ 93446939f8b15e44f065d052e89ea4f2adc81fdc740Rafael J. Wysocki struct pci_dev *pci_dev = to_pci_dev(dev); 935adf094931ffb25ef4b381559918f1a34181a5273Rafael J. Wysocki struct device_driver *drv = dev->driver; 936bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki 937bb8089454391ac5577215aec1f1991adcd4b4cbfRafael J. Wysocki if (pci_has_legacy_pm_support(to_pci_dev(dev))) 938bb8089454391ac5577215aec1f1991adcd4b4cbfRafael J. Wysocki return pci_legacy_suspend_late(dev, PMSG_HIBERNATE); 939bb8089454391ac5577215aec1f1991adcd4b4cbfRafael J. Wysocki 94046939f8b15e44f065d052e89ea4f2adc81fdc740Rafael J. Wysocki if (!drv || !drv->pm) 94146939f8b15e44f065d052e89ea4f2adc81fdc740Rafael J. Wysocki return 0; 94246939f8b15e44f065d052e89ea4f2adc81fdc740Rafael J. Wysocki 94346939f8b15e44f065d052e89ea4f2adc81fdc740Rafael J. Wysocki if (drv->pm->poweroff_noirq) { 94446939f8b15e44f065d052e89ea4f2adc81fdc740Rafael J. Wysocki int error; 94546939f8b15e44f065d052e89ea4f2adc81fdc740Rafael J. Wysocki 946d67e37d7933ba3b28a63ff38c957e433aaca5dc4Rafael J. Wysocki error = drv->pm->poweroff_noirq(dev); 947d67e37d7933ba3b28a63ff38c957e433aaca5dc4Rafael J. Wysocki suspend_report_result(drv->pm->poweroff_noirq, error); 94846939f8b15e44f065d052e89ea4f2adc81fdc740Rafael J. Wysocki if (error) 94946939f8b15e44f065d052e89ea4f2adc81fdc740Rafael J. Wysocki return error; 950bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki } 951bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki 95246939f8b15e44f065d052e89ea4f2adc81fdc740Rafael J. Wysocki if (!pci_dev->state_saved && !pci_is_bridge(pci_dev)) 95346939f8b15e44f065d052e89ea4f2adc81fdc740Rafael J. Wysocki pci_prepare_to_sleep(pci_dev); 95446939f8b15e44f065d052e89ea4f2adc81fdc740Rafael J. Wysocki 95546939f8b15e44f065d052e89ea4f2adc81fdc740Rafael J. Wysocki return 0; 956bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki} 957bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki 958f6dc1e5e3d4b523e1616b43beddb04e4fb1d376aRafael J. Wysockistatic int pci_pm_restore_noirq(struct device *dev) 959bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki{ 960bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki struct pci_dev *pci_dev = to_pci_dev(dev); 961bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki struct device_driver *drv = dev->driver; 962355a72d75b3b4f4877db4c9070c798238028ecb5Rafael J. Wysocki int error = 0; 963bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki 9646cbf82148ff286ec22a55be6836c3a5bffc489c1Rafael J. Wysocki pci_pm_default_resume_early(pci_dev); 965aa8c6c93747f7b55fa11e1624fec8ca33763a805Rafael J. Wysocki 966ad8cfa1defee14a5181d9b63e666318c51cfaeedRafael J. Wysocki if (pci_has_legacy_pm_support(pci_dev)) 967f6dc1e5e3d4b523e1616b43beddb04e4fb1d376aRafael J. Wysocki return pci_legacy_resume_early(dev); 968bb8089454391ac5577215aec1f1991adcd4b4cbfRafael J. Wysocki 969f6dc1e5e3d4b523e1616b43beddb04e4fb1d376aRafael J. Wysocki if (drv && drv->pm && drv->pm->restore_noirq) 970f6dc1e5e3d4b523e1616b43beddb04e4fb1d376aRafael J. Wysocki error = drv->pm->restore_noirq(dev); 971bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki 972bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki return error; 973bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki} 974bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki 975f6dc1e5e3d4b523e1616b43beddb04e4fb1d376aRafael J. Wysockistatic int pci_pm_restore(struct device *dev) 976bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki{ 977bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki struct pci_dev *pci_dev = to_pci_dev(dev); 9788150f32b90f630ad3e460f026ce338cb81685bc9Dmitry Torokhov const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL; 979bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki int error = 0; 980bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki 981418e4da33f45fd7bdcce48778b149b780ff730bcRafael J. Wysocki /* 982418e4da33f45fd7bdcce48778b149b780ff730bcRafael J. Wysocki * This is necessary for the hibernation error path in which restore is 983418e4da33f45fd7bdcce48778b149b780ff730bcRafael J. Wysocki * called without restoring the standard config registers of the device. 984418e4da33f45fd7bdcce48778b149b780ff730bcRafael J. Wysocki */ 985418e4da33f45fd7bdcce48778b149b780ff730bcRafael J. Wysocki if (pci_dev->state_saved) 986418e4da33f45fd7bdcce48778b149b780ff730bcRafael J. Wysocki pci_restore_standard_config(pci_dev); 987418e4da33f45fd7bdcce48778b149b780ff730bcRafael J. Wysocki 988ad8cfa1defee14a5181d9b63e666318c51cfaeedRafael J. Wysocki if (pci_has_legacy_pm_support(pci_dev)) 989f6dc1e5e3d4b523e1616b43beddb04e4fb1d376aRafael J. Wysocki return pci_legacy_resume(dev); 990bb8089454391ac5577215aec1f1991adcd4b4cbfRafael J. Wysocki 9915294e256717923f4a3297bb8b802f5e0625763f3Rafael J. Wysocki pci_pm_default_resume(pci_dev); 992734104292ff77dc71fe626b4ebd91b314547ca1bRafael J. Wysocki 9935294e256717923f4a3297bb8b802f5e0625763f3Rafael J. Wysocki if (pm) { 9945294e256717923f4a3297bb8b802f5e0625763f3Rafael J. Wysocki if (pm->restore) 9955294e256717923f4a3297bb8b802f5e0625763f3Rafael J. Wysocki error = pm->restore(dev); 9965294e256717923f4a3297bb8b802f5e0625763f3Rafael J. Wysocki } else { 9975294e256717923f4a3297bb8b802f5e0625763f3Rafael J. Wysocki pci_pm_reenable_device(pci_dev); 9985294e256717923f4a3297bb8b802f5e0625763f3Rafael J. Wysocki } 999bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki 1000bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki return error; 1001c8958177224622411b9979eabb5610e30b06034bGreg Kroah-Hartman} 10021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 10031f112cee07b314e244ee9e71d9c1e6950dc13327Rafael J. Wysocki#else /* !CONFIG_HIBERNATE_CALLBACKS */ 1004bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki 1005bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki#define pci_pm_freeze NULL 1006bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki#define pci_pm_freeze_noirq NULL 1007bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki#define pci_pm_thaw NULL 1008bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki#define pci_pm_thaw_noirq NULL 1009bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki#define pci_pm_poweroff NULL 1010bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki#define pci_pm_poweroff_noirq NULL 1011bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki#define pci_pm_restore NULL 1012bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki#define pci_pm_restore_noirq NULL 1013bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki 10141f112cee07b314e244ee9e71d9c1e6950dc13327Rafael J. Wysocki#endif /* !CONFIG_HIBERNATE_CALLBACKS */ 1015bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki 10166cbf82148ff286ec22a55be6836c3a5bffc489c1Rafael J. Wysocki#ifdef CONFIG_PM_RUNTIME 10176cbf82148ff286ec22a55be6836c3a5bffc489c1Rafael J. Wysocki 10186cbf82148ff286ec22a55be6836c3a5bffc489c1Rafael J. Wysockistatic int pci_pm_runtime_suspend(struct device *dev) 10196cbf82148ff286ec22a55be6836c3a5bffc489c1Rafael J. Wysocki{ 10206cbf82148ff286ec22a55be6836c3a5bffc489c1Rafael J. Wysocki struct pci_dev *pci_dev = to_pci_dev(dev); 10216cbf82148ff286ec22a55be6836c3a5bffc489c1Rafael J. Wysocki const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL; 10226cbf82148ff286ec22a55be6836c3a5bffc489c1Rafael J. Wysocki pci_power_t prev = pci_dev->current_state; 10236cbf82148ff286ec22a55be6836c3a5bffc489c1Rafael J. Wysocki int error; 10246cbf82148ff286ec22a55be6836c3a5bffc489c1Rafael J. Wysocki 10256cbf82148ff286ec22a55be6836c3a5bffc489c1Rafael J. Wysocki if (!pm || !pm->runtime_suspend) 10266cbf82148ff286ec22a55be6836c3a5bffc489c1Rafael J. Wysocki return -ENOSYS; 10276cbf82148ff286ec22a55be6836c3a5bffc489c1Rafael J. Wysocki 10286cbf82148ff286ec22a55be6836c3a5bffc489c1Rafael J. Wysocki error = pm->runtime_suspend(dev); 10296cbf82148ff286ec22a55be6836c3a5bffc489c1Rafael J. Wysocki suspend_report_result(pm->runtime_suspend, error); 10306cbf82148ff286ec22a55be6836c3a5bffc489c1Rafael J. Wysocki if (error) 10316cbf82148ff286ec22a55be6836c3a5bffc489c1Rafael J. Wysocki return error; 10326cbf82148ff286ec22a55be6836c3a5bffc489c1Rafael J. Wysocki 10336cbf82148ff286ec22a55be6836c3a5bffc489c1Rafael J. Wysocki pci_fixup_device(pci_fixup_suspend, pci_dev); 10346cbf82148ff286ec22a55be6836c3a5bffc489c1Rafael J. Wysocki 10356cbf82148ff286ec22a55be6836c3a5bffc489c1Rafael J. Wysocki if (!pci_dev->state_saved && pci_dev->current_state != PCI_D0 10366cbf82148ff286ec22a55be6836c3a5bffc489c1Rafael J. Wysocki && pci_dev->current_state != PCI_UNKNOWN) { 10376cbf82148ff286ec22a55be6836c3a5bffc489c1Rafael J. Wysocki WARN_ONCE(pci_dev->current_state != prev, 10386cbf82148ff286ec22a55be6836c3a5bffc489c1Rafael J. Wysocki "PCI PM: State of device not saved by %pF\n", 10396cbf82148ff286ec22a55be6836c3a5bffc489c1Rafael J. Wysocki pm->runtime_suspend); 10406cbf82148ff286ec22a55be6836c3a5bffc489c1Rafael J. Wysocki return 0; 10416cbf82148ff286ec22a55be6836c3a5bffc489c1Rafael J. Wysocki } 10426cbf82148ff286ec22a55be6836c3a5bffc489c1Rafael J. Wysocki 10436cbf82148ff286ec22a55be6836c3a5bffc489c1Rafael J. Wysocki if (!pci_dev->state_saved) 10446cbf82148ff286ec22a55be6836c3a5bffc489c1Rafael J. Wysocki pci_save_state(pci_dev); 10456cbf82148ff286ec22a55be6836c3a5bffc489c1Rafael J. Wysocki 10466cbf82148ff286ec22a55be6836c3a5bffc489c1Rafael J. Wysocki pci_finish_runtime_suspend(pci_dev); 10476cbf82148ff286ec22a55be6836c3a5bffc489c1Rafael J. Wysocki 10486cbf82148ff286ec22a55be6836c3a5bffc489c1Rafael J. Wysocki return 0; 10496cbf82148ff286ec22a55be6836c3a5bffc489c1Rafael J. Wysocki} 10506cbf82148ff286ec22a55be6836c3a5bffc489c1Rafael J. Wysocki 10516cbf82148ff286ec22a55be6836c3a5bffc489c1Rafael J. Wysockistatic int pci_pm_runtime_resume(struct device *dev) 10526cbf82148ff286ec22a55be6836c3a5bffc489c1Rafael J. Wysocki{ 10536cbf82148ff286ec22a55be6836c3a5bffc489c1Rafael J. Wysocki struct pci_dev *pci_dev = to_pci_dev(dev); 10546cbf82148ff286ec22a55be6836c3a5bffc489c1Rafael J. Wysocki const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL; 10556cbf82148ff286ec22a55be6836c3a5bffc489c1Rafael J. Wysocki 10566cbf82148ff286ec22a55be6836c3a5bffc489c1Rafael J. Wysocki if (!pm || !pm->runtime_resume) 10576cbf82148ff286ec22a55be6836c3a5bffc489c1Rafael J. Wysocki return -ENOSYS; 10586cbf82148ff286ec22a55be6836c3a5bffc489c1Rafael J. Wysocki 10596cbf82148ff286ec22a55be6836c3a5bffc489c1Rafael J. Wysocki pci_pm_default_resume_early(pci_dev); 10606cbf82148ff286ec22a55be6836c3a5bffc489c1Rafael J. Wysocki __pci_enable_wake(pci_dev, PCI_D0, true, false); 10616cbf82148ff286ec22a55be6836c3a5bffc489c1Rafael J. Wysocki pci_fixup_device(pci_fixup_resume, pci_dev); 10626cbf82148ff286ec22a55be6836c3a5bffc489c1Rafael J. Wysocki 10636cbf82148ff286ec22a55be6836c3a5bffc489c1Rafael J. Wysocki return pm->runtime_resume(dev); 10646cbf82148ff286ec22a55be6836c3a5bffc489c1Rafael J. Wysocki} 10656cbf82148ff286ec22a55be6836c3a5bffc489c1Rafael J. Wysocki 10666cbf82148ff286ec22a55be6836c3a5bffc489c1Rafael J. Wysockistatic int pci_pm_runtime_idle(struct device *dev) 10676cbf82148ff286ec22a55be6836c3a5bffc489c1Rafael J. Wysocki{ 10686cbf82148ff286ec22a55be6836c3a5bffc489c1Rafael J. Wysocki const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL; 10696cbf82148ff286ec22a55be6836c3a5bffc489c1Rafael J. Wysocki 10706cbf82148ff286ec22a55be6836c3a5bffc489c1Rafael J. Wysocki if (!pm) 10716cbf82148ff286ec22a55be6836c3a5bffc489c1Rafael J. Wysocki return -ENOSYS; 10726cbf82148ff286ec22a55be6836c3a5bffc489c1Rafael J. Wysocki 10736cbf82148ff286ec22a55be6836c3a5bffc489c1Rafael J. Wysocki if (pm->runtime_idle) { 10746cbf82148ff286ec22a55be6836c3a5bffc489c1Rafael J. Wysocki int ret = pm->runtime_idle(dev); 10756cbf82148ff286ec22a55be6836c3a5bffc489c1Rafael J. Wysocki if (ret) 10766cbf82148ff286ec22a55be6836c3a5bffc489c1Rafael J. Wysocki return ret; 10776cbf82148ff286ec22a55be6836c3a5bffc489c1Rafael J. Wysocki } 10786cbf82148ff286ec22a55be6836c3a5bffc489c1Rafael J. Wysocki 10796cbf82148ff286ec22a55be6836c3a5bffc489c1Rafael J. Wysocki pm_runtime_suspend(dev); 10806cbf82148ff286ec22a55be6836c3a5bffc489c1Rafael J. Wysocki 10816cbf82148ff286ec22a55be6836c3a5bffc489c1Rafael J. Wysocki return 0; 10826cbf82148ff286ec22a55be6836c3a5bffc489c1Rafael J. Wysocki} 10836cbf82148ff286ec22a55be6836c3a5bffc489c1Rafael J. Wysocki 10846cbf82148ff286ec22a55be6836c3a5bffc489c1Rafael J. Wysocki#else /* !CONFIG_PM_RUNTIME */ 10856cbf82148ff286ec22a55be6836c3a5bffc489c1Rafael J. Wysocki 10866cbf82148ff286ec22a55be6836c3a5bffc489c1Rafael J. Wysocki#define pci_pm_runtime_suspend NULL 10876cbf82148ff286ec22a55be6836c3a5bffc489c1Rafael J. Wysocki#define pci_pm_runtime_resume NULL 10886cbf82148ff286ec22a55be6836c3a5bffc489c1Rafael J. Wysocki#define pci_pm_runtime_idle NULL 10896cbf82148ff286ec22a55be6836c3a5bffc489c1Rafael J. Wysocki 10906cbf82148ff286ec22a55be6836c3a5bffc489c1Rafael J. Wysocki#endif /* !CONFIG_PM_RUNTIME */ 10916cbf82148ff286ec22a55be6836c3a5bffc489c1Rafael J. Wysocki 1092aa33860158114d0df3c7997bc1dd41c0168e1c2aRafael J. Wysocki#ifdef CONFIG_PM 10936cbf82148ff286ec22a55be6836c3a5bffc489c1Rafael J. Wysocki 10948150f32b90f630ad3e460f026ce338cb81685bc9Dmitry Torokhovconst struct dev_pm_ops pci_dev_pm_ops = { 1095adf094931ffb25ef4b381559918f1a34181a5273Rafael J. Wysocki .prepare = pci_pm_prepare, 1096adf094931ffb25ef4b381559918f1a34181a5273Rafael J. Wysocki .complete = pci_pm_complete, 1097adf094931ffb25ef4b381559918f1a34181a5273Rafael J. Wysocki .suspend = pci_pm_suspend, 1098adf094931ffb25ef4b381559918f1a34181a5273Rafael J. Wysocki .resume = pci_pm_resume, 1099adf094931ffb25ef4b381559918f1a34181a5273Rafael J. Wysocki .freeze = pci_pm_freeze, 1100adf094931ffb25ef4b381559918f1a34181a5273Rafael J. Wysocki .thaw = pci_pm_thaw, 1101adf094931ffb25ef4b381559918f1a34181a5273Rafael J. Wysocki .poweroff = pci_pm_poweroff, 1102adf094931ffb25ef4b381559918f1a34181a5273Rafael J. Wysocki .restore = pci_pm_restore, 1103bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki .suspend_noirq = pci_pm_suspend_noirq, 1104bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki .resume_noirq = pci_pm_resume_noirq, 1105bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki .freeze_noirq = pci_pm_freeze_noirq, 1106bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki .thaw_noirq = pci_pm_thaw_noirq, 1107bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki .poweroff_noirq = pci_pm_poweroff_noirq, 1108bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki .restore_noirq = pci_pm_restore_noirq, 11096cbf82148ff286ec22a55be6836c3a5bffc489c1Rafael J. Wysocki .runtime_suspend = pci_pm_runtime_suspend, 11106cbf82148ff286ec22a55be6836c3a5bffc489c1Rafael J. Wysocki .runtime_resume = pci_pm_runtime_resume, 11116cbf82148ff286ec22a55be6836c3a5bffc489c1Rafael J. Wysocki .runtime_idle = pci_pm_runtime_idle, 1112bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki}; 1113bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki 1114adf094931ffb25ef4b381559918f1a34181a5273Rafael J. Wysocki#define PCI_PM_OPS_PTR (&pci_dev_pm_ops) 1115bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki 11166cbf82148ff286ec22a55be6836c3a5bffc489c1Rafael J. Wysocki#else /* !COMFIG_PM_OPS */ 1117bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki 1118bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki#define PCI_PM_OPS_PTR NULL 1119bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki 11206cbf82148ff286ec22a55be6836c3a5bffc489c1Rafael J. Wysocki#endif /* !COMFIG_PM_OPS */ 1121bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki 11221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/** 1123863b18f4b5e7d9e6903b353328cf6fa084dbb619Laurent riffard * __pci_register_driver - register a new pci driver 11241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * @drv: the driver structure to register 1125863b18f4b5e7d9e6903b353328cf6fa084dbb619Laurent riffard * @owner: owner module of drv 1126f95d882d81ee731be2a4a3b34f86810e29b68836Randy Dunlap * @mod_name: module name string 11271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 11281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Adds the driver structure to the list of registered drivers. 11291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Returns a negative value on error, otherwise 0. 1130eaae4b3a84a3781543a32bcaf0a33306ae915574Steven Cole * If no error occurred, the driver remains registered even if 11311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * no device was claimed during registration. 11321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 1133725522b5453dd680412f2b6463a988e4fd148757Greg Kroah-Hartmanint __pci_register_driver(struct pci_driver *drv, struct module *owner, 1134725522b5453dd680412f2b6463a988e4fd148757Greg Kroah-Hartman const char *mod_name) 11351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 11361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int error; 11371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 11381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* initialize common driver fields */ 11391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds drv->driver.name = drv->name; 11401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds drv->driver.bus = &pci_bus_type; 1141863b18f4b5e7d9e6903b353328cf6fa084dbb619Laurent riffard drv->driver.owner = owner; 1142725522b5453dd680412f2b6463a988e4fd148757Greg Kroah-Hartman drv->driver.mod_name = mod_name; 114350b0075520a0acba9cabab5203bbce918b966d9aAlan Cox 114475865858971add95809c5c9cd35dc4cfba08e33bGreg Kroah-Hartman spin_lock_init(&drv->dynids.lock); 114575865858971add95809c5c9cd35dc4cfba08e33bGreg Kroah-Hartman INIT_LIST_HEAD(&drv->dynids.list); 11461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 11471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* register with core */ 11481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds error = driver_register(&drv->driver); 114950bf14b3ff05fb6e10688021b96f95d30a300f8dAkinobu Mita if (error) 11500994375e9614f78657031e04e30019b9cdb62795Chris Wright goto out; 11511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1152ed283e9f0a2cc0541870828c76c6c6997c51a318Alan Stern error = pci_create_newid_files(drv); 115350bf14b3ff05fb6e10688021b96f95d30a300f8dAkinobu Mita if (error) 11540994375e9614f78657031e04e30019b9cdb62795Chris Wright goto out_newid; 11550994375e9614f78657031e04e30019b9cdb62795Chris Wrightout: 11561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return error; 11570994375e9614f78657031e04e30019b9cdb62795Chris Wright 11580994375e9614f78657031e04e30019b9cdb62795Chris Wrightout_newid: 11590994375e9614f78657031e04e30019b9cdb62795Chris Wright driver_unregister(&drv->driver); 11600994375e9614f78657031e04e30019b9cdb62795Chris Wright goto out; 11611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 11621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 11631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/** 11641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * pci_unregister_driver - unregister a pci driver 11651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * @drv: the driver structure to unregister 11661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 11671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Deletes the driver structure from the list of registered PCI drivers, 11681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * gives it a chance to clean up by calling its remove() function for 11691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * each device it was responsible for, and marks those devices as 11701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * driverless. 11711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 11721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 11731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsvoid 11741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldspci_unregister_driver(struct pci_driver *drv) 11751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 1176ed283e9f0a2cc0541870828c76c6c6997c51a318Alan Stern pci_remove_newid_files(drv); 11771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds driver_unregister(&drv->driver); 11781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pci_free_dynids(drv); 11791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 11801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 11811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic struct pci_driver pci_compat_driver = { 11821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .name = "compat" 11831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}; 11841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 11851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/** 11861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * pci_dev_driver - get the pci_driver of a device 11871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * @dev: the device to query 11881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 11891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Returns the appropriate pci_driver structure or %NULL if there is no 11901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * registered driver for the device. 11911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 11921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstruct pci_driver * 11931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldspci_dev_driver(const struct pci_dev *dev) 11941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 11951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (dev->driver) 11961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return dev->driver; 11971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else { 11981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int i; 11991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for(i=0; i<=PCI_ROM_RESOURCE; i++) 12001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (dev->resource[i].flags & IORESOURCE_BUSY) 12011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return &pci_compat_driver; 12021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 12031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return NULL; 12041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 12051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 12061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/** 12071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * pci_bus_match - Tell if a PCI device structure has a matching PCI device id structure 12081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * @dev: the PCI device structure to match against 12098f7020d36374dda9366fee1343f8eacfe8f5e641Randy Dunlap * @drv: the device driver to search for matching PCI device id structures 12101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 12111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Used by a driver to check whether a PCI device present in the 12128f7020d36374dda9366fee1343f8eacfe8f5e641Randy Dunlap * system is in its list of supported devices. Returns the matching 12131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * pci_device_id structure or %NULL if there is no match. 12141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 121575865858971add95809c5c9cd35dc4cfba08e33bGreg Kroah-Hartmanstatic int pci_bus_match(struct device *dev, struct device_driver *drv) 12161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 121775865858971add95809c5c9cd35dc4cfba08e33bGreg Kroah-Hartman struct pci_dev *pci_dev = to_pci_dev(dev); 121875865858971add95809c5c9cd35dc4cfba08e33bGreg Kroah-Hartman struct pci_driver *pci_drv = to_pci_driver(drv); 12191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds const struct pci_device_id *found_id; 12201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 122175865858971add95809c5c9cd35dc4cfba08e33bGreg Kroah-Hartman found_id = pci_match_device(pci_drv, pci_dev); 12221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (found_id) 12231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 1; 12241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 122575865858971add95809c5c9cd35dc4cfba08e33bGreg Kroah-Hartman return 0; 12261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 12271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 12281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/** 12291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * pci_dev_get - increments the reference count of the pci device structure 12301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * @dev: the device being referenced 12311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 12321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Each live reference to a device should be refcounted. 12331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 12341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Drivers for PCI devices should normally record such references in 12351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * their probe() methods, when they bind to a device, and release 12361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * them by calling pci_dev_put(), in their disconnect() methods. 12371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 12381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * A pointer to the device with the incremented reference counter is returned. 12391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 12401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstruct pci_dev *pci_dev_get(struct pci_dev *dev) 12411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 12421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (dev) 12431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds get_device(&dev->dev); 12441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return dev; 12451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 12461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 12471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/** 12481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * pci_dev_put - release a use of the pci device structure 12491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * @dev: device that's been disconnected 12501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 12511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Must be called when a user of a device is finished with it. When the last 12521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * user of the device calls this function, the memory of the device is freed. 12531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 12541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsvoid pci_dev_put(struct pci_dev *dev) 12551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 12561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (dev) 12571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds put_device(&dev->dev); 12581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 12591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 12601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#ifndef CONFIG_HOTPLUG 12617eff2e7a8b65c25920207324e56611150eb1cd9aKay Sieversint pci_uevent(struct device *dev, struct kobj_uevent_env *env) 12621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 12631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -ENODEV; 12641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 12651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif 12661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 12671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstruct bus_type pci_bus_type = { 12681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .name = "pci", 12691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .match = pci_bus_match, 1270312c004d36ce6c739512bac83b452f4c20ab1f62Kay Sievers .uevent = pci_uevent, 1271b15d686a2b589c9e4f1ea116553e9c3c3d030daeRussell King .probe = pci_device_probe, 1272b15d686a2b589c9e4f1ea116553e9c3c3d030daeRussell King .remove = pci_device_remove, 1273cbd69dbbf1adfce6e048f15afc8629901ca9dae5Linus Torvalds .shutdown = pci_device_shutdown, 12741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .dev_attrs = pci_dev_attrs, 1275705b1aaa823e800490f157cd9366ad8cff385f5fAlex Chiang .bus_attrs = pci_bus_attrs, 1276bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki .pm = PCI_PM_OPS_PTR, 12771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}; 12781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 12791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int __init pci_driver_init(void) 12801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 12811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return bus_register(&pci_bus_type); 12821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 12831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 12841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldspostcore_initcall(pci_driver_init); 12851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 12869dba910e9de2c4aa15ec1286f10052c107ef48caTejun HeoEXPORT_SYMBOL_GPL(pci_add_dynid); 128775865858971add95809c5c9cd35dc4cfba08e33bGreg Kroah-HartmanEXPORT_SYMBOL(pci_match_id); 1288863b18f4b5e7d9e6903b353328cf6fa084dbb619Laurent riffardEXPORT_SYMBOL(__pci_register_driver); 12891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsEXPORT_SYMBOL(pci_unregister_driver); 12901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsEXPORT_SYMBOL(pci_dev_driver); 12911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsEXPORT_SYMBOL(pci_bus_type); 12921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsEXPORT_SYMBOL(pci_dev_get); 12931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsEXPORT_SYMBOL(pci_dev_put); 1294