aboutsummaryrefslogtreecommitdiffstats
path: root/arch/s390
diff options
context:
space:
mode:
authorJan Glauber <jang@linux.vnet.ibm.com>2012-11-29 07:05:05 -0500
committerMartin Schwidefsky <schwidefsky@de.ibm.com>2012-11-30 11:47:21 -0500
commit9a4da8a5b109906a64bed5aaeb83bf4edb1f5888 (patch)
tree2788d7c8fe3e90333555435c7539d9f31d2c520e /arch/s390
parente56e4e87e370a0f121450d52337969aa1be21ff7 (diff)
s390/pci: PCI adapter interrupts for MSI/MSI-X
Support PCI adapter interrupts using the Single-IRQ-mode. Single-IRQ-mode disables an adapter IRQ automatically after delivering it until the SIC instruction enables it again. This is used to reduce the number of IRQs for streaming workloads. Up to 64 MSI handlers can be registered per PCI function. A hash table is used to map interrupt numbers to MSI descriptors. The interrupt vector is scanned using the flogr instruction. Only MSI/MSI-X interrupts are supported, no legacy INTs. Signed-off-by: Jan Glauber <jang@linux.vnet.ibm.com> Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Diffstat (limited to 'arch/s390')
-rw-r--r--arch/s390/include/asm/hw_irq.h22
-rw-r--r--arch/s390/include/asm/irq.h12
-rw-r--r--arch/s390/include/asm/isc.h1
-rw-r--r--arch/s390/include/asm/pci.h27
-rw-r--r--arch/s390/kernel/irq.c2
-rw-r--r--arch/s390/pci/Makefile2
-rw-r--r--arch/s390/pci/pci.c464
-rw-r--r--arch/s390/pci/pci_clp.c3
-rw-r--r--arch/s390/pci/pci_msi.c141
9 files changed, 672 insertions, 2 deletions
diff --git a/arch/s390/include/asm/hw_irq.h b/arch/s390/include/asm/hw_irq.h
new file mode 100644
index 000000000000..7e3d2586c1ff
--- /dev/null
+++ b/arch/s390/include/asm/hw_irq.h
@@ -0,0 +1,22 @@
1#ifndef _HW_IRQ_H
2#define _HW_IRQ_H
3
4#include <linux/msi.h>
5#include <linux/pci.h>
6
7static inline struct msi_desc *irq_get_msi_desc(unsigned int irq)
8{
9 return __irq_get_msi_desc(irq);
10}
11
12/* Must be called with msi map lock held */
13static inline int irq_set_msi_desc(unsigned int irq, struct msi_desc *msi)
14{
15 if (!msi)
16 return -EINVAL;
17
18 msi->irq = irq;
19 return 0;
20}
21
22#endif
diff --git a/arch/s390/include/asm/irq.h b/arch/s390/include/asm/irq.h
index 6703dd986fd4..e6972f85d2b0 100644
--- a/arch/s390/include/asm/irq.h
+++ b/arch/s390/include/asm/irq.h
@@ -33,6 +33,8 @@ enum interruption_class {
33 IOINT_APB, 33 IOINT_APB,
34 IOINT_ADM, 34 IOINT_ADM,
35 IOINT_CSC, 35 IOINT_CSC,
36 IOINT_PCI,
37 IOINT_MSI,
36 NMI_NMI, 38 NMI_NMI,
37 NR_IRQS, 39 NR_IRQS,
38}; 40};
@@ -51,4 +53,14 @@ void service_subclass_irq_unregister(void);
51void measurement_alert_subclass_register(void); 53void measurement_alert_subclass_register(void);
52void measurement_alert_subclass_unregister(void); 54void measurement_alert_subclass_unregister(void);
53 55
56#ifdef CONFIG_LOCKDEP
57# define disable_irq_nosync_lockdep(irq) disable_irq_nosync(irq)
58# define disable_irq_nosync_lockdep_irqsave(irq, flags) \
59 disable_irq_nosync(irq)
60# define disable_irq_lockdep(irq) disable_irq(irq)
61# define enable_irq_lockdep(irq) enable_irq(irq)
62# define enable_irq_lockdep_irqrestore(irq, flags) \
63 enable_irq(irq)
64#endif
65
54#endif /* _ASM_IRQ_H */ 66#endif /* _ASM_IRQ_H */
diff --git a/arch/s390/include/asm/isc.h b/arch/s390/include/asm/isc.h
index 5ae606456b0a..68d7d68300f2 100644
--- a/arch/s390/include/asm/isc.h
+++ b/arch/s390/include/asm/isc.h
@@ -18,6 +18,7 @@
18#define CHSC_SCH_ISC 7 /* CHSC subchannels */ 18#define CHSC_SCH_ISC 7 /* CHSC subchannels */
19/* Adapter interrupts. */ 19/* Adapter interrupts. */
20#define QDIO_AIRQ_ISC IO_SCH_ISC /* I/O subchannel in qdio mode */ 20#define QDIO_AIRQ_ISC IO_SCH_ISC /* I/O subchannel in qdio mode */
21#define PCI_ISC 2 /* PCI I/O subchannels */
21#define AP_ISC 6 /* adjunct processor (crypto) devices */ 22#define AP_ISC 6 /* adjunct processor (crypto) devices */
22 23
23/* Functions for registration of I/O interruption subclasses */ 24/* Functions for registration of I/O interruption subclasses */
diff --git a/arch/s390/include/asm/pci.h b/arch/s390/include/asm/pci.h
index 6f98a54950ea..2a6084fa4b1a 100644
--- a/arch/s390/include/asm/pci.h
+++ b/arch/s390/include/asm/pci.h
@@ -20,6 +20,10 @@ void pci_iounmap(struct pci_dev *, void __iomem *);
20int pci_domain_nr(struct pci_bus *); 20int pci_domain_nr(struct pci_bus *);
21int pci_proc_domain(struct pci_bus *); 21int pci_proc_domain(struct pci_bus *);
22 22
23/* MSI arch hooks */
24#define arch_setup_msi_irqs arch_setup_msi_irqs
25#define arch_teardown_msi_irqs arch_teardown_msi_irqs
26
23#define ZPCI_BUS_NR 0 /* default bus number */ 27#define ZPCI_BUS_NR 0 /* default bus number */
24#define ZPCI_DEVFN 0 /* default device number */ 28#define ZPCI_DEVFN 0 /* default device number */
25 29
@@ -29,6 +33,15 @@ int pci_proc_domain(struct pci_bus *);
29#define ZPCI_FC_BLOCKED 0x20 33#define ZPCI_FC_BLOCKED 0x20
30#define ZPCI_FC_DMA_ENABLED 0x10 34#define ZPCI_FC_DMA_ENABLED 0x10
31 35
36struct msi_map {
37 unsigned long irq;
38 struct msi_desc *msi;
39 struct hlist_node msi_chain;
40};
41
42#define ZPCI_NR_MSI_VECS 64
43#define ZPCI_MSI_MASK (ZPCI_NR_MSI_VECS - 1)
44
32enum zpci_state { 45enum zpci_state {
33 ZPCI_FN_STATE_RESERVED, 46 ZPCI_FN_STATE_RESERVED,
34 ZPCI_FN_STATE_STANDBY, 47 ZPCI_FN_STATE_STANDBY,
@@ -56,6 +69,12 @@ struct zpci_dev {
56 u8 pfgid; /* function group ID */ 69 u8 pfgid; /* function group ID */
57 u16 domain; 70 u16 domain;
58 71
72 /* IRQ stuff */
73 u64 msi_addr; /* MSI address */
74 struct zdev_irq_map *irq_map;
75 struct msi_map *msi_map[ZPCI_NR_MSI_VECS];
76 unsigned int aisb; /* number of the summary bit */
77
59 struct zpci_bar_struct bars[PCI_BAR_COUNT]; 78 struct zpci_bar_struct bars[PCI_BAR_COUNT];
60 79
61 enum pci_bus_speed max_bus_speed; 80 enum pci_bus_speed max_bus_speed;
@@ -83,6 +102,14 @@ int clp_add_pci_device(u32, u32, int);
83int clp_enable_fh(struct zpci_dev *, u8); 102int clp_enable_fh(struct zpci_dev *, u8);
84int clp_disable_fh(struct zpci_dev *); 103int clp_disable_fh(struct zpci_dev *);
85 104
105/* MSI */
106struct msi_desc *__irq_get_msi_desc(unsigned int);
107int zpci_msi_set_mask_bits(struct msi_desc *, u32, u32);
108int zpci_setup_msi_irq(struct zpci_dev *, struct msi_desc *, unsigned int, int);
109void zpci_teardown_msi_irq(struct zpci_dev *, struct msi_desc *);
110int zpci_msihash_init(void);
111void zpci_msihash_exit(void);
112
86/* Helpers */ 113/* Helpers */
87struct zpci_dev *get_zdev(struct pci_dev *); 114struct zpci_dev *get_zdev(struct pci_dev *);
88struct zpci_dev *get_zdev_by_fid(u32); 115struct zpci_dev *get_zdev_by_fid(u32);
diff --git a/arch/s390/kernel/irq.c b/arch/s390/kernel/irq.c
index 6cdc55b26d68..bf24293970ce 100644
--- a/arch/s390/kernel/irq.c
+++ b/arch/s390/kernel/irq.c
@@ -58,6 +58,8 @@ static const struct irq_class intrclass_names[] = {
58 [IOINT_APB] = {.name = "APB", .desc = "[I/O] AP Bus"}, 58 [IOINT_APB] = {.name = "APB", .desc = "[I/O] AP Bus"},
59 [IOINT_ADM] = {.name = "ADM", .desc = "[I/O] EADM Subchannel"}, 59 [IOINT_ADM] = {.name = "ADM", .desc = "[I/O] EADM Subchannel"},
60 [IOINT_CSC] = {.name = "CSC", .desc = "[I/O] CHSC Subchannel"}, 60 [IOINT_CSC] = {.name = "CSC", .desc = "[I/O] CHSC Subchannel"},
61 [IOINT_PCI] = {.name = "PCI", .desc = "[I/O] PCI Interrupt" },
62 [IOINT_MSI] = {.name = "MSI", .desc = "[I/O] MSI Interrupt" },
61 [NMI_NMI] = {.name = "NMI", .desc = "[NMI] Machine Check"}, 63 [NMI_NMI] = {.name = "NMI", .desc = "[NMI] Machine Check"},
62}; 64};
63 65
diff --git a/arch/s390/pci/Makefile b/arch/s390/pci/Makefile
index 1afd68c4c984..628be7bc006c 100644
--- a/arch/s390/pci/Makefile
+++ b/arch/s390/pci/Makefile
@@ -2,4 +2,4 @@
2# Makefile for the s390 PCI subsystem. 2# Makefile for the s390 PCI subsystem.
3# 3#
4 4
5obj-$(CONFIG_PCI) += pci.o pci_clp.o 5obj-$(CONFIG_PCI) += pci.o pci_clp.o pci_msi.o
diff --git a/arch/s390/pci/pci.c b/arch/s390/pci/pci.c
index 70f6c56c8d0f..d11dc8a25f34 100644
--- a/arch/s390/pci/pci.c
+++ b/arch/s390/pci/pci.c
@@ -23,17 +23,25 @@
23#include <linux/err.h> 23#include <linux/err.h>
24#include <linux/export.h> 24#include <linux/export.h>
25#include <linux/delay.h> 25#include <linux/delay.h>
26#include <linux/irq.h>
27#include <linux/kernel_stat.h>
26#include <linux/seq_file.h> 28#include <linux/seq_file.h>
27#include <linux/pci.h> 29#include <linux/pci.h>
28#include <linux/msi.h> 30#include <linux/msi.h>
29 31
32#include <asm/isc.h>
33#include <asm/airq.h>
30#include <asm/facility.h> 34#include <asm/facility.h>
31#include <asm/pci_insn.h> 35#include <asm/pci_insn.h>
32#include <asm/pci_clp.h> 36#include <asm/pci_clp.h>
33 37
34#define DEBUG /* enable pr_debug */ 38#define DEBUG /* enable pr_debug */
35 39
40#define SIC_IRQ_MODE_ALL 0
41#define SIC_IRQ_MODE_SINGLE 1
42
36#define ZPCI_NR_DMA_SPACES 1 43#define ZPCI_NR_DMA_SPACES 1
44#define ZPCI_MSI_VEC_BITS 6
37#define ZPCI_NR_DEVICES CONFIG_PCI_NR_FUNCTIONS 45#define ZPCI_NR_DEVICES CONFIG_PCI_NR_FUNCTIONS
38 46
39/* list of all detected zpci devices */ 47/* list of all detected zpci devices */
@@ -43,12 +51,63 @@ DEFINE_MUTEX(zpci_list_lock);
43static DECLARE_BITMAP(zpci_domain, ZPCI_NR_DEVICES); 51static DECLARE_BITMAP(zpci_domain, ZPCI_NR_DEVICES);
44static DEFINE_SPINLOCK(zpci_domain_lock); 52static DEFINE_SPINLOCK(zpci_domain_lock);
45 53
54struct callback {
55 irq_handler_t handler;
56 void *data;
57};
58
59struct zdev_irq_map {
60 unsigned long aibv; /* AI bit vector */
61 int msi_vecs; /* consecutive MSI-vectors used */
62 int __unused;
63 struct callback cb[ZPCI_NR_MSI_VECS]; /* callback handler array */
64 spinlock_t lock; /* protect callbacks against de-reg */
65};
66
67struct intr_bucket {
68 /* amap of adapters, one bit per dev, corresponds to one irq nr */
69 unsigned long *alloc;
70 /* AI summary bit, global page for all devices */
71 unsigned long *aisb;
72 /* pointer to aibv and callback data in zdev */
73 struct zdev_irq_map *imap[ZPCI_NR_DEVICES];
74 /* protects the whole bucket struct */
75 spinlock_t lock;
76};
77
78static struct intr_bucket *bucket;
79
80/* Adapter local summary indicator */
81static u8 *zpci_irq_si;
82
83static atomic_t irq_retries = ATOMIC_INIT(0);
84
46/* I/O Map */ 85/* I/O Map */
47static DEFINE_SPINLOCK(zpci_iomap_lock); 86static DEFINE_SPINLOCK(zpci_iomap_lock);
48static DECLARE_BITMAP(zpci_iomap, ZPCI_IOMAP_MAX_ENTRIES); 87static DECLARE_BITMAP(zpci_iomap, ZPCI_IOMAP_MAX_ENTRIES);
49struct zpci_iomap_entry *zpci_iomap_start; 88struct zpci_iomap_entry *zpci_iomap_start;
50EXPORT_SYMBOL_GPL(zpci_iomap_start); 89EXPORT_SYMBOL_GPL(zpci_iomap_start);
51 90
91/* highest irq summary bit */
92static int __read_mostly aisb_max;
93
94static struct kmem_cache *zdev_irq_cache;
95
96static inline int irq_to_msi_nr(unsigned int irq)
97{
98 return irq & ZPCI_MSI_MASK;
99}
100
101static inline int irq_to_dev_nr(unsigned int irq)
102{
103 return irq >> ZPCI_MSI_VEC_BITS;
104}
105
106static inline struct zdev_irq_map *get_imap(unsigned int irq)
107{
108 return bucket->imap[irq_to_dev_nr(irq)];
109}
110
52struct zpci_dev *get_zdev(struct pci_dev *pdev) 111struct zpci_dev *get_zdev(struct pci_dev *pdev)
53{ 112{
54 return (struct zpci_dev *) pdev->sysdata; 113 return (struct zpci_dev *) pdev->sysdata;
@@ -120,6 +179,67 @@ static int zpci_store_fib(struct zpci_dev *zdev, u8 *fc)
120 return (cc) ? -EIO : 0; 179 return (cc) ? -EIO : 0;
121} 180}
122 181
182/* Modify PCI: Register adapter interruptions */
183static int zpci_register_airq(struct zpci_dev *zdev, unsigned int aisb,
184 u64 aibv)
185{
186 u64 req = ZPCI_CREATE_REQ(zdev->fh, 0, ZPCI_MOD_FC_REG_INT);
187 struct zpci_fib *fib;
188 int rc;
189
190 fib = (void *) get_zeroed_page(GFP_KERNEL);
191 if (!fib)
192 return -ENOMEM;
193
194 fib->isc = PCI_ISC;
195 fib->noi = zdev->irq_map->msi_vecs;
196 fib->sum = 1; /* enable summary notifications */
197 fib->aibv = aibv;
198 fib->aibvo = 0; /* every function has its own page */
199 fib->aisb = (u64) bucket->aisb + aisb / 8;
200 fib->aisbo = aisb & ZPCI_MSI_MASK;
201
202 rc = mpcifc_instr(req, fib);
203 pr_debug("%s mpcifc returned noi: %d\n", __func__, fib->noi);
204
205 free_page((unsigned long) fib);
206 return rc;
207}
208
209struct mod_pci_args {
210 u64 base;
211 u64 limit;
212 u64 iota;
213};
214
215static int mod_pci(struct zpci_dev *zdev, int fn, u8 dmaas, struct mod_pci_args *args)
216{
217 u64 req = ZPCI_CREATE_REQ(zdev->fh, dmaas, fn);
218 struct zpci_fib *fib;
219 int rc;
220
221 /* The FIB must be available even if it's not used */
222 fib = (void *) get_zeroed_page(GFP_KERNEL);
223 if (!fib)
224 return -ENOMEM;
225
226 fib->pba = args->base;
227 fib->pal = args->limit;
228 fib->iota = args->iota;
229
230 rc = mpcifc_instr(req, fib);
231 free_page((unsigned long) fib);
232 return rc;
233}
234
235/* Modify PCI: Unregister adapter interruptions */
236static int zpci_unregister_airq(struct zpci_dev *zdev)
237{
238 struct mod_pci_args args = { 0, 0, 0 };
239
240 return mod_pci(zdev, ZPCI_MOD_FC_DEREG_INT, 0, &args);
241}
242
123#define ZPCI_PCIAS_CFGSPC 15 243#define ZPCI_PCIAS_CFGSPC 15
124 244
125static int zpci_cfg_load(struct zpci_dev *zdev, int offset, u32 *val, u8 len) 245static int zpci_cfg_load(struct zpci_dev *zdev, int offset, u32 *val, u8 len)
@@ -150,6 +270,55 @@ static int zpci_cfg_store(struct zpci_dev *zdev, int offset, u32 val, u8 len)
150 return rc; 270 return rc;
151} 271}
152 272
273void synchronize_irq(unsigned int irq)
274{
275 /*
276 * Not needed, the handler is protected by a lock and IRQs that occur
277 * after the handler is deleted are just NOPs.
278 */
279}
280EXPORT_SYMBOL_GPL(synchronize_irq);
281
282void enable_irq(unsigned int irq)
283{
284 struct msi_desc *msi = irq_get_msi_desc(irq);
285
286 zpci_msi_set_mask_bits(msi, 1, 0);
287}
288EXPORT_SYMBOL_GPL(enable_irq);
289
290void disable_irq(unsigned int irq)
291{
292 struct msi_desc *msi = irq_get_msi_desc(irq);
293
294 zpci_msi_set_mask_bits(msi, 1, 1);
295}
296EXPORT_SYMBOL_GPL(disable_irq);
297
298void disable_irq_nosync(unsigned int irq)
299{
300 disable_irq(irq);
301}
302EXPORT_SYMBOL_GPL(disable_irq_nosync);
303
304unsigned long probe_irq_on(void)
305{
306 return 0;
307}
308EXPORT_SYMBOL_GPL(probe_irq_on);
309
310int probe_irq_off(unsigned long val)
311{
312 return 0;
313}
314EXPORT_SYMBOL_GPL(probe_irq_off);
315
316unsigned int probe_irq_mask(unsigned long val)
317{
318 return val;
319}
320EXPORT_SYMBOL_GPL(probe_irq_mask);
321
153void __devinit pcibios_fixup_bus(struct pci_bus *bus) 322void __devinit pcibios_fixup_bus(struct pci_bus *bus)
154{ 323{
155} 324}
@@ -219,6 +388,155 @@ static struct pci_ops pci_root_ops = {
219 .write = pci_write, 388 .write = pci_write,
220}; 389};
221 390
391/* store the last handled bit to implement fair scheduling of devices */
392static DEFINE_PER_CPU(unsigned long, next_sbit);
393
394static void zpci_irq_handler(void *dont, void *need)
395{
396 unsigned long sbit, mbit, last = 0, start = __get_cpu_var(next_sbit);
397 int rescan = 0, max = aisb_max;
398 struct zdev_irq_map *imap;
399
400 kstat_cpu(smp_processor_id()).irqs[IOINT_PCI]++;
401 sbit = start;
402
403scan:
404 /* find summary_bit */
405 for_each_set_bit_left_cont(sbit, bucket->aisb, max) {
406 clear_bit(63 - (sbit & 63), bucket->aisb + (sbit >> 6));
407 last = sbit;
408
409 /* find vector bit */
410 imap = bucket->imap[sbit];
411 for_each_set_bit_left(mbit, &imap->aibv, imap->msi_vecs) {
412 kstat_cpu(smp_processor_id()).irqs[IOINT_MSI]++;
413 clear_bit(63 - mbit, &imap->aibv);
414
415 spin_lock(&imap->lock);
416 if (imap->cb[mbit].handler)
417 imap->cb[mbit].handler(mbit,
418 imap->cb[mbit].data);
419 spin_unlock(&imap->lock);
420 }
421 }
422
423 if (rescan)
424 goto out;
425
426 /* scan the skipped bits */
427 if (start > 0) {
428 sbit = 0;
429 max = start;
430 start = 0;
431 goto scan;
432 }
433
434 /* enable interrupts again */
435 sic_instr(SIC_IRQ_MODE_SINGLE, NULL, PCI_ISC);
436
437 /* check again to not lose initiative */
438 rmb();
439 max = aisb_max;
440 sbit = find_first_bit_left(bucket->aisb, max);
441 if (sbit != max) {
442 atomic_inc(&irq_retries);
443 rescan++;
444 goto scan;
445 }
446out:
447 /* store next device bit to scan */
448 __get_cpu_var(next_sbit) = (++last >= aisb_max) ? 0 : last;
449}
450
451/* msi_vecs - number of requested interrupts, 0 place function to error state */
452static int zpci_setup_msi(struct pci_dev *pdev, int msi_vecs)
453{
454 struct zpci_dev *zdev = get_zdev(pdev);
455 unsigned int aisb, msi_nr;
456 struct msi_desc *msi;
457 int rc;
458
459 /* store the number of used MSI vectors */
460 zdev->irq_map->msi_vecs = min(msi_vecs, ZPCI_NR_MSI_VECS);
461
462 spin_lock(&bucket->lock);
463 aisb = find_first_zero_bit(bucket->alloc, PAGE_SIZE);
464 /* alloc map exhausted? */
465 if (aisb == PAGE_SIZE) {
466 spin_unlock(&bucket->lock);
467 return -EIO;
468 }
469 set_bit(aisb, bucket->alloc);
470 spin_unlock(&bucket->lock);
471
472 zdev->aisb = aisb;
473 if (aisb + 1 > aisb_max)
474 aisb_max = aisb + 1;
475
476 /* wire up IRQ shortcut pointer */
477 bucket->imap[zdev->aisb] = zdev->irq_map;
478 pr_debug("%s: imap[%u] linked to %p\n", __func__, zdev->aisb, zdev->irq_map);
479
480 /* TODO: irq number 0 wont be found if we return less than requested MSIs.
481 * ignore it for now and fix in common code.
482 */
483 msi_nr = aisb << ZPCI_MSI_VEC_BITS;
484
485 list_for_each_entry(msi, &pdev->msi_list, list) {
486 rc = zpci_setup_msi_irq(zdev, msi, msi_nr,
487 aisb << ZPCI_MSI_VEC_BITS);
488 if (rc)
489 return rc;
490 msi_nr++;
491 }
492
493 rc = zpci_register_airq(zdev, aisb, (u64) &zdev->irq_map->aibv);
494 if (rc) {
495 clear_bit(aisb, bucket->alloc);
496 dev_err(&pdev->dev, "register MSI failed with: %d\n", rc);
497 return rc;
498 }
499 return (zdev->irq_map->msi_vecs == msi_vecs) ?
500 0 : zdev->irq_map->msi_vecs;
501}
502
503static void zpci_teardown_msi(struct pci_dev *pdev)
504{
505 struct zpci_dev *zdev = get_zdev(pdev);
506 struct msi_desc *msi;
507 int aisb, rc;
508
509 rc = zpci_unregister_airq(zdev);
510 if (rc) {
511 dev_err(&pdev->dev, "deregister MSI failed with: %d\n", rc);
512 return;
513 }
514
515 msi = list_first_entry(&pdev->msi_list, struct msi_desc, list);
516 aisb = irq_to_dev_nr(msi->irq);
517
518 list_for_each_entry(msi, &pdev->msi_list, list)
519 zpci_teardown_msi_irq(zdev, msi);
520
521 clear_bit(aisb, bucket->alloc);
522 if (aisb + 1 == aisb_max)
523 aisb_max--;
524}
525
526int arch_setup_msi_irqs(struct pci_dev *pdev, int nvec, int type)
527{
528 pr_debug("%s: requesting %d MSI-X interrupts...", __func__, nvec);
529 if (type != PCI_CAP_ID_MSIX && type != PCI_CAP_ID_MSI)
530 return -EINVAL;
531 return zpci_setup_msi(pdev, nvec);
532}
533
534void arch_teardown_msi_irqs(struct pci_dev *pdev)
535{
536 pr_info("%s: on pdev: %p\n", __func__, pdev);
537 zpci_teardown_msi(pdev);
538}
539
222static void zpci_map_resources(struct zpci_dev *zdev) 540static void zpci_map_resources(struct zpci_dev *zdev)
223{ 541{
224 struct pci_dev *pdev = zdev->pdev; 542 struct pci_dev *pdev = zdev->pdev;
@@ -257,11 +575,23 @@ struct zpci_dev *zpci_alloc_device(void)
257 zdev = kzalloc(sizeof(*zdev), GFP_KERNEL); 575 zdev = kzalloc(sizeof(*zdev), GFP_KERNEL);
258 if (!zdev) 576 if (!zdev)
259 return ERR_PTR(-ENOMEM); 577 return ERR_PTR(-ENOMEM);
578
579 /* Alloc aibv & callback space */
580 zdev->irq_map = kmem_cache_alloc(zdev_irq_cache, GFP_KERNEL);
581 if (!zdev->irq_map)
582 goto error;
583 memset(zdev->irq_map, 0, sizeof(*zdev->irq_map));
584 WARN_ON((u64) zdev->irq_map & 0xff);
260 return zdev; 585 return zdev;
586
587error:
588 kfree(zdev);
589 return ERR_PTR(-ENOMEM);
261} 590}
262 591
263void zpci_free_device(struct zpci_dev *zdev) 592void zpci_free_device(struct zpci_dev *zdev)
264{ 593{
594 kmem_cache_free(zdev_irq_cache, zdev->irq_map);
265 kfree(zdev); 595 kfree(zdev);
266} 596}
267 597
@@ -320,6 +650,118 @@ void pcibios_disable_device(struct pci_dev *pdev)
320 pdev->sysdata = NULL; 650 pdev->sysdata = NULL;
321} 651}
322 652
653int zpci_request_irq(unsigned int irq, irq_handler_t handler, void *data)
654{
655 int msi_nr = irq_to_msi_nr(irq);
656 struct zdev_irq_map *imap;
657 struct msi_desc *msi;
658
659 msi = irq_get_msi_desc(irq);
660 if (!msi)
661 return -EIO;
662
663 imap = get_imap(irq);
664 spin_lock_init(&imap->lock);
665
666 pr_debug("%s: register handler for IRQ:MSI %d:%d\n", __func__, irq >> 6, msi_nr);
667 imap->cb[msi_nr].handler = handler;
668 imap->cb[msi_nr].data = data;
669
670 /*
671 * The generic MSI code returns with the interrupt disabled on the
672 * card, using the MSI mask bits. Firmware doesn't appear to unmask
673 * at that level, so we do it here by hand.
674 */
675 zpci_msi_set_mask_bits(msi, 1, 0);
676 return 0;
677}
678
679void zpci_free_irq(unsigned int irq)
680{
681 struct zdev_irq_map *imap = get_imap(irq);
682 int msi_nr = irq_to_msi_nr(irq);
683 unsigned long flags;
684
685 pr_debug("%s: for irq: %d\n", __func__, irq);
686
687 spin_lock_irqsave(&imap->lock, flags);
688 imap->cb[msi_nr].handler = NULL;
689 imap->cb[msi_nr].data = NULL;
690 spin_unlock_irqrestore(&imap->lock, flags);
691}
692
693int request_irq(unsigned int irq, irq_handler_t handler,
694 unsigned long irqflags, const char *devname, void *dev_id)
695{
696 pr_debug("%s: irq: %d handler: %p flags: %lx dev: %s\n",
697 __func__, irq, handler, irqflags, devname);
698
699 return zpci_request_irq(irq, handler, dev_id);
700}
701EXPORT_SYMBOL_GPL(request_irq);
702
703void free_irq(unsigned int irq, void *dev_id)
704{
705 zpci_free_irq(irq);
706}
707EXPORT_SYMBOL_GPL(free_irq);
708
709static int __init zpci_irq_init(void)
710{
711 int cpu, rc;
712
713 bucket = kzalloc(sizeof(*bucket), GFP_KERNEL);
714 if (!bucket)
715 return -ENOMEM;
716
717 bucket->aisb = (unsigned long *) get_zeroed_page(GFP_KERNEL);
718 if (!bucket->aisb) {
719 rc = -ENOMEM;
720 goto out_aisb;
721 }
722
723 bucket->alloc = (unsigned long *) get_zeroed_page(GFP_KERNEL);
724 if (!bucket->alloc) {
725 rc = -ENOMEM;
726 goto out_alloc;
727 }
728
729 isc_register(PCI_ISC);
730 zpci_irq_si = s390_register_adapter_interrupt(&zpci_irq_handler, NULL, PCI_ISC);
731 if (IS_ERR(zpci_irq_si)) {
732 rc = PTR_ERR(zpci_irq_si);
733 zpci_irq_si = NULL;
734 goto out_ai;
735 }
736
737 for_each_online_cpu(cpu)
738 per_cpu(next_sbit, cpu) = 0;
739
740 spin_lock_init(&bucket->lock);
741 /* set summary to 1 to be called every time for the ISC */
742 *zpci_irq_si = 1;
743 sic_instr(SIC_IRQ_MODE_SINGLE, NULL, PCI_ISC);
744 return 0;
745
746out_ai:
747 isc_unregister(PCI_ISC);
748 free_page((unsigned long) bucket->alloc);
749out_alloc:
750 free_page((unsigned long) bucket->aisb);
751out_aisb:
752 kfree(bucket);
753 return rc;
754}
755
756static void zpci_irq_exit(void)
757{
758 free_page((unsigned long) bucket->alloc);
759 free_page((unsigned long) bucket->aisb);
760 s390_unregister_adapter_interrupt(zpci_irq_si, PCI_ISC);
761 isc_unregister(PCI_ISC);
762 kfree(bucket);
763}
764
323static struct resource *zpci_alloc_bus_resource(unsigned long start, unsigned long size, 765static struct resource *zpci_alloc_bus_resource(unsigned long start, unsigned long size,
324 unsigned long flags, int domain) 766 unsigned long flags, int domain)
325{ 767{
@@ -523,13 +965,20 @@ static inline int barsize(u8 size)
523 965
524static int zpci_mem_init(void) 966static int zpci_mem_init(void)
525{ 967{
968 zdev_irq_cache = kmem_cache_create("PCI_IRQ_cache", sizeof(struct zdev_irq_map),
969 L1_CACHE_BYTES, SLAB_HWCACHE_ALIGN, NULL);
970 if (!zdev_irq_cache)
971 goto error_zdev;
972
526 /* TODO: use realloc */ 973 /* TODO: use realloc */
527 zpci_iomap_start = kzalloc(ZPCI_IOMAP_MAX_ENTRIES * sizeof(*zpci_iomap_start), 974 zpci_iomap_start = kzalloc(ZPCI_IOMAP_MAX_ENTRIES * sizeof(*zpci_iomap_start),
528 GFP_KERNEL); 975 GFP_KERNEL);
529 if (!zpci_iomap_start) 976 if (!zpci_iomap_start)
530 goto error_zdev; 977 goto error_iomap;
531 return 0; 978 return 0;
532 979
980error_iomap:
981 kmem_cache_destroy(zdev_irq_cache);
533error_zdev: 982error_zdev:
534 return -ENOMEM; 983 return -ENOMEM;
535} 984}
@@ -537,6 +986,7 @@ error_zdev:
537static void zpci_mem_exit(void) 986static void zpci_mem_exit(void)
538{ 987{
539 kfree(zpci_iomap_start); 988 kfree(zpci_iomap_start);
989 kmem_cache_destroy(zdev_irq_cache);
540} 990}
541 991
542unsigned int pci_probe = 1; 992unsigned int pci_probe = 1;
@@ -570,6 +1020,14 @@ static int __init pci_base_init(void)
570 if (rc) 1020 if (rc)
571 goto out_mem; 1021 goto out_mem;
572 1022
1023 rc = zpci_msihash_init();
1024 if (rc)
1025 goto out_hash;
1026
1027 rc = zpci_irq_init();
1028 if (rc)
1029 goto out_irq;
1030
573 rc = clp_find_pci_devices(); 1031 rc = clp_find_pci_devices();
574 if (rc) 1032 if (rc)
575 goto out_find; 1033 goto out_find;
@@ -578,6 +1036,10 @@ static int __init pci_base_init(void)
578 return 0; 1036 return 0;
579 1037
580out_find: 1038out_find:
1039 zpci_irq_exit();
1040out_irq:
1041 zpci_msihash_exit();
1042out_hash:
581 zpci_mem_exit(); 1043 zpci_mem_exit();
582out_mem: 1044out_mem:
583 return rc; 1045 return rc;
diff --git a/arch/s390/pci/pci_clp.c b/arch/s390/pci/pci_clp.c
index 291da1a96560..72694fb6d525 100644
--- a/arch/s390/pci/pci_clp.c
+++ b/arch/s390/pci/pci_clp.c
@@ -48,6 +48,9 @@ static void clp_free_block(void *ptr)
48static void clp_store_query_pci_fngrp(struct zpci_dev *zdev, 48static void clp_store_query_pci_fngrp(struct zpci_dev *zdev,
49 struct clp_rsp_query_pci_grp *response) 49 struct clp_rsp_query_pci_grp *response)
50{ 50{
51 zdev->msi_addr = response->msia;
52
53 pr_debug("Supported number of MSI vectors: %u\n", response->noi);
51 switch (response->version) { 54 switch (response->version) {
52 case 1: 55 case 1:
53 zdev->max_bus_speed = PCIE_SPEED_5_0GT; 56 zdev->max_bus_speed = PCIE_SPEED_5_0GT;
diff --git a/arch/s390/pci/pci_msi.c b/arch/s390/pci/pci_msi.c
new file mode 100644
index 000000000000..90fd3482b9e2
--- /dev/null
+++ b/arch/s390/pci/pci_msi.c
@@ -0,0 +1,141 @@
1/*
2 * Copyright IBM Corp. 2012
3 *
4 * Author(s):
5 * Jan Glauber <jang@linux.vnet.ibm.com>
6 */
7
8#define COMPONENT "zPCI"
9#define pr_fmt(fmt) COMPONENT ": " fmt
10
11#include <linux/kernel.h>
12#include <linux/err.h>
13#include <linux/rculist.h>
14#include <linux/hash.h>
15#include <linux/pci.h>
16#include <linux/msi.h>
17#include <asm/hw_irq.h>
18
19/* mapping of irq numbers to msi_desc */
20static struct hlist_head *msi_hash;
21static unsigned int msihash_shift = 6;
22#define msi_hashfn(nr) hash_long(nr, msihash_shift)
23
24static DEFINE_SPINLOCK(msi_map_lock);
25
26struct msi_desc *__irq_get_msi_desc(unsigned int irq)
27{
28 struct hlist_node *entry;
29 struct msi_map *map;
30
31 hlist_for_each_entry_rcu(map, entry,
32 &msi_hash[msi_hashfn(irq)], msi_chain)
33 if (map->irq == irq)
34 return map->msi;
35 return NULL;
36}
37
38int zpci_msi_set_mask_bits(struct msi_desc *msi, u32 mask, u32 flag)
39{
40 if (msi->msi_attrib.is_msix) {
41 int offset = msi->msi_attrib.entry_nr * PCI_MSIX_ENTRY_SIZE +
42 PCI_MSIX_ENTRY_VECTOR_CTRL;
43 msi->masked = readl(msi->mask_base + offset);
44 writel(flag, msi->mask_base + offset);
45 } else {
46 if (msi->msi_attrib.maskbit) {
47 int pos;
48 u32 mask_bits;
49
50 pos = (long) msi->mask_base;
51 pci_read_config_dword(msi->dev, pos, &mask_bits);
52 mask_bits &= ~(mask);
53 mask_bits |= flag & mask;
54 pci_write_config_dword(msi->dev, pos, mask_bits);
55 } else {
56 return 0;
57 }
58 }
59
60 msi->msi_attrib.maskbit = !!flag;
61 return 1;
62}
63
64int zpci_setup_msi_irq(struct zpci_dev *zdev, struct msi_desc *msi,
65 unsigned int nr, int offset)
66{
67 struct msi_map *map;
68 struct msi_msg msg;
69 int rc;
70
71 map = kmalloc(sizeof(*map), GFP_KERNEL);
72 if (map == NULL)
73 return -ENOMEM;
74
75 map->irq = nr;
76 map->msi = msi;
77 zdev->msi_map[nr & ZPCI_MSI_MASK] = map;
78
79 pr_debug("%s hashing irq: %u to bucket nr: %llu\n",
80 __func__, nr, msi_hashfn(nr));
81 hlist_add_head_rcu(&map->msi_chain, &msi_hash[msi_hashfn(nr)]);
82
83 spin_lock(&msi_map_lock);
84 rc = irq_set_msi_desc(nr, msi);
85 if (rc) {
86 spin_unlock(&msi_map_lock);
87 hlist_del_rcu(&map->msi_chain);
88 kfree(map);
89 zdev->msi_map[nr & ZPCI_MSI_MASK] = NULL;
90 return rc;
91 }
92 spin_unlock(&msi_map_lock);
93
94 msg.data = nr - offset;
95 msg.address_lo = zdev->msi_addr & 0xffffffff;
96 msg.address_hi = zdev->msi_addr >> 32;
97 write_msi_msg(nr, &msg);
98 return 0;
99}
100
101void zpci_teardown_msi_irq(struct zpci_dev *zdev, struct msi_desc *msi)
102{
103 int irq = msi->irq & ZPCI_MSI_MASK;
104 struct msi_map *map;
105
106 msi->msg.address_lo = 0;
107 msi->msg.address_hi = 0;
108 msi->msg.data = 0;
109 msi->irq = 0;
110 zpci_msi_set_mask_bits(msi, 1, 1);
111
112 spin_lock(&msi_map_lock);
113 map = zdev->msi_map[irq];
114 hlist_del_rcu(&map->msi_chain);
115 kfree(map);
116 zdev->msi_map[irq] = NULL;
117 spin_unlock(&msi_map_lock);
118}
119
120/*
121 * The msi hash table has 256 entries which is good for 4..20
122 * devices (a typical device allocates 10 + CPUs MSI's). Maybe make
123 * the hash table size adjustable later.
124 */
125int __init zpci_msihash_init(void)
126{
127 unsigned int i;
128
129 msi_hash = kmalloc(256 * sizeof(*msi_hash), GFP_KERNEL);
130 if (!msi_hash)
131 return -ENOMEM;
132
133 for (i = 0; i < (1U << msihash_shift); i++)
134 INIT_HLIST_HEAD(&msi_hash[i]);
135 return 0;
136}
137
138void __init zpci_msihash_exit(void)
139{
140 kfree(msi_hash);
141}