aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pci/pcie
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/pci/pcie')
-rw-r--r--drivers/pci/pcie/portdrv_core.c41
1 files changed, 28 insertions, 13 deletions
diff --git a/drivers/pci/pcie/portdrv_core.c b/drivers/pci/pcie/portdrv_core.c
index 273e97619bce..265eba033a4a 100644
--- a/drivers/pci/pcie/portdrv_core.c
+++ b/drivers/pci/pcie/portdrv_core.c
@@ -43,7 +43,7 @@ static int assign_interrupt_mode(struct pci_dev *dev, int *vectors, int mask)
43{ 43{
44 struct pcie_port_data *port_data = pci_get_drvdata(dev); 44 struct pcie_port_data *port_data = pci_get_drvdata(dev);
45 int i, pos, nvec, status = -EINVAL; 45 int i, pos, nvec, status = -EINVAL;
46 int interrupt_mode = PCIE_PORT_INTx_MODE; 46 int interrupt_mode = PCIE_PORT_NO_IRQ;
47 47
48 /* Set INTx as default */ 48 /* Set INTx as default */
49 for (i = 0, nvec = 0; i < PCIE_PORT_DEVICE_MAXSERVICES; i++) { 49 for (i = 0, nvec = 0; i < PCIE_PORT_DEVICE_MAXSERVICES; i++) {
@@ -51,7 +51,9 @@ static int assign_interrupt_mode(struct pci_dev *dev, int *vectors, int mask)
51 nvec++; 51 nvec++;
52 vectors[i] = dev->irq; 52 vectors[i] = dev->irq;
53 } 53 }
54 54 if (dev->pin)
55 interrupt_mode = PCIE_PORT_INTx_MODE;
56
55 /* Check MSI quirk */ 57 /* Check MSI quirk */
56 if (port_data->port_type == PCIE_RC_PORT && pcie_mch_quirk) 58 if (port_data->port_type == PCIE_RC_PORT && pcie_mch_quirk)
57 return interrupt_mode; 59 return interrupt_mode;
@@ -141,7 +143,7 @@ static void pcie_device_init(struct pci_dev *parent, struct pcie_device *dev,
141 dev->id.vendor = parent->vendor; 143 dev->id.vendor = parent->vendor;
142 dev->id.device = parent->device; 144 dev->id.device = parent->device;
143 dev->id.port_type = port_type; 145 dev->id.port_type = port_type;
144 dev->id.service_type = (1 << service_type); 146 dev->id.service_type = service_type;
145 147
146 /* Initialize generic device interface */ 148 /* Initialize generic device interface */
147 device = &dev->device; 149 device = &dev->device;
@@ -232,19 +234,32 @@ int pcie_port_device_register(struct pci_dev *dev)
232 /* Allocate child services if any */ 234 /* Allocate child services if any */
233 for (i = 0; i < PCIE_PORT_DEVICE_MAXSERVICES; i++) { 235 for (i = 0; i < PCIE_PORT_DEVICE_MAXSERVICES; i++) {
234 struct pcie_device *child; 236 struct pcie_device *child;
237 int service = 1 << i;
235 238
236 if (capabilities & (1 << i)) { 239 if (!(capabilities & service))
237 child = alloc_pcie_device(dev, i, vectors[i]); 240 continue;
238 if (child) { 241
239 status = device_register(&child->device); 242 /*
240 if (status) { 243 * Don't use service devices that require interrupts if there is
241 kfree(child); 244 * no way to generate them.
242 continue; 245 */
243 } 246 if (irq_mode == PCIE_PORT_NO_IRQ
244 get_device(&child->device); 247 && service != PCIE_PORT_SERVICE_VC)
245 } 248 continue;
249
250 child = alloc_pcie_device(dev, service, vectors[i]);
251 if (!child)
252 continue;
253
254 status = device_register(&child->device);
255 if (status) {
256 kfree(child);
257 continue;
246 } 258 }
259
260 get_device(&child->device);
247 } 261 }
262
248 return 0; 263 return 0;
249} 264}
250 265