diff options
-rw-r--r-- | arch/powerpc/include/asm/opal.h | 2 | ||||
-rw-r--r-- | arch/powerpc/include/asm/xics.h | 1 | ||||
-rw-r--r-- | arch/powerpc/platforms/powernv/opal-wrappers.S | 1 | ||||
-rw-r--r-- | arch/powerpc/platforms/powernv/pci-ioda.c | 38 | ||||
-rw-r--r-- | arch/powerpc/platforms/powernv/pci-p5ioc2.c | 4 | ||||
-rw-r--r-- | arch/powerpc/platforms/powernv/pci.c | 2 | ||||
-rw-r--r-- | arch/powerpc/platforms/powernv/pci.h | 8 | ||||
-rw-r--r-- | arch/powerpc/sysdev/xics/icp-native.c | 2 |
8 files changed, 50 insertions, 8 deletions
diff --git a/arch/powerpc/include/asm/opal.h b/arch/powerpc/include/asm/opal.h index a4b28f165b6c..b6c8b58b1d76 100644 --- a/arch/powerpc/include/asm/opal.h +++ b/arch/powerpc/include/asm/opal.h | |||
@@ -117,6 +117,7 @@ extern int opal_enter_rtas(struct rtas_args *args, | |||
117 | #define OPAL_SET_SLOT_LED_STATUS 55 | 117 | #define OPAL_SET_SLOT_LED_STATUS 55 |
118 | #define OPAL_GET_EPOW_STATUS 56 | 118 | #define OPAL_GET_EPOW_STATUS 56 |
119 | #define OPAL_SET_SYSTEM_ATTENTION_LED 57 | 119 | #define OPAL_SET_SYSTEM_ATTENTION_LED 57 |
120 | #define OPAL_PCI_MSI_EOI 63 | ||
120 | 121 | ||
121 | #ifndef __ASSEMBLY__ | 122 | #ifndef __ASSEMBLY__ |
122 | 123 | ||
@@ -506,6 +507,7 @@ int64_t opal_pci_get_xive_reissue(uint64_t phb_id, uint32_t xive_number, | |||
506 | uint8_t *p_bit, uint8_t *q_bit); | 507 | uint8_t *p_bit, uint8_t *q_bit); |
507 | int64_t opal_pci_set_xive_reissue(uint64_t phb_id, uint32_t xive_number, | 508 | int64_t opal_pci_set_xive_reissue(uint64_t phb_id, uint32_t xive_number, |
508 | uint8_t p_bit, uint8_t q_bit); | 509 | uint8_t p_bit, uint8_t q_bit); |
510 | int64_t opal_pci_msi_eoi(uint64_t phb_id, uint32_t hw_irq); | ||
509 | int64_t opal_pci_set_xive_pe(uint64_t phb_id, uint32_t pe_number, | 511 | int64_t opal_pci_set_xive_pe(uint64_t phb_id, uint32_t pe_number, |
510 | uint32_t xive_num); | 512 | uint32_t xive_num); |
511 | int64_t opal_get_xive_source(uint64_t phb_id, uint32_t xive_num, | 513 | int64_t opal_get_xive_source(uint64_t phb_id, uint32_t xive_num, |
diff --git a/arch/powerpc/include/asm/xics.h b/arch/powerpc/include/asm/xics.h index 4ae9a09c3b89..282d43a0c855 100644 --- a/arch/powerpc/include/asm/xics.h +++ b/arch/powerpc/include/asm/xics.h | |||
@@ -150,6 +150,7 @@ extern void xics_register_ics(struct ics *ics); | |||
150 | extern void xics_teardown_cpu(void); | 150 | extern void xics_teardown_cpu(void); |
151 | extern void xics_kexec_teardown_cpu(int secondary); | 151 | extern void xics_kexec_teardown_cpu(int secondary); |
152 | extern void xics_migrate_irqs_away(void); | 152 | extern void xics_migrate_irqs_away(void); |
153 | extern void icp_native_eoi(struct irq_data *d); | ||
153 | #ifdef CONFIG_SMP | 154 | #ifdef CONFIG_SMP |
154 | extern int xics_get_irq_server(unsigned int virq, const struct cpumask *cpumask, | 155 | extern int xics_get_irq_server(unsigned int virq, const struct cpumask *cpumask, |
155 | unsigned int strict_check); | 156 | unsigned int strict_check); |
diff --git a/arch/powerpc/platforms/powernv/opal-wrappers.S b/arch/powerpc/platforms/powernv/opal-wrappers.S index 3bb07e5e43cd..6fabe92eafb6 100644 --- a/arch/powerpc/platforms/powernv/opal-wrappers.S +++ b/arch/powerpc/platforms/powernv/opal-wrappers.S | |||
@@ -107,3 +107,4 @@ OPAL_CALL(opal_pci_mask_pe_error, OPAL_PCI_MASK_PE_ERROR); | |||
107 | OPAL_CALL(opal_set_slot_led_status, OPAL_SET_SLOT_LED_STATUS); | 107 | OPAL_CALL(opal_set_slot_led_status, OPAL_SET_SLOT_LED_STATUS); |
108 | OPAL_CALL(opal_get_epow_status, OPAL_GET_EPOW_STATUS); | 108 | OPAL_CALL(opal_get_epow_status, OPAL_GET_EPOW_STATUS); |
109 | OPAL_CALL(opal_set_system_attention_led, OPAL_SET_SYSTEM_ATTENTION_LED); | 109 | OPAL_CALL(opal_set_system_attention_led, OPAL_SET_SYSTEM_ATTENTION_LED); |
110 | OPAL_CALL(opal_pci_msi_eoi, OPAL_PCI_MSI_EOI); | ||
diff --git a/arch/powerpc/platforms/powernv/pci-ioda.c b/arch/powerpc/platforms/powernv/pci-ioda.c index 3d4e9588a695..3f88c51cb95b 100644 --- a/arch/powerpc/platforms/powernv/pci-ioda.c +++ b/arch/powerpc/platforms/powernv/pci-ioda.c | |||
@@ -31,6 +31,7 @@ | |||
31 | #include <asm/opal.h> | 31 | #include <asm/opal.h> |
32 | #include <asm/iommu.h> | 32 | #include <asm/iommu.h> |
33 | #include <asm/tce.h> | 33 | #include <asm/tce.h> |
34 | #include <asm/xics.h> | ||
34 | 35 | ||
35 | #include "powernv.h" | 36 | #include "powernv.h" |
36 | #include "pci.h" | 37 | #include "pci.h" |
@@ -589,11 +590,27 @@ static void pnv_ioda_setup_dma(struct pnv_phb *phb) | |||
589 | } | 590 | } |
590 | 591 | ||
591 | #ifdef CONFIG_PCI_MSI | 592 | #ifdef CONFIG_PCI_MSI |
593 | static void pnv_ioda2_msi_eoi(struct irq_data *d) | ||
594 | { | ||
595 | unsigned int hw_irq = (unsigned int)irqd_to_hwirq(d); | ||
596 | struct irq_chip *chip = irq_data_get_irq_chip(d); | ||
597 | struct pnv_phb *phb = container_of(chip, struct pnv_phb, | ||
598 | ioda.irq_chip); | ||
599 | int64_t rc; | ||
600 | |||
601 | rc = opal_pci_msi_eoi(phb->opal_id, hw_irq); | ||
602 | WARN_ON_ONCE(rc); | ||
603 | |||
604 | icp_native_eoi(d); | ||
605 | } | ||
606 | |||
592 | static int pnv_pci_ioda_msi_setup(struct pnv_phb *phb, struct pci_dev *dev, | 607 | static int pnv_pci_ioda_msi_setup(struct pnv_phb *phb, struct pci_dev *dev, |
593 | unsigned int hwirq, unsigned int is_64, | 608 | unsigned int hwirq, unsigned int virq, |
594 | struct msi_msg *msg) | 609 | unsigned int is_64, struct msi_msg *msg) |
595 | { | 610 | { |
596 | struct pnv_ioda_pe *pe = pnv_ioda_get_pe(dev); | 611 | struct pnv_ioda_pe *pe = pnv_ioda_get_pe(dev); |
612 | struct irq_data *idata; | ||
613 | struct irq_chip *ichip; | ||
597 | unsigned int xive_num = hwirq - phb->msi_base; | 614 | unsigned int xive_num = hwirq - phb->msi_base; |
598 | uint64_t addr64; | 615 | uint64_t addr64; |
599 | uint32_t addr32, data; | 616 | uint32_t addr32, data; |
@@ -638,6 +655,23 @@ static int pnv_pci_ioda_msi_setup(struct pnv_phb *phb, struct pci_dev *dev, | |||
638 | } | 655 | } |
639 | msg->data = data; | 656 | msg->data = data; |
640 | 657 | ||
658 | /* | ||
659 | * Change the IRQ chip for the MSI interrupts on PHB3. | ||
660 | * The corresponding IRQ chip should be populated for | ||
661 | * the first time. | ||
662 | */ | ||
663 | if (phb->type == PNV_PHB_IODA2) { | ||
664 | if (!phb->ioda.irq_chip_init) { | ||
665 | idata = irq_get_irq_data(virq); | ||
666 | ichip = irq_data_get_irq_chip(idata); | ||
667 | phb->ioda.irq_chip_init = 1; | ||
668 | phb->ioda.irq_chip = *ichip; | ||
669 | phb->ioda.irq_chip.irq_eoi = pnv_ioda2_msi_eoi; | ||
670 | } | ||
671 | |||
672 | irq_set_chip(virq, &phb->ioda.irq_chip); | ||
673 | } | ||
674 | |||
641 | pr_devel("%s: %s-bit MSI on hwirq %x (xive #%d)," | 675 | pr_devel("%s: %s-bit MSI on hwirq %x (xive #%d)," |
642 | " address=%x_%08x data=%x PE# %d\n", | 676 | " address=%x_%08x data=%x PE# %d\n", |
643 | pci_name(dev), is_64 ? "64" : "32", hwirq, xive_num, | 677 | pci_name(dev), is_64 ? "64" : "32", hwirq, xive_num, |
diff --git a/arch/powerpc/platforms/powernv/pci-p5ioc2.c b/arch/powerpc/platforms/powernv/pci-p5ioc2.c index d5c066ea7d1f..92b37a0186c9 100644 --- a/arch/powerpc/platforms/powernv/pci-p5ioc2.c +++ b/arch/powerpc/platforms/powernv/pci-p5ioc2.c | |||
@@ -42,8 +42,8 @@ | |||
42 | 42 | ||
43 | #ifdef CONFIG_PCI_MSI | 43 | #ifdef CONFIG_PCI_MSI |
44 | static int pnv_pci_p5ioc2_msi_setup(struct pnv_phb *phb, struct pci_dev *dev, | 44 | static int pnv_pci_p5ioc2_msi_setup(struct pnv_phb *phb, struct pci_dev *dev, |
45 | unsigned int hwirq, unsigned int is_64, | 45 | unsigned int hwirq, unsigned int virq, |
46 | struct msi_msg *msg) | 46 | unsigned int is_64, struct msi_msg *msg) |
47 | { | 47 | { |
48 | if (WARN_ON(!is_64)) | 48 | if (WARN_ON(!is_64)) |
49 | return -ENXIO; | 49 | return -ENXIO; |
diff --git a/arch/powerpc/platforms/powernv/pci.c b/arch/powerpc/platforms/powernv/pci.c index a11b5a60c91e..861e185483fe 100644 --- a/arch/powerpc/platforms/powernv/pci.c +++ b/arch/powerpc/platforms/powernv/pci.c | |||
@@ -84,7 +84,7 @@ static int pnv_setup_msi_irqs(struct pci_dev *pdev, int nvec, int type) | |||
84 | return -ENOMEM; | 84 | return -ENOMEM; |
85 | } | 85 | } |
86 | rc = phb->msi_setup(phb, pdev, phb->msi_base + hwirq, | 86 | rc = phb->msi_setup(phb, pdev, phb->msi_base + hwirq, |
87 | entry->msi_attrib.is_64, &msg); | 87 | virq, entry->msi_attrib.is_64, &msg); |
88 | if (rc) { | 88 | if (rc) { |
89 | pr_warn("%s: Failed to setup MSI\n", pci_name(pdev)); | 89 | pr_warn("%s: Failed to setup MSI\n", pci_name(pdev)); |
90 | irq_dispose_mapping(virq); | 90 | irq_dispose_mapping(virq); |
diff --git a/arch/powerpc/platforms/powernv/pci.h b/arch/powerpc/platforms/powernv/pci.h index f6314d65c4d9..3c552b3dd0c6 100644 --- a/arch/powerpc/platforms/powernv/pci.h +++ b/arch/powerpc/platforms/powernv/pci.h | |||
@@ -79,8 +79,8 @@ struct pnv_phb { | |||
79 | struct msi_bitmap msi_bmp; | 79 | struct msi_bitmap msi_bmp; |
80 | #endif | 80 | #endif |
81 | int (*msi_setup)(struct pnv_phb *phb, struct pci_dev *dev, | 81 | int (*msi_setup)(struct pnv_phb *phb, struct pci_dev *dev, |
82 | unsigned int hwirq, unsigned int is_64, | 82 | unsigned int hwirq, unsigned int virq, |
83 | struct msi_msg *msg); | 83 | unsigned int is_64, struct msi_msg *msg); |
84 | void (*dma_dev_setup)(struct pnv_phb *phb, struct pci_dev *pdev); | 84 | void (*dma_dev_setup)(struct pnv_phb *phb, struct pci_dev *pdev); |
85 | void (*fixup_phb)(struct pci_controller *hose); | 85 | void (*fixup_phb)(struct pci_controller *hose); |
86 | u32 (*bdfn_to_pe)(struct pnv_phb *phb, struct pci_bus *bus, u32 devfn); | 86 | u32 (*bdfn_to_pe)(struct pnv_phb *phb, struct pci_bus *bus, u32 devfn); |
@@ -108,6 +108,10 @@ struct pnv_phb { | |||
108 | unsigned int *io_segmap; | 108 | unsigned int *io_segmap; |
109 | struct pnv_ioda_pe *pe_array; | 109 | struct pnv_ioda_pe *pe_array; |
110 | 110 | ||
111 | /* IRQ chip */ | ||
112 | int irq_chip_init; | ||
113 | struct irq_chip irq_chip; | ||
114 | |||
111 | /* Sorted list of used PE's based | 115 | /* Sorted list of used PE's based |
112 | * on the sequence of creation | 116 | * on the sequence of creation |
113 | */ | 117 | */ |
diff --git a/arch/powerpc/sysdev/xics/icp-native.c b/arch/powerpc/sysdev/xics/icp-native.c index 48861d3fcd07..89db29d17c25 100644 --- a/arch/powerpc/sysdev/xics/icp-native.c +++ b/arch/powerpc/sysdev/xics/icp-native.c | |||
@@ -81,7 +81,7 @@ static void icp_native_set_cpu_priority(unsigned char cppr) | |||
81 | iosync(); | 81 | iosync(); |
82 | } | 82 | } |
83 | 83 | ||
84 | static void icp_native_eoi(struct irq_data *d) | 84 | void icp_native_eoi(struct irq_data *d) |
85 | { | 85 | { |
86 | unsigned int hw_irq = (unsigned int)irqd_to_hwirq(d); | 86 | unsigned int hw_irq = (unsigned int)irqd_to_hwirq(d); |
87 | 87 | ||