pci-driver.c revision 2debb4d2019fa05a0896f1591dea0e0dc21bc046
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> 191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include "pci.h" 201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Dynamic device IDs are disabled for !CONFIG_HOTPLUG 231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2575865858971add95809c5c9cd35dc4cfba08e33bGreg Kroah-Hartmanstruct pci_dynid { 2675865858971add95809c5c9cd35dc4cfba08e33bGreg Kroah-Hartman struct list_head node; 2775865858971add95809c5c9cd35dc4cfba08e33bGreg Kroah-Hartman struct pci_device_id id; 2875865858971add95809c5c9cd35dc4cfba08e33bGreg Kroah-Hartman}; 291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 303d3c2ae1101c1f2dff7e2f9d514769779dbd2737Greg Kroah-Hartman#ifdef CONFIG_HOTPLUG 313d3c2ae1101c1f2dff7e2f9d514769779dbd2737Greg Kroah-Hartman 321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/** 338f7020d36374dda9366fee1343f8eacfe8f5e641Randy Dunlap * store_new_id - add a new PCI device ID to this driver and re-probe devices 348f7020d36374dda9366fee1343f8eacfe8f5e641Randy Dunlap * @driver: target device driver 358f7020d36374dda9366fee1343f8eacfe8f5e641Randy Dunlap * @buf: buffer for scanning device ID data 368f7020d36374dda9366fee1343f8eacfe8f5e641Randy Dunlap * @count: input size 371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Adds a new dynamic pci device ID to this driver, 391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * and causes the driver to probe for all devices again. 401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 41f8eb1005a5bdb019d2a4ff3ef8d8e8015b22afcbRandy Dunlapstatic ssize_t 421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstore_new_id(struct device_driver *driver, const char *buf, size_t count) 431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 4475865858971add95809c5c9cd35dc4cfba08e33bGreg Kroah-Hartman struct pci_dynid *dynid; 451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct pci_driver *pdrv = to_pci_driver(driver); 46b41d6cf38e27a940d998d989526a9748de1bf028Jean Delvare const struct pci_device_id *ids = pdrv->id_table; 476ba186361ed2cda7e174856a3ab8a8e3237b3c3dJean Delvare __u32 vendor, device, subvendor=PCI_ANY_ID, 481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds subdevice=PCI_ANY_ID, class=0, class_mask=0; 491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned long driver_data=0; 501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int fields=0; 512debb4d2019fa05a0896f1591dea0e0dc21bc046Chris Wright int retval=0; 521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 53b41d6cf38e27a940d998d989526a9748de1bf028Jean Delvare fields = sscanf(buf, "%x %x %x %x %x %x %lx", 541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds &vendor, &device, &subvendor, &subdevice, 551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds &class, &class_mask, &driver_data); 566ba186361ed2cda7e174856a3ab8a8e3237b3c3dJean Delvare if (fields < 2) 571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -EINVAL; 581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 59b41d6cf38e27a940d998d989526a9748de1bf028Jean Delvare /* Only accept driver_data values that match an existing id_table 60b41d6cf38e27a940d998d989526a9748de1bf028Jean Delvare entry */ 612debb4d2019fa05a0896f1591dea0e0dc21bc046Chris Wright if (ids) { 622debb4d2019fa05a0896f1591dea0e0dc21bc046Chris Wright retval = -EINVAL; 632debb4d2019fa05a0896f1591dea0e0dc21bc046Chris Wright while (ids->vendor || ids->subvendor || ids->class_mask) { 642debb4d2019fa05a0896f1591dea0e0dc21bc046Chris Wright if (driver_data == ids->driver_data) { 652debb4d2019fa05a0896f1591dea0e0dc21bc046Chris Wright retval = 0; 662debb4d2019fa05a0896f1591dea0e0dc21bc046Chris Wright break; 672debb4d2019fa05a0896f1591dea0e0dc21bc046Chris Wright } 682debb4d2019fa05a0896f1591dea0e0dc21bc046Chris Wright ids++; 69b41d6cf38e27a940d998d989526a9748de1bf028Jean Delvare } 702debb4d2019fa05a0896f1591dea0e0dc21bc046Chris Wright if (retval) /* No match */ 712debb4d2019fa05a0896f1591dea0e0dc21bc046Chris Wright return retval; 72b41d6cf38e27a940d998d989526a9748de1bf028Jean Delvare } 73b41d6cf38e27a940d998d989526a9748de1bf028Jean Delvare 74f5afe8064f3087bead8fea7e32547c2a3ada5fd0Eric Sesterhenn dynid = kzalloc(sizeof(*dynid), GFP_KERNEL); 751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!dynid) 761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -ENOMEM; 771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dynid->id.vendor = vendor; 791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dynid->id.device = device; 801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dynid->id.subvendor = subvendor; 811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dynid->id.subdevice = subdevice; 821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dynid->id.class = class; 831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dynid->id.class_mask = class_mask; 84edbc25caaa492a82e19baa915f1f6b0a0db6554dMilton Miller dynid->id.driver_data = driver_data; 851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds spin_lock(&pdrv->dynids.lock); 87a56bc69a182f501582557af7fad5bc882b1c856cMichael Ellerman list_add_tail(&dynid->node, &pdrv->dynids.list); 881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds spin_unlock(&pdrv->dynids.lock); 891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9075865858971add95809c5c9cd35dc4cfba08e33bGreg Kroah-Hartman if (get_driver(&pdrv->driver)) { 91b19441af185559118e8247382ea4f2f76ebffc6dGreg Kroah-Hartman retval = driver_attach(&pdrv->driver); 9275865858971add95809c5c9cd35dc4cfba08e33bGreg Kroah-Hartman put_driver(&pdrv->driver); 931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 95b19441af185559118e8247382ea4f2f76ebffc6dGreg Kroah-Hartman if (retval) 96b19441af185559118e8247382ea4f2f76ebffc6dGreg Kroah-Hartman return retval; 971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return count; 981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic DRIVER_ATTR(new_id, S_IWUSR, NULL, store_new_id); 1001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void 1021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldspci_free_dynids(struct pci_driver *drv) 1031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 10475865858971add95809c5c9cd35dc4cfba08e33bGreg Kroah-Hartman struct pci_dynid *dynid, *n; 1051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds spin_lock(&drv->dynids.lock); 10775865858971add95809c5c9cd35dc4cfba08e33bGreg Kroah-Hartman list_for_each_entry_safe(dynid, n, &drv->dynids.list, node) { 1081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds list_del(&dynid->node); 1091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds kfree(dynid); 1101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 1111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds spin_unlock(&drv->dynids.lock); 1121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 1131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int 1151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldspci_create_newid_file(struct pci_driver *drv) 1161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 1171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int error = 0; 1181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (drv->probe != NULL) 11903d43b19b9f56c1d18bc8f2f7890534fbe6a285dGreg Kroah-Hartman error = driver_create_file(&drv->driver, &driver_attr_new_id); 1201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return error; 1211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 1221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 12303d43b19b9f56c1d18bc8f2f7890534fbe6a285dGreg Kroah-Hartmanstatic void pci_remove_newid_file(struct pci_driver *drv) 12403d43b19b9f56c1d18bc8f2f7890534fbe6a285dGreg Kroah-Hartman{ 12503d43b19b9f56c1d18bc8f2f7890534fbe6a285dGreg Kroah-Hartman driver_remove_file(&drv->driver, &driver_attr_new_id); 12603d43b19b9f56c1d18bc8f2f7890534fbe6a285dGreg Kroah-Hartman} 1271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#else /* !CONFIG_HOTPLUG */ 1281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic inline void pci_free_dynids(struct pci_driver *drv) {} 1291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic inline int pci_create_newid_file(struct pci_driver *drv) 1301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 1311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 1321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 13303d43b19b9f56c1d18bc8f2f7890534fbe6a285dGreg Kroah-Hartmanstatic inline void pci_remove_newid_file(struct pci_driver *drv) {} 1341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif 1351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/** 13775865858971add95809c5c9cd35dc4cfba08e33bGreg Kroah-Hartman * pci_match_id - See if a pci device matches a given pci_id table 1381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * @ids: array of PCI device id structures to search in 13975865858971add95809c5c9cd35dc4cfba08e33bGreg Kroah-Hartman * @dev: the PCI device structure to match against. 14075865858971add95809c5c9cd35dc4cfba08e33bGreg Kroah-Hartman * 1411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Used by a driver to check whether a PCI device present in the 14275865858971add95809c5c9cd35dc4cfba08e33bGreg Kroah-Hartman * system is in its list of supported devices. Returns the matching 1431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * pci_device_id structure or %NULL if there is no match. 14475865858971add95809c5c9cd35dc4cfba08e33bGreg Kroah-Hartman * 1458b60756a628a73bc8bf8b59d8716cb3f09b7e7ebRandy Dunlap * Deprecated, don't use this as it will not catch any dynamic ids 14675865858971add95809c5c9cd35dc4cfba08e33bGreg Kroah-Hartman * that a driver might want to check for. 1471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 14875865858971add95809c5c9cd35dc4cfba08e33bGreg Kroah-Hartmanconst struct pci_device_id *pci_match_id(const struct pci_device_id *ids, 14975865858971add95809c5c9cd35dc4cfba08e33bGreg Kroah-Hartman struct pci_dev *dev) 1501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 15175865858971add95809c5c9cd35dc4cfba08e33bGreg Kroah-Hartman if (ids) { 15275865858971add95809c5c9cd35dc4cfba08e33bGreg Kroah-Hartman while (ids->vendor || ids->subvendor || ids->class_mask) { 15375865858971add95809c5c9cd35dc4cfba08e33bGreg Kroah-Hartman if (pci_match_one_device(ids, dev)) 15475865858971add95809c5c9cd35dc4cfba08e33bGreg Kroah-Hartman return ids; 15575865858971add95809c5c9cd35dc4cfba08e33bGreg Kroah-Hartman ids++; 15675865858971add95809c5c9cd35dc4cfba08e33bGreg Kroah-Hartman } 1571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 1581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return NULL; 1591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 1601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/** 162ae9608af9e300395ec032479621f32688c121141Randy Dunlap * pci_match_device - Tell if a PCI device structure has a matching PCI device id structure 16375865858971add95809c5c9cd35dc4cfba08e33bGreg Kroah-Hartman * @drv: the PCI driver to match against 16439ba487fe22a63b3df7c543c82d01db0f0fed700Henrik Kretzschmar * @dev: the PCI device structure to match against 16575865858971add95809c5c9cd35dc4cfba08e33bGreg Kroah-Hartman * 16675865858971add95809c5c9cd35dc4cfba08e33bGreg Kroah-Hartman * Used by a driver to check whether a PCI device present in the 16775865858971add95809c5c9cd35dc4cfba08e33bGreg Kroah-Hartman * system is in its list of supported devices. Returns the matching 16875865858971add95809c5c9cd35dc4cfba08e33bGreg Kroah-Hartman * pci_device_id structure or %NULL if there is no match. 1691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 170d73460d79bc88de74221d73723ed61a0081b7a36Adrian Bunkstatic const struct pci_device_id *pci_match_device(struct pci_driver *drv, 171d73460d79bc88de74221d73723ed61a0081b7a36Adrian Bunk struct pci_dev *dev) 17275865858971add95809c5c9cd35dc4cfba08e33bGreg Kroah-Hartman{ 17375865858971add95809c5c9cd35dc4cfba08e33bGreg Kroah-Hartman struct pci_dynid *dynid; 1741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1757461b60afa62b26943e97861d87b9f9a32d7fd9cRussell King /* Look at the dynamic ids first, before the static ones */ 17675865858971add95809c5c9cd35dc4cfba08e33bGreg Kroah-Hartman spin_lock(&drv->dynids.lock); 17775865858971add95809c5c9cd35dc4cfba08e33bGreg Kroah-Hartman list_for_each_entry(dynid, &drv->dynids.list, node) { 17875865858971add95809c5c9cd35dc4cfba08e33bGreg Kroah-Hartman if (pci_match_one_device(&dynid->id, dev)) { 17975865858971add95809c5c9cd35dc4cfba08e33bGreg Kroah-Hartman spin_unlock(&drv->dynids.lock); 18075865858971add95809c5c9cd35dc4cfba08e33bGreg Kroah-Hartman return &dynid->id; 18175865858971add95809c5c9cd35dc4cfba08e33bGreg Kroah-Hartman } 1821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 18375865858971add95809c5c9cd35dc4cfba08e33bGreg Kroah-Hartman spin_unlock(&drv->dynids.lock); 1847461b60afa62b26943e97861d87b9f9a32d7fd9cRussell King 1857461b60afa62b26943e97861d87b9f9a32d7fd9cRussell King return pci_match_id(drv->id_table, dev); 1861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 1871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 188d42c69972b853fd33a26c8c7405624be41a22136Andi Kleenstatic int pci_call_probe(struct pci_driver *drv, struct pci_dev *dev, 189d42c69972b853fd33a26c8c7405624be41a22136Andi Kleen const struct pci_device_id *id) 190d42c69972b853fd33a26c8c7405624be41a22136Andi Kleen{ 191d42c69972b853fd33a26c8c7405624be41a22136Andi Kleen int error; 192d42c69972b853fd33a26c8c7405624be41a22136Andi Kleen#ifdef CONFIG_NUMA 193d42c69972b853fd33a26c8c7405624be41a22136Andi Kleen /* Execute driver initialization on node where the 194d42c69972b853fd33a26c8c7405624be41a22136Andi Kleen device's bus is attached to. This way the driver likely 195d42c69972b853fd33a26c8c7405624be41a22136Andi Kleen allocates its local memory on the right node without 196d42c69972b853fd33a26c8c7405624be41a22136Andi Kleen any need to change it. */ 197d42c69972b853fd33a26c8c7405624be41a22136Andi Kleen struct mempolicy *oldpol; 198d42c69972b853fd33a26c8c7405624be41a22136Andi Kleen cpumask_t oldmask = current->cpus_allowed; 1994efeb4dd3c0bf534e431a8e7c72d0afbd4cd24aaYinghai Lu int node = dev_to_node(&dev->dev); 200f70316dace2bb99730800d47044acb818c6735f6Mike Travis 201f70316dace2bb99730800d47044acb818c6735f6Mike Travis if (node >= 0) { 202f70316dace2bb99730800d47044acb818c6735f6Mike Travis node_to_cpumask_ptr(nodecpumask, node); 203f70316dace2bb99730800d47044acb818c6735f6Mike Travis set_cpus_allowed_ptr(current, nodecpumask); 204f70316dace2bb99730800d47044acb818c6735f6Mike Travis } 205d42c69972b853fd33a26c8c7405624be41a22136Andi Kleen /* And set default memory allocation policy */ 206d42c69972b853fd33a26c8c7405624be41a22136Andi Kleen oldpol = current->mempolicy; 20774e27e44b0407fb1f6e8d1f7b7818f108463c4b8Lee Schermerhorn current->mempolicy = NULL; /* fall back to system default policy */ 208d42c69972b853fd33a26c8c7405624be41a22136Andi Kleen#endif 209d42c69972b853fd33a26c8c7405624be41a22136Andi Kleen error = drv->probe(dev, id); 210d42c69972b853fd33a26c8c7405624be41a22136Andi Kleen#ifdef CONFIG_NUMA 211f70316dace2bb99730800d47044acb818c6735f6Mike Travis set_cpus_allowed_ptr(current, &oldmask); 212d42c69972b853fd33a26c8c7405624be41a22136Andi Kleen current->mempolicy = oldpol; 213d42c69972b853fd33a26c8c7405624be41a22136Andi Kleen#endif 214d42c69972b853fd33a26c8c7405624be41a22136Andi Kleen return error; 215d42c69972b853fd33a26c8c7405624be41a22136Andi Kleen} 216d42c69972b853fd33a26c8c7405624be41a22136Andi Kleen 2171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/** 2181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * __pci_device_probe() 2198f7020d36374dda9366fee1343f8eacfe8f5e641Randy Dunlap * @drv: driver to call to check if it wants the PCI device 2208f7020d36374dda9366fee1343f8eacfe8f5e641Randy Dunlap * @pci_dev: PCI device being probed 2211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 2228f7020d36374dda9366fee1343f8eacfe8f5e641Randy Dunlap * returns 0 on success, else error. 2231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * side-effect: pci_dev->driver is set to drv when drv claims pci_dev. 2241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 2251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int 2261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds__pci_device_probe(struct pci_driver *drv, struct pci_dev *pci_dev) 22775865858971add95809c5c9cd35dc4cfba08e33bGreg Kroah-Hartman{ 22875865858971add95809c5c9cd35dc4cfba08e33bGreg Kroah-Hartman const struct pci_device_id *id; 2291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int error = 0; 2301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!pci_dev->driver && drv->probe) { 23275865858971add95809c5c9cd35dc4cfba08e33bGreg Kroah-Hartman error = -ENODEV; 23375865858971add95809c5c9cd35dc4cfba08e33bGreg Kroah-Hartman 23475865858971add95809c5c9cd35dc4cfba08e33bGreg Kroah-Hartman id = pci_match_device(drv, pci_dev); 23575865858971add95809c5c9cd35dc4cfba08e33bGreg Kroah-Hartman if (id) 236d42c69972b853fd33a26c8c7405624be41a22136Andi Kleen error = pci_call_probe(drv, pci_dev, id); 23775865858971add95809c5c9cd35dc4cfba08e33bGreg Kroah-Hartman if (error >= 0) { 23875865858971add95809c5c9cd35dc4cfba08e33bGreg Kroah-Hartman pci_dev->driver = drv; 23975865858971add95809c5c9cd35dc4cfba08e33bGreg Kroah-Hartman error = 0; 24075865858971add95809c5c9cd35dc4cfba08e33bGreg Kroah-Hartman } 2411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 2421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return error; 2431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 2441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int pci_device_probe(struct device * dev) 2461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 2471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int error = 0; 2481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct pci_driver *drv; 2491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct pci_dev *pci_dev; 2501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds drv = to_pci_driver(dev->driver); 2521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pci_dev = to_pci_dev(dev); 2531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pci_dev_get(pci_dev); 2541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds error = __pci_device_probe(drv, pci_dev); 2551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (error) 2561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pci_dev_put(pci_dev); 2571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return error; 2591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 2601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int pci_device_remove(struct device * dev) 2621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 2631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct pci_dev * pci_dev = to_pci_dev(dev); 2641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct pci_driver * drv = pci_dev->driver; 2651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (drv) { 2671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (drv->remove) 2681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds drv->remove(pci_dev); 2691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pci_dev->driver = NULL; 2701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 2711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* 2732449e06a5696b7af1c8a369b04c97f3b139cf3bbShaohua Li * If the device is still on, set the power state as "unknown", 2742449e06a5696b7af1c8a369b04c97f3b139cf3bbShaohua Li * since it might change by the next time we load the driver. 2752449e06a5696b7af1c8a369b04c97f3b139cf3bbShaohua Li */ 2762449e06a5696b7af1c8a369b04c97f3b139cf3bbShaohua Li if (pci_dev->current_state == PCI_D0) 2772449e06a5696b7af1c8a369b04c97f3b139cf3bbShaohua Li pci_dev->current_state = PCI_UNKNOWN; 2782449e06a5696b7af1c8a369b04c97f3b139cf3bbShaohua Li 2792449e06a5696b7af1c8a369b04c97f3b139cf3bbShaohua Li /* 2801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * We would love to complain here if pci_dev->is_enabled is set, that 2811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * the driver should have called pci_disable_device(), but the 2821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * unfortunate fact is there are too many odd BIOS and bridge setups 2831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * that don't like drivers doing that all of the time. 2841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Oh well, we can dream of sane hardware when we sleep, no matter how 2851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * horrible the crap we have to deal with is when we are awake... 2861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 2871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pci_dev_put(pci_dev); 2891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 2901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 2911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 292bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysockistatic void pci_device_shutdown(struct device *dev) 293bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki{ 294bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki struct pci_dev *pci_dev = to_pci_dev(dev); 295bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki struct pci_driver *drv = pci_dev->driver; 296bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki 297bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki if (drv && drv->shutdown) 298bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki drv->shutdown(pci_dev); 299bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki pci_msi_shutdown(pci_dev); 300bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki pci_msix_shutdown(pci_dev); 301bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki} 302bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki 303bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki#ifdef CONFIG_PM_SLEEP 304bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki 305355a72d75b3b4f4877db4c9070c798238028ecb5Rafael J. Wysockistatic bool pci_has_legacy_pm_support(struct pci_dev *pci_dev) 306355a72d75b3b4f4877db4c9070c798238028ecb5Rafael J. Wysocki{ 307355a72d75b3b4f4877db4c9070c798238028ecb5Rafael J. Wysocki struct pci_driver *drv = pci_dev->driver; 308355a72d75b3b4f4877db4c9070c798238028ecb5Rafael J. Wysocki 309355a72d75b3b4f4877db4c9070c798238028ecb5Rafael J. Wysocki return drv && (drv->suspend || drv->suspend_late || drv->resume 310355a72d75b3b4f4877db4c9070c798238028ecb5Rafael J. Wysocki || drv->resume_early); 311355a72d75b3b4f4877db4c9070c798238028ecb5Rafael J. Wysocki} 312355a72d75b3b4f4877db4c9070c798238028ecb5Rafael J. Wysocki 313bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki/* 314bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki * Default "suspend" method for devices that have no driver provided suspend, 315bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki * or not even a driver at all. 316bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki */ 317bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysockistatic void pci_default_pm_suspend(struct pci_dev *pci_dev) 318bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki{ 319bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki pci_save_state(pci_dev); 320bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki /* 321bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki * mark its power state as "unknown", since we don't know if 322bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki * e.g. the BIOS will change its device state when we suspend. 323bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki */ 324bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki if (pci_dev->current_state == PCI_D0) 325bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki pci_dev->current_state = PCI_UNKNOWN; 326bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki} 327bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki 328bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki/* 329bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki * Default "resume" method for devices that have no driver provided resume, 330355a72d75b3b4f4877db4c9070c798238028ecb5Rafael J. Wysocki * or not even a driver at all (first part). 331bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki */ 332355a72d75b3b4f4877db4c9070c798238028ecb5Rafael J. Wysockistatic void pci_default_pm_resume_early(struct pci_dev *pci_dev) 333bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki{ 334bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki /* restore the PCI config space */ 335bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki pci_restore_state(pci_dev); 336355a72d75b3b4f4877db4c9070c798238028ecb5Rafael J. Wysocki} 337355a72d75b3b4f4877db4c9070c798238028ecb5Rafael J. Wysocki 338355a72d75b3b4f4877db4c9070c798238028ecb5Rafael J. Wysocki/* 339355a72d75b3b4f4877db4c9070c798238028ecb5Rafael J. Wysocki * Default "resume" method for devices that have no driver provided resume, 340355a72d75b3b4f4877db4c9070c798238028ecb5Rafael J. Wysocki * or not even a driver at all (second part). 341355a72d75b3b4f4877db4c9070c798238028ecb5Rafael J. Wysocki */ 342355a72d75b3b4f4877db4c9070c798238028ecb5Rafael J. Wysockistatic int pci_default_pm_resume_late(struct pci_dev *pci_dev) 343355a72d75b3b4f4877db4c9070c798238028ecb5Rafael J. Wysocki{ 344355a72d75b3b4f4877db4c9070c798238028ecb5Rafael J. Wysocki int retval; 345355a72d75b3b4f4877db4c9070c798238028ecb5Rafael J. Wysocki 346bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki /* if the device was enabled before suspend, reenable */ 347bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki retval = pci_reenable_device(pci_dev); 348bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki /* 349bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki * if the device was busmaster before the suspend, make it busmaster 350bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki * again 351bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki */ 352bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki if (pci_dev->is_busmaster) 353bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki pci_set_master(pci_dev); 354bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki 355bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki return retval; 356bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki} 357bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki 358bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysockistatic int pci_legacy_suspend(struct device *dev, pm_message_t state) 3591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 3601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct pci_dev * pci_dev = to_pci_dev(dev); 3611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct pci_driver * drv = pci_dev->driver; 3621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int i = 0; 3631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 364026694920579590c73b5c56705d543568ed5ad41Andrew Morton if (drv && drv->suspend) { 3651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds i = drv->suspend(pci_dev, state); 366026694920579590c73b5c56705d543568ed5ad41Andrew Morton suspend_report_result(drv->suspend, i); 367026694920579590c73b5c56705d543568ed5ad41Andrew Morton } else { 368bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki pci_default_pm_suspend(pci_dev); 369026694920579590c73b5c56705d543568ed5ad41Andrew Morton } 3701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return i; 3711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 3721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 373bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysockistatic int pci_legacy_suspend_late(struct device *dev, pm_message_t state) 374cbd69dbbf1adfce6e048f15afc8629901ca9dae5Linus Torvalds{ 375cbd69dbbf1adfce6e048f15afc8629901ca9dae5Linus Torvalds struct pci_dev * pci_dev = to_pci_dev(dev); 376cbd69dbbf1adfce6e048f15afc8629901ca9dae5Linus Torvalds struct pci_driver * drv = pci_dev->driver; 377cbd69dbbf1adfce6e048f15afc8629901ca9dae5Linus Torvalds int i = 0; 378cbd69dbbf1adfce6e048f15afc8629901ca9dae5Linus Torvalds 379cbd69dbbf1adfce6e048f15afc8629901ca9dae5Linus Torvalds if (drv && drv->suspend_late) { 380cbd69dbbf1adfce6e048f15afc8629901ca9dae5Linus Torvalds i = drv->suspend_late(pci_dev, state); 381cbd69dbbf1adfce6e048f15afc8629901ca9dae5Linus Torvalds suspend_report_result(drv->suspend_late, i); 382cbd69dbbf1adfce6e048f15afc8629901ca9dae5Linus Torvalds } 383cbd69dbbf1adfce6e048f15afc8629901ca9dae5Linus Torvalds return i; 384cbd69dbbf1adfce6e048f15afc8629901ca9dae5Linus Torvalds} 3851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 386bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysockistatic int pci_legacy_resume(struct device *dev) 3871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 3888d92bc2270d67a43b1d7e94a8cb6f81f1435fe9aJean Delvare int error; 3891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct pci_dev * pci_dev = to_pci_dev(dev); 3901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct pci_driver * drv = pci_dev->driver; 3911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 392355a72d75b3b4f4877db4c9070c798238028ecb5Rafael J. Wysocki if (drv && drv->resume) { 3938d92bc2270d67a43b1d7e94a8cb6f81f1435fe9aJean Delvare error = drv->resume(pci_dev); 394355a72d75b3b4f4877db4c9070c798238028ecb5Rafael J. Wysocki } else { 395355a72d75b3b4f4877db4c9070c798238028ecb5Rafael J. Wysocki pci_default_pm_resume_early(pci_dev); 396355a72d75b3b4f4877db4c9070c798238028ecb5Rafael J. Wysocki error = pci_default_pm_resume_late(pci_dev); 397355a72d75b3b4f4877db4c9070c798238028ecb5Rafael J. Wysocki } 3988d92bc2270d67a43b1d7e94a8cb6f81f1435fe9aJean Delvare return error; 3991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 4001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 401bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysockistatic int pci_legacy_resume_early(struct device *dev) 402cbd69dbbf1adfce6e048f15afc8629901ca9dae5Linus Torvalds{ 403cbd69dbbf1adfce6e048f15afc8629901ca9dae5Linus Torvalds int error = 0; 404cbd69dbbf1adfce6e048f15afc8629901ca9dae5Linus Torvalds struct pci_dev * pci_dev = to_pci_dev(dev); 405cbd69dbbf1adfce6e048f15afc8629901ca9dae5Linus Torvalds struct pci_driver * drv = pci_dev->driver; 406cbd69dbbf1adfce6e048f15afc8629901ca9dae5Linus Torvalds 407cbd69dbbf1adfce6e048f15afc8629901ca9dae5Linus Torvalds if (drv && drv->resume_early) 408cbd69dbbf1adfce6e048f15afc8629901ca9dae5Linus Torvalds error = drv->resume_early(pci_dev); 409cbd69dbbf1adfce6e048f15afc8629901ca9dae5Linus Torvalds return error; 410cbd69dbbf1adfce6e048f15afc8629901ca9dae5Linus Torvalds} 411cbd69dbbf1adfce6e048f15afc8629901ca9dae5Linus Torvalds 412bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysockistatic int pci_pm_prepare(struct device *dev) 413bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki{ 414bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki struct device_driver *drv = dev->driver; 415bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki int error = 0; 416bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki 417bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki if (drv && drv->pm && drv->pm->prepare) 418bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki error = drv->pm->prepare(dev); 419bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki 420bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki return error; 421bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki} 422bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki 423bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysockistatic void pci_pm_complete(struct device *dev) 424bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki{ 425bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki struct device_driver *drv = dev->driver; 426bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki 427bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki if (drv && drv->pm && drv->pm->complete) 428bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki drv->pm->complete(dev); 429bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki} 430bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki 431bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki#ifdef CONFIG_SUSPEND 432bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki 433bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysockistatic int pci_pm_suspend(struct device *dev) 434bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki{ 435bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki struct pci_dev *pci_dev = to_pci_dev(dev); 436bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki struct device_driver *drv = dev->driver; 437bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki int error = 0; 438bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki 439bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki if (drv && drv->pm) { 440bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki if (drv->pm->suspend) { 441bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki error = drv->pm->suspend(dev); 442bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki suspend_report_result(drv->pm->suspend, error); 443bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki } 444355a72d75b3b4f4877db4c9070c798238028ecb5Rafael J. Wysocki } else if (pci_has_legacy_pm_support(pci_dev)) { 445bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki error = pci_legacy_suspend(dev, PMSG_SUSPEND); 446bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki } 447bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki pci_fixup_device(pci_fixup_suspend, pci_dev); 448bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki 449bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki return error; 450bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki} 451bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki 452bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysockistatic int pci_pm_suspend_noirq(struct device *dev) 453c8958177224622411b9979eabb5610e30b06034bGreg Kroah-Hartman{ 454355a72d75b3b4f4877db4c9070c798238028ecb5Rafael J. Wysocki struct pci_dev *pci_dev = to_pci_dev(dev); 455adf094931ffb25ef4b381559918f1a34181a5273Rafael J. Wysocki struct device_driver *drv = dev->driver; 456bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki int error = 0; 457c8958177224622411b9979eabb5610e30b06034bGreg Kroah-Hartman 458bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki if (drv && drv->pm) { 459bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki if (drv->pm->suspend_noirq) { 460bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki error = drv->pm->suspend_noirq(dev); 461bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki suspend_report_result(drv->pm->suspend_noirq, error); 462bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki } 463355a72d75b3b4f4877db4c9070c798238028ecb5Rafael J. Wysocki } else if (pci_has_legacy_pm_support(pci_dev)) { 464bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki error = pci_legacy_suspend_late(dev, PMSG_SUSPEND); 465355a72d75b3b4f4877db4c9070c798238028ecb5Rafael J. Wysocki } else { 466355a72d75b3b4f4877db4c9070c798238028ecb5Rafael J. Wysocki pci_default_pm_suspend(pci_dev); 467bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki } 468bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki 469bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki return error; 470c8958177224622411b9979eabb5610e30b06034bGreg Kroah-Hartman} 4711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 472bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysockistatic int pci_pm_resume(struct device *dev) 473bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki{ 474bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki struct pci_dev *pci_dev = to_pci_dev(dev); 475bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki struct device_driver *drv = dev->driver; 476355a72d75b3b4f4877db4c9070c798238028ecb5Rafael J. Wysocki int error = 0; 477bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki 478bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki pci_fixup_device(pci_fixup_resume, pci_dev); 479bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki 480bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki if (drv && drv->pm) { 481355a72d75b3b4f4877db4c9070c798238028ecb5Rafael J. Wysocki if (drv->pm->resume) 482355a72d75b3b4f4877db4c9070c798238028ecb5Rafael J. Wysocki error = drv->pm->resume(dev); 483355a72d75b3b4f4877db4c9070c798238028ecb5Rafael J. Wysocki } else if (pci_has_legacy_pm_support(pci_dev)) { 484bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki error = pci_legacy_resume(dev); 485355a72d75b3b4f4877db4c9070c798238028ecb5Rafael J. Wysocki } else { 486355a72d75b3b4f4877db4c9070c798238028ecb5Rafael J. Wysocki error = pci_default_pm_resume_late(pci_dev); 487bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki } 488bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki 489bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki return error; 490bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki} 491bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki 492bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysockistatic int pci_pm_resume_noirq(struct device *dev) 493bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki{ 494355a72d75b3b4f4877db4c9070c798238028ecb5Rafael J. Wysocki struct pci_dev *pci_dev = to_pci_dev(dev); 495adf094931ffb25ef4b381559918f1a34181a5273Rafael J. Wysocki struct device_driver *drv = dev->driver; 496bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki int error = 0; 497bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki 498adf094931ffb25ef4b381559918f1a34181a5273Rafael J. Wysocki pci_fixup_device(pci_fixup_resume_early, to_pci_dev(dev)); 499bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki 500bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki if (drv && drv->pm) { 501bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki if (drv->pm->resume_noirq) 502bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki error = drv->pm->resume_noirq(dev); 503355a72d75b3b4f4877db4c9070c798238028ecb5Rafael J. Wysocki } else if (pci_has_legacy_pm_support(pci_dev)) { 504bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki error = pci_legacy_resume_early(dev); 505355a72d75b3b4f4877db4c9070c798238028ecb5Rafael J. Wysocki } else { 506355a72d75b3b4f4877db4c9070c798238028ecb5Rafael J. Wysocki pci_default_pm_resume_early(pci_dev); 507bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki } 508bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki 509bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki return error; 510bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki} 511bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki 512bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki#else /* !CONFIG_SUSPEND */ 513bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki 514bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki#define pci_pm_suspend NULL 515bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki#define pci_pm_suspend_noirq NULL 516bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki#define pci_pm_resume NULL 517bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki#define pci_pm_resume_noirq NULL 518bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki 519bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki#endif /* !CONFIG_SUSPEND */ 520bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki 521bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki#ifdef CONFIG_HIBERNATION 522bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki 523bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysockistatic int pci_pm_freeze(struct device *dev) 524bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki{ 525bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki struct pci_dev *pci_dev = to_pci_dev(dev); 526bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki struct device_driver *drv = dev->driver; 527bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki int error = 0; 528bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki 529bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki if (drv && drv->pm) { 530bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki if (drv->pm->freeze) { 531bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki error = drv->pm->freeze(dev); 532bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki suspend_report_result(drv->pm->freeze, error); 533bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki } 534355a72d75b3b4f4877db4c9070c798238028ecb5Rafael J. Wysocki } else if (pci_has_legacy_pm_support(pci_dev)) { 535bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki error = pci_legacy_suspend(dev, PMSG_FREEZE); 536bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki pci_fixup_device(pci_fixup_suspend, pci_dev); 537bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki } 538bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki 539bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki return error; 540bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki} 541bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki 542bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysockistatic int pci_pm_freeze_noirq(struct device *dev) 543bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki{ 544355a72d75b3b4f4877db4c9070c798238028ecb5Rafael J. Wysocki struct pci_dev *pci_dev = to_pci_dev(dev); 545adf094931ffb25ef4b381559918f1a34181a5273Rafael J. Wysocki struct device_driver *drv = dev->driver; 546bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki int error = 0; 547bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki 548bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki if (drv && drv->pm) { 549bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki if (drv->pm->freeze_noirq) { 550bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki error = drv->pm->freeze_noirq(dev); 551bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki suspend_report_result(drv->pm->freeze_noirq, error); 552bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki } 553355a72d75b3b4f4877db4c9070c798238028ecb5Rafael J. Wysocki } else if (pci_has_legacy_pm_support(pci_dev)) { 554bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki error = pci_legacy_suspend_late(dev, PMSG_FREEZE); 555355a72d75b3b4f4877db4c9070c798238028ecb5Rafael J. Wysocki } else { 556355a72d75b3b4f4877db4c9070c798238028ecb5Rafael J. Wysocki pci_default_pm_suspend(pci_dev); 557bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki } 558bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki 559bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki return error; 560bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki} 561bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki 562bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysockistatic int pci_pm_thaw(struct device *dev) 563bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki{ 564355a72d75b3b4f4877db4c9070c798238028ecb5Rafael J. Wysocki struct pci_dev *pci_dev = to_pci_dev(dev); 565bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki struct device_driver *drv = dev->driver; 566bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki int error = 0; 567bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki 568bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki if (drv && drv->pm) { 569bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki if (drv->pm->thaw) 570bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki error = drv->pm->thaw(dev); 571355a72d75b3b4f4877db4c9070c798238028ecb5Rafael J. Wysocki } else if (pci_has_legacy_pm_support(pci_dev)) { 572355a72d75b3b4f4877db4c9070c798238028ecb5Rafael J. Wysocki pci_fixup_device(pci_fixup_resume, pci_dev); 573bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki error = pci_legacy_resume(dev); 574bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki } 575bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki 576bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki return error; 577bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki} 578bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki 579bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysockistatic int pci_pm_thaw_noirq(struct device *dev) 580bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki{ 581355a72d75b3b4f4877db4c9070c798238028ecb5Rafael J. Wysocki struct pci_dev *pci_dev = to_pci_dev(dev); 582adf094931ffb25ef4b381559918f1a34181a5273Rafael J. Wysocki struct device_driver *drv = dev->driver; 583bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki int error = 0; 584bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki 585bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki if (drv && drv->pm) { 586bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki if (drv->pm->thaw_noirq) 587bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki error = drv->pm->thaw_noirq(dev); 588355a72d75b3b4f4877db4c9070c798238028ecb5Rafael J. Wysocki } else if (pci_has_legacy_pm_support(pci_dev)) { 589adf094931ffb25ef4b381559918f1a34181a5273Rafael J. Wysocki pci_fixup_device(pci_fixup_resume_early, to_pci_dev(dev)); 590bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki error = pci_legacy_resume_early(dev); 591bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki } 592bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki 593bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki return error; 594bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki} 595bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki 596bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysockistatic int pci_pm_poweroff(struct device *dev) 597bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki{ 598355a72d75b3b4f4877db4c9070c798238028ecb5Rafael J. Wysocki struct pci_dev *pci_dev = to_pci_dev(dev); 599bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki struct device_driver *drv = dev->driver; 600bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki int error = 0; 601bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki 602355a72d75b3b4f4877db4c9070c798238028ecb5Rafael J. Wysocki pci_fixup_device(pci_fixup_suspend, pci_dev); 603bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki 604bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki if (drv && drv->pm) { 605bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki if (drv->pm->poweroff) { 606bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki error = drv->pm->poweroff(dev); 607bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki suspend_report_result(drv->pm->poweroff, error); 608bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki } 609355a72d75b3b4f4877db4c9070c798238028ecb5Rafael J. Wysocki } else if (pci_has_legacy_pm_support(pci_dev)) { 610bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki error = pci_legacy_suspend(dev, PMSG_HIBERNATE); 611bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki } 612bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki 613bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki return error; 614bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki} 615bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki 616bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysockistatic int pci_pm_poweroff_noirq(struct device *dev) 617bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki{ 618adf094931ffb25ef4b381559918f1a34181a5273Rafael J. Wysocki struct device_driver *drv = dev->driver; 619bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki int error = 0; 620bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki 621bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki if (drv && drv->pm) { 622bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki if (drv->pm->poweroff_noirq) { 623bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki error = drv->pm->poweroff_noirq(dev); 624bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki suspend_report_result(drv->pm->poweroff_noirq, error); 625bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki } 626355a72d75b3b4f4877db4c9070c798238028ecb5Rafael J. Wysocki } else if (pci_has_legacy_pm_support(to_pci_dev(dev))) { 627bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki error = pci_legacy_suspend_late(dev, PMSG_HIBERNATE); 628bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki } 629bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki 630bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki return error; 631bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki} 632bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki 633bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysockistatic int pci_pm_restore(struct device *dev) 634bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki{ 635bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki struct pci_dev *pci_dev = to_pci_dev(dev); 636bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki struct device_driver *drv = dev->driver; 637355a72d75b3b4f4877db4c9070c798238028ecb5Rafael J. Wysocki int error = 0; 638bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki 639bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki if (drv && drv->pm) { 640355a72d75b3b4f4877db4c9070c798238028ecb5Rafael J. Wysocki if (drv->pm->restore) 641355a72d75b3b4f4877db4c9070c798238028ecb5Rafael J. Wysocki error = drv->pm->restore(dev); 642355a72d75b3b4f4877db4c9070c798238028ecb5Rafael J. Wysocki } else if (pci_has_legacy_pm_support(pci_dev)) { 643bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki error = pci_legacy_resume(dev); 644355a72d75b3b4f4877db4c9070c798238028ecb5Rafael J. Wysocki } else { 645355a72d75b3b4f4877db4c9070c798238028ecb5Rafael J. Wysocki error = pci_default_pm_resume_late(pci_dev); 646bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki } 647bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki pci_fixup_device(pci_fixup_resume, pci_dev); 648bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki 649bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki return error; 650bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki} 651bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki 652bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysockistatic int pci_pm_restore_noirq(struct device *dev) 653bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki{ 654bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki struct pci_dev *pci_dev = to_pci_dev(dev); 655adf094931ffb25ef4b381559918f1a34181a5273Rafael J. Wysocki struct device_driver *drv = dev->driver; 656bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki int error = 0; 657bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki 658bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki pci_fixup_device(pci_fixup_resume, pci_dev); 659bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki 660bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki if (drv && drv->pm) { 661bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki if (drv->pm->restore_noirq) 662bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki error = drv->pm->restore_noirq(dev); 663355a72d75b3b4f4877db4c9070c798238028ecb5Rafael J. Wysocki } else if (pci_has_legacy_pm_support(pci_dev)) { 664bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki error = pci_legacy_resume_early(dev); 665355a72d75b3b4f4877db4c9070c798238028ecb5Rafael J. Wysocki } else { 666355a72d75b3b4f4877db4c9070c798238028ecb5Rafael J. Wysocki pci_default_pm_resume_early(pci_dev); 667bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki } 668bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki pci_fixup_device(pci_fixup_resume_early, pci_dev); 669bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki 670bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki return error; 671c8958177224622411b9979eabb5610e30b06034bGreg Kroah-Hartman} 6721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 673bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki#else /* !CONFIG_HIBERNATION */ 674bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki 675bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki#define pci_pm_freeze NULL 676bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki#define pci_pm_freeze_noirq NULL 677bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki#define pci_pm_thaw NULL 678bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki#define pci_pm_thaw_noirq NULL 679bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki#define pci_pm_poweroff NULL 680bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki#define pci_pm_poweroff_noirq NULL 681bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki#define pci_pm_restore NULL 682bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki#define pci_pm_restore_noirq NULL 683bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki 684bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki#endif /* !CONFIG_HIBERNATION */ 685bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki 686adf094931ffb25ef4b381559918f1a34181a5273Rafael J. Wysockistruct dev_pm_ops pci_dev_pm_ops = { 687adf094931ffb25ef4b381559918f1a34181a5273Rafael J. Wysocki .prepare = pci_pm_prepare, 688adf094931ffb25ef4b381559918f1a34181a5273Rafael J. Wysocki .complete = pci_pm_complete, 689adf094931ffb25ef4b381559918f1a34181a5273Rafael J. Wysocki .suspend = pci_pm_suspend, 690adf094931ffb25ef4b381559918f1a34181a5273Rafael J. Wysocki .resume = pci_pm_resume, 691adf094931ffb25ef4b381559918f1a34181a5273Rafael J. Wysocki .freeze = pci_pm_freeze, 692adf094931ffb25ef4b381559918f1a34181a5273Rafael J. Wysocki .thaw = pci_pm_thaw, 693adf094931ffb25ef4b381559918f1a34181a5273Rafael J. Wysocki .poweroff = pci_pm_poweroff, 694adf094931ffb25ef4b381559918f1a34181a5273Rafael J. Wysocki .restore = pci_pm_restore, 695bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki .suspend_noirq = pci_pm_suspend_noirq, 696bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki .resume_noirq = pci_pm_resume_noirq, 697bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki .freeze_noirq = pci_pm_freeze_noirq, 698bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki .thaw_noirq = pci_pm_thaw_noirq, 699bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki .poweroff_noirq = pci_pm_poweroff_noirq, 700bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki .restore_noirq = pci_pm_restore_noirq, 701bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki}; 702bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki 703adf094931ffb25ef4b381559918f1a34181a5273Rafael J. Wysocki#define PCI_PM_OPS_PTR (&pci_dev_pm_ops) 704bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki 705bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki#else /* !CONFIG_PM_SLEEP */ 706bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki 707bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki#define PCI_PM_OPS_PTR NULL 708bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki 709bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki#endif /* !CONFIG_PM_SLEEP */ 710bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki 7111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/** 712863b18f4b5e7d9e6903b353328cf6fa084dbb619Laurent riffard * __pci_register_driver - register a new pci driver 7131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * @drv: the driver structure to register 714863b18f4b5e7d9e6903b353328cf6fa084dbb619Laurent riffard * @owner: owner module of drv 715f95d882d81ee731be2a4a3b34f86810e29b68836Randy Dunlap * @mod_name: module name string 7161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 7171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Adds the driver structure to the list of registered drivers. 7181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Returns a negative value on error, otherwise 0. 719eaae4b3a84a3781543a32bcaf0a33306ae915574Steven Cole * If no error occurred, the driver remains registered even if 7201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * no device was claimed during registration. 7211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 722725522b5453dd680412f2b6463a988e4fd148757Greg Kroah-Hartmanint __pci_register_driver(struct pci_driver *drv, struct module *owner, 723725522b5453dd680412f2b6463a988e4fd148757Greg Kroah-Hartman const char *mod_name) 7241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 7251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int error; 7261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* initialize common driver fields */ 7281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds drv->driver.name = drv->name; 7291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds drv->driver.bus = &pci_bus_type; 730863b18f4b5e7d9e6903b353328cf6fa084dbb619Laurent riffard drv->driver.owner = owner; 731725522b5453dd680412f2b6463a988e4fd148757Greg Kroah-Hartman drv->driver.mod_name = mod_name; 73250b0075520a0acba9cabab5203bbce918b966d9aAlan Cox 73375865858971add95809c5c9cd35dc4cfba08e33bGreg Kroah-Hartman spin_lock_init(&drv->dynids.lock); 73475865858971add95809c5c9cd35dc4cfba08e33bGreg Kroah-Hartman INIT_LIST_HEAD(&drv->dynids.list); 7351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* register with core */ 7371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds error = driver_register(&drv->driver); 73850bf14b3ff05fb6e10688021b96f95d30a300f8dAkinobu Mita if (error) 73950bf14b3ff05fb6e10688021b96f95d30a300f8dAkinobu Mita return error; 7401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 74150bf14b3ff05fb6e10688021b96f95d30a300f8dAkinobu Mita error = pci_create_newid_file(drv); 74250bf14b3ff05fb6e10688021b96f95d30a300f8dAkinobu Mita if (error) 74350bf14b3ff05fb6e10688021b96f95d30a300f8dAkinobu Mita driver_unregister(&drv->driver); 7441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return error; 7461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 7471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/** 7491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * pci_unregister_driver - unregister a pci driver 7501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * @drv: the driver structure to unregister 7511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 7521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Deletes the driver structure from the list of registered PCI drivers, 7531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * gives it a chance to clean up by calling its remove() function for 7541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * each device it was responsible for, and marks those devices as 7551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * driverless. 7561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 7571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsvoid 7591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldspci_unregister_driver(struct pci_driver *drv) 7601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 76103d43b19b9f56c1d18bc8f2f7890534fbe6a285dGreg Kroah-Hartman pci_remove_newid_file(drv); 7621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds driver_unregister(&drv->driver); 7631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pci_free_dynids(drv); 7641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 7651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic struct pci_driver pci_compat_driver = { 7671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .name = "compat" 7681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}; 7691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/** 7711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * pci_dev_driver - get the pci_driver of a device 7721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * @dev: the device to query 7731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 7741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Returns the appropriate pci_driver structure or %NULL if there is no 7751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * registered driver for the device. 7761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 7771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstruct pci_driver * 7781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldspci_dev_driver(const struct pci_dev *dev) 7791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 7801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (dev->driver) 7811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return dev->driver; 7821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else { 7831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int i; 7841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for(i=0; i<=PCI_ROM_RESOURCE; i++) 7851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (dev->resource[i].flags & IORESOURCE_BUSY) 7861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return &pci_compat_driver; 7871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 7881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return NULL; 7891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 7901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/** 7921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * pci_bus_match - Tell if a PCI device structure has a matching PCI device id structure 7931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * @dev: the PCI device structure to match against 7948f7020d36374dda9366fee1343f8eacfe8f5e641Randy Dunlap * @drv: the device driver to search for matching PCI device id structures 7951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 7961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Used by a driver to check whether a PCI device present in the 7978f7020d36374dda9366fee1343f8eacfe8f5e641Randy Dunlap * system is in its list of supported devices. Returns the matching 7981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * pci_device_id structure or %NULL if there is no match. 7991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 80075865858971add95809c5c9cd35dc4cfba08e33bGreg Kroah-Hartmanstatic int pci_bus_match(struct device *dev, struct device_driver *drv) 8011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 80275865858971add95809c5c9cd35dc4cfba08e33bGreg Kroah-Hartman struct pci_dev *pci_dev = to_pci_dev(dev); 80375865858971add95809c5c9cd35dc4cfba08e33bGreg Kroah-Hartman struct pci_driver *pci_drv = to_pci_driver(drv); 8041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds const struct pci_device_id *found_id; 8051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 80675865858971add95809c5c9cd35dc4cfba08e33bGreg Kroah-Hartman found_id = pci_match_device(pci_drv, pci_dev); 8071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (found_id) 8081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 1; 8091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 81075865858971add95809c5c9cd35dc4cfba08e33bGreg Kroah-Hartman return 0; 8111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 8121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/** 8141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * pci_dev_get - increments the reference count of the pci device structure 8151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * @dev: the device being referenced 8161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 8171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Each live reference to a device should be refcounted. 8181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 8191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Drivers for PCI devices should normally record such references in 8201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * their probe() methods, when they bind to a device, and release 8211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * them by calling pci_dev_put(), in their disconnect() methods. 8221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 8231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * A pointer to the device with the incremented reference counter is returned. 8241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 8251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstruct pci_dev *pci_dev_get(struct pci_dev *dev) 8261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 8271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (dev) 8281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds get_device(&dev->dev); 8291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return dev; 8301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 8311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/** 8331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * pci_dev_put - release a use of the pci device structure 8341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * @dev: device that's been disconnected 8351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 8361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Must be called when a user of a device is finished with it. When the last 8371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * user of the device calls this function, the memory of the device is freed. 8381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 8391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsvoid pci_dev_put(struct pci_dev *dev) 8401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 8411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (dev) 8421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds put_device(&dev->dev); 8431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 8441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#ifndef CONFIG_HOTPLUG 8467eff2e7a8b65c25920207324e56611150eb1cd9aKay Sieversint pci_uevent(struct device *dev, struct kobj_uevent_env *env) 8471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 8481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -ENODEV; 8491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 8501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif 8511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstruct bus_type pci_bus_type = { 8531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .name = "pci", 8541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .match = pci_bus_match, 855312c004d36ce6c739512bac83b452f4c20ab1f62Kay Sievers .uevent = pci_uevent, 856b15d686a2b589c9e4f1ea116553e9c3c3d030daeRussell King .probe = pci_device_probe, 857b15d686a2b589c9e4f1ea116553e9c3c3d030daeRussell King .remove = pci_device_remove, 858cbd69dbbf1adfce6e048f15afc8629901ca9dae5Linus Torvalds .shutdown = pci_device_shutdown, 8591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .dev_attrs = pci_dev_attrs, 860bbb44d9f23d868a2837c6b22b8dfb123d8e7800cRafael J. Wysocki .pm = PCI_PM_OPS_PTR, 8611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}; 8621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int __init pci_driver_init(void) 8641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 8651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return bus_register(&pci_bus_type); 8661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 8671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldspostcore_initcall(pci_driver_init); 8691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 87075865858971add95809c5c9cd35dc4cfba08e33bGreg Kroah-HartmanEXPORT_SYMBOL(pci_match_id); 871863b18f4b5e7d9e6903b353328cf6fa084dbb619Laurent riffardEXPORT_SYMBOL(__pci_register_driver); 8721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsEXPORT_SYMBOL(pci_unregister_driver); 8731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsEXPORT_SYMBOL(pci_dev_driver); 8741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsEXPORT_SYMBOL(pci_bus_type); 8751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsEXPORT_SYMBOL(pci_dev_get); 8761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsEXPORT_SYMBOL(pci_dev_put); 877