aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/powerpc/include/asm/opal.h2
-rw-r--r--arch/powerpc/include/asm/xics.h1
-rw-r--r--arch/powerpc/platforms/powernv/opal-wrappers.S1
-rw-r--r--arch/powerpc/platforms/powernv/pci-ioda.c38
-rw-r--r--arch/powerpc/platforms/powernv/pci-p5ioc2.c4
-rw-r--r--arch/powerpc/platforms/powernv/pci.c2
-rw-r--r--arch/powerpc/platforms/powernv/pci.h8
-rw-r--r--arch/powerpc/sysdev/xics/icp-native.c2
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);
507int64_t opal_pci_set_xive_reissue(uint64_t phb_id, uint32_t xive_number, 508int64_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);
510int64_t opal_pci_msi_eoi(uint64_t phb_id, uint32_t hw_irq);
509int64_t opal_pci_set_xive_pe(uint64_t phb_id, uint32_t pe_number, 511int64_t opal_pci_set_xive_pe(uint64_t phb_id, uint32_t pe_number,
510 uint32_t xive_num); 512 uint32_t xive_num);
511int64_t opal_get_xive_source(uint64_t phb_id, uint32_t xive_num, 513int64_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);
150extern void xics_teardown_cpu(void); 150extern void xics_teardown_cpu(void);
151extern void xics_kexec_teardown_cpu(int secondary); 151extern void xics_kexec_teardown_cpu(int secondary);
152extern void xics_migrate_irqs_away(void); 152extern void xics_migrate_irqs_away(void);
153extern void icp_native_eoi(struct irq_data *d);
153#ifdef CONFIG_SMP 154#ifdef CONFIG_SMP
154extern int xics_get_irq_server(unsigned int virq, const struct cpumask *cpumask, 155extern 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);
107OPAL_CALL(opal_set_slot_led_status, OPAL_SET_SLOT_LED_STATUS); 107OPAL_CALL(opal_set_slot_led_status, OPAL_SET_SLOT_LED_STATUS);
108OPAL_CALL(opal_get_epow_status, OPAL_GET_EPOW_STATUS); 108OPAL_CALL(opal_get_epow_status, OPAL_GET_EPOW_STATUS);
109OPAL_CALL(opal_set_system_attention_led, OPAL_SET_SYSTEM_ATTENTION_LED); 109OPAL_CALL(opal_set_system_attention_led, OPAL_SET_SYSTEM_ATTENTION_LED);
110OPAL_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
593static 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
592static int pnv_pci_ioda_msi_setup(struct pnv_phb *phb, struct pci_dev *dev, 607static 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
44static int pnv_pci_p5ioc2_msi_setup(struct pnv_phb *phb, struct pci_dev *dev, 44static 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
84static void icp_native_eoi(struct irq_data *d) 84void 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