aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSebastian Ott <sebott@linux.ibm.com>2018-09-27 07:57:12 -0400
committerMartin Schwidefsky <schwidefsky@de.ibm.com>2019-04-29 04:47:01 -0400
commite979ce7bced2ee019b5b1a040295484bd7f23680 (patch)
treec2c7b88423ea2011ab2bab5fa05f5c393d5b9493
parent414cbd1e3d14ec0e60666a0fb9d8ae2d77eb7c63 (diff)
s390/pci: provide support for CPU directed interrupts
Up until now all interrupts on s390 have been floating. For MSI interrupts we've used a global summary bit vector (with a bit for each function) and a per-function interrupt bit vector (with a bit per MSI). This patch introduces a new IRQ delivery mode: CPU directed interrupts. In this new mode a per-CPU interrupt bit vector is used (with a bit per MSI per function). Further it is now possible to direct an IRQ to a specific CPU so we can finally support IRQ affinity. If an interrupt can't be delivered because the appointed CPU is occupied by a hypervisor the interrupt is delivered floating. For this a global summary bit vector is used (with a bit per CPU). Signed-off-by: Sebastian Ott <sebott@linux.ibm.com> Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
-rw-r--r--arch/s390/include/asm/pci.h2
-rw-r--r--arch/s390/include/asm/pci_clp.h6
-rw-r--r--arch/s390/include/asm/pci_insn.h74
-rw-r--r--arch/s390/pci/pci_insn.c10
-rw-r--r--arch/s390/pci/pci_irq.c339
5 files changed, 368 insertions, 63 deletions
diff --git a/arch/s390/include/asm/pci.h b/arch/s390/include/asm/pci.h
index 71517451750b..a285754d0742 100644
--- a/arch/s390/include/asm/pci.h
+++ b/arch/s390/include/asm/pci.h
@@ -115,6 +115,8 @@ struct zpci_dev {
115 /* IRQ stuff */ 115 /* IRQ stuff */
116 u64 msi_addr; /* MSI address */ 116 u64 msi_addr; /* MSI address */
117 unsigned int max_msi; /* maximum number of MSI's */ 117 unsigned int max_msi; /* maximum number of MSI's */
118 unsigned int msi_first_bit;
119 unsigned int msi_nr_irqs;
118 struct airq_iv *aibv; /* adapter interrupt bit vector */ 120 struct airq_iv *aibv; /* adapter interrupt bit vector */
119 unsigned long aisb; /* number of the summary bit */ 121 unsigned long aisb; /* number of the summary bit */
120 122
diff --git a/arch/s390/include/asm/pci_clp.h b/arch/s390/include/asm/pci_clp.h
index b3b31b31f0d3..d2d824a91e66 100644
--- a/arch/s390/include/asm/pci_clp.h
+++ b/arch/s390/include/asm/pci_clp.h
@@ -118,7 +118,11 @@ struct clp_rsp_query_pci_grp {
118 u8 refresh : 1; /* TLB refresh mode */ 118 u8 refresh : 1; /* TLB refresh mode */
119 u16 reserved2; 119 u16 reserved2;
120 u16 mui; 120 u16 mui;
121 u64 reserved3; 121 u16 : 16;
122 u16 maxfaal;
123 u16 : 4;
124 u16 dnoi : 12;
125 u16 maxcpu;
122 u64 dasm; /* dma address space mask */ 126 u64 dasm; /* dma address space mask */
123 u64 msia; /* MSI address */ 127 u64 msia; /* MSI address */
124 u64 reserved4; 128 u64 reserved4;
diff --git a/arch/s390/include/asm/pci_insn.h b/arch/s390/include/asm/pci_insn.h
index ba22a6ea51a1..ab1031070503 100644
--- a/arch/s390/include/asm/pci_insn.h
+++ b/arch/s390/include/asm/pci_insn.h
@@ -38,6 +38,8 @@
38#define ZPCI_MOD_FC_RESET_ERROR 7 38#define ZPCI_MOD_FC_RESET_ERROR 7
39#define ZPCI_MOD_FC_RESET_BLOCK 9 39#define ZPCI_MOD_FC_RESET_BLOCK 9
40#define ZPCI_MOD_FC_SET_MEASURE 10 40#define ZPCI_MOD_FC_SET_MEASURE 10
41#define ZPCI_MOD_FC_REG_INT_D 16
42#define ZPCI_MOD_FC_DEREG_INT_D 17
41 43
42/* FIB function controls */ 44/* FIB function controls */
43#define ZPCI_FIB_FC_ENABLED 0x80 45#define ZPCI_FIB_FC_ENABLED 0x80
@@ -51,16 +53,7 @@
51#define ZPCI_FIB_FC_LS_BLOCKED 0x20 53#define ZPCI_FIB_FC_LS_BLOCKED 0x20
52#define ZPCI_FIB_FC_DMAAS_REG 0x10 54#define ZPCI_FIB_FC_DMAAS_REG 0x10
53 55
54/* Function Information Block */ 56struct zpci_fib_fmt0 {
55struct zpci_fib {
56 u32 fmt : 8; /* format */
57 u32 : 24;
58 u32 : 32;
59 u8 fc; /* function controls */
60 u64 : 56;
61 u64 pba; /* PCI base address */
62 u64 pal; /* PCI address limit */
63 u64 iota; /* I/O Translation Anchor */
64 u32 : 1; 57 u32 : 1;
65 u32 isc : 3; /* Interrupt subclass */ 58 u32 isc : 3; /* Interrupt subclass */
66 u32 noi : 12; /* Number of interrupts */ 59 u32 noi : 12; /* Number of interrupts */
@@ -72,16 +65,75 @@ struct zpci_fib {
72 u32 : 32; 65 u32 : 32;
73 u64 aibv; /* Adapter int bit vector address */ 66 u64 aibv; /* Adapter int bit vector address */
74 u64 aisb; /* Adapter int summary bit address */ 67 u64 aisb; /* Adapter int summary bit address */
68};
69
70struct zpci_fib_fmt1 {
71 u32 : 4;
72 u32 noi : 12;
73 u32 : 16;
74 u32 dibvo : 16;
75 u32 : 16;
76 u64 : 64;
77 u64 : 64;
78};
79
80/* Function Information Block */
81struct zpci_fib {
82 u32 fmt : 8; /* format */
83 u32 : 24;
84 u32 : 32;
85 u8 fc; /* function controls */
86 u64 : 56;
87 u64 pba; /* PCI base address */
88 u64 pal; /* PCI address limit */
89 u64 iota; /* I/O Translation Anchor */
90 union {
91 struct zpci_fib_fmt0 fmt0;
92 struct zpci_fib_fmt1 fmt1;
93 };
75 u64 fmb_addr; /* Function measurement block address and key */ 94 u64 fmb_addr; /* Function measurement block address and key */
76 u32 : 32; 95 u32 : 32;
77 u32 gd; 96 u32 gd;
78} __packed __aligned(8); 97} __packed __aligned(8);
79 98
99/* directed interruption information block */
100struct zpci_diib {
101 u32 : 1;
102 u32 isc : 3;
103 u32 : 28;
104 u16 : 16;
105 u16 nr_cpus;
106 u64 disb_addr;
107 u64 : 64;
108 u64 : 64;
109} __packed __aligned(8);
110
111/* cpu directed interruption information block */
112struct zpci_cdiib {
113 u64 : 64;
114 u64 dibv_addr;
115 u64 : 64;
116 u64 : 64;
117 u64 : 64;
118} __packed __aligned(8);
119
120union zpci_sic_iib {
121 struct zpci_diib diib;
122 struct zpci_cdiib cdiib;
123};
124
80u8 zpci_mod_fc(u64 req, struct zpci_fib *fib, u8 *status); 125u8 zpci_mod_fc(u64 req, struct zpci_fib *fib, u8 *status);
81int zpci_refresh_trans(u64 fn, u64 addr, u64 range); 126int zpci_refresh_trans(u64 fn, u64 addr, u64 range);
82int zpci_load(u64 *data, u64 req, u64 offset); 127int zpci_load(u64 *data, u64 req, u64 offset);
83int zpci_store(u64 data, u64 req, u64 offset); 128int zpci_store(u64 data, u64 req, u64 offset);
84int zpci_store_block(const u64 *data, u64 req, u64 offset); 129int zpci_store_block(const u64 *data, u64 req, u64 offset);
85int zpci_set_irq_ctrl(u16 ctl, char *unused, u8 isc); 130int __zpci_set_irq_ctrl(u16 ctl, u8 isc, union zpci_sic_iib *iib);
131
132static inline int zpci_set_irq_ctrl(u16 ctl, u8 isc)
133{
134 union zpci_sic_iib iib = {{0}};
135
136 return __zpci_set_irq_ctrl(ctl, isc, &iib);
137}
86 138
87#endif 139#endif
diff --git a/arch/s390/pci/pci_insn.c b/arch/s390/pci/pci_insn.c
index f069929e8211..4b2ca068d40e 100644
--- a/arch/s390/pci/pci_insn.c
+++ b/arch/s390/pci/pci_insn.c
@@ -96,13 +96,15 @@ int zpci_refresh_trans(u64 fn, u64 addr, u64 range)
96} 96}
97 97
98/* Set Interruption Controls */ 98/* Set Interruption Controls */
99int zpci_set_irq_ctrl(u16 ctl, char *unused, u8 isc) 99int __zpci_set_irq_ctrl(u16 ctl, u8 isc, union zpci_sic_iib *iib)
100{ 100{
101 if (!test_facility(72)) 101 if (!test_facility(72))
102 return -EIO; 102 return -EIO;
103 asm volatile ( 103
104 " .insn rsy,0xeb00000000d1,%[ctl],%[isc],%[u]\n" 104 asm volatile(
105 : : [ctl] "d" (ctl), [isc] "d" (isc << 27), [u] "Q" (*unused)); 105 ".insn rsy,0xeb00000000d1,%[ctl],%[isc],%[iib]\n"
106 : : [ctl] "d" (ctl), [isc] "d" (isc << 27), [iib] "Q" (*iib));
107
106 return 0; 108 return 0;
107} 109}
108 110
diff --git a/arch/s390/pci/pci_irq.c b/arch/s390/pci/pci_irq.c
index 0170db93be82..4bfd902f27f4 100644
--- a/arch/s390/pci/pci_irq.c
+++ b/arch/s390/pci/pci_irq.c
@@ -7,20 +7,31 @@
7#include <linux/kernel_stat.h> 7#include <linux/kernel_stat.h>
8#include <linux/pci.h> 8#include <linux/pci.h>
9#include <linux/msi.h> 9#include <linux/msi.h>
10#include <linux/smp.h>
10 11
11#include <asm/isc.h> 12#include <asm/isc.h>
12#include <asm/airq.h> 13#include <asm/airq.h>
13 14
15static enum {FLOATING, DIRECTED} irq_delivery;
16
14#define SIC_IRQ_MODE_ALL 0 17#define SIC_IRQ_MODE_ALL 0
15#define SIC_IRQ_MODE_SINGLE 1 18#define SIC_IRQ_MODE_SINGLE 1
19#define SIC_IRQ_MODE_DIRECT 4
20#define SIC_IRQ_MODE_D_ALL 16
21#define SIC_IRQ_MODE_D_SINGLE 17
22#define SIC_IRQ_MODE_SET_CPU 18
16 23
17/* 24/*
18 * summary bit vector - one summary bit per function 25 * summary bit vector
26 * FLOATING - summary bit per function
27 * DIRECTED - summary bit per cpu (only used in fallback path)
19 */ 28 */
20static struct airq_iv *zpci_sbv; 29static struct airq_iv *zpci_sbv;
21 30
22/* 31/*
23 * interrupt bit vectors - one vector per function 32 * interrupt bit vectors
33 * FLOATING - interrupt bit vector per function
34 * DIRECTED - interrupt bit vector per cpu
24 */ 35 */
25static struct airq_iv **zpci_ibv; 36static struct airq_iv **zpci_ibv;
26 37
@@ -31,13 +42,13 @@ static int zpci_set_airq(struct zpci_dev *zdev)
31 struct zpci_fib fib = {0}; 42 struct zpci_fib fib = {0};
32 u8 status; 43 u8 status;
33 44
34 fib.isc = PCI_ISC; 45 fib.fmt0.isc = PCI_ISC;
35 fib.sum = 1; /* enable summary notifications */ 46 fib.fmt0.sum = 1; /* enable summary notifications */
36 fib.noi = airq_iv_end(zdev->aibv); 47 fib.fmt0.noi = airq_iv_end(zdev->aibv);
37 fib.aibv = (unsigned long) zdev->aibv->vector; 48 fib.fmt0.aibv = (unsigned long) zdev->aibv->vector;
38 fib.aibvo = 0; /* each zdev has its own interrupt vector */ 49 fib.fmt0.aibvo = 0; /* each zdev has its own interrupt vector */
39 fib.aisb = (unsigned long) zpci_sbv->vector + (zdev->aisb/64)*8; 50 fib.fmt0.aisb = (unsigned long) zpci_sbv->vector + (zdev->aisb/64)*8;
40 fib.aisbo = zdev->aisb & 63; 51 fib.fmt0.aisbo = zdev->aisb & 63;
41 52
42 return zpci_mod_fc(req, &fib, &status) ? -EIO : 0; 53 return zpci_mod_fc(req, &fib, &status) ? -EIO : 0;
43} 54}
@@ -57,13 +68,134 @@ static int zpci_clear_airq(struct zpci_dev *zdev)
57 return cc ? -EIO : 0; 68 return cc ? -EIO : 0;
58} 69}
59 70
71/* Modify PCI: Register CPU directed interruptions */
72static int zpci_set_directed_irq(struct zpci_dev *zdev)
73{
74 u64 req = ZPCI_CREATE_REQ(zdev->fh, 0, ZPCI_MOD_FC_REG_INT_D);
75 struct zpci_fib fib = {0};
76 u8 status;
77
78 fib.fmt = 1;
79 fib.fmt1.noi = zdev->msi_nr_irqs;
80 fib.fmt1.dibvo = zdev->msi_first_bit;
81
82 return zpci_mod_fc(req, &fib, &status) ? -EIO : 0;
83}
84
85/* Modify PCI: Unregister CPU directed interruptions */
86static int zpci_clear_directed_irq(struct zpci_dev *zdev)
87{
88 u64 req = ZPCI_CREATE_REQ(zdev->fh, 0, ZPCI_MOD_FC_DEREG_INT_D);
89 struct zpci_fib fib = {0};
90 u8 cc, status;
91
92 fib.fmt = 1;
93 cc = zpci_mod_fc(req, &fib, &status);
94 if (cc == 3 || (cc == 1 && status == 24))
95 /* Function already gone or IRQs already deregistered. */
96 cc = 0;
97
98 return cc ? -EIO : 0;
99}
100
101static int zpci_set_irq_affinity(struct irq_data *data, const struct cpumask *dest,
102 bool force)
103{
104 struct msi_desc *entry = irq_get_msi_desc(data->irq);
105 struct msi_msg msg = entry->msg;
106
107 msg.address_lo &= 0xff0000ff;
108 msg.address_lo |= (cpumask_first(dest) << 8);
109 pci_write_msi_msg(data->irq, &msg);
110
111 return IRQ_SET_MASK_OK;
112}
113
60static struct irq_chip zpci_irq_chip = { 114static struct irq_chip zpci_irq_chip = {
61 .name = "zPCI", 115 .name = "zPCI",
62 .irq_unmask = pci_msi_unmask_irq, 116 .irq_unmask = pci_msi_unmask_irq,
63 .irq_mask = pci_msi_mask_irq, 117 .irq_mask = pci_msi_mask_irq,
118 .irq_set_affinity = zpci_set_irq_affinity,
64}; 119};
65 120
66static void zpci_irq_handler(struct airq_struct *airq, bool floating) 121static void zpci_handle_cpu_local_irq(bool rescan)
122{
123 struct airq_iv *dibv = zpci_ibv[smp_processor_id()];
124 unsigned long bit;
125 int irqs_on = 0;
126
127 for (bit = 0;;) {
128 /* Scan the directed IRQ bit vector */
129 bit = airq_iv_scan(dibv, bit, airq_iv_end(dibv));
130 if (bit == -1UL) {
131 if (!rescan || irqs_on++)
132 /* End of second scan with interrupts on. */
133 break;
134 /* First scan complete, reenable interrupts. */
135 if (zpci_set_irq_ctrl(SIC_IRQ_MODE_D_SINGLE, PCI_ISC))
136 break;
137 bit = 0;
138 continue;
139 }
140 inc_irq_stat(IRQIO_MSI);
141 generic_handle_irq(airq_iv_get_data(dibv, bit));
142 }
143}
144
145struct cpu_irq_data {
146 call_single_data_t csd;
147 atomic_t scheduled;
148};
149static DEFINE_PER_CPU_SHARED_ALIGNED(struct cpu_irq_data, irq_data);
150
151static void zpci_handle_remote_irq(void *data)
152{
153 atomic_t *scheduled = data;
154
155 do {
156 zpci_handle_cpu_local_irq(false);
157 } while (atomic_dec_return(scheduled));
158}
159
160static void zpci_handle_fallback_irq(void)
161{
162 struct cpu_irq_data *cpu_data;
163 unsigned long cpu;
164 int irqs_on = 0;
165
166 for (cpu = 0;;) {
167 cpu = airq_iv_scan(zpci_sbv, cpu, airq_iv_end(zpci_sbv));
168 if (cpu == -1UL) {
169 if (irqs_on++)
170 /* End of second scan with interrupts on. */
171 break;
172 /* First scan complete, reenable interrupts. */
173 if (zpci_set_irq_ctrl(SIC_IRQ_MODE_SINGLE, PCI_ISC))
174 break;
175 cpu = 0;
176 continue;
177 }
178 cpu_data = &per_cpu(irq_data, cpu);
179 if (atomic_inc_return(&cpu_data->scheduled) > 1)
180 continue;
181
182 cpu_data->csd.func = zpci_handle_remote_irq;
183 cpu_data->csd.info = &cpu_data->scheduled;
184 cpu_data->csd.flags = 0;
185 smp_call_function_single_async(cpu, &cpu_data->csd);
186 }
187}
188
189static void zpci_directed_irq_handler(struct airq_struct *airq, bool floating)
190{
191 inc_irq_stat(IRQIO_PCI);
192 if (floating)
193 zpci_handle_fallback_irq();
194 else
195 zpci_handle_cpu_local_irq(true);
196}
197
198static void zpci_floating_irq_handler(struct airq_struct *airq, bool floating)
67{ 199{
68 unsigned long si, ai; 200 unsigned long si, ai;
69 struct airq_iv *aibv; 201 struct airq_iv *aibv;
@@ -78,7 +210,7 @@ static void zpci_irq_handler(struct airq_struct *airq, bool floating)
78 /* End of second scan with interrupts on. */ 210 /* End of second scan with interrupts on. */
79 break; 211 break;
80 /* First scan complete, reenable interrupts. */ 212 /* First scan complete, reenable interrupts. */
81 if (zpci_set_irq_ctrl(SIC_IRQ_MODE_SINGLE, NULL, PCI_ISC)) 213 if (zpci_set_irq_ctrl(SIC_IRQ_MODE_SINGLE, PCI_ISC))
82 break; 214 break;
83 si = 0; 215 si = 0;
84 continue; 216 continue;
@@ -101,54 +233,79 @@ static void zpci_irq_handler(struct airq_struct *airq, bool floating)
101int arch_setup_msi_irqs(struct pci_dev *pdev, int nvec, int type) 233int arch_setup_msi_irqs(struct pci_dev *pdev, int nvec, int type)
102{ 234{
103 struct zpci_dev *zdev = to_zpci(pdev); 235 struct zpci_dev *zdev = to_zpci(pdev);
104 unsigned int hwirq, msi_vecs; 236 unsigned int hwirq, msi_vecs, cpu;
105 unsigned long aisb; 237 unsigned long bit;
106 struct msi_desc *msi; 238 struct msi_desc *msi;
107 struct msi_msg msg; 239 struct msi_msg msg;
108 int rc, irq; 240 int rc, irq;
109 241
110 zdev->aisb = -1UL; 242 zdev->aisb = -1UL;
243 zdev->msi_first_bit = -1U;
111 if (type == PCI_CAP_ID_MSI && nvec > 1) 244 if (type == PCI_CAP_ID_MSI && nvec > 1)
112 return 1; 245 return 1;
113 msi_vecs = min_t(unsigned int, nvec, zdev->max_msi); 246 msi_vecs = min_t(unsigned int, nvec, zdev->max_msi);
114 247
115 /* Allocate adapter summary indicator bit */ 248 if (irq_delivery == DIRECTED) {
116 aisb = airq_iv_alloc_bit(zpci_sbv); 249 /* Allocate cpu vector bits */
117 if (aisb == -1UL) 250 bit = airq_iv_alloc(zpci_ibv[0], msi_vecs);
118 return -EIO; 251 if (bit == -1UL)
119 zdev->aisb = aisb; 252 return -EIO;
120 253 } else {
121 /* Create adapter interrupt vector */ 254 /* Allocate adapter summary indicator bit */
122 zdev->aibv = airq_iv_create(msi_vecs, AIRQ_IV_DATA | AIRQ_IV_BITLOCK); 255 bit = airq_iv_alloc_bit(zpci_sbv);
123 if (!zdev->aibv) 256 if (bit == -1UL)
124 return -ENOMEM; 257 return -EIO;
258 zdev->aisb = bit;
259
260 /* Create adapter interrupt vector */
261 zdev->aibv = airq_iv_create(msi_vecs, AIRQ_IV_DATA | AIRQ_IV_BITLOCK);
262 if (!zdev->aibv)
263 return -ENOMEM;
125 264
126 /* Wire up shortcut pointer */ 265 /* Wire up shortcut pointer */
127 zpci_ibv[aisb] = zdev->aibv; 266 zpci_ibv[bit] = zdev->aibv;
267 /* Each function has its own interrupt vector */
268 bit = 0;
269 }
128 270
129 /* Request MSI interrupts */ 271 /* Request MSI interrupts */
130 hwirq = 0; 272 hwirq = bit;
131 for_each_pci_msi_entry(msi, pdev) { 273 for_each_pci_msi_entry(msi, pdev) {
132 if (hwirq >= msi_vecs) 274 rc = -EIO;
275 if (hwirq - bit >= msi_vecs)
133 break; 276 break;
134 irq = irq_alloc_desc(0); /* Alloc irq on node 0 */ 277 irq = __irq_alloc_descs(-1, 0, 1, 0, THIS_MODULE, msi->affinity);
135 if (irq < 0) 278 if (irq < 0)
136 return -ENOMEM; 279 return -ENOMEM;
137 rc = irq_set_msi_desc(irq, msi); 280 rc = irq_set_msi_desc(irq, msi);
138 if (rc) 281 if (rc)
139 return rc; 282 return rc;
140 irq_set_chip_and_handler(irq, &zpci_irq_chip, 283 irq_set_chip_and_handler(irq, &zpci_irq_chip,
141 handle_simple_irq); 284 handle_percpu_irq);
142 msg.data = hwirq; 285 msg.data = hwirq;
143 msg.address_lo = zdev->msi_addr & 0xffffffff; 286 if (irq_delivery == DIRECTED) {
287 msg.address_lo = zdev->msi_addr & 0xff0000ff;
288 msg.address_lo |= msi->affinity ?
289 (cpumask_first(&msi->affinity->mask) << 8) : 0;
290 for_each_possible_cpu(cpu) {
291 airq_iv_set_data(zpci_ibv[cpu], hwirq, irq);
292 }
293 } else {
294 msg.address_lo = zdev->msi_addr & 0xffffffff;
295 airq_iv_set_data(zdev->aibv, hwirq, irq);
296 }
144 msg.address_hi = zdev->msi_addr >> 32; 297 msg.address_hi = zdev->msi_addr >> 32;
145 pci_write_msi_msg(irq, &msg); 298 pci_write_msi_msg(irq, &msg);
146 airq_iv_set_data(zdev->aibv, hwirq, irq);
147 hwirq++; 299 hwirq++;
148 } 300 }
149 301
150 /* Enable adapter interrupts */ 302 zdev->msi_first_bit = bit;
151 rc = zpci_set_airq(zdev); 303 zdev->msi_nr_irqs = msi_vecs;
304
305 if (irq_delivery == DIRECTED)
306 rc = zpci_set_directed_irq(zdev);
307 else
308 rc = zpci_set_airq(zdev);
152 if (rc) 309 if (rc)
153 return rc; 310 return rc;
154 311
@@ -161,8 +318,11 @@ void arch_teardown_msi_irqs(struct pci_dev *pdev)
161 struct msi_desc *msi; 318 struct msi_desc *msi;
162 int rc; 319 int rc;
163 320
164 /* Disable adapter interrupts */ 321 /* Disable interrupts */
165 rc = zpci_clear_airq(zdev); 322 if (irq_delivery == DIRECTED)
323 rc = zpci_clear_directed_irq(zdev);
324 else
325 rc = zpci_clear_airq(zdev);
166 if (rc) 326 if (rc)
167 return; 327 return;
168 328
@@ -191,37 +351,114 @@ void arch_teardown_msi_irqs(struct pci_dev *pdev)
191 airq_iv_release(zdev->aibv); 351 airq_iv_release(zdev->aibv);
192 zdev->aibv = NULL; 352 zdev->aibv = NULL;
193 } 353 }
354
355 if ((irq_delivery == DIRECTED) && zdev->msi_first_bit != -1U)
356 airq_iv_free(zpci_ibv[0], zdev->msi_first_bit, zdev->msi_nr_irqs);
194} 357}
195 358
196static struct airq_struct zpci_airq = { 359static struct airq_struct zpci_airq = {
197 .handler = zpci_irq_handler, 360 .handler = zpci_floating_irq_handler,
198 .isc = PCI_ISC, 361 .isc = PCI_ISC,
199}; 362};
200 363
201int __init zpci_irq_init(void) 364static void __init cpu_enable_directed_irq(void *unused)
202{ 365{
203 int rc; 366 union zpci_sic_iib iib = {{0}};
204 367
205 rc = register_adapter_interrupt(&zpci_airq); 368 iib.cdiib.dibv_addr = (u64) zpci_ibv[smp_processor_id()]->vector;
206 if (rc) 369
207 goto out; 370 __zpci_set_irq_ctrl(SIC_IRQ_MODE_SET_CPU, 0, &iib);
208 /* Set summary to 1 to be called every time for the ISC. */ 371 zpci_set_irq_ctrl(SIC_IRQ_MODE_D_SINGLE, PCI_ISC);
209 *zpci_airq.lsi_ptr = 1; 372}
373
374static int __init zpci_directed_irq_init(void)
375{
376 union zpci_sic_iib iib = {{0}};
377 unsigned int cpu;
378
379 zpci_sbv = airq_iv_create(num_possible_cpus(), 0);
380 if (!zpci_sbv)
381 return -ENOMEM;
382
383 iib.diib.isc = PCI_ISC;
384 iib.diib.nr_cpus = num_possible_cpus();
385 iib.diib.disb_addr = (u64) zpci_sbv->vector;
386 __zpci_set_irq_ctrl(SIC_IRQ_MODE_DIRECT, 0, &iib);
387
388 zpci_ibv = kcalloc(num_possible_cpus(), sizeof(*zpci_ibv),
389 GFP_KERNEL);
390 if (!zpci_ibv)
391 return -ENOMEM;
392
393 for_each_possible_cpu(cpu) {
394 /*
395 * Per CPU IRQ vectors look the same but bit-allocation
396 * is only done on the first vector.
397 */
398 zpci_ibv[cpu] = airq_iv_create(cache_line_size() * BITS_PER_BYTE,
399 AIRQ_IV_DATA |
400 AIRQ_IV_CACHELINE |
401 (!cpu ? AIRQ_IV_ALLOC : 0));
402 if (!zpci_ibv[cpu])
403 return -ENOMEM;
404 }
405 on_each_cpu(cpu_enable_directed_irq, NULL, 1);
210 406
211 rc = -ENOMEM; 407 zpci_irq_chip.irq_set_affinity = zpci_set_irq_affinity;
408
409 return 0;
410}
411
412static int __init zpci_floating_irq_init(void)
413{
212 zpci_ibv = kcalloc(ZPCI_NR_DEVICES, sizeof(*zpci_ibv), GFP_KERNEL); 414 zpci_ibv = kcalloc(ZPCI_NR_DEVICES, sizeof(*zpci_ibv), GFP_KERNEL);
213 if (!zpci_ibv) 415 if (!zpci_ibv)
214 goto out_airq; 416 return -ENOMEM;
215 417
216 zpci_sbv = airq_iv_create(ZPCI_NR_DEVICES, AIRQ_IV_ALLOC); 418 zpci_sbv = airq_iv_create(ZPCI_NR_DEVICES, AIRQ_IV_ALLOC);
217 if (!zpci_sbv) 419 if (!zpci_sbv)
218 goto out_free; 420 goto out_free;
219 421
220 zpci_set_irq_ctrl(SIC_IRQ_MODE_SINGLE, NULL, PCI_ISC);
221 return 0; 422 return 0;
222 423
223out_free: 424out_free:
224 kfree(zpci_ibv); 425 kfree(zpci_ibv);
426 return -ENOMEM;
427}
428
429int __init zpci_irq_init(void)
430{
431 int rc;
432
433 irq_delivery = sclp.has_dirq ? DIRECTED : FLOATING;
434 if (irq_delivery == DIRECTED)
435 zpci_airq.handler = zpci_directed_irq_handler;
436
437 rc = register_adapter_interrupt(&zpci_airq);
438 if (rc)
439 goto out;
440 /* Set summary to 1 to be called every time for the ISC. */
441 *zpci_airq.lsi_ptr = 1;
442
443 switch (irq_delivery) {
444 case FLOATING:
445 rc = zpci_floating_irq_init();
446 break;
447 case DIRECTED:
448 rc = zpci_directed_irq_init();
449 break;
450 }
451
452 if (rc)
453 goto out_airq;
454
455 /*
456 * Enable floating IRQs (with suppression after one IRQ). When using
457 * directed IRQs this enables the fallback path.
458 */
459 zpci_set_irq_ctrl(SIC_IRQ_MODE_SINGLE, PCI_ISC);
460
461 return 0;
225out_airq: 462out_airq:
226 unregister_adapter_interrupt(&zpci_airq); 463 unregister_adapter_interrupt(&zpci_airq);
227out: 464out:
@@ -230,7 +467,15 @@ out:
230 467
231void __init zpci_irq_exit(void) 468void __init zpci_irq_exit(void)
232{ 469{
233 airq_iv_release(zpci_sbv); 470 unsigned int cpu;
471
472 if (irq_delivery == DIRECTED) {
473 for_each_possible_cpu(cpu) {
474 airq_iv_release(zpci_ibv[cpu]);
475 }
476 }
234 kfree(zpci_ibv); 477 kfree(zpci_ibv);
478 if (zpci_sbv)
479 airq_iv_release(zpci_sbv);
235 unregister_adapter_interrupt(&zpci_airq); 480 unregister_adapter_interrupt(&zpci_airq);
236} 481}