aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pci/pci-driver.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/pci/pci-driver.c')
-rw-r--r--drivers/pci/pci-driver.c37
1 files changed, 34 insertions, 3 deletions
diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c
index e4115a0d5ba6..0d0d533894e0 100644
--- a/drivers/pci/pci-driver.c
+++ b/drivers/pci/pci-driver.c
@@ -7,6 +7,7 @@
7#include <linux/module.h> 7#include <linux/module.h>
8#include <linux/init.h> 8#include <linux/init.h>
9#include <linux/device.h> 9#include <linux/device.h>
10#include <linux/mempolicy.h>
10#include "pci.h" 11#include "pci.h"
11 12
12/* 13/*
@@ -163,6 +164,34 @@ const struct pci_device_id *pci_match_device(struct pci_driver *drv,
163 return NULL; 164 return NULL;
164} 165}
165 166
167static int pci_call_probe(struct pci_driver *drv, struct pci_dev *dev,
168 const struct pci_device_id *id)
169{
170 int error;
171#ifdef CONFIG_NUMA
172 /* Execute driver initialization on node where the
173 device's bus is attached to. This way the driver likely
174 allocates its local memory on the right node without
175 any need to change it. */
176 struct mempolicy *oldpol;
177 cpumask_t oldmask = current->cpus_allowed;
178 int node = pcibus_to_node(dev->bus);
179 if (node >= 0 && node_online(node))
180 set_cpus_allowed(current, node_to_cpumask(node));
181 /* And set default memory allocation policy */
182 oldpol = current->mempolicy;
183 current->mempolicy = &default_policy;
184 mpol_get(current->mempolicy);
185#endif
186 error = drv->probe(dev, id);
187#ifdef CONFIG_NUMA
188 set_cpus_allowed(current, oldmask);
189 mpol_free(current->mempolicy);
190 current->mempolicy = oldpol;
191#endif
192 return error;
193}
194
166/** 195/**
167 * __pci_device_probe() 196 * __pci_device_probe()
168 * 197 *
@@ -180,7 +209,7 @@ __pci_device_probe(struct pci_driver *drv, struct pci_dev *pci_dev)
180 209
181 id = pci_match_device(drv, pci_dev); 210 id = pci_match_device(drv, pci_dev);
182 if (id) 211 if (id)
183 error = drv->probe(pci_dev, id); 212 error = pci_call_probe(drv, pci_dev, id);
184 if (error >= 0) { 213 if (error >= 0) {
185 pci_dev->driver = drv; 214 pci_dev->driver = drv;
186 error = 0; 215 error = 0;
@@ -243,17 +272,19 @@ static int pci_device_suspend(struct device * dev, pm_message_t state)
243} 272}
244 273
245 274
246/* 275/*
247 * Default resume method for devices that have no driver provided resume, 276 * Default resume method for devices that have no driver provided resume,
248 * or not even a driver at all. 277 * or not even a driver at all.
249 */ 278 */
250static void pci_default_resume(struct pci_dev *pci_dev) 279static void pci_default_resume(struct pci_dev *pci_dev)
251{ 280{
281 int retval;
282
252 /* restore the PCI config space */ 283 /* restore the PCI config space */
253 pci_restore_state(pci_dev); 284 pci_restore_state(pci_dev);
254 /* if the device was enabled before suspend, reenable */ 285 /* if the device was enabled before suspend, reenable */
255 if (pci_dev->is_enabled) 286 if (pci_dev->is_enabled)
256 pci_enable_device(pci_dev); 287 retval = pci_enable_device(pci_dev);
257 /* if the device was busmaster before the suspend, make it busmaster again */ 288 /* if the device was busmaster before the suspend, make it busmaster again */
258 if (pci_dev->is_busmaster) 289 if (pci_dev->is_busmaster)
259 pci_set_master(pci_dev); 290 pci_set_master(pci_dev);