diff options
author | Kenji Kaneshige <kaneshige.kenji@jp.fujitsu.com> | 2009-11-25 07:04:00 -0500 |
---|---|---|
committer | Jesse Barnes <jbarnes@virtuousgeek.org> | 2009-12-04 18:55:51 -0500 |
commit | dc5351784eb36f1fec4efa88e01581be72c0b711 (patch) | |
tree | b91a30f23149bbf7d243c63f68af43bc0e46dc6f /drivers/pci | |
parent | d013598d9a46befebdfd37195829ce411e4878ea (diff) |
PCI: portdrv: cleanup service irqs initialization
This patch cleans up the service irqs initialization as follows:
- Remove 'irq_mode' field in pcie_port_data and related definitions,
which is not needed because we can get the same information from
'is_msix', 'is_msi' and 'pin' fields in struct pci_dev.
- Change the name of 'vectors' argument of assign_interrupt_mode() to
'irqs' because it holds irq numbers actually. People might confuse
it with CPU vector or MSI/MSI-X vector.
- Change function name assign_interrupt_mode() to init_service_irqs()
becasuse we no longer have 'irq_mode' data structure, and new name
is more straightforward (IMO).
Signed-off-by: Kenji Kaneshige <kaneshige.kenji@jp.fujitsu.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Diffstat (limited to 'drivers/pci')
-rw-r--r-- | drivers/pci/pcie/portdrv_core.c | 71 |
1 files changed, 29 insertions, 42 deletions
diff --git a/drivers/pci/pcie/portdrv_core.c b/drivers/pci/pcie/portdrv_core.c index 52c4e6fd6fd4..d208dc2d62fd 100644 --- a/drivers/pci/pcie/portdrv_core.c +++ b/drivers/pci/pcie/portdrv_core.c | |||
@@ -177,37 +177,32 @@ static int pcie_port_enable_msix(struct pci_dev *dev, int *vectors, int mask) | |||
177 | } | 177 | } |
178 | 178 | ||
179 | /** | 179 | /** |
180 | * assign_interrupt_mode - choose interrupt mode for PCI Express port services | 180 | * init_service_irqs - initialize irqs for PCI Express port services |
181 | * (INTx, MSI-X, MSI) and set up vectors | ||
182 | * @dev: PCI Express port to handle | 181 | * @dev: PCI Express port to handle |
183 | * @vectors: Array of interrupt vectors to populate | 182 | * @irqs: Array of irqs to populate |
184 | * @mask: Bitmask of port capabilities returned by get_port_device_capability() | 183 | * @mask: Bitmask of port capabilities returned by get_port_device_capability() |
185 | * | 184 | * |
186 | * Return value: Interrupt mode associated with the port | 185 | * Return value: Interrupt mode associated with the port |
187 | */ | 186 | */ |
188 | static int assign_interrupt_mode(struct pci_dev *dev, int *vectors, int mask) | 187 | static int init_service_irqs(struct pci_dev *dev, int *irqs, int mask) |
189 | { | 188 | { |
190 | int irq, interrupt_mode = PCIE_PORT_NO_IRQ; | 189 | int i, irq; |
191 | int i; | ||
192 | 190 | ||
193 | /* Try to use MSI-X if supported */ | 191 | /* Try to use MSI-X if supported */ |
194 | if (!pcie_port_enable_msix(dev, vectors, mask)) | 192 | if (!pcie_port_enable_msix(dev, irqs, mask)) |
195 | return PCIE_PORT_MSIX_MODE; | 193 | return 0; |
196 | |||
197 | /* We're not going to use MSI-X, so try MSI and fall back to INTx */ | 194 | /* We're not going to use MSI-X, so try MSI and fall back to INTx */ |
198 | if (!pci_enable_msi(dev)) | 195 | irq = -1; |
199 | interrupt_mode = PCIE_PORT_MSI_MODE; | 196 | if (!pci_enable_msi(dev) || dev->pin) |
197 | irq = dev->irq; | ||
200 | 198 | ||
201 | if (interrupt_mode == PCIE_PORT_NO_IRQ && dev->pin) | ||
202 | interrupt_mode = PCIE_PORT_INTx_MODE; | ||
203 | |||
204 | irq = interrupt_mode != PCIE_PORT_NO_IRQ ? dev->irq : -1; | ||
205 | for (i = 0; i < PCIE_PORT_DEVICE_MAXSERVICES; i++) | 199 | for (i = 0; i < PCIE_PORT_DEVICE_MAXSERVICES; i++) |
206 | vectors[i] = irq; | 200 | irqs[i] = irq; |
207 | 201 | irqs[PCIE_PORT_SERVICE_VC_SHIFT] = -1; | |
208 | vectors[PCIE_PORT_SERVICE_VC_SHIFT] = -1; | ||
209 | 202 | ||
210 | return interrupt_mode; | 203 | if (irq < 0) |
204 | return -ENODEV; | ||
205 | return 0; | ||
211 | } | 206 | } |
212 | 207 | ||
213 | /** | 208 | /** |
@@ -294,8 +289,8 @@ static int pcie_device_init(struct pci_dev *pdev, int service, int irq) | |||
294 | int pcie_port_device_register(struct pci_dev *dev) | 289 | int pcie_port_device_register(struct pci_dev *dev) |
295 | { | 290 | { |
296 | struct pcie_port_data *port_data; | 291 | struct pcie_port_data *port_data; |
297 | int status, capabilities, irq_mode, i, nr_serv; | 292 | int status, capabilities, i, nr_serv; |
298 | int vectors[PCIE_PORT_DEVICE_MAXSERVICES]; | 293 | int irqs[PCIE_PORT_DEVICE_MAXSERVICES]; |
299 | 294 | ||
300 | capabilities = get_port_device_capability(dev); | 295 | capabilities = get_port_device_capability(dev); |
301 | if (!capabilities) | 296 | if (!capabilities) |
@@ -304,23 +299,19 @@ int pcie_port_device_register(struct pci_dev *dev) | |||
304 | port_data = kzalloc(sizeof(*port_data), GFP_KERNEL); | 299 | port_data = kzalloc(sizeof(*port_data), GFP_KERNEL); |
305 | if (!port_data) | 300 | if (!port_data) |
306 | return -ENOMEM; | 301 | return -ENOMEM; |
307 | pci_set_drvdata(dev, port_data); | ||
308 | |||
309 | port_data->port_type = dev->pcie_type; | 302 | port_data->port_type = dev->pcie_type; |
303 | pci_set_drvdata(dev, port_data); | ||
310 | 304 | ||
311 | irq_mode = assign_interrupt_mode(dev, vectors, capabilities); | 305 | /* |
312 | if (irq_mode == PCIE_PORT_NO_IRQ) { | 306 | * Initialize service irqs. Don't use service devices that |
313 | /* | 307 | * require interrupts if there is no way to generate them. |
314 | * Don't use service devices that require interrupts if there is | 308 | */ |
315 | * no way to generate them. | 309 | status = init_service_irqs(dev, irqs, capabilities); |
316 | */ | 310 | if (status) { |
317 | if (!(capabilities & PCIE_PORT_SERVICE_VC)) { | 311 | capabilities &= PCIE_PORT_SERVICE_VC; |
318 | status = -ENODEV; | 312 | if (!capabilities) |
319 | goto Error; | 313 | goto Error; |
320 | } | ||
321 | capabilities = PCIE_PORT_SERVICE_VC; | ||
322 | } | 314 | } |
323 | port_data->port_irq_mode = irq_mode; | ||
324 | 315 | ||
325 | status = pci_enable_device(dev); | 316 | status = pci_enable_device(dev); |
326 | if (status) | 317 | if (status) |
@@ -334,7 +325,7 @@ int pcie_port_device_register(struct pci_dev *dev) | |||
334 | if (!(capabilities & service)) | 325 | if (!(capabilities & service)) |
335 | continue; | 326 | continue; |
336 | 327 | ||
337 | status = pcie_device_init(dev, service, vectors[i]); | 328 | status = pcie_device_init(dev, service, irqs[i]); |
338 | if (!status) | 329 | if (!status) |
339 | nr_serv++; | 330 | nr_serv++; |
340 | } | 331 | } |
@@ -418,17 +409,13 @@ void pcie_port_device_remove(struct pci_dev *dev) | |||
418 | struct pcie_port_data *port_data = pci_get_drvdata(dev); | 409 | struct pcie_port_data *port_data = pci_get_drvdata(dev); |
419 | 410 | ||
420 | device_for_each_child(&dev->dev, NULL, remove_iter); | 411 | device_for_each_child(&dev->dev, NULL, remove_iter); |
421 | pci_disable_device(dev); | ||
422 | 412 | ||
423 | switch (port_data->port_irq_mode) { | 413 | if (dev->msix_enabled) |
424 | case PCIE_PORT_MSIX_MODE: | ||
425 | pci_disable_msix(dev); | 414 | pci_disable_msix(dev); |
426 | break; | 415 | else if (dev->msi_enabled) |
427 | case PCIE_PORT_MSI_MODE: | ||
428 | pci_disable_msi(dev); | 416 | pci_disable_msi(dev); |
429 | break; | ||
430 | } | ||
431 | 417 | ||
418 | pci_disable_device(dev); | ||
432 | kfree(port_data); | 419 | kfree(port_data); |
433 | } | 420 | } |
434 | 421 | ||