diff options
Diffstat (limited to 'arch/s390/pci/pci.c')
-rw-r--r-- | arch/s390/pci/pci.c | 575 |
1 files changed, 219 insertions, 356 deletions
diff --git a/arch/s390/pci/pci.c b/arch/s390/pci/pci.c index e2956ad39a4f..f17a8343e360 100644 --- a/arch/s390/pci/pci.c +++ b/arch/s390/pci/pci.c | |||
@@ -42,45 +42,26 @@ | |||
42 | #define SIC_IRQ_MODE_SINGLE 1 | 42 | #define SIC_IRQ_MODE_SINGLE 1 |
43 | 43 | ||
44 | #define ZPCI_NR_DMA_SPACES 1 | 44 | #define ZPCI_NR_DMA_SPACES 1 |
45 | #define ZPCI_MSI_VEC_BITS 6 | ||
46 | #define ZPCI_NR_DEVICES CONFIG_PCI_NR_FUNCTIONS | 45 | #define ZPCI_NR_DEVICES CONFIG_PCI_NR_FUNCTIONS |
47 | 46 | ||
48 | /* list of all detected zpci devices */ | 47 | /* list of all detected zpci devices */ |
49 | LIST_HEAD(zpci_list); | 48 | static LIST_HEAD(zpci_list); |
50 | EXPORT_SYMBOL_GPL(zpci_list); | 49 | static DEFINE_SPINLOCK(zpci_list_lock); |
51 | DEFINE_MUTEX(zpci_list_lock); | ||
52 | EXPORT_SYMBOL_GPL(zpci_list_lock); | ||
53 | 50 | ||
54 | static struct pci_hp_callback_ops *hotplug_ops; | 51 | static void zpci_enable_irq(struct irq_data *data); |
52 | static void zpci_disable_irq(struct irq_data *data); | ||
55 | 53 | ||
56 | static DECLARE_BITMAP(zpci_domain, ZPCI_NR_DEVICES); | 54 | static struct irq_chip zpci_irq_chip = { |
57 | static DEFINE_SPINLOCK(zpci_domain_lock); | 55 | .name = "zPCI", |
58 | 56 | .irq_unmask = zpci_enable_irq, | |
59 | struct callback { | 57 | .irq_mask = zpci_disable_irq, |
60 | irq_handler_t handler; | ||
61 | void *data; | ||
62 | }; | 58 | }; |
63 | 59 | ||
64 | struct zdev_irq_map { | 60 | static DECLARE_BITMAP(zpci_domain, ZPCI_NR_DEVICES); |
65 | unsigned long aibv; /* AI bit vector */ | 61 | static DEFINE_SPINLOCK(zpci_domain_lock); |
66 | int msi_vecs; /* consecutive MSI-vectors used */ | ||
67 | int __unused; | ||
68 | struct callback cb[ZPCI_NR_MSI_VECS]; /* callback handler array */ | ||
69 | spinlock_t lock; /* protect callbacks against de-reg */ | ||
70 | }; | ||
71 | |||
72 | struct intr_bucket { | ||
73 | /* amap of adapters, one bit per dev, corresponds to one irq nr */ | ||
74 | unsigned long *alloc; | ||
75 | /* AI summary bit, global page for all devices */ | ||
76 | unsigned long *aisb; | ||
77 | /* pointer to aibv and callback data in zdev */ | ||
78 | struct zdev_irq_map *imap[ZPCI_NR_DEVICES]; | ||
79 | /* protects the whole bucket struct */ | ||
80 | spinlock_t lock; | ||
81 | }; | ||
82 | 62 | ||
83 | static struct intr_bucket *bucket; | 63 | static struct airq_iv *zpci_aisb_iv; |
64 | static struct airq_iv *zpci_aibv[ZPCI_NR_DEVICES]; | ||
84 | 65 | ||
85 | /* Adapter interrupt definitions */ | 66 | /* Adapter interrupt definitions */ |
86 | static void zpci_irq_handler(struct airq_struct *airq); | 67 | static void zpci_irq_handler(struct airq_struct *airq); |
@@ -96,27 +77,8 @@ static DECLARE_BITMAP(zpci_iomap, ZPCI_IOMAP_MAX_ENTRIES); | |||
96 | struct zpci_iomap_entry *zpci_iomap_start; | 77 | struct zpci_iomap_entry *zpci_iomap_start; |
97 | EXPORT_SYMBOL_GPL(zpci_iomap_start); | 78 | EXPORT_SYMBOL_GPL(zpci_iomap_start); |
98 | 79 | ||
99 | /* highest irq summary bit */ | ||
100 | static int __read_mostly aisb_max; | ||
101 | |||
102 | static struct kmem_cache *zdev_irq_cache; | ||
103 | static struct kmem_cache *zdev_fmb_cache; | 80 | static struct kmem_cache *zdev_fmb_cache; |
104 | 81 | ||
105 | static inline int irq_to_msi_nr(unsigned int irq) | ||
106 | { | ||
107 | return irq & ZPCI_MSI_MASK; | ||
108 | } | ||
109 | |||
110 | static inline int irq_to_dev_nr(unsigned int irq) | ||
111 | { | ||
112 | return irq >> ZPCI_MSI_VEC_BITS; | ||
113 | } | ||
114 | |||
115 | static inline struct zdev_irq_map *get_imap(unsigned int irq) | ||
116 | { | ||
117 | return bucket->imap[irq_to_dev_nr(irq)]; | ||
118 | } | ||
119 | |||
120 | struct zpci_dev *get_zdev(struct pci_dev *pdev) | 82 | struct zpci_dev *get_zdev(struct pci_dev *pdev) |
121 | { | 83 | { |
122 | return (struct zpci_dev *) pdev->sysdata; | 84 | return (struct zpci_dev *) pdev->sysdata; |
@@ -126,22 +88,17 @@ struct zpci_dev *get_zdev_by_fid(u32 fid) | |||
126 | { | 88 | { |
127 | struct zpci_dev *tmp, *zdev = NULL; | 89 | struct zpci_dev *tmp, *zdev = NULL; |
128 | 90 | ||
129 | mutex_lock(&zpci_list_lock); | 91 | spin_lock(&zpci_list_lock); |
130 | list_for_each_entry(tmp, &zpci_list, entry) { | 92 | list_for_each_entry(tmp, &zpci_list, entry) { |
131 | if (tmp->fid == fid) { | 93 | if (tmp->fid == fid) { |
132 | zdev = tmp; | 94 | zdev = tmp; |
133 | break; | 95 | break; |
134 | } | 96 | } |
135 | } | 97 | } |
136 | mutex_unlock(&zpci_list_lock); | 98 | spin_unlock(&zpci_list_lock); |
137 | return zdev; | 99 | return zdev; |
138 | } | 100 | } |
139 | 101 | ||
140 | bool zpci_fid_present(u32 fid) | ||
141 | { | ||
142 | return (get_zdev_by_fid(fid) != NULL) ? true : false; | ||
143 | } | ||
144 | |||
145 | static struct zpci_dev *get_zdev_by_bus(struct pci_bus *bus) | 102 | static struct zpci_dev *get_zdev_by_bus(struct pci_bus *bus) |
146 | { | 103 | { |
147 | return (bus && bus->sysdata) ? (struct zpci_dev *) bus->sysdata : NULL; | 104 | return (bus && bus->sysdata) ? (struct zpci_dev *) bus->sysdata : NULL; |
@@ -160,8 +117,7 @@ int pci_proc_domain(struct pci_bus *bus) | |||
160 | EXPORT_SYMBOL_GPL(pci_proc_domain); | 117 | EXPORT_SYMBOL_GPL(pci_proc_domain); |
161 | 118 | ||
162 | /* Modify PCI: Register adapter interruptions */ | 119 | /* Modify PCI: Register adapter interruptions */ |
163 | static int zpci_register_airq(struct zpci_dev *zdev, unsigned int aisb, | 120 | static int zpci_set_airq(struct zpci_dev *zdev) |
164 | u64 aibv) | ||
165 | { | 121 | { |
166 | u64 req = ZPCI_CREATE_REQ(zdev->fh, 0, ZPCI_MOD_FC_REG_INT); | 122 | u64 req = ZPCI_CREATE_REQ(zdev->fh, 0, ZPCI_MOD_FC_REG_INT); |
167 | struct zpci_fib *fib; | 123 | struct zpci_fib *fib; |
@@ -172,14 +128,14 @@ static int zpci_register_airq(struct zpci_dev *zdev, unsigned int aisb, | |||
172 | return -ENOMEM; | 128 | return -ENOMEM; |
173 | 129 | ||
174 | fib->isc = PCI_ISC; | 130 | fib->isc = PCI_ISC; |
175 | fib->noi = zdev->irq_map->msi_vecs; | ||
176 | fib->sum = 1; /* enable summary notifications */ | 131 | fib->sum = 1; /* enable summary notifications */ |
177 | fib->aibv = aibv; | 132 | fib->noi = airq_iv_end(zdev->aibv); |
178 | fib->aibvo = 0; /* every function has its own page */ | 133 | fib->aibv = (unsigned long) zdev->aibv->vector; |
179 | fib->aisb = (u64) bucket->aisb + aisb / 8; | 134 | fib->aibvo = 0; /* each zdev has its own interrupt vector */ |
180 | fib->aisbo = aisb & ZPCI_MSI_MASK; | 135 | fib->aisb = (unsigned long) zpci_aisb_iv->vector + (zdev->aisb/64)*8; |
136 | fib->aisbo = zdev->aisb & 63; | ||
181 | 137 | ||
182 | rc = s390pci_mod_fc(req, fib); | 138 | rc = zpci_mod_fc(req, fib); |
183 | pr_debug("%s mpcifc returned noi: %d\n", __func__, fib->noi); | 139 | pr_debug("%s mpcifc returned noi: %d\n", __func__, fib->noi); |
184 | 140 | ||
185 | free_page((unsigned long) fib); | 141 | free_page((unsigned long) fib); |
@@ -209,7 +165,7 @@ static int mod_pci(struct zpci_dev *zdev, int fn, u8 dmaas, struct mod_pci_args | |||
209 | fib->iota = args->iota; | 165 | fib->iota = args->iota; |
210 | fib->fmb_addr = args->fmb_addr; | 166 | fib->fmb_addr = args->fmb_addr; |
211 | 167 | ||
212 | rc = s390pci_mod_fc(req, fib); | 168 | rc = zpci_mod_fc(req, fib); |
213 | free_page((unsigned long) fib); | 169 | free_page((unsigned long) fib); |
214 | return rc; | 170 | return rc; |
215 | } | 171 | } |
@@ -234,7 +190,7 @@ int zpci_unregister_ioat(struct zpci_dev *zdev, u8 dmaas) | |||
234 | } | 190 | } |
235 | 191 | ||
236 | /* Modify PCI: Unregister adapter interruptions */ | 192 | /* Modify PCI: Unregister adapter interruptions */ |
237 | static int zpci_unregister_airq(struct zpci_dev *zdev) | 193 | static int zpci_clear_airq(struct zpci_dev *zdev) |
238 | { | 194 | { |
239 | struct mod_pci_args args = { 0, 0, 0, 0 }; | 195 | struct mod_pci_args args = { 0, 0, 0, 0 }; |
240 | 196 | ||
@@ -283,7 +239,7 @@ static int zpci_cfg_load(struct zpci_dev *zdev, int offset, u32 *val, u8 len) | |||
283 | u64 data; | 239 | u64 data; |
284 | int rc; | 240 | int rc; |
285 | 241 | ||
286 | rc = s390pci_load(&data, req, offset); | 242 | rc = zpci_load(&data, req, offset); |
287 | if (!rc) { | 243 | if (!rc) { |
288 | data = data << ((8 - len) * 8); | 244 | data = data << ((8 - len) * 8); |
289 | data = le64_to_cpu(data); | 245 | data = le64_to_cpu(data); |
@@ -301,25 +257,46 @@ static int zpci_cfg_store(struct zpci_dev *zdev, int offset, u32 val, u8 len) | |||
301 | 257 | ||
302 | data = cpu_to_le64(data); | 258 | data = cpu_to_le64(data); |
303 | data = data >> ((8 - len) * 8); | 259 | data = data >> ((8 - len) * 8); |
304 | rc = s390pci_store(data, req, offset); | 260 | rc = zpci_store(data, req, offset); |
305 | return rc; | 261 | return rc; |
306 | } | 262 | } |
307 | 263 | ||
308 | void enable_irq(unsigned int irq) | 264 | static int zpci_msi_set_mask_bits(struct msi_desc *msi, u32 mask, u32 flag) |
265 | { | ||
266 | int offset, pos; | ||
267 | u32 mask_bits; | ||
268 | |||
269 | if (msi->msi_attrib.is_msix) { | ||
270 | offset = msi->msi_attrib.entry_nr * PCI_MSIX_ENTRY_SIZE + | ||
271 | PCI_MSIX_ENTRY_VECTOR_CTRL; | ||
272 | msi->masked = readl(msi->mask_base + offset); | ||
273 | writel(flag, msi->mask_base + offset); | ||
274 | } else if (msi->msi_attrib.maskbit) { | ||
275 | pos = (long) msi->mask_base; | ||
276 | pci_read_config_dword(msi->dev, pos, &mask_bits); | ||
277 | mask_bits &= ~(mask); | ||
278 | mask_bits |= flag & mask; | ||
279 | pci_write_config_dword(msi->dev, pos, mask_bits); | ||
280 | } else | ||
281 | return 0; | ||
282 | |||
283 | msi->msi_attrib.maskbit = !!flag; | ||
284 | return 1; | ||
285 | } | ||
286 | |||
287 | static void zpci_enable_irq(struct irq_data *data) | ||
309 | { | 288 | { |
310 | struct msi_desc *msi = irq_get_msi_desc(irq); | 289 | struct msi_desc *msi = irq_get_msi_desc(data->irq); |
311 | 290 | ||
312 | zpci_msi_set_mask_bits(msi, 1, 0); | 291 | zpci_msi_set_mask_bits(msi, 1, 0); |
313 | } | 292 | } |
314 | EXPORT_SYMBOL_GPL(enable_irq); | ||
315 | 293 | ||
316 | void disable_irq(unsigned int irq) | 294 | static void zpci_disable_irq(struct irq_data *data) |
317 | { | 295 | { |
318 | struct msi_desc *msi = irq_get_msi_desc(irq); | 296 | struct msi_desc *msi = irq_get_msi_desc(data->irq); |
319 | 297 | ||
320 | zpci_msi_set_mask_bits(msi, 1, 1); | 298 | zpci_msi_set_mask_bits(msi, 1, 1); |
321 | } | 299 | } |
322 | EXPORT_SYMBOL_GPL(disable_irq); | ||
323 | 300 | ||
324 | void pcibios_fixup_bus(struct pci_bus *bus) | 301 | void pcibios_fixup_bus(struct pci_bus *bus) |
325 | { | 302 | { |
@@ -404,152 +381,147 @@ static struct pci_ops pci_root_ops = { | |||
404 | .write = pci_write, | 381 | .write = pci_write, |
405 | }; | 382 | }; |
406 | 383 | ||
407 | /* store the last handled bit to implement fair scheduling of devices */ | ||
408 | static DEFINE_PER_CPU(unsigned long, next_sbit); | ||
409 | |||
410 | static void zpci_irq_handler(struct airq_struct *airq) | 384 | static void zpci_irq_handler(struct airq_struct *airq) |
411 | { | 385 | { |
412 | unsigned long sbit, mbit, last = 0, start = __get_cpu_var(next_sbit); | 386 | unsigned long si, ai; |
413 | int rescan = 0, max = aisb_max; | 387 | struct airq_iv *aibv; |
414 | struct zdev_irq_map *imap; | 388 | int irqs_on = 0; |
415 | 389 | ||
416 | inc_irq_stat(IRQIO_PCI); | 390 | inc_irq_stat(IRQIO_PCI); |
417 | sbit = start; | 391 | for (si = 0;;) { |
418 | 392 | /* Scan adapter summary indicator bit vector */ | |
419 | scan: | 393 | si = airq_iv_scan(zpci_aisb_iv, si, airq_iv_end(zpci_aisb_iv)); |
420 | /* find summary_bit */ | 394 | if (si == -1UL) { |
421 | for_each_set_bit_left_cont(sbit, bucket->aisb, max) { | 395 | if (irqs_on++) |
422 | clear_bit(63 - (sbit & 63), bucket->aisb + (sbit >> 6)); | 396 | /* End of second scan with interrupts on. */ |
423 | last = sbit; | 397 | break; |
398 | /* First scan complete, reenable interrupts. */ | ||
399 | zpci_set_irq_ctrl(SIC_IRQ_MODE_SINGLE, NULL, PCI_ISC); | ||
400 | si = 0; | ||
401 | continue; | ||
402 | } | ||
424 | 403 | ||
425 | /* find vector bit */ | 404 | /* Scan the adapter interrupt vector for this device. */ |
426 | imap = bucket->imap[sbit]; | 405 | aibv = zpci_aibv[si]; |
427 | for_each_set_bit_left(mbit, &imap->aibv, imap->msi_vecs) { | 406 | for (ai = 0;;) { |
407 | ai = airq_iv_scan(aibv, ai, airq_iv_end(aibv)); | ||
408 | if (ai == -1UL) | ||
409 | break; | ||
428 | inc_irq_stat(IRQIO_MSI); | 410 | inc_irq_stat(IRQIO_MSI); |
429 | clear_bit(63 - mbit, &imap->aibv); | 411 | airq_iv_lock(aibv, ai); |
430 | 412 | generic_handle_irq(airq_iv_get_data(aibv, ai)); | |
431 | spin_lock(&imap->lock); | 413 | airq_iv_unlock(aibv, ai); |
432 | if (imap->cb[mbit].handler) | ||
433 | imap->cb[mbit].handler(mbit, | ||
434 | imap->cb[mbit].data); | ||
435 | spin_unlock(&imap->lock); | ||
436 | } | 414 | } |
437 | } | 415 | } |
438 | |||
439 | if (rescan) | ||
440 | goto out; | ||
441 | |||
442 | /* scan the skipped bits */ | ||
443 | if (start > 0) { | ||
444 | sbit = 0; | ||
445 | max = start; | ||
446 | start = 0; | ||
447 | goto scan; | ||
448 | } | ||
449 | |||
450 | /* enable interrupts again */ | ||
451 | set_irq_ctrl(SIC_IRQ_MODE_SINGLE, NULL, PCI_ISC); | ||
452 | |||
453 | /* check again to not lose initiative */ | ||
454 | rmb(); | ||
455 | max = aisb_max; | ||
456 | sbit = find_first_bit_left(bucket->aisb, max); | ||
457 | if (sbit != max) { | ||
458 | rescan++; | ||
459 | goto scan; | ||
460 | } | ||
461 | out: | ||
462 | /* store next device bit to scan */ | ||
463 | __get_cpu_var(next_sbit) = (++last >= aisb_max) ? 0 : last; | ||
464 | } | 416 | } |
465 | 417 | ||
466 | /* msi_vecs - number of requested interrupts, 0 place function to error state */ | 418 | int arch_setup_msi_irqs(struct pci_dev *pdev, int nvec, int type) |
467 | static int zpci_setup_msi(struct pci_dev *pdev, int msi_vecs) | ||
468 | { | 419 | { |
469 | struct zpci_dev *zdev = get_zdev(pdev); | 420 | struct zpci_dev *zdev = get_zdev(pdev); |
470 | unsigned int aisb, msi_nr; | 421 | unsigned int hwirq, irq, msi_vecs; |
422 | unsigned long aisb; | ||
471 | struct msi_desc *msi; | 423 | struct msi_desc *msi; |
424 | struct msi_msg msg; | ||
472 | int rc; | 425 | int rc; |
473 | 426 | ||
474 | /* store the number of used MSI vectors */ | 427 | pr_debug("%s: requesting %d MSI-X interrupts...", __func__, nvec); |
475 | zdev->irq_map->msi_vecs = min(msi_vecs, ZPCI_NR_MSI_VECS); | 428 | if (type != PCI_CAP_ID_MSIX && type != PCI_CAP_ID_MSI) |
476 | 429 | return -EINVAL; | |
477 | spin_lock(&bucket->lock); | 430 | msi_vecs = min(nvec, ZPCI_MSI_VEC_MAX); |
478 | aisb = find_first_zero_bit(bucket->alloc, PAGE_SIZE); | 431 | msi_vecs = min_t(unsigned int, msi_vecs, CONFIG_PCI_NR_MSI); |
479 | /* alloc map exhausted? */ | ||
480 | if (aisb == PAGE_SIZE) { | ||
481 | spin_unlock(&bucket->lock); | ||
482 | return -EIO; | ||
483 | } | ||
484 | set_bit(aisb, bucket->alloc); | ||
485 | spin_unlock(&bucket->lock); | ||
486 | 432 | ||
433 | /* Allocate adapter summary indicator bit */ | ||
434 | rc = -EIO; | ||
435 | aisb = airq_iv_alloc_bit(zpci_aisb_iv); | ||
436 | if (aisb == -1UL) | ||
437 | goto out; | ||
487 | zdev->aisb = aisb; | 438 | zdev->aisb = aisb; |
488 | if (aisb + 1 > aisb_max) | ||
489 | aisb_max = aisb + 1; | ||
490 | 439 | ||
491 | /* wire up IRQ shortcut pointer */ | 440 | /* Create adapter interrupt vector */ |
492 | bucket->imap[zdev->aisb] = zdev->irq_map; | 441 | rc = -ENOMEM; |
493 | pr_debug("%s: imap[%u] linked to %p\n", __func__, zdev->aisb, zdev->irq_map); | 442 | zdev->aibv = airq_iv_create(msi_vecs, AIRQ_IV_DATA | AIRQ_IV_BITLOCK); |
443 | if (!zdev->aibv) | ||
444 | goto out_si; | ||
494 | 445 | ||
495 | /* TODO: irq number 0 wont be found if we return less than requested MSIs. | 446 | /* Wire up shortcut pointer */ |
496 | * ignore it for now and fix in common code. | 447 | zpci_aibv[aisb] = zdev->aibv; |
497 | */ | ||
498 | msi_nr = aisb << ZPCI_MSI_VEC_BITS; | ||
499 | 448 | ||
449 | /* Request MSI interrupts */ | ||
450 | hwirq = 0; | ||
500 | list_for_each_entry(msi, &pdev->msi_list, list) { | 451 | list_for_each_entry(msi, &pdev->msi_list, list) { |
501 | rc = zpci_setup_msi_irq(zdev, msi, msi_nr, | 452 | rc = -EIO; |
502 | aisb << ZPCI_MSI_VEC_BITS); | 453 | irq = irq_alloc_desc(0); /* Alloc irq on node 0 */ |
454 | if (irq == NO_IRQ) | ||
455 | goto out_msi; | ||
456 | rc = irq_set_msi_desc(irq, msi); | ||
503 | if (rc) | 457 | if (rc) |
504 | return rc; | 458 | goto out_msi; |
505 | msi_nr++; | 459 | irq_set_chip_and_handler(irq, &zpci_irq_chip, |
460 | handle_simple_irq); | ||
461 | msg.data = hwirq; | ||
462 | msg.address_lo = zdev->msi_addr & 0xffffffff; | ||
463 | msg.address_hi = zdev->msi_addr >> 32; | ||
464 | write_msi_msg(irq, &msg); | ||
465 | airq_iv_set_data(zdev->aibv, hwirq, irq); | ||
466 | hwirq++; | ||
506 | } | 467 | } |
507 | 468 | ||
508 | rc = zpci_register_airq(zdev, aisb, (u64) &zdev->irq_map->aibv); | 469 | /* Enable adapter interrupts */ |
509 | if (rc) { | 470 | rc = zpci_set_airq(zdev); |
510 | clear_bit(aisb, bucket->alloc); | 471 | if (rc) |
511 | dev_err(&pdev->dev, "register MSI failed with: %d\n", rc); | 472 | goto out_msi; |
512 | return rc; | 473 | |
474 | return (msi_vecs == nvec) ? 0 : msi_vecs; | ||
475 | |||
476 | out_msi: | ||
477 | list_for_each_entry(msi, &pdev->msi_list, list) { | ||
478 | if (hwirq-- == 0) | ||
479 | break; | ||
480 | irq_set_msi_desc(msi->irq, NULL); | ||
481 | irq_free_desc(msi->irq); | ||
482 | msi->msg.address_lo = 0; | ||
483 | msi->msg.address_hi = 0; | ||
484 | msi->msg.data = 0; | ||
485 | msi->irq = 0; | ||
513 | } | 486 | } |
514 | return (zdev->irq_map->msi_vecs == msi_vecs) ? | 487 | zpci_aibv[aisb] = NULL; |
515 | 0 : zdev->irq_map->msi_vecs; | 488 | airq_iv_release(zdev->aibv); |
489 | out_si: | ||
490 | airq_iv_free_bit(zpci_aisb_iv, aisb); | ||
491 | out: | ||
492 | dev_err(&pdev->dev, "register MSI failed with: %d\n", rc); | ||
493 | return rc; | ||
516 | } | 494 | } |
517 | 495 | ||
518 | static void zpci_teardown_msi(struct pci_dev *pdev) | 496 | void arch_teardown_msi_irqs(struct pci_dev *pdev) |
519 | { | 497 | { |
520 | struct zpci_dev *zdev = get_zdev(pdev); | 498 | struct zpci_dev *zdev = get_zdev(pdev); |
521 | struct msi_desc *msi; | 499 | struct msi_desc *msi; |
522 | int aisb, rc; | 500 | int rc; |
523 | 501 | ||
524 | rc = zpci_unregister_airq(zdev); | 502 | pr_info("%s: on pdev: %p\n", __func__, pdev); |
503 | |||
504 | /* Disable adapter interrupts */ | ||
505 | rc = zpci_clear_airq(zdev); | ||
525 | if (rc) { | 506 | if (rc) { |
526 | dev_err(&pdev->dev, "deregister MSI failed with: %d\n", rc); | 507 | dev_err(&pdev->dev, "deregister MSI failed with: %d\n", rc); |
527 | return; | 508 | return; |
528 | } | 509 | } |
529 | 510 | ||
530 | msi = list_first_entry(&pdev->msi_list, struct msi_desc, list); | 511 | /* Release MSI interrupts */ |
531 | aisb = irq_to_dev_nr(msi->irq); | 512 | list_for_each_entry(msi, &pdev->msi_list, list) { |
532 | 513 | zpci_msi_set_mask_bits(msi, 1, 1); | |
533 | list_for_each_entry(msi, &pdev->msi_list, list) | 514 | irq_set_msi_desc(msi->irq, NULL); |
534 | zpci_teardown_msi_irq(zdev, msi); | 515 | irq_free_desc(msi->irq); |
535 | 516 | msi->msg.address_lo = 0; | |
536 | clear_bit(aisb, bucket->alloc); | 517 | msi->msg.address_hi = 0; |
537 | if (aisb + 1 == aisb_max) | 518 | msi->msg.data = 0; |
538 | aisb_max--; | 519 | msi->irq = 0; |
539 | } | 520 | } |
540 | |||
541 | int arch_setup_msi_irqs(struct pci_dev *pdev, int nvec, int type) | ||
542 | { | ||
543 | pr_debug("%s: requesting %d MSI-X interrupts...", __func__, nvec); | ||
544 | if (type != PCI_CAP_ID_MSIX && type != PCI_CAP_ID_MSI) | ||
545 | return -EINVAL; | ||
546 | return zpci_setup_msi(pdev, nvec); | ||
547 | } | ||
548 | 521 | ||
549 | void arch_teardown_msi_irqs(struct pci_dev *pdev) | 522 | zpci_aibv[zdev->aisb] = NULL; |
550 | { | 523 | airq_iv_release(zdev->aibv); |
551 | pr_info("%s: on pdev: %p\n", __func__, pdev); | 524 | airq_iv_free_bit(zpci_aisb_iv, zdev->aisb); |
552 | zpci_teardown_msi(pdev); | ||
553 | } | 525 | } |
554 | 526 | ||
555 | static void zpci_map_resources(struct zpci_dev *zdev) | 527 | static void zpci_map_resources(struct zpci_dev *zdev) |
@@ -564,8 +536,6 @@ static void zpci_map_resources(struct zpci_dev *zdev) | |||
564 | continue; | 536 | continue; |
565 | pdev->resource[i].start = (resource_size_t) pci_iomap(pdev, i, 0); | 537 | pdev->resource[i].start = (resource_size_t) pci_iomap(pdev, i, 0); |
566 | pdev->resource[i].end = pdev->resource[i].start + len - 1; | 538 | pdev->resource[i].end = pdev->resource[i].start + len - 1; |
567 | pr_debug("BAR%i: -> start: %Lx end: %Lx\n", | ||
568 | i, pdev->resource[i].start, pdev->resource[i].end); | ||
569 | } | 539 | } |
570 | } | 540 | } |
571 | 541 | ||
@@ -589,162 +559,47 @@ struct zpci_dev *zpci_alloc_device(void) | |||
589 | 559 | ||
590 | /* Alloc memory for our private pci device data */ | 560 | /* Alloc memory for our private pci device data */ |
591 | zdev = kzalloc(sizeof(*zdev), GFP_KERNEL); | 561 | zdev = kzalloc(sizeof(*zdev), GFP_KERNEL); |
592 | if (!zdev) | 562 | return zdev ? : ERR_PTR(-ENOMEM); |
593 | return ERR_PTR(-ENOMEM); | ||
594 | |||
595 | /* Alloc aibv & callback space */ | ||
596 | zdev->irq_map = kmem_cache_zalloc(zdev_irq_cache, GFP_KERNEL); | ||
597 | if (!zdev->irq_map) | ||
598 | goto error; | ||
599 | WARN_ON((u64) zdev->irq_map & 0xff); | ||
600 | return zdev; | ||
601 | |||
602 | error: | ||
603 | kfree(zdev); | ||
604 | return ERR_PTR(-ENOMEM); | ||
605 | } | 563 | } |
606 | 564 | ||
607 | void zpci_free_device(struct zpci_dev *zdev) | 565 | void zpci_free_device(struct zpci_dev *zdev) |
608 | { | 566 | { |
609 | kmem_cache_free(zdev_irq_cache, zdev->irq_map); | ||
610 | kfree(zdev); | 567 | kfree(zdev); |
611 | } | 568 | } |
612 | 569 | ||
613 | /* | ||
614 | * Too late for any s390 specific setup, since interrupts must be set up | ||
615 | * already which requires DMA setup too and the pci scan will access the | ||
616 | * config space, which only works if the function handle is enabled. | ||
617 | */ | ||
618 | int pcibios_enable_device(struct pci_dev *pdev, int mask) | ||
619 | { | ||
620 | struct resource *res; | ||
621 | u16 cmd; | ||
622 | int i; | ||
623 | |||
624 | pci_read_config_word(pdev, PCI_COMMAND, &cmd); | ||
625 | |||
626 | for (i = 0; i < PCI_BAR_COUNT; i++) { | ||
627 | res = &pdev->resource[i]; | ||
628 | |||
629 | if (res->flags & IORESOURCE_IO) | ||
630 | return -EINVAL; | ||
631 | |||
632 | if (res->flags & IORESOURCE_MEM) | ||
633 | cmd |= PCI_COMMAND_MEMORY; | ||
634 | } | ||
635 | pci_write_config_word(pdev, PCI_COMMAND, cmd); | ||
636 | return 0; | ||
637 | } | ||
638 | |||
639 | int pcibios_add_platform_entries(struct pci_dev *pdev) | 570 | int pcibios_add_platform_entries(struct pci_dev *pdev) |
640 | { | 571 | { |
641 | return zpci_sysfs_add_device(&pdev->dev); | 572 | return zpci_sysfs_add_device(&pdev->dev); |
642 | } | 573 | } |
643 | 574 | ||
644 | int zpci_request_irq(unsigned int irq, irq_handler_t handler, void *data) | ||
645 | { | ||
646 | int msi_nr = irq_to_msi_nr(irq); | ||
647 | struct zdev_irq_map *imap; | ||
648 | struct msi_desc *msi; | ||
649 | |||
650 | msi = irq_get_msi_desc(irq); | ||
651 | if (!msi) | ||
652 | return -EIO; | ||
653 | |||
654 | imap = get_imap(irq); | ||
655 | spin_lock_init(&imap->lock); | ||
656 | |||
657 | pr_debug("%s: register handler for IRQ:MSI %d:%d\n", __func__, irq >> 6, msi_nr); | ||
658 | imap->cb[msi_nr].handler = handler; | ||
659 | imap->cb[msi_nr].data = data; | ||
660 | |||
661 | /* | ||
662 | * The generic MSI code returns with the interrupt disabled on the | ||
663 | * card, using the MSI mask bits. Firmware doesn't appear to unmask | ||
664 | * at that level, so we do it here by hand. | ||
665 | */ | ||
666 | zpci_msi_set_mask_bits(msi, 1, 0); | ||
667 | return 0; | ||
668 | } | ||
669 | |||
670 | void zpci_free_irq(unsigned int irq) | ||
671 | { | ||
672 | struct zdev_irq_map *imap = get_imap(irq); | ||
673 | int msi_nr = irq_to_msi_nr(irq); | ||
674 | unsigned long flags; | ||
675 | |||
676 | pr_debug("%s: for irq: %d\n", __func__, irq); | ||
677 | |||
678 | spin_lock_irqsave(&imap->lock, flags); | ||
679 | imap->cb[msi_nr].handler = NULL; | ||
680 | imap->cb[msi_nr].data = NULL; | ||
681 | spin_unlock_irqrestore(&imap->lock, flags); | ||
682 | } | ||
683 | |||
684 | int request_irq(unsigned int irq, irq_handler_t handler, | ||
685 | unsigned long irqflags, const char *devname, void *dev_id) | ||
686 | { | ||
687 | pr_debug("%s: irq: %d handler: %p flags: %lx dev: %s\n", | ||
688 | __func__, irq, handler, irqflags, devname); | ||
689 | |||
690 | return zpci_request_irq(irq, handler, dev_id); | ||
691 | } | ||
692 | EXPORT_SYMBOL_GPL(request_irq); | ||
693 | |||
694 | void free_irq(unsigned int irq, void *dev_id) | ||
695 | { | ||
696 | zpci_free_irq(irq); | ||
697 | } | ||
698 | EXPORT_SYMBOL_GPL(free_irq); | ||
699 | |||
700 | static int __init zpci_irq_init(void) | 575 | static int __init zpci_irq_init(void) |
701 | { | 576 | { |
702 | int cpu, rc; | 577 | int rc; |
703 | |||
704 | bucket = kzalloc(sizeof(*bucket), GFP_KERNEL); | ||
705 | if (!bucket) | ||
706 | return -ENOMEM; | ||
707 | |||
708 | bucket->aisb = (unsigned long *) get_zeroed_page(GFP_KERNEL); | ||
709 | if (!bucket->aisb) { | ||
710 | rc = -ENOMEM; | ||
711 | goto out_aisb; | ||
712 | } | ||
713 | |||
714 | bucket->alloc = (unsigned long *) get_zeroed_page(GFP_KERNEL); | ||
715 | if (!bucket->alloc) { | ||
716 | rc = -ENOMEM; | ||
717 | goto out_alloc; | ||
718 | } | ||
719 | 578 | ||
720 | rc = register_adapter_interrupt(&zpci_airq); | 579 | rc = register_adapter_interrupt(&zpci_airq); |
721 | if (rc) | 580 | if (rc) |
722 | goto out_ai; | 581 | goto out; |
723 | /* Set summary to 1 to be called every time for the ISC. */ | 582 | /* Set summary to 1 to be called every time for the ISC. */ |
724 | *zpci_airq.lsi_ptr = 1; | 583 | *zpci_airq.lsi_ptr = 1; |
725 | 584 | ||
726 | for_each_online_cpu(cpu) | 585 | rc = -ENOMEM; |
727 | per_cpu(next_sbit, cpu) = 0; | 586 | zpci_aisb_iv = airq_iv_create(ZPCI_NR_DEVICES, AIRQ_IV_ALLOC); |
587 | if (!zpci_aisb_iv) | ||
588 | goto out_airq; | ||
728 | 589 | ||
729 | spin_lock_init(&bucket->lock); | 590 | zpci_set_irq_ctrl(SIC_IRQ_MODE_SINGLE, NULL, PCI_ISC); |
730 | set_irq_ctrl(SIC_IRQ_MODE_SINGLE, NULL, PCI_ISC); | ||
731 | return 0; | 591 | return 0; |
732 | 592 | ||
733 | out_ai: | 593 | out_airq: |
734 | free_page((unsigned long) bucket->alloc); | 594 | unregister_adapter_interrupt(&zpci_airq); |
735 | out_alloc: | 595 | out: |
736 | free_page((unsigned long) bucket->aisb); | ||
737 | out_aisb: | ||
738 | kfree(bucket); | ||
739 | return rc; | 596 | return rc; |
740 | } | 597 | } |
741 | 598 | ||
742 | static void zpci_irq_exit(void) | 599 | static void zpci_irq_exit(void) |
743 | { | 600 | { |
744 | free_page((unsigned long) bucket->alloc); | 601 | airq_iv_release(zpci_aisb_iv); |
745 | free_page((unsigned long) bucket->aisb); | ||
746 | unregister_adapter_interrupt(&zpci_airq); | 602 | unregister_adapter_interrupt(&zpci_airq); |
747 | kfree(bucket); | ||
748 | } | 603 | } |
749 | 604 | ||
750 | static struct resource *zpci_alloc_bus_resource(unsigned long start, unsigned long size, | 605 | static struct resource *zpci_alloc_bus_resource(unsigned long start, unsigned long size, |
@@ -801,16 +656,49 @@ static void zpci_free_iomap(struct zpci_dev *zdev, int entry) | |||
801 | int pcibios_add_device(struct pci_dev *pdev) | 656 | int pcibios_add_device(struct pci_dev *pdev) |
802 | { | 657 | { |
803 | struct zpci_dev *zdev = get_zdev(pdev); | 658 | struct zpci_dev *zdev = get_zdev(pdev); |
659 | struct resource *res; | ||
660 | int i; | ||
661 | |||
662 | zdev->pdev = pdev; | ||
663 | zpci_map_resources(zdev); | ||
664 | |||
665 | for (i = 0; i < PCI_BAR_COUNT; i++) { | ||
666 | res = &pdev->resource[i]; | ||
667 | if (res->parent || !res->flags) | ||
668 | continue; | ||
669 | pci_claim_resource(pdev, i); | ||
670 | } | ||
671 | |||
672 | return 0; | ||
673 | } | ||
674 | |||
675 | int pcibios_enable_device(struct pci_dev *pdev, int mask) | ||
676 | { | ||
677 | struct zpci_dev *zdev = get_zdev(pdev); | ||
678 | struct resource *res; | ||
679 | u16 cmd; | ||
680 | int i; | ||
804 | 681 | ||
805 | zdev->pdev = pdev; | 682 | zdev->pdev = pdev; |
806 | zpci_debug_init_device(zdev); | 683 | zpci_debug_init_device(zdev); |
807 | zpci_fmb_enable_device(zdev); | 684 | zpci_fmb_enable_device(zdev); |
808 | zpci_map_resources(zdev); | 685 | zpci_map_resources(zdev); |
809 | 686 | ||
687 | pci_read_config_word(pdev, PCI_COMMAND, &cmd); | ||
688 | for (i = 0; i < PCI_BAR_COUNT; i++) { | ||
689 | res = &pdev->resource[i]; | ||
690 | |||
691 | if (res->flags & IORESOURCE_IO) | ||
692 | return -EINVAL; | ||
693 | |||
694 | if (res->flags & IORESOURCE_MEM) | ||
695 | cmd |= PCI_COMMAND_MEMORY; | ||
696 | } | ||
697 | pci_write_config_word(pdev, PCI_COMMAND, cmd); | ||
810 | return 0; | 698 | return 0; |
811 | } | 699 | } |
812 | 700 | ||
813 | void pcibios_release_device(struct pci_dev *pdev) | 701 | void pcibios_disable_device(struct pci_dev *pdev) |
814 | { | 702 | { |
815 | struct zpci_dev *zdev = get_zdev(pdev); | 703 | struct zpci_dev *zdev = get_zdev(pdev); |
816 | 704 | ||
@@ -898,6 +786,8 @@ int zpci_enable_device(struct zpci_dev *zdev) | |||
898 | rc = zpci_dma_init_device(zdev); | 786 | rc = zpci_dma_init_device(zdev); |
899 | if (rc) | 787 | if (rc) |
900 | goto out_dma; | 788 | goto out_dma; |
789 | |||
790 | zdev->state = ZPCI_FN_STATE_ONLINE; | ||
901 | return 0; | 791 | return 0; |
902 | 792 | ||
903 | out_dma: | 793 | out_dma: |
@@ -926,18 +816,16 @@ int zpci_create_device(struct zpci_dev *zdev) | |||
926 | rc = zpci_enable_device(zdev); | 816 | rc = zpci_enable_device(zdev); |
927 | if (rc) | 817 | if (rc) |
928 | goto out_free; | 818 | goto out_free; |
929 | |||
930 | zdev->state = ZPCI_FN_STATE_ONLINE; | ||
931 | } | 819 | } |
932 | rc = zpci_scan_bus(zdev); | 820 | rc = zpci_scan_bus(zdev); |
933 | if (rc) | 821 | if (rc) |
934 | goto out_disable; | 822 | goto out_disable; |
935 | 823 | ||
936 | mutex_lock(&zpci_list_lock); | 824 | spin_lock(&zpci_list_lock); |
937 | list_add_tail(&zdev->entry, &zpci_list); | 825 | list_add_tail(&zdev->entry, &zpci_list); |
938 | if (hotplug_ops) | 826 | spin_unlock(&zpci_list_lock); |
939 | hotplug_ops->create_slot(zdev); | 827 | |
940 | mutex_unlock(&zpci_list_lock); | 828 | zpci_init_slot(zdev); |
941 | 829 | ||
942 | return 0; | 830 | return 0; |
943 | 831 | ||
@@ -967,15 +855,10 @@ static inline int barsize(u8 size) | |||
967 | 855 | ||
968 | static int zpci_mem_init(void) | 856 | static int zpci_mem_init(void) |
969 | { | 857 | { |
970 | zdev_irq_cache = kmem_cache_create("PCI_IRQ_cache", sizeof(struct zdev_irq_map), | ||
971 | L1_CACHE_BYTES, SLAB_HWCACHE_ALIGN, NULL); | ||
972 | if (!zdev_irq_cache) | ||
973 | goto error_zdev; | ||
974 | |||
975 | zdev_fmb_cache = kmem_cache_create("PCI_FMB_cache", sizeof(struct zpci_fmb), | 858 | zdev_fmb_cache = kmem_cache_create("PCI_FMB_cache", sizeof(struct zpci_fmb), |
976 | 16, 0, NULL); | 859 | 16, 0, NULL); |
977 | if (!zdev_fmb_cache) | 860 | if (!zdev_fmb_cache) |
978 | goto error_fmb; | 861 | goto error_zdev; |
979 | 862 | ||
980 | /* TODO: use realloc */ | 863 | /* TODO: use realloc */ |
981 | zpci_iomap_start = kzalloc(ZPCI_IOMAP_MAX_ENTRIES * sizeof(*zpci_iomap_start), | 864 | zpci_iomap_start = kzalloc(ZPCI_IOMAP_MAX_ENTRIES * sizeof(*zpci_iomap_start), |
@@ -986,8 +869,6 @@ static int zpci_mem_init(void) | |||
986 | 869 | ||
987 | error_iomap: | 870 | error_iomap: |
988 | kmem_cache_destroy(zdev_fmb_cache); | 871 | kmem_cache_destroy(zdev_fmb_cache); |
989 | error_fmb: | ||
990 | kmem_cache_destroy(zdev_irq_cache); | ||
991 | error_zdev: | 872 | error_zdev: |
992 | return -ENOMEM; | 873 | return -ENOMEM; |
993 | } | 874 | } |
@@ -995,28 +876,10 @@ error_zdev: | |||
995 | static void zpci_mem_exit(void) | 876 | static void zpci_mem_exit(void) |
996 | { | 877 | { |
997 | kfree(zpci_iomap_start); | 878 | kfree(zpci_iomap_start); |
998 | kmem_cache_destroy(zdev_irq_cache); | ||
999 | kmem_cache_destroy(zdev_fmb_cache); | 879 | kmem_cache_destroy(zdev_fmb_cache); |
1000 | } | 880 | } |
1001 | 881 | ||
1002 | void zpci_register_hp_ops(struct pci_hp_callback_ops *ops) | 882 | static unsigned int s390_pci_probe; |
1003 | { | ||
1004 | mutex_lock(&zpci_list_lock); | ||
1005 | hotplug_ops = ops; | ||
1006 | mutex_unlock(&zpci_list_lock); | ||
1007 | } | ||
1008 | EXPORT_SYMBOL_GPL(zpci_register_hp_ops); | ||
1009 | |||
1010 | void zpci_deregister_hp_ops(void) | ||
1011 | { | ||
1012 | mutex_lock(&zpci_list_lock); | ||
1013 | hotplug_ops = NULL; | ||
1014 | mutex_unlock(&zpci_list_lock); | ||
1015 | } | ||
1016 | EXPORT_SYMBOL_GPL(zpci_deregister_hp_ops); | ||
1017 | |||
1018 | unsigned int s390_pci_probe; | ||
1019 | EXPORT_SYMBOL_GPL(s390_pci_probe); | ||
1020 | 883 | ||
1021 | char * __init pcibios_setup(char *str) | 884 | char * __init pcibios_setup(char *str) |
1022 | { | 885 | { |
@@ -1044,16 +907,12 @@ static int __init pci_base_init(void) | |||
1044 | 907 | ||
1045 | rc = zpci_debug_init(); | 908 | rc = zpci_debug_init(); |
1046 | if (rc) | 909 | if (rc) |
1047 | return rc; | 910 | goto out; |
1048 | 911 | ||
1049 | rc = zpci_mem_init(); | 912 | rc = zpci_mem_init(); |
1050 | if (rc) | 913 | if (rc) |
1051 | goto out_mem; | 914 | goto out_mem; |
1052 | 915 | ||
1053 | rc = zpci_msihash_init(); | ||
1054 | if (rc) | ||
1055 | goto out_hash; | ||
1056 | |||
1057 | rc = zpci_irq_init(); | 916 | rc = zpci_irq_init(); |
1058 | if (rc) | 917 | if (rc) |
1059 | goto out_irq; | 918 | goto out_irq; |
@@ -1062,7 +921,7 @@ static int __init pci_base_init(void) | |||
1062 | if (rc) | 921 | if (rc) |
1063 | goto out_dma; | 922 | goto out_dma; |
1064 | 923 | ||
1065 | rc = clp_find_pci_devices(); | 924 | rc = clp_scan_pci_devices(); |
1066 | if (rc) | 925 | if (rc) |
1067 | goto out_find; | 926 | goto out_find; |
1068 | 927 | ||
@@ -1073,11 +932,15 @@ out_find: | |||
1073 | out_dma: | 932 | out_dma: |
1074 | zpci_irq_exit(); | 933 | zpci_irq_exit(); |
1075 | out_irq: | 934 | out_irq: |
1076 | zpci_msihash_exit(); | ||
1077 | out_hash: | ||
1078 | zpci_mem_exit(); | 935 | zpci_mem_exit(); |
1079 | out_mem: | 936 | out_mem: |
1080 | zpci_debug_exit(); | 937 | zpci_debug_exit(); |
938 | out: | ||
1081 | return rc; | 939 | return rc; |
1082 | } | 940 | } |
1083 | subsys_initcall(pci_base_init); | 941 | subsys_initcall_sync(pci_base_init); |
942 | |||
943 | void zpci_rescan(void) | ||
944 | { | ||
945 | clp_rescan_pci_devices_simple(); | ||
946 | } | ||