blob: 27e7fed3707d90f0c95275e8c3d4e50abe50acc7 [file] [log] [blame]
Jan Glaubercd248342012-11-29 12:50:30 +01001/*
2 * Copyright IBM Corp. 2012
3 *
4 * Author(s):
5 * Jan Glauber <jang@linux.vnet.ibm.com>
6 *
7 * The System z PCI code is a rewrite from a prototype by
8 * the following people (Kudoz!):
Jan Glauberbedef752012-12-06 14:06:28 +01009 * Alexander Schmidt
10 * Christoph Raisch
11 * Hannes Hering
12 * Hoang-Nam Nguyen
13 * Jan-Bernd Themann
14 * Stefan Roscher
15 * Thomas Klein
Jan Glaubercd248342012-11-29 12:50:30 +010016 */
17
18#define COMPONENT "zPCI"
19#define pr_fmt(fmt) COMPONENT ": " fmt
20
21#include <linux/kernel.h>
22#include <linux/slab.h>
23#include <linux/err.h>
24#include <linux/export.h>
25#include <linux/delay.h>
Jan Glauber9a4da8a2012-11-29 13:05:05 +010026#include <linux/irq.h>
27#include <linux/kernel_stat.h>
Jan Glaubercd248342012-11-29 12:50:30 +010028#include <linux/seq_file.h>
29#include <linux/pci.h>
30#include <linux/msi.h>
31
Jan Glauber9a4da8a2012-11-29 13:05:05 +010032#include <asm/isc.h>
33#include <asm/airq.h>
Jan Glaubercd248342012-11-29 12:50:30 +010034#include <asm/facility.h>
35#include <asm/pci_insn.h>
Jan Glaubera755a452012-11-29 12:55:21 +010036#include <asm/pci_clp.h>
Jan Glauber828b35f2012-11-29 14:33:30 +010037#include <asm/pci_dma.h>
Jan Glaubercd248342012-11-29 12:50:30 +010038
39#define DEBUG /* enable pr_debug */
40
Jan Glauber9a4da8a2012-11-29 13:05:05 +010041#define SIC_IRQ_MODE_ALL 0
42#define SIC_IRQ_MODE_SINGLE 1
43
Jan Glaubercd248342012-11-29 12:50:30 +010044#define ZPCI_NR_DMA_SPACES 1
45#define ZPCI_NR_DEVICES CONFIG_PCI_NR_FUNCTIONS
46
47/* list of all detected zpci devices */
48LIST_HEAD(zpci_list);
Jan Glauber7441b062012-11-29 14:35:47 +010049EXPORT_SYMBOL_GPL(zpci_list);
Jan Glaubercd248342012-11-29 12:50:30 +010050DEFINE_MUTEX(zpci_list_lock);
Jan Glauber7441b062012-11-29 14:35:47 +010051EXPORT_SYMBOL_GPL(zpci_list_lock);
52
Sebastian Ott53923352013-01-31 19:55:17 +010053static struct pci_hp_callback_ops *hotplug_ops;
Jan Glaubercd248342012-11-29 12:50:30 +010054
55static DECLARE_BITMAP(zpci_domain, ZPCI_NR_DEVICES);
56static DEFINE_SPINLOCK(zpci_domain_lock);
57
Jan Glauber9a4da8a2012-11-29 13:05:05 +010058struct callback {
59 irq_handler_t handler;
60 void *data;
61};
62
63struct zdev_irq_map {
Martin Schwidefsky5d0d8f42013-06-25 16:36:29 +020064 struct airq_iv *aibv; /* Adapter interrupt bit vector */
65 struct callback *cb; /* callback handler array */
66 int msi_vecs; /* consecutive MSI-vectors used */
Jan Glauber9a4da8a2012-11-29 13:05:05 +010067};
68
Martin Schwidefsky5d0d8f42013-06-25 16:36:29 +020069static struct airq_iv *zpci_aisb_iv;
70static struct zdev_irq_map *zpci_imap[ZPCI_NR_DEVICES];
Jan Glauber9a4da8a2012-11-29 13:05:05 +010071
Martin Schwidefskyf4eae942013-06-24 10:30:41 +020072/* Adapter interrupt definitions */
73static void zpci_irq_handler(struct airq_struct *airq);
74
75static struct airq_struct zpci_airq = {
76 .handler = zpci_irq_handler,
77 .isc = PCI_ISC,
78};
Jan Glauber9a4da8a2012-11-29 13:05:05 +010079
Jan Glaubercd248342012-11-29 12:50:30 +010080/* I/O Map */
81static DEFINE_SPINLOCK(zpci_iomap_lock);
82static DECLARE_BITMAP(zpci_iomap, ZPCI_IOMAP_MAX_ENTRIES);
83struct zpci_iomap_entry *zpci_iomap_start;
84EXPORT_SYMBOL_GPL(zpci_iomap_start);
85
Jan Glauber9a4da8a2012-11-29 13:05:05 +010086static struct kmem_cache *zdev_irq_cache;
Jan Glauberd0b08852012-12-11 14:53:35 +010087static struct kmem_cache *zdev_fmb_cache;
88
Jan Glauber9a4da8a2012-11-29 13:05:05 +010089static inline int irq_to_msi_nr(unsigned int irq)
90{
Martin Schwidefsky5d0d8f42013-06-25 16:36:29 +020091 return irq & ZPCI_MSI_VEC_MASK;
Jan Glauber9a4da8a2012-11-29 13:05:05 +010092}
93
94static inline int irq_to_dev_nr(unsigned int irq)
95{
96 return irq >> ZPCI_MSI_VEC_BITS;
97}
98
Jan Glaubercd248342012-11-29 12:50:30 +010099struct zpci_dev *get_zdev(struct pci_dev *pdev)
100{
101 return (struct zpci_dev *) pdev->sysdata;
102}
103
104struct zpci_dev *get_zdev_by_fid(u32 fid)
105{
106 struct zpci_dev *tmp, *zdev = NULL;
107
108 mutex_lock(&zpci_list_lock);
109 list_for_each_entry(tmp, &zpci_list, entry) {
110 if (tmp->fid == fid) {
111 zdev = tmp;
112 break;
113 }
114 }
115 mutex_unlock(&zpci_list_lock);
116 return zdev;
117}
118
119bool zpci_fid_present(u32 fid)
120{
121 return (get_zdev_by_fid(fid) != NULL) ? true : false;
122}
123
124static struct zpci_dev *get_zdev_by_bus(struct pci_bus *bus)
125{
126 return (bus && bus->sysdata) ? (struct zpci_dev *) bus->sysdata : NULL;
127}
128
129int pci_domain_nr(struct pci_bus *bus)
130{
131 return ((struct zpci_dev *) bus->sysdata)->domain;
132}
133EXPORT_SYMBOL_GPL(pci_domain_nr);
134
135int pci_proc_domain(struct pci_bus *bus)
136{
137 return pci_domain_nr(bus);
138}
139EXPORT_SYMBOL_GPL(pci_proc_domain);
140
Jan Glauber9a4da8a2012-11-29 13:05:05 +0100141/* Modify PCI: Register adapter interruptions */
Martin Schwidefsky5d0d8f42013-06-25 16:36:29 +0200142static int zpci_set_airq(struct zpci_dev *zdev)
Jan Glauber9a4da8a2012-11-29 13:05:05 +0100143{
144 u64 req = ZPCI_CREATE_REQ(zdev->fh, 0, ZPCI_MOD_FC_REG_INT);
145 struct zpci_fib *fib;
146 int rc;
147
148 fib = (void *) get_zeroed_page(GFP_KERNEL);
149 if (!fib)
150 return -ENOMEM;
151
152 fib->isc = PCI_ISC;
Jan Glauber9a4da8a2012-11-29 13:05:05 +0100153 fib->sum = 1; /* enable summary notifications */
Martin Schwidefsky5d0d8f42013-06-25 16:36:29 +0200154 fib->noi = airq_iv_end(zdev->aibv);
155 fib->aibv = (unsigned long) zdev->aibv->vector;
156 fib->aibvo = 0; /* each zdev has its own interrupt vector */
157 fib->aisb = (unsigned long) zpci_aisb_iv->vector + (zdev->aisb/64)*8;
158 fib->aisbo = zdev->aisb & 63;
Jan Glauber9a4da8a2012-11-29 13:05:05 +0100159
Martin Schwidefsky93893392013-06-25 14:52:23 +0200160 rc = zpci_mod_fc(req, fib);
Jan Glauber9a4da8a2012-11-29 13:05:05 +0100161 pr_debug("%s mpcifc returned noi: %d\n", __func__, fib->noi);
162
163 free_page((unsigned long) fib);
164 return rc;
165}
166
167struct mod_pci_args {
168 u64 base;
169 u64 limit;
170 u64 iota;
Jan Glauberd0b08852012-12-11 14:53:35 +0100171 u64 fmb_addr;
Jan Glauber9a4da8a2012-11-29 13:05:05 +0100172};
173
174static int mod_pci(struct zpci_dev *zdev, int fn, u8 dmaas, struct mod_pci_args *args)
175{
176 u64 req = ZPCI_CREATE_REQ(zdev->fh, dmaas, fn);
177 struct zpci_fib *fib;
178 int rc;
179
180 /* The FIB must be available even if it's not used */
181 fib = (void *) get_zeroed_page(GFP_KERNEL);
182 if (!fib)
183 return -ENOMEM;
184
185 fib->pba = args->base;
186 fib->pal = args->limit;
187 fib->iota = args->iota;
Jan Glauberd0b08852012-12-11 14:53:35 +0100188 fib->fmb_addr = args->fmb_addr;
Jan Glauber9a4da8a2012-11-29 13:05:05 +0100189
Martin Schwidefsky93893392013-06-25 14:52:23 +0200190 rc = zpci_mod_fc(req, fib);
Jan Glauber9a4da8a2012-11-29 13:05:05 +0100191 free_page((unsigned long) fib);
192 return rc;
193}
194
Jan Glauber828b35f2012-11-29 14:33:30 +0100195/* Modify PCI: Register I/O address translation parameters */
196int zpci_register_ioat(struct zpci_dev *zdev, u8 dmaas,
197 u64 base, u64 limit, u64 iota)
198{
Jan Glauberd0b08852012-12-11 14:53:35 +0100199 struct mod_pci_args args = { base, limit, iota, 0 };
Jan Glauber828b35f2012-11-29 14:33:30 +0100200
201 WARN_ON_ONCE(iota & 0x3fff);
202 args.iota |= ZPCI_IOTA_RTTO_FLAG;
203 return mod_pci(zdev, ZPCI_MOD_FC_REG_IOAT, dmaas, &args);
204}
205
206/* Modify PCI: Unregister I/O address translation parameters */
207int zpci_unregister_ioat(struct zpci_dev *zdev, u8 dmaas)
208{
Jan Glauberd0b08852012-12-11 14:53:35 +0100209 struct mod_pci_args args = { 0, 0, 0, 0 };
Jan Glauber828b35f2012-11-29 14:33:30 +0100210
211 return mod_pci(zdev, ZPCI_MOD_FC_DEREG_IOAT, dmaas, &args);
212}
213
Jan Glauber9a4da8a2012-11-29 13:05:05 +0100214/* Modify PCI: Unregister adapter interruptions */
Martin Schwidefsky5d0d8f42013-06-25 16:36:29 +0200215static int zpci_clear_airq(struct zpci_dev *zdev)
Jan Glauber9a4da8a2012-11-29 13:05:05 +0100216{
Jan Glauberd0b08852012-12-11 14:53:35 +0100217 struct mod_pci_args args = { 0, 0, 0, 0 };
Jan Glauber9a4da8a2012-11-29 13:05:05 +0100218
219 return mod_pci(zdev, ZPCI_MOD_FC_DEREG_INT, 0, &args);
220}
221
Jan Glauberd0b08852012-12-11 14:53:35 +0100222/* Modify PCI: Set PCI function measurement parameters */
223int zpci_fmb_enable_device(struct zpci_dev *zdev)
224{
225 struct mod_pci_args args = { 0, 0, 0, 0 };
226
227 if (zdev->fmb)
228 return -EINVAL;
229
Wei Yongjun08b42122013-02-25 22:09:25 +0800230 zdev->fmb = kmem_cache_zalloc(zdev_fmb_cache, GFP_KERNEL);
Jan Glauberd0b08852012-12-11 14:53:35 +0100231 if (!zdev->fmb)
232 return -ENOMEM;
Jan Glauberd0b08852012-12-11 14:53:35 +0100233 WARN_ON((u64) zdev->fmb & 0xf);
234
235 args.fmb_addr = virt_to_phys(zdev->fmb);
236 return mod_pci(zdev, ZPCI_MOD_FC_SET_MEASURE, 0, &args);
237}
238
239/* Modify PCI: Disable PCI function measurement */
240int zpci_fmb_disable_device(struct zpci_dev *zdev)
241{
242 struct mod_pci_args args = { 0, 0, 0, 0 };
243 int rc;
244
245 if (!zdev->fmb)
246 return -EINVAL;
247
248 /* Function measurement is disabled if fmb address is zero */
249 rc = mod_pci(zdev, ZPCI_MOD_FC_SET_MEASURE, 0, &args);
250
251 kmem_cache_free(zdev_fmb_cache, zdev->fmb);
252 zdev->fmb = NULL;
253 return rc;
254}
255
Jan Glaubercd248342012-11-29 12:50:30 +0100256#define ZPCI_PCIAS_CFGSPC 15
257
258static int zpci_cfg_load(struct zpci_dev *zdev, int offset, u32 *val, u8 len)
259{
260 u64 req = ZPCI_CREATE_REQ(zdev->fh, ZPCI_PCIAS_CFGSPC, len);
261 u64 data;
262 int rc;
263
Martin Schwidefsky93893392013-06-25 14:52:23 +0200264 rc = zpci_load(&data, req, offset);
Sebastian Ottb170bad2013-04-16 14:17:15 +0200265 if (!rc) {
266 data = data << ((8 - len) * 8);
267 data = le64_to_cpu(data);
Jan Glaubercd248342012-11-29 12:50:30 +0100268 *val = (u32) data;
Sebastian Ottb170bad2013-04-16 14:17:15 +0200269 } else
Jan Glaubercd248342012-11-29 12:50:30 +0100270 *val = 0xffffffff;
271 return rc;
272}
273
274static int zpci_cfg_store(struct zpci_dev *zdev, int offset, u32 val, u8 len)
275{
276 u64 req = ZPCI_CREATE_REQ(zdev->fh, ZPCI_PCIAS_CFGSPC, len);
277 u64 data = val;
278 int rc;
279
280 data = cpu_to_le64(data);
281 data = data >> ((8 - len) * 8);
Martin Schwidefsky93893392013-06-25 14:52:23 +0200282 rc = zpci_store(data, req, offset);
Jan Glaubercd248342012-11-29 12:50:30 +0100283 return rc;
284}
285
Jan Glauber9a4da8a2012-11-29 13:05:05 +0100286void enable_irq(unsigned int irq)
287{
288 struct msi_desc *msi = irq_get_msi_desc(irq);
289
290 zpci_msi_set_mask_bits(msi, 1, 0);
291}
292EXPORT_SYMBOL_GPL(enable_irq);
293
294void disable_irq(unsigned int irq)
295{
296 struct msi_desc *msi = irq_get_msi_desc(irq);
297
298 zpci_msi_set_mask_bits(msi, 1, 1);
299}
300EXPORT_SYMBOL_GPL(disable_irq);
301
Greg Kroah-Hartmanb881bc42012-12-21 14:06:37 -0800302void pcibios_fixup_bus(struct pci_bus *bus)
Jan Glaubercd248342012-11-29 12:50:30 +0100303{
304}
305
306resource_size_t pcibios_align_resource(void *data, const struct resource *res,
307 resource_size_t size,
308 resource_size_t align)
309{
310 return 0;
311}
312
Jan Glauber87bc3592012-12-06 14:30:28 +0100313/* combine single writes by using store-block insn */
314void __iowrite64_copy(void __iomem *to, const void *from, size_t count)
315{
316 zpci_memcpy_toio(to, from, count);
317}
318
Jan Glaubercd248342012-11-29 12:50:30 +0100319/* Create a virtual mapping cookie for a PCI BAR */
320void __iomem *pci_iomap(struct pci_dev *pdev, int bar, unsigned long max)
321{
322 struct zpci_dev *zdev = get_zdev(pdev);
323 u64 addr;
324 int idx;
325
326 if ((bar & 7) != bar)
327 return NULL;
328
329 idx = zdev->bars[bar].map_idx;
330 spin_lock(&zpci_iomap_lock);
331 zpci_iomap_start[idx].fh = zdev->fh;
332 zpci_iomap_start[idx].bar = bar;
333 spin_unlock(&zpci_iomap_lock);
334
335 addr = ZPCI_IOMAP_ADDR_BASE | ((u64) idx << 48);
336 return (void __iomem *) addr;
337}
338EXPORT_SYMBOL_GPL(pci_iomap);
339
340void pci_iounmap(struct pci_dev *pdev, void __iomem *addr)
341{
342 unsigned int idx;
343
344 idx = (((__force u64) addr) & ~ZPCI_IOMAP_ADDR_BASE) >> 48;
345 spin_lock(&zpci_iomap_lock);
346 zpci_iomap_start[idx].fh = 0;
347 zpci_iomap_start[idx].bar = 0;
348 spin_unlock(&zpci_iomap_lock);
349}
350EXPORT_SYMBOL_GPL(pci_iounmap);
351
352static int pci_read(struct pci_bus *bus, unsigned int devfn, int where,
353 int size, u32 *val)
354{
355 struct zpci_dev *zdev = get_zdev_by_bus(bus);
Sebastian Ott2c3700b2013-04-16 14:18:41 +0200356 int ret;
Jan Glaubercd248342012-11-29 12:50:30 +0100357
358 if (!zdev || devfn != ZPCI_DEVFN)
Sebastian Ott2c3700b2013-04-16 14:18:41 +0200359 ret = -ENODEV;
360 else
361 ret = zpci_cfg_load(zdev, where, val, size);
362
363 return ret;
Jan Glaubercd248342012-11-29 12:50:30 +0100364}
365
366static int pci_write(struct pci_bus *bus, unsigned int devfn, int where,
367 int size, u32 val)
368{
369 struct zpci_dev *zdev = get_zdev_by_bus(bus);
Sebastian Ott2c3700b2013-04-16 14:18:41 +0200370 int ret;
Jan Glaubercd248342012-11-29 12:50:30 +0100371
372 if (!zdev || devfn != ZPCI_DEVFN)
Sebastian Ott2c3700b2013-04-16 14:18:41 +0200373 ret = -ENODEV;
374 else
375 ret = zpci_cfg_store(zdev, where, val, size);
376
377 return ret;
Jan Glaubercd248342012-11-29 12:50:30 +0100378}
379
380static struct pci_ops pci_root_ops = {
381 .read = pci_read,
382 .write = pci_write,
383};
384
Martin Schwidefskyf4eae942013-06-24 10:30:41 +0200385static void zpci_irq_handler(struct airq_struct *airq)
Jan Glauber9a4da8a2012-11-29 13:05:05 +0100386{
Martin Schwidefsky5d0d8f42013-06-25 16:36:29 +0200387 unsigned long si, ai;
Jan Glauber9a4da8a2012-11-29 13:05:05 +0100388 struct zdev_irq_map *imap;
Martin Schwidefsky5d0d8f42013-06-25 16:36:29 +0200389 int irqs_on = 0;
Jan Glauber9a4da8a2012-11-29 13:05:05 +0100390
Heiko Carstens420f42e2013-01-02 15:18:18 +0100391 inc_irq_stat(IRQIO_PCI);
Martin Schwidefsky5d0d8f42013-06-25 16:36:29 +0200392 for (si = 0;;) {
393 /* Scan adapter summary indicator bit vector */
394 si = airq_iv_scan(zpci_aisb_iv, si, airq_iv_end(zpci_aisb_iv));
395 if (si == -1UL) {
396 if (irqs_on++)
397 /* End of second scan with interrupts on. */
398 break;
399 /* First scan complete, reenable interrupts. */
400 zpci_set_irq_ctrl(SIC_IRQ_MODE_SINGLE, NULL, PCI_ISC);
401 si = 0;
402 continue;
403 }
Jan Glauber9a4da8a2012-11-29 13:05:05 +0100404
Martin Schwidefsky5d0d8f42013-06-25 16:36:29 +0200405 /* Scan the adapter interrupt vector for this device. */
406 imap = zpci_imap[si];
407 for (ai = 0;;) {
408 ai = airq_iv_scan(imap->aibv, ai, imap->msi_vecs);
409 if (ai == -1UL)
410 break;
Heiko Carstens420f42e2013-01-02 15:18:18 +0100411 inc_irq_stat(IRQIO_MSI);
Martin Schwidefsky5d0d8f42013-06-25 16:36:29 +0200412 airq_iv_lock(imap->aibv, ai);
413 if (imap->cb[ai].handler)
414 imap->cb[ai].handler(ai, imap->cb[ai].data);
415 airq_iv_unlock(imap->aibv, ai);
Jan Glauber9a4da8a2012-11-29 13:05:05 +0100416 }
417 }
Jan Glauber9a4da8a2012-11-29 13:05:05 +0100418}
419
Martin Schwidefsky5d0d8f42013-06-25 16:36:29 +0200420static int zpci_alloc_msi(struct zpci_dev *zdev, int msi_vecs)
421{
422 unsigned long size;
423
424 /* Alloc aibv & callback space */
425 zdev->irq_map = kmem_cache_zalloc(zdev_irq_cache, GFP_KERNEL);
426 if (!zdev->irq_map)
427 goto out;
428 /* Store the number of used MSI vectors */
429 zdev->irq_map->msi_vecs = msi_vecs;
430 /* Allocate callback array */
431 size = sizeof(struct callback) * msi_vecs;
432 zdev->irq_map->cb = kzalloc(size, GFP_KERNEL);
433 if (!zdev->irq_map->cb)
434 goto out_map;
435 /* Allocate msi_map array */
436 size = sizeof(struct msi_map) * msi_vecs;
437 zdev->msi_map = kzalloc(size, GFP_KERNEL);
438 if (!zdev->msi_map)
439 goto out_cb;
440 return 0;
441
442out_cb:
443 kfree(zdev->irq_map->cb);
444out_map:
445 kmem_cache_free(zdev_irq_cache, zdev->irq_map);
446out:
447 return -ENOMEM;
448}
449
450static void zpci_free_msi(struct zpci_dev *zdev)
451{
452 kfree(zdev->msi_map);
453 kfree(zdev->irq_map->cb);
454 kmem_cache_free(zdev_irq_cache, zdev->irq_map);
455}
456
457int arch_setup_msi_irqs(struct pci_dev *pdev, int nvec, int type)
Jan Glauber9a4da8a2012-11-29 13:05:05 +0100458{
459 struct zpci_dev *zdev = get_zdev(pdev);
Martin Schwidefsky5d0d8f42013-06-25 16:36:29 +0200460 unsigned int msi_nr, msi_vecs;
461 unsigned long aisb;
Jan Glauber9a4da8a2012-11-29 13:05:05 +0100462 struct msi_desc *msi;
463 int rc;
464
Martin Schwidefsky5d0d8f42013-06-25 16:36:29 +0200465 pr_debug("%s: requesting %d MSI-X interrupts...", __func__, nvec);
466 if (type != PCI_CAP_ID_MSIX && type != PCI_CAP_ID_MSI)
467 return -EINVAL;
468 msi_vecs = min(nvec, ZPCI_MSI_VEC_MAX);
Jan Glauber9a4da8a2012-11-29 13:05:05 +0100469
Martin Schwidefsky5d0d8f42013-06-25 16:36:29 +0200470 /* Allocate adapter summary indicator bit */
471 rc = -EIO;
472 aisb = airq_iv_alloc_bit(zpci_aisb_iv);
473 if (aisb == -1UL)
474 goto out;
Jan Glauber9a4da8a2012-11-29 13:05:05 +0100475 zdev->aisb = aisb;
Jan Glauber9a4da8a2012-11-29 13:05:05 +0100476
Martin Schwidefsky5d0d8f42013-06-25 16:36:29 +0200477 /* Create adapter interrupt vector */
478 rc = -ENOMEM;
479 zdev->aibv = airq_iv_create(msi_vecs, AIRQ_IV_BITLOCK);
480 if (!zdev->aibv)
481 goto out_si;
Jan Glauber9a4da8a2012-11-29 13:05:05 +0100482
Martin Schwidefsky5d0d8f42013-06-25 16:36:29 +0200483 /* Allocate data structures for msi interrupts */
484 rc = zpci_alloc_msi(zdev, msi_vecs);
485 if (rc)
486 goto out_iv;
487
488 /* Wire up shortcut pointer */
489 zpci_imap[aisb] = zdev->irq_map;
490 zdev->irq_map->aibv = zdev->aibv;
491
492 /*
493 * TODO: irq number 0 wont be found if we return less than the
494 * requested MSIs. Ignore it for now and fix in common code.
Jan Glauber9a4da8a2012-11-29 13:05:05 +0100495 */
496 msi_nr = aisb << ZPCI_MSI_VEC_BITS;
Jan Glauber9a4da8a2012-11-29 13:05:05 +0100497 list_for_each_entry(msi, &pdev->msi_list, list) {
498 rc = zpci_setup_msi_irq(zdev, msi, msi_nr,
499 aisb << ZPCI_MSI_VEC_BITS);
500 if (rc)
Martin Schwidefsky5d0d8f42013-06-25 16:36:29 +0200501 goto out_msi;
Jan Glauber9a4da8a2012-11-29 13:05:05 +0100502 msi_nr++;
503 }
504
Martin Schwidefsky5d0d8f42013-06-25 16:36:29 +0200505 /* Enable adapter interrupts */
506 rc = zpci_set_airq(zdev);
507 if (rc)
508 goto out_msi;
509
510 return (msi_vecs == nvec) ? 0 : msi_vecs;
511
512out_msi:
513 msi_nr -= aisb << ZPCI_MSI_VEC_BITS;
514 list_for_each_entry(msi, &pdev->msi_list, list) {
515 if (msi_nr-- == 0)
516 break;
517 zpci_teardown_msi_irq(zdev, msi);
Jan Glauber9a4da8a2012-11-29 13:05:05 +0100518 }
Martin Schwidefsky5d0d8f42013-06-25 16:36:29 +0200519 zpci_free_msi(zdev);
520out_iv:
521 airq_iv_release(zdev->aibv);
522out_si:
523 airq_iv_free_bit(zpci_aisb_iv, aisb);
524out:
525 dev_err(&pdev->dev, "register MSI failed with: %d\n", rc);
526 return rc;
Jan Glauber9a4da8a2012-11-29 13:05:05 +0100527}
528
Martin Schwidefsky5d0d8f42013-06-25 16:36:29 +0200529void arch_teardown_msi_irqs(struct pci_dev *pdev)
Jan Glauber9a4da8a2012-11-29 13:05:05 +0100530{
531 struct zpci_dev *zdev = get_zdev(pdev);
532 struct msi_desc *msi;
Martin Schwidefsky5d0d8f42013-06-25 16:36:29 +0200533 int rc;
Jan Glauber9a4da8a2012-11-29 13:05:05 +0100534
Martin Schwidefsky5d0d8f42013-06-25 16:36:29 +0200535 pr_info("%s: on pdev: %p\n", __func__, pdev);
536
537 /* Disable adapter interrupts */
538 rc = zpci_clear_airq(zdev);
Jan Glauber9a4da8a2012-11-29 13:05:05 +0100539 if (rc) {
540 dev_err(&pdev->dev, "deregister MSI failed with: %d\n", rc);
541 return;
542 }
543
Jan Glauber9a4da8a2012-11-29 13:05:05 +0100544 list_for_each_entry(msi, &pdev->msi_list, list)
545 zpci_teardown_msi_irq(zdev, msi);
546
Martin Schwidefsky5d0d8f42013-06-25 16:36:29 +0200547 zpci_free_msi(zdev);
548 airq_iv_release(zdev->aibv);
549 airq_iv_free_bit(zpci_aisb_iv, zdev->aisb);
Jan Glauber9a4da8a2012-11-29 13:05:05 +0100550}
551
Jan Glaubercd248342012-11-29 12:50:30 +0100552static void zpci_map_resources(struct zpci_dev *zdev)
553{
554 struct pci_dev *pdev = zdev->pdev;
555 resource_size_t len;
556 int i;
557
558 for (i = 0; i < PCI_BAR_COUNT; i++) {
559 len = pci_resource_len(pdev, i);
560 if (!len)
561 continue;
562 pdev->resource[i].start = (resource_size_t) pci_iomap(pdev, i, 0);
563 pdev->resource[i].end = pdev->resource[i].start + len - 1;
564 pr_debug("BAR%i: -> start: %Lx end: %Lx\n",
565 i, pdev->resource[i].start, pdev->resource[i].end);
566 }
Sebastian Ott944239c2013-06-05 16:06:16 +0200567}
568
569static void zpci_unmap_resources(struct zpci_dev *zdev)
570{
571 struct pci_dev *pdev = zdev->pdev;
572 resource_size_t len;
573 int i;
574
575 for (i = 0; i < PCI_BAR_COUNT; i++) {
576 len = pci_resource_len(pdev, i);
577 if (!len)
578 continue;
579 pci_iounmap(pdev, (void *) pdev->resource[i].start);
580 }
581}
Jan Glaubercd248342012-11-29 12:50:30 +0100582
Jan Glaubercd248342012-11-29 12:50:30 +0100583struct zpci_dev *zpci_alloc_device(void)
584{
585 struct zpci_dev *zdev;
586
587 /* Alloc memory for our private pci device data */
588 zdev = kzalloc(sizeof(*zdev), GFP_KERNEL);
Martin Schwidefsky5d0d8f42013-06-25 16:36:29 +0200589 return zdev ? : ERR_PTR(-ENOMEM);
Jan Glaubercd248342012-11-29 12:50:30 +0100590}
591
592void zpci_free_device(struct zpci_dev *zdev)
593{
594 kfree(zdev);
595}
596
Jan Glaubercd248342012-11-29 12:50:30 +0100597/*
598 * Too late for any s390 specific setup, since interrupts must be set up
599 * already which requires DMA setup too and the pci scan will access the
600 * config space, which only works if the function handle is enabled.
601 */
602int pcibios_enable_device(struct pci_dev *pdev, int mask)
603{
604 struct resource *res;
605 u16 cmd;
606 int i;
607
608 pci_read_config_word(pdev, PCI_COMMAND, &cmd);
609
610 for (i = 0; i < PCI_BAR_COUNT; i++) {
611 res = &pdev->resource[i];
612
613 if (res->flags & IORESOURCE_IO)
614 return -EINVAL;
615
616 if (res->flags & IORESOURCE_MEM)
617 cmd |= PCI_COMMAND_MEMORY;
618 }
619 pci_write_config_word(pdev, PCI_COMMAND, cmd);
620 return 0;
621}
622
Jan Glauber1e8da952012-11-29 14:36:55 +0100623int pcibios_add_platform_entries(struct pci_dev *pdev)
624{
625 return zpci_sysfs_add_device(&pdev->dev);
626}
627
Jan Glauber9a4da8a2012-11-29 13:05:05 +0100628int zpci_request_irq(unsigned int irq, irq_handler_t handler, void *data)
629{
Martin Schwidefsky5d0d8f42013-06-25 16:36:29 +0200630 unsigned int msi_nr = irq_to_msi_nr(irq);
631 unsigned int dev_nr = irq_to_dev_nr(irq);
Jan Glauber9a4da8a2012-11-29 13:05:05 +0100632 struct zdev_irq_map *imap;
633 struct msi_desc *msi;
634
635 msi = irq_get_msi_desc(irq);
636 if (!msi)
637 return -EIO;
638
Martin Schwidefsky5d0d8f42013-06-25 16:36:29 +0200639 imap = zpci_imap[dev_nr];
Jan Glauber9a4da8a2012-11-29 13:05:05 +0100640 imap->cb[msi_nr].handler = handler;
641 imap->cb[msi_nr].data = data;
642
643 /*
644 * The generic MSI code returns with the interrupt disabled on the
645 * card, using the MSI mask bits. Firmware doesn't appear to unmask
646 * at that level, so we do it here by hand.
647 */
648 zpci_msi_set_mask_bits(msi, 1, 0);
649 return 0;
650}
651
652void zpci_free_irq(unsigned int irq)
653{
Martin Schwidefsky5d0d8f42013-06-25 16:36:29 +0200654 unsigned int msi_nr = irq_to_msi_nr(irq);
655 unsigned int dev_nr = irq_to_dev_nr(irq);
656 struct zdev_irq_map *imap;
657 struct msi_desc *msi;
Jan Glauber9a4da8a2012-11-29 13:05:05 +0100658
Martin Schwidefsky5d0d8f42013-06-25 16:36:29 +0200659 /* Disable interrupt */
660 msi = irq_get_msi_desc(irq);
661 if (!msi)
662 return;
663 zpci_msi_set_mask_bits(msi, 1, 1);
664 imap = zpci_imap[dev_nr];
Jan Glauber9a4da8a2012-11-29 13:05:05 +0100665 imap->cb[msi_nr].handler = NULL;
666 imap->cb[msi_nr].data = NULL;
Martin Schwidefsky5d0d8f42013-06-25 16:36:29 +0200667 synchronize_rcu();
Jan Glauber9a4da8a2012-11-29 13:05:05 +0100668}
669
670int request_irq(unsigned int irq, irq_handler_t handler,
671 unsigned long irqflags, const char *devname, void *dev_id)
672{
Jan Glauber9a4da8a2012-11-29 13:05:05 +0100673 return zpci_request_irq(irq, handler, dev_id);
674}
675EXPORT_SYMBOL_GPL(request_irq);
676
677void free_irq(unsigned int irq, void *dev_id)
678{
679 zpci_free_irq(irq);
680}
681EXPORT_SYMBOL_GPL(free_irq);
682
683static int __init zpci_irq_init(void)
684{
Martin Schwidefsky5d0d8f42013-06-25 16:36:29 +0200685 int rc;
Jan Glauber9a4da8a2012-11-29 13:05:05 +0100686
Martin Schwidefskyf4eae942013-06-24 10:30:41 +0200687 rc = register_adapter_interrupt(&zpci_airq);
688 if (rc)
Martin Schwidefsky5d0d8f42013-06-25 16:36:29 +0200689 goto out;
Martin Schwidefskyf4eae942013-06-24 10:30:41 +0200690 /* Set summary to 1 to be called every time for the ISC. */
691 *zpci_airq.lsi_ptr = 1;
Jan Glauber9a4da8a2012-11-29 13:05:05 +0100692
Martin Schwidefsky5d0d8f42013-06-25 16:36:29 +0200693 rc = -ENOMEM;
694 zpci_aisb_iv = airq_iv_create(ZPCI_NR_DEVICES, AIRQ_IV_ALLOC);
695 if (!zpci_aisb_iv)
696 goto out_airq;
Jan Glauber9a4da8a2012-11-29 13:05:05 +0100697
Martin Schwidefsky93893392013-06-25 14:52:23 +0200698 zpci_set_irq_ctrl(SIC_IRQ_MODE_SINGLE, NULL, PCI_ISC);
Jan Glauber9a4da8a2012-11-29 13:05:05 +0100699 return 0;
700
Martin Schwidefsky5d0d8f42013-06-25 16:36:29 +0200701out_airq:
702 unregister_adapter_interrupt(&zpci_airq);
703out:
Jan Glauber9a4da8a2012-11-29 13:05:05 +0100704 return rc;
705}
706
707static void zpci_irq_exit(void)
708{
Martin Schwidefsky5d0d8f42013-06-25 16:36:29 +0200709 airq_iv_release(zpci_aisb_iv);
Martin Schwidefskyf4eae942013-06-24 10:30:41 +0200710 unregister_adapter_interrupt(&zpci_airq);
Jan Glauber9a4da8a2012-11-29 13:05:05 +0100711}
712
Jan Glaubercd248342012-11-29 12:50:30 +0100713static struct resource *zpci_alloc_bus_resource(unsigned long start, unsigned long size,
714 unsigned long flags, int domain)
715{
716 struct resource *r;
717 char *name;
718 int rc;
719
720 r = kzalloc(sizeof(*r), GFP_KERNEL);
721 if (!r)
722 return ERR_PTR(-ENOMEM);
723 r->start = start;
724 r->end = r->start + size - 1;
725 r->flags = flags;
726 r->parent = &iomem_resource;
727 name = kmalloc(18, GFP_KERNEL);
728 if (!name) {
729 kfree(r);
730 return ERR_PTR(-ENOMEM);
731 }
732 sprintf(name, "PCI Bus: %04x:%02x", domain, ZPCI_BUS_NR);
733 r->name = name;
734
735 rc = request_resource(&iomem_resource, r);
736 if (rc)
737 pr_debug("request resource %pR failed\n", r);
738 return r;
739}
740
741static int zpci_alloc_iomap(struct zpci_dev *zdev)
742{
743 int entry;
744
745 spin_lock(&zpci_iomap_lock);
746 entry = find_first_zero_bit(zpci_iomap, ZPCI_IOMAP_MAX_ENTRIES);
747 if (entry == ZPCI_IOMAP_MAX_ENTRIES) {
748 spin_unlock(&zpci_iomap_lock);
749 return -ENOSPC;
750 }
751 set_bit(entry, zpci_iomap);
752 spin_unlock(&zpci_iomap_lock);
753 return entry;
754}
755
756static void zpci_free_iomap(struct zpci_dev *zdev, int entry)
757{
758 spin_lock(&zpci_iomap_lock);
759 memset(&zpci_iomap_start[entry], 0, sizeof(struct zpci_iomap_entry));
760 clear_bit(entry, zpci_iomap);
761 spin_unlock(&zpci_iomap_lock);
762}
763
Sebastian Ottaf0a8a82013-04-16 14:13:21 +0200764int pcibios_add_device(struct pci_dev *pdev)
765{
766 struct zpci_dev *zdev = get_zdev(pdev);
767
Sebastian Ott1c213512013-04-25 14:49:48 +0200768 zdev->pdev = pdev;
Sebastian Ottaf0a8a82013-04-16 14:13:21 +0200769 zpci_debug_init_device(zdev);
770 zpci_fmb_enable_device(zdev);
771 zpci_map_resources(zdev);
772
773 return 0;
774}
775
Sebastian Ott944239c2013-06-05 16:06:16 +0200776void pcibios_release_device(struct pci_dev *pdev)
777{
778 struct zpci_dev *zdev = get_zdev(pdev);
779
780 zpci_unmap_resources(zdev);
781 zpci_fmb_disable_device(zdev);
782 zpci_debug_exit_device(zdev);
783 zdev->pdev = NULL;
784}
785
Sebastian Ott1c213512013-04-25 14:49:48 +0200786static int zpci_scan_bus(struct zpci_dev *zdev)
Jan Glaubercd248342012-11-29 12:50:30 +0100787{
788 struct resource *res;
789 LIST_HEAD(resources);
790 int i;
791
792 /* allocate mapping entry for each used bar */
793 for (i = 0; i < PCI_BAR_COUNT; i++) {
794 unsigned long addr, size, flags;
795 int entry;
796
797 if (!zdev->bars[i].size)
798 continue;
799 entry = zpci_alloc_iomap(zdev);
800 if (entry < 0)
801 return entry;
802 zdev->bars[i].map_idx = entry;
803
804 /* only MMIO is supported */
805 flags = IORESOURCE_MEM;
806 if (zdev->bars[i].val & 8)
807 flags |= IORESOURCE_PREFETCH;
808 if (zdev->bars[i].val & 4)
809 flags |= IORESOURCE_MEM_64;
810
811 addr = ZPCI_IOMAP_ADDR_BASE + ((u64) entry << 48);
812
813 size = 1UL << zdev->bars[i].size;
814
815 res = zpci_alloc_bus_resource(addr, size, flags, zdev->domain);
816 if (IS_ERR(res)) {
817 zpci_free_iomap(zdev, entry);
818 return PTR_ERR(res);
819 }
820 pci_add_resource(&resources, res);
821 }
822
Sebastian Ott1c213512013-04-25 14:49:48 +0200823 zdev->bus = pci_scan_root_bus(NULL, ZPCI_BUS_NR, &pci_root_ops,
824 zdev, &resources);
Jan Glaubercd248342012-11-29 12:50:30 +0100825 if (!zdev->bus)
826 return -EIO;
827
828 zdev->bus->max_bus_speed = zdev->max_bus_speed;
829 return 0;
830}
831
832static int zpci_alloc_domain(struct zpci_dev *zdev)
833{
834 spin_lock(&zpci_domain_lock);
835 zdev->domain = find_first_zero_bit(zpci_domain, ZPCI_NR_DEVICES);
836 if (zdev->domain == ZPCI_NR_DEVICES) {
837 spin_unlock(&zpci_domain_lock);
838 return -ENOSPC;
839 }
840 set_bit(zdev->domain, zpci_domain);
841 spin_unlock(&zpci_domain_lock);
842 return 0;
843}
844
845static void zpci_free_domain(struct zpci_dev *zdev)
846{
847 spin_lock(&zpci_domain_lock);
848 clear_bit(zdev->domain, zpci_domain);
849 spin_unlock(&zpci_domain_lock);
850}
851
Jan Glaubera755a452012-11-29 12:55:21 +0100852int zpci_enable_device(struct zpci_dev *zdev)
853{
854 int rc;
855
856 rc = clp_enable_fh(zdev, ZPCI_NR_DMA_SPACES);
857 if (rc)
858 goto out;
859 pr_info("Enabled fh: 0x%x fid: 0x%x\n", zdev->fh, zdev->fid);
Jan Glauber828b35f2012-11-29 14:33:30 +0100860
861 rc = zpci_dma_init_device(zdev);
862 if (rc)
863 goto out_dma;
Jan Glaubera755a452012-11-29 12:55:21 +0100864 return 0;
Jan Glauber828b35f2012-11-29 14:33:30 +0100865
866out_dma:
867 clp_disable_fh(zdev);
Jan Glaubera755a452012-11-29 12:55:21 +0100868out:
869 return rc;
870}
871EXPORT_SYMBOL_GPL(zpci_enable_device);
872
Sebastian Ottcb65a662013-04-16 14:12:17 +0200873int zpci_disable_device(struct zpci_dev *zdev)
874{
875 zpci_dma_exit_device(zdev);
876 return clp_disable_fh(zdev);
877}
878EXPORT_SYMBOL_GPL(zpci_disable_device);
879
Jan Glaubercd248342012-11-29 12:50:30 +0100880int zpci_create_device(struct zpci_dev *zdev)
881{
882 int rc;
883
884 rc = zpci_alloc_domain(zdev);
885 if (rc)
886 goto out;
887
Sebastian Ott1c213512013-04-25 14:49:48 +0200888 if (zdev->state == ZPCI_FN_STATE_CONFIGURED) {
889 rc = zpci_enable_device(zdev);
890 if (rc)
891 goto out_free;
892
893 zdev->state = ZPCI_FN_STATE_ONLINE;
894 }
895 rc = zpci_scan_bus(zdev);
Jan Glaubercd248342012-11-29 12:50:30 +0100896 if (rc)
Sebastian Ott1c213512013-04-25 14:49:48 +0200897 goto out_disable;
Jan Glaubercd248342012-11-29 12:50:30 +0100898
899 mutex_lock(&zpci_list_lock);
900 list_add_tail(&zdev->entry, &zpci_list);
Sebastian Ott53923352013-01-31 19:55:17 +0100901 if (hotplug_ops)
902 hotplug_ops->create_slot(zdev);
Jan Glaubercd248342012-11-29 12:50:30 +0100903 mutex_unlock(&zpci_list_lock);
904
Jan Glaubercd248342012-11-29 12:50:30 +0100905 return 0;
906
Sebastian Ott1c213512013-04-25 14:49:48 +0200907out_disable:
908 if (zdev->state == ZPCI_FN_STATE_ONLINE)
909 zpci_disable_device(zdev);
910out_free:
Jan Glaubercd248342012-11-29 12:50:30 +0100911 zpci_free_domain(zdev);
912out:
913 return rc;
914}
915
916void zpci_stop_device(struct zpci_dev *zdev)
917{
Jan Glauber828b35f2012-11-29 14:33:30 +0100918 zpci_dma_exit_device(zdev);
Jan Glaubercd248342012-11-29 12:50:30 +0100919 /*
920 * Note: SCLP disables fh via set-pci-fn so don't
921 * do that here.
922 */
923}
924EXPORT_SYMBOL_GPL(zpci_stop_device);
925
Jan Glaubercd248342012-11-29 12:50:30 +0100926static inline int barsize(u8 size)
927{
928 return (size) ? (1 << size) >> 10 : 0;
929}
930
931static int zpci_mem_init(void)
932{
Jan Glauber9a4da8a2012-11-29 13:05:05 +0100933 zdev_irq_cache = kmem_cache_create("PCI_IRQ_cache", sizeof(struct zdev_irq_map),
934 L1_CACHE_BYTES, SLAB_HWCACHE_ALIGN, NULL);
935 if (!zdev_irq_cache)
936 goto error_zdev;
937
Jan Glauberd0b08852012-12-11 14:53:35 +0100938 zdev_fmb_cache = kmem_cache_create("PCI_FMB_cache", sizeof(struct zpci_fmb),
939 16, 0, NULL);
940 if (!zdev_fmb_cache)
941 goto error_fmb;
942
Jan Glaubercd248342012-11-29 12:50:30 +0100943 /* TODO: use realloc */
944 zpci_iomap_start = kzalloc(ZPCI_IOMAP_MAX_ENTRIES * sizeof(*zpci_iomap_start),
945 GFP_KERNEL);
946 if (!zpci_iomap_start)
Jan Glauber9a4da8a2012-11-29 13:05:05 +0100947 goto error_iomap;
Jan Glaubercd248342012-11-29 12:50:30 +0100948 return 0;
949
Jan Glauber9a4da8a2012-11-29 13:05:05 +0100950error_iomap:
Jan Glauberd0b08852012-12-11 14:53:35 +0100951 kmem_cache_destroy(zdev_fmb_cache);
952error_fmb:
Jan Glauber9a4da8a2012-11-29 13:05:05 +0100953 kmem_cache_destroy(zdev_irq_cache);
Jan Glaubercd248342012-11-29 12:50:30 +0100954error_zdev:
955 return -ENOMEM;
956}
957
958static void zpci_mem_exit(void)
959{
960 kfree(zpci_iomap_start);
Jan Glauber9a4da8a2012-11-29 13:05:05 +0100961 kmem_cache_destroy(zdev_irq_cache);
Jan Glauberd0b08852012-12-11 14:53:35 +0100962 kmem_cache_destroy(zdev_fmb_cache);
Jan Glaubercd248342012-11-29 12:50:30 +0100963}
964
Sebastian Ott53923352013-01-31 19:55:17 +0100965void zpci_register_hp_ops(struct pci_hp_callback_ops *ops)
966{
967 mutex_lock(&zpci_list_lock);
968 hotplug_ops = ops;
969 mutex_unlock(&zpci_list_lock);
970}
971EXPORT_SYMBOL_GPL(zpci_register_hp_ops);
972
973void zpci_deregister_hp_ops(void)
974{
975 mutex_lock(&zpci_list_lock);
976 hotplug_ops = NULL;
977 mutex_unlock(&zpci_list_lock);
978}
979EXPORT_SYMBOL_GPL(zpci_deregister_hp_ops);
980
Sebastian Ott89b0dc952013-04-16 14:19:22 +0200981unsigned int s390_pci_probe;
Heiko Carstens1e5635d2013-01-30 15:52:16 +0100982EXPORT_SYMBOL_GPL(s390_pci_probe);
Jan Glaubercd248342012-11-29 12:50:30 +0100983
984char * __init pcibios_setup(char *str)
985{
Sebastian Ott89b0dc952013-04-16 14:19:22 +0200986 if (!strcmp(str, "on")) {
987 s390_pci_probe = 1;
Jan Glaubercd248342012-11-29 12:50:30 +0100988 return NULL;
989 }
990 return str;
991}
992
993static int __init pci_base_init(void)
994{
995 int rc;
996
Heiko Carstens1e5635d2013-01-30 15:52:16 +0100997 if (!s390_pci_probe)
Jan Glaubercd248342012-11-29 12:50:30 +0100998 return 0;
999
1000 if (!test_facility(2) || !test_facility(69)
1001 || !test_facility(71) || !test_facility(72))
1002 return 0;
1003
1004 pr_info("Probing PCI hardware: PCI:%d SID:%d AEN:%d\n",
1005 test_facility(69), test_facility(70),
1006 test_facility(71));
1007
Jan Glauberd0b08852012-12-11 14:53:35 +01001008 rc = zpci_debug_init();
1009 if (rc)
1010 return rc;
1011
Jan Glaubercd248342012-11-29 12:50:30 +01001012 rc = zpci_mem_init();
1013 if (rc)
1014 goto out_mem;
1015
Jan Glauber9a4da8a2012-11-29 13:05:05 +01001016 rc = zpci_msihash_init();
1017 if (rc)
1018 goto out_hash;
1019
1020 rc = zpci_irq_init();
1021 if (rc)
1022 goto out_irq;
1023
Jan Glauber828b35f2012-11-29 14:33:30 +01001024 rc = zpci_dma_init();
1025 if (rc)
1026 goto out_dma;
1027
Jan Glaubera755a452012-11-29 12:55:21 +01001028 rc = clp_find_pci_devices();
1029 if (rc)
1030 goto out_find;
1031
Jan Glaubercd248342012-11-29 12:50:30 +01001032 return 0;
1033
Jan Glaubera755a452012-11-29 12:55:21 +01001034out_find:
Jan Glauber828b35f2012-11-29 14:33:30 +01001035 zpci_dma_exit();
1036out_dma:
Jan Glauber9a4da8a2012-11-29 13:05:05 +01001037 zpci_irq_exit();
1038out_irq:
1039 zpci_msihash_exit();
1040out_hash:
Jan Glaubercd248342012-11-29 12:50:30 +01001041 zpci_mem_exit();
1042out_mem:
Jan Glauberd0b08852012-12-11 14:53:35 +01001043 zpci_debug_exit();
Jan Glaubercd248342012-11-29 12:50:30 +01001044 return rc;
1045}
1046subsys_initcall(pci_base_init);