xref: /linux/arch/s390/pci/pci.c (revision a755a45dd928e05a4fb980d31d4a0dbc49adc562)
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!):
9cd248341SJan Glauber  *   Alexander Schmidt <alexschm@de.ibm.com>
10cd248341SJan Glauber  *   Christoph Raisch <raisch@de.ibm.com>
11cd248341SJan Glauber  *   Hannes Hering <hering2@de.ibm.com>
12cd248341SJan Glauber  *   Hoang-Nam Nguyen <hnguyen@de.ibm.com>
13cd248341SJan Glauber  *   Jan-Bernd Themann <themann@de.ibm.com>
14cd248341SJan Glauber  *   Stefan Roscher <stefan.roscher@de.ibm.com>
15cd248341SJan Glauber  *   Thomas Klein <tklein@de.ibm.com>
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>
26cd248341SJan Glauber #include <linux/seq_file.h>
27cd248341SJan Glauber #include <linux/pci.h>
28cd248341SJan Glauber #include <linux/msi.h>
29cd248341SJan Glauber 
30cd248341SJan Glauber #include <asm/facility.h>
31cd248341SJan Glauber #include <asm/pci_insn.h>
32*a755a45dSJan Glauber #include <asm/pci_clp.h>
33cd248341SJan Glauber 
34cd248341SJan Glauber #define DEBUG				/* enable pr_debug */
35cd248341SJan Glauber 
36cd248341SJan Glauber #define ZPCI_NR_DMA_SPACES		1
37cd248341SJan Glauber #define ZPCI_NR_DEVICES			CONFIG_PCI_NR_FUNCTIONS
38cd248341SJan Glauber 
39cd248341SJan Glauber /* list of all detected zpci devices */
40cd248341SJan Glauber LIST_HEAD(zpci_list);
41cd248341SJan Glauber DEFINE_MUTEX(zpci_list_lock);
42cd248341SJan Glauber 
43cd248341SJan Glauber static DECLARE_BITMAP(zpci_domain, ZPCI_NR_DEVICES);
44cd248341SJan Glauber static DEFINE_SPINLOCK(zpci_domain_lock);
45cd248341SJan Glauber 
46cd248341SJan Glauber /* I/O Map */
47cd248341SJan Glauber static DEFINE_SPINLOCK(zpci_iomap_lock);
48cd248341SJan Glauber static DECLARE_BITMAP(zpci_iomap, ZPCI_IOMAP_MAX_ENTRIES);
49cd248341SJan Glauber struct zpci_iomap_entry *zpci_iomap_start;
50cd248341SJan Glauber EXPORT_SYMBOL_GPL(zpci_iomap_start);
51cd248341SJan Glauber 
52cd248341SJan Glauber struct zpci_dev *get_zdev(struct pci_dev *pdev)
53cd248341SJan Glauber {
54cd248341SJan Glauber 	return (struct zpci_dev *) pdev->sysdata;
55cd248341SJan Glauber }
56cd248341SJan Glauber 
57cd248341SJan Glauber struct zpci_dev *get_zdev_by_fid(u32 fid)
58cd248341SJan Glauber {
59cd248341SJan Glauber 	struct zpci_dev *tmp, *zdev = NULL;
60cd248341SJan Glauber 
61cd248341SJan Glauber 	mutex_lock(&zpci_list_lock);
62cd248341SJan Glauber 	list_for_each_entry(tmp, &zpci_list, entry) {
63cd248341SJan Glauber 		if (tmp->fid == fid) {
64cd248341SJan Glauber 			zdev = tmp;
65cd248341SJan Glauber 			break;
66cd248341SJan Glauber 		}
67cd248341SJan Glauber 	}
68cd248341SJan Glauber 	mutex_unlock(&zpci_list_lock);
69cd248341SJan Glauber 	return zdev;
70cd248341SJan Glauber }
71cd248341SJan Glauber 
72cd248341SJan Glauber bool zpci_fid_present(u32 fid)
73cd248341SJan Glauber {
74cd248341SJan Glauber 	return (get_zdev_by_fid(fid) != NULL) ? true : false;
75cd248341SJan Glauber }
76cd248341SJan Glauber 
77cd248341SJan Glauber static struct zpci_dev *get_zdev_by_bus(struct pci_bus *bus)
78cd248341SJan Glauber {
79cd248341SJan Glauber 	return (bus && bus->sysdata) ? (struct zpci_dev *) bus->sysdata : NULL;
80cd248341SJan Glauber }
81cd248341SJan Glauber 
82cd248341SJan Glauber int pci_domain_nr(struct pci_bus *bus)
83cd248341SJan Glauber {
84cd248341SJan Glauber 	return ((struct zpci_dev *) bus->sysdata)->domain;
85cd248341SJan Glauber }
86cd248341SJan Glauber EXPORT_SYMBOL_GPL(pci_domain_nr);
87cd248341SJan Glauber 
88cd248341SJan Glauber int pci_proc_domain(struct pci_bus *bus)
89cd248341SJan Glauber {
90cd248341SJan Glauber 	return pci_domain_nr(bus);
91cd248341SJan Glauber }
92cd248341SJan Glauber EXPORT_SYMBOL_GPL(pci_proc_domain);
93cd248341SJan Glauber 
94cd248341SJan Glauber /* Store PCI function information block */
95cd248341SJan Glauber static int zpci_store_fib(struct zpci_dev *zdev, u8 *fc)
96cd248341SJan Glauber {
97cd248341SJan Glauber 	struct zpci_fib *fib;
98cd248341SJan Glauber 	u8 status, cc;
99cd248341SJan Glauber 
100cd248341SJan Glauber 	fib = (void *) get_zeroed_page(GFP_KERNEL);
101cd248341SJan Glauber 	if (!fib)
102cd248341SJan Glauber 		return -ENOMEM;
103cd248341SJan Glauber 
104cd248341SJan Glauber 	do {
105cd248341SJan Glauber 		cc = __stpcifc(zdev->fh, 0, fib, &status);
106cd248341SJan Glauber 		if (cc == 2) {
107cd248341SJan Glauber 			msleep(ZPCI_INSN_BUSY_DELAY);
108cd248341SJan Glauber 			memset(fib, 0, PAGE_SIZE);
109cd248341SJan Glauber 		}
110cd248341SJan Glauber 	} while (cc == 2);
111cd248341SJan Glauber 
112cd248341SJan Glauber 	if (cc)
113cd248341SJan Glauber 		pr_err_once("%s: cc: %u  status: %u\n",
114cd248341SJan Glauber 			    __func__, cc, status);
115cd248341SJan Glauber 
116cd248341SJan Glauber 	/* Return PCI function controls */
117cd248341SJan Glauber 	*fc = fib->fc;
118cd248341SJan Glauber 
119cd248341SJan Glauber 	free_page((unsigned long) fib);
120cd248341SJan Glauber 	return (cc) ? -EIO : 0;
121cd248341SJan Glauber }
122cd248341SJan Glauber 
123cd248341SJan Glauber #define ZPCI_PCIAS_CFGSPC	15
124cd248341SJan Glauber 
125cd248341SJan Glauber static int zpci_cfg_load(struct zpci_dev *zdev, int offset, u32 *val, u8 len)
126cd248341SJan Glauber {
127cd248341SJan Glauber 	u64 req = ZPCI_CREATE_REQ(zdev->fh, ZPCI_PCIAS_CFGSPC, len);
128cd248341SJan Glauber 	u64 data;
129cd248341SJan Glauber 	int rc;
130cd248341SJan Glauber 
131cd248341SJan Glauber 	rc = pcilg_instr(&data, req, offset);
132cd248341SJan Glauber 	data = data << ((8 - len) * 8);
133cd248341SJan Glauber 	data = le64_to_cpu(data);
134cd248341SJan Glauber 	if (!rc)
135cd248341SJan Glauber 		*val = (u32) data;
136cd248341SJan Glauber 	else
137cd248341SJan Glauber 		*val = 0xffffffff;
138cd248341SJan Glauber 	return rc;
139cd248341SJan Glauber }
140cd248341SJan Glauber 
141cd248341SJan Glauber static int zpci_cfg_store(struct zpci_dev *zdev, int offset, u32 val, u8 len)
142cd248341SJan Glauber {
143cd248341SJan Glauber 	u64 req = ZPCI_CREATE_REQ(zdev->fh, ZPCI_PCIAS_CFGSPC, len);
144cd248341SJan Glauber 	u64 data = val;
145cd248341SJan Glauber 	int rc;
146cd248341SJan Glauber 
147cd248341SJan Glauber 	data = cpu_to_le64(data);
148cd248341SJan Glauber 	data = data >> ((8 - len) * 8);
149cd248341SJan Glauber 	rc = pcistg_instr(data, req, offset);
150cd248341SJan Glauber 	return rc;
151cd248341SJan Glauber }
152cd248341SJan Glauber 
153cd248341SJan Glauber void __devinit pcibios_fixup_bus(struct pci_bus *bus)
154cd248341SJan Glauber {
155cd248341SJan Glauber }
156cd248341SJan Glauber 
157cd248341SJan Glauber resource_size_t pcibios_align_resource(void *data, const struct resource *res,
158cd248341SJan Glauber 				       resource_size_t size,
159cd248341SJan Glauber 				       resource_size_t align)
160cd248341SJan Glauber {
161cd248341SJan Glauber 	return 0;
162cd248341SJan Glauber }
163cd248341SJan Glauber 
164cd248341SJan Glauber /* Create a virtual mapping cookie for a PCI BAR */
165cd248341SJan Glauber void __iomem *pci_iomap(struct pci_dev *pdev, int bar, unsigned long max)
166cd248341SJan Glauber {
167cd248341SJan Glauber 	struct zpci_dev *zdev =	get_zdev(pdev);
168cd248341SJan Glauber 	u64 addr;
169cd248341SJan Glauber 	int idx;
170cd248341SJan Glauber 
171cd248341SJan Glauber 	if ((bar & 7) != bar)
172cd248341SJan Glauber 		return NULL;
173cd248341SJan Glauber 
174cd248341SJan Glauber 	idx = zdev->bars[bar].map_idx;
175cd248341SJan Glauber 	spin_lock(&zpci_iomap_lock);
176cd248341SJan Glauber 	zpci_iomap_start[idx].fh = zdev->fh;
177cd248341SJan Glauber 	zpci_iomap_start[idx].bar = bar;
178cd248341SJan Glauber 	spin_unlock(&zpci_iomap_lock);
179cd248341SJan Glauber 
180cd248341SJan Glauber 	addr = ZPCI_IOMAP_ADDR_BASE | ((u64) idx << 48);
181cd248341SJan Glauber 	return (void __iomem *) addr;
182cd248341SJan Glauber }
183cd248341SJan Glauber EXPORT_SYMBOL_GPL(pci_iomap);
184cd248341SJan Glauber 
185cd248341SJan Glauber void pci_iounmap(struct pci_dev *pdev, void __iomem *addr)
186cd248341SJan Glauber {
187cd248341SJan Glauber 	unsigned int idx;
188cd248341SJan Glauber 
189cd248341SJan Glauber 	idx = (((__force u64) addr) & ~ZPCI_IOMAP_ADDR_BASE) >> 48;
190cd248341SJan Glauber 	spin_lock(&zpci_iomap_lock);
191cd248341SJan Glauber 	zpci_iomap_start[idx].fh = 0;
192cd248341SJan Glauber 	zpci_iomap_start[idx].bar = 0;
193cd248341SJan Glauber 	spin_unlock(&zpci_iomap_lock);
194cd248341SJan Glauber }
195cd248341SJan Glauber EXPORT_SYMBOL_GPL(pci_iounmap);
196cd248341SJan Glauber 
197cd248341SJan Glauber static int pci_read(struct pci_bus *bus, unsigned int devfn, int where,
198cd248341SJan Glauber 		    int size, u32 *val)
199cd248341SJan Glauber {
200cd248341SJan Glauber 	struct zpci_dev *zdev = get_zdev_by_bus(bus);
201cd248341SJan Glauber 
202cd248341SJan Glauber 	if (!zdev || devfn != ZPCI_DEVFN)
203cd248341SJan Glauber 		return 0;
204cd248341SJan Glauber 	return zpci_cfg_load(zdev, where, val, size);
205cd248341SJan Glauber }
206cd248341SJan Glauber 
207cd248341SJan Glauber static int pci_write(struct pci_bus *bus, unsigned int devfn, int where,
208cd248341SJan Glauber 		     int size, u32 val)
209cd248341SJan Glauber {
210cd248341SJan Glauber 	struct zpci_dev *zdev = get_zdev_by_bus(bus);
211cd248341SJan Glauber 
212cd248341SJan Glauber 	if (!zdev || devfn != ZPCI_DEVFN)
213cd248341SJan Glauber 		return 0;
214cd248341SJan Glauber 	return zpci_cfg_store(zdev, where, val, size);
215cd248341SJan Glauber }
216cd248341SJan Glauber 
217cd248341SJan Glauber static struct pci_ops pci_root_ops = {
218cd248341SJan Glauber 	.read = pci_read,
219cd248341SJan Glauber 	.write = pci_write,
220cd248341SJan Glauber };
221cd248341SJan Glauber 
222cd248341SJan Glauber static void zpci_map_resources(struct zpci_dev *zdev)
223cd248341SJan Glauber {
224cd248341SJan Glauber 	struct pci_dev *pdev = zdev->pdev;
225cd248341SJan Glauber 	resource_size_t len;
226cd248341SJan Glauber 	int i;
227cd248341SJan Glauber 
228cd248341SJan Glauber 	for (i = 0; i < PCI_BAR_COUNT; i++) {
229cd248341SJan Glauber 		len = pci_resource_len(pdev, i);
230cd248341SJan Glauber 		if (!len)
231cd248341SJan Glauber 			continue;
232cd248341SJan Glauber 		pdev->resource[i].start = (resource_size_t) pci_iomap(pdev, i, 0);
233cd248341SJan Glauber 		pdev->resource[i].end = pdev->resource[i].start + len - 1;
234cd248341SJan Glauber 		pr_debug("BAR%i: -> start: %Lx  end: %Lx\n",
235cd248341SJan Glauber 			i, pdev->resource[i].start, pdev->resource[i].end);
236cd248341SJan Glauber 	}
237cd248341SJan Glauber };
238cd248341SJan Glauber 
239cd248341SJan Glauber static void zpci_unmap_resources(struct pci_dev *pdev)
240cd248341SJan Glauber {
241cd248341SJan Glauber 	resource_size_t len;
242cd248341SJan Glauber 	int i;
243cd248341SJan Glauber 
244cd248341SJan Glauber 	for (i = 0; i < PCI_BAR_COUNT; i++) {
245cd248341SJan Glauber 		len = pci_resource_len(pdev, i);
246cd248341SJan Glauber 		if (!len)
247cd248341SJan Glauber 			continue;
248cd248341SJan Glauber 		pci_iounmap(pdev, (void *) pdev->resource[i].start);
249cd248341SJan Glauber 	}
250cd248341SJan Glauber };
251cd248341SJan Glauber 
252cd248341SJan Glauber struct zpci_dev *zpci_alloc_device(void)
253cd248341SJan Glauber {
254cd248341SJan Glauber 	struct zpci_dev *zdev;
255cd248341SJan Glauber 
256cd248341SJan Glauber 	/* Alloc memory for our private pci device data */
257cd248341SJan Glauber 	zdev = kzalloc(sizeof(*zdev), GFP_KERNEL);
258cd248341SJan Glauber 	if (!zdev)
259cd248341SJan Glauber 		return ERR_PTR(-ENOMEM);
260cd248341SJan Glauber 	return zdev;
261cd248341SJan Glauber }
262cd248341SJan Glauber 
263cd248341SJan Glauber void zpci_free_device(struct zpci_dev *zdev)
264cd248341SJan Glauber {
265cd248341SJan Glauber 	kfree(zdev);
266cd248341SJan Glauber }
267cd248341SJan Glauber 
268cd248341SJan Glauber /* Called on removal of pci_dev, leaves zpci and bus device */
269cd248341SJan Glauber static void zpci_remove_device(struct pci_dev *pdev)
270cd248341SJan Glauber {
271cd248341SJan Glauber 	struct zpci_dev *zdev = get_zdev(pdev);
272cd248341SJan Glauber 
273cd248341SJan Glauber 	dev_info(&pdev->dev, "Removing device %u\n", zdev->domain);
274cd248341SJan Glauber 	zdev->state = ZPCI_FN_STATE_CONFIGURED;
275cd248341SJan Glauber 	zpci_unmap_resources(pdev);
276cd248341SJan Glauber 	list_del(&zdev->entry);		/* can be called from init */
277cd248341SJan Glauber 	zdev->pdev = NULL;
278cd248341SJan Glauber }
279cd248341SJan Glauber 
280cd248341SJan Glauber static void zpci_scan_devices(void)
281cd248341SJan Glauber {
282cd248341SJan Glauber 	struct zpci_dev *zdev;
283cd248341SJan Glauber 
284cd248341SJan Glauber 	mutex_lock(&zpci_list_lock);
285cd248341SJan Glauber 	list_for_each_entry(zdev, &zpci_list, entry)
286cd248341SJan Glauber 		if (zdev->state == ZPCI_FN_STATE_CONFIGURED)
287cd248341SJan Glauber 			zpci_scan_device(zdev);
288cd248341SJan Glauber 	mutex_unlock(&zpci_list_lock);
289cd248341SJan Glauber }
290cd248341SJan Glauber 
291cd248341SJan Glauber /*
292cd248341SJan Glauber  * Too late for any s390 specific setup, since interrupts must be set up
293cd248341SJan Glauber  * already which requires DMA setup too and the pci scan will access the
294cd248341SJan Glauber  * config space, which only works if the function handle is enabled.
295cd248341SJan Glauber  */
296cd248341SJan Glauber int pcibios_enable_device(struct pci_dev *pdev, int mask)
297cd248341SJan Glauber {
298cd248341SJan Glauber 	struct resource *res;
299cd248341SJan Glauber 	u16 cmd;
300cd248341SJan Glauber 	int i;
301cd248341SJan Glauber 
302cd248341SJan Glauber 	pci_read_config_word(pdev, PCI_COMMAND, &cmd);
303cd248341SJan Glauber 
304cd248341SJan Glauber 	for (i = 0; i < PCI_BAR_COUNT; i++) {
305cd248341SJan Glauber 		res = &pdev->resource[i];
306cd248341SJan Glauber 
307cd248341SJan Glauber 		if (res->flags & IORESOURCE_IO)
308cd248341SJan Glauber 			return -EINVAL;
309cd248341SJan Glauber 
310cd248341SJan Glauber 		if (res->flags & IORESOURCE_MEM)
311cd248341SJan Glauber 			cmd |= PCI_COMMAND_MEMORY;
312cd248341SJan Glauber 	}
313cd248341SJan Glauber 	pci_write_config_word(pdev, PCI_COMMAND, cmd);
314cd248341SJan Glauber 	return 0;
315cd248341SJan Glauber }
316cd248341SJan Glauber 
317cd248341SJan Glauber void pcibios_disable_device(struct pci_dev *pdev)
318cd248341SJan Glauber {
319cd248341SJan Glauber 	zpci_remove_device(pdev);
320cd248341SJan Glauber 	pdev->sysdata = NULL;
321cd248341SJan Glauber }
322cd248341SJan Glauber 
323cd248341SJan Glauber static struct resource *zpci_alloc_bus_resource(unsigned long start, unsigned long size,
324cd248341SJan Glauber 						unsigned long flags, int domain)
325cd248341SJan Glauber {
326cd248341SJan Glauber 	struct resource *r;
327cd248341SJan Glauber 	char *name;
328cd248341SJan Glauber 	int rc;
329cd248341SJan Glauber 
330cd248341SJan Glauber 	r = kzalloc(sizeof(*r), GFP_KERNEL);
331cd248341SJan Glauber 	if (!r)
332cd248341SJan Glauber 		return ERR_PTR(-ENOMEM);
333cd248341SJan Glauber 	r->start = start;
334cd248341SJan Glauber 	r->end = r->start + size - 1;
335cd248341SJan Glauber 	r->flags = flags;
336cd248341SJan Glauber 	r->parent = &iomem_resource;
337cd248341SJan Glauber 	name = kmalloc(18, GFP_KERNEL);
338cd248341SJan Glauber 	if (!name) {
339cd248341SJan Glauber 		kfree(r);
340cd248341SJan Glauber 		return ERR_PTR(-ENOMEM);
341cd248341SJan Glauber 	}
342cd248341SJan Glauber 	sprintf(name, "PCI Bus: %04x:%02x", domain, ZPCI_BUS_NR);
343cd248341SJan Glauber 	r->name = name;
344cd248341SJan Glauber 
345cd248341SJan Glauber 	rc = request_resource(&iomem_resource, r);
346cd248341SJan Glauber 	if (rc)
347cd248341SJan Glauber 		pr_debug("request resource %pR failed\n", r);
348cd248341SJan Glauber 	return r;
349cd248341SJan Glauber }
350cd248341SJan Glauber 
351cd248341SJan Glauber static int zpci_alloc_iomap(struct zpci_dev *zdev)
352cd248341SJan Glauber {
353cd248341SJan Glauber 	int entry;
354cd248341SJan Glauber 
355cd248341SJan Glauber 	spin_lock(&zpci_iomap_lock);
356cd248341SJan Glauber 	entry = find_first_zero_bit(zpci_iomap, ZPCI_IOMAP_MAX_ENTRIES);
357cd248341SJan Glauber 	if (entry == ZPCI_IOMAP_MAX_ENTRIES) {
358cd248341SJan Glauber 		spin_unlock(&zpci_iomap_lock);
359cd248341SJan Glauber 		return -ENOSPC;
360cd248341SJan Glauber 	}
361cd248341SJan Glauber 	set_bit(entry, zpci_iomap);
362cd248341SJan Glauber 	spin_unlock(&zpci_iomap_lock);
363cd248341SJan Glauber 	return entry;
364cd248341SJan Glauber }
365cd248341SJan Glauber 
366cd248341SJan Glauber static void zpci_free_iomap(struct zpci_dev *zdev, int entry)
367cd248341SJan Glauber {
368cd248341SJan Glauber 	spin_lock(&zpci_iomap_lock);
369cd248341SJan Glauber 	memset(&zpci_iomap_start[entry], 0, sizeof(struct zpci_iomap_entry));
370cd248341SJan Glauber 	clear_bit(entry, zpci_iomap);
371cd248341SJan Glauber 	spin_unlock(&zpci_iomap_lock);
372cd248341SJan Glauber }
373cd248341SJan Glauber 
374cd248341SJan Glauber static int zpci_create_device_bus(struct zpci_dev *zdev)
375cd248341SJan Glauber {
376cd248341SJan Glauber 	struct resource *res;
377cd248341SJan Glauber 	LIST_HEAD(resources);
378cd248341SJan Glauber 	int i;
379cd248341SJan Glauber 
380cd248341SJan Glauber 	/* allocate mapping entry for each used bar */
381cd248341SJan Glauber 	for (i = 0; i < PCI_BAR_COUNT; i++) {
382cd248341SJan Glauber 		unsigned long addr, size, flags;
383cd248341SJan Glauber 		int entry;
384cd248341SJan Glauber 
385cd248341SJan Glauber 		if (!zdev->bars[i].size)
386cd248341SJan Glauber 			continue;
387cd248341SJan Glauber 		entry = zpci_alloc_iomap(zdev);
388cd248341SJan Glauber 		if (entry < 0)
389cd248341SJan Glauber 			return entry;
390cd248341SJan Glauber 		zdev->bars[i].map_idx = entry;
391cd248341SJan Glauber 
392cd248341SJan Glauber 		/* only MMIO is supported */
393cd248341SJan Glauber 		flags = IORESOURCE_MEM;
394cd248341SJan Glauber 		if (zdev->bars[i].val & 8)
395cd248341SJan Glauber 			flags |= IORESOURCE_PREFETCH;
396cd248341SJan Glauber 		if (zdev->bars[i].val & 4)
397cd248341SJan Glauber 			flags |= IORESOURCE_MEM_64;
398cd248341SJan Glauber 
399cd248341SJan Glauber 		addr = ZPCI_IOMAP_ADDR_BASE + ((u64) entry << 48);
400cd248341SJan Glauber 
401cd248341SJan Glauber 		size = 1UL << zdev->bars[i].size;
402cd248341SJan Glauber 
403cd248341SJan Glauber 		res = zpci_alloc_bus_resource(addr, size, flags, zdev->domain);
404cd248341SJan Glauber 		if (IS_ERR(res)) {
405cd248341SJan Glauber 			zpci_free_iomap(zdev, entry);
406cd248341SJan Glauber 			return PTR_ERR(res);
407cd248341SJan Glauber 		}
408cd248341SJan Glauber 		pci_add_resource(&resources, res);
409cd248341SJan Glauber 	}
410cd248341SJan Glauber 
411cd248341SJan Glauber 	zdev->bus = pci_create_root_bus(NULL, ZPCI_BUS_NR, &pci_root_ops,
412cd248341SJan Glauber 					zdev, &resources);
413cd248341SJan Glauber 	if (!zdev->bus)
414cd248341SJan Glauber 		return -EIO;
415cd248341SJan Glauber 
416cd248341SJan Glauber 	zdev->bus->max_bus_speed = zdev->max_bus_speed;
417cd248341SJan Glauber 	return 0;
418cd248341SJan Glauber }
419cd248341SJan Glauber 
420cd248341SJan Glauber static int zpci_alloc_domain(struct zpci_dev *zdev)
421cd248341SJan Glauber {
422cd248341SJan Glauber 	spin_lock(&zpci_domain_lock);
423cd248341SJan Glauber 	zdev->domain = find_first_zero_bit(zpci_domain, ZPCI_NR_DEVICES);
424cd248341SJan Glauber 	if (zdev->domain == ZPCI_NR_DEVICES) {
425cd248341SJan Glauber 		spin_unlock(&zpci_domain_lock);
426cd248341SJan Glauber 		return -ENOSPC;
427cd248341SJan Glauber 	}
428cd248341SJan Glauber 	set_bit(zdev->domain, zpci_domain);
429cd248341SJan Glauber 	spin_unlock(&zpci_domain_lock);
430cd248341SJan Glauber 	return 0;
431cd248341SJan Glauber }
432cd248341SJan Glauber 
433cd248341SJan Glauber static void zpci_free_domain(struct zpci_dev *zdev)
434cd248341SJan Glauber {
435cd248341SJan Glauber 	spin_lock(&zpci_domain_lock);
436cd248341SJan Glauber 	clear_bit(zdev->domain, zpci_domain);
437cd248341SJan Glauber 	spin_unlock(&zpci_domain_lock);
438cd248341SJan Glauber }
439cd248341SJan Glauber 
440*a755a45dSJan Glauber int zpci_enable_device(struct zpci_dev *zdev)
441*a755a45dSJan Glauber {
442*a755a45dSJan Glauber 	int rc;
443*a755a45dSJan Glauber 
444*a755a45dSJan Glauber 	rc = clp_enable_fh(zdev, ZPCI_NR_DMA_SPACES);
445*a755a45dSJan Glauber 	if (rc)
446*a755a45dSJan Glauber 		goto out;
447*a755a45dSJan Glauber 	pr_info("Enabled fh: 0x%x fid: 0x%x\n", zdev->fh, zdev->fid);
448*a755a45dSJan Glauber 	return 0;
449*a755a45dSJan Glauber out:
450*a755a45dSJan Glauber 	return rc;
451*a755a45dSJan Glauber }
452*a755a45dSJan Glauber EXPORT_SYMBOL_GPL(zpci_enable_device);
453*a755a45dSJan Glauber 
454cd248341SJan Glauber int zpci_create_device(struct zpci_dev *zdev)
455cd248341SJan Glauber {
456cd248341SJan Glauber 	int rc;
457cd248341SJan Glauber 
458cd248341SJan Glauber 	rc = zpci_alloc_domain(zdev);
459cd248341SJan Glauber 	if (rc)
460cd248341SJan Glauber 		goto out;
461cd248341SJan Glauber 
462cd248341SJan Glauber 	rc = zpci_create_device_bus(zdev);
463cd248341SJan Glauber 	if (rc)
464cd248341SJan Glauber 		goto out_bus;
465cd248341SJan Glauber 
466cd248341SJan Glauber 	mutex_lock(&zpci_list_lock);
467cd248341SJan Glauber 	list_add_tail(&zdev->entry, &zpci_list);
468cd248341SJan Glauber 	mutex_unlock(&zpci_list_lock);
469cd248341SJan Glauber 
470cd248341SJan Glauber 	if (zdev->state == ZPCI_FN_STATE_STANDBY)
471cd248341SJan Glauber 		return 0;
472cd248341SJan Glauber 
473*a755a45dSJan Glauber 	rc = zpci_enable_device(zdev);
474*a755a45dSJan Glauber 	if (rc)
475*a755a45dSJan Glauber 		goto out_start;
476cd248341SJan Glauber 	return 0;
477cd248341SJan Glauber 
478*a755a45dSJan Glauber out_start:
479*a755a45dSJan Glauber 	mutex_lock(&zpci_list_lock);
480*a755a45dSJan Glauber 	list_del(&zdev->entry);
481*a755a45dSJan Glauber 	mutex_unlock(&zpci_list_lock);
482cd248341SJan Glauber out_bus:
483cd248341SJan Glauber 	zpci_free_domain(zdev);
484cd248341SJan Glauber out:
485cd248341SJan Glauber 	return rc;
486cd248341SJan Glauber }
487cd248341SJan Glauber 
488cd248341SJan Glauber void zpci_stop_device(struct zpci_dev *zdev)
489cd248341SJan Glauber {
490cd248341SJan Glauber 	/*
491cd248341SJan Glauber 	 * Note: SCLP disables fh via set-pci-fn so don't
492cd248341SJan Glauber 	 * do that here.
493cd248341SJan Glauber 	 */
494cd248341SJan Glauber }
495cd248341SJan Glauber EXPORT_SYMBOL_GPL(zpci_stop_device);
496cd248341SJan Glauber 
497cd248341SJan Glauber int zpci_scan_device(struct zpci_dev *zdev)
498cd248341SJan Glauber {
499cd248341SJan Glauber 	zdev->pdev = pci_scan_single_device(zdev->bus, ZPCI_DEVFN);
500cd248341SJan Glauber 	if (!zdev->pdev) {
501cd248341SJan Glauber 		pr_err("pci_scan_single_device failed for fid: 0x%x\n",
502cd248341SJan Glauber 			zdev->fid);
503cd248341SJan Glauber 		goto out;
504cd248341SJan Glauber 	}
505cd248341SJan Glauber 
506cd248341SJan Glauber 	zpci_map_resources(zdev);
507cd248341SJan Glauber 	pci_bus_add_devices(zdev->bus);
508cd248341SJan Glauber 
509cd248341SJan Glauber 	/* now that pdev was added to the bus mark it as used */
510cd248341SJan Glauber 	zdev->state = ZPCI_FN_STATE_ONLINE;
511cd248341SJan Glauber 	return 0;
512cd248341SJan Glauber 
513cd248341SJan Glauber out:
514*a755a45dSJan Glauber 	clp_disable_fh(zdev);
515cd248341SJan Glauber 	return -EIO;
516cd248341SJan Glauber }
517cd248341SJan Glauber EXPORT_SYMBOL_GPL(zpci_scan_device);
518cd248341SJan Glauber 
519cd248341SJan Glauber static inline int barsize(u8 size)
520cd248341SJan Glauber {
521cd248341SJan Glauber 	return (size) ? (1 << size) >> 10 : 0;
522cd248341SJan Glauber }
523cd248341SJan Glauber 
524cd248341SJan Glauber static int zpci_mem_init(void)
525cd248341SJan Glauber {
526cd248341SJan Glauber 	/* TODO: use realloc */
527cd248341SJan Glauber 	zpci_iomap_start = kzalloc(ZPCI_IOMAP_MAX_ENTRIES * sizeof(*zpci_iomap_start),
528cd248341SJan Glauber 				   GFP_KERNEL);
529cd248341SJan Glauber 	if (!zpci_iomap_start)
530cd248341SJan Glauber 		goto error_zdev;
531cd248341SJan Glauber 	return 0;
532cd248341SJan Glauber 
533cd248341SJan Glauber error_zdev:
534cd248341SJan Glauber 	return -ENOMEM;
535cd248341SJan Glauber }
536cd248341SJan Glauber 
537cd248341SJan Glauber static void zpci_mem_exit(void)
538cd248341SJan Glauber {
539cd248341SJan Glauber 	kfree(zpci_iomap_start);
540cd248341SJan Glauber }
541cd248341SJan Glauber 
542cd248341SJan Glauber unsigned int pci_probe = 1;
543cd248341SJan Glauber EXPORT_SYMBOL_GPL(pci_probe);
544cd248341SJan Glauber 
545cd248341SJan Glauber char * __init pcibios_setup(char *str)
546cd248341SJan Glauber {
547cd248341SJan Glauber 	if (!strcmp(str, "off")) {
548cd248341SJan Glauber 		pci_probe = 0;
549cd248341SJan Glauber 		return NULL;
550cd248341SJan Glauber 	}
551cd248341SJan Glauber 	return str;
552cd248341SJan Glauber }
553cd248341SJan Glauber 
554cd248341SJan Glauber static int __init pci_base_init(void)
555cd248341SJan Glauber {
556cd248341SJan Glauber 	int rc;
557cd248341SJan Glauber 
558cd248341SJan Glauber 	if (!pci_probe)
559cd248341SJan Glauber 		return 0;
560cd248341SJan Glauber 
561cd248341SJan Glauber 	if (!test_facility(2) || !test_facility(69)
562cd248341SJan Glauber 	    || !test_facility(71) || !test_facility(72))
563cd248341SJan Glauber 		return 0;
564cd248341SJan Glauber 
565cd248341SJan Glauber 	pr_info("Probing PCI hardware: PCI:%d  SID:%d  AEN:%d\n",
566cd248341SJan Glauber 		test_facility(69), test_facility(70),
567cd248341SJan Glauber 		test_facility(71));
568cd248341SJan Glauber 
569cd248341SJan Glauber 	rc = zpci_mem_init();
570cd248341SJan Glauber 	if (rc)
571cd248341SJan Glauber 		goto out_mem;
572cd248341SJan Glauber 
573*a755a45dSJan Glauber 	rc = clp_find_pci_devices();
574*a755a45dSJan Glauber 	if (rc)
575*a755a45dSJan Glauber 		goto out_find;
576*a755a45dSJan Glauber 
577cd248341SJan Glauber 	zpci_scan_devices();
578cd248341SJan Glauber 	return 0;
579cd248341SJan Glauber 
580*a755a45dSJan Glauber out_find:
581cd248341SJan Glauber 	zpci_mem_exit();
582cd248341SJan Glauber out_mem:
583cd248341SJan Glauber 	return rc;
584cd248341SJan Glauber }
585cd248341SJan Glauber subsys_initcall(pci_base_init);
586