diff options
Diffstat (limited to 'arch/s390/pci/pci.c')
-rw-r--r-- | arch/s390/pci/pci.c | 464 |
1 files changed, 463 insertions, 1 deletions
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); | |||
43 | static DECLARE_BITMAP(zpci_domain, ZPCI_NR_DEVICES); | 51 | static DECLARE_BITMAP(zpci_domain, ZPCI_NR_DEVICES); |
44 | static DEFINE_SPINLOCK(zpci_domain_lock); | 52 | static DEFINE_SPINLOCK(zpci_domain_lock); |
45 | 53 | ||
54 | struct callback { | ||
55 | irq_handler_t handler; | ||
56 | void *data; | ||
57 | }; | ||
58 | |||
59 | struct 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 | |||
67 | struct 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 | |||
78 | static struct intr_bucket *bucket; | ||
79 | |||
80 | /* Adapter local summary indicator */ | ||
81 | static u8 *zpci_irq_si; | ||
82 | |||
83 | static atomic_t irq_retries = ATOMIC_INIT(0); | ||
84 | |||
46 | /* I/O Map */ | 85 | /* I/O Map */ |
47 | static DEFINE_SPINLOCK(zpci_iomap_lock); | 86 | static DEFINE_SPINLOCK(zpci_iomap_lock); |
48 | static DECLARE_BITMAP(zpci_iomap, ZPCI_IOMAP_MAX_ENTRIES); | 87 | static DECLARE_BITMAP(zpci_iomap, ZPCI_IOMAP_MAX_ENTRIES); |
49 | struct zpci_iomap_entry *zpci_iomap_start; | 88 | struct zpci_iomap_entry *zpci_iomap_start; |
50 | EXPORT_SYMBOL_GPL(zpci_iomap_start); | 89 | EXPORT_SYMBOL_GPL(zpci_iomap_start); |
51 | 90 | ||
91 | /* highest irq summary bit */ | ||
92 | static int __read_mostly aisb_max; | ||
93 | |||
94 | static struct kmem_cache *zdev_irq_cache; | ||
95 | |||
96 | static inline int irq_to_msi_nr(unsigned int irq) | ||
97 | { | ||
98 | return irq & ZPCI_MSI_MASK; | ||
99 | } | ||
100 | |||
101 | static inline int irq_to_dev_nr(unsigned int irq) | ||
102 | { | ||
103 | return irq >> ZPCI_MSI_VEC_BITS; | ||
104 | } | ||
105 | |||
106 | static inline struct zdev_irq_map *get_imap(unsigned int irq) | ||
107 | { | ||
108 | return bucket->imap[irq_to_dev_nr(irq)]; | ||
109 | } | ||
110 | |||
52 | struct zpci_dev *get_zdev(struct pci_dev *pdev) | 111 | struct 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 */ | ||
183 | static 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 | |||
209 | struct mod_pci_args { | ||
210 | u64 base; | ||
211 | u64 limit; | ||
212 | u64 iota; | ||
213 | }; | ||
214 | |||
215 | static 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 */ | ||
236 | static 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 | ||
125 | static int zpci_cfg_load(struct zpci_dev *zdev, int offset, u32 *val, u8 len) | 245 | static 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 | ||
273 | void 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 | } | ||
280 | EXPORT_SYMBOL_GPL(synchronize_irq); | ||
281 | |||
282 | void 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 | } | ||
288 | EXPORT_SYMBOL_GPL(enable_irq); | ||
289 | |||
290 | void 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 | } | ||
296 | EXPORT_SYMBOL_GPL(disable_irq); | ||
297 | |||
298 | void disable_irq_nosync(unsigned int irq) | ||
299 | { | ||
300 | disable_irq(irq); | ||
301 | } | ||
302 | EXPORT_SYMBOL_GPL(disable_irq_nosync); | ||
303 | |||
304 | unsigned long probe_irq_on(void) | ||
305 | { | ||
306 | return 0; | ||
307 | } | ||
308 | EXPORT_SYMBOL_GPL(probe_irq_on); | ||
309 | |||
310 | int probe_irq_off(unsigned long val) | ||
311 | { | ||
312 | return 0; | ||
313 | } | ||
314 | EXPORT_SYMBOL_GPL(probe_irq_off); | ||
315 | |||
316 | unsigned int probe_irq_mask(unsigned long val) | ||
317 | { | ||
318 | return val; | ||
319 | } | ||
320 | EXPORT_SYMBOL_GPL(probe_irq_mask); | ||
321 | |||
153 | void __devinit pcibios_fixup_bus(struct pci_bus *bus) | 322 | void __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 */ | ||
392 | static DEFINE_PER_CPU(unsigned long, next_sbit); | ||
393 | |||
394 | static 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 | |||
403 | scan: | ||
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 | } | ||
446 | out: | ||
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 */ | ||
452 | static 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 | |||
503 | static 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 | |||
526 | int 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 | |||
534 | void 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 | |||
222 | static void zpci_map_resources(struct zpci_dev *zdev) | 540 | static 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 | |||
587 | error: | ||
588 | kfree(zdev); | ||
589 | return ERR_PTR(-ENOMEM); | ||
261 | } | 590 | } |
262 | 591 | ||
263 | void zpci_free_device(struct zpci_dev *zdev) | 592 | void 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 | ||
653 | int 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 | |||
679 | void 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 | |||
693 | int 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 | } | ||
701 | EXPORT_SYMBOL_GPL(request_irq); | ||
702 | |||
703 | void free_irq(unsigned int irq, void *dev_id) | ||
704 | { | ||
705 | zpci_free_irq(irq); | ||
706 | } | ||
707 | EXPORT_SYMBOL_GPL(free_irq); | ||
708 | |||
709 | static 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 | |||
746 | out_ai: | ||
747 | isc_unregister(PCI_ISC); | ||
748 | free_page((unsigned long) bucket->alloc); | ||
749 | out_alloc: | ||
750 | free_page((unsigned long) bucket->aisb); | ||
751 | out_aisb: | ||
752 | kfree(bucket); | ||
753 | return rc; | ||
754 | } | ||
755 | |||
756 | static 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 | |||
323 | static struct resource *zpci_alloc_bus_resource(unsigned long start, unsigned long size, | 765 | static 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 | ||
524 | static int zpci_mem_init(void) | 966 | static 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 | ||
980 | error_iomap: | ||
981 | kmem_cache_destroy(zdev_irq_cache); | ||
533 | error_zdev: | 982 | error_zdev: |
534 | return -ENOMEM; | 983 | return -ENOMEM; |
535 | } | 984 | } |
@@ -537,6 +986,7 @@ error_zdev: | |||
537 | static void zpci_mem_exit(void) | 986 | static 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 | ||
542 | unsigned int pci_probe = 1; | 992 | unsigned 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 | ||
580 | out_find: | 1038 | out_find: |
1039 | zpci_irq_exit(); | ||
1040 | out_irq: | ||
1041 | zpci_msihash_exit(); | ||
1042 | out_hash: | ||
581 | zpci_mem_exit(); | 1043 | zpci_mem_exit(); |
582 | out_mem: | 1044 | out_mem: |
583 | return rc; | 1045 | return rc; |