xref: /linux/arch/s390/pci/pci.c (revision d0b0885316ab7a97cc8a19027905de3ff7bd1e79)
1cd248341SJan Glauber /*
2cd248341SJan Glauber  * Copyright IBM Corp. 2012
3cd248341SJan Glauber  *
4cd248341SJan Glauber  * Author(s):
5cd248341SJan Glauber  *   Jan Glauber <jang@linux.vnet.ibm.com>
6cd248341SJan Glauber  *
7cd248341SJan Glauber  * The System z PCI code is a rewrite from a prototype by
8cd248341SJan Glauber  * the following people (Kudoz!):
9bedef755SJan Glauber  *   Alexander Schmidt
10bedef755SJan Glauber  *   Christoph Raisch
11bedef755SJan Glauber  *   Hannes Hering
12bedef755SJan Glauber  *   Hoang-Nam Nguyen
13bedef755SJan Glauber  *   Jan-Bernd Themann
14bedef755SJan Glauber  *   Stefan Roscher
15bedef755SJan Glauber  *   Thomas Klein
16cd248341SJan Glauber  */
17cd248341SJan Glauber 
18cd248341SJan Glauber #define COMPONENT "zPCI"
19cd248341SJan Glauber #define pr_fmt(fmt) COMPONENT ": " fmt
20cd248341SJan Glauber 
21cd248341SJan Glauber #include <linux/kernel.h>
22cd248341SJan Glauber #include <linux/slab.h>
23cd248341SJan Glauber #include <linux/err.h>
24cd248341SJan Glauber #include <linux/export.h>
25cd248341SJan Glauber #include <linux/delay.h>
269a4da8a5SJan Glauber #include <linux/irq.h>
279a4da8a5SJan Glauber #include <linux/kernel_stat.h>
28cd248341SJan Glauber #include <linux/seq_file.h>
29cd248341SJan Glauber #include <linux/pci.h>
30cd248341SJan Glauber #include <linux/msi.h>
31cd248341SJan Glauber 
329a4da8a5SJan Glauber #include <asm/isc.h>
339a4da8a5SJan Glauber #include <asm/airq.h>
34cd248341SJan Glauber #include <asm/facility.h>
35cd248341SJan Glauber #include <asm/pci_insn.h>
36a755a45dSJan Glauber #include <asm/pci_clp.h>
37828b35f6SJan Glauber #include <asm/pci_dma.h>
38cd248341SJan Glauber 
39cd248341SJan Glauber #define DEBUG				/* enable pr_debug */
40cd248341SJan Glauber 
419a4da8a5SJan Glauber #define	SIC_IRQ_MODE_ALL		0
429a4da8a5SJan Glauber #define	SIC_IRQ_MODE_SINGLE		1
439a4da8a5SJan Glauber 
44cd248341SJan Glauber #define ZPCI_NR_DMA_SPACES		1
459a4da8a5SJan Glauber #define ZPCI_MSI_VEC_BITS		6
46cd248341SJan Glauber #define ZPCI_NR_DEVICES			CONFIG_PCI_NR_FUNCTIONS
47cd248341SJan Glauber 
48cd248341SJan Glauber /* list of all detected zpci devices */
49cd248341SJan Glauber LIST_HEAD(zpci_list);
507441b062SJan Glauber EXPORT_SYMBOL_GPL(zpci_list);
51cd248341SJan Glauber DEFINE_MUTEX(zpci_list_lock);
527441b062SJan Glauber EXPORT_SYMBOL_GPL(zpci_list_lock);
537441b062SJan Glauber 
547441b062SJan Glauber struct pci_hp_callback_ops hotplug_ops;
557441b062SJan Glauber EXPORT_SYMBOL_GPL(hotplug_ops);
56cd248341SJan Glauber 
57cd248341SJan Glauber static DECLARE_BITMAP(zpci_domain, ZPCI_NR_DEVICES);
58cd248341SJan Glauber static DEFINE_SPINLOCK(zpci_domain_lock);
59cd248341SJan Glauber 
609a4da8a5SJan Glauber struct callback {
619a4da8a5SJan Glauber 	irq_handler_t	handler;
629a4da8a5SJan Glauber 	void		*data;
639a4da8a5SJan Glauber };
649a4da8a5SJan Glauber 
659a4da8a5SJan Glauber struct zdev_irq_map {
669a4da8a5SJan Glauber 	unsigned long	aibv;		/* AI bit vector */
679a4da8a5SJan Glauber 	int		msi_vecs;	/* consecutive MSI-vectors used */
689a4da8a5SJan Glauber 	int		__unused;
699a4da8a5SJan Glauber 	struct callback	cb[ZPCI_NR_MSI_VECS]; /* callback handler array */
709a4da8a5SJan Glauber 	spinlock_t	lock;		/* protect callbacks against de-reg */
719a4da8a5SJan Glauber };
729a4da8a5SJan Glauber 
739a4da8a5SJan Glauber struct intr_bucket {
749a4da8a5SJan Glauber 	/* amap of adapters, one bit per dev, corresponds to one irq nr */
759a4da8a5SJan Glauber 	unsigned long	*alloc;
769a4da8a5SJan Glauber 	/* AI summary bit, global page for all devices */
779a4da8a5SJan Glauber 	unsigned long	*aisb;
789a4da8a5SJan Glauber 	/* pointer to aibv and callback data in zdev */
799a4da8a5SJan Glauber 	struct zdev_irq_map *imap[ZPCI_NR_DEVICES];
809a4da8a5SJan Glauber 	/* protects the whole bucket struct */
819a4da8a5SJan Glauber 	spinlock_t	lock;
829a4da8a5SJan Glauber };
839a4da8a5SJan Glauber 
849a4da8a5SJan Glauber static struct intr_bucket *bucket;
859a4da8a5SJan Glauber 
869a4da8a5SJan Glauber /* Adapter local summary indicator */
879a4da8a5SJan Glauber static u8 *zpci_irq_si;
889a4da8a5SJan Glauber 
899a4da8a5SJan Glauber static atomic_t irq_retries = ATOMIC_INIT(0);
909a4da8a5SJan Glauber 
91cd248341SJan Glauber /* I/O Map */
92cd248341SJan Glauber static DEFINE_SPINLOCK(zpci_iomap_lock);
93cd248341SJan Glauber static DECLARE_BITMAP(zpci_iomap, ZPCI_IOMAP_MAX_ENTRIES);
94cd248341SJan Glauber struct zpci_iomap_entry *zpci_iomap_start;
95cd248341SJan Glauber EXPORT_SYMBOL_GPL(zpci_iomap_start);
96cd248341SJan Glauber 
979a4da8a5SJan Glauber /* highest irq summary bit */
989a4da8a5SJan Glauber static int __read_mostly aisb_max;
999a4da8a5SJan Glauber 
1009a4da8a5SJan Glauber static struct kmem_cache *zdev_irq_cache;
101*d0b08853SJan Glauber static struct kmem_cache *zdev_fmb_cache;
102*d0b08853SJan Glauber 
103*d0b08853SJan Glauber debug_info_t *pci_debug_msg_id;
104*d0b08853SJan Glauber debug_info_t *pci_debug_err_id;
1059a4da8a5SJan Glauber 
1069a4da8a5SJan Glauber static inline int irq_to_msi_nr(unsigned int irq)
1079a4da8a5SJan Glauber {
1089a4da8a5SJan Glauber 	return irq & ZPCI_MSI_MASK;
1099a4da8a5SJan Glauber }
1109a4da8a5SJan Glauber 
1119a4da8a5SJan Glauber static inline int irq_to_dev_nr(unsigned int irq)
1129a4da8a5SJan Glauber {
1139a4da8a5SJan Glauber 	return irq >> ZPCI_MSI_VEC_BITS;
1149a4da8a5SJan Glauber }
1159a4da8a5SJan Glauber 
1169a4da8a5SJan Glauber static inline struct zdev_irq_map *get_imap(unsigned int irq)
1179a4da8a5SJan Glauber {
1189a4da8a5SJan Glauber 	return bucket->imap[irq_to_dev_nr(irq)];
1199a4da8a5SJan Glauber }
1209a4da8a5SJan Glauber 
121cd248341SJan Glauber struct zpci_dev *get_zdev(struct pci_dev *pdev)
122cd248341SJan Glauber {
123cd248341SJan Glauber 	return (struct zpci_dev *) pdev->sysdata;
124cd248341SJan Glauber }
125cd248341SJan Glauber 
126cd248341SJan Glauber struct zpci_dev *get_zdev_by_fid(u32 fid)
127cd248341SJan Glauber {
128cd248341SJan Glauber 	struct zpci_dev *tmp, *zdev = NULL;
129cd248341SJan Glauber 
130cd248341SJan Glauber 	mutex_lock(&zpci_list_lock);
131cd248341SJan Glauber 	list_for_each_entry(tmp, &zpci_list, entry) {
132cd248341SJan Glauber 		if (tmp->fid == fid) {
133cd248341SJan Glauber 			zdev = tmp;
134cd248341SJan Glauber 			break;
135cd248341SJan Glauber 		}
136cd248341SJan Glauber 	}
137cd248341SJan Glauber 	mutex_unlock(&zpci_list_lock);
138cd248341SJan Glauber 	return zdev;
139cd248341SJan Glauber }
140cd248341SJan Glauber 
141cd248341SJan Glauber bool zpci_fid_present(u32 fid)
142cd248341SJan Glauber {
143cd248341SJan Glauber 	return (get_zdev_by_fid(fid) != NULL) ? true : false;
144cd248341SJan Glauber }
145cd248341SJan Glauber 
146cd248341SJan Glauber static struct zpci_dev *get_zdev_by_bus(struct pci_bus *bus)
147cd248341SJan Glauber {
148cd248341SJan Glauber 	return (bus && bus->sysdata) ? (struct zpci_dev *) bus->sysdata : NULL;
149cd248341SJan Glauber }
150cd248341SJan Glauber 
151cd248341SJan Glauber int pci_domain_nr(struct pci_bus *bus)
152cd248341SJan Glauber {
153cd248341SJan Glauber 	return ((struct zpci_dev *) bus->sysdata)->domain;
154cd248341SJan Glauber }
155cd248341SJan Glauber EXPORT_SYMBOL_GPL(pci_domain_nr);
156cd248341SJan Glauber 
157cd248341SJan Glauber int pci_proc_domain(struct pci_bus *bus)
158cd248341SJan Glauber {
159cd248341SJan Glauber 	return pci_domain_nr(bus);
160cd248341SJan Glauber }
161cd248341SJan Glauber EXPORT_SYMBOL_GPL(pci_proc_domain);
162cd248341SJan Glauber 
163cd248341SJan Glauber /* Store PCI function information block */
164cd248341SJan Glauber static int zpci_store_fib(struct zpci_dev *zdev, u8 *fc)
165cd248341SJan Glauber {
166cd248341SJan Glauber 	struct zpci_fib *fib;
167cd248341SJan Glauber 	u8 status, cc;
168cd248341SJan Glauber 
169cd248341SJan Glauber 	fib = (void *) get_zeroed_page(GFP_KERNEL);
170cd248341SJan Glauber 	if (!fib)
171cd248341SJan Glauber 		return -ENOMEM;
172cd248341SJan Glauber 
173cd248341SJan Glauber 	do {
174cd248341SJan Glauber 		cc = __stpcifc(zdev->fh, 0, fib, &status);
175cd248341SJan Glauber 		if (cc == 2) {
176cd248341SJan Glauber 			msleep(ZPCI_INSN_BUSY_DELAY);
177cd248341SJan Glauber 			memset(fib, 0, PAGE_SIZE);
178cd248341SJan Glauber 		}
179cd248341SJan Glauber 	} while (cc == 2);
180cd248341SJan Glauber 
181cd248341SJan Glauber 	if (cc)
182cd248341SJan Glauber 		pr_err_once("%s: cc: %u  status: %u\n",
183cd248341SJan Glauber 			    __func__, cc, status);
184cd248341SJan Glauber 
185cd248341SJan Glauber 	/* Return PCI function controls */
186cd248341SJan Glauber 	*fc = fib->fc;
187cd248341SJan Glauber 
188cd248341SJan Glauber 	free_page((unsigned long) fib);
189cd248341SJan Glauber 	return (cc) ? -EIO : 0;
190cd248341SJan Glauber }
191cd248341SJan Glauber 
1929a4da8a5SJan Glauber /* Modify PCI: Register adapter interruptions */
1939a4da8a5SJan Glauber static int zpci_register_airq(struct zpci_dev *zdev, unsigned int aisb,
1949a4da8a5SJan Glauber 			      u64 aibv)
1959a4da8a5SJan Glauber {
1969a4da8a5SJan Glauber 	u64 req = ZPCI_CREATE_REQ(zdev->fh, 0, ZPCI_MOD_FC_REG_INT);
1979a4da8a5SJan Glauber 	struct zpci_fib *fib;
1989a4da8a5SJan Glauber 	int rc;
1999a4da8a5SJan Glauber 
2009a4da8a5SJan Glauber 	fib = (void *) get_zeroed_page(GFP_KERNEL);
2019a4da8a5SJan Glauber 	if (!fib)
2029a4da8a5SJan Glauber 		return -ENOMEM;
2039a4da8a5SJan Glauber 
2049a4da8a5SJan Glauber 	fib->isc = PCI_ISC;
2059a4da8a5SJan Glauber 	fib->noi = zdev->irq_map->msi_vecs;
2069a4da8a5SJan Glauber 	fib->sum = 1;		/* enable summary notifications */
2079a4da8a5SJan Glauber 	fib->aibv = aibv;
2089a4da8a5SJan Glauber 	fib->aibvo = 0;		/* every function has its own page */
2099a4da8a5SJan Glauber 	fib->aisb = (u64) bucket->aisb + aisb / 8;
2109a4da8a5SJan Glauber 	fib->aisbo = aisb & ZPCI_MSI_MASK;
2119a4da8a5SJan Glauber 
2129a4da8a5SJan Glauber 	rc = mpcifc_instr(req, fib);
2139a4da8a5SJan Glauber 	pr_debug("%s mpcifc returned noi: %d\n", __func__, fib->noi);
2149a4da8a5SJan Glauber 
2159a4da8a5SJan Glauber 	free_page((unsigned long) fib);
2169a4da8a5SJan Glauber 	return rc;
2179a4da8a5SJan Glauber }
2189a4da8a5SJan Glauber 
2199a4da8a5SJan Glauber struct mod_pci_args {
2209a4da8a5SJan Glauber 	u64 base;
2219a4da8a5SJan Glauber 	u64 limit;
2229a4da8a5SJan Glauber 	u64 iota;
223*d0b08853SJan Glauber 	u64 fmb_addr;
2249a4da8a5SJan Glauber };
2259a4da8a5SJan Glauber 
2269a4da8a5SJan Glauber static int mod_pci(struct zpci_dev *zdev, int fn, u8 dmaas, struct mod_pci_args *args)
2279a4da8a5SJan Glauber {
2289a4da8a5SJan Glauber 	u64 req = ZPCI_CREATE_REQ(zdev->fh, dmaas, fn);
2299a4da8a5SJan Glauber 	struct zpci_fib *fib;
2309a4da8a5SJan Glauber 	int rc;
2319a4da8a5SJan Glauber 
2329a4da8a5SJan Glauber 	/* The FIB must be available even if it's not used */
2339a4da8a5SJan Glauber 	fib = (void *) get_zeroed_page(GFP_KERNEL);
2349a4da8a5SJan Glauber 	if (!fib)
2359a4da8a5SJan Glauber 		return -ENOMEM;
2369a4da8a5SJan Glauber 
2379a4da8a5SJan Glauber 	fib->pba = args->base;
2389a4da8a5SJan Glauber 	fib->pal = args->limit;
2399a4da8a5SJan Glauber 	fib->iota = args->iota;
240*d0b08853SJan Glauber 	fib->fmb_addr = args->fmb_addr;
2419a4da8a5SJan Glauber 
2429a4da8a5SJan Glauber 	rc = mpcifc_instr(req, fib);
2439a4da8a5SJan Glauber 	free_page((unsigned long) fib);
2449a4da8a5SJan Glauber 	return rc;
2459a4da8a5SJan Glauber }
2469a4da8a5SJan Glauber 
247828b35f6SJan Glauber /* Modify PCI: Register I/O address translation parameters */
248828b35f6SJan Glauber int zpci_register_ioat(struct zpci_dev *zdev, u8 dmaas,
249828b35f6SJan Glauber 		       u64 base, u64 limit, u64 iota)
250828b35f6SJan Glauber {
251*d0b08853SJan Glauber 	struct mod_pci_args args = { base, limit, iota, 0 };
252828b35f6SJan Glauber 
253828b35f6SJan Glauber 	WARN_ON_ONCE(iota & 0x3fff);
254828b35f6SJan Glauber 	args.iota |= ZPCI_IOTA_RTTO_FLAG;
255828b35f6SJan Glauber 	return mod_pci(zdev, ZPCI_MOD_FC_REG_IOAT, dmaas, &args);
256828b35f6SJan Glauber }
257828b35f6SJan Glauber 
258828b35f6SJan Glauber /* Modify PCI: Unregister I/O address translation parameters */
259828b35f6SJan Glauber int zpci_unregister_ioat(struct zpci_dev *zdev, u8 dmaas)
260828b35f6SJan Glauber {
261*d0b08853SJan Glauber 	struct mod_pci_args args = { 0, 0, 0, 0 };
262828b35f6SJan Glauber 
263828b35f6SJan Glauber 	return mod_pci(zdev, ZPCI_MOD_FC_DEREG_IOAT, dmaas, &args);
264828b35f6SJan Glauber }
265828b35f6SJan Glauber 
2669a4da8a5SJan Glauber /* Modify PCI: Unregister adapter interruptions */
2679a4da8a5SJan Glauber static int zpci_unregister_airq(struct zpci_dev *zdev)
2689a4da8a5SJan Glauber {
269*d0b08853SJan Glauber 	struct mod_pci_args args = { 0, 0, 0, 0 };
2709a4da8a5SJan Glauber 
2719a4da8a5SJan Glauber 	return mod_pci(zdev, ZPCI_MOD_FC_DEREG_INT, 0, &args);
2729a4da8a5SJan Glauber }
2739a4da8a5SJan Glauber 
274*d0b08853SJan Glauber /* Modify PCI: Set PCI function measurement parameters */
275*d0b08853SJan Glauber int zpci_fmb_enable_device(struct zpci_dev *zdev)
276*d0b08853SJan Glauber {
277*d0b08853SJan Glauber 	struct mod_pci_args args = { 0, 0, 0, 0 };
278*d0b08853SJan Glauber 
279*d0b08853SJan Glauber 	if (zdev->fmb)
280*d0b08853SJan Glauber 		return -EINVAL;
281*d0b08853SJan Glauber 
282*d0b08853SJan Glauber 	zdev->fmb = kmem_cache_alloc(zdev_fmb_cache, GFP_KERNEL);
283*d0b08853SJan Glauber 	if (!zdev->fmb)
284*d0b08853SJan Glauber 		return -ENOMEM;
285*d0b08853SJan Glauber 	memset(zdev->fmb, 0, sizeof(*zdev->fmb));
286*d0b08853SJan Glauber 	WARN_ON((u64) zdev->fmb & 0xf);
287*d0b08853SJan Glauber 
288*d0b08853SJan Glauber 	args.fmb_addr = virt_to_phys(zdev->fmb);
289*d0b08853SJan Glauber 	return mod_pci(zdev, ZPCI_MOD_FC_SET_MEASURE, 0, &args);
290*d0b08853SJan Glauber }
291*d0b08853SJan Glauber 
292*d0b08853SJan Glauber /* Modify PCI: Disable PCI function measurement */
293*d0b08853SJan Glauber int zpci_fmb_disable_device(struct zpci_dev *zdev)
294*d0b08853SJan Glauber {
295*d0b08853SJan Glauber 	struct mod_pci_args args = { 0, 0, 0, 0 };
296*d0b08853SJan Glauber 	int rc;
297*d0b08853SJan Glauber 
298*d0b08853SJan Glauber 	if (!zdev->fmb)
299*d0b08853SJan Glauber 		return -EINVAL;
300*d0b08853SJan Glauber 
301*d0b08853SJan Glauber 	/* Function measurement is disabled if fmb address is zero */
302*d0b08853SJan Glauber 	rc = mod_pci(zdev, ZPCI_MOD_FC_SET_MEASURE, 0, &args);
303*d0b08853SJan Glauber 
304*d0b08853SJan Glauber 	kmem_cache_free(zdev_fmb_cache, zdev->fmb);
305*d0b08853SJan Glauber 	zdev->fmb = NULL;
306*d0b08853SJan Glauber 	return rc;
307*d0b08853SJan Glauber }
308*d0b08853SJan Glauber 
309cd248341SJan Glauber #define ZPCI_PCIAS_CFGSPC	15
310cd248341SJan Glauber 
311cd248341SJan Glauber static int zpci_cfg_load(struct zpci_dev *zdev, int offset, u32 *val, u8 len)
312cd248341SJan Glauber {
313cd248341SJan Glauber 	u64 req = ZPCI_CREATE_REQ(zdev->fh, ZPCI_PCIAS_CFGSPC, len);
314cd248341SJan Glauber 	u64 data;
315cd248341SJan Glauber 	int rc;
316cd248341SJan Glauber 
317cd248341SJan Glauber 	rc = pcilg_instr(&data, req, offset);
318cd248341SJan Glauber 	data = data << ((8 - len) * 8);
319cd248341SJan Glauber 	data = le64_to_cpu(data);
320cd248341SJan Glauber 	if (!rc)
321cd248341SJan Glauber 		*val = (u32) data;
322cd248341SJan Glauber 	else
323cd248341SJan Glauber 		*val = 0xffffffff;
324cd248341SJan Glauber 	return rc;
325cd248341SJan Glauber }
326cd248341SJan Glauber 
327cd248341SJan Glauber static int zpci_cfg_store(struct zpci_dev *zdev, int offset, u32 val, u8 len)
328cd248341SJan Glauber {
329cd248341SJan Glauber 	u64 req = ZPCI_CREATE_REQ(zdev->fh, ZPCI_PCIAS_CFGSPC, len);
330cd248341SJan Glauber 	u64 data = val;
331cd248341SJan Glauber 	int rc;
332cd248341SJan Glauber 
333cd248341SJan Glauber 	data = cpu_to_le64(data);
334cd248341SJan Glauber 	data = data >> ((8 - len) * 8);
335cd248341SJan Glauber 	rc = pcistg_instr(data, req, offset);
336cd248341SJan Glauber 	return rc;
337cd248341SJan Glauber }
338cd248341SJan Glauber 
3399a4da8a5SJan Glauber void synchronize_irq(unsigned int irq)
3409a4da8a5SJan Glauber {
3419a4da8a5SJan Glauber 	/*
3429a4da8a5SJan Glauber 	 * Not needed, the handler is protected by a lock and IRQs that occur
3439a4da8a5SJan Glauber 	 * after the handler is deleted are just NOPs.
3449a4da8a5SJan Glauber 	 */
3459a4da8a5SJan Glauber }
3469a4da8a5SJan Glauber EXPORT_SYMBOL_GPL(synchronize_irq);
3479a4da8a5SJan Glauber 
3489a4da8a5SJan Glauber void enable_irq(unsigned int irq)
3499a4da8a5SJan Glauber {
3509a4da8a5SJan Glauber 	struct msi_desc *msi = irq_get_msi_desc(irq);
3519a4da8a5SJan Glauber 
3529a4da8a5SJan Glauber 	zpci_msi_set_mask_bits(msi, 1, 0);
3539a4da8a5SJan Glauber }
3549a4da8a5SJan Glauber EXPORT_SYMBOL_GPL(enable_irq);
3559a4da8a5SJan Glauber 
3569a4da8a5SJan Glauber void disable_irq(unsigned int irq)
3579a4da8a5SJan Glauber {
3589a4da8a5SJan Glauber 	struct msi_desc *msi = irq_get_msi_desc(irq);
3599a4da8a5SJan Glauber 
3609a4da8a5SJan Glauber 	zpci_msi_set_mask_bits(msi, 1, 1);
3619a4da8a5SJan Glauber }
3629a4da8a5SJan Glauber EXPORT_SYMBOL_GPL(disable_irq);
3639a4da8a5SJan Glauber 
3649a4da8a5SJan Glauber void disable_irq_nosync(unsigned int irq)
3659a4da8a5SJan Glauber {
3669a4da8a5SJan Glauber 	disable_irq(irq);
3679a4da8a5SJan Glauber }
3689a4da8a5SJan Glauber EXPORT_SYMBOL_GPL(disable_irq_nosync);
3699a4da8a5SJan Glauber 
3709a4da8a5SJan Glauber unsigned long probe_irq_on(void)
3719a4da8a5SJan Glauber {
3729a4da8a5SJan Glauber 	return 0;
3739a4da8a5SJan Glauber }
3749a4da8a5SJan Glauber EXPORT_SYMBOL_GPL(probe_irq_on);
3759a4da8a5SJan Glauber 
3769a4da8a5SJan Glauber int probe_irq_off(unsigned long val)
3779a4da8a5SJan Glauber {
3789a4da8a5SJan Glauber 	return 0;
3799a4da8a5SJan Glauber }
3809a4da8a5SJan Glauber EXPORT_SYMBOL_GPL(probe_irq_off);
3819a4da8a5SJan Glauber 
3829a4da8a5SJan Glauber unsigned int probe_irq_mask(unsigned long val)
3839a4da8a5SJan Glauber {
3849a4da8a5SJan Glauber 	return val;
3859a4da8a5SJan Glauber }
3869a4da8a5SJan Glauber EXPORT_SYMBOL_GPL(probe_irq_mask);
3879a4da8a5SJan Glauber 
388cd248341SJan Glauber void __devinit pcibios_fixup_bus(struct pci_bus *bus)
389cd248341SJan Glauber {
390cd248341SJan Glauber }
391cd248341SJan Glauber 
392cd248341SJan Glauber resource_size_t pcibios_align_resource(void *data, const struct resource *res,
393cd248341SJan Glauber 				       resource_size_t size,
394cd248341SJan Glauber 				       resource_size_t align)
395cd248341SJan Glauber {
396cd248341SJan Glauber 	return 0;
397cd248341SJan Glauber }
398cd248341SJan Glauber 
39987bc359bSJan Glauber /* combine single writes by using store-block insn */
40087bc359bSJan Glauber void __iowrite64_copy(void __iomem *to, const void *from, size_t count)
40187bc359bSJan Glauber {
40287bc359bSJan Glauber        zpci_memcpy_toio(to, from, count);
40387bc359bSJan Glauber }
40487bc359bSJan Glauber 
405cd248341SJan Glauber /* Create a virtual mapping cookie for a PCI BAR */
406cd248341SJan Glauber void __iomem *pci_iomap(struct pci_dev *pdev, int bar, unsigned long max)
407cd248341SJan Glauber {
408cd248341SJan Glauber 	struct zpci_dev *zdev =	get_zdev(pdev);
409cd248341SJan Glauber 	u64 addr;
410cd248341SJan Glauber 	int idx;
411cd248341SJan Glauber 
412cd248341SJan Glauber 	if ((bar & 7) != bar)
413cd248341SJan Glauber 		return NULL;
414cd248341SJan Glauber 
415cd248341SJan Glauber 	idx = zdev->bars[bar].map_idx;
416cd248341SJan Glauber 	spin_lock(&zpci_iomap_lock);
417cd248341SJan Glauber 	zpci_iomap_start[idx].fh = zdev->fh;
418cd248341SJan Glauber 	zpci_iomap_start[idx].bar = bar;
419cd248341SJan Glauber 	spin_unlock(&zpci_iomap_lock);
420cd248341SJan Glauber 
421cd248341SJan Glauber 	addr = ZPCI_IOMAP_ADDR_BASE | ((u64) idx << 48);
422cd248341SJan Glauber 	return (void __iomem *) addr;
423cd248341SJan Glauber }
424cd248341SJan Glauber EXPORT_SYMBOL_GPL(pci_iomap);
425cd248341SJan Glauber 
426cd248341SJan Glauber void pci_iounmap(struct pci_dev *pdev, void __iomem *addr)
427cd248341SJan Glauber {
428cd248341SJan Glauber 	unsigned int idx;
429cd248341SJan Glauber 
430cd248341SJan Glauber 	idx = (((__force u64) addr) & ~ZPCI_IOMAP_ADDR_BASE) >> 48;
431cd248341SJan Glauber 	spin_lock(&zpci_iomap_lock);
432cd248341SJan Glauber 	zpci_iomap_start[idx].fh = 0;
433cd248341SJan Glauber 	zpci_iomap_start[idx].bar = 0;
434cd248341SJan Glauber 	spin_unlock(&zpci_iomap_lock);
435cd248341SJan Glauber }
436cd248341SJan Glauber EXPORT_SYMBOL_GPL(pci_iounmap);
437cd248341SJan Glauber 
438cd248341SJan Glauber static int pci_read(struct pci_bus *bus, unsigned int devfn, int where,
439cd248341SJan Glauber 		    int size, u32 *val)
440cd248341SJan Glauber {
441cd248341SJan Glauber 	struct zpci_dev *zdev = get_zdev_by_bus(bus);
442cd248341SJan Glauber 
443cd248341SJan Glauber 	if (!zdev || devfn != ZPCI_DEVFN)
444cd248341SJan Glauber 		return 0;
445cd248341SJan Glauber 	return zpci_cfg_load(zdev, where, val, size);
446cd248341SJan Glauber }
447cd248341SJan Glauber 
448cd248341SJan Glauber static int pci_write(struct pci_bus *bus, unsigned int devfn, int where,
449cd248341SJan Glauber 		     int size, u32 val)
450cd248341SJan Glauber {
451cd248341SJan Glauber 	struct zpci_dev *zdev = get_zdev_by_bus(bus);
452cd248341SJan Glauber 
453cd248341SJan Glauber 	if (!zdev || devfn != ZPCI_DEVFN)
454cd248341SJan Glauber 		return 0;
455cd248341SJan Glauber 	return zpci_cfg_store(zdev, where, val, size);
456cd248341SJan Glauber }
457cd248341SJan Glauber 
458cd248341SJan Glauber static struct pci_ops pci_root_ops = {
459cd248341SJan Glauber 	.read = pci_read,
460cd248341SJan Glauber 	.write = pci_write,
461cd248341SJan Glauber };
462cd248341SJan Glauber 
4639a4da8a5SJan Glauber /* store the last handled bit to implement fair scheduling of devices */
4649a4da8a5SJan Glauber static DEFINE_PER_CPU(unsigned long, next_sbit);
4659a4da8a5SJan Glauber 
4669a4da8a5SJan Glauber static void zpci_irq_handler(void *dont, void *need)
4679a4da8a5SJan Glauber {
4689a4da8a5SJan Glauber 	unsigned long sbit, mbit, last = 0, start = __get_cpu_var(next_sbit);
4699a4da8a5SJan Glauber 	int rescan = 0, max = aisb_max;
4709a4da8a5SJan Glauber 	struct zdev_irq_map *imap;
4719a4da8a5SJan Glauber 
4729a4da8a5SJan Glauber 	kstat_cpu(smp_processor_id()).irqs[IOINT_PCI]++;
4739a4da8a5SJan Glauber 	sbit = start;
4749a4da8a5SJan Glauber 
4759a4da8a5SJan Glauber scan:
4769a4da8a5SJan Glauber 	/* find summary_bit */
4779a4da8a5SJan Glauber 	for_each_set_bit_left_cont(sbit, bucket->aisb, max) {
4789a4da8a5SJan Glauber 		clear_bit(63 - (sbit & 63), bucket->aisb + (sbit >> 6));
4799a4da8a5SJan Glauber 		last = sbit;
4809a4da8a5SJan Glauber 
4819a4da8a5SJan Glauber 		/* find vector bit */
4829a4da8a5SJan Glauber 		imap = bucket->imap[sbit];
4839a4da8a5SJan Glauber 		for_each_set_bit_left(mbit, &imap->aibv, imap->msi_vecs) {
4849a4da8a5SJan Glauber 			kstat_cpu(smp_processor_id()).irqs[IOINT_MSI]++;
4859a4da8a5SJan Glauber 			clear_bit(63 - mbit, &imap->aibv);
4869a4da8a5SJan Glauber 
4879a4da8a5SJan Glauber 			spin_lock(&imap->lock);
4889a4da8a5SJan Glauber 			if (imap->cb[mbit].handler)
4899a4da8a5SJan Glauber 				imap->cb[mbit].handler(mbit,
4909a4da8a5SJan Glauber 					imap->cb[mbit].data);
4919a4da8a5SJan Glauber 			spin_unlock(&imap->lock);
4929a4da8a5SJan Glauber 		}
4939a4da8a5SJan Glauber 	}
4949a4da8a5SJan Glauber 
4959a4da8a5SJan Glauber 	if (rescan)
4969a4da8a5SJan Glauber 		goto out;
4979a4da8a5SJan Glauber 
4989a4da8a5SJan Glauber 	/* scan the skipped bits */
4999a4da8a5SJan Glauber 	if (start > 0) {
5009a4da8a5SJan Glauber 		sbit = 0;
5019a4da8a5SJan Glauber 		max = start;
5029a4da8a5SJan Glauber 		start = 0;
5039a4da8a5SJan Glauber 		goto scan;
5049a4da8a5SJan Glauber 	}
5059a4da8a5SJan Glauber 
5069a4da8a5SJan Glauber 	/* enable interrupts again */
5079a4da8a5SJan Glauber 	sic_instr(SIC_IRQ_MODE_SINGLE, NULL, PCI_ISC);
5089a4da8a5SJan Glauber 
5099a4da8a5SJan Glauber 	/* check again to not lose initiative */
5109a4da8a5SJan Glauber 	rmb();
5119a4da8a5SJan Glauber 	max = aisb_max;
5129a4da8a5SJan Glauber 	sbit = find_first_bit_left(bucket->aisb, max);
5139a4da8a5SJan Glauber 	if (sbit != max) {
5149a4da8a5SJan Glauber 		atomic_inc(&irq_retries);
5159a4da8a5SJan Glauber 		rescan++;
5169a4da8a5SJan Glauber 		goto scan;
5179a4da8a5SJan Glauber 	}
5189a4da8a5SJan Glauber out:
5199a4da8a5SJan Glauber 	/* store next device bit to scan */
5209a4da8a5SJan Glauber 	__get_cpu_var(next_sbit) = (++last >= aisb_max) ? 0 : last;
5219a4da8a5SJan Glauber }
5229a4da8a5SJan Glauber 
5239a4da8a5SJan Glauber /* msi_vecs - number of requested interrupts, 0 place function to error state */
5249a4da8a5SJan Glauber static int zpci_setup_msi(struct pci_dev *pdev, int msi_vecs)
5259a4da8a5SJan Glauber {
5269a4da8a5SJan Glauber 	struct zpci_dev *zdev = get_zdev(pdev);
5279a4da8a5SJan Glauber 	unsigned int aisb, msi_nr;
5289a4da8a5SJan Glauber 	struct msi_desc *msi;
5299a4da8a5SJan Glauber 	int rc;
5309a4da8a5SJan Glauber 
5319a4da8a5SJan Glauber 	/* store the number of used MSI vectors */
5329a4da8a5SJan Glauber 	zdev->irq_map->msi_vecs = min(msi_vecs, ZPCI_NR_MSI_VECS);
5339a4da8a5SJan Glauber 
5349a4da8a5SJan Glauber 	spin_lock(&bucket->lock);
5359a4da8a5SJan Glauber 	aisb = find_first_zero_bit(bucket->alloc, PAGE_SIZE);
5369a4da8a5SJan Glauber 	/* alloc map exhausted? */
5379a4da8a5SJan Glauber 	if (aisb == PAGE_SIZE) {
5389a4da8a5SJan Glauber 		spin_unlock(&bucket->lock);
5399a4da8a5SJan Glauber 		return -EIO;
5409a4da8a5SJan Glauber 	}
5419a4da8a5SJan Glauber 	set_bit(aisb, bucket->alloc);
5429a4da8a5SJan Glauber 	spin_unlock(&bucket->lock);
5439a4da8a5SJan Glauber 
5449a4da8a5SJan Glauber 	zdev->aisb = aisb;
5459a4da8a5SJan Glauber 	if (aisb + 1 > aisb_max)
5469a4da8a5SJan Glauber 		aisb_max = aisb + 1;
5479a4da8a5SJan Glauber 
5489a4da8a5SJan Glauber 	/* wire up IRQ shortcut pointer */
5499a4da8a5SJan Glauber 	bucket->imap[zdev->aisb] = zdev->irq_map;
5509a4da8a5SJan Glauber 	pr_debug("%s: imap[%u] linked to %p\n", __func__, zdev->aisb, zdev->irq_map);
5519a4da8a5SJan Glauber 
5529a4da8a5SJan Glauber 	/* TODO: irq number 0 wont be found if we return less than requested MSIs.
5539a4da8a5SJan Glauber 	 * ignore it for now and fix in common code.
5549a4da8a5SJan Glauber 	 */
5559a4da8a5SJan Glauber 	msi_nr = aisb << ZPCI_MSI_VEC_BITS;
5569a4da8a5SJan Glauber 
5579a4da8a5SJan Glauber 	list_for_each_entry(msi, &pdev->msi_list, list) {
5589a4da8a5SJan Glauber 		rc = zpci_setup_msi_irq(zdev, msi, msi_nr,
5599a4da8a5SJan Glauber 					  aisb << ZPCI_MSI_VEC_BITS);
5609a4da8a5SJan Glauber 		if (rc)
5619a4da8a5SJan Glauber 			return rc;
5629a4da8a5SJan Glauber 		msi_nr++;
5639a4da8a5SJan Glauber 	}
5649a4da8a5SJan Glauber 
5659a4da8a5SJan Glauber 	rc = zpci_register_airq(zdev, aisb, (u64) &zdev->irq_map->aibv);
5669a4da8a5SJan Glauber 	if (rc) {
5679a4da8a5SJan Glauber 		clear_bit(aisb, bucket->alloc);
5689a4da8a5SJan Glauber 		dev_err(&pdev->dev, "register MSI failed with: %d\n", rc);
5699a4da8a5SJan Glauber 		return rc;
5709a4da8a5SJan Glauber 	}
5719a4da8a5SJan Glauber 	return (zdev->irq_map->msi_vecs == msi_vecs) ?
5729a4da8a5SJan Glauber 		0 : zdev->irq_map->msi_vecs;
5739a4da8a5SJan Glauber }
5749a4da8a5SJan Glauber 
5759a4da8a5SJan Glauber static void zpci_teardown_msi(struct pci_dev *pdev)
5769a4da8a5SJan Glauber {
5779a4da8a5SJan Glauber 	struct zpci_dev *zdev = get_zdev(pdev);
5789a4da8a5SJan Glauber 	struct msi_desc *msi;
5799a4da8a5SJan Glauber 	int aisb, rc;
5809a4da8a5SJan Glauber 
5819a4da8a5SJan Glauber 	rc = zpci_unregister_airq(zdev);
5829a4da8a5SJan Glauber 	if (rc) {
5839a4da8a5SJan Glauber 		dev_err(&pdev->dev, "deregister MSI failed with: %d\n", rc);
5849a4da8a5SJan Glauber 		return;
5859a4da8a5SJan Glauber 	}
5869a4da8a5SJan Glauber 
5879a4da8a5SJan Glauber 	msi = list_first_entry(&pdev->msi_list, struct msi_desc, list);
5889a4da8a5SJan Glauber 	aisb = irq_to_dev_nr(msi->irq);
5899a4da8a5SJan Glauber 
5909a4da8a5SJan Glauber 	list_for_each_entry(msi, &pdev->msi_list, list)
5919a4da8a5SJan Glauber 		zpci_teardown_msi_irq(zdev, msi);
5929a4da8a5SJan Glauber 
5939a4da8a5SJan Glauber 	clear_bit(aisb, bucket->alloc);
5949a4da8a5SJan Glauber 	if (aisb + 1 == aisb_max)
5959a4da8a5SJan Glauber 		aisb_max--;
5969a4da8a5SJan Glauber }
5979a4da8a5SJan Glauber 
5989a4da8a5SJan Glauber int arch_setup_msi_irqs(struct pci_dev *pdev, int nvec, int type)
5999a4da8a5SJan Glauber {
6009a4da8a5SJan Glauber 	pr_debug("%s: requesting %d MSI-X interrupts...", __func__, nvec);
6019a4da8a5SJan Glauber 	if (type != PCI_CAP_ID_MSIX && type != PCI_CAP_ID_MSI)
6029a4da8a5SJan Glauber 		return -EINVAL;
6039a4da8a5SJan Glauber 	return zpci_setup_msi(pdev, nvec);
6049a4da8a5SJan Glauber }
6059a4da8a5SJan Glauber 
6069a4da8a5SJan Glauber void arch_teardown_msi_irqs(struct pci_dev *pdev)
6079a4da8a5SJan Glauber {
6089a4da8a5SJan Glauber 	pr_info("%s: on pdev: %p\n", __func__, pdev);
6099a4da8a5SJan Glauber 	zpci_teardown_msi(pdev);
6109a4da8a5SJan Glauber }
6119a4da8a5SJan Glauber 
612cd248341SJan Glauber static void zpci_map_resources(struct zpci_dev *zdev)
613cd248341SJan Glauber {
614cd248341SJan Glauber 	struct pci_dev *pdev = zdev->pdev;
615cd248341SJan Glauber 	resource_size_t len;
616cd248341SJan Glauber 	int i;
617cd248341SJan Glauber 
618cd248341SJan Glauber 	for (i = 0; i < PCI_BAR_COUNT; i++) {
619cd248341SJan Glauber 		len = pci_resource_len(pdev, i);
620cd248341SJan Glauber 		if (!len)
621cd248341SJan Glauber 			continue;
622cd248341SJan Glauber 		pdev->resource[i].start = (resource_size_t) pci_iomap(pdev, i, 0);
623cd248341SJan Glauber 		pdev->resource[i].end = pdev->resource[i].start + len - 1;
624cd248341SJan Glauber 		pr_debug("BAR%i: -> start: %Lx  end: %Lx\n",
625cd248341SJan Glauber 			i, pdev->resource[i].start, pdev->resource[i].end);
626cd248341SJan Glauber 	}
627cd248341SJan Glauber };
628cd248341SJan Glauber 
629cd248341SJan Glauber static void zpci_unmap_resources(struct pci_dev *pdev)
630cd248341SJan Glauber {
631cd248341SJan Glauber 	resource_size_t len;
632cd248341SJan Glauber 	int i;
633cd248341SJan Glauber 
634cd248341SJan Glauber 	for (i = 0; i < PCI_BAR_COUNT; i++) {
635cd248341SJan Glauber 		len = pci_resource_len(pdev, i);
636cd248341SJan Glauber 		if (!len)
637cd248341SJan Glauber 			continue;
638cd248341SJan Glauber 		pci_iounmap(pdev, (void *) pdev->resource[i].start);
639cd248341SJan Glauber 	}
640cd248341SJan Glauber };
641cd248341SJan Glauber 
642cd248341SJan Glauber struct zpci_dev *zpci_alloc_device(void)
643cd248341SJan Glauber {
644cd248341SJan Glauber 	struct zpci_dev *zdev;
645cd248341SJan Glauber 
646cd248341SJan Glauber 	/* Alloc memory for our private pci device data */
647cd248341SJan Glauber 	zdev = kzalloc(sizeof(*zdev), GFP_KERNEL);
648cd248341SJan Glauber 	if (!zdev)
649cd248341SJan Glauber 		return ERR_PTR(-ENOMEM);
6509a4da8a5SJan Glauber 
6519a4da8a5SJan Glauber 	/* Alloc aibv & callback space */
6524118fee7SWei Yongjun 	zdev->irq_map = kmem_cache_zalloc(zdev_irq_cache, GFP_KERNEL);
6539a4da8a5SJan Glauber 	if (!zdev->irq_map)
6549a4da8a5SJan Glauber 		goto error;
6559a4da8a5SJan Glauber 	WARN_ON((u64) zdev->irq_map & 0xff);
656cd248341SJan Glauber 	return zdev;
6579a4da8a5SJan Glauber 
6589a4da8a5SJan Glauber error:
6599a4da8a5SJan Glauber 	kfree(zdev);
6609a4da8a5SJan Glauber 	return ERR_PTR(-ENOMEM);
661cd248341SJan Glauber }
662cd248341SJan Glauber 
663cd248341SJan Glauber void zpci_free_device(struct zpci_dev *zdev)
664cd248341SJan Glauber {
6659a4da8a5SJan Glauber 	kmem_cache_free(zdev_irq_cache, zdev->irq_map);
666cd248341SJan Glauber 	kfree(zdev);
667cd248341SJan Glauber }
668cd248341SJan Glauber 
669cd248341SJan Glauber /* Called on removal of pci_dev, leaves zpci and bus device */
670cd248341SJan Glauber static void zpci_remove_device(struct pci_dev *pdev)
671cd248341SJan Glauber {
672cd248341SJan Glauber 	struct zpci_dev *zdev = get_zdev(pdev);
673cd248341SJan Glauber 
674cd248341SJan Glauber 	dev_info(&pdev->dev, "Removing device %u\n", zdev->domain);
675cd248341SJan Glauber 	zdev->state = ZPCI_FN_STATE_CONFIGURED;
676828b35f6SJan Glauber 	zpci_dma_exit_device(zdev);
677*d0b08853SJan Glauber 	zpci_fmb_disable_device(zdev);
6781e8da956SJan Glauber 	zpci_sysfs_remove_device(&pdev->dev);
679cd248341SJan Glauber 	zpci_unmap_resources(pdev);
680cd248341SJan Glauber 	list_del(&zdev->entry);		/* can be called from init */
681cd248341SJan Glauber 	zdev->pdev = NULL;
682cd248341SJan Glauber }
683cd248341SJan Glauber 
684cd248341SJan Glauber static void zpci_scan_devices(void)
685cd248341SJan Glauber {
686cd248341SJan Glauber 	struct zpci_dev *zdev;
687cd248341SJan Glauber 
688cd248341SJan Glauber 	mutex_lock(&zpci_list_lock);
689cd248341SJan Glauber 	list_for_each_entry(zdev, &zpci_list, entry)
690cd248341SJan Glauber 		if (zdev->state == ZPCI_FN_STATE_CONFIGURED)
691cd248341SJan Glauber 			zpci_scan_device(zdev);
692cd248341SJan Glauber 	mutex_unlock(&zpci_list_lock);
693cd248341SJan Glauber }
694cd248341SJan Glauber 
695cd248341SJan Glauber /*
696cd248341SJan Glauber  * Too late for any s390 specific setup, since interrupts must be set up
697cd248341SJan Glauber  * already which requires DMA setup too and the pci scan will access the
698cd248341SJan Glauber  * config space, which only works if the function handle is enabled.
699cd248341SJan Glauber  */
700cd248341SJan Glauber int pcibios_enable_device(struct pci_dev *pdev, int mask)
701cd248341SJan Glauber {
702cd248341SJan Glauber 	struct resource *res;
703cd248341SJan Glauber 	u16 cmd;
704cd248341SJan Glauber 	int i;
705cd248341SJan Glauber 
706cd248341SJan Glauber 	pci_read_config_word(pdev, PCI_COMMAND, &cmd);
707cd248341SJan Glauber 
708cd248341SJan Glauber 	for (i = 0; i < PCI_BAR_COUNT; i++) {
709cd248341SJan Glauber 		res = &pdev->resource[i];
710cd248341SJan Glauber 
711cd248341SJan Glauber 		if (res->flags & IORESOURCE_IO)
712cd248341SJan Glauber 			return -EINVAL;
713cd248341SJan Glauber 
714cd248341SJan Glauber 		if (res->flags & IORESOURCE_MEM)
715cd248341SJan Glauber 			cmd |= PCI_COMMAND_MEMORY;
716cd248341SJan Glauber 	}
717cd248341SJan Glauber 	pci_write_config_word(pdev, PCI_COMMAND, cmd);
718cd248341SJan Glauber 	return 0;
719cd248341SJan Glauber }
720cd248341SJan Glauber 
721cd248341SJan Glauber void pcibios_disable_device(struct pci_dev *pdev)
722cd248341SJan Glauber {
723cd248341SJan Glauber 	zpci_remove_device(pdev);
724cd248341SJan Glauber 	pdev->sysdata = NULL;
725cd248341SJan Glauber }
726cd248341SJan Glauber 
7271e8da956SJan Glauber int pcibios_add_platform_entries(struct pci_dev *pdev)
7281e8da956SJan Glauber {
7291e8da956SJan Glauber 	return zpci_sysfs_add_device(&pdev->dev);
7301e8da956SJan Glauber }
7311e8da956SJan Glauber 
7329a4da8a5SJan Glauber int zpci_request_irq(unsigned int irq, irq_handler_t handler, void *data)
7339a4da8a5SJan Glauber {
7349a4da8a5SJan Glauber 	int msi_nr = irq_to_msi_nr(irq);
7359a4da8a5SJan Glauber 	struct zdev_irq_map *imap;
7369a4da8a5SJan Glauber 	struct msi_desc *msi;
7379a4da8a5SJan Glauber 
7389a4da8a5SJan Glauber 	msi = irq_get_msi_desc(irq);
7399a4da8a5SJan Glauber 	if (!msi)
7409a4da8a5SJan Glauber 		return -EIO;
7419a4da8a5SJan Glauber 
7429a4da8a5SJan Glauber 	imap = get_imap(irq);
7439a4da8a5SJan Glauber 	spin_lock_init(&imap->lock);
7449a4da8a5SJan Glauber 
7459a4da8a5SJan Glauber 	pr_debug("%s: register handler for IRQ:MSI %d:%d\n", __func__, irq >> 6, msi_nr);
7469a4da8a5SJan Glauber 	imap->cb[msi_nr].handler = handler;
7479a4da8a5SJan Glauber 	imap->cb[msi_nr].data = data;
7489a4da8a5SJan Glauber 
7499a4da8a5SJan Glauber 	/*
7509a4da8a5SJan Glauber 	 * The generic MSI code returns with the interrupt disabled on the
7519a4da8a5SJan Glauber 	 * card, using the MSI mask bits. Firmware doesn't appear to unmask
7529a4da8a5SJan Glauber 	 * at that level, so we do it here by hand.
7539a4da8a5SJan Glauber 	 */
7549a4da8a5SJan Glauber 	zpci_msi_set_mask_bits(msi, 1, 0);
7559a4da8a5SJan Glauber 	return 0;
7569a4da8a5SJan Glauber }
7579a4da8a5SJan Glauber 
7589a4da8a5SJan Glauber void zpci_free_irq(unsigned int irq)
7599a4da8a5SJan Glauber {
7609a4da8a5SJan Glauber 	struct zdev_irq_map *imap = get_imap(irq);
7619a4da8a5SJan Glauber 	int msi_nr = irq_to_msi_nr(irq);
7629a4da8a5SJan Glauber 	unsigned long flags;
7639a4da8a5SJan Glauber 
7649a4da8a5SJan Glauber 	pr_debug("%s: for irq: %d\n", __func__, irq);
7659a4da8a5SJan Glauber 
7669a4da8a5SJan Glauber 	spin_lock_irqsave(&imap->lock, flags);
7679a4da8a5SJan Glauber 	imap->cb[msi_nr].handler = NULL;
7689a4da8a5SJan Glauber 	imap->cb[msi_nr].data = NULL;
7699a4da8a5SJan Glauber 	spin_unlock_irqrestore(&imap->lock, flags);
7709a4da8a5SJan Glauber }
7719a4da8a5SJan Glauber 
7729a4da8a5SJan Glauber int request_irq(unsigned int irq, irq_handler_t handler,
7739a4da8a5SJan Glauber 		unsigned long irqflags, const char *devname, void *dev_id)
7749a4da8a5SJan Glauber {
7759a4da8a5SJan Glauber 	pr_debug("%s: irq: %d  handler: %p  flags: %lx  dev: %s\n",
7769a4da8a5SJan Glauber 		__func__, irq, handler, irqflags, devname);
7779a4da8a5SJan Glauber 
7789a4da8a5SJan Glauber 	return zpci_request_irq(irq, handler, dev_id);
7799a4da8a5SJan Glauber }
7809a4da8a5SJan Glauber EXPORT_SYMBOL_GPL(request_irq);
7819a4da8a5SJan Glauber 
7829a4da8a5SJan Glauber void free_irq(unsigned int irq, void *dev_id)
7839a4da8a5SJan Glauber {
7849a4da8a5SJan Glauber 	zpci_free_irq(irq);
7859a4da8a5SJan Glauber }
7869a4da8a5SJan Glauber EXPORT_SYMBOL_GPL(free_irq);
7879a4da8a5SJan Glauber 
7889a4da8a5SJan Glauber static int __init zpci_irq_init(void)
7899a4da8a5SJan Glauber {
7909a4da8a5SJan Glauber 	int cpu, rc;
7919a4da8a5SJan Glauber 
7929a4da8a5SJan Glauber 	bucket = kzalloc(sizeof(*bucket), GFP_KERNEL);
7939a4da8a5SJan Glauber 	if (!bucket)
7949a4da8a5SJan Glauber 		return -ENOMEM;
7959a4da8a5SJan Glauber 
7969a4da8a5SJan Glauber 	bucket->aisb = (unsigned long *) get_zeroed_page(GFP_KERNEL);
7979a4da8a5SJan Glauber 	if (!bucket->aisb) {
7989a4da8a5SJan Glauber 		rc = -ENOMEM;
7999a4da8a5SJan Glauber 		goto out_aisb;
8009a4da8a5SJan Glauber 	}
8019a4da8a5SJan Glauber 
8029a4da8a5SJan Glauber 	bucket->alloc = (unsigned long *) get_zeroed_page(GFP_KERNEL);
8039a4da8a5SJan Glauber 	if (!bucket->alloc) {
8049a4da8a5SJan Glauber 		rc = -ENOMEM;
8059a4da8a5SJan Glauber 		goto out_alloc;
8069a4da8a5SJan Glauber 	}
8079a4da8a5SJan Glauber 
8089a4da8a5SJan Glauber 	isc_register(PCI_ISC);
8099a4da8a5SJan Glauber 	zpci_irq_si = s390_register_adapter_interrupt(&zpci_irq_handler, NULL, PCI_ISC);
8109a4da8a5SJan Glauber 	if (IS_ERR(zpci_irq_si)) {
8119a4da8a5SJan Glauber 		rc = PTR_ERR(zpci_irq_si);
8129a4da8a5SJan Glauber 		zpci_irq_si = NULL;
8139a4da8a5SJan Glauber 		goto out_ai;
8149a4da8a5SJan Glauber 	}
8159a4da8a5SJan Glauber 
8169a4da8a5SJan Glauber 	for_each_online_cpu(cpu)
8179a4da8a5SJan Glauber 		per_cpu(next_sbit, cpu) = 0;
8189a4da8a5SJan Glauber 
8199a4da8a5SJan Glauber 	spin_lock_init(&bucket->lock);
8209a4da8a5SJan Glauber 	/* set summary to 1 to be called every time for the ISC */
8219a4da8a5SJan Glauber 	*zpci_irq_si = 1;
8229a4da8a5SJan Glauber 	sic_instr(SIC_IRQ_MODE_SINGLE, NULL, PCI_ISC);
8239a4da8a5SJan Glauber 	return 0;
8249a4da8a5SJan Glauber 
8259a4da8a5SJan Glauber out_ai:
8269a4da8a5SJan Glauber 	isc_unregister(PCI_ISC);
8279a4da8a5SJan Glauber 	free_page((unsigned long) bucket->alloc);
8289a4da8a5SJan Glauber out_alloc:
8299a4da8a5SJan Glauber 	free_page((unsigned long) bucket->aisb);
8309a4da8a5SJan Glauber out_aisb:
8319a4da8a5SJan Glauber 	kfree(bucket);
8329a4da8a5SJan Glauber 	return rc;
8339a4da8a5SJan Glauber }
8349a4da8a5SJan Glauber 
8359a4da8a5SJan Glauber static void zpci_irq_exit(void)
8369a4da8a5SJan Glauber {
8379a4da8a5SJan Glauber 	free_page((unsigned long) bucket->alloc);
8389a4da8a5SJan Glauber 	free_page((unsigned long) bucket->aisb);
8399a4da8a5SJan Glauber 	s390_unregister_adapter_interrupt(zpci_irq_si, PCI_ISC);
8409a4da8a5SJan Glauber 	isc_unregister(PCI_ISC);
8419a4da8a5SJan Glauber 	kfree(bucket);
8429a4da8a5SJan Glauber }
8439a4da8a5SJan Glauber 
844*d0b08853SJan Glauber void zpci_debug_info(struct zpci_dev *zdev, struct seq_file *m)
845*d0b08853SJan Glauber {
846*d0b08853SJan Glauber 	if (!zdev)
847*d0b08853SJan Glauber 		return;
848*d0b08853SJan Glauber 
849*d0b08853SJan Glauber 	seq_printf(m, "global irq retries: %u\n", atomic_read(&irq_retries));
850*d0b08853SJan Glauber 	seq_printf(m, "aibv[0]:%016lx  aibv[1]:%016lx  aisb:%016lx\n",
851*d0b08853SJan Glauber 		   get_imap(0)->aibv, get_imap(1)->aibv, *bucket->aisb);
852*d0b08853SJan Glauber }
853*d0b08853SJan Glauber 
854cd248341SJan Glauber static struct resource *zpci_alloc_bus_resource(unsigned long start, unsigned long size,
855cd248341SJan Glauber 						unsigned long flags, int domain)
856cd248341SJan Glauber {
857cd248341SJan Glauber 	struct resource *r;
858cd248341SJan Glauber 	char *name;
859cd248341SJan Glauber 	int rc;
860cd248341SJan Glauber 
861cd248341SJan Glauber 	r = kzalloc(sizeof(*r), GFP_KERNEL);
862cd248341SJan Glauber 	if (!r)
863cd248341SJan Glauber 		return ERR_PTR(-ENOMEM);
864cd248341SJan Glauber 	r->start = start;
865cd248341SJan Glauber 	r->end = r->start + size - 1;
866cd248341SJan Glauber 	r->flags = flags;
867cd248341SJan Glauber 	r->parent = &iomem_resource;
868cd248341SJan Glauber 	name = kmalloc(18, GFP_KERNEL);
869cd248341SJan Glauber 	if (!name) {
870cd248341SJan Glauber 		kfree(r);
871cd248341SJan Glauber 		return ERR_PTR(-ENOMEM);
872cd248341SJan Glauber 	}
873cd248341SJan Glauber 	sprintf(name, "PCI Bus: %04x:%02x", domain, ZPCI_BUS_NR);
874cd248341SJan Glauber 	r->name = name;
875cd248341SJan Glauber 
876cd248341SJan Glauber 	rc = request_resource(&iomem_resource, r);
877cd248341SJan Glauber 	if (rc)
878cd248341SJan Glauber 		pr_debug("request resource %pR failed\n", r);
879cd248341SJan Glauber 	return r;
880cd248341SJan Glauber }
881cd248341SJan Glauber 
882cd248341SJan Glauber static int zpci_alloc_iomap(struct zpci_dev *zdev)
883cd248341SJan Glauber {
884cd248341SJan Glauber 	int entry;
885cd248341SJan Glauber 
886cd248341SJan Glauber 	spin_lock(&zpci_iomap_lock);
887cd248341SJan Glauber 	entry = find_first_zero_bit(zpci_iomap, ZPCI_IOMAP_MAX_ENTRIES);
888cd248341SJan Glauber 	if (entry == ZPCI_IOMAP_MAX_ENTRIES) {
889cd248341SJan Glauber 		spin_unlock(&zpci_iomap_lock);
890cd248341SJan Glauber 		return -ENOSPC;
891cd248341SJan Glauber 	}
892cd248341SJan Glauber 	set_bit(entry, zpci_iomap);
893cd248341SJan Glauber 	spin_unlock(&zpci_iomap_lock);
894cd248341SJan Glauber 	return entry;
895cd248341SJan Glauber }
896cd248341SJan Glauber 
897cd248341SJan Glauber static void zpci_free_iomap(struct zpci_dev *zdev, int entry)
898cd248341SJan Glauber {
899cd248341SJan Glauber 	spin_lock(&zpci_iomap_lock);
900cd248341SJan Glauber 	memset(&zpci_iomap_start[entry], 0, sizeof(struct zpci_iomap_entry));
901cd248341SJan Glauber 	clear_bit(entry, zpci_iomap);
902cd248341SJan Glauber 	spin_unlock(&zpci_iomap_lock);
903cd248341SJan Glauber }
904cd248341SJan Glauber 
905cd248341SJan Glauber static int zpci_create_device_bus(struct zpci_dev *zdev)
906cd248341SJan Glauber {
907cd248341SJan Glauber 	struct resource *res;
908cd248341SJan Glauber 	LIST_HEAD(resources);
909cd248341SJan Glauber 	int i;
910cd248341SJan Glauber 
911cd248341SJan Glauber 	/* allocate mapping entry for each used bar */
912cd248341SJan Glauber 	for (i = 0; i < PCI_BAR_COUNT; i++) {
913cd248341SJan Glauber 		unsigned long addr, size, flags;
914cd248341SJan Glauber 		int entry;
915cd248341SJan Glauber 
916cd248341SJan Glauber 		if (!zdev->bars[i].size)
917cd248341SJan Glauber 			continue;
918cd248341SJan Glauber 		entry = zpci_alloc_iomap(zdev);
919cd248341SJan Glauber 		if (entry < 0)
920cd248341SJan Glauber 			return entry;
921cd248341SJan Glauber 		zdev->bars[i].map_idx = entry;
922cd248341SJan Glauber 
923cd248341SJan Glauber 		/* only MMIO is supported */
924cd248341SJan Glauber 		flags = IORESOURCE_MEM;
925cd248341SJan Glauber 		if (zdev->bars[i].val & 8)
926cd248341SJan Glauber 			flags |= IORESOURCE_PREFETCH;
927cd248341SJan Glauber 		if (zdev->bars[i].val & 4)
928cd248341SJan Glauber 			flags |= IORESOURCE_MEM_64;
929cd248341SJan Glauber 
930cd248341SJan Glauber 		addr = ZPCI_IOMAP_ADDR_BASE + ((u64) entry << 48);
931cd248341SJan Glauber 
932cd248341SJan Glauber 		size = 1UL << zdev->bars[i].size;
933cd248341SJan Glauber 
934cd248341SJan Glauber 		res = zpci_alloc_bus_resource(addr, size, flags, zdev->domain);
935cd248341SJan Glauber 		if (IS_ERR(res)) {
936cd248341SJan Glauber 			zpci_free_iomap(zdev, entry);
937cd248341SJan Glauber 			return PTR_ERR(res);
938cd248341SJan Glauber 		}
939cd248341SJan Glauber 		pci_add_resource(&resources, res);
940cd248341SJan Glauber 	}
941cd248341SJan Glauber 
942cd248341SJan Glauber 	zdev->bus = pci_create_root_bus(NULL, ZPCI_BUS_NR, &pci_root_ops,
943cd248341SJan Glauber 					zdev, &resources);
944cd248341SJan Glauber 	if (!zdev->bus)
945cd248341SJan Glauber 		return -EIO;
946cd248341SJan Glauber 
947cd248341SJan Glauber 	zdev->bus->max_bus_speed = zdev->max_bus_speed;
948cd248341SJan Glauber 	return 0;
949cd248341SJan Glauber }
950cd248341SJan Glauber 
951cd248341SJan Glauber static int zpci_alloc_domain(struct zpci_dev *zdev)
952cd248341SJan Glauber {
953cd248341SJan Glauber 	spin_lock(&zpci_domain_lock);
954cd248341SJan Glauber 	zdev->domain = find_first_zero_bit(zpci_domain, ZPCI_NR_DEVICES);
955cd248341SJan Glauber 	if (zdev->domain == ZPCI_NR_DEVICES) {
956cd248341SJan Glauber 		spin_unlock(&zpci_domain_lock);
957cd248341SJan Glauber 		return -ENOSPC;
958cd248341SJan Glauber 	}
959cd248341SJan Glauber 	set_bit(zdev->domain, zpci_domain);
960cd248341SJan Glauber 	spin_unlock(&zpci_domain_lock);
961cd248341SJan Glauber 	return 0;
962cd248341SJan Glauber }
963cd248341SJan Glauber 
964cd248341SJan Glauber static void zpci_free_domain(struct zpci_dev *zdev)
965cd248341SJan Glauber {
966cd248341SJan Glauber 	spin_lock(&zpci_domain_lock);
967cd248341SJan Glauber 	clear_bit(zdev->domain, zpci_domain);
968cd248341SJan Glauber 	spin_unlock(&zpci_domain_lock);
969cd248341SJan Glauber }
970cd248341SJan Glauber 
971a755a45dSJan Glauber int zpci_enable_device(struct zpci_dev *zdev)
972a755a45dSJan Glauber {
973a755a45dSJan Glauber 	int rc;
974a755a45dSJan Glauber 
975a755a45dSJan Glauber 	rc = clp_enable_fh(zdev, ZPCI_NR_DMA_SPACES);
976a755a45dSJan Glauber 	if (rc)
977a755a45dSJan Glauber 		goto out;
978a755a45dSJan Glauber 	pr_info("Enabled fh: 0x%x fid: 0x%x\n", zdev->fh, zdev->fid);
979828b35f6SJan Glauber 
980828b35f6SJan Glauber 	rc = zpci_dma_init_device(zdev);
981828b35f6SJan Glauber 	if (rc)
982828b35f6SJan Glauber 		goto out_dma;
983a755a45dSJan Glauber 	return 0;
984828b35f6SJan Glauber 
985828b35f6SJan Glauber out_dma:
986828b35f6SJan Glauber 	clp_disable_fh(zdev);
987a755a45dSJan Glauber out:
988a755a45dSJan Glauber 	return rc;
989a755a45dSJan Glauber }
990a755a45dSJan Glauber EXPORT_SYMBOL_GPL(zpci_enable_device);
991a755a45dSJan Glauber 
992cd248341SJan Glauber int zpci_create_device(struct zpci_dev *zdev)
993cd248341SJan Glauber {
994cd248341SJan Glauber 	int rc;
995cd248341SJan Glauber 
996cd248341SJan Glauber 	rc = zpci_alloc_domain(zdev);
997cd248341SJan Glauber 	if (rc)
998cd248341SJan Glauber 		goto out;
999cd248341SJan Glauber 
1000cd248341SJan Glauber 	rc = zpci_create_device_bus(zdev);
1001cd248341SJan Glauber 	if (rc)
1002cd248341SJan Glauber 		goto out_bus;
1003cd248341SJan Glauber 
1004cd248341SJan Glauber 	mutex_lock(&zpci_list_lock);
1005cd248341SJan Glauber 	list_add_tail(&zdev->entry, &zpci_list);
10067441b062SJan Glauber 	if (hotplug_ops.create_slot)
10077441b062SJan Glauber 		hotplug_ops.create_slot(zdev);
1008cd248341SJan Glauber 	mutex_unlock(&zpci_list_lock);
1009cd248341SJan Glauber 
1010cd248341SJan Glauber 	if (zdev->state == ZPCI_FN_STATE_STANDBY)
1011cd248341SJan Glauber 		return 0;
1012cd248341SJan Glauber 
1013a755a45dSJan Glauber 	rc = zpci_enable_device(zdev);
1014a755a45dSJan Glauber 	if (rc)
1015a755a45dSJan Glauber 		goto out_start;
1016cd248341SJan Glauber 	return 0;
1017cd248341SJan Glauber 
1018a755a45dSJan Glauber out_start:
1019a755a45dSJan Glauber 	mutex_lock(&zpci_list_lock);
1020a755a45dSJan Glauber 	list_del(&zdev->entry);
10217441b062SJan Glauber 	if (hotplug_ops.remove_slot)
10227441b062SJan Glauber 		hotplug_ops.remove_slot(zdev);
1023a755a45dSJan Glauber 	mutex_unlock(&zpci_list_lock);
1024cd248341SJan Glauber out_bus:
1025cd248341SJan Glauber 	zpci_free_domain(zdev);
1026cd248341SJan Glauber out:
1027cd248341SJan Glauber 	return rc;
1028cd248341SJan Glauber }
1029cd248341SJan Glauber 
1030cd248341SJan Glauber void zpci_stop_device(struct zpci_dev *zdev)
1031cd248341SJan Glauber {
1032828b35f6SJan Glauber 	zpci_dma_exit_device(zdev);
1033cd248341SJan Glauber 	/*
1034cd248341SJan Glauber 	 * Note: SCLP disables fh via set-pci-fn so don't
1035cd248341SJan Glauber 	 * do that here.
1036cd248341SJan Glauber 	 */
1037cd248341SJan Glauber }
1038cd248341SJan Glauber EXPORT_SYMBOL_GPL(zpci_stop_device);
1039cd248341SJan Glauber 
1040cd248341SJan Glauber int zpci_scan_device(struct zpci_dev *zdev)
1041cd248341SJan Glauber {
1042cd248341SJan Glauber 	zdev->pdev = pci_scan_single_device(zdev->bus, ZPCI_DEVFN);
1043cd248341SJan Glauber 	if (!zdev->pdev) {
1044cd248341SJan Glauber 		pr_err("pci_scan_single_device failed for fid: 0x%x\n",
1045cd248341SJan Glauber 			zdev->fid);
1046cd248341SJan Glauber 		goto out;
1047cd248341SJan Glauber 	}
1048cd248341SJan Glauber 
1049*d0b08853SJan Glauber 	zpci_debug_init_device(zdev);
1050*d0b08853SJan Glauber 	zpci_fmb_enable_device(zdev);
1051cd248341SJan Glauber 	zpci_map_resources(zdev);
1052cd248341SJan Glauber 	pci_bus_add_devices(zdev->bus);
1053cd248341SJan Glauber 
1054cd248341SJan Glauber 	/* now that pdev was added to the bus mark it as used */
1055cd248341SJan Glauber 	zdev->state = ZPCI_FN_STATE_ONLINE;
1056cd248341SJan Glauber 	return 0;
1057cd248341SJan Glauber 
1058cd248341SJan Glauber out:
1059828b35f6SJan Glauber 	zpci_dma_exit_device(zdev);
1060a755a45dSJan Glauber 	clp_disable_fh(zdev);
1061cd248341SJan Glauber 	return -EIO;
1062cd248341SJan Glauber }
1063cd248341SJan Glauber EXPORT_SYMBOL_GPL(zpci_scan_device);
1064cd248341SJan Glauber 
1065cd248341SJan Glauber static inline int barsize(u8 size)
1066cd248341SJan Glauber {
1067cd248341SJan Glauber 	return (size) ? (1 << size) >> 10 : 0;
1068cd248341SJan Glauber }
1069cd248341SJan Glauber 
1070cd248341SJan Glauber static int zpci_mem_init(void)
1071cd248341SJan Glauber {
10729a4da8a5SJan Glauber 	zdev_irq_cache = kmem_cache_create("PCI_IRQ_cache", sizeof(struct zdev_irq_map),
10739a4da8a5SJan Glauber 				L1_CACHE_BYTES, SLAB_HWCACHE_ALIGN, NULL);
10749a4da8a5SJan Glauber 	if (!zdev_irq_cache)
10759a4da8a5SJan Glauber 		goto error_zdev;
10769a4da8a5SJan Glauber 
1077*d0b08853SJan Glauber 	zdev_fmb_cache = kmem_cache_create("PCI_FMB_cache", sizeof(struct zpci_fmb),
1078*d0b08853SJan Glauber 				16, 0, NULL);
1079*d0b08853SJan Glauber 	if (!zdev_fmb_cache)
1080*d0b08853SJan Glauber 		goto error_fmb;
1081*d0b08853SJan Glauber 
1082cd248341SJan Glauber 	/* TODO: use realloc */
1083cd248341SJan Glauber 	zpci_iomap_start = kzalloc(ZPCI_IOMAP_MAX_ENTRIES * sizeof(*zpci_iomap_start),
1084cd248341SJan Glauber 				   GFP_KERNEL);
1085cd248341SJan Glauber 	if (!zpci_iomap_start)
10869a4da8a5SJan Glauber 		goto error_iomap;
1087cd248341SJan Glauber 	return 0;
1088cd248341SJan Glauber 
10899a4da8a5SJan Glauber error_iomap:
1090*d0b08853SJan Glauber 	kmem_cache_destroy(zdev_fmb_cache);
1091*d0b08853SJan Glauber error_fmb:
10929a4da8a5SJan Glauber 	kmem_cache_destroy(zdev_irq_cache);
1093cd248341SJan Glauber error_zdev:
1094cd248341SJan Glauber 	return -ENOMEM;
1095cd248341SJan Glauber }
1096cd248341SJan Glauber 
1097cd248341SJan Glauber static void zpci_mem_exit(void)
1098cd248341SJan Glauber {
1099cd248341SJan Glauber 	kfree(zpci_iomap_start);
11009a4da8a5SJan Glauber 	kmem_cache_destroy(zdev_irq_cache);
1101*d0b08853SJan Glauber 	kmem_cache_destroy(zdev_fmb_cache);
1102cd248341SJan Glauber }
1103cd248341SJan Glauber 
1104cd248341SJan Glauber unsigned int pci_probe = 1;
1105cd248341SJan Glauber EXPORT_SYMBOL_GPL(pci_probe);
1106cd248341SJan Glauber 
1107cd248341SJan Glauber char * __init pcibios_setup(char *str)
1108cd248341SJan Glauber {
1109cd248341SJan Glauber 	if (!strcmp(str, "off")) {
1110cd248341SJan Glauber 		pci_probe = 0;
1111cd248341SJan Glauber 		return NULL;
1112cd248341SJan Glauber 	}
1113cd248341SJan Glauber 	return str;
1114cd248341SJan Glauber }
1115cd248341SJan Glauber 
1116cd248341SJan Glauber static int __init pci_base_init(void)
1117cd248341SJan Glauber {
1118cd248341SJan Glauber 	int rc;
1119cd248341SJan Glauber 
1120cd248341SJan Glauber 	if (!pci_probe)
1121cd248341SJan Glauber 		return 0;
1122cd248341SJan Glauber 
1123cd248341SJan Glauber 	if (!test_facility(2) || !test_facility(69)
1124cd248341SJan Glauber 	    || !test_facility(71) || !test_facility(72))
1125cd248341SJan Glauber 		return 0;
1126cd248341SJan Glauber 
1127cd248341SJan Glauber 	pr_info("Probing PCI hardware: PCI:%d  SID:%d  AEN:%d\n",
1128cd248341SJan Glauber 		test_facility(69), test_facility(70),
1129cd248341SJan Glauber 		test_facility(71));
1130cd248341SJan Glauber 
1131*d0b08853SJan Glauber 	rc = zpci_debug_init();
1132*d0b08853SJan Glauber 	if (rc)
1133*d0b08853SJan Glauber 		return rc;
1134*d0b08853SJan Glauber 
1135cd248341SJan Glauber 	rc = zpci_mem_init();
1136cd248341SJan Glauber 	if (rc)
1137cd248341SJan Glauber 		goto out_mem;
1138cd248341SJan Glauber 
11399a4da8a5SJan Glauber 	rc = zpci_msihash_init();
11409a4da8a5SJan Glauber 	if (rc)
11419a4da8a5SJan Glauber 		goto out_hash;
11429a4da8a5SJan Glauber 
11439a4da8a5SJan Glauber 	rc = zpci_irq_init();
11449a4da8a5SJan Glauber 	if (rc)
11459a4da8a5SJan Glauber 		goto out_irq;
11469a4da8a5SJan Glauber 
1147828b35f6SJan Glauber 	rc = zpci_dma_init();
1148828b35f6SJan Glauber 	if (rc)
1149828b35f6SJan Glauber 		goto out_dma;
1150828b35f6SJan Glauber 
1151a755a45dSJan Glauber 	rc = clp_find_pci_devices();
1152a755a45dSJan Glauber 	if (rc)
1153a755a45dSJan Glauber 		goto out_find;
1154a755a45dSJan Glauber 
1155cd248341SJan Glauber 	zpci_scan_devices();
1156cd248341SJan Glauber 	return 0;
1157cd248341SJan Glauber 
1158a755a45dSJan Glauber out_find:
1159828b35f6SJan Glauber 	zpci_dma_exit();
1160828b35f6SJan Glauber out_dma:
11619a4da8a5SJan Glauber 	zpci_irq_exit();
11629a4da8a5SJan Glauber out_irq:
11639a4da8a5SJan Glauber 	zpci_msihash_exit();
11649a4da8a5SJan Glauber out_hash:
1165cd248341SJan Glauber 	zpci_mem_exit();
1166cd248341SJan Glauber out_mem:
1167*d0b08853SJan Glauber 	zpci_debug_exit();
1168cd248341SJan Glauber 	return rc;
1169cd248341SJan Glauber }
1170cd248341SJan Glauber subsys_initcall(pci_base_init);
1171