aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
Diffstat (limited to 'arch')
-rw-r--r--arch/powerpc/platforms/pseries/msi.c40
1 files changed, 37 insertions, 3 deletions
diff --git a/arch/powerpc/platforms/pseries/msi.c b/arch/powerpc/platforms/pseries/msi.c
index d34f4ffdb796..6d2f0abce6fa 100644
--- a/arch/powerpc/platforms/pseries/msi.c
+++ b/arch/powerpc/platforms/pseries/msi.c
@@ -374,6 +374,23 @@ static int check_msix_entries(struct pci_dev *pdev)
374 return 0; 374 return 0;
375} 375}
376 376
377static void rtas_hack_32bit_msi_gen2(struct pci_dev *pdev)
378{
379 u32 addr_hi, addr_lo;
380
381 /*
382 * We should only get in here for IODA1 configs. This is based on the
383 * fact that we using RTAS for MSIs, we don't have the 32 bit MSI RTAS
384 * support, and we are in a PCIe Gen2 slot.
385 */
386 dev_info(&pdev->dev,
387 "rtas_msi: No 32 bit MSI firmware support, forcing 32 bit MSI\n");
388 pci_read_config_dword(pdev, pdev->msi_cap + PCI_MSI_ADDRESS_HI, &addr_hi);
389 addr_lo = 0xffff0000 | ((addr_hi >> (48 - 32)) << 4);
390 pci_write_config_dword(pdev, pdev->msi_cap + PCI_MSI_ADDRESS_LO, addr_lo);
391 pci_write_config_dword(pdev, pdev->msi_cap + PCI_MSI_ADDRESS_HI, 0);
392}
393
377static int rtas_setup_msi_irqs(struct pci_dev *pdev, int nvec_in, int type) 394static int rtas_setup_msi_irqs(struct pci_dev *pdev, int nvec_in, int type)
378{ 395{
379 struct pci_dn *pdn; 396 struct pci_dn *pdn;
@@ -381,6 +398,7 @@ static int rtas_setup_msi_irqs(struct pci_dev *pdev, int nvec_in, int type)
381 struct msi_desc *entry; 398 struct msi_desc *entry;
382 struct msi_msg msg; 399 struct msi_msg msg;
383 int nvec = nvec_in; 400 int nvec = nvec_in;
401 int use_32bit_msi_hack = 0;
384 402
385 pdn = pci_get_pdn(pdev); 403 pdn = pci_get_pdn(pdev);
386 if (!pdn) 404 if (!pdn)
@@ -408,15 +426,31 @@ static int rtas_setup_msi_irqs(struct pci_dev *pdev, int nvec_in, int type)
408 */ 426 */
409again: 427again:
410 if (type == PCI_CAP_ID_MSI) { 428 if (type == PCI_CAP_ID_MSI) {
411 if (pdn->force_32bit_msi) 429 if (pdn->force_32bit_msi) {
412 rc = rtas_change_msi(pdn, RTAS_CHANGE_32MSI_FN, nvec); 430 rc = rtas_change_msi(pdn, RTAS_CHANGE_32MSI_FN, nvec);
413 else 431 if (rc < 0) {
432 /*
433 * We only want to run the 32 bit MSI hack below if
434 * the max bus speed is Gen2 speed
435 */
436 if (pdev->bus->max_bus_speed != PCIE_SPEED_5_0GT)
437 return rc;
438
439 use_32bit_msi_hack = 1;
440 }
441 } else
442 rc = -1;
443
444 if (rc < 0)
414 rc = rtas_change_msi(pdn, RTAS_CHANGE_MSI_FN, nvec); 445 rc = rtas_change_msi(pdn, RTAS_CHANGE_MSI_FN, nvec);
415 446
416 if (rc < 0 && !pdn->force_32bit_msi) { 447 if (rc < 0) {
417 pr_debug("rtas_msi: trying the old firmware call.\n"); 448 pr_debug("rtas_msi: trying the old firmware call.\n");
418 rc = rtas_change_msi(pdn, RTAS_CHANGE_FN, nvec); 449 rc = rtas_change_msi(pdn, RTAS_CHANGE_FN, nvec);
419 } 450 }
451
452 if (use_32bit_msi_hack && rc > 0)
453 rtas_hack_32bit_msi_gen2(pdev);
420 } else 454 } else
421 rc = rtas_change_msi(pdn, RTAS_CHANGE_MSIX_FN, nvec); 455 rc = rtas_change_msi(pdn, RTAS_CHANGE_MSIX_FN, nvec);
422 456