diff options
author | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2013-05-26 21:40:19 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2013-05-26 21:40:19 -0400 |
commit | f35c69b736e4f910d7447346980145212c283570 (patch) | |
tree | 824b90cd870e6de07bbba19d761c1c74cf1fb4a7 /arch/powerpc/platforms/pseries/msi.c | |
parent | cd4373984a5903276f52777a6003425e023eaa7e (diff) | |
parent | e4aa937ec75df0eea0bee03bffa3303ad36c986b (diff) |
Merge 3.10-rc3 into char-misc-next
We want the changes in here.
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'arch/powerpc/platforms/pseries/msi.c')
-rw-r--r-- | arch/powerpc/platforms/pseries/msi.c | 75 |
1 files changed, 40 insertions, 35 deletions
diff --git a/arch/powerpc/platforms/pseries/msi.c b/arch/powerpc/platforms/pseries/msi.c index 420524e6f8c9..6d2f0abce6fa 100644 --- a/arch/powerpc/platforms/pseries/msi.c +++ b/arch/powerpc/platforms/pseries/msi.c | |||
@@ -26,26 +26,6 @@ static int query_token, change_token; | |||
26 | #define RTAS_CHANGE_MSIX_FN 4 | 26 | #define RTAS_CHANGE_MSIX_FN 4 |
27 | #define RTAS_CHANGE_32MSI_FN 5 | 27 | #define RTAS_CHANGE_32MSI_FN 5 |
28 | 28 | ||
29 | static struct pci_dn *get_pdn(struct pci_dev *pdev) | ||
30 | { | ||
31 | struct device_node *dn; | ||
32 | struct pci_dn *pdn; | ||
33 | |||
34 | dn = pci_device_to_OF_node(pdev); | ||
35 | if (!dn) { | ||
36 | dev_dbg(&pdev->dev, "rtas_msi: No OF device node\n"); | ||
37 | return NULL; | ||
38 | } | ||
39 | |||
40 | pdn = PCI_DN(dn); | ||
41 | if (!pdn) { | ||
42 | dev_dbg(&pdev->dev, "rtas_msi: No PCI DN\n"); | ||
43 | return NULL; | ||
44 | } | ||
45 | |||
46 | return pdn; | ||
47 | } | ||
48 | |||
49 | /* RTAS Helpers */ | 29 | /* RTAS Helpers */ |
50 | 30 | ||
51 | static int rtas_change_msi(struct pci_dn *pdn, u32 func, u32 num_irqs) | 31 | static int rtas_change_msi(struct pci_dn *pdn, u32 func, u32 num_irqs) |
@@ -91,7 +71,7 @@ static void rtas_disable_msi(struct pci_dev *pdev) | |||
91 | { | 71 | { |
92 | struct pci_dn *pdn; | 72 | struct pci_dn *pdn; |
93 | 73 | ||
94 | pdn = get_pdn(pdev); | 74 | pdn = pci_get_pdn(pdev); |
95 | if (!pdn) | 75 | if (!pdn) |
96 | return; | 76 | return; |
97 | 77 | ||
@@ -152,7 +132,7 @@ static int check_req(struct pci_dev *pdev, int nvec, char *prop_name) | |||
152 | struct pci_dn *pdn; | 132 | struct pci_dn *pdn; |
153 | const u32 *req_msi; | 133 | const u32 *req_msi; |
154 | 134 | ||
155 | pdn = get_pdn(pdev); | 135 | pdn = pci_get_pdn(pdev); |
156 | if (!pdn) | 136 | if (!pdn) |
157 | return -ENODEV; | 137 | return -ENODEV; |
158 | 138 | ||
@@ -394,6 +374,23 @@ static int check_msix_entries(struct pci_dev *pdev) | |||
394 | return 0; | 374 | return 0; |
395 | } | 375 | } |
396 | 376 | ||
377 | static 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 | |||
397 | static int rtas_setup_msi_irqs(struct pci_dev *pdev, int nvec_in, int type) | 394 | static int rtas_setup_msi_irqs(struct pci_dev *pdev, int nvec_in, int type) |
398 | { | 395 | { |
399 | struct pci_dn *pdn; | 396 | struct pci_dn *pdn; |
@@ -401,8 +398,9 @@ static int rtas_setup_msi_irqs(struct pci_dev *pdev, int nvec_in, int type) | |||
401 | struct msi_desc *entry; | 398 | struct msi_desc *entry; |
402 | struct msi_msg msg; | 399 | struct msi_msg msg; |
403 | int nvec = nvec_in; | 400 | int nvec = nvec_in; |
401 | int use_32bit_msi_hack = 0; | ||
404 | 402 | ||
405 | pdn = get_pdn(pdev); | 403 | pdn = pci_get_pdn(pdev); |
406 | if (!pdn) | 404 | if (!pdn) |
407 | return -ENODEV; | 405 | return -ENODEV; |
408 | 406 | ||
@@ -428,15 +426,31 @@ static int rtas_setup_msi_irqs(struct pci_dev *pdev, int nvec_in, int type) | |||
428 | */ | 426 | */ |
429 | again: | 427 | again: |
430 | if (type == PCI_CAP_ID_MSI) { | 428 | if (type == PCI_CAP_ID_MSI) { |
431 | if (pdn->force_32bit_msi) | 429 | if (pdn->force_32bit_msi) { |
432 | rc = rtas_change_msi(pdn, RTAS_CHANGE_32MSI_FN, nvec); | 430 | rc = rtas_change_msi(pdn, RTAS_CHANGE_32MSI_FN, nvec); |
433 | 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) | ||
434 | rc = rtas_change_msi(pdn, RTAS_CHANGE_MSI_FN, nvec); | 445 | rc = rtas_change_msi(pdn, RTAS_CHANGE_MSI_FN, nvec); |
435 | 446 | ||
436 | if (rc < 0 && !pdn->force_32bit_msi) { | 447 | if (rc < 0) { |
437 | pr_debug("rtas_msi: trying the old firmware call.\n"); | 448 | pr_debug("rtas_msi: trying the old firmware call.\n"); |
438 | rc = rtas_change_msi(pdn, RTAS_CHANGE_FN, nvec); | 449 | rc = rtas_change_msi(pdn, RTAS_CHANGE_FN, nvec); |
439 | } | 450 | } |
451 | |||
452 | if (use_32bit_msi_hack && rc > 0) | ||
453 | rtas_hack_32bit_msi_gen2(pdev); | ||
440 | } else | 454 | } else |
441 | rc = rtas_change_msi(pdn, RTAS_CHANGE_MSIX_FN, nvec); | 455 | rc = rtas_change_msi(pdn, RTAS_CHANGE_MSIX_FN, nvec); |
442 | 456 | ||
@@ -518,12 +532,3 @@ static int rtas_msi_init(void) | |||
518 | } | 532 | } |
519 | arch_initcall(rtas_msi_init); | 533 | arch_initcall(rtas_msi_init); |
520 | 534 | ||
521 | static void quirk_radeon(struct pci_dev *dev) | ||
522 | { | ||
523 | struct pci_dn *pdn = get_pdn(dev); | ||
524 | |||
525 | if (pdn) | ||
526 | pdn->force_32bit_msi = 1; | ||
527 | } | ||
528 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, 0x68f2, quirk_radeon); | ||
529 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, 0xaa68, quirk_radeon); | ||